open-vm-tools-9.4.0-1280544/0000755765153500003110000000000012220061621013430 5ustar dtormtsopen-vm-tools-9.4.0-1280544/tests/0000755765153500003110000000000012220061625014576 5ustar dtormtsopen-vm-tools-9.4.0-1280544/tests/testPlugin/0000755765153500003110000000000012220061625016734 5ustar dtormtsopen-vm-tools-9.4.0-1280544/tests/testPlugin/testData.x0000644765153500003110000000206212220061556020701 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file testData.x * * Just define a struct for testing automatic XDR serialization. */ struct TestPluginData { string data<128>; uint32 f_int; Bool f_bool; }; open-vm-tools-9.4.0-1280544/tests/testPlugin/testPlugin.c0000644765153500003110000002744112220061556021251 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file testPlugin.c * * Implements a test plugin for the tools services. The plugin register for * a few RPCs that are never sent by the VMX, so to "use" it you have to use * a debug plugin that sends those RPCs. The test debug plugin does that. */ #define G_LOG_DOMAIN "test" #include #include #include #include "testData.h" #include "util.h" #include "vmware/tools/log.h" #include "vmware/tools/plugin.h" #include "vmware/tools/rpcdebug.h" #include "vmware/tools/utils.h" #define TEST_APP_PROVIDER "TestProvider" #define TEST_APP_NAME "TestProviderApp1" #define TEST_APP_ERROR "TestProviderError" #define TEST_APP_DONT_REGISTER "TestProviderDontRegister" #define TEST_SIG_INVALID "TestInvalidSignal" typedef struct TestApp { const char *name; } TestApp; static gboolean gInvalidAppError = FALSE; static gboolean gInvalidAppProvider = FALSE; static gboolean gInvalidSigError = FALSE; static gboolean gValidAppRegistration = FALSE; /** * Handles a "test.rpcin.msg1" RPC message. The incoming data should be an * XDR-encoded TestPluginData struct; the struct is written back * to the RPC channel using RpcChannel_Send (command "test.rpcout.msg1"). * * Also emits a "test-signal", to test custom signal registration. * * @param[in] data RPC data. * * @return TRUE on success. */ static gboolean TestPluginRpc1(RpcInData *data) { ToolsAppCtx *ctx = data->appCtx; TestPluginData *testdata = (TestPluginData *) data->args; char *cmd; size_t cmdLen; CU_ASSERT_STRING_EQUAL(testdata->data, "rpc1test"); CU_ASSERT_EQUAL(testdata->f_int, 1357); CU_ASSERT(testdata->f_bool); g_signal_emit_by_name(ctx->serviceObj, "test-signal"); if (!RpcChannel_BuildXdrCommand("test.rpcout.msg1", xdr_TestPluginData, testdata, &cmd, &cmdLen)) { vm_error("Failed to create test.rpcout.msg1 command."); } if (!RpcChannel_Send(ctx->rpc, cmd, cmdLen, NULL, NULL)) { vm_error("Failed to send 'test.rpcout.msg1' message."); } vm_free(cmd); vm_debug("Successfully handled rpc %s", data->name); return RPCIN_SETRETVALS(data, "", TRUE); } /** * Handles a "test.rpcin.msg2" RPC message. * * @param[in] data RPC data. * * @return TRUE on success. */ static gboolean TestPluginRpc2(RpcInData *data) { vm_debug("%s", data->name); return RPCIN_SETRETVALS(data, "", TRUE); } /** * Handles a "test.rpcin.msg3" RPC message. Logs information to the * output and returns data to be serialized using XDR. * * @param[in] data RPC data. * * @return TRUE on success. */ static gboolean TestPluginRpc3(RpcInData *data) { TestPluginData *ret; vm_debug("%s", data->name); ret = g_malloc(sizeof *ret); ret->data = Util_SafeStrdup("Hello World!"); ret->f_int = 8642; ret->f_bool = TRUE; data->result = (char *) ret; return TRUE; } /** * Called by the service core when the host requests the capabilities supported * by the guest tools. * * @param[in] src Unused. * @param[in] ctx The app context. * @param[in] set Whether capabilities are being set or unset (unused). * @param[in] plugin Plugin registration data. * * @return A list of capabilities to be sent to the host. */ static GArray * TestPluginCapabilities(gpointer src, ToolsAppCtx *ctx, gboolean set, ToolsPluginData *plugin) { ToolsAppCapability caps[] = { { TOOLS_CAP_OLD, "resolution_set", 0, 1 }, { TOOLS_CAP_OLD, "display_topology_set", 0, 2 }, { TOOLS_CAP_NEW, NULL, UNITY_CAP_START_MENU, 1 }, { TOOLS_CAP_NEW, NULL, GHI_CAP_SHELL_ACTION_BROWSE, 1 } }; vm_debug("got capability signal, setting = %d.", set); return VMTools_WrapArray(caps, sizeof *caps, ARRAYSIZE(caps)); } /** * Handles a reset signal; just logs debug information. This callback is * called when the service receives a "reset" message from the VMX, meaning * the VMX may be restarting the RPC channel (due, for example, to restoring * a snapshot, resuming a VM or a VMotion), and should be used to reset any * application state that depends on the VMX. * * @param[in] src Event source. * @param[in] ctx The app context. * @param[in] plugin Plugin registration data. * * @return TRUE on success. */ static gboolean TestPluginReset(gpointer src, ToolsAppCtx *ctx, ToolsPluginData *plugin) { RPCDEBUG_ASSERT(ctx != NULL, FALSE); vm_debug("reset signal for app %s", ctx->name); return TRUE; } #if defined(G_PLATFORM_WIN32) /** * Handles a service control signal; this is only called on Windows. * * @param[in] src The source object. * @param[in] ctx The application context. * @param[in] serviceStatusHandle Handle of type SERVICE_STATUS_HANDLE. * @param[in] controlCode Control code. * @param[in] eventType Unused. * @param[in] eventData Unused. * @param[in] data Unused. * * @retval ERROR_CALL_NOT_IMPLEMENTED */ static DWORD TestPluginServiceControl(gpointer src, ToolsAppCtx *ctx, gpointer serviceStatusHandle, guint controlCode, guint eventType, gpointer eventData, gpointer data) { vm_debug("Got service control signal, code = %u, event = %u", controlCode, eventType); return ERROR_CALL_NOT_IMPLEMENTED; } #endif /** * Handles a shutdown callback; just logs debug information. This is called * before the service is shut down, and should be used to clean up any resources * that were initialized by the application. * * @param[in] src The source object. * @param[in] ctx The app context. * @param[in] plugin Plugin registration data. */ static void TestPluginShutdown(gpointer src, ToolsAppCtx *ctx, ToolsPluginData *plugin) { vm_debug("shutdown signal."); CU_ASSERT(gInvalidSigError); CU_ASSERT(gInvalidAppError); CU_ASSERT(gInvalidAppProvider); CU_ASSERT(gValidAppRegistration); } /** * Handles a "Set_Option" callback. Just logs debug information. This callback * is called when the VMX sends a "Set_Option" command to tools, to configure * different options whose values are kept outside of the virtual machine. * * @param[in] src Event source. * @param[in] ctx The app context. * @param[in] plugin Plugin registration data. * @param[in] option Option being set. * @param[in] value Option value. * * @return TRUE on success. */ static gboolean TestPluginSetOption(gpointer src, ToolsAppCtx *ctx, const gchar *option, const gchar *value, ToolsPluginData *plugin) { vm_debug("set '%s' to '%s'", option, value); return TRUE; } /** * Prints out the registration data for the test provider. * * @param[in] ctx Unused. * @param[in] prov Unused. * @param[in] plugin Unused. * @param[in] reg Registration data (should be a string). * * @retval FALSE if registration value is TEST_APP_ERROR. * @retval TRUE otherwise. */ static gboolean TestProviderRegisterApp(ToolsAppCtx *ctx, ToolsAppProvider *prov, ToolsPluginData *plugin, gpointer reg) { TestApp *app = reg; vm_debug("registration data is '%s'", app->name); gValidAppRegistration |= strcmp(app->name, TEST_APP_NAME) == 0; CU_ASSERT(strcmp(app->name, TEST_APP_DONT_REGISTER) != 0); return (strcmp(app->name, TEST_APP_ERROR) != 0); } /** * Registration error callback; make sure it's called for the errors we expect. * * @see plugin.h (for parameter descriptions) * * @retval FALSE for TEST_APP_ERROR. * @retval TRUE otherwise. */ static gboolean TestPluginErrorCb(ToolsAppCtx *ctx, ToolsAppType type, gpointer data, ToolsPluginData *plugin) { /* Make sure the non-existant signal we tried to register fires an error. */ if (type == TOOLS_APP_SIGNALS) { ToolsPluginSignalCb *sig = data; CU_ASSERT(strcmp(sig->signame, TEST_SIG_INVALID) == 0); gInvalidSigError = TRUE; } /* Make sure we're notified about the "error" app we tried to register. */ if (type == 42) { TestApp *app = data; CU_ASSERT(strcmp(app->name, TEST_APP_ERROR) == 0); gInvalidAppError = TRUE; return FALSE; } /* Make sure we're notified about a non-existant app provider. */ if (type == 43) { CU_ASSERT(data == NULL); gInvalidAppProvider = TRUE; } return TRUE; } /** * Plugin entry point. Returns the registration data. This is called once when * the plugin is loaded into the service process. * * @param[in] ctx The app context. * * @return The registration data. */ TOOLS_MODULE_EXPORT ToolsPluginData * ToolsOnLoad(ToolsAppCtx *ctx) { static ToolsPluginData regData = { "testPlugin", NULL, TestPluginErrorCb, NULL }; RpcChannelCallback rpcs[] = { { "test.rpcin.msg1", TestPluginRpc1, NULL, xdr_TestPluginData, NULL, sizeof (TestPluginData) }, { "test.rpcin.msg2", TestPluginRpc2, NULL, NULL, NULL, 0 }, { "test.rpcin.msg3", TestPluginRpc3, NULL, NULL, xdr_TestPluginData, 0 } }; ToolsAppProvider provs[] = { { TEST_APP_PROVIDER, 42, sizeof (char *), NULL, TestProviderRegisterApp, NULL, NULL } }; ToolsPluginSignalCb sigs[] = { { TOOLS_CORE_SIG_RESET, TestPluginReset, ®Data }, { TOOLS_CORE_SIG_SHUTDOWN, TestPluginShutdown, ®Data }, { TOOLS_CORE_SIG_CAPABILITIES, TestPluginCapabilities, ®Data }, { TOOLS_CORE_SIG_SET_OPTION, TestPluginSetOption, ®Data }, #if defined(G_PLATFORM_WIN32) { TOOLS_CORE_SIG_SERVICE_CONTROL, TestPluginServiceControl, ®Data }, #endif { TEST_SIG_INVALID, TestPluginReset, ®Data }, }; TestApp tapp[] = { { TEST_APP_NAME }, { TEST_APP_ERROR }, { TEST_APP_DONT_REGISTER } }; TestApp tnoprov[] = { { "TestAppNoProvider" } }; ToolsAppReg regs[] = { { TOOLS_APP_GUESTRPC, VMTOOLS_WRAP_ARRAY(rpcs) }, { TOOLS_APP_PROVIDER, VMTOOLS_WRAP_ARRAY(provs) }, { TOOLS_APP_SIGNALS, VMTOOLS_WRAP_ARRAY(sigs) }, { 42, VMTOOLS_WRAP_ARRAY(tapp) }, { 43, VMTOOLS_WRAP_ARRAY(tnoprov) }, }; vm_info("loading test plugin..."); g_signal_new("test-signal", G_OBJECT_TYPE(ctx->serviceObj), 0, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); regData.regs = VMTOOLS_WRAP_ARRAY(regs); return ®Data; } open-vm-tools-9.4.0-1280544/tests/testPlugin/COPYING0000644765153500003110000006347112220061556020005 0ustar dtormts GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! open-vm-tools-9.4.0-1280544/tests/testPlugin/Makefile.am0000644765153500003110000000360412220061556020776 0ustar dtormts################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ plugindir = @TEST_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libtestPlugin.la libtestPlugin_la_CPPFLAGS = libtestPlugin_la_CPPFLAGS += @CUNIT_CPPFLAGS@ libtestPlugin_la_CPPFLAGS += @GOBJECT_CPPFLAGS@ libtestPlugin_la_CPPFLAGS += @PLUGIN_CPPFLAGS@ libtestPlugin_la_LDFLAGS = libtestPlugin_la_LDFLAGS += @PLUGIN_LDFLAGS@ libtestPlugin_la_LIBADD = libtestPlugin_la_LIBADD += @CUNIT_LIBS@ libtestPlugin_la_LIBADD += @GOBJECT_LIBS@ libtestPlugin_la_LIBADD += @VMTOOLS_LIBS@ libtestPlugin_la_LIBADD += @XDR_LIBS@ libtestPlugin_la_SOURCES = libtestPlugin_la_SOURCES += testData_xdr.c libtestPlugin_la_SOURCES += testPlugin.c BUILT_SOURCES = BUILT_SOURCES += testData_xdr.c BUILT_SOURCES += testData.h # XXX: see explanation in lib/guestRpc/Makefile.am CFLAGS += -Wno-unused CLEANFILES = CLEANFILES += testData_xdr.c CLEANFILES += testData.h EXTRA_DIST = EXTRA_DIST += testData.x testData.h: testData.x @RPCGEN_WRAPPER@ tests/testPlugin/testData.x $@ testData_xdr.c: testData.x testData.h @RPCGEN_WRAPPER@ tests/testPlugin/testData.x $@ open-vm-tools-9.4.0-1280544/tests/testPlugin/Makefile.in0000644765153500003110000005726212220061625021015 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tests/testPlugin DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(plugin_LTLIBRARIES) libtestPlugin_la_DEPENDENCIES = am_libtestPlugin_la_OBJECTS = libtestPlugin_la-testData_xdr.lo \ libtestPlugin_la-testPlugin.lo libtestPlugin_la_OBJECTS = $(am_libtestPlugin_la_OBJECTS) libtestPlugin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libtestPlugin_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libtestPlugin_la_SOURCES) DIST_SOURCES = $(libtestPlugin_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ # XXX: see explanation in lib/guestRpc/Makefile.am CFLAGS = @CFLAGS@ -Wno-unused COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ plugindir = @TEST_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libtestPlugin.la libtestPlugin_la_CPPFLAGS = @CUNIT_CPPFLAGS@ @GOBJECT_CPPFLAGS@ \ @PLUGIN_CPPFLAGS@ $(am__empty) libtestPlugin_la_LDFLAGS = @PLUGIN_LDFLAGS@ libtestPlugin_la_LIBADD = @CUNIT_LIBS@ @GOBJECT_LIBS@ @VMTOOLS_LIBS@ \ @XDR_LIBS@ $(am__empty) libtestPlugin_la_SOURCES = testData_xdr.c testPlugin.c BUILT_SOURCES = testData_xdr.c testData.h CLEANFILES = testData_xdr.c testData.h EXTRA_DIST = testData.x all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/testPlugin/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/testPlugin/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ } uninstall-pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ done clean-pluginLTLIBRARIES: -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) @list='$(plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libtestPlugin.la: $(libtestPlugin_la_OBJECTS) $(libtestPlugin_la_DEPENDENCIES) $(EXTRA_libtestPlugin_la_DEPENDENCIES) $(libtestPlugin_la_LINK) -rpath $(plugindir) $(libtestPlugin_la_OBJECTS) $(libtestPlugin_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtestPlugin_la-testData_xdr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtestPlugin_la-testPlugin.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libtestPlugin_la-testData_xdr.lo: testData_xdr.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestPlugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtestPlugin_la-testData_xdr.lo -MD -MP -MF $(DEPDIR)/libtestPlugin_la-testData_xdr.Tpo -c -o libtestPlugin_la-testData_xdr.lo `test -f 'testData_xdr.c' || echo '$(srcdir)/'`testData_xdr.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtestPlugin_la-testData_xdr.Tpo $(DEPDIR)/libtestPlugin_la-testData_xdr.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testData_xdr.c' object='libtestPlugin_la-testData_xdr.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestPlugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtestPlugin_la-testData_xdr.lo `test -f 'testData_xdr.c' || echo '$(srcdir)/'`testData_xdr.c libtestPlugin_la-testPlugin.lo: testPlugin.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestPlugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtestPlugin_la-testPlugin.lo -MD -MP -MF $(DEPDIR)/libtestPlugin_la-testPlugin.Tpo -c -o libtestPlugin_la-testPlugin.lo `test -f 'testPlugin.c' || echo '$(srcdir)/'`testPlugin.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtestPlugin_la-testPlugin.Tpo $(DEPDIR)/libtestPlugin_la-testPlugin.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testPlugin.c' object='libtestPlugin_la-testPlugin.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestPlugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtestPlugin_la-testPlugin.lo `test -f 'testPlugin.c' || echo '$(srcdir)/'`testPlugin.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(plugindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pluginLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pluginLTLIBRARIES .MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-pluginLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-pluginLTLIBRARIES install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-pluginLTLIBRARIES testData.h: testData.x @RPCGEN_WRAPPER@ tests/testPlugin/testData.x $@ testData_xdr.c: testData.x testData.h @RPCGEN_WRAPPER@ tests/testPlugin/testData.x $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/tests/testVmblock/0000755765153500003110000000000012220061625017073 5ustar dtormtsopen-vm-tools-9.4.0-1280544/tests/testVmblock/vmblocktest.c0000644765153500003110000004434512220061556021611 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vmblocktest.c -- * * Test program for the vmblock file system. Ensures correctness and * stability. * */ #if !defined(linux) && !defined(sun) && !defined(__FreeBSD__) && !defined(vmblock_fuse) # error "vmblocktest.c needs to be ported to your OS." #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef sun # include #endif #include "vmblock_user.h" #include "vm_basic_types.h" #define CONTROLFILE VMBLOCK_DEVICE #define CONTROLFILE_MODE VMBLOCK_DEVICE_MODE #define REALROOT "/tmp/VMwareDnD/" #define FILENAME "/foo" #define ACCESSORFULLNAME(dir) VMBLOCK_FS_ROOT "/" dir FILENAME #define BLOCKERFULLNAME(dir) REALROOT dir #define lprintf(...) \ do { \ pthread_mutex_lock(&print_lock); \ printf(__VA_ARGS__); \ fflush(stdout); \ pthread_mutex_unlock(&print_lock); \ } while(0) #define lfprintf(stream, ...) \ do { \ pthread_mutex_lock(&print_lock); \ fprintf(stream, __VA_ARGS__); \ fflush(stream); \ pthread_mutex_unlock(&print_lock); \ } while(0) #define Log(fmt, args...) lprintf(fmt, ## args) #define ERROR(fmt, args...) lfprintf(stderr, fmt, ## args) #define THREAD_LOG(fmt, args...) lprintf(" (%lx) " fmt, (unsigned long)pthread_self(), ## args) #define THREAD_ERROR(fmt, args...) lfprintf(stderr, " (%"FMTPID") " fmt, getpid(), ## args) #if defined (linux) || defined(__FreeBSD__) # define os_thread_yield() sched_yield() #elif defined(sun) # define os_thread_yield() yield() #endif /* * This program may optionally throttle accessor thread generation * via POSIX semaphores. */ #if defined(USE_SEMAPHORES) sem_t sem; # define SEM_THREADS (unsigned int)10 # define SEM_INIT() sem_init(&sem, 0, SEM_THREADS) # define SEM_DESTROY() sem_destroy(&sem) # define SEM_WAIT() sem_wait(&sem) # define SEM_POST() sem_post(&sem) # define PTHREAD_SEMAPHORE_CLEANUP() pthread_cleanup_push(sem_post, \ (void *)&sem) #else # define SEM_INIT() # define SEM_DESTROY() # define SEM_WAIT() # define SEM_POST() # define PTHREAD_SEMAPHORE_CLEANUP() #endif /* Types */ typedef struct FileState { /* Accessors will access the file through the vmblock namespace */ char *accessorName; /* The blocker will add blocks using the real file's name */ char *blockerName; Bool blocked; unsigned int waiters; } FileState; typedef struct ThreadInfo { int blockFd; pthread_mutex_t *lock; FileState *files; size_t filesArraySize; unsigned int sleepTime; } ThreadInfo; /* Variables */ static Bool programQuit = FALSE; static FileState files[] = { { ACCESSORFULLNAME("0"), BLOCKERFULLNAME("0"), FALSE, 0 }, { ACCESSORFULLNAME("1"), BLOCKERFULLNAME("1"), FALSE, 0 }, { ACCESSORFULLNAME("2"), BLOCKERFULLNAME("2"), FALSE, 0 }, { ACCESSORFULLNAME("3"), BLOCKERFULLNAME("3"), FALSE, 0 }, { ACCESSORFULLNAME("4"), BLOCKERFULLNAME("4"), FALSE, 0 }, { ACCESSORFULLNAME("5"), BLOCKERFULLNAME("5"), FALSE, 0 }, { ACCESSORFULLNAME("6"), BLOCKERFULLNAME("6"), FALSE, 0 }, { ACCESSORFULLNAME("7"), BLOCKERFULLNAME("7"), FALSE, 0 }, { ACCESSORFULLNAME("8"), BLOCKERFULLNAME("8"), FALSE, 0 }, { ACCESSORFULLNAME("9"), BLOCKERFULLNAME("9"), FALSE, 0 }, }; /* Thread entry points */ static void *blocker(void *arg); static void *accessor(void *arg); /* Utility functions */ static Bool addBlock(int fd, char const *filename); static Bool delBlock(int fd, char const *filename); static Bool listBlocks(int fd); #ifdef VMBLOCK_PURGE_FILEBLOCKS static Bool purgeBlocks(int fd); #endif static unsigned int getRand(unsigned int max); static void sighandler(int sig); pthread_mutex_t print_lock; /* *---------------------------------------------------------------------------- * * main -- * * Does all necessary setup then starts the blocker thread and continually * starts accessor threads. * * Results: * EXIT_SUCCESS and EXIT_FAILURE. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int main(int argc, char *argv[]) { int ret = EXIT_SUCCESS; int i; int blockFd; char *progname; pthread_t blockerThread; pthread_mutex_t filesLock; pthread_attr_t attr; ThreadInfo info; int count; progname = basename(argv[0]); pthread_mutex_init(&filesLock, NULL); SEM_INIT(); pthread_mutex_init(&print_lock, NULL); /* Open device user to add/delete blocks */ blockFd = open(CONTROLFILE, CONTROLFILE_MODE); if (blockFd < 0) { ERROR("%s: could not open " CONTROLFILE "\n", progname); exit(EXIT_FAILURE); } /* Provide ability to just list blocks */ if (argc > 1) { if (strcmp(argv[1], "-list") == 0) { listBlocks(blockFd); #ifdef VMBLOCK_PURGE_FILEBLOCKS } else if (strcmp(argv[1], "-purge") == 0) { purgeBlocks(blockFd); #endif } close(blockFd); exit(EXIT_SUCCESS); } /* Create directories/files used during test */ for (i = 0; i < sizeof files/sizeof files[0]; i++) { int err; struct stat statbuf; char buf[PATH_MAX]; err = stat(files[i].blockerName, &statbuf); if (!err) { if (S_ISDIR(statbuf.st_mode)) { goto create_file; } ERROR("%s: file [%s] already exists and is not a directory\n", progname, files[i].blockerName); goto exit_failure; } err = mkdir(files[i].blockerName, S_IRWXU | S_IRWXG); if (err) { ERROR("%s: could not create [%s]\n", progname, files[i].blockerName); goto exit_failure; } create_file: strncpy(buf, files[i].blockerName, sizeof buf); strncat(buf, FILENAME, sizeof buf - strlen(files[i].blockerName)); err = stat(buf, &statbuf); if (!err) { if (S_ISREG(statbuf.st_mode)) { continue; } ERROR("%s: file [%s] already exists and is not a regular file\n", progname, buf); goto exit_failure; } err = creat(buf, S_IRUSR | S_IRGRP); if (err < 0) { ERROR("%s: could not create [%s]\n", progname, buf); goto exit_failure; } continue; exit_failure: close(blockFd); exit(EXIT_FAILURE); } if (signal(SIGINT, sighandler) == SIG_ERR || signal(SIGTERM, sighandler) == SIG_ERR) { ERROR("%s: could not install signal handlers\n", progname); close(blockFd); exit(EXIT_FAILURE); } /* Seems cleaner than a bunch of globals ... */ info.blockFd = blockFd; info.lock = &filesLock; info.files = files; info.filesArraySize = sizeof files/sizeof files[0]; info.sleepTime = 1; /* * Start a thread that flips a random file's state, then sleeps for a while * and does it again. */ if (pthread_create(&blockerThread, NULL, blocker, &info)) { ERROR("%s: could not create blocker thread\n", progname); close(blockFd); exit(EXIT_FAILURE); } /* * Start a bunch of threads that try to open a random file, check its status * once they have it open (to make sure it is not blocked), then close it * and exit. */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); count = 0; while (!programQuit) { pthread_t thread; int rv; SEM_WAIT(); /* Create threads until we cannot anymore */ if ((rv = pthread_create(&thread, &attr, accessor, &info)) != 0) { SEM_POST(); if (rv == EAGAIN || rv == ENOMEM) { os_thread_yield(); continue; } ERROR("%s: could not create an accessor thread (%d total)\n", progname, count); ERROR("%s: pthread_create: %s\n", progname, strerror(rv)); ret = EXIT_FAILURE; break; } count++; } Log("%s: Not creating any more accessor threads.\n", progname); programQuit = TRUE; pthread_join(blockerThread, NULL); pthread_mutex_destroy(&filesLock); close(blockFd); Log("%s: Exiting with %s.\n", progname, ret == EXIT_SUCCESS ? "success" : "failure"); exit(ret); } /* *---------------------------------------------------------------------------- * * blocker -- * * Entry point for the single blocker thread. Continuously picks a file at * random and changes its state by adding or deleting a block on that file. * * Results: * EXIT_SUCCESS and EXIT_FAILURE. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void * blocker(void *arg) // IN { ThreadInfo *info = (ThreadInfo *)arg; unsigned int index; if (!info) { THREAD_ERROR("blocker: no thread info provided\n"); pthread_exit((void *)EXIT_FAILURE); } while (!programQuit) { index = getRand(info->filesArraySize - 1); pthread_mutex_lock(info->lock); if (info->files[index].blocked) { info->files[index].blocked = FALSE; if ( !delBlock(info->blockFd, info->files[index].blockerName) ) { THREAD_ERROR("blocker: could not delete block on [%s]\n", info->files[index].blockerName); goto error; } } else if (info->files[index].waiters == 0) { /* * Only add a new block if all previous waiters are done. This * ensures we don't get incorrect error messages from accessor threads * even though the open(2) and check are not atomic in the accessor. */ info->files[index].blocked = TRUE; if ( !addBlock(info->blockFd, info->files[index].blockerName) ) { THREAD_ERROR("blocker: could not add block on [%s]\n", info->files[index].blockerName); goto error; } } pthread_mutex_unlock(info->lock); sleep(info->sleepTime); } pthread_mutex_lock(info->lock); for (index = 0; index < info->filesArraySize; index++) { if (info->files[index].blocked) { info->files[index].blocked = FALSE; #ifndef TEST_CLOSE_FD THREAD_LOG("blocker: deleting block for [%s]\n", info->files[index].blockerName); if ( !delBlock(info->blockFd, info->files[index].blockerName) ) { THREAD_ERROR("blocker: could not delete existing block on exit for [%s]\n", info->files[index].blockerName); } #else THREAD_LOG("blocker: unmarking block for [%s], left for unblock on release\n", info->files[index].blockerName); #endif } } pthread_mutex_unlock(info->lock); pthread_exit(EXIT_SUCCESS); error: programQuit = TRUE; pthread_mutex_unlock(info->lock); pthread_exit((void *)EXIT_FAILURE); } /* *---------------------------------------------------------------------------- * * accessor -- * * Entry point for accessor threads. Picks a file at random and attempts to * open it. Once it is opened, ensures the state of the file is not blocked * and outputs an error message accordingly. * * Results: * EXIT_SUCCESS and EXIT_FAILURE. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void * accessor(void *arg) // IN { ThreadInfo *info = (ThreadInfo *)arg; unsigned int index; int fd; uintptr_t ret = EXIT_SUCCESS; PTHREAD_SEMAPHORE_CLEANUP(); if (!info) { THREAD_ERROR("blocker: no thread info provided\n"); pthread_exit((void *)EXIT_FAILURE); } index = getRand(info->filesArraySize - 1); /* * We can't hold the lock while calling open(2), since we will deadlock * waiting for the blocker thread to remove the block on the file. So, we * bump the waiter count to ensure that a new block is not placed on this * file until we have checked its state. This prevents incorrect error * messages that would happen if the blocker placed a new block on the file * between our open(2) call returning and acquiring the lock. * * The fact that we can't hold the lock through open(2) also means that it's * not atomic with respect to checking the file's blocked flag. Given this, * it's possible that we'll miss some errors if the block is removed after * open(2) returns but before we check the blocked flag -- hopefully running * this test for a very long time will be sufficient to catch these cases. * (Having the blocker sleep increases the likelihood of seeing such * errors.) */ pthread_mutex_lock(info->lock); info->files[index].waiters++; pthread_mutex_unlock(info->lock); fd = open(info->files[index].accessorName, O_RDONLY); if (fd < 0) { if (errno == EMFILE) { /* We already have hit the maximum number of file descriptors */ pthread_mutex_lock(info->lock); info->files[index].waiters--; pthread_mutex_unlock(info->lock); pthread_exit((void *)EXIT_FAILURE); } THREAD_ERROR("accessor: could not open file [%s]\n", info->files[index].accessorName); THREAD_ERROR("accessor: open: %s\n", strerror(errno)); pthread_exit((void *)EXIT_FAILURE); } pthread_mutex_lock(info->lock); info->files[index].waiters--; if (info->files[index].blocked) { THREAD_ERROR("accessor: [ERROR] accessed file [%s] while blocked (%d)\n", info->files[index].accessorName, info->files[index].blocked); ret = EXIT_FAILURE; } pthread_mutex_unlock(info->lock); close(fd); pthread_exit((void *)ret); } /* *---------------------------------------------------------------------------- * * addBlock -- * * Adds a block on the specified filename. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * Future open(2)s on the file will block until delBlock() is called for * that file. * *---------------------------------------------------------------------------- */ static Bool addBlock(int fd, // IN: fd of control device char const *filename) // IN: filename to add block for { Log("Blocking [%s]\n", filename); return VMBLOCK_CONTROL(fd, VMBLOCK_ADD_FILEBLOCK, filename) == 0; } /* *---------------------------------------------------------------------------- * * delBlock -- * * Deletes a block on the specified filename. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * Previous open(2)s that had blocked will now complete. * *---------------------------------------------------------------------------- */ static Bool delBlock(int fd, // IN: fd of control device char const *filename) // IN: filename to delete block for { Log("Unblocking [%s]\n", filename); return VMBLOCK_CONTROL(fd, VMBLOCK_DEL_FILEBLOCK, filename) == 0; } /* *---------------------------------------------------------------------------- * * listBlocks -- * * Tells the kernel module to list all existing blocks. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static Bool listBlocks(int fd) // IN: fd of control device { Log("Listing blocks (check kernel log output)\n"); return VMBLOCK_CONTROL(fd, VMBLOCK_LIST_FILEBLOCKS, NULL) == 0; } #ifdef VMBLOCK_PURGE_FILEBLOCKS /* *---------------------------------------------------------------------------- * * purgeBlocks -- * * Tells the kernel module to purge all existing blocks, regardless of * who opened them. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static Bool purgeBlocks(int fd) // IN: fd of control device { Log("Purging all blocks\n"); return VMBLOCK_CONTROL(fd, VMBLOCK_PURGE_FILEBLOCKS, NULL) == 0; } #endif /* *---------------------------------------------------------------------------- * * getRand -- * * Retrieves the next random number within the range [0, max]. * * Results: * A random number. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static unsigned int getRand(unsigned int max) // IN: max value returnable { return random() % max; } /* *---------------------------------------------------------------------------- * * sighandler -- * * Sets the programQuit flag when a signal is received. * * Results: * None. * * Side effects: * Program will quit. * *---------------------------------------------------------------------------- */ static void sighandler(int sig) { programQuit = TRUE; } open-vm-tools-9.4.0-1280544/tests/testVmblock/COPYING0000644765153500003110000006347112220061556020144 0ustar dtormts GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! open-vm-tools-9.4.0-1280544/tests/testVmblock/Makefile.am0000644765153500003110000000302012220061556021125 0ustar dtormts################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_PROGRAMS = vmware-testvmblock-legacy noinst_PROGRAMS += vmware-testvmblock-manual-legacy if HAVE_FUSE noinst_PROGRAMS += vmware-testvmblock-fuse noinst_PROGRAMS += vmware-testvmblock-manual-fuse endif AM_CFLAGS = AM_CFLAGS += -DVMX86_DEVEL AM_CFLAGS += -DVMX86_DEBUG AM_LDFLAGS = AM_LDFLAGS += -lpthread vmware_testvmblock_legacy_SOURCES = vmblocktest.c vmware_testvmblock_manual_legacy_SOURCES = manual-blocker.c vmware_testvmblock_fuse_CFLAGS = $(AM_CFLAGS) -Dvmblock_fuse vmware_testvmblock_fuse_SOURCES = vmblocktest.c vmware_testvmblock_manual_fuse_CFLAGS = $(AM_CFLAGS) -Dvmblock_fuse vmware_testvmblock_manual_fuse_SOURCES = manual-blocker.c open-vm-tools-9.4.0-1280544/tests/testVmblock/manual-blocker.c0000644765153500003110000000541312220061556022141 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * manual-blocker.c -- * * A small test program for manually manipulating vmblock. */ #include #include #include #include #include #include #include #include "vmblock_user.h" /* *----------------------------------------------------------------------------- * * main -- * * Takes the target file to block as a command line arg. Sits in a loop * waiting for commands. * * Results: * Returns 0 on success and nonzero on failure. * * Side effects: * None/all. * *----------------------------------------------------------------------------- */ int main(int argc, char *argv[]) { int status; char op; if (argc < 2 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { printf("Usage: %s \n", argv[0]); puts("a to Add a block, d to Delete a block, or l to List blocks (to" " vmblock's log).\n"); return 1; } int fd = open(VMBLOCK_DEVICE, VMBLOCK_DEVICE_MODE); if (fd <= 0) { perror("open"); return 2; } printf("Opened " VMBLOCK_DEVICE " as fd %d.\n", fd); while (1) { op = getchar(); if (op == 'a') { status = VMBLOCK_CONTROL(fd, VMBLOCK_ADD_FILEBLOCK, argv[1]); if (status != 0) { perror(NULL); } else { printf("%s blocked.\n", argv[1]); } } else if (op == 'd') { status = VMBLOCK_CONTROL(fd, VMBLOCK_DEL_FILEBLOCK, argv[1]); if (status != 0) { perror(NULL); } else { printf("%s unblocked.\n", argv[1]); } } else if (op == 'l') { status = VMBLOCK_CONTROL(fd, VMBLOCK_LIST_FILEBLOCKS, argv[1]); if (status != 0) { perror(NULL); } else { printf("Check vmblock's log for list of blocks.\n"); } } } return 0; } open-vm-tools-9.4.0-1280544/tests/testVmblock/Makefile.in0000644765153500003110000006314712220061625021153 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ noinst_PROGRAMS = vmware-testvmblock-legacy$(EXEEXT) \ vmware-testvmblock-manual-legacy$(EXEEXT) $(am__EXEEXT_1) @HAVE_FUSE_TRUE@am__append_1 = vmware-testvmblock-fuse \ @HAVE_FUSE_TRUE@ vmware-testvmblock-manual-fuse subdir = tests/testVmblock DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @HAVE_FUSE_TRUE@am__EXEEXT_1 = vmware-testvmblock-fuse$(EXEEXT) \ @HAVE_FUSE_TRUE@ vmware-testvmblock-manual-fuse$(EXEEXT) PROGRAMS = $(noinst_PROGRAMS) am_vmware_testvmblock_fuse_OBJECTS = \ vmware_testvmblock_fuse-vmblocktest.$(OBJEXT) vmware_testvmblock_fuse_OBJECTS = \ $(am_vmware_testvmblock_fuse_OBJECTS) vmware_testvmblock_fuse_LDADD = $(LDADD) vmware_testvmblock_fuse_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(vmware_testvmblock_fuse_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am_vmware_testvmblock_legacy_OBJECTS = vmblocktest.$(OBJEXT) vmware_testvmblock_legacy_OBJECTS = \ $(am_vmware_testvmblock_legacy_OBJECTS) vmware_testvmblock_legacy_LDADD = $(LDADD) am_vmware_testvmblock_manual_fuse_OBJECTS = \ vmware_testvmblock_manual_fuse-manual-blocker.$(OBJEXT) vmware_testvmblock_manual_fuse_OBJECTS = \ $(am_vmware_testvmblock_manual_fuse_OBJECTS) vmware_testvmblock_manual_fuse_LDADD = $(LDADD) vmware_testvmblock_manual_fuse_LINK = $(LIBTOOL) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(vmware_testvmblock_manual_fuse_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ am_vmware_testvmblock_manual_legacy_OBJECTS = \ manual-blocker.$(OBJEXT) vmware_testvmblock_manual_legacy_OBJECTS = \ $(am_vmware_testvmblock_manual_legacy_OBJECTS) vmware_testvmblock_manual_legacy_LDADD = $(LDADD) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(vmware_testvmblock_fuse_SOURCES) \ $(vmware_testvmblock_legacy_SOURCES) \ $(vmware_testvmblock_manual_fuse_SOURCES) \ $(vmware_testvmblock_manual_legacy_SOURCES) DIST_SOURCES = $(vmware_testvmblock_fuse_SOURCES) \ $(vmware_testvmblock_legacy_SOURCES) \ $(vmware_testvmblock_manual_fuse_SOURCES) \ $(vmware_testvmblock_manual_legacy_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CFLAGS = -DVMX86_DEVEL -DVMX86_DEBUG AM_LDFLAGS = -lpthread vmware_testvmblock_legacy_SOURCES = vmblocktest.c vmware_testvmblock_manual_legacy_SOURCES = manual-blocker.c vmware_testvmblock_fuse_CFLAGS = $(AM_CFLAGS) -Dvmblock_fuse vmware_testvmblock_fuse_SOURCES = vmblocktest.c vmware_testvmblock_manual_fuse_CFLAGS = $(AM_CFLAGS) -Dvmblock_fuse vmware_testvmblock_manual_fuse_SOURCES = manual-blocker.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/testVmblock/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/testVmblock/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list vmware-testvmblock-fuse$(EXEEXT): $(vmware_testvmblock_fuse_OBJECTS) $(vmware_testvmblock_fuse_DEPENDENCIES) $(EXTRA_vmware_testvmblock_fuse_DEPENDENCIES) @rm -f vmware-testvmblock-fuse$(EXEEXT) $(vmware_testvmblock_fuse_LINK) $(vmware_testvmblock_fuse_OBJECTS) $(vmware_testvmblock_fuse_LDADD) $(LIBS) vmware-testvmblock-legacy$(EXEEXT): $(vmware_testvmblock_legacy_OBJECTS) $(vmware_testvmblock_legacy_DEPENDENCIES) $(EXTRA_vmware_testvmblock_legacy_DEPENDENCIES) @rm -f vmware-testvmblock-legacy$(EXEEXT) $(LINK) $(vmware_testvmblock_legacy_OBJECTS) $(vmware_testvmblock_legacy_LDADD) $(LIBS) vmware-testvmblock-manual-fuse$(EXEEXT): $(vmware_testvmblock_manual_fuse_OBJECTS) $(vmware_testvmblock_manual_fuse_DEPENDENCIES) $(EXTRA_vmware_testvmblock_manual_fuse_DEPENDENCIES) @rm -f vmware-testvmblock-manual-fuse$(EXEEXT) $(vmware_testvmblock_manual_fuse_LINK) $(vmware_testvmblock_manual_fuse_OBJECTS) $(vmware_testvmblock_manual_fuse_LDADD) $(LIBS) vmware-testvmblock-manual-legacy$(EXEEXT): $(vmware_testvmblock_manual_legacy_OBJECTS) $(vmware_testvmblock_manual_legacy_DEPENDENCIES) $(EXTRA_vmware_testvmblock_manual_legacy_DEPENDENCIES) @rm -f vmware-testvmblock-manual-legacy$(EXEEXT) $(LINK) $(vmware_testvmblock_manual_legacy_OBJECTS) $(vmware_testvmblock_manual_legacy_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/manual-blocker.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmblocktest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmware_testvmblock_fuse-vmblocktest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmware_testvmblock_manual_fuse-manual-blocker.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< vmware_testvmblock_fuse-vmblocktest.o: vmblocktest.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_testvmblock_fuse_CFLAGS) $(CFLAGS) -MT vmware_testvmblock_fuse-vmblocktest.o -MD -MP -MF $(DEPDIR)/vmware_testvmblock_fuse-vmblocktest.Tpo -c -o vmware_testvmblock_fuse-vmblocktest.o `test -f 'vmblocktest.c' || echo '$(srcdir)/'`vmblocktest.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmware_testvmblock_fuse-vmblocktest.Tpo $(DEPDIR)/vmware_testvmblock_fuse-vmblocktest.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vmblocktest.c' object='vmware_testvmblock_fuse-vmblocktest.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_testvmblock_fuse_CFLAGS) $(CFLAGS) -c -o vmware_testvmblock_fuse-vmblocktest.o `test -f 'vmblocktest.c' || echo '$(srcdir)/'`vmblocktest.c vmware_testvmblock_fuse-vmblocktest.obj: vmblocktest.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_testvmblock_fuse_CFLAGS) $(CFLAGS) -MT vmware_testvmblock_fuse-vmblocktest.obj -MD -MP -MF $(DEPDIR)/vmware_testvmblock_fuse-vmblocktest.Tpo -c -o vmware_testvmblock_fuse-vmblocktest.obj `if test -f 'vmblocktest.c'; then $(CYGPATH_W) 'vmblocktest.c'; else $(CYGPATH_W) '$(srcdir)/vmblocktest.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmware_testvmblock_fuse-vmblocktest.Tpo $(DEPDIR)/vmware_testvmblock_fuse-vmblocktest.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vmblocktest.c' object='vmware_testvmblock_fuse-vmblocktest.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_testvmblock_fuse_CFLAGS) $(CFLAGS) -c -o vmware_testvmblock_fuse-vmblocktest.obj `if test -f 'vmblocktest.c'; then $(CYGPATH_W) 'vmblocktest.c'; else $(CYGPATH_W) '$(srcdir)/vmblocktest.c'; fi` vmware_testvmblock_manual_fuse-manual-blocker.o: manual-blocker.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_testvmblock_manual_fuse_CFLAGS) $(CFLAGS) -MT vmware_testvmblock_manual_fuse-manual-blocker.o -MD -MP -MF $(DEPDIR)/vmware_testvmblock_manual_fuse-manual-blocker.Tpo -c -o vmware_testvmblock_manual_fuse-manual-blocker.o `test -f 'manual-blocker.c' || echo '$(srcdir)/'`manual-blocker.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmware_testvmblock_manual_fuse-manual-blocker.Tpo $(DEPDIR)/vmware_testvmblock_manual_fuse-manual-blocker.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='manual-blocker.c' object='vmware_testvmblock_manual_fuse-manual-blocker.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_testvmblock_manual_fuse_CFLAGS) $(CFLAGS) -c -o vmware_testvmblock_manual_fuse-manual-blocker.o `test -f 'manual-blocker.c' || echo '$(srcdir)/'`manual-blocker.c vmware_testvmblock_manual_fuse-manual-blocker.obj: manual-blocker.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_testvmblock_manual_fuse_CFLAGS) $(CFLAGS) -MT vmware_testvmblock_manual_fuse-manual-blocker.obj -MD -MP -MF $(DEPDIR)/vmware_testvmblock_manual_fuse-manual-blocker.Tpo -c -o vmware_testvmblock_manual_fuse-manual-blocker.obj `if test -f 'manual-blocker.c'; then $(CYGPATH_W) 'manual-blocker.c'; else $(CYGPATH_W) '$(srcdir)/manual-blocker.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmware_testvmblock_manual_fuse-manual-blocker.Tpo $(DEPDIR)/vmware_testvmblock_manual_fuse-manual-blocker.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='manual-blocker.c' object='vmware_testvmblock_manual_fuse-manual-blocker.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_testvmblock_manual_fuse_CFLAGS) $(CFLAGS) -c -o vmware_testvmblock_manual_fuse-manual-blocker.obj `if test -f 'manual-blocker.c'; then $(CYGPATH_W) 'manual-blocker.c'; else $(CYGPATH_W) '$(srcdir)/manual-blocker.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstPROGRAMS cscopelist ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/tests/testDebug/0000755765153500003110000000000012220061625016524 5ustar dtormtsopen-vm-tools-9.4.0-1280544/tests/testDebug/COPYING0000644765153500003110000006347112220061556017575 0ustar dtormts GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! open-vm-tools-9.4.0-1280544/tests/testDebug/Makefile.am0000644765153500003110000000356112220061556020570 0ustar dtormts################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ plugindir = @TEST_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libtestDebug.la libtestDebug_la_CPPFLAGS = libtestDebug_la_CPPFLAGS += @CUNIT_CPPFLAGS@ libtestDebug_la_CPPFLAGS += @GOBJECT_CPPFLAGS@ libtestDebug_la_CPPFLAGS += @PLUGIN_CPPFLAGS@ libtestDebug_la_LDFLAGS = libtestDebug_la_LDFLAGS += @PLUGIN_LDFLAGS@ libtestDebug_la_LIBADD = libtestDebug_la_LIBADD += @CUNIT_LIBS@ libtestDebug_la_LIBADD += @GOBJECT_LIBS@ libtestDebug_la_LIBADD += @VMTOOLS_LIBS@ libtestDebug_la_LIBADD += ../vmrpcdbg/libvmrpcdbg.la libtestDebug_la_SOURCES = libtestDebug_la_SOURCES += testDebug.c libtestDebug_la_SOURCES += testData_xdr.c BUILT_SOURCES = BUILT_SOURCES += testData_xdr.c BUILT_SOURCES += testData.h # XXX: see explanation in lib/guestRpc/Makefile.am CFLAGS += -Wno-unused CLEANFILES = CLEANFILES += testData_xdr.c CLEANFILES += testData.h testData.h: $(top_srcdir)/tests/testPlugin/testData.x @RPCGEN_WRAPPER@ tests/testPlugin/testData.x $@ testData_xdr.c: testData.h @RPCGEN_WRAPPER@ tests/testPlugin/testData.x $@ open-vm-tools-9.4.0-1280544/tests/testDebug/testDebug.c0000644765153500003110000002046512220061556020630 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file testDebug.c * * A simple debug plugin that validates the messages sent by the service after * a "reset" is received, and also interacts with the test plugin to test the * functions provided by the service. */ #define G_LOG_DOMAIN "testDebug" #include #include #include "util.h" #include "testData.h" #include "xdrutil.h" #include "vmware/guestrpc/tclodefs.h" #include "vmware/tools/rpcdebug.h" static gboolean TestDebugValidateReset(RpcInData *data, gboolean ret); static gboolean TestDebugValidateUnknown(RpcInData *data, gboolean ret); static gboolean TestDebugValidateRpc3(RpcInData *data, gboolean ret); #define SET_OPTION_TEST ("Set_Option " TOOLSOPTION_BROADCASTIP " 1") /** RPC messages injected into the application using RpcDebug_SendNext(). */ static RpcDebugMsgMapping gRpcMessages[] = { { "reset", sizeof "reset", TestDebugValidateReset, FALSE }, { "ping", sizeof "ping", NULL, FALSE }, { "Capabilities_Register", sizeof "Capabilities_Register", NULL, FALSE }, { "test.rpcin.unknown", sizeof "test.rpcin.unknown", TestDebugValidateUnknown, FALSE }, /* This one is initialized manually, since it contains dynamic data. */ { NULL, 0, NULL, TRUE }, { "test.rpcin.msg2", sizeof "test.rpcin.msg2", NULL, FALSE }, { "test.rpcin.msg3", sizeof "test.rpcin.msg3", TestDebugValidateRpc3, FALSE }, { SET_OPTION_TEST, sizeof SET_OPTION_TEST, NULL, FALSE }, { "Capabilities_Register", sizeof "Capabilities_Register", NULL, FALSE }, /* NULL terminator. */ { NULL, 0, NULL, FALSE } }; static gboolean gSignalReceived = FALSE; static ToolsAppCtx *gCtx; /** * Handles a "test-signal" sent by the test plugin. Just sets a static variable * that will be checked by TestDebugReceiveRpc1 to make sure custom signals are * working. * * @param[in] src Unused. * @param[in] data Unused. */ static void TestDebugHandleSignal(gpointer src, gpointer data) { g_debug("Received test signal.\n"); gSignalReceived = TRUE; } /** * Validates the response from a "reset". * * @param[in] data RPC request data. * @param[in] ret Return value from RPC handler. * * @return @a ret. */ static gboolean TestDebugValidateReset(RpcInData *data, gboolean ret) { RPCDEBUG_ASSERT(data->result != NULL, FALSE); CU_ASSERT_STRING_EQUAL(data->result, "ATR debug"); return (gboolean) ret; } /** * Validates a "test.rpcout.msg1" message sent by the test plugin. This message * is sent when the plugin receives a "test.rpcin.msg1" RPC, and contains an * XDR-encoded TestPluginData struct. * * @param[in] data Incoming data. * @param[in] dataLen Size of incoming data. * @param[out] result Result sent back to the application. * @param[out] resultLen Length of result. * * @return TRUE (asserts on failure). */ static gboolean TestDebugReceiveRpc1(char *data, size_t dataLen, char **result, size_t *resultLen) { TestPluginData *details = (TestPluginData *) data; CU_ASSERT(gSignalReceived); CU_ASSERT_STRING_EQUAL(details->data, "rpc1test"); CU_ASSERT_EQUAL(details->f_int, 1357); CU_ASSERT(details->f_bool); return TRUE; } /** * Validates the response of the "msg3" RPC. * * @param[in] data RPC data. * @param[in] ret RPC result. * * @return Whether the RPC succeded. */ static gboolean TestDebugValidateRpc3(RpcInData *data, gboolean ret) { TestPluginData pdata = { NULL, }; CU_ASSERT(XdrUtil_Deserialize(data->result, data->resultLen, xdr_TestPluginData, &pdata)); CU_ASSERT_STRING_EQUAL(pdata.data, "Hello World!"); CU_ASSERT_EQUAL(pdata.f_int, 8642); CU_ASSERT(pdata.f_bool); VMX_XDR_FREE(xdr_TestPluginData, &pdata); return ret; } /** * Validates a "version" message sent during capability registration. * No validation is actually done - the message is just printed. * * @param[in] data Incoming data. * @param[in] dataLen Size of incoming data. * @param[out] result Result sent back to the application. * @param[out] resultLen Length of result. * * @return TRUE. */ static gboolean TestDebugReceiveVersion(char *data, size_t dataLen, char **result, size_t *resultLen) { g_debug("Received tools version message: %s\n", data); RpcDebug_SetResult("", result, resultLen); return TRUE; } /** * Validates the results for an unknown RPC sent to the guest. * * @param[in] data RPC request data. * @param[in] ret Return value from RPC handler. * * @return The opposite of @a ret. */ static gboolean TestDebugValidateUnknown(RpcInData *data, gboolean ret) { CU_ASSERT_STRING_EQUAL(data->result, "Unknown Command"); return !ret; } /** * Populates the RPC request data with the next message in the queue. * * @param[in] rpcdata Data for the injected RPC request data. * * @return TRUE if sending messages, FALSE if no more messages to be sent. */ static gboolean TestDebugSendNext(RpcDebugMsgMapping *rpcdata) { static RpcDebugMsgList msgList = { gRpcMessages, 0 }; if (!RpcDebug_SendNext(rpcdata, &msgList)) { /* * Test for bug 391553: send two resets in sequence without * pumping the main loop. The channel should handle the second * reset successfully instead of asserting. */ int i; for (i = 0; i < 2; i++) { RpcInData data; memset(&data, 0, sizeof data); data.clientData = gCtx->rpc; data.appCtx = gCtx; data.args = "reset"; data.argsSize = sizeof "reset"; g_debug("reset test %d\n", i + 1); RpcChannel_Dispatch(&data); } return FALSE; } return TRUE; } /** * Returns the debug plugin's registration data. * * @param[in] ctx The application context. * * @return The application data. */ TOOLS_MODULE_EXPORT RpcDebugPlugin * RpcDebugOnLoad(ToolsAppCtx *ctx) { static RpcDebugRecvMapping recvFns[] = { { "tools.set.version", TestDebugReceiveVersion, NULL, 0 }, { "test.rpcout.msg1", TestDebugReceiveRpc1, xdr_TestPluginData, sizeof (TestPluginData) }, { NULL, NULL } }; static ToolsPluginData pluginData = { "testDebug", NULL, NULL, NULL, }; static RpcDebugPlugin regData = { recvFns, NULL, TestDebugSendNext, NULL, &pluginData, }; /* Standard plugin interface, used to listen for signals. */ { ToolsPluginSignalCb sigs[] = { { "test-signal", TestDebugHandleSignal, NULL }, }; ToolsAppReg regs[] = { { TOOLS_APP_SIGNALS, VMTOOLS_WRAP_ARRAY(sigs) }, }; pluginData.regs = VMTOOLS_WRAP_ARRAY(regs); } /* Initialize the paylod of the "test.rpcin.msg1" RPC. */ { TestPluginData testdata; testdata.data = "rpc1test"; testdata.f_int = 1357; testdata.f_bool = TRUE; /* Build the command for the "test.rpcin.msg1" RPC. */ if (!RpcChannel_BuildXdrCommand("test.rpcin.msg1", xdr_TestPluginData, &testdata, &gRpcMessages[4].message, &gRpcMessages[4].messageLen)) { g_error("Failed to create test.rpcin.msg1 command.\n"); } } gCtx = ctx; return ®Data; } open-vm-tools-9.4.0-1280544/tests/testDebug/Makefile.in0000644765153500003110000005721412220061625020602 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tests/testDebug DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(plugin_LTLIBRARIES) libtestDebug_la_DEPENDENCIES = ../vmrpcdbg/libvmrpcdbg.la am_libtestDebug_la_OBJECTS = libtestDebug_la-testDebug.lo \ libtestDebug_la-testData_xdr.lo libtestDebug_la_OBJECTS = $(am_libtestDebug_la_OBJECTS) libtestDebug_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libtestDebug_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libtestDebug_la_SOURCES) DIST_SOURCES = $(libtestDebug_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ # XXX: see explanation in lib/guestRpc/Makefile.am CFLAGS = @CFLAGS@ -Wno-unused COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ plugindir = @TEST_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libtestDebug.la libtestDebug_la_CPPFLAGS = @CUNIT_CPPFLAGS@ @GOBJECT_CPPFLAGS@ \ @PLUGIN_CPPFLAGS@ $(am__empty) libtestDebug_la_LDFLAGS = @PLUGIN_LDFLAGS@ libtestDebug_la_LIBADD = @CUNIT_LIBS@ @GOBJECT_LIBS@ @VMTOOLS_LIBS@ \ ../vmrpcdbg/libvmrpcdbg.la libtestDebug_la_SOURCES = testDebug.c testData_xdr.c BUILT_SOURCES = testData_xdr.c testData.h CLEANFILES = testData_xdr.c testData.h all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/testDebug/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/testDebug/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ } uninstall-pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ done clean-pluginLTLIBRARIES: -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) @list='$(plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libtestDebug.la: $(libtestDebug_la_OBJECTS) $(libtestDebug_la_DEPENDENCIES) $(EXTRA_libtestDebug_la_DEPENDENCIES) $(libtestDebug_la_LINK) -rpath $(plugindir) $(libtestDebug_la_OBJECTS) $(libtestDebug_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtestDebug_la-testData_xdr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtestDebug_la-testDebug.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libtestDebug_la-testDebug.lo: testDebug.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestDebug_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtestDebug_la-testDebug.lo -MD -MP -MF $(DEPDIR)/libtestDebug_la-testDebug.Tpo -c -o libtestDebug_la-testDebug.lo `test -f 'testDebug.c' || echo '$(srcdir)/'`testDebug.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtestDebug_la-testDebug.Tpo $(DEPDIR)/libtestDebug_la-testDebug.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testDebug.c' object='libtestDebug_la-testDebug.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestDebug_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtestDebug_la-testDebug.lo `test -f 'testDebug.c' || echo '$(srcdir)/'`testDebug.c libtestDebug_la-testData_xdr.lo: testData_xdr.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestDebug_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtestDebug_la-testData_xdr.lo -MD -MP -MF $(DEPDIR)/libtestDebug_la-testData_xdr.Tpo -c -o libtestDebug_la-testData_xdr.lo `test -f 'testData_xdr.c' || echo '$(srcdir)/'`testData_xdr.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtestDebug_la-testData_xdr.Tpo $(DEPDIR)/libtestDebug_la-testData_xdr.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testData_xdr.c' object='libtestDebug_la-testData_xdr.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestDebug_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtestDebug_la-testData_xdr.lo `test -f 'testData_xdr.c' || echo '$(srcdir)/'`testData_xdr.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(plugindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pluginLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pluginLTLIBRARIES .MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-pluginLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-pluginLTLIBRARIES install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-pluginLTLIBRARIES testData.h: $(top_srcdir)/tests/testPlugin/testData.x @RPCGEN_WRAPPER@ tests/testPlugin/testData.x $@ testData_xdr.c: testData.h @RPCGEN_WRAPPER@ tests/testPlugin/testData.x $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/tests/Makefile.am0000644765153500003110000000211212220061556016631 0ustar dtormts################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ SUBDIRS = SUBDIRS += vmrpcdbg SUBDIRS += testDebug SUBDIRS += testPlugin SUBDIRS += testVmblock install-exec-local: rm -f $(DESTDIR)$(TEST_PLUGIN_INSTALLDIR)/*.a rm -f $(DESTDIR)$(TEST_PLUGIN_INSTALLDIR)/*.la open-vm-tools-9.4.0-1280544/tests/vmrpcdbg/0000755765153500003110000000000012220061625016402 5ustar dtormtsopen-vm-tools-9.4.0-1280544/tests/vmrpcdbg/vmrpcdbgInt.h0000644765153500003110000000223512220061556021037 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _VMRPCDBGINT_H_ #define _VMRPCDBGINT_H_ /** * @file vmrpcdbgInt.h * * Internal definitions for the vmrpcdbg library. */ #include "vmware/tools/rpcdebug.h" RpcChannel * RpcDebug_NewDebugChannel(ToolsAppCtx *ctx, RpcDebugLibData *data); #endif /* _VMRPCDBGINT_H_ */ open-vm-tools-9.4.0-1280544/tests/vmrpcdbg/COPYING0000644765153500003110000006347112220061556017453 0ustar dtormts GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! open-vm-tools-9.4.0-1280544/tests/vmrpcdbg/vmrpcdbg.c0000644765153500003110000001547312220061556020367 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file vmrpcdbg.c * * Implementation of the library functions not related to the RPC channel. */ #define G_LOG_DOMAIN "rpcdbg" #include #include "CUnit/Basic.h" #include #include "util.h" #include "vmrpcdbgInt.h" #include "embed_version.h" #include "vmtoolsd_version.h" VM_EMBED_VERSION(VMTOOLSD_VERSION_STRING); static GModule *gPlugin = NULL; /* * Static variables to hold the app's main loop data. CUnit test functions * don't take any parameters so there's no other way to do this... */ static struct { void (*mainLoop)(gpointer); gpointer loopData; RpcDebugLibData *libData; ToolsAppCtx *ctx; gint refCount; } gLibRunData; /* ****************************************************************************** * RpcDebugRunLoop -- */ /** * * Runs the app's main loop as part of a CUnit test. * ****************************************************************************** */ static void RpcDebugRunLoop(void) { ASSERT(gLibRunData.libData); ASSERT(gLibRunData.mainLoop); ASSERT(gLibRunData.loopData); gLibRunData.mainLoop(gLibRunData.loopData); if (gLibRunData.libData->debugPlugin->shutdownFn != NULL) { gLibRunData.libData->debugPlugin->shutdownFn(gLibRunData.ctx, gLibRunData.libData->debugPlugin); } } /* ****************************************************************************** * RpcDebugRun -- */ /** * * Runs the main application's main loop function through CUnit so that we * get all the test tracking / reporting goodness that it provides. * * @param[in] runMainLoop A function that runs the application's main loop. * The function should take one argument, * @param[in] runData Argument to be passed to the main loop function. * @param[in] ldata Debug library data. * * @return CUnit test run result (cast to int). * ****************************************************************************** */ static int RpcDebugRun(ToolsAppCtx *ctx, gpointer runMainLoop, gpointer runData, RpcDebugLibData *ldata) { CU_ErrorCode err; CU_Suite *suite; CU_Test *test; ASSERT(runMainLoop != NULL); ASSERT(ldata != NULL); err = CU_initialize_registry(); ASSERT(err == CUE_SUCCESS); suite = CU_add_suite(g_module_name(gPlugin), NULL, NULL); ASSERT(suite != NULL); test = CU_add_test(suite, g_module_name(gPlugin), RpcDebugRunLoop); ASSERT_NOT_IMPLEMENTED(test != NULL); gLibRunData.ctx = ctx; gLibRunData.libData = ldata; gLibRunData.mainLoop = runMainLoop; gLibRunData.loopData = runData; err = CU_basic_run_tests(); /* Clean up internal library / debug plugin state. */ ASSERT(g_atomic_int_get(&gLibRunData.refCount) >= 0); if (gPlugin != NULL) { g_module_close(gPlugin); gPlugin = NULL; } if (CU_get_failure_list() != NULL) { err = 1; } CU_cleanup_registry(); memset(&gLibRunData, 0, sizeof gLibRunData); return (int) err; } /** * Decreases the internal ref count of the library. When the ref count reaches * zero, this function will ask the application's main loop to stop running. * * @param[in] ctx The application contexnt. */ void RpcDebug_DecRef(ToolsAppCtx *ctx) { if (g_atomic_int_dec_and_test(&gLibRunData.refCount)) { g_main_loop_quit(ctx->mainLoop); } } /** * Increases the internal ref count of the library. Test code that needs the * process to stay alive should call this function to ensure that. */ void RpcDebug_IncRef(void) { g_atomic_int_inc(&gLibRunData.refCount); } /** * Initializes the debug library and loads the debug plugin at the given path. * This function panics if something goes wrong. * * @param[in] ctx The application context. * @param[in] dbgPlugin Path to the debug plugin. * * @return Structure containing the debug library's information. */ RpcDebugLibData * RpcDebug_Initialize(ToolsAppCtx *ctx, gchar *dbgPlugin) { RpcDebugOnLoadFn onload; RpcDebugLibData *ldata; ASSERT(gPlugin == NULL); ldata = g_malloc(sizeof *ldata); gPlugin = g_module_open(dbgPlugin, G_MODULE_BIND_LOCAL); if (gPlugin == NULL) { g_error("Can't load plugin: %s\n", dbgPlugin); } if (!g_module_symbol(gPlugin, "RpcDebugOnLoad", (gpointer *) &onload)) { g_error("No entry point in debug plugin %s\n", dbgPlugin); } ldata->debugPlugin = onload(ctx); if (ldata->debugPlugin == NULL) { g_error("No registration data from plugin %s\n", dbgPlugin); } ldata->newDebugChannel = RpcDebug_NewDebugChannel; ldata->run = RpcDebugRun; return ldata; } /** * Places the next item on the given RPC message list into the given RPC data. * Updates the current index of the list. * * @param[in] rpcdata The injected RPC data. * @param[in] list The message list. * * @return TRUE if updated the RPC data, FALSE if reached the end of the list. */ gboolean RpcDebug_SendNext(RpcDebugMsgMapping *rpcdata, RpcDebugMsgList *list) { if (list->mappings[list->index].message != NULL) { rpcdata->message = list->mappings[list->index].message; rpcdata->messageLen = list->mappings[list->index].messageLen; rpcdata->validateFn = list->mappings[list->index].validateFn; rpcdata->freeMsg = list->mappings[list->index].freeMsg; list->index++; return TRUE; } return FALSE; } /** * Sets @a res / @a len when responding to an RPC. * * @param[in] str The string to set. * @param[out] res Where to store the result. * @param[out] len Where to store the length. */ void RpcDebug_SetResult(const char *str, char **res, size_t *len) { if (res != NULL) { *res = Util_SafeStrdup(str); } if (len != NULL) { *len = strlen(str); } } open-vm-tools-9.4.0-1280544/tests/vmrpcdbg/Makefile.am0000644765153500003110000000263512220061556020447 0ustar dtormts################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libvmrpcdbg.la libvmrpcdbg_la_CPPFLAGS = libvmrpcdbg_la_CPPFLAGS += @CUNIT_CPPFLAGS@ libvmrpcdbg_la_CPPFLAGS += @GMODULE_CPPFLAGS@ libvmrpcdbg_la_CPPFLAGS += @VMTOOLS_CPPFLAGS@ libvmrpcdbg_la_LDFLAGS = libvmrpcdbg_la_LDFLAGS += @PLUGIN_LDFLAGS@ libvmrpcdbg_la_LIBADD = libvmrpcdbg_la_LIBADD += @CUNIT_LIBS@ libvmrpcdbg_la_LIBADD += @GMODULE_LIBS@ libvmrpcdbg_la_LIBADD += @VMTOOLS_LIBS@ libvmrpcdbg_la_LIBADD += @XDR_LIBS@ libvmrpcdbg_la_SOURCES = libvmrpcdbg_la_SOURCES += debugChannel.c libvmrpcdbg_la_SOURCES += vmrpcdbg.c open-vm-tools-9.4.0-1280544/tests/vmrpcdbg/debugChannel.c0000644765153500003110000002105612220061556021134 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file debugChannel.c * * Implements an RPC Channel that is backed by a "debug plugin". The plugin * provides information about what data should be "read" by the RPC Channel, * and sinks for the data the application writes to the channel, so that the * plugin can perform validation. */ #define G_LOG_DOMAIN "rpcdbg" #include #include "strutil.h" #include "util.h" #include "vmrpcdbgInt.h" #include "vmxrpc.h" #include "xdrutil.h" #include "vmware/tools/utils.h" typedef struct DbgChannelData { ToolsAppCtx *ctx; gboolean hasLibRef; RpcDebugPlugin *plugin; GSource *msgTimer; } DbgChannelData; /** * Reads one RPC from the plugin and dispatches it to the application. * This function will ask the service process to stop running if a * failure occurs, where failure is defined either by the validation * function returning FALSE, or, if no validation function is provided, * the application's callback returning FALSE. * * @param[in] _chan The RPC channel instance. * * @return TRUE if the callback should continue to be scheduled. */ static gboolean RpcDebugDispatch(gpointer _chan) { gboolean ret; RpcChannel *chan = _chan; DbgChannelData *cdata = chan->_private; RpcDebugPlugin *plugin = cdata->plugin; RpcInData data; RpcDebugMsgMapping rpcdata; memset(&data, 0, sizeof data); memset(&rpcdata, 0, sizeof rpcdata); if (plugin->sendFn == NULL || !plugin->sendFn(&rpcdata)) { RpcDebug_DecRef(cdata->ctx); cdata->hasLibRef = FALSE; return FALSE; } else if (rpcdata.message == NULL) { /* * Nothing to send. Maybe the debug plugin is waiting for something to * happen before sending another message. */ return TRUE; } data.clientData = chan; data.appCtx = cdata->ctx; data.args = rpcdata.message; data.argsSize = rpcdata.messageLen; ret = RpcChannel_Dispatch(&data); if (rpcdata.validateFn != NULL) { ret = rpcdata.validateFn(&data, ret); } else if (!ret) { g_debug("RpcChannel_Dispatch returned error for RPC.\n"); } if (data.freeResult) { vm_free(data.result); } if (rpcdata.freeMsg) { vm_free(rpcdata.message); } if (!ret) { VMTOOLSAPP_ERROR(cdata->ctx, 1); RpcDebug_DecRef(cdata->ctx); cdata->hasLibRef = FALSE; return FALSE; } return TRUE; } /** * Starts sending data to the service. The function will send one RPC * approximately every 100ms, to somewhat mimic the behavior of the * backdoor-based channel. * * @param[in] chan The RPC channel instance. * * @return TRUE. */ static gboolean RpcDebugStart(RpcChannel *chan) { DbgChannelData *data = chan->_private; ASSERT(data->ctx != NULL); ASSERT(data->msgTimer == NULL); data->msgTimer = g_timeout_source_new(100); VMTOOLSAPP_ATTACH_SOURCE(data->ctx, data->msgTimer, RpcDebugDispatch, chan, NULL); return TRUE; } /** * Stops the channel; cancel the timer that sends polls the debug plugin for * messages to send. * * @param[in] chan Unused. */ static void RpcDebugStop(RpcChannel *chan) { DbgChannelData *data = chan->_private; if (data->msgTimer != NULL) { g_source_unref(data->msgTimer); data->msgTimer = NULL; } } /** * Sends the given data to the plugin. This function tries to parse the * incoming data based on the "cmd args" convention, and call the "receive" * function provided by the debug plugin. * * @param[in] chan The RPC channel instance. * @param[in] data Data to send. * @param[in] dataLen Number of bytes to send. * @param[out] result Response from other side. * @param[out] resultLen Number of bytes in response. * * @return The result from the plugin's validation function, or TRUE if * a validation function was not provided. */ static gboolean RpcDebugSend(RpcChannel *chan, char const *data, size_t dataLen, char **result, size_t *resultLen) { char *copy; gpointer xdrdata = NULL; DbgChannelData *cdata = chan->_private; RpcDebugPlugin *plugin = cdata->plugin; RpcDebugRecvMapping *mapping = NULL; RpcDebugRecvFn recvFn = NULL; gboolean ret = TRUE; ASSERT(cdata->ctx != NULL); /* Be paranoid. Like the VMX, NULL-terminate the incoming data. */ copy = g_malloc(dataLen + 1); memcpy(copy, data, dataLen); copy[dataLen] = '\0'; /* Try to find a mapping the the command in the RPC. */ if (plugin->recvFns) { char *cmd; unsigned int idx = 0; cmd = StrUtil_GetNextToken(&idx, copy, " "); if (cmd != NULL) { RpcDebugRecvMapping *test; for (test = plugin->recvFns; test->name != NULL; test++) { if (strcmp(test->name, cmd) == 0) { mapping = test; break; } } } vm_free(cmd); } if (mapping != NULL) { recvFn = mapping->recvFn; if (mapping->xdrProc != NULL) { char *start; ASSERT(mapping->xdrSize > 0); /* Find out where the XDR data starts. */ start = strchr(copy, ' '); if (start == NULL) { RpcDebug_SetResult("Can't find command delimiter.", result, resultLen); ret = FALSE; goto exit; } start++; xdrdata = g_malloc0(mapping->xdrSize); if (!XdrUtil_Deserialize(start, dataLen - (start - copy), mapping->xdrProc, xdrdata)) { RpcDebug_SetResult("XDR deserialization failed.", result, resultLen); ret = FALSE; goto exit; } } } else { recvFn = plugin->dfltRecvFn; } if (recvFn != NULL) { ret = recvFn((xdrdata != NULL) ? xdrdata : copy, dataLen, result, resultLen); } else { RpcDebug_SetResult("", result, resultLen); } exit: if (xdrdata != NULL) { VMX_XDR_FREE(mapping->xdrProc, xdrdata); g_free(xdrdata); } g_free(copy); return ret; } /** * Intiializes internal state for the inbound channel. * * @param[in] chan The RPC channel instance. * @param[in] ctx Unused. * @param[in] appName Unused. * @param[in] appCtx A ToolsAppCtx instance. */ static void RpcDebugSetup(RpcChannel *chan, GMainContext *ctx, const char *appName, gpointer appCtx) { DbgChannelData *cdata = chan->_private; cdata->ctx = appCtx; } /** * Cleans up the internal channel state. * * @param[in] chan The RPC channel instance. */ static void RpcDebugShutdown(RpcChannel *chan) { DbgChannelData *cdata = chan->_private; ASSERT(cdata->ctx != NULL); if (cdata->hasLibRef) { RpcDebug_DecRef(cdata->ctx); } g_free(chan->_private); } /** * Instantiates a new RPC Debug Channel. This function will load and initialize * the given debug plugin. * * This function will panic is something wrong happens while loading the plugin. * * @param[in] ctx The application context. * @param[in] data Debug library data. * * @return A new channel. */ RpcChannel * RpcDebug_NewDebugChannel(ToolsAppCtx *ctx, RpcDebugLibData *data) { DbgChannelData *cdata; RpcChannel *ret; ASSERT(data != NULL); ret = RpcChannel_Create(); ret->start = RpcDebugStart; ret->stop = RpcDebugStop; ret->send = RpcDebugSend; ret->setup = RpcDebugSetup; ret->shutdown = RpcDebugShutdown; cdata = g_malloc0(sizeof *cdata); cdata->plugin = data->debugPlugin; ret->_private = cdata; RpcDebug_IncRef(); return ret; } open-vm-tools-9.4.0-1280544/tests/vmrpcdbg/Makefile.in0000644765153500003110000005101012220061625020444 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tests/vmrpcdbg DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libvmrpcdbg_la_DEPENDENCIES = am_libvmrpcdbg_la_OBJECTS = libvmrpcdbg_la-debugChannel.lo \ libvmrpcdbg_la-vmrpcdbg.lo libvmrpcdbg_la_OBJECTS = $(am_libvmrpcdbg_la_OBJECTS) libvmrpcdbg_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libvmrpcdbg_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libvmrpcdbg_la_SOURCES) DIST_SOURCES = $(libvmrpcdbg_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libvmrpcdbg.la libvmrpcdbg_la_CPPFLAGS = @CUNIT_CPPFLAGS@ @GMODULE_CPPFLAGS@ \ @VMTOOLS_CPPFLAGS@ $(am__empty) libvmrpcdbg_la_LDFLAGS = @PLUGIN_LDFLAGS@ libvmrpcdbg_la_LIBADD = @CUNIT_LIBS@ @GMODULE_LIBS@ @VMTOOLS_LIBS@ \ @XDR_LIBS@ $(am__empty) libvmrpcdbg_la_SOURCES = debugChannel.c vmrpcdbg.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/vmrpcdbg/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/vmrpcdbg/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libvmrpcdbg.la: $(libvmrpcdbg_la_OBJECTS) $(libvmrpcdbg_la_DEPENDENCIES) $(EXTRA_libvmrpcdbg_la_DEPENDENCIES) $(libvmrpcdbg_la_LINK) $(libvmrpcdbg_la_OBJECTS) $(libvmrpcdbg_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvmrpcdbg_la-debugChannel.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvmrpcdbg_la-vmrpcdbg.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libvmrpcdbg_la-debugChannel.lo: debugChannel.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvmrpcdbg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libvmrpcdbg_la-debugChannel.lo -MD -MP -MF $(DEPDIR)/libvmrpcdbg_la-debugChannel.Tpo -c -o libvmrpcdbg_la-debugChannel.lo `test -f 'debugChannel.c' || echo '$(srcdir)/'`debugChannel.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libvmrpcdbg_la-debugChannel.Tpo $(DEPDIR)/libvmrpcdbg_la-debugChannel.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='debugChannel.c' object='libvmrpcdbg_la-debugChannel.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvmrpcdbg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libvmrpcdbg_la-debugChannel.lo `test -f 'debugChannel.c' || echo '$(srcdir)/'`debugChannel.c libvmrpcdbg_la-vmrpcdbg.lo: vmrpcdbg.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvmrpcdbg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libvmrpcdbg_la-vmrpcdbg.lo -MD -MP -MF $(DEPDIR)/libvmrpcdbg_la-vmrpcdbg.Tpo -c -o libvmrpcdbg_la-vmrpcdbg.lo `test -f 'vmrpcdbg.c' || echo '$(srcdir)/'`vmrpcdbg.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libvmrpcdbg_la-vmrpcdbg.Tpo $(DEPDIR)/libvmrpcdbg_la-vmrpcdbg.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vmrpcdbg.c' object='libvmrpcdbg_la-vmrpcdbg.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvmrpcdbg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libvmrpcdbg_la-vmrpcdbg.lo `test -f 'vmrpcdbg.c' || echo '$(srcdir)/'`vmrpcdbg.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/tests/Makefile.in0000644765153500003110000005003012220061625016641 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tests DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = vmrpcdbg testDebug testPlugin testVmblock all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done cscopelist-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) cscopelist); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-exec-local install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) \ cscopelist-recursive ctags-recursive install-am install-strip \ tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ cscopelist cscopelist-recursive ctags ctags-recursive \ distclean distclean-generic distclean-libtool distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-exec-local \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am install-exec-local: rm -f $(DESTDIR)$(TEST_PLUGIN_INSTALLDIR)/*.a rm -f $(DESTDIR)$(TEST_PLUGIN_INSTALLDIR)/*.la # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/INSTALL0000644765153500003110000003660512220061621014473 0ustar dtormtsInstallation Instructions ************************* Copyright (C) 1994-1996, 1999-2002, 2004-2012 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell commands `./configure; make; make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for instructions specific to this package. Some packages provide this `INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. Running `configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type `make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the `make install' phase executed with root privileges. 5. Optionally, type `make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior `make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type `make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide `make distcheck', which can by used by developers to test that all other targets like `make install' and `make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. This is known as a "VPATH" build. With a non-GNU `make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple `-arch' options to the compiler but only a single `-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the `lipo' tool if you have problems. Installation Names ================== By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of `${prefix}', so that specifying just `--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to `configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the `make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, `make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of `${prefix}'. Any directories that were specified during `configure', but not in terms of `${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the `DESTDIR' variable. For example, `make install DESTDIR=/alternate/directory' will prepend `/alternate/directory' before all installation names. The approach of `DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of `${prefix}' at `configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of `make' will be. For these packages, running `./configure --enable-silent-rules' sets the default to minimal output, which can be overridden with `make V=1'; while running `./configure --disable-silent-rules' sets the default to verbose, which can be overridden with `make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. HP-UX `make' updates targets which have the same time stamps as their prerequisites, which makes it generally unusable when shipped generated files such as `configure' are involved. Use GNU `make' instead. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its `' header file. The option `-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put `/usr/ucb' early in your `PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in `/usr/bin'. So, if you need `/usr/ucb' in your `PATH', put it _after_ `/usr/bin'. On Haiku, software installed for all users goes in `/boot/common', not `/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to an Autoconf limitation. Until the limitation is lifted, you can use this workaround: CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of all of the options to `configure', and exit. `--help=short' `--help=recursive' Print a summary of the options unique to this package's `configure', and exit. The `short' variant lists options used only in the top level, while the `recursive' variant lists options also present in any nested packages. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. `--no-create' `-n' Run the configure checks, but stop before creating any output files. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. open-vm-tools-9.4.0-1280544/ChangeLog0000644765153500003110000035741112220061556015224 0ustar dtormts9.4.0 Dmitry Torokhov Release matching the vSphere 5.5 release. 2012.05.21 Dmitry Torokhov This release tag contains commits up to the following id: 482332b8d4282df09838df5ea4c58df9cdb4faf3 2012.03.13 Dmitry Torokhov This release tag contains commits up to the following id: 0114aabd54bf2db4556563b7149c4fbbdec3d87b 2011.12.20 Marcelo Vanzin This release tag contains commits up to the following id: dfca5cf9d1c2335c5d001deedd9266c84956b508 2011.11.20 Marcelo Vanzin This release tag contains commits up to the following id: 6c197b8e5eccf32bfee0e2452d8926968182aada 2011.10.26 Marcelo Vanzin This release tag contains commits up to the following id: 6271fde90248a4fd49e38aa61498db9e1dbf37c3 2011.09.23 Marcelo Vanzin This release tag contains commits up to the following id: 05baddbed1c5e47e9789a44d30bb217d7184232a 2011.08.21 Marcelo Vanzin This release tag contains commits up to the following id: 2b3d76ba776f55d06fb5b62499b189ebd6bc1c75 2011.07.19 Marcelo Vanzin This release tag contains commits up to the following id: 5bed6f1369ca6e9c2c7fbaf4205d86e50f219c5f 2011.06.27 Marcelo Vanzin This release tag contains commits up to the following id: 166bbe1d28da4dab763b9568f163c8dca99ced9c 2011.05.27 Marcelo Vanzin This release tag contains commits up to the following id: 3793ddc9c9b5facf376a2625d4c2252aa9bd3daa 2011.04.25 Marcelo Vanzin This release tag contains commits up to the following id: 3112c27981074deb53e86e30e1c168d55e42220c 2011.03.28 Marcelo Vanzin This release tag contains commits up to the following id: ec43520f5f3a50f5a980a73d22ae231380f97555 2011.02.23 Marcelo Vanzin This release tag contains commits up to the following id: 96cf4718ac0aff1743e50a2165599306ba442fe1 2011.01.24 Marcelo Vanzin This release tag contains commits up to the following id: 60c470337c8932a6d9564130dcaf06c7a1a3df53 2010.12.19 Marcelo Vanzin This release tag contains commits up to the following id: 5aef2b20a519788613350752575bcba0ac71df79 2010.11.17 Marcelo Vanzin This release tag contains commits up to the following id: 11c0273ed4269f6f7a92f82f6c822df7da4c8720 2010.10.18 Marcelo Vanzin This release tag contains commits up to the following id: 2162c5d770cdac3b0e275907a1a5d22ece8ce23c 2010.09.19 Marcelo Vanzin This release tag contains commits up to the following id: c92a8bfbb406a906bcd2fb9ef6801f92c5b64d1f 2010.08.24 Marcelo Vanzin This release tag contains commits up to the following id: 94e63742d734b41638d37580602de4232da5ece6 2010.07.25 Marcelo Vanzin This release tag contains commits up to the following id: b15cffc7961b97129d0b77643db42b4d4d8e3da7 2010.06.16 Marcelo Vanzin This release tag contains commits up to the following id: ec87703fccdd0f954a118640c0b097e383994391 2010.04.25 Marcelo Vanzin This release tag contains commits up to the following id: 6fafd672e006208c1e479b297e19618170ff19bd 2010.03.20 Marcelo Vanzin This release tag contains commits up to the following id: 7cdbb623125729b41bf54068568dfbcc2dd58733 2010.02.23 Marcelo Vanzin This release tag contains commits up to the following id: 8baa8588d5fd4cf64efb17164cb70c86c758d0c6 2010.01.19 Marcelo Vanzin This release tag contains commits up to the following id: 8ee82a5774ae7badeb98ecf4dc629c7e9aac7077 2009.12.16 Marcelo Vanzin This release tag contains commits up to the following id: 0d28106da5684dc31ea52ebb5a2dc6a0af5c1d61 2009.11.16 Marcelo Vanzin This release tag contains commits up to the following id: 6f4cdd0f38be020d722f2393c0b78d7cd13f04d2 2009.10.15 Marcelo Vanzin This release tag contains commits up to the following id: d2f1b83daab1d7882fd651ad1cc77c729bbd9760 2009.09.18 Marcelo Vanzin This release tag contains commits up to the following id: 8bb94fbfbdf65b53b87279cf81529756dba7a2ca Other changes not captured in the git logs: * Resync with internal dev branch (2009.08.24) * hgfsmounter/hgfsmounter.c: allow hgfs users to set ttl to 0 at mount time. * lib/guestApp/guestApp.c, lib/include/conf.h, lib/include/netutil.h, lib/include/procMgr.h, lib/include/system.h, lib/vixTools/vixTools.c, lib/vmCheck/vmcheck.c: remove (now unused) Netware checks. * lib/message/*, modules/freebsd/vmhgfs/Makefile, modules/linux/vmhgfs/Makefile.*, modules/solaris/vmhgfs/Makefile: remove unused message transport abstraction. The rpcChannel library is now used to do RPC abstraction. * modules/*/vmmemctl/*: refactor of the vmmemctl module as part of adding support for Mac OS guests. * modules/linux/pvscsi/pvscsi.c: don't clobber RESERVATION_CONFLICT sdstat up from linux pvscsi driver. * modules/linux/shared/*: VMCI changes unrelated to the guest driver. * modules/linux/vmhgfs/fsutil.c, modules/linux/vmhgfs/inode.c: fix the case where two directories refer to the same inode. * scripts/linux/*: support older versions of NetworkManager. 2009-08-24 Marcelo Vanzin * Resync with internal trunk (2009.08.19) * configure.ac: remove support for Linux kernels < 2.6.9. * lib/include/vmtools.h, libvmtools/vmtoolsLog.c, doc/api/services/util.txt: add new log handled that allows appending to existing log files, and fix an issue where old log files would be "rotated" whenever the config file was reloaded. * lib/appUtil/appUtilX11.c, lib/ghIntegration/ghIntegrationX11.c, lib/include/appUtil.h: fix compilation issues on FreeBSD when unity was enabled. * lib/dnd/dndLinux.c, lib/include/vmblock_user.h, tests/testVmblock/*: add vmblock tests and, as part of the change, do some refactoring of vmblock related functions. * lib/guestInfo/guestInfo.c, lib/include/wiper.h, lib/wiper/*, toolbox/toolboxcmd-shrink.c, toolbox/toolboxShrink.c: refactor the wiper structures so that they behave the same on Win32 and other platforms, and also reuse data structures already in use by other parts of the code. This fixes an "use after free" issue that toolbox-cmd had on Win32. * lib/guestInfo/guestInfo.c, lib/guestInfo/guestInfoInt.h, lib/guestInfo/guestInfoPosix.c, lib/guestRpc/nicinfo.x, lib/include/guestInfo.h, lib/include/netutil.h, lib/include/slashProc.h, lib/netutil/netUtilLinux.c, lib/slashProc/*, services/plugins/guestInfo/guestInfoServer.c: add support for sending more network-related information to the host, such as routing tables and name servers. * lib/hgfsBd/hgfsBd.c: don't log RPC errors when HGFS is disabled. * lib/hgfsHelper/*, lib/include/hgfsHelper.h, lib/vixTools/vixTools.c: new library with functions to query information about HGFS; expose some HGFS properties through VIX. * lib/hgfsServer/*, lib/hgfsServerPolicyGuest/hgfsServerPolicyGuest.c, lib/include/hgfsServerPolicy.h: fix checking of whether an object belongs to a particular share; this was causing issues with invalid information being returned in certain cases. * lib/hgfsServer/*, lib/include/hgfsProto.h: changes to support new VIX API calls (mostly affecting Win32 only). * lib/include/guestCaps.h, lib/include/unityCommon.h: add boilerplate for new RPCs for setting windows as sticky / non-sticky (not yet implemented). * lib/include/hgfsProto.h: new definitions for the next version of the HGFS protocol. * lib/include/xdrutil.h: make XDRUTIL_ARRAYAPPEND() more type-safe when using GCC. * lib/misc/codesetOld.c: fix some issues with UTF16 -> UTF8 conversion. * lib/rpcChannel/rpcChannel.c, libvmtools/signalSource.c, libvmtools/vmtools.c, libvmtools/vmtoolsConfig.c: g_assert -> ASSERT. * lib/unityWindowTracker/unityWindowTracker.c: fix issue with z-ordering of modal dialogs. * libvmtools/vmtoolsConfig.c: fix some old config translation issues. * modules/freebsd/shared/*, modules/freebsd/vmblock/*: make vmblock work on FreeBSD 8. * modules/freebsd/vmmemctl/*, modules/linux/vmmemctl/*, modules/solaris/vmmemctl/*, : refactoring and code changes to support the driver on Mac OS X. * modules/linux/vmblock/*, modules/linux/vmci/*, modules/linux/vsock/linux/*: remove compatibility code for older kernels. * modules/linux/vmhgfs/*: fix memory leak in HgfsAccessInt(). * modules/linux/vmxnet3/*: fix kunmap usage in vmxnet3_shm, and reset the shared pages when the char device is closed. * modules/linux/vsock/linux/af_vsock.{c,h}, modules/linux/vsock/linux/util.c: add vsock protocol negotiation for notifyOn ops. This allows the driver to negotiate with the remove end which version of the notification protocol to use. * modules/linux/vsock/linux/notify.c, modules/linux/vsock/linux/notify.h, modules/linux/vsock/linux/notifyQState.c, modules/linux/vsock/linux/vsockPacket.h: add pktOn protocol. This new protocol improves performance by detecting changes in the queue state instead of sending WAITING_READ and WAITING_WRITE packets. * services/plugins/hgfsServer/hgfsPlugin.c, services/plugins/resolutionSet/resolutionSet.c, services/vmtoolsd/mainLoop.c, services/vmtoolsd/pluginMgr.c, services/vmtoolsd/toolsRpc.c: load plugins even when an RPC channel cannot be instantiated (i.e., when running outside of a virtual machine); this allows plugins to perform actions (at load time) also when running outside virtual machines (e.g., to undo some configuration done when the OS was run in a VM). * services/vmtoolsd/mainLoop.c, services/vmtoolsd/mainPosix.c, services/vmtoolsd/toolsCoreInt.h: handle SIGHUP differently; instead of stopping the service, just re-load the config data. This should make it easier to integrate the tools service with other tools such as logrotate. * toolbox/toolbox-cmd.c, toolbox/toolboxcmd-stat.c: remove memory info query, which didn't really return useful information. * vmware-user/copyPasteUI.cpp: if the clipboard/primary with most recent timestamp has no data on it, try the other before giving up during copy/paste. 2009-07-22 Marcelo Vanzin * Resync with internal trunk (2009.07.17) * configure.ac: fix detection of "dot" and its usage in the doxygen config file. * configure.ac, libguestlib/Makefile.am, libguestlib/vmguestlib.pc.in: install vmguestlib headers and add new pkgconfig script. * lib/dndGuest/dnd.{cc,hh}, lib/include/dndBase.h, vmware-user/dndUI.{cpp,h}: fix an issue where the DnD code would prevent drops to other windows in Unity mode, instead of just intercepting drops to the desktop. * lib/dndGuest/dnd.{cc,hh}, lib/dndGuest/dndRpc.hh, lib/dndGuest/dndRpcV3.cc, lib/include/dndBase.h, vmware-user/dndUI.{cpp,h}: fix an issue where the host Unity code would cause an undesired drop event. * lib/dndGuest/dnd.{cc,hh}, lib/dndGuest/dndRpc.hh, lib/dndGuest/dndRpcV3.cc, lib/include/dndBase.h: cleanup mouse simulation code, and fix an issue where a drag would be canceled if the contents were dragged out of a guest and then back in. * lib/dndGuest/dndRpcV3.cc, vmware-user/copyPasteDnDWrapper.cpp, vmware-user/dndUI.cpp, vmware-user/dndUI.h, vmware-user/dragDetWnd.cpp, vmware-user/dragDetWnd.h: several DnD fixes; make the DnD code behave more like other GTK applications (based on analysing the flow of signals on a test widget), and get rid of one of the detection windows, merging both the Unity and non-Unity windows. Also, some code refactoring. * lib/ghIntegration/*, lib/guestRpc/*, lib/include/guestCaps.h, lib/include/unityCommon.h: add stubs for a few new GHI functions (setting window focus, tray icon updates and enhanced app info) - currently only implemented on Win32. * lib/ghIntegration/ghIntegrationX11.c: examine WM_CLASS when determining which DE Tools are running in. The previous code was failing to show a few entries set as "OnlyShowIn=xxx" because checking WM_NAME wasn't enough to properly detect the desktop environment in certain cases. * lib/guestApp/guestAppPosixX11.c: use gconftool-2 to detect the user's browser, since gnome-open fails to open "file://" URLs which contain query strings. Also, use "kde-open" when running under KDE. * lib/guestInfo/guestInfo.c, lib/include/wiper.h, lib/wiper/wiperPosix.c: allow shrinking LVM partitions. * lib/include/appUtil.h: partial refactoring of icon retrieval code. * lib/include/dbllnklst.h, lib/misc/dbllnklst.c: inline linked list functions. * lib/include/guest_os.h, lib/misc/hostinfoPosix.c: add a couple of distros to the known distro list. * lib/include/netutil.h, lib/netUtil/netUtilLinux.c: add Linux interface name, index lookup routines. * lib/include/system.h, lib/system/systemLinux.c, services/plugins/timeSync/timeSync.c: fixes a few bugs in the backwards time sync code, mostly due to unit mismatches. * lib/include/unityWindowTracker.h, lib/unity/unity.c, lib/unity/unityPlatform.h, lib/unity/unityPlatformX11Window.c, lib/unityWindowTracker/unityWindowTracker.c: expose two new properties in the window tracker to save an RPC to retrieve those properties. * lib/include/vmtoolsApp.h, services/vmtoolsd/mainLoop.c, services/vmtoolsd/pluginMgr.c, services/vmtoolsd/toolsCoreInt.h: add support for "application providers", which allow plugins to add support to new kinds of application frameworks through vmtoolsd. * lib/unity/unityPlatformX11.c: only enable GIO channels when Unity is actually active. * lib/unity/*: cleanup old GTK1 code. * libvmtools/vmtoolsConfig.c: don't complain if config file is empty. * modules/linux/dkms.conf, modules/linux/dkms.sh: fix dkms.conf, and provide a script to create a dkms tree from open-vm-tools. * modules/linux/shared/vmci_queue_pair.h, modules/linux/vmci/vmciKernelIf.c: remove two (now) unneeded functions. * modules/linux/vmhgfs/*: code cleanups, properly initialize the list head, and allow receives to timeout so that hibernation works. * modules/linux/vmxnet/vmxnet.c, modules/linux/vmxnet3/vmxnet3_drv.c: fix drivers for kernels 2.6.29+. * modules/linux/vmxnet3/*: add shared memory support for faster communication between user space and the device backend; this doesn't affect the regular driver functionality, but is used by some VMware code not part of Tools. * modules/linux/vsock/*: fix an issue where it was possible for users to send VMCI datagrams directly to the hypervisor. * scripts/common/vmware-user.desktop: work around a bug in KDE where desktop files with "NoDisplay" fail to autostart. * scripts/freebsd/suspend-vm-default: use netif to bring down interfaces, since dhclient doesn't understand "-r" in the default install. * services/plugins/vmbackup/*: add some new code used by enhancements being done in the Win32 version of the plugin. * services/vmtoolsd/mainPosix.c: fix running in background when executing vmtoolsd while relying on PATH. * services/vmtoolsd/Makefile.am: point to the correct plugin install directory. * toolbox/*: better command line handling in the CLI utility, plus some code cleanup. * vmware-user/copyPaste.c, vmware-user/copyPasteDnDWrapper.cpp, vmware-user/copyPasteDnDWrapper.h, vmware-user/dnd.c: properly unregister RPCs to avoid multiple registrations (and the ensuing ASSERT) in certain cases. * vmware-user/copyPasteUI.{cpp,h}: change way data is retrieved from the clipboard, using the gtk+ clipboard wait APIs (which turn out to be more reliable than the previous approach). 2009-06-18 Marcelo Vanzin * Resync with internal trunk (2009.06.15) * docs/api/Makefile.am: replace all variables in the doxygen conf file with the correct values. * lib/appUtil/appUtilX11.c: try alternate file extensions during icon search. Sometimes a package lists its icon as icon-foo.png, but the package didn't include icon-foo.png. Instead, it included icon-foo.xpm. Ex: Ubuntu 8.04's hwtest. * lib/guestApp/guestAppPosixX11.c: change detection of the default browser so that the new help system works; the help files are not yet available in open-vm-tools. * lib/hgfs/*, lib/include/cpName.h, lib/include/cpNameLite.h, lib/include/hgfsUtil.h: avoid compiling certain parts of the source in kernel modules. * lib/hgfsServer/*: return correct error when files / directories don't exist. * lib/include/hgfsChannel.h, modules/linux/vmhgfs/*: added support for vsock channel for HGFS. * lib/include/util.h, lib/misc/utilMem.c: un-inline a bunch of functions to reduce the size of binaries. * lib/include/vm_tools_version.h: bumped Tools version. * lib/resolution/resolutionX11.c: fix for issue where the host would send a "topology set" command with a top-left corner that was not (0, 0) and cause the screen to be reconfigured in the wrong way. * lib/unity/unityPlatformX11Window.c: check for errors in calls to XQueryTree. * lib/wiper/wiperPosix.c: check return of fgets() to avoid compiler warnings. * libvmtools/vmtools.c: fix initialization of wiper library on Win32. * modules/Makefile.am: install vsock header file on Linux. * modules/freebsd/vmhgfs/*, modules/linux/vmci/*, modules/linux/vsock/*: changes related to 64-bit Mac drivers, don't affect either the FreeBSD or Linux drivers. * modules/linux/vmhgfs/hgfs.h: removed duplicate file. * modules/linux/vmhgfs/fsutil.c, modules/linux/vmhgfs/inode.c, modules/linux/vmhgfs/module.h: fix issue where two files would get the same inode number in some situations. * modules/linux/vmxnet/vmxnet.c: re-probe vmxnet2 device features on resume from hibernate, to cover the case where a VM is resumed on a platform with a different version of the device backend (bug #2209565). * scripts/resume-vm-default, scripts/suspend-vm-default: use NetworkManager to handle networking where it is available. * services/plugins/hgfsServer/Makefile.am, services/plugins/vix/Makefile.am: fix installation of vmusr plugins that are shared with vmsvc. * services/plugins/timeSync/timeSync.c: fix backwards time sync. * services/vmtoolsd/cmdLine.c, toolbox/toolbox-cmd.c: print build number as part of "-v" output. * toolbox/toolboxcmd-shrink.c: correctly ignore unsupported partitions when shrinking. * toolbox/toolbox-gtk.c: changes for the new help system, not yet available for open-vm-tools. * toolbox/toolboxInt.{c,h}, toolbox/toolboxScripts.c: some code refactoring. * vmware-user/Makefile.am: fix linking when compiling without gtkmm. 2009-05-22 Marcelo Vanzin * Resync with internal trunk (2009.05.18) * configure.ac, m4/vmtools.m4: check for PAM and enable PAM support when available. * configure.ac, services/plugins/*/Makefile.am, tests/*/Makefile.am: avoid the "-rpath" hack to create plugins, using plugin_LTLIBRARIES instead (and manually fixing things when necessary). Thanks to Dominique Leuenberger for the suggestion (and sample patch). * docs/api/Makefile.am: fix doc target directories. * configure.ac, lib/Makefile.am, lib/deployPkg/*, lib/include/deployPkg.h: remove the deployPkg code, which depends on some VMware code that is not yet open source. * lib/backdoor/*, lib/hgfs/*, lib/hgfsBd/*, lib/include/*, lib/include/compat/*, lib/message/*, lib/misc/dbllnklst.c, lib/rpcOut/rpcout.c: as part of sharing code between user-level code and kernel modules, some files have been tagged with more than one license. * lib/dndGuest/*, lib/include/dndBase.h, lib/include/dndMsg.h, lib/include/unity*, lib/unity/unityPlatformX11.c: implement mouse movement from within the guest; this avoids a dependency on "unofficial" mouse APIs in the VMware host code, making DnD more reliable, and makes a few things (such as cancelling an ongoing DnD operation) easier. * lib/file/filePosix.c: make File_FullPath()'s behavior consistent when the input path starts with a '/'. * lib/ghIntegration/ghIntegration.c: send more info about the "start menu" contents to the host (only usable for Windows guests). * lib/ghIntegration/ghIntegrationX11.c: prettify the category names of menu items. This is a temporary solution before actually reading this information from .desktop files. * lib/guestApp/guestApp.c, libguestlib/vmGuestLib.c, lib/include/guestApp.h, toolbox/toolbox-gtk.c, vmware-user/foreignVM*, vmware-user/vmware-user.cpp, configure.ac, lib/Makefile.am, lib/include/socketMgr.h, lib/socketMgr.*: remove code related to "foreign VM" support, which was never really used. * lib/guestInfo/guestInfo.c, lib/include/wiper.h, lib/wiper/wiperPosix.c: properly report disk info for LVM volumes. * lib/hgfsServer/hgfsDirNotify*, lib/hgfsServer/hgfsServer.c: add support for directory / file monitoring. It's currently only implemented on Mac OS X. * lib/hgfsServer/hgfsServer*: fix issue where it was possible to create a file on a read-only share on Windows hosts. * lib/hgfsServer/hgfsServer*, lib/hgfsServerManagerGuest/*, lib/include/hgfs*.h, services/plugins/hgfsServer/hgfsPlugin.c, services/plugins/vix/foundryToolsDaemon.c: some refactoring caused by the work to make HGFS support pluggable transports. * lib/include/procMgr.h, lib/procMgr/procMgrPosix.c: remove ProcMgr_GetAsyncStatus(). * lib/include/vmsupport.h, scripts/vm-support, xferlogs/xferlogs.c, services/plugins/guestInfo/guestInfoServer.c: new feature to automatically collect support data from the guest from the VMware UI. * lib/panicDefault/*, lib/user/*: change file names to avoid clash with another file (Mac OS linker doesn't really like that). * lib/rpcChannel/rpcChannel.c: try to reinitialize the outbound channel on failure. * lib/vixTools/vixTools.c, lib/include/vixCommands.h, lib/include/vixOpenSource.h: add backend for new VIX API call to list the guest's filesystems. * libvmtools/vmtoolsLog.c: lazily open the log file, instead of opening it during configuration of the log system. This way two processes can use the same conf file and not overwrite each other's log files (assuming the conf data is sane). * modules/Makefile.am, modules/linux/vmci/Makefile.kernel, modules/linux/vsock/Makefile.kernel: don't store VMCI module symbols in /tmp during build; this avoids a possible symlink attack that could cause data to be overwritten when building open-vm-tools. * modules/*/*, vmblock-fuse/*: remove a lot of duplicated files by either moving them to a shared location or reusing files that were already available elsewhere. * modules/freebsd/vmblock/subr.c, modules/freebsd/vmblock/vmblock_k.h, modules/freebsd/vmblock/vnoops.c: fix a possible kernel crash caused by trying to read / write to the mount point (something vmware-user does to detect whether it's using fuse or non-fuse vmblock). * modules/linux/pvscsi/*: adds support for a generic msg framework that is currently used to deliver hot-plug/unplug notifications; get rid of a few divisions; fix a bug where pvscsi_probe could return 0 (aka success) if a call to kmalloc() failed; remove a few unused fields. * modules/linux/shared/vmci*: mostly changes related to the host VMCI drivers (removed user-level queue-pair daemon, added support for trusted VMCI endpoints) to keep binary compatibility between the host and guest VMCI drivers. * modules/linux/hgfs/inode.c: check host's access rights when checking file permissions, so that permissions are correctly checked when the guest's user id is different from the host's user id. * modules/linux/bdhandler.*, modules/linux/filesystem.c; modules/linux/tcp.*, modules/linux/transport.*,: postpone opening the channels so that module can load successfully even if shared folders are disabled on the host; fix a synchronization problem between recv and close/open; allow hibernation to work by timing out the recv thread; correctly handle failures in recv, including injecting a dummy error to the pending requests when the recv thread exits; move the recv code to the channel's implementation so that it can be simpler. * modules/linux/vmxnet3/vmxnet3.c, modules/linux/shared/compat_pci.h: fix Wake-On-LAN for 2.6.27 and newer Linux guests. * modules/linux/vsock/linux/*: changes to support trusted VMCI host apps; pull out notification and stats logging code into their own files. * modules/solaris/vmhgfs/vnode.c: do not substitute errors returned by uiomove() calls with EIO, propagate returned error code (which is EFAULT) up the stack. * services/vmtoolsd/Makefile.am, scripts/common/linux/pam.d/vmtoolsd-x64, scripts/common/linux/pam.d/64/vmtoolsd: install the 64-bit PAM config file with the correct name. * services/plugins/powerOps/powerOps.c: fix running default scripts by making sure the path to the script is absolute. * services/vmtoolsd/Makefile.am, services/vmtoolsd/pluginMgr.c: use info from the configure step to define the plugin path; this avoids requiring a symlink to be placed in /etc/vmware-tools for vmtoolsd to be able to find the plugins. * services/vmtoolsd/toolsRpc.c: send the build information to the host so it's logged in the VM's logs. * toolbox/toolbox-cmd.c, toolbox/toolboxcmd-*, toolbox/toolboxCmdInt.h: make string comparison case-insensitive on Win32. * toolbox/toolboxcmd-shrink.c: properly finish the shrinking process by sending the "disk.shrink" RPC to the host. * toolbox/toolboxScripts.c: fix showing default settings for power ops scripts (should show default script enabled, not script disabled). * vmblock-fuse/Makefile.am: fix compilation on FreeBSD. * vmware-user/copyPasteUI.cpp: disallow copy-paste text of size greater than 4MB, instead of truncating the data. * vmware-user/dndUI.*, lib/dndGuest/dnd.cc, lib/include/dndBase.h: remove drag timeout callback (which was not needed), and add new signal to indicate that a GH DnD was cancelled. * vmware-user/Makefile.am: remove C++ link hack (not needed now since vmware-user has C++ code already). 2009-04-23 Marcelo Vanzin * Resync with internal trunk (2009.04.17) * configure.ac, Makefile.am, docs/*: build API docs for vmtools; the documentation files are provided under a BSD-style license. * configure.ac, Makefile.am, guestd/*, lib/Makefile.am, lib/guestInfo/*, lib/include/vmbackup_def.h, lib/include/vmBackup.h, lib/vmBackupLib/*, libvmtools/Makefile.am, services/plugins/vmbackup/vmbackup_def.h: remove guestd from open-vm-tools, and clean up code in other places that was only there because of guestd. * configure.ac, modules/solaris/vmblock/*, modules/solaris/vmmemctl/*: add Solaris vmblock and vmmemctl driver sources. The vmmemctl module also includes a user-level daemon (vmmemctld.c). * lib/conf/conf.c, lib/include/conf.h, libvmtools/vmtoolsConfig.c: remove unused config options. * lib/deployPkg/toolsDeployPkg.h: code refactoring. * lib/dnd/dndClipboard.c: if size of clipboard exceeds the maximum backdoor packet size, only keep text data (dropping the RTF data). * lib/dnd/dndLinux.c, lib/include/dnd.h, lib/include/vmblock.h, vmware-user/copyPaste.c, vmware-user/dnd.c, vmware-user/vmware-user.cpp, vmware-user/vmwareuserint.h, vmware-user-suid-wrapper/main.c: detect whether plain vmblock or vmblock-fuse is being used, allowing the same executable to be used with either. * lib/dndGuest/*, vmware-user/copyPaseDnDWrapper.{cpp,h}, vmware-user/dndUI.{cpp,h}, vmware-user/dragDetWnd.{cpp,h}: vmware-user/vmware-user.cpp: more DnD V3 protocol work. * lib/ghIntegration/*, lib/include/guestCaps.h, lib/include/unityCommon.h: work related to mapping Outlook folders over HGFS and exposing the Windows Recycle Bin to the host (doesn't really affect open-vm-tools). * lib/ghIntegration/ghIntegrationX11.c: restore the native environment when launching external applications. This doesn't really affect open-vm-tools. * lib/guestRpc/*, vmware-user/copyPasteUI.{cpp,h}: implement RTF and file contents copy & paste. * lib/include/circList.h, lib/include/vm_basic_math.h, lib/include/vm_device_version.h, modules/linux/*, modules/Makefile.am: changes to share files between the user space code and the kernel code, instead of duplicating the same source files in different places. * lib/include/rpcChannel.h, lib/rpcChannel/*, tests/testDebug/testDebug.c, test/vmrpcdbg/debugChannel.c: some code cleanup, and fix crash when dealing with multiple reset messages. * lib/include/system.h, lib/system/systemLinux.c, services/vmtoolsd/mainPosix.c: remove System_Daemon() (replaced with Hostinfo_Daemonize()). * lib/include/unityCommon.h, lib/unity/*: ressurrect UNITY_RPC_WINDOW_SHOW and UNITY_RPC_WINDOW_HIDE RPCs. * lib/procMgr/procMgrPosix.c: fix ProcMgr_IsProcessRunning(). * lib/system/systemLinux.c: fix shutdown / reboot commands on Solaris; fix rebuilding of native environment from variables set by VMware scripts (this last one doesn't really affect open-vm-tools). * lib/unicode/unicodeSimpleTypes.c: speed up UnicodeIANALookup, and fix case where C++ constructors could call UnicodeIANALookup before Unicode_Init() was called by lazily creating the internal cache. * libguestlib/*: link libguestlib against libvmtools. This avoids having two definitions of certain symbols (like Debug()) when an application links to both libraries. * modules/linux/vmblock/linux/control.c: only set directory entry owner when needed. * modules/linux/vmhgfs/bdhandler.{c,h}, modules/linux/vmhgfs/dir.c, modules/linux/vmhgfs/file.c, modules/linux/vmhgfs/filesystem.c, modules/linux/vmhgfs/fsutil.c, modules/linux/vmhgfs/inode.c, modules/linux/vmhgfs/module.{c,h}, modules/linux/vmhgfs/page.c, modules/linux/vmhgfs/request.{c,h}, modules/linux/vmhgfs/super.c, modules/linux/vmhgfs/tcp.{c,h}, modules/linux/vmhgfs/transport.{c,h}: cleanup use of atomic variables in HGFS; add a transport abstraction layer, and add an initial version of a socket-based transport (not yet stable and not yet supported by any released VMware product). * modules/linux/vmxnet3/vmxnet3.c: fix build on kernel 2.6.29. * modules/linux/vsock/af_vsock.c: export more functions to other kernel modules; some changes to statistics gathering code. * modules/solaris/vmhgfs/filesystem.c: make module loadable on Solaris 9. * modules/solaris/vmhgfs/vnode.c: unify mapping of HGFS to Solaris error codes. * scripts/*: restart network before running user scripts in resume scripts. * services/plugin/powerOps/powerOps.c: fix running default power scripts. * services/vmtoolsd/pluginMgr.c: better error logging. * toolbox/toolbox-cmd.c: fix help string. * vmblock-fuse/block.c: fix vmblock-fuse compilation on FreeBSD. 2009-03-18 Marcelo Vanzin * Resync with internal trunk (2009.03.13) * configure.ac: check for FreeBSD kernel tree when building modules; warn about which version of make to use when building kernel modules on FreeBSD and Solaris; add compiler defines for identifying Solaris 9 and 11. * configure.ac, modules/Makefile.am: handle SYSDIR on FreeBSD. * guestd/main.c, modules/solaris/vmhgfs/Makefile: remove HGFS-related that is now obsolete with the recent changes to the HGFS module on Solaris. * guestd/toolsDaemon.c: default to the configuration dir when the power script path is not absolute. * guestd/toolsDaemon.c, lib/include/guestInfo.h, lib/netUtil/netUtilLinux.c: handle case when all network interfaces have been disabled and send an "unknown" IP address to the host. * guestd/toolsDaemon.c, services/vmtoolsd/toolsRpc.c: always send TOOLS_VERSION_UNMANAGED from an open-vm-tools build, so there's no need for a config file option anymore. * hgfsclient/*: make it link to libvmtools to avoid code duplication. * lib/appUtil/appUtil.c: update list of "skippable" apps when figuring out an application's path. * lib/auth/authPosix.c, scripts/linux/pam.d/*, guestd/Makefile.am, services/vmtoolsd/Makefile.am : change the name of the PAM application to "vmtoolsd" to reflect the new service name. * lib/dnd/dndFileContentsUtil.h, lib/dnd/dndInt.h, lib/dndGuest/*.hh, and corresponding files in lib/include: relocate private headers. * lib/ghIntegration/ghIntegration.c, lib/ghIntegration/ghIntegrationInt.h, lib/ghIntegration/ghIntegrationX11.c, lib/include/unityCommon.h: glue code for Outlook mirrored folder, which does not affect open-vm-tools. * lib/guestRpc/guestlibV3.x, lib/include/vmGuestLib.h, libguestlib/vmGuestLib.c: add new guestlib counters. * lib/include/conf.h, toolbox/toolbox-gtk.c: remove the need for the "helpdir" config option; this doesn't really affect open-vm-tools since the help files are not yet included. * lib/include/guest_os.h, lib/misc/hostinfoPosix.c: more guest OS names; fix name used to identify Solaris to match what VMware's host code expects. * lib/include/guestStats.h: documentation changes. * lib/include/hostinfo.h, lib/user/hostinfoPosix.c: add a new function that behaves like daemon(3), but is more Mac OS-friendly. * lib/include/toolsLogger.h, lib/Makefile.am, lib/toolsLogger/*: removed library, which is not used anymore. * lib/include/vm_basic_types.h, lib/misc/timeutil.c: fixes to compile under (Open) Solaris 11. * lib/include/vmtoolsApp.h, services/plugins/vmbackup/stateMachine.c, services/vmtoolsd/mainLoop.c, services/vmtoolsd/mainPosix.c, services/vmtoolsd/serviceObj.c, services/vmtoolsd/toolsCoreInt.h: add new signal handler to gather debugging information from a running vmtoolsd instance. * lib/misc/posixPosix.c: fix off-by-one error. * lib/unity/unity.c, lib/unity/unityPlatform.h, lib/unity/unityPlatformX11.c, lib/unity/unityPlatformX11Settings.c: always send Unity updates using RPCI; this avoids a possible race between replying to an incoming RPC and sending an Unity update from a different thread; also, API documentation updates. * lib/unity/unityPlatformX11.c: verify the DnD detection window was initialized before actually using it. * lib/unity/unityPlatformX11Settings.c, lib/unity/unityPlatformX11Window.c: reset _NET_WM_DESKTOP as necessary before exiting Unity; this could cause guest taskbars to disappear when in Unity mode. * lib/unity/unityPlatformX11.c, lib/unity/unityPlatformX11Window.c, lib/unity/unityX11.h: examine WM_CLIENT_LEADER when gathering application information; certain applications use this property to define the window where the WM_COMMAND property should be. * lib/vixTools/vixTools.c: do not follow symlinks when deleting files in the guest using the VIX API. * libvmtools/vmtools.c, libvmtools/vmtoolsLog.c: allow the logging subsystem to be re-configured, and clean up the logging data when unloading the library; allow ${USER} and ${PID} to be used in log file paths. * modules/freebsd/vmblock/subr.c, modules/freebsd/vmblock/vnops.c: fix kernel panic on FreeBSD 7. * modules/linux/*/Makefile: remove GCC version check. * modules/linux/*/compat_wait.h: fix COMPAT_DEFINE_WAIT for "vanilla" 2.4 kernels. * modules/linux/vmhgfs/Makefile.normal: fix build of HGFS module on 2.4 kernels. * modules/linux/vmxnet/*, modules/linux/vmxnet3/*: avoid using compat functions when they're not needed; add compatibility functions for newer Linux kernels. * modules/linux/vsock/linux/af_vsock.c: fix two races; one when the socket state changed between calls to VSockVmciRecvStreamCB and VSockVmciRecvPktWork, and another when trying to read from the socket after a RST arrived after the socket got a detach notification. * modules/solaris/vmxnet3/*: add Solaris vmxnet3 driver. * rpctool/*: add "rpctool", a simple, stand-alone tool to send RPC commands to the host software. * services/plugins/guestInfo/guestInfoServer.c: don't cache configuration data. * services/plugins/guestInfo/perfMonLinux.c: fix problem with overwriting flags after GuestInfoMonitorReadMeminfo() was called. (Same as fix to lib/guestInfo on previous release.) * services/plugins/powerOps/powerOps.c: handle power ops-related options sent from the host. * services/vmtoolsd/mainLoop.c: handle re-loading the configuration file. * services/vmtoolsd/mainPosix.c: exec after forking on Mac OS, since CoreFoundation classes don't work after a fork. * services/vmtoolsd/pluginMgr.c: allow both 32 and 64 bit plugins to be installed on Solaris by loading them from the appropriate directory; add library loading code that is not really needed (nor used) in open-vm-tools. * services/vmtoolsd/toolsRpc.c: send another "capability" the host expects from Tools. * toolbox/toolbox-gtk.c: add F1 shortcut to invoke help. * toolbox/toolboxScripts.c: fix issue with freeing data that should not be freed. * vmware-user/*: implement the new DnD protocol (V3). 2009-02-18 Marcelo Vanzin * Resync with internal trunk (2009.02.13) * configure.ac, m4/vmtools.m4: clean up a lot of the library detection code. * configure.ac: remove support for gtk+ 1.2 (code already depended on it in any case); enforce need for glib 2.6.0 or later due to new code being added; add detection for gtkmm; check for C++ compiler when it's needed; reorder the include path to avoid clashing with system headers in some situations. * guestd/foundryToolsDaemon.*, vmware-user/foundryToolsDaemon.*, guestd/Makefile.am, vmware-user/Makefile.am: moved shared source files to a new place to avoid duplication. * hgfsmounter/hgfsmounter.c: add support for Solaris. * lib/appUtil/appUtilX11.c: fix loading of icons when the name has a period. * lib/dnd/dndClipboard.c, lib/dnd/dndInt.h, lib/dnd/dndMsg.c, lib/dnd/Makefile.am, lib/dndGuest/*, lib/include/copyPasteBase.h, lib/include/copyPaste.hh, lib/include/copyPasteRpc.hh, lib/include/copyPasteRpcV3.hh, lib/include/dndBase.h, lib/include/dndClipboard.h, lib/include/dndFileContentsUtil.h, lib/include/dndFileList.hh, lib/include/dnd.h, lib/include/dnd.hh, lib/include/dndInt.h, lib/include/dndMsg.h, lib/include/dndRpc.hh, lib/include/dndRpcV3.hh, lib/include/dndTransportGuestRpc.hh, lib/include/dndTransport.hh, lib/include/libExport.hh, vmware-user/copyPaste.cpp, vmware-user/copyPasteUI.{cpp,h}, vmware-user/copyPasteV3.h, vmware-user/copyPasteWrapper.{cpp,h}, vmware-user/dnd.cpp, vmware-user/Makefile.am, vmware-user/vmware-user.{c,cpp}, vmware-user/vmwareuserInt.h, vmware-user/stringxx/string.{cc,hh}, vmware-user/stringxx/ubstr_t.hh: add support for new version of the DnD protocol. * lib/guestInfo/guestInfoPerfMonLinux.c: fix problem with overwriting flags after GuestInfoMonitorReadMeminfo() was called. * lib/guestRpc/guestlibV3.x, lib/include/vmGuestLib.h, libguestlib/vmGuestLib.c: add new host stats. * lib/guestRpc/Makefile.am: fix a few compatibility issues with non-GNU versions of make. * lib/hgfsServer/hgfsServer.c, lib/hgfsServer/hgfsServerInt.h, lib/hgfsServer/hgfsServerLinux.c, */hgfsProto.h, modules/freebsd/vmhgfs/vnops.c, modules/freebsd/vmhgfs/vnopscommon.{c,h}: don't trust the local VFS layer, check the HGFS server to see if an operation would succeed. * lib/include/rpcChannel.h, lib/rpcChannel/*: add new Guest RPC channel abstraction library used by the new "core services" code. * lib/include/vmrpcdbg.h, tests/*: add test code from the "core services" project. * lib/include/vmtoolsApp.h, lib/include/vmtoolsd_version.h, services/vmtoolsd/*: add "vmtoolsd", the new service "shell" used in the "core services" project. * lib/unity/unityPlatformX11Window.c: don't send initial "region" updates for shaped windows. This works around an issue where resizing a shaped window would not work as expected in Unity mode. * lib/wiper/wiperPosix.c: fix major number detection for disks on newer Linux kernels. * libvmtools/Makefile.am: link more libraries needed by vmtoolsd and the new plugins. * modules/linux/pvscsi/pvscsi.c, modules/linux/pvscsi/pvscsi_version.h: use PCI-specific memory allocation functions and update driver version. * modules/linux/vmci/vmciKernelIf.c: disable queue pair support in the host version of the driver on older Linux kernels. This doesn't affect the guest driver. * modules/linux/vmci/vmci_queue_pair.h: implement MSG_PEEK support on Linux driver. * modules/linux/vmhgfs/bdhandler.c, modules/linux/vmhgfs/compat_sched.h, modules/linux/vmmemctl/os.c: fix issue with HGFS module interfering with suspend / hibernation on newer Linux kernels (bug #2523263). * modules/linux/vmhgfs/compat_cred.h, modules/linux/vmhgfs/file.c, modules/linux/vmhgfs/filesystem.c, modules/linux/vmhgfs/inode.c: changes for compatibility with newer Linux kernels, where it's not possible to change fsuid/capabilities directly anymore. * modules/linux/vmhgfs/compat_pagemap.h, modules/linux/vmhgfs/page.c: fix warning, and compatibility changes for newer Linux kernels (2.6.28.1 and newer; bug #2530616). * modules/linux/vmhgfs/inode.c: fix creation of symlinks (bug #2531303). * modules/linux/vmxnet/vmxnet.c: use PCI-specific memory allocation functions. * modules/linux/vmxnet/vmxnet.c, modules/linux/vmxnet3/vmxnet3.c: add option to disable LRO. * modules/linux/vsock/af_inet.{c,h}, modules/linux/vsock/util.{c,h}: add MSG_PEEK support; remove ifdefs that were disabling support for queue pairs on the host kernel module; fix compilation with certain versions of gcc (bug #2531283). * modules/solaris/vmhgfs/*: move backdoor handling code to the HGFS driver; this makes the user-level code to handle the driver (currently in vmware-guestd) obsolete. * modules/solaris/vmxnet/*: add vmxnet driver for Solaris, under the CDDL. * services/plugins/*: add all currently available "core services" plugins. The current set of plugins provide the functionality available in vmware-guestd; there are a few plugins that replace functionality from vmware-user, but not all features are ported yet (and vmtoolsd - with vmware-user plugins - and vmware-user cannot run at the same time). * toolbox/toolboxAbout.c: fix the copyright character. * toolbox/toolbox-cmd.c: reword a few messages, fix typos. * toolbox/toolboxCmdInt.h, toolbox/toolboxcmd-record.c, toolbox/toolbox-gtk.c, toolbox/toolboxRecord.c: remove the "record" functionality from tools (due to internal request). * toolbox/toolboxInt.c, toolbox/toolboxScripts.c, toolbox/toolbox-scripts.c: changes to use the new config file format used by the "core services" code. * */Makefile.am: make sure 'rm' and 'mv' are being used instead of $(RM) and $(MV) (which are not defined by automake; bug #2492040). 2009-01-21 Marcelo Vanzin * Resync with internal trunk (2009.01.19) * configure.ac: detect the presence of FUSE libraries. * configure.ac, Makefile.am: compile kernel modules for Solaris, and vmblock-fuse module if FUSE is available. * lib/ghIntegration/ghIntegrationX11.c: retrieved localized application names. * lib/guestInfo/guestInfo.c, lib/guestInfo/guestInfoPosix.c, lib/include/hostinfo.h, lib/misc/hostinfo_misc.c, lib/misc/hostinfoPosic.c, lib/vixTools/vixTools.c: refactoring to move code shared with other VMware products to a common library. * lib/guestRpc/guestlibV3.x, lib/guestRpc/Makefile.am, lib/include/vmGuestLib.h, libguestlib/*: add new iteration of the "guestlib" protocol. This is a more extensible solution than the current protocol, and should make it easier to add new information when needed. * lib/include/dynarray.h, lib/include/dynbuf.h, lib/misc/dynarray.c, lib/misc/dynbuf.c: make some DynArray/DynBuf functions inline for speed. * lib/include/unityCommon.h: more documentation about the Unity protocol. * lib/unity/unityPlatformX11.c: fix Unity<->guest desktop ID mappings. * libvmtools/vmtoolsLog.c: change the way log domains are configured; now sub-domains inherit the default handler for the app if no handler is specified. * modules/freebsd/vmhgfs/state.c, modules/freebsd/vmhgfs/state.h, modules/freebsd/vmhgfs/vnopscommon.{c,h}: implement support for mmap on the Mac OS driver, which allows running executables from an HGFS share. The FreeBSD module still does not support this functionality. * modules/freebsd/vmhgfs/transport.{c,h}: refactoring for sharing structure definitions. * modules/linux/pvscsi/pvscsi.c, modules/linux/vmblock/linux/module.c, modules/linux/vmci/vmci_drv.c, modules/linux/hgfs/module.c, modules/linux/vmmemctl/os.c, modules/linux/vmsync/sync.c, modules/linux/vmxnet/vmxnet.c, modules/linux/vmxnet3/vmxnet3.c: add support for Novell's proprietary module info tag ("supported"). * modules/linux/vmci/vmciKernelIf.c: add support for VMCI queue pairs on the host. This does not affect the driver when it runs inside virtual machines. * modules/linux/vmci/*.h, modules/linux/vsock/*.h: some changes in the common code to support Mac OS X, and also queue pairs on the Solaris VMCI module. * modules/linux/vsock/af_vsock.{c,h}: add functions for registering with the vsock driver from within the kernel. * modules/linux/*/Makefile: add $(LINUXINCLUDE) to the compiler flags; this allows compiling the modules against recent kernels which removed that from $(KBUILD_CPPFLAGS). * modules/Makefile.am: add support for compiling Solaris kernel modules. * modules/solaris/vmhgfs/*: initial release of the Solaris HGFS driver in open-vm-tools. Driver is licensed under the CDDL 1.0. * vmblock-fuse/*: add the user-level implementation of the vmblock driver, which is build on top of FUSE, to open-vm-tools. vmware-user hasn't yet been modified to use this version of vmblock. * vmware-user/copyPaseV3.h: new header introduced during development of the next version of copy paste / DnD for X11 platforms. 2008-11-23 Marcelo Vanzin * Resync with internal trunk (2008.12.19) * configure.ac, */Makefile.am: standardize on using libtool archives for the libraries. This also means several makefiles were removed, since there's no need to build two archives of the same library anymore. * configure.ac: add logic to detect glib 2.6; this is the minimum version required by the "Core Services" project. Currently it's an optional dependency. * configure.ac: disable Unity when user specifies --disable-multimon. * configure.ac: actually build the pvscsi modules if the detected kernel version supports it. * configure.ac, Makefile.am, lib/guestInfo/Makefile.am, lib/stubs/Makefile.am, libvmtools/*, lib/include/vmtools.h: add the "vmtools" shared library used in the "Core Services" project. The library is a collection of a lot of other libraries used by most VMware Tools programs, and adds some functionality on top of glib that is used in the "Core Services" project. Currently no other components from that project are available as part of open-vm-tools. * lib/deployPkg/deployPkgLog.h, lib/deployPkg/toolsDeployPkg.h: moved private headers out of the public header directory. * lib/guestRpc/Makefile.am, modules/Makefile.am: fix the makefiles so that it's possible to build open-vm-tools from a directory different from the source dir. * lib/hgfsServer/hgfsServer.c: changes to support aliases on Mac OS hosts. * lib/hgfsServer/hgfsServerLinux.c: changes to map Windows attributes to Mac OS FileInfo. * lib/include/circList.h: removed unused file. * lib/include/unityCommon.h, lib/unity/unity.c: changes to add documentation to various application RPCs used in Tools. * lib/misc/posixPosix.c, toolbox/toolboxScripts.c: fix include path for syslimits.h on FreeBSD. * lib/unity/unityPlatformX11.c: better detection of the guest's work area boundaries; fixes a problem when dragging a Window in Unity mode with the host's task bar on the left/right of screen would result in weird behavior. * lib/unity/unityPlatformX11Settings.c, lib/unity/unityPlatformX11Window.c, lib/unity/unityX11.h: preserve the _NET_WM_DESKTOP setting when hiding windows; this fixes a problem where hiding a panel and later restoring it would result in the wrong _NET_WM_DESKTOP property being set for the panel, causing it to only display on the first virtual desktop. * modules/linux/vmci/*: minor changes related to internal development of the Mac OS drivers. * modules/linux/vmhgfs/page.c: fix HGFS driver for kernel 2.6.28. * modules/linux/vsock/linux/af_vsock.c: added code to gather some performance statistics for the driver. * toolbox/toolbox-gtk.c: a few fixes to the help functionality. * vmware-user/vmware-user.c, vmware-user-suid-wrapper/main.c: change the "blockFd" argument to have an extra dash so it follows the convention of common command line parsing libraries. * Other bug fixes and changes in shared code that don't affect open-vm-tools. 2008-11-18 Marcelo Vanzin * Resync with internal trunk (2008.11.14) * lib/include/vm_version.h: Bumped TOOLS_VERSION. * guestd/toolsDaemon.c, lib/include/vm_app.h: changes related to host-side configuration of power operations. * hgfsclient/hgfsclient.c, lib/dnd/dndCommon.c, lib/dnd/dndLinux.c, lib/hgfs/*, lib/hgfsServer/*, lib/include/cpName.h, lib/include/dnd.h, lib/include/hgfsEscape.h, lib/include/staticEscape.h, modules/*/vmhgfs/*, vmware-user/dnd.c: refactor the HGFS character escaping code; escape invalid characters when the sender allows characters in the file name that the receiver does not allow. * lib/hgfsServer/hgfsServerLinux.c: return proper error code when the remote path points to a non-existent directory. * lib/deployPkg/deployPkg.c, lib/deployPkg/deployPkgLog.c, lib/include/deployPkg.h, lib/include/rpcin.h, lib/rpcin/rpcin.c: refactoring for the Tools Core Services project. * lib/dnd/dndCommon.c: don't ASSERT if the staging directory is not actually a directory. * lib/dynxdr/xdrutil.c, lib/include/xdrutil.h: more XDR-related utility functions. * lib/file/file.c, lib/file/fileLockPrimitive.c, lib/include/vm_basic_defs.h: replace use of strtok with strtok_r. * lib/guestApp/guestApp.c, lib/include/guestApp.h: more utility functions. * lib/guestApp/guestApp.c, lib/include/backdoor_def.h, vmware-user/pointer.c: add the ability to detect whether the mouse hardware can be used in absolute mode, which allows for auto grab / auto ungrab to work. * lib/guestInfo/guestInfo.c, lib/guestInfo/guestInfoPosix.c, lib/guestRpc/nicinfo.x: provide the prefix length of an IPv6 address in a separate field of the NicInfo struct. * lib/guestInfo/guestInfoPerfMonLinux.c: reduce log spew. * lib/guestInfo/guestInfoServer.c, lib/include/guestInfo.h: changes related to how the VMware code in the host handles Tools version information. * lib/include/unityCommon.h: changes related to documenting the Unity API. * lib/include/unity.h, lib/unity/*: remove a few unused RPCs, add a new function used to notify the host of the status of Unity. * modules/freebsd/vmhgfs/state.c, modules/vmhgfs/freebsd/vnops.c, modules/vmhgfs/freebsd/vnopscommon.*: support symlinks on FreeBSD and Mac OS. * modules/freebsd/vmhgfs/worker.c: fix mutex not being unlocked in some error paths. * modules/linux/dkms.conf: add rudimentary dkms support. * modules/linux/pvscsi/*: add a driver for VMware's paravirtualized SCSI device. * modules/linux/*/Makefile, modules/linux/vmci/Makefile.kernel, modules/linux/vsock/Makefile.kernel: add support for exporing symbols, needed for dependent modules to load if a kernel >= 2.6.26 is compiled with CONFIG_MODVERSIONS. Make the vsock module reference the vmci module's symbols. * modules/vmmemctl/freebsd/os.c: add sysctl to get driver status. Information can be retrieved with "sysctl vm.vmmemctl". * modules/linux/vmci/vmci_defs.h, modules/linux/vmci/vmci_call_defs.h, modules/linux/vsock/vmciHostKernelAPI.h: changes related to VMCI work on VMware ESX. * modules/linux/vsock/linux/*: improve performance of some applications by improving the poll behavior and sending less packets when waiting for a response. * modules/linux/vmsnc/sync.c: fix panic on kernels < 2.6.20. * modules/linux/vmxnet3/vmxnet3.c, modules/linux/vmxnet3/vmxnet3_int.h, modules/linux/vmxnet3/vmxnet3_version.h: inherit net device features to avoid having the kernel setting the PSH flag on every TCP packet (among other issues). * modules/*/*/*: Reflected changes from elsewhere. * scripts/common/vmware-user.desktop: add missing "Type" information; fixes auto-start of vmware-user on Ubuntu 8.10. * toolbox/*: fix a GTK+ warning caused when trying to unref a dialog instance from a signal callback. * vmware-user/copyPaste.c: work around an issue when OpenOffice's "cut" command is used; it sets the timestamp of both the clipboard and the primary selection, but only puts data in the clipboard. * Other files: minor refactorings, and changes unrelated to open-vm-tools. 2008-10-13 Adar Dembo * Resync with internal trunk (2008.10.09) * configure.ac, modules/Makefile.am: Added a command-line option to skip privileged operations during make install (requested by Dennis Leroy). Integrated new vmxnet3 kernel module. * configure.ac, lib/guestInfo/Makefile.am, lib/guestInfo/guestInfoPerfMonLinux.c, lib/include/vm_procps.h: Removed open-vm-tools dependency on libproc-dev by providing some procps bits and pieces in our own vm_procps.h (Sourceforge bug 1960947). * hgfsmounter/Makefile.am: Removed chown calls. Only call chmod if we're running as root (requested by Dennis Leroy). * */foreignVMToolsDaemon.c, */foundryToolsDaemon.[ch], lib/guestInfo/guestInfo.c, lib/guestInfo/guestInfoServer.c, lib/include/guestInfoServer.h, lib/include/vixTools.h, lib/rpcin/rpcin.c, lib/vixTools/vixTools.c, vmware-user/copyPaste.c, vmware-user/vmware-user.c: More refactoring from the Tools core services project. * */foundryToolsDaemon.c: Changed HGFS mounting behavior such that the global HGFS share is mounted at /mnt/hgfs instead of relying on "mount -a". * guestd/toolsDaemon.[ch], lib/include/backdoor_def.h, lib/include/system.h, lib/include/vm_app.h, lib/system/systemLinux.c: Added backwards time synchronization functionality. Moved Tools scripts checking from VMX to guestd. * hgfsmounter/hgfsmounter.c: Added handling for multiple "-o" flags on the command line. * lib/dynxdr/dynxdr.c: Fixed x_putint32 behavior on 64-bit Solaris. * lib/file/*, lib/include/codeset.h, lib/include/file.h, lib/include/fileIO.h, lib/include/hostinfo.h, lib/include/loglevel_user.h, lib/include/productState.h, lib/include/timeutil.h, lib/include/unicodeTypes.h, lib/include/vixCommands.h, lib/include/vix.h, lib/include/vm_basic_asm.h, lib/include/vm_basic_types.h, lib/include/vm_legal.h, lib/include/vm_product.h, lib/include/win32util.h, lib/include/x86cpuid.h, lib/misc/codeset.c, lib/misc/codesetOld.[ch], lib/misc/posixPosix.c, lib/misc/timeutil.c, lib/region/region.c, lib/string/bsd_vsnprintf.c, lib/unicode/*, lib/user/hostinfoPosix.c, modules/freebsd/vmhgfs/sha1.c, modules/*/*/vm_device_version.h, modules/linux/*/vmci_iocontrols.h, modules/linux/*/vmci_version.h, modules/linux/vmhgfs/hgfsEscape.h: Changes from work unrelated to open-vm-tools on internal trunk. * lib/ghIntegration/ghIntegrationX11.c: Fixed some bugs in menu-spec and desktop-entry-spec support in Linux guests. * lib/guestApp/guestApp.c, lib/include/guestApp.h, lib/include/statelogger_backdoor_def.h, toolbox/Makefile.am, toolbox/toolbox-cmd.c, toolbox/toolbox-gtk.c, toolbox/toolboxCmdInt.h, toolbox/toolboxGtkInt.h, toolbox/toolboxInt.h, toolbox/toolboxRecord.c, toolbox/toolboxcmd-record.c: Patches from Yiwen Zhang to add basic record/replay controls to the gtk and command-line toolbox apps. * lib/guestInfo/guestInfoPosix.c: Fixed a bug where we assumed the primary interface's addresses were all IPv4 addresses. * lib/guestInfo/guestInfoServer.c: Fixed a memory leak. * lib/guestRpc/Makefile.am, lib/guestRpc/unityActive.x, lib/include/guestCaps.h, lib/include/unityCommon.h, lib/unity/unity.c, vmware-user/Makefile.am: Added new unityActive xdr protocol, used for tracking whether Unity is enabled or not. * lib/hgfsServer/hgfsServer.c, lib/hgfsServer/hgfsServerLinux.c, lib/hgfsServerPolicyGuest/hgfsServerPolicyGuest.c, lib/include/hgfsProto.h: Fixed bug where we were invalidating HGFS handles on the share of entire drive ("/"). Added optional symlink following behavior to HGFS server. Fixed a UTF-8 validation issue. Added volume ID field to attribute fields. * lib/include/vm_tools_version.h: Bumped internal Tools backdoor version. * lib/include/vm_version.h: Bumped TOOLS_VERSION. * lib/procMgr/progMgrPosix.c: Fixed impersonation behavior so that uids are passed to setresuid instead of gids. Added alternate way to list processes in situations where a process lacks a command line. * lib/region/region.c: Reforked xorg miregion.c and apply open-vm-tools specific patches. * lib/unity/*, lib/unityWindowTracker/unityWindowTracker.c: Fixed an overflow that lead to a panic when a window title exceeded 1024 bytes. Fixed some initialization assumptions when using virtual desktops. * lib/unity/unityPlatformX11Window.c: Fixed an issue with restacking windows above non-existent windows. Other minor fixes. * modules/*/*/*: Reflected changes from elsewhere. * modules/linux/*/Makefile.kernel: Changed clean target to remove Module.markers and modules.order. * modules/linux/vsock/include/compat_sock.h, modules/linux/vsock/*: Fixed several issues in vsock. 2008-09-03 Adar Dembo * Resync with internal trunk (2008.08.29) * Makefile.am, aclocal.m4, m4/*: Moved macros to 'm4' subdir. * compile, config.guess, config.sub, config/*, depcomp, install-sh, ltmain.sh, missing: Moved auxiliary build tools to 'config' subdir. * configure.ac: Moved macros and auxiliary build tools into separate subdirectories. Added command line option to force the use of gtk1 over gtk2. Cosmetic fixes. Reworked libicu detection. Switched over to libtool-2.2. Added library check for new gdk symbol. Added library check for libnotify. Reworked use of macros from AC_PATH_XTRA and some X11 library checks. * */foundryToolsDaemon.c, toolbox/toolbox-cmd.c, guestd/main.c, lib/guestInfo/guestInfoPerfMonLinux.c, lib/guestInfo/guestInfoPosix.c, lib/misc/posixPosix.c, lib/panic/panic.c, lib/system/systemLinux.c, modules/linux/vsock/linux/util.c, xferlogs/xferlogs.c: Added checks for return codes of certain functions and passed %s to formatted string functions where appropriate (needed to compile on Ubuntu Intrepid). * lib/appUtil/appUtilX11.c: Fixed command line skipping logic and added more icon paths. Removed unnecessary chdir(2) canonicalization logic. * lib/deployPkg/runDeployPkgPosix.c, lib/file/fileIO.c, lib/file/fileIOPosix.c, lib/file/fileLockPrimitive.c, lib/file/filePosix.c, lib/hgfsServer/hgfsServerLinux.c, lib/include/bsdfmt.h, lib/include/file.h, lib/include/fileIO.h, lib/include/iovector.h, lib/include/msgfmt.h, lib/include/str.h, lib/include/vm_basic_defs.h, lib/include/vm_basic_types.h, lib/misc/hostname.c, lib/misc/idLinux.c, lib/misc/posixPosix.c, lib/SLPv2Parser/*.c, lib/wiper/wiperPosix.c, toolbox/toolboxScripts.c: Added FreeBSD compatibility glue. * guestd/toolsDaemon.c, lib/file/file.c, lib/foundryMsg/foundryPropertyListCommon.c, lib/image/imageUtilPng.c, lib/include/appUtil.h, lib/include/backdoor_def.h, lib/include/conf.h, lib/include/cpuid_info.h, lib/include/guest_os.h, lib/include/hostinfo.h, lib/include/imageUtil.h, lib/include/imageUtilTypes.h, lib/include/log.h, lib/include/loglevel_user.h, lib/include/netutil.h, lib/include/posix.h, lib/include/timeutil.h, lib/include/util.h, lib/include/uuid.h, lib/include/vix.h, lib/include/vixOpenSource.h, lib/include/vm_atomic.h, lib/include/vm_legal.h, lib/include/vm_version.h, lib/include/x86cpuid.h, lib/misc/codesetOld.c, lib/misc/timeutil.c, lib/string/bsd_vsnprintf.c, lib/user/util.c, lib/user/utilPosix.c, lib/vixTools/vixTools.c, modules/linux/*/vmci_kernel_if.h, modules/linux/vmxnet/compat_timer.h, toolbox/toolboxCmdInt.h, toolbox/toolboxcmd-*.c: Changes from work unrelated to open-vm-tools on internal trunk. * lib/ghIntegration/ghIntegration.c, lib/guestRpc/ghiGetBinaryHandlers.x: Don't send oversized messages. Increased maximum number of binary handlers. * lib/ghIntegration/ghIntegrationX11.c, lib/guestApp/guestAppPosix.c, lib/include/guestApp.h, lib/include/system.h, lib/system/systemLinux.c, toolbox/toolbox-gtk.c: Improved "run program" functionality by restoring program environment and stripping any VMware wrapper script changes to LD_LIBRARY_PATH. * lib/guestApp/guestAppPosixX11.c: Now using glib to open URLs instead of system(3). Improved gnome and kde session detection. * lib/guestApp/Makefile.am: This library needed GTK_CPPFLAGS too. * lib/guestInfo/guestInfoInt.h, lib/guestInfo/guestInfoPosix.c, lib/guestInfo/guestInfoServer.c: Added logic to optionally convert subnet mask to an ASCII string. * lib/guestRpc/Makefile.am: Cleaned up generated xdr headers better. * lib/hgfsServer/hgfsServer.c, lib/hgfsServer/hgfsServerInt.h, lib/hgfsServer/hgfsServerLinux.c: Fixed problems when packing V3 replies. * lib/hgfsServer/hgfsServerLinux.c: Fixed UTF-8 normal form D/C conversions on the root directory. * lib/include/dndGuest.h: Changed preprocessor usage to allow gtk1 to access UnityDnD. * lib/include/dnd.h, vmware-user/copyPaste.c: Code motion. * lib/include/guestCaps.h: Resort the capabilities table. * lib/include/rpcin.h, lib/rpcIn/rpcin.c, : Beginnings of the Tools core services. This is a full-fledged refactoring of the Tools userlevel apps to a "service" vs. "plugin" programming model. * lib/include/vmblock.h, modules/*/vmblock/block.c, modules/*/vmblock/stubs.c, modules/*/vmblock/stubs.h: Changes needed to support the fuse-based implementation of vmblock (coming soon). * lib/include/vm_tools_version.h: Some Tools version bumps. * modules/*/*/*: Reflected changes from elsewhere. * modules/*/*/compat/compat_stdarg.h: Added compatibility wrappers for stdarg features. * modules/freebsd/vmhgfs/debug.*: Cosmetic fixes. * modules/freebsd/vmhgfs/*: Make driver compliant with HGFSv3. * modules/*/vmmemctl/vmballoon.c: Allow module to yield the processor when allocating many pages. * modules/linux/*/autoconf/cachector1.c, modules/linux/*/include/compat_sched.h, modules/linux/*/include/compat_semaphore.h, modules/linux/*/include/compat_slab.h, modules/linux/vmblock/linux/filesystem.c, modules/linux/*/Makefile.kernel, modules/linux/vmhgfs/bdhandler.c, modules/linux/vmhgfs/filesystem.c, modules/linux/vmhgfs/module.h, modules/linux/vmhgfs/request.c, modules/linux/vmsync/sync.c, modules/linux/vsock/linux/af_vsock.c: Fix modules for 2.6.27 kernels. * modules/linux/*/Makefile: Fixed DRIVER target. * modules/linux/vmci/vmci_drv.c: Moved interrupt registration to be after driver initialization. * modules/linux/vsock/linux/af_vsock.c, modules/linux/vsock/linux/af_vsock.c: Added optimized flow control protocol. * toolbox/toolboxScripts.c, toolbox/toolboxShrink.c: Cosmetic fixes. * vmware-user/copyPaste.c, vmware-user/dnd.c: Fixed edge case behavior with file copy paste and DnD. * vmware-user/modconfig.c, vmware-user/notify.c, vmware-user/vmware-user.c, vmware-user/vmwareuserInt.h: Added stubbed modconfig module out-of-date notification framework. Not useful for open-vm-tools, hence the stubs. 2008-08-08 Adar Dembo * Resync with internal trunk (2008.07.24) * configure.ac, */Makefile.am: Landed support for command line Toolbox, Unity, vsock, and vmci. Refactored and reformatted a few things. Improved portability by using $(SED) and AC_PROG_SED instead of "sed", $(MKDIR_P) and AC_PROG_MKDIR_P instead of "mkdir -p", $(LN_S) and AC_PROG_LN_S instead of "ln -s". Changed icu feature detection and linking to rely on C++ linker instead of C linker. Fixed module compilation checks on FreeBSD. Fixed $(DESTDIR) handling (patch by Mike Auty). Refactored lib/strUtil into lib/misc. Changed hgfsmounter install hook to symlink mount.vmhgfs. Renamed libghIntegrationStub to libGhIntegrationStub. Fixed compilation of lib/guestApp when using --without-x (reported by Martin Preishuber). Renamed libunityStub to libUnityStub. Fix build on FreeBSD by using ":=" instead of "=" when exporting module directories. The vmware-user desktop link now executes vmware-user-suid-wrapper. Properly install vmware-user-suid-wrapper. * */foundryToolsDaemon.c, lib/vixTools/vixTools.c: Use a larger result packet when handling impersonated HGFS requests (since HGFSv3 uses larger packets). * guestd/main.c: Moved foreign VM check. * guestd/toolsDaemon.*: Added plumbing for HGFS usability library calls. * hgfsmounter/hgfsmounter.c: Added support for passing options to the MacOS HGFS driver. * lib/appUtil/*, lib/include/appUtil.h: New library for Unity support. * lib/auth/authPosix.c: Don't try using PAM from the Tools. * lib/dnd/dndCommon.c, lib/dnd/dndLinux.c, lib/file/file.c, lib/file/fileIOPosix.c, lib/file/filePosix.c, lib/include/dnd.h, lib/include/loglevel_user.h, lib/include/panic.h, lib/include/posix.h, lib/include/strutil.h, lib/unicode/unicodeBase.h, lib/include/unicodeOperations.h, lib/include/vix.h, lib/include/vm_app.h, lib/include/vm_assert.h, lib/include/vm_product.h, lib/include/x86cpuid.h, lib/misc/codeset.c, lib/misc/hashTable.c, lib/misc/strutil.c, lib/misc/timeutil.c, lib/panic/panic.c, lib/string/bsd_vsnprintf.c, lib/strUtil/*, lib/unicode/unicodeCommon.c, lib/unicode/unicodeSimpleBase.c, lib/unicode/unicodeStatic.c, lib/user/hostinfoPosix.c, lib/user/util.c, lib/user/utilPosix.c: Changes from work unrelated to open-vm-tools on the internal trunk. * lib/backdoor/backdoorInt.h, lib/deployPkg/runDeployPkgInt.h, lib/dnd/dndInt.h, lib/file/fileInt.h, lib/guestInfo/guestInfoInt.h, lib/hgfs/cpNameInt.h, lib/hgfsServer/hgfsServerInt.h, lib/impersonate/impersonateInt.h, lib/include/backdoorInt.h, lib/include/bsd_output_int.h, lib/include/cpNameInt.h, lib/include/dndInt.h, lib/include/fileInt.h, lib/include/guestInfoInt.h, lib/hgfsServer/hgfsServerInt.h, lib/include/impersonateInt.h, lib/include/runDeployPkgInt.h, lib/include/toolsLoggerInt.h, lib/include/unicodeInt.h, lib/string/bsd_output_int.h, lib/toolsLogger/toolsLoggerInt.h, lib/unicode/unicodeInt.h: Moved some internal header files out of the general include directory and into the appropriate libraries. * lib/ghIntegration/*: New library for Unity support. * lib/guestApp/guestAppPosixX11.c: Reset the value of LD_LIBRARY_PATH before running the web browser. * lib/guestInfo/guestInfoPosix.c, lib/include/guest_os.h: Fixed a typo in Mandriva guest detection. Added Asianux. * lib/guestInfo/guestInfoServer.c: Fixed behavior for sending nicInfo updates to the host (patch by Jason Lunz). * lib/guestRpc/ghi*.*: New xdr protocol for Unity support. * lib/guestRpc/nicinfo.x: Correctly applied LGPL to file. * lib/hgfs/cpNameLinux.c: Allow building for versions of Solaris newer than 10. * lib/hgfsServer/hgfsServer.c, lib/hgfsServerPolicyGuest/hgfsServerPolicyGuest.c, lib/include/hgfsServerPolicy.h: Provide an override setting for disabling case conversion during file lookups. * lib/hgfsServer/hgfsServerLinux.c: Only perform case insensitive file lookups if a case sensitive lookup fails. * lib/image/imageUtilPng.c, lib/include/imageUtil.h, lib/include/imageUtilTypes.h: New library for Unity support. * lib/include/conf.h, toolbox/toolbox-gtk.c: Robustified the help page discovery mechanism. * lib/include/dndGuest.h: Allow inclusion of header into source files without GTK2 support. * lib/unity/*, lib/include/guestCaps.h, lib/include/unityCommon.h: New library for Unity support. * lib/include/hgfsUtil.h: Fixed a precedence issue in a macro. * lib/raster/*, lib/include/rasterConv.h: New library for Unity support. * lib/region/*, lib/include/region.h: New library for Unity support. * lib/include/system.h: Added new OS type for WinXP 64-bit, reformatted enums. * lib/unityWindowTracker/*, lib/include/unityWindowTracker.h: New library for Unity support. * lib/include/vm_version.h: Bumped TOOLS_VERSION. * lib/wiper/wiperPosix.c: Replaced BSD_VERSION with __FreeBSD_version. * modules/*/*/*: Reflected changes from elsewhere. * modules/freebsd/vmhgfs/*: Reflected changes from MacOS HGFS work, and fixed file permissions so that they're not all owned by root. * modules/linux/vmblock/linux/dentry.c: Changed d_revalidate to properly invalidate negative dentries. * modules/linux/vmci/*: Landed the Virtual Machine Communication Interface guest module. * modules/linux/vmmemctl/os.c: Fixed vmmemctl to build on 2.6.26 (reported by Pavol Rusnak). * modules/linux/vmsync/sync.c: Fixed vmsync to build on 2.6.26 (reported by Pavol Rusnak). * modules/linux/vsock/*: Landed the VMCI sockets interface module. * modules/linux/vmxnet/vmxnet.c, modules/linux/vmxnet/vmxnet2_def.h, modules/linux/vmxnet/vmxnetInt.h: Increased rx ring size for enhanced vmxnet2. * toolbox/*: Refactored pieces of GTK Toolbox and landed the command line Toolbox. Fixed mnemonic collisions in the GTK Toolbox. * vmware-user/copyPaste.c: Fixed several bugs with file copy paste behavior. * vmware-user/notify.c, vmware-user/vmware-user.c, vmware-user/vmwareuserInt.h: Added stubs for notification framework. * vmware-user/pointer.c: Reverted fix for bug with clipboard retry behavior. * vmware-user/vmware-user.c: Fixed build with gtk 1.2 (reported by Stephen Duncan). Added signal handlers for SIGUSR1/SIGUSR2 used by VMware Tools installer to reload vmware-user cleanly during a Tools upgrader. Reload vmware-user on a fatal X I/O error. Don't panic if run outside of a VM. Don't leave Unity mode on a Tools reset. 2008-07-01 Adar Dembo * Resync with internal trunk (2008.06.30) * configure.ac, lib/guestApp/*, toolbox/Makefile.am, vmware-user/Makefile.am: Split lib/guestApp into two libraries, one with X11 functionality, and one without. Improved detection of gnome-open. * guestd/*, lib/netUtil/netUtilLinux.c: guestd now compiles for MacOS guests. * guestd/main.c, lib/include/system.h, lib/system/systemLinux.c: Refactored GuestdWritePidfile into System_Daemon. * guestd/toolsDaemon.c: Fixed a backwards time synchronization issue. Thanks to Eric Castan for reporting the bug. * lib/conf/conf.c, lib/include/conf.h: Removed obsolete configuration keys and values. * lib/file/*, lib/dict/*, lib/foundryMsg/*, lib/include/backdoor_def.h, lib/include/codeset.h, lib/include/config.h, lib/include/file_extensions.h, lib/include/fileInt.h, lib/include/loglevel_user.h, lib/include/msg.h, lib/include/msgid.h, lib/include/posix.h, lib/include/preference.h, lib/include/unity.h, lib/include/vixCommands.h, lib/include/vix.h, lib/include/vmbackup_def.h, lib/include/vmBackup.h, lib/include/vm_basic_defs.h, lib/include/vm_basic_types.h, lib/include/vm_product.h, lib/include/win32util.h, lib/include/x86cpuid.h, lib/misc/codeset.c, lib/misc/codesetOld.c, lib/misc/codesetOld.h, lib/misc/posixPosix.c, lib/strUtil/strutil.c, lib/user/hostinfoPosix.c, lib/user/util.c, lib/vmBackupLib/stateMachine.c, modules/*/vmxnet/net.h: Changes from work unrelated to open-vm-tools on the internal trunk. * lib/guestRpc/Makefile.am: Added comment about misuse of CFLAGS. * lib/hgfsServer/hgfsServer.c: Corrected pointer arithmetic so that new node and search allocation works consistently in 64-bit apps. * lib/hgfsServer/hgfsServerLinux.c, lib/include/hgfsProto.h: Added HGFS_ATTR_HIDDEN_FORCED and set it when returning hidden files. * lib/hgfsServer/*, lib/hgfsServerPolicy/hgfsServerPolicyGuest.c, lib/include/hgfsServerInt.h, lib/include/hgfsServerPolicy.h: Refactored and cleaned up some code. * lib/include/resolution.h, lib/resolution/*, vmware-user/vmware-user.c: Refactored some functions. * lib/include/vm_legal.h: Added another patent to the patent string. * lib/include/vm_tools_version.h: Added a pair of Tools version macros. * lib/include/vm_version.h: Bumped Tools product version. * lib/Makefile.am: Included a fix for compilation --without-x. Thanks to Mark Foster for reporting the issue. * lib/misc/Makefile.am, lib/misc/shared/Makefile.am: Realphabetized some sources and added missing source files. * lib/misc/posixWin32.c: Removed unneeded file from tree. * lib/procMgr/procMgrPosix.c: Made safe for -fPIC and for MacOS. * modules/*/*/*: Reflected changes from elsewhere. * modules/freebsd/vmhgfs/*: Added some code to handle codeset conversions between UTF-8 precomposed and decomposed strings. * modules/linux/vmhgfs/*: Refactored string escaping/unescaping code. * toolbox/*: Added mnemonics for some buttons. * vmware-user/pointer.c: Fixed bug in clipboard retry behavior. * vmware-user/vmware-user.c: Added handlers for SIGUSR1 and SIGUSR2 to facilitate smooth vmware-user upgrades with respect to the vmblock kernel module. 2008-06-20 Elliot Lee * Resync with internal trunk (2008.06.13) * FreeBSD 7/8 fixes from Martin Blapp. * Fix getpwnam_r etc. on FreeBSD & Solaris. * configure.ac: Add --without-kernel-modules, --with-linux-release, and --with-linuxdir (gissa). * configure.ac, lib/guestRpc/*, lib/guestInfo/guestInfo.c, lib/guestInfo/guestInfoServer.c, lib/dynxdr/*, {vmware-user,guestd}/foreignVMToolsNetworking.c, guestd/Makefile.am, {vmware-user,guestd}/foundryToolsDaemon.c, lib/include/dynxdr.h, lib/include/guestInfo.h, lib/include/vmxrpc.h, lib/include/xdrutil.h, lib/Makefile.am, lib/netUtil/*, lib/vixTools/Makefile.am: Add support for XDR encoding of RPC values, including the NicInfoV2 structure. * guestd/stub.c, hgfsclient/Makefile.am, hgfsclient/stub.c, hgfsclient/stub-user-util.c, hgfsmounter/Makefile.am, hgfsmounter/stub.c, lib/stubs/*, libguestlib/Makefile.am, libguestlib/stubs.c, toolbox/Makefile.am, toolbox/stub.c, vmware-user/stub.c: Centralize stubs. * lib/guestInfo/guestInfoPerfMonLinux.c: Convert ioInRate and ioOutRate to be in terms of KB instead of pages. * lib/hgfsBd/hgfsBd.c, lib/hgfsServer/hgfsServer.c, lib/hgfsServer/hgfsServerLinux.c: Large packet support, and additional case-insensitivity fixes. * lib/include/hgfsBd.h, lib/include/hgfs.h, lib/include/hgfsProto.h: Add HGFS error code. * lib/hgfs/hgfsUtil.c, lib/guestInfo/Makefile.am, lib/guestInfo/guestInfoPosix.c, lib/guestApp/guestApp.c, lib/foundryMsg/foundryMsg.c, lib/file/fileLockPrimitive.c, lib/file/fileIOPosix.c, lib/file/fileLockPosix.c, guestd/toolsDaemon.c, guestd/debugStdio.c, guestd/main.c, lib/hgfsServerManagerGuest/hgfsServerManagerGuest.c, lib/include/codeset.h, lib/include/cpuid_info.h, lib/include/dnd.h, lib/include/file_extensions.h, lib/include/fileInt.h, lib/include/ghIntegration.h, lib/include/guestApp.h, lib/include/guestStats.h, lib/include/hgfsServerInt.h, lib/include/hgfsUtil.h, lib/include/hostinfo.h, lib/include/loglevel_user.h, lib/include/netutil.h, lib/include/panic.h, lib/include/posix.h, lib/include/unicode*.h, lib/include/util.h, lib/include/vix.h, lib/include/vixTools.h, lib/include/vm_app.h, lib/include/vm_basic_defs.h, lib/include/vm_product.h, lib/include/vm_tools_version.h, lib/include/vm_version.h, lib/include/x86cpuid.h, lib/misc/codeset.c, lib/misc/codesetOld.c, lib/misc/codesetOld.h, lib/misc/hashTable.c, lib/misc/hostname.c, lib/misc/timeutil.c, lib/panic/panic.c, lib/string/str.c, lib/sync/syncMutex.c, lib/system/systemLinux.c, lib/unicode/*.c, lib/unityStub/*, lib/user/hostinfo.c, lib/user/hostinfoPosix.c, lib/vixTools/*, modules/linux/vmxnet/*, toolbox/debugStdio.c, vmware-user/debugStdio.c, vmware-user/dnd.c, vmware-user/main.c: Bug fixes. * modules/linux/vmxnet/*: Remove unused BPF code. Add ethtool callbacks to get & set driver settings. * lib/user/util.c: Add function for getting backtraces. * lib/resolution/*, vmware-user/*, lib/Makefile.am, configure.ac: Move resolution-changing code into separate library. * guestd/main.c, lib/include/tools.h: Allow disabling tools version reporting to the host, via config file. * lib/rpcIn/*, lib/include/rpcin.h, guestd/toolsDaemon.c, toolbox/toolbox-gtk.c: Updated RPC API * lib/include/dndGuest.h: Helper API for DnD code * modules/freebsd/vmhgfs/*, modules/freebsd/vmmemctl/*, modules/freebsd/vmblock/*, modules/linux/vmhgfs/*, modules/linux/vmmemctl/*: Reflect changes from main source tree. * vmware-user/copyPaste.c: Copy/paste cleanup. * vmware-user/vmware-user.c: Updated locking code to use X11 display instead of lockfiles. 2008-06-03 Adar Dembo * Resync with internal trunk (2008.05.28). * configure.ac, Makefile.am, */Makefile.am: Added rudimentary `make install` support. Fixes Sourceforge bug 1839981. * configure.ac, Makefile.am, vmware-user-suid-wrapper/*: Added vmware-user-suid-wrapper to help autostart vmware-user. Added some informational tags to AC_DEFINE macros. * */debugStdio.c: Fixed a format string vulnerability in Debug. Allocate fd on the stack in DebugToFile. * lib/auth/authPosix.c, lib/dnd/dndCommon.c, lib/dnd/dndLinux.c lib/impersonate/impersonate.c: Add inclusion of vmware.h and refactor some include statements. * lib/file/file.c, lib/include/file.h: Added File_UnlinkNoFollow function. * lib/file/fileIO.c, lib/file/fileLockPrimitive.c, lib/include/fileIO.h: Added error case for ENAMETOOLONG to FileIO_Lock. Constified 'buf' in FileIO_Pwrite. * lib/file/fileIOPosix.c: Removed coalescing and decoalescing code. Consolidated some Unicode calls. * lib/file/filePosix.c: Reworked some error handling logic. * lib/foundryMsg/foundryMsg.c: Refactored buffer encoding and decoding logic into a single pair of functions. * lib/foundryMsg/foundryThreads.c, lib/include/foundryThreads.h lib/include/util.h, lib/misc/util_misc.c: Changed generic thread type from uintptr_t to Util_ThreadID. * lib/hgfsServer/*, lib/hgfs/hgfsProto.h, modules/linux/vmhgfs/*: Additional HGFSv3 fixes and refactoring. * lib/include/dbllnklst.h, lib/misc/dbllnklst.c: Constified argument to DblLnkLst_IsLinked. * lib/include/dnd.h: Added support for DnD of RTF. * lib/include/fileInt.h: Removed prototype of FileLockFileSize. * lib/include/hashTable.h, lib/misc/hashTable.c: Cosmetic changes. Added HashTable_ReplaceIfEqual. * lib/include/loglevel_user.h: Added hpet loglevel. * lib/include/msg.h: Removed prototype of MsgSetPostStderrBlock. * lib/include/posix.h: Removed certain includeCheck allowances. * lib/include/productState.h: Added VDM client product. * lib/include/unicode*, lib/unicode/*: Ongoing i18n work. * lib/include/vixCommands.h: Added command to set snapshot information. * lib/include/vix.h: Added more errors and a new flag. * lib/include/vixOpenSource.h: Reworked asserts and added VIX_ASSERT. * lib/include/vm_app.h: Added Tools tray app. * lib/include/vm_product.h: Reworked VMRC product definitions and added VDM client product definitions. * lib/include/vm_tools_version.h: Added WS65 Tools version. * lib/include/vm_version.h: Bumped Tools version. Added logic for VMRC product. * lib/include/x86cpuid.h: Modified a flag and trimmed an unneeded macro. * lib/misc/codesetOld.c: Implement UTF-16 codest conversion to UTF-8 for CURRENT_IS_UTF8. * lib/misc/dynbuf.c: Modified dynbuf growing behavior. * lib/misc/posixDlopen.c, lib/misc/posixInt.h, lib/misc/posixPosix.h: Refactored codeset conversion code into PosixConvertToCurrent. * lib/misc/posixWin32.c: Added some path checks. * lib/misc/timeutil.c: Win32-wrappified TimeUtil_GetTimeFormat. * lib/misc/vmstdio.c: Reduce virtual memory usage and add '\r' as a line ending in StdIO_ReadNextLine. * lib/rpcout/rpcout.c: Added comments. * lib/str/str.c: Cosmetic changes. * lib/vixTools/vixTools.c: Added unlink(2) logic to avoid deleting symlink targets. Cosmetic changes. * modules/*/*/*: Reflect changes from elsewhere in the source tree. * modules/linux/vmhgfs/super.c: Fix vmhgfs to properly report the available space on the host (Sourceforge bug 1924246). * vmware-user/vmware-user.c: Add advisory locking code to help maintain only one vmware-user instance per X session. * xferlogs/xferlogs.c: Fix a formatted string vulnerability. 2008-05-12 Elliot Lee * Resync with internal trunk (2008.05.08). * configure.ac, **/Makefile.am: Use CPPFLAGS instead of CFLAGS to eliminate warning about proc/sysinfo.h. * guestd/foreignVMToolsNetworking.c, vmware-user/foreignVMToolsNetworking.c lib/hgfsServer/hgfsServerLinux.c, lib/include/hgfsServerInt.h, modules/linux/vmhgfs/bdhandler.c, modules/linux/vmhgfs/dir.c, modules/linux/vmhgfs/file.c, modules/linux/vmhgfs/filesystem.h, modules/linux/vmhgfs/fsutil.h, modules/linux/vmhgfs/inode.c, modules/linux/vmhgfs/link.c, modules/linux/vmhgfs/module.h, modules/linux/vmhgfs/page.c, modules/linux/vmhgfs/request.c, modules/linux/vmhgfs/request.h: Whitespace cleanups. * guestd/main.c: Removed "blessed app" code for starting vmware-user. Hooray! * lib/deployPkg/deployPkg.c: Remove unneeded Utf8 conversion for Windows. * lib/file/filePosix.c: Use new Posix_RealPath implementation. * lib/guestApp/guestApp.c, lib/include/guestApp.h: Remove/cleanup UTF-8 related RPC functions. * lib/guestInfo/guestInfoPerfMonLinux.c, lib/guestInfo/guestInfoPosix.c, lib/include/guestInfo.h, lib/include/guestInfoInt.h, lib/include/guestStats.h: Rename structures to GuestMemInfo, GuestNicInfo, and GuestDiskInfo. * lib/guestInfo/guestInfoServer.c, lib/include/guest_msg_def.h: As above, and also GUESTMSG_MAX_IN_SIZE moved to guest_msg_def.h, and misc locking updates. Also add GuestInfoServer_Main(), and cleanup whitespace. * lib/hgfsServer/hgfsServer.c: Cleanup UTF-8 handling. * lib/include/codeset.h: Update defines that indicate whether the current platform is using UTF-8. * lib/include/dnd.h: Add prototypes for a couple of string conversion functions. * lib/include/file_extensions.h: Add OVF and Archived OVF file extensions. * lib/include/file.h: C++ guard thingies. Update a couple of function prototypes to work on file descriptors instead of filenames. * lib/include/hashTable.h, lib/include/guest_os.h, lib/include/loglevel_defs.h, lib/include/stats_user_defs.h, lib/include/stats_user_setup.h, lib/include/str.h, lib/include/unicodeTypes.h, lib/include/util.h: Allow inclusion in kernel modules... * lib/include/loglevel_user.h: As above, and add a couple of loglevel variables. * lib/include/util.h, lib/misc/util_misc.c: Allow inclusion in kernel modules as above, and add some utility functions on Windows for manipulating canonical paths. * lib/include/hgfsProto.h, lib/include/hgfsUtil.h: Move request/reply payload macros to hgfsProto.h. * lib/include/hgfsServerPolicy.h: Add ShareList management prototypes and structure members. * lib/include/msg.h: Add function prototypes for creating and posting lists of messages. * lib/include/system.h: Add types & functions related to desktop switch monitoring on Windows. * lib/include/unicodeOperations.h: Add/update inline unicode operations. * lib/include/vixCommands.h: Add VIX requests and events. * lib/include/vmbackup_def.h, lib/vmBackupLib/stateMachine.c: Move backup status enum to public header. * lib/include/vm_basic_asm_x86_64.h: Div643232 now also works on MSC. * lib/include/vm_basic_defs.h: Add debug output macros for Windows drivers. * lib/include/vm_basic_types.h: Update the FMTPD macro, add SCANF_DECL macro for arg checking on scanf-like functions. * lib/include/x86cpuid.h: Defines for AMD L2/L3 cache separately, and CPUID for Nehalem. * lib/misc/codesetOld.c: Bug fixes and general unicode handling updates. * lib/system/systemLinux.c: Use Posix_Getenv/Posix_Setenv impls. * lib/vixTools/vixTools.c, lib/vmBackupLib/scriptOps.c: Bug fixes. * modules/freebsd/*, modules/linux/*: Updates to correspond to updates of files in main tree. * modules/freebsd/vmhgfs/hgfs_kernel.h: Bug fixes. * modules/freebsd/vmxnet/vm_device_version: Add SCSI_IDE_HOSTED_CHANNEL define, update SCSI_MAX_CHANNELS. * modules/freebsd/vmxnet/vmnet.def: Add capabilities for IPv6 checksumming and TSO, and large packet TSO. * lib/include/vmblock.h, modules/linux/vmblock/linux/control.c, modules/linux/vmblock/linux/vmblockInt.h: Use a macro to better abstract the vmblock mount point & device. * vmware-user/vmware-user.c: Add SIGPIPE to the list of signals that vmware-user handles. 2008-05-02 Adar Dembo * Resync with internal trunk (2008.04.19). * configure.ac, guestd/Makefile.am, hgfsclient/Makefile.am, lib/misc/*/Makefile.am, lib/string/*/Makefile.am, toolbox/Makefile.am, vmware-user/Makefile.am, xferlogs/Makefile.am: Added libicu support for codeset conversions. This includes some makefile logic as well as autoconf arguments for controlling libicu behavior at compile-time. * */foreignVMToolsNetworking.c, lib/vixTools/vixTools.c: Unicode fixes. * */foundryToolsDaemon.c, lib/foundryMsg/vixTranslateErrOpenSource.c, lib/panic/panic.c, lib/printer/printer.c: Added calls to Win32 Unicode wrappers. * guestd/main.c: Cleaned up guestInfo server when guestd shuts down. * guestd/toolsDaemon.c, vmware-user/resolution.c: Disabled multi-mon advertisement for Win2k. * lib/auth/authPosix.c, lib/dnd/dndLinux.c, lib/file/*, lib/impersonate/impersonatePosix.c, lib/include/mntinfo.h, lib/sync/syncWaitQPosix.c, lib/user/hostinfoPosix.c, lib/user/util.c, lib/user/utilPosix.c, lib/wiper/wiperPosix.c: Added calls to POSIX Unicode wrappers. * lib/file/*: Replaced calls to string functions with calls to the "safe" family of string functions. * lib/dict/dictll.c, lib/include/dictll.h: Detect and tolerate UTF-8 dictionary files that contain the UTF-8 BOM. * lib/err/*, lib/include/err.h, lib/include/msgfmt.h, lib/include/msg.h: Added support for localization of error strings. * lib/foundryMsg/foundryThreads.c, lib/include/foundryThreads.h, lib/misc/util_misc.c: Added opaque type for threads/process IDs. * lib/guestInfo/guestInfoServer.c: Removed separate thread context. * lib/hgfsServer/*, lib/include/hgfs*.h: Additional HGFSv3 cleanup. * lib/hgfsServer/hgfsServerLinux.c: Added calls to POSIX Unicode wrappers. Fixed some alias detection code for MacOS. * lib/include/backdoor_def.h: Added backdoor call for debugging events. * lib/include/bsdfmt.h, lib/string/bsd_vsnprintf.c, lib/string/bsd_vsnprintfw.c: Replaced BSDFmt_WCSonv with BSDFmt_WChartoUTF8. * lib/include/codeset.h, lib/include/codesetOld.h, lib/misc/codeset.c, lib/misc/codesetOld.c, lib/string/convertutf.h: Implemented libicu-backed codeset layer. When building without libicu, fallback on codesetOld. * lib/include/guestApp.h: Added wide versions of dictionary functions. * lib/include/loglevel_user.h: Added two new loglevels. * lib/include/posix.h, lib/misc/posixPosix.c: Added new POSIX wrappers. * lib/include/str.h: Clarified the use of some functions. * lib/include/syncMutex.h, lib/include/syncWaitQ.h: Removed unneeded macros. * lib/include/unicode*.h, lib/unicode/*: Ongoing Unicode work. * lib/include/util.h: Added Util_FreeStringList, removed Util_FreeList. * lib/include/uuid.h: Added new UUID creation scheme. * lib/include/vix*.h: Tweaked some VIX commands, errors, and properties. * lib/include/vmBackup.h, lib/vmBackupLib/scriptOps.c, lib/vmBackupLib/stateMachine.c: Moved disabled targets logic from library to Windows VSS provider. * lib/include/vm_basic_asm_x86*.h: Allow emitted FX functions to modify main memory as a side effect. * lib/include/vm_tools_version.h: Bump Tools version. * lib/include/vm_version.h: Added several product versions. * modules/linux/vmhgfs/*: Additional cleanup for HGFSv3. Use new kthread wrapper when possible. Bump module version. * modules/linux/vmmemctl/*: Use new kthread wrapper when possible. Remove dead delayed work code. Bump module version. * modules/linux/*/compat_kthread.c: Added kthread wrapper implementation for modules that use kernel threads. * modules/*/*/*: Reflect header file changes from elsewhere in the source code tree. * vmware-user/copyPaste.c, vmware-user/pointer.c, vmware-user/vmwareuserInt.h: Stop wastefully polling for pointer updates if the VMX is new enough. * xferlogs/xferlogs.c: Fixed a warning in the call to fwrite. (Thanks to Denis Leroy for reporting this bug.) 2008-04-14 Elliot Lee * Resync with internal trunk (2008.04.01). * Fixed legal header on all LGPL-licensed files. * vmware-user/resolution.c: Normalize the display topology that comes in from the host, and report 'global_offset' capability. * toolbox/Makefile.am, vmware-user/Makefile.am, lib/misc/Makefile.am, lib/misc/atomic.c, lib/Makefile.am, lib/atomic/*, hgfsclient/Makefile.am: Move libAtomic stuff into libmisc * vmware-user/foundryToolsDaemon.c, lib/vixTools/vixTools.c, lib/include/hgfsServerInt.h, guestd/toolsDaemon.c, guestd/foundryToolsDaemon.c: Remove WIN9XCOMPAT, and some SOCKET_MGR code. * vmware-user/copyPaste.c: Copy/paste fixes for cross-platform operation. * modules/linux/vmxnet/vmnet_def.h: Add SG_SPAN_PAGES capability. * modules/linux/vmxnet/vm_device_version.h: Update some device limits. * modules/linux/*/compat_sched.h: Add TASK_COMM_LEN define. * modules/linux/*/compat_kernel.h, modules/linux/*/kernelStubsLinux.c: Add vsnprintf define. * modules/linux/*/x86cpuid.h: Add new CPUs. * modules/linux/vmhgfs/vmhgfs_version.h: Bump HGFS version. * modules/linux/*/vm_basic_asm_x86.h, modules/linux/*/vm_basic_asm_x86_64.h, lib/include/vm_basic_asm_x86.h, lib/include/vm_basic_asm_x86_64.h: Formatting fixes, and change asm directives used. * modules/linux/vmhgfs/module.h, modules/linux/vmhgfs/filesystem.c, modules/linux/vmhgfs/bdhandler.c, modules/linux/*/compat_kthread.h: compat_kthread fixes. * modules/freebsd/vmxnet/net_compat.h, modules/freebsd/vmxnet/if_vxn.c: Updates for FreeBSD 7.0. (Thanks to Martin Blapp for contributing to these changes.) * lib/misc/util_misc.c, lib/include/loglevel_user.h, lib/user/hostinfoPosix.c, lib/misc/hostname.c: Bugfix. * lib/unityStub/unityStub.c, lib/include/unity.h: Add stub and enums related to DnD support. * lib/unicode/unicodeSimpleTypes.c, lib/unicode/unicodeSimpleTransforms.c, lib/unicode/unicodeSimpleBase.c, lib/unicode/unicodeCommon.c, lib/include/unicodeTypes.h, lib/include/unicodeTransforms.h, lib/include/unicodeBase.h, lib/include/unicodeCommon.h: Add additional Unicode-related functions. * lib/sync/syncMutex.c, lib/include/syncMutex.h: Add TryLock method. * lib/strUtil/strutil.c: Add int64-related functions. * lib/string/str.c: Compile fix * lib/string/bsd_output_shared.c: Better handling of floating point on Windows. * lib/include/progMgr.h, lib/procMgr/procMgrPosix.c: Clarify that the strings are in UTF-8, do conversion as needed. * lib/include/posix.h, lib/misc/posixPosix.c, lib/misc/posixWin32.c, lib/file/filePosix.c: Add new Posix_ function implementations, and unicodify existing ones. * lib/misc/hashTable.c, lib/include/hashTable.h: Add lock-less hash table functions. * lib/misc/util_misc.c, lib/include/w32util.h: Add a couple of Win32 utility functions. * lib/include/vm_version.h: Add WS5 config version. * lib/include/vm_atomic.h: Add typecasts to atomic operations to make compilers stop complaining, and expand the AtomicUseFence option. * lib/include/vm_app.h: Add a couple of HGFS-related options. * lib/include/vix.h: Update a few errors and other macros. * lib/include/vixCommands.h, lib/foundry/foundryMsg.c: Change a bunch of structure members from int32 to uint32, and add a parsing function. * lib/include/msgfmt.h, lib/include/msg.h: Additional message-handling prototypes. * lib/include/guestInfoInt.h, lib/include/guestInfo.h, lib/guestInfo/Makefile.am, lib/guestInfo/guestInfoServer.c, lib/guestInfo/guestInfoPosix.c, lib/guestInfo/guestInfoPerfMonLinux.c: Add IPv6 support, and the ability to read mem stats on Linux. * lib/include/fileIO.h, lib/file/fileIOPosix.c: Add MacOS function related to Time Machine. * lib/guestApp/guestApp.c: Use Posix_ variants of functions. * lib/ghIntegrationStub/ghIntegrationStub.c: Add GHI capabilities stubs. * lib/dnd/dndCommon.c, lib/file/file.c: Use new Unicode_Format() function, bugfix. * guestd/main.c: Fix a security bug. * configure.ac: Allow calling libdnet 'dumbnet' for Debian systems. Detect libprocps. 2008-03-19 Adar Dembo * Resync with internal trunk (2008.03.13). * vm_version.h: Updated Tools version. * configure.ac: Added dynamic dnet detection and --without-dnet flag. * guestd/debugStdio.c, lib/include/system.h, lib/system/systemLinux.c: Modified debugging to file behavior to prepend debug strings with human readable timestamps. * guestd/main.c, guestd/toolsDaemon.c, lib/conf/conf.c, lib/guestApp/guestApp.c, lib/include/guestApp.h: Internationalized GuestApp_GetInstallPath and GuestApp_GetconfPath. * lib/auth/authPosix.c, lib/dnd/dndLinux.c, lib/file/*, lib/impersonate/impersonatePosix.c, lib/include/fileInt.h, lib/include/posix.h, lib/misc/posix*.c: Refactored, extended, and made use of the set of POSIX internationalization-safe function wrappers. * lib/dnd/dndCommon.c, lib/include/dnd.h, lib/include/dndInt.h, vmware-user/copyPaste.c, vmware-user/dnd.c: Replaced some duplicated UTF-8 formatting code with calls to lib/unicode. * lib/guestInfo/guestInfoPosix.c: Replaced the old syscall-based implementation of nicinfo with a simpler implementation that uses dnet. * lib/guestInfo/guestInfoServer.c, lib/include/guestInfo.h, lib/include/guestInfoInt.h: Added Win32 implementation of meminfo. POSIX implementation to follow. * lib/hgfsServer/hgfsServerLinux.c: Replaced a direct readlink(3) call with a call to the POSIX wrapper for readlink(3). Relax an overeager ASSERT in symlink checking when using the special empty share. * lib/include/codeset.h, lib/string/bsd_vsnprintf.c, lib/string/str.c, lib/unicode/unicodeSimpleOperations.c, lib/unicode/unicodeSimpleUTF16.h: Refactored ICU routines from unicodeSimpleUtf16.h to codeset.h, which is now licensed under the ICU license (BSD variant). * lib/include/file.h, lib/file/file.c: Added function File_StripSlashes. * lib/include/hgfsProto.h: Removed an A acute from a comment to allow the file to be built on Windows systems where the default language isn't English. * lib/include/hostinfo.h, lib/include/util.h, lib/user/hostinfoPosix.c, lib/user/util.c, lib/user/utilPosix.c: More conversions to lib/unicode. Added Util_ZeroFreeStringW function for Windows in util.h. * lib/include/msg.h: Removed obsolete NO_MSGFMT macro. * lib/include/unicodeBase.h, lib/unicode/unicodeCommon.c, lib/unicode/unicodeSimpleBase.c: Added some more encoding functions. * lib/include/vixCommands.h, lib/include/vixOpenSource.h: Added another user credential type, some command flags, some command layouts, some error codes, some properties, and tweaked existing commands. * lib/include/vixTools.h: Added VixToolsUserIsMemberOfAdministratorGroup function. * lib/include/vm_assert.h, lib/include/vm_basic_defs.h: Move IMPLIES to vm_basic_defs.h. Removed some vprobes definitions. * lib/include/vmBackup.h, lib/vmBackupLib/scriptOps.c, lib/vmBackupLib/stateMachine.c: Added infrastructure to disable quiescing targets from a config file. * lib/include/vm_basic_asm.h: Changed __GET_CPUID2 handling for Windows. * lib/include/vm_produt.h: Added VDM product. * lib/include/vm_tools_version.h: Bumped internal Tools version. * lib/include/win32util.h, lib/misc/hostname.c, lib/misc/util_misc: Refactored functions to separate set of Win32 wrappers (next to the POSIX wrappers mentioned earlier). * lib/misc/codeset.c: Made CodeSetGetCurrentCodeSet non-static. * lib/misc/*/Makefile.am: Added POSIX wrappers to build system. * lib/strUtil/strutil.c: Fixed bug in StrUtil_EndsWith function. * lib/include/unicodeTypes.h, lib/unicode/unicodeSimpleTypes.c: Removed ISO-8859-11 encoding. Added cross-reference of IANA character set names, windows code pages, and ICU encodings. * lib/vixTools/vixTools.c: Impersonation tweaks. * modules/*/*/*: Reflect header file changes from elsewhere in the source code tree. 2008-03-11 Adar Dembo * vm_version.h: Updated Tools version. * modules/vmblock/linux/*: Make vmblock build under 2.6.25-rc2. The dentry and mount objects have been moved out of struct nameidata and into the new struct path. Also, path_release() is now path_put(). * modules/vmsync/linux/*: Make vmsync build under 2.6.25-rc2. The same changes were needed here as in vmblock above. 2008-03-10 Adar Dembo * vm_version.h: Updated Tools version. * modules/vmhgfs/linux/*: Make vmhgfs build under 2.6.25-rc1. The iget() function has been removed and filesystems are now expected to implement it themselves using iget_locked(). 2008-02-27 Elliot Lee * configure.ac, guestd/Makefile.am, toolbox/Makefile.am, vmware-user/Makefile.am: Allow passing custom LDFLAGS in to build process (patch by Mike Auty). * Resync with internal trunk (2008.02.27). * guestd/foundryToolsDaemon.c, lib/vixTools/vixTools.c, vmware-user/foundryToolsDaemon.c: Win9x compat changes. * guestd/toolsDaemon.c: Style fixes. * hgfsmounter/hgfsmounter.c: Bug fixes. * lib/dnd/dndLinux.c, lib/dnd/dndCommon.c: Move some code to the platform-independant file, some DnDv3 support. * lib/include/dnd.h, lib/include/dndInt.h: DnDv3 support. * lib/file/file.c, lib/file/fileIO.c, lib/file/fileIOPosix.c, lib/file/fileLockPrimitive.c, lib/file/filePosix.c, lib/include/file_extensions.h, lib/include/fileInt.h, lib/include/fileIO.h: Move functions around, Unicode fixes, misc fixes. * lib/foundryMsg/foundryPropertyListCommon.c: Error handling fixes. * lib/hgfsServer/*.c, lib/include/hgfs*.h, modules/freebsd/vmhgfs/*, modules/linux/vmhgfs/*: HGFS v3 support, updates to improve code re-use between the FreeBSD and MacOS X ports, and updates to make the Linux port build on 2.6.25-rc1 (but not rc2, yet). * lib/include/auth.h, lib/include/codeset.h, lib/include/hostinfo.h, lib/include/str.h, lib/include/unicode*.h, lib/include/vm_basic_types.h, lib/misc/hostname.c, lib/unicode/*.c, lib/user/hostinfoPosix.c: Unicode fixes. * lib/include/backdoor_def.h: Add a new command for use by the BIOS in checking the GuestOS against Darwin. * lib/include/dynarray.h, lib/misc/dynarray.c, lib/misc/Makefile.am, lib/misc/shared/Makefile.am: Add Dynarray implementation. * lib/include/bsdfmt.h, lib/include/bsd_output_int.h, lib/string/bsd_output_shared.c, lib/string/bs_vsnprintf.c, lib/string/bsd_vsnwprintf.c, lib/string/str.c: Rework built-in printf implementation, esp. for Unicode fixes. * lib/include/ghIntegration.h: Shuffle types around. * lib/include/loglevel_user.h, lib/include/unity.h, lib/syncDriver/syncDriverPosix.c, lib/user/util.c, toolbox/toolbox-gtk.c: Misc fixes. * lib/include/vmBackup.h, lib/vmBackupLib/scriptOps.c, lib/vmBackupLib/stateMachine.c, lib/vmBackupLib/vmBackupInt.h: Rework scripts for freeze & thaw operations. * lib/include/vm_product.h, lib/include/vm_version.h: Add new product defs (VMRC). * lib/include/vm_tools_version.h: Add ESX 3.5U1 product. * lib/include/vixCommands.h, lib/include/vix.h: Add new VIX commands and error code. * lib/include/win32util.h: Add misc Win32 utilities. * modules/*/*/*: Reflect header file changes from elsewhere in the source code tree. 2008-02-13 Adar Dembo * Resync with internal trunk (2008.02.12). * configure.ac, lib/unityStub/*, lib/ghIntegrationStub/*, lib/Makefile.am, vmware-user/Makefile.am, vmware-user/vmware-user.c: Added lib/unityStub and lib/ghIntegrationStub. Unity and guest-host integration features for X11 guests are on the way. * configure.ac, guestd/Makefile.am, lib/fileUtf8/*, lib/vixTools/vixTools.c, vmare-user/Makefile.am: lib/file is now fully internationalized. Removed unneeded lib/fileUtf8. * foundryToolsDaemon.c: Fixed a leak of the sync driver handle. * guestd/toolsDaemon.c: Send guestd's "config directory" to the VMX for publishing. * hgfsmounter/hgfsmounter.c: Port to MacOS. * lib/dnd/*, lib/err/err.c, lib/file/*, lib/include/dnd*, lib/include/file*, lib/include/unicode*, lib/include/util.h, lib/unicode/*, lib/user/utilPosix.c: More Unicodification. * lib/file/file.c, lib/include/file.h: Added File_EnsureDirectory. * lib/foundryMsg/foundryMsg.c, lib/guestInfo/guestInfoServer.c, lib/misc/codeset.c, lib/misc/vmstdio.c, lib/SLPv2Parser/SLPv2MsgAssembler.c, lib/user/util.c: Removed some unneeded casts. * lib/foundryMsg/foundryThreads.c, lib/include/foundryThreads.h: Added FoundryThreads_Free. * lib/guestInfo/*, lib/include/guest_os.h, lib/include/guestInfo.h: Refactored GetSystemBitness. Removed osNames.h. * lib/hgfsServer/hgfsServerLinux.c: Modified MacOS alias resolution code so as not to mount volumes. Made HGFS query volume code more resilient to failures. * lib/include/backdoor_def.h: Added commands for VAssert. * lib/include/escape.h, lib/misc/escape.c: Escape_Do is no longer declared inline. * lib/include/hashTable.h, lib/misc/hashTable.c, lib/misc/Makefile.am, lib/misc/shared/Makefile.am: Renamed from hash.[ch]. * lib/include/iovector.h, lib/include/vm_basic_types.h: Added SectorType definition. * lib/include/loglevel_user.h: Added additional log levels. * lib/include/msgfmt.h: Modified for use in VMKERNEL. Added MsgFmt_GetArgswithBuf. * lib/include/msg.h: Added Msg_AppendVob for ESX. * lib/include/stats_user*: Modified some preprocessing steps. Added SETUP_WANT_GETVAL to retrieve named stat counter values. * lib/include/str.h: Modified behavior Str_* family of functions for Windows. * lib/include/strutil.h, lib/strUtil/strutil.c: Removed Split, Grep, GrepFd, and GrepFree. Added EndsWith and DecimalStrToUint. * lib/include/syncWaitQ.h, lib/sync/*: Modified SyncWaitQ_Add and SyncWaitQ_Remove to use PollDevHandle fd types instead of int fd types. * lib/include/timeutil.h, lib/misc/timeutil.c: Added TimeUtil_GetLocalWindowsTimeZoneIndex and some helper functions. * lib/include/util.h, lib/user/utilPosix.c: Added Util_BumpNoFds. * lib/include/vixCommands.h: Added commands for device hotplug and remote debugging. * lib/include/vix.h, lib/include/vixOpenSource.h: Added some new errors and properties. Added more VM manipulation functions. * lib/include/vm_atomic.h: Comment cleanup and added VMKERNEL-specific calls for fencing. * lib/include/vm_basic_asm_x86_64.h: Added inline routines to save and restore ES1. * lib/include/vm_basic_types.h: Added some types and cleaned up a bit. * lib/include/vm_legal.h: Updated COPYRIGHT_YEARS. * lib/include/vm_product.h: Added hostd service name. * lib/include/x86cpuid.h: Cleaned up the file and added some definitions for Penryn processors. * lib/misc/codeset.c: Added new UTF-16 --> UTF-8 conversion routine. * lib/misc/util_misc.c, lib/user/util.c: Moved Util_GetCurrentThreadId and friends to util_misc.c. * lib/procMgr/procMgrPosix.c: Cleaned up some code and reworked asynchronous process execution so as to properly track the grandchild's pid instead of the child's pid. * lib/string/bsd*: Reorganized BSD formatter. * lib/string/str.c: Updated unit tests. Added some Windows corner case behavior for Str_Vsnwprintf. * lib/strUtil/strutil.c: Fixed some corner cases in existing functions that call strtoul. * lib/vixTools/vixTools.c: Changed signature of VixToolsImpersonateUser. Changed error code handling in a few places. * modules/freebsd/vmhgfs/*: Refactored a lot of code so that it can be safely reused within the MacOS vmhgfs module. * modules/*/*/kernelStubs*: Removed dead System_Uptime function. * modules/linux/*/compat_wait.h: Reworked VMW_HAVE_EPOLL macro. Added waitqueue helper macros for older kernels. * modules/linux/vmhgfs/file.c, modules/linux/vmhgfs/fsutil.*, modules/linux/vmhgfs/inode.c: Added HgfsSetUidGid function and used it to preserve uid/gid after creating a directory. * modules/linux/vmhgfs/vmhgfs_version.h: Bumped driver version. * modules/linux/vmsync/compat_workqueue.h: Basic implementation of work queues and delayed work queues (using taskqueues and timers) for older kernels. * modules/linux/vmsync/sync.c: Modified internal state to use new compatible work queue implementation. * modules/linux/vmxnet/compat_ioport.h, modules/linux/vmxnet/compat_netdevice.h, modules/linux/vmxnet/compat_pci.h, modules/linux/vmxnet/compat_skbuff.h, modules/linux/vmxnet/vmxnetInt.h: Added and refactored compatibility macros for use in vmxnet3 and vmci sockets modules. * modules/linux/vmxnet/vmxnet.c: Hide some kernel functions behind compatibility macros. 2008-01-23 Adar Dembo * Resync with internal trunk (2008.01.08). * configure.ac, guestd/Makefile.am, hgfsclient/Makefile.am, lib/Makefile.am, toolbox/Makefile.am, vmware-user/Makefile.am: integrated lib/unicode for internationalizing strings. * guestd/main.c: Stopped using pgrep for finding existing instances of guestd. Removed ancient bandwidth test code. * guestd/toolsDaemon.c: Moved initial send of the guest's uptime from when guestd sends its version to when guestd registers its capabilities. * lib/file/*, lib/include/file*.h : Massive overhaul of lib/file to integrate the new unicode strings that are i18n-safe. Quite a bit of cleanup and refactoring as well. * lib/file/file.c: Addition of File_PrependToPath function. * lib/file/fileIOPosix.c: Addition of FileIO_SetExcludedFromTimeMachine and FileIO_PrivilegedPosixOpen functions. * lib/fileUTF8/fileUTF8Linux.c, lib/include/fileUTF8.h: Removal of some casts and addition of FileUTF8_GetSize function. * lib/foundryMsg/foundryMsg.c, lib/misc/vmstdio.c, lib/SLPv2Parser/SLPv2MsgAssembler.c: Addition of some casts. * lib/foundryMsg/foundryPropertyListCommon.c: Robustified some error cases. * lib/foundryMsg/vixTranslateErrOpenSource.c, lib/include/vixOpenSource.h: Added VIX_E_OUT_OF_MEMORY error code. Added Vix_TranslateCOMError function. ADded VIX_DEBUG macro. * lib/guestInfo/guestInfoServer.c, lib/include/guestInfo.h: Added some casts and refactored some functions. Also fixed a crash that hinders backwards compatibility. * lib/hgfs/cpNameUtil.c, lib/hgfs/cpNameUtilLinux.c, lib/hgfsBd/hgfsBd.c, lib/include/cpName.h, lib/include/cpNameLite.h, lib/include/escBitvector.h, lib/include/hgfsUtil.h, lib/message/messageBackdoor.c, lib/message/message.c, lib/message/messageStub.c, lib/rpcout/rpcout.c, modules/freebsd/vmhgfs/kernelStubs.h: Made safe for inclusion in MacOS kernel module code. * lib/include/backdoor.h: Refactored some type definitions. * lib/include/bsd_output_int.h, lib/include/safetime.h, lib/string/bsd_output_shared.c: Made safe for Win64 builds. * lib/include/dynbuf.h: Added DynBuf_AppendString function. * lib/include/err.h: Assorted cleanup. * lib/include/escape.h, lib/misc/escape.c: Converted Escape_Do to be inline. Some cleanup. * lib/include/guest_os.h: Assorted cleanup. * lib/include/hash.h, lib/misc/hash.c, lib/misc/Makefile.am, lib/misc/shared/Makefile.am: Added basic hash table implementation. * lib/include/hostinfo.h, lib/user/hostinfoPosix.c: Refactored and added several timekeeping functions. * lib/include/localconfig.h, lib/include/util_shared.h: Modified statements for include check. * lib/include/log.h: Changed the value of some macros when debugging. * lib/include/loglevel_defs.h: Refactoed some code, added macros for use in the VMM. * lib/include/loglevel_user.h: Added loglevels for some new components. * lib/include/msgfmt.h: Added new functions. * lib/include/msg.h: Added new Msg_LocalizeList function. * lib/include/netutil.h: Modified prototypes for two Windows-only functions. * lib/include/preference.h: Added new Preference_GetInt64 and Preference_SetFromString functions. * lib/include/strutil.h, lib/strUtil/strutil.c: Cleaned up and added some new functions. * lib/include/su.h: Cleanup. * lib/include/syncMutex.h, lib/sync/syncMutex.c: Added NetWare implementation of some synchronization primitives. * lib/include/unicode*, lib/unicode/*: New library for handling Unicode-aware strings. * lib/include/util.h, lib/user/util.c: Assorted refactoring and addition of some new functions, one related to backtracing. * lib/include/vixCommands.h: New commands for vprobes, replay, message dialogs, and others, plus cleanup of some existing commands. * lib/include/vm_assert.h: Added IMPLIES macro. * lib/include/vm_atomic.h, lib/include/vm_basic_asm.h: Refactored for safe Win64 builds. * lib/include/vm_basic_defs.h: Added compatibility code for __va_copy. * lib/include/vm_basic_types.h: Added FMTH for printing the value of handles. Set a new #pragma to ignore size_t truncation warnings on Windows. Added several other macros, as well as a ssize_t definition for some versions of BSD. * lib/include/vm_legal.h: Added more patents to the patent string. * lib/include/vm_product.h: Added new macros for some products. * lib/include/vm_tools_version.h: Added macros for certain older Tools versions and for PRODUCT_BUILD_NUMBER refactoring. * lib/include/vm_version.h: Tweaked some product expiration dates and versions. Refactored many uses of BUILD_NUMBER to PRODUCT_BUILD_NUMBER. * lib/include/x86cpuid.h: Tweaked definition of RDTSCP flag. Refactored BIT_MASK macro to VMW_BIT_MASK. * lib/misc/base64.c: Modified calling contract for Base64_EasyEncode. * lib/misc/codeset.c: Tweaked casts and preprocessor conditioning. * lib/misc/idLinux.c: Added IdAuthCreateWithFork and reworked several other functions to work around a bug in Apple's detection of GUI processes. * lib/misc/util_misc.c: Moved W32Util_GetLongPathName and W32UTil_LookupSidForAccount elsewhere. * lib/rpcin/rpcin.c: Addition of a ping GuestRPC callback. * lib/string/str.c: Removed a comment. * lib/sync/syncWaitQPosix.c: Added code to disable a workaround for a MacOS bug when appropriate (it was fixed in Leopard). * lib/vixTools/vixTools.c: Refactored some code, added code to modify the guest's networking configuration, added some casts, and added code to prevent renaming a file to itself. * modules/freebsd/*/Makefile, modules/linux/*/Makefile.normal: Set a make variable so the module file will be build in the parent directory. Removed some unused rules. * modules/freebsd/vmhgfs/kernelStubsBSD.c, modules/linux/vmhgfs/kernelStubsLinux.c: Removed unused function. * modules/linux/*/include/driver-config.h: Added check to prevent uintptr_t from being declared twice. * modules/linux/vmblock/linux/filesystem.c, modules/linux/vmblock/Makefile.kernel: Added check for newer kernels where the slab allocator's constructor function expects three arguments. Makes it work with 2.6.25-rc1 (but not rc2, yet). * modules/linux/vmblock/linux/vmblock_version.h: Bumped module version. * modules/linux/vmhgfs/filesystem.c, modules/linux/vmhgfs/inode.c, modules/linux/vmhgfs/module.h, modules/linux/vmhgfs/page.c: Added support for writeback caching in conformant kernels. * modules/linux/vmhgfs/vmhgfs_version.h: Bumped module version. * modules/linux/vmxnet/vmxnetInt.h: Renamed a type and removed the inclusion of unnecessary headers. Pruned said headers from codebase. 2007-11-15 Elliot Lee * Bandsaw release (2007.11.15). * configure.ac: Handle building modules for multiple OS's. Improve X detection to allow building --without-x. Improve Gtk+ detection. Detect libdnet on Solaris. Detect which -Wwarning flags the compiler can handle. * vmware-user/foreignVMToolsNetworking.c, lib/vixTools/vixTools.c, guestd/foreignVMToolsNetworking.c, lib/include/netutil.h, lib/include/guestInfo.h, lib/netUtil/netUtilLinux.c, lib/include/guestInfoInt.h, lib/guestInfo/guestInfoPosix.c, lib/guestInfo/guestInfoServer.c: Move to new NicInfo structures. * vmware-user/foundryToolsDaemon.c, guestd/foundryToolsDaemon.c: Make sure requestMsg is not NULL before looking inside it. * guestd/main.c: Cleanup of HGFS pserver and mounting code. Check for some type of signal when sending an RPC. * guestd/toolsDaemon.c, vmware-user/resolution.c: Have the guest tell the host whether screen resolution changes should be sent, instead of having the host guess it based on the OS type set in the .vmx file. Better timeout checking to avoid problems when host & guest time diverge. * hgfsmounter/hgfsmounter.c: FreeBSD support. Fixes to compile on old systems. * lib/backdoor/backdoor.c: Tweak for FreeBSD kernel modules. * lib/include/mntinfo.h, lib/dnd/dndLinux.c, lib/wiper/wiperPosix.c, lib/syncDriver/syncDriverPosix.c: Fixes to compile on new systems w/gcc 4.2. * lib/err/err.c, lib/err/errPosix.c, lib/err/Makefile.am: Move Err_Errno2String function into POSIX-specific source file. * lib/file/fileIOPosix.c: Handle EDQUOT if applicable. Fixes to compile on new systems where SYS__llseek may not be available. Better reporting of errors, by translating errno into FILEIO_* error codes. * lib/file/fileLockPosix.c: Fixes to compile on old systems. Add a bunch of functions to the FileLock* API. * lib/file/fileLockPrimitive.c, lib/include/fileInt.h: Bunch of file locking cleanups and bug fixes. * lib/file/filePosix.c: Bunch of MacOS-related fixes. Add File_GetTimes(), FilePosixGetParent(), FilePosixGetBlockDevice(), etc. * lib/fileUtf8/fileUTF8Linux.c: Add FileUTF8_GetTimes() function. * lib/foundry/foundryMsg.c, lib/include/vixCommands.h: Add VIX_USER_CREDENTIAL_HOST_CONFIG_HASHED_SECRET credential type, and a bunch of VIX commands relating to record-replay. * lib/foundryMsg/vixTranslateErrOpenSource.c: Translate a couple more error codes. * lib/guestInfo/guestInfoPosix.c, lib/guestInfo/Makefile.am: Use libdnet on Solaris to retrieve networking info. * lib/hgfs/cpNameUtil.c, lib/hgfs/cpNameUtilInt.h, lib/hgfs/cpNameUtilLinux.c: Couple more CPName <-> UTF8 conversion routines. Some MacOS changes as well. * lib/hgfs/hgfsUtil.c, lib/include/hgfs.h, modules/linux/vmhgfs/fsutil.c: Handle ENAMETOOLONG. * lib/hgfs/staticEscape.c, lib/hgfs/hgfsBd.c: Handle FreeBSD as well. * lib/hgfsServer/hgfsServer.c: Tie in the cpNameUtil UTF8 changes on MacOS. * lib/hgfsServer/hgfsServerLinux.c: Make the getdents() wrapper work on a wider range of Linux systems. Add "alias" resolution on MacOS, and tie in the cpNameUtil UTF8 changes on MacOS. * lib/hgfsServer/hgfsServerPolicyGuest.c: Handle FreeBSD. * lib/include/backdoor_def.h: Add BDOOR_CMD_LAZYTIMEREMULATION and BDOOR_CMD_BIOSBBS. * lib/include/str.h, lib/include/bsd_output.h, lib/include/bsd_output_int.h: include compat_stdarg.h, change vsnwprintf prototype, add HAVE_BSD_WPRINTF define, other compat fixups. * lib/include/cpNameUtil.h, lib/include/codeset.h, lib/misc/codeset.c: Changes to correspond to cpNameUtil UTF8 changes. * lib/include/compat/compat_stdarg.h: New header for doing stdarg easily across platforms. * lib/include/cpName.h: FreeBSD fixes. * lib/include/dnd.h: Add Dnd_SetClipboard and Dnd_GetFileList(). * lib/include/escBitvector.h: FreeBSD fixes. * lib/include/file.h, lib/include/fileUTF8.h: Add new MacOS routines and File_GetTimes/FileUTF8_GetTimes. * lib/include/hgfsProto.h: Explanation of the whole cpNameUtil and codeset UTF8 changes and how they tie in with HGFS. * lib/include/hgfsUtil.h: Random compatibility changes. * lib/include/loglevel_user.h: Add a few LOGLEVEL_VAR definitions. * lib/include/msg.h: s/USE_MSGFMT/NO_MSGFMT/ * lib/include/osNames.h: Add Windows 2003 Datacenter Edition, and user-visible 64bit suffix macro. * lib/misc/random.c, lib/include/random.h: Add Random_Quick() and Random_QuickSeed() routines. * lib/misc/idLinux.c, lib/include/su.h: Add Id_AuthGetLocal() and Id_GetAuthExternal() routines, and compat fixes. * lib/misc/timeutil.c, lib/include/timeutil.h: Add TimeUtil_UnixTimeToNtTime() routine. * lib/include/util.h: Add a couple of MacOS routines. * lib/include/vmBackup.h, lib/vmBackupLib/stateMachine.c: add a couple of structure elements for Windows backup fixes. * lib/include/vm_basic_asm.h: fixes for reading TSC on 64-bit platforms. * lib/include/vm_basic_defs.h: Add other va_copy macros. * lib/include/vm_basic_types.h: Fixes for compiling on a wide range of systems. * lib/include/vm_legal.h: Change the PATENTS_STRING * lib/include/vm_product.h: Add "License Infrastructure" product. * lib/include/vm_tools_version.h: Change tools versions listed for various upcoming product releases. * lib/include/vm_version.h: Update the versions. * lib/include/x86cpuid.h: Define more CPU flags & fields, add new CPU models. Fixes for fully writable TSC detection. * lib/message/message.c, lib/message/messageBackdoor.c: Fixes for FreeBSD. * lib/misc/util_misc.c: Handle MacOS. * lib/rpcIn/rpcin.c: Fail a badly-formed RPC instead of ASSERT()'ing into oblivion. * lib/string/bsd_vsnprintf.c: Various fixes to synchronize with bsd_vsnwprintf.c. * lib/string/Makefile.am, lib/string/shared/Makefile.am, lib/string/str.c lib/string/bsd_vsnwprintf.c: New file to implement vsnwprintf() for compat purposes. * lib/vixTools/vixTools.c: New FileUTF8 routines. * Makefile.am, modules/Makefile.am: --without-x fixes, add xferlogs, move kernel module building into separate Makefile.am * modules/freebsd/*: Add FreeBSD kernel modules (vmblock, vmhgfs, vmmemctl, vmxnet). * modules/linux/*/include/compat_*.h, modules/linux/*/autoconf/cachector.c, modules/linux/*/autoconf/cachecreate.c, modules/linux/*/backdoor.c, modules/linux/vmhgfs/filesystem.c, modules/linux/vmhgfs/hgfsBd.c, lib/procMgr/procMgrPosix.c, lib/rpcOut/rpcout.c, lib/user/util.c, lib/vmCheck/vmcheck.c, libguestlib/Makefile.am, lib/deployPkg/runDeployPkgPosix.c, lib/include/vm_atomic.h: Compat fixes. * modules/linux/*/kernelStubs.h: Update for FreeBSD. * modules/linux/*/include/*.h, modules/linux/*/backdoor_def.h, modules/linux/*/cpName.h, modules/linux/*/hgfs.h, modules/linux/*/hgfsProto.h, modules/linux/*/hgfsUtil.[ch], modules/linux/*/kernelStubsLinux.c, modules/linux/*/messageBackdoor.c, modules/linux/*/message.c, modules/linux/*/rpcout.c, modules/linux/*/rpcin.c, modules/linux/*/staticEscape.c, modules/linux/*/vm_basic_asm.h, modules/linux/*/vm_basic_defs.h, modules/linux/*/vm_basic_types.h, modules/linux/*/x86cpuid.h, modules/linux/*/compat_*.h: Pull in updated files from main source tree. * modules/linux/*/Makefile.kernel: Remove CC_WARNINGS/CC_OPTS gunk. * modules/linux/*/README, modules/linux/*/Makefile.normal: Build foo.o driver by default on systems with VM_KBUILD=no. * modules/linux/vmhgfs/vmhgfs_version.h: Updated VMHGFS driver version. * modules/linux/vmmemctl/os.[ch], modules/linux/vmmemctl/vmballoon.c: Implement and use os_yield() to deprioritize the Balloon_Deallocate operation. * modules/linux/vmsync/*: New sync driver to make VM snapshots consistent. * modules/linux/vmxnet/bpf_meta.h: New file. * modules/linux/vmxnet/net_dist.h: Update NET_MAX_IMPL_PKT_OVHD value. * modules/linux/vmxnet/vm_device_version.h: Mention VMXNET3 * modules/linux/vmxnet/vmkapi_status.h: Updated VMK_ERR codes. * modules/linux/vmxnet/vmkapi_types.h: Add VMK_CONST64(U) macros. * modules/linux/vmxnet/vmxnet2_def.h, modules/linux/vmxnet/vmnet_def.h, modules/linux/vmxnet/vmxnet_def.h, modules/linux/vmxnet/vmxnetInt.h, modules/linux/vmxnet/vmxnet.c: Add (optional) BPF support. * modules/linux/vmxnet/vmxnetInt.h, modules/linux/vmxnet/vmxnet.c: Add vmxnet_link_check to propagate device link status to netdev. * common/vm-support: New script to gather support info from a VM. * scripts/*/*-default: New poweron/poweroff/suspend/resume scripts for a VM. Add support for dropping user-provided scripts into a subdirectory. * toolbox/toolboxAbout.c: Eliminate warnings about unused variables. * toolbox/toolboxShrink.c: Update wording of message. * toolbox/copyPaste.c: Try cutting & pasting UTF8 text if we can. * xferlogs/*: New log transfer utility. 2007-10-26 Elliot Lee * Initial import of 2007.09.04-56574 code ("Axe" release). * Import 2007.10.08 snapshot, which includes patches to fix the --without-x flag, and compilation with gcc 4.2. open-vm-tools-9.4.0-1280544/NEWS0000644765153500003110000005273712220061556014154 0ustar dtormtsopen-vm-tools 9.4.0 changes: * Release of open-vm-tools matching vSphere 5.5. * Branch was cut from commit id 63be9626897c801ccafee8367e15d7ac1e1c4b6f (tagged as 2012.12.26-958366) and clobbered with the released files. open-vm-tools 2012.05.21 changes: * Updates for newer Linux kernel releases (3.4). * Fix for vmxnet driver and IPV6 * VMCI updates and fixes. * Other fixes and cleanups. open-vm-tools 2012.03.13 changes: * Updates for newer Linux kernel releases (3.3). * Updates for Solaris 11. * Updates for FreeBSD 9.0. * Translation updates. * Other fixes and cleanups. open-vm-tools 2011.12.20 changes: * Updates for new Linux kernel releases, including some fixes for Fedora's re-versioned 3.x kernels. * VMCI sockets has some changes for a new socket type, targeted at replacing the "backdoor" communication used by the tools services. * HGFS has better session support. * Miscelaneous bug fixes and small enhancements in other parts of the code. open-vm-tools 2011.11.20 changes: * Updates for new Linux kernel releases. * Better Unity and DnD compatibility with newer Linux distros. * Other minor fixes and cleanups. open-vm-tools 2011.10.26 changes: * Mostly cleanups and bug fixes. * Code can now compile with uClibc, with some caveats. open-vm-tools 2011.09.23 changes: * open-vm-tools now can use the built in Linux freeze / thaw support for block devices, making the vmsync driver unnecessary in kernels supporting that feature. * The VMCI driver has been simplified, removing VM-to-VM communication support (which is being removed from VMware products). * The Unity team decided to remove the Unity plugin from open-vm-tools, given its partial brokenness due to reliance on internally-modified version of GNOME libraries, among other reasons. * Other bug fixes and code cleanup. open-vm-tools 2011.08.21 changes: * Enabled several VIX APIs on FreeBSD. * Minor bug fixes and code cleanup. open-vm-tools 2011.07.19 changes: * Fix an issue in the HGFS driver that could lead to a kernel panic. * Update some code to support new compiler and kernel versions. * Minor bug fixes and code cleanup. open-vm-tools 2011.06.27 changes: * A few enhancements to Unity: XFCE support, better interaction with "the other" (Ubuntu's) Unity and compositing window managers, better X error handling, and a few bug fixes. * A few bug fixes in HGFS, and minor bug fixes in other components. * Otherwise, mostly code cleanup. open-vm-tools 2011.05.27 changes: * Mostly cleanups and a few bug fixes. open-vm-tools 2011.04.25 changes: * Mostly cleanups and small bug fixes in this release. * Logging is enabled by default in vmtoolsd, writing to syslog. The default log level is not chatty, so few messages should make it to syslog during normal operation. * The GUI version of the toolbox was removed. open-vm-tools 2011.03.28 changes: * HGFS mounter and vmusr's suid wrapper were changed to avoid issues with symlink attacks. A new mount utility for vmblock on Solaris and FreeBSD was added. * The VMCI driver was thoroughly reworked so that it can serve as both the host and guest VMCI driver. This is mostly targeted at supporting nested VMs. * vmusr got better integration with X's session manager, including proper cleanup during session teardown. * Unity has been enhanced to better handle some desktop environments. * Many small bug fixes in other areas, including updates for newer Linux kernels. open-vm-tools 2011.02.23 changes: * Some copy & paste issues with KDE were fixed. * Mostly cleanups and bug fixes, with a few build enhancements. open-vm-tools 2011.01.24 changes: * Mostly cleanups and bug fixes. * Install code fixed to handle translation catalogs correctly. open-vm-tools 2010.12.19 changes: * New version of DnD code lands in open-vm-tools. The host part of the new DnD protocol is not available yet in VMware products, though. * vmtoolsd gets some new functionality to support new features being developed internally. * vmxnet driver for FreeBSD fixed to allow changing the MAC address. * lots of bug fixes and other cleanups in various areas. open-vm-tools 2010.11.17 changes: * Mostly cleanups and bug fixes. * vmxnet3 on Solaris now supports jumbo frames. open-vm-tools 2010.10.18 changes: * The unity plugin has received some refactoring work, and the menu gathering code has been enhanced to be more DE-agnostic and support the new app icon code. It now needs glib 2.24 to compile. * Several bug fixes and enhancements to the VIX plugin. * Bug fixes to the guest info plugin so that it better supports VMs with several network interfaces. * Other minor enhancements and bug fixes in several areas, including vsock, vmmemctl and copy & paste. open-vm-tools 2010.09.19 changes: * Mostly cleanups and minor bug fixes. * VIX plugin has been updated with lots of new commands being added to the next VIX API release. open-vm-tools 2010.08.24 changes: * HGFS and VMCI kernel module bug fixes, and updates to compile in newer Linux kernels. * HGFS server interface refactoring was finished, now supports the transport abstraction available for the kernel interface. * VIX operations are now properly implemented on Solaris, plus new operations added to support features under development. * Other minor cleanups and bug fixes. open-vm-tools 2010.07.25 changes: * Features previously provided by vmware-user are now provided as vmtoolsd plugins. vmware-user has been removed and code that interacted with it changed to start the correct vmtoolsd instance. * Lots of cleanup: removed old compatibility headers not needed anymore, removed dead code, consolidated logging code. * Time synchronization now works more like NTP. * New code for features not yet exposed by VMware host software is being added. open-vm-tools 2010.06.16 changes: * VMCI moves towards unifying the guest and host driver APIs, and gets support for MSI/MSI-X. * More work on new VMCI-backed HGFS protocol. * vmmemctl: Linux driver removed (it's now upstream), plus cleanup and simplification of the FreeBSD and Solaris drivers. * some Linux kernel compatibility fixes. * Cleanup of old kernel support code. * Some cleanup of old VIX features. * toolbox-cmd was updated to use newer APIs, and got some i18n enhancements. * some bug fixes and enhancements to the logging code. * update detection and use of some needed libraries. * More progress in making libraries thread-safe. open-vm-tools 2010.04.25 changes: * VMCI and HGFS get some initial work for new features. * vmbackup support has been extended to more systems, allowing its use even if the system lacks a proper "sync" implementation. * A few bug fixes in different areas: Unity/X11, vmware-user startup on upstart-based systems, and other minor fixes / thread safety fixes. * The pvscsi driver was removed from the open-vm-tools distribution (it is upstream as of Linux 2.6.33). * The vmmemctl driver will be upstream as of Linux 2.6.34, at which point it will be removed from open-vm-tools. open-vm-tools 2010.03.20 changes: * New i18n support for Tools; it is based on VMware's internal tools (instead of gettext). * Logging infrastructure has been enhanced and now supports rotation (without the need for logrotate) and syslog. * Bug fixes in several areas (DnD, backup support, thread safety). * Updates in Linux kernel modules for compatibility with newer kernels. * New functionality in the Unity support code. open-vm-tools 2010.02.23 changes: * Mostly bug fixes, cleanups and code refactoring. open-vm-tools 2010.01.19 changes: * Linux modules have been updated to compile on newer kernels. * Solaris modules now should compile on OpenSolaris (tested on 2009.06). * Other than those, mostly bug fixes and minor refactoring. open-vm-tools 2009.12.16 changes: * Some improvements to vmtoolsd, base libraries and and the plugin interface. * Some library refactoring: use new lock library, changes to support compilation of some code on ARM. * some fixes in configure.ac to try to correctly support newer distros. * vsock/vmci improvements. * bug fixes in the vmxnet / vmxnet3 drivers, and FreeBSD's vmblock driver. * vmxnet3 for Linux is now upstream (as of Linux 2.6.32), and will be removed from later releases of open-vm-tools. * pvscsi will be available upstream starting with Linux 2.6.33 and at that time will be removed from open-vm-tools. open-vm-tools 2009.11.16 changes: * Lots of refactoring and cleanup in the code, mainly targeting the definition of a set of public APIs. * vmblock-fuse can now replace the vmblock kernel module for DnD operations. * Fix some memory leaks in the guestInfo module. Users of the 2009.10.15 release are recommended to upgrade, or at least crossport cid 6a8d4279. open-vm-tools 2009.10.15 changes: * The HGFS module got some performance enhancements. * Minor enhancements to vmtoolsd and the logging system. * Fix for a few issues reported on the sourceforge bug tracker. * Lots of code refactoring, and a few bug fixes. open-vm-tools 2009.09.18 changes: * Mostly bug fixes and minor enhancements. * The pvscsi code was re-factored in preparation for upstreaming. The driver has been sent to the LKML for inclusion in the main Linux tree, and might be removed from open-vm-tools once it's accepted. open-vm-tools 2009.08.24 changes: * Remove support for Linux kernels < 2.6.9. * The vsock now implements a new notification protocol that has better performance than the previous. * New infrastructure for sending more network config-related information about the virtual machine to the host. * Other bug fixes and minor improvements to the code. open-vm-tools 2009.07.22 changes: * Better support for dkms by means of a script to help create a dkms tree. * "make install" now also installs header files for public libraries, plus a few fixes to incorrect install behavior. * Lots of improvements to the new DnD code. * This will be the last release with support for Linux kernels < 2.6.9. open-vm-tools 2009.06.18 changes: * Mostly a bug fix release. * vmhgfs now is able to use vsock as a transport (although backend support for HGFS over vsock is not yet released in VMware products). open-vm-tools 2009.05.22 changes: * Mostly a cleanup and bug fix release. * Fix a build issue where a symlink attack could cause the open-vm-tools build to overwrite data (by placing a symlink in /tmp). * Second (and last?) batch of changes to clean up duplicate files in the source tree, including Solaris and FreeBSD kernel modules and other module-specific shared files. * Plugins now are properly built using plugins_LTLIBRARIES so that "-rpath" doesn't need to be used (this would cause an RPATH entry to be added to the final binary, which some tools didn't like). Thanks to Dominique Leuenberger for the suggestion. * open-vm-tools now properly detects PAM and enables PAM support in the code. open-vm-tools 2009.04.23 changes: * Implemented copy & paste support for RTF data and file contents. * guestd has been removed from open-vm-tools; vmtoolsd is now the only option for the main tools service. * Added vmblock and vmmemctl modules for Solaris (under the CDDL). * vmware-user can now work with both vmblock-fuse and vmblock. * Linux HGFS now has a stream-based (TCP, vsock) transport, still under development. * First batch of changes to cleanup duplicated files in the source tree. Most duplicated files in the Linux kernel modules have been cleaned up. open-vm-tools 2009.03.18 changes: * Mostly a bug fix release. * Solaris vmxnet3 driver was added; open-vm-tools now should also compile on OpenSolaris (tested on 08.11), as long as the --without-gtkmm option is used. * The new DnD V3 protocol is now available in open-vm-tools. * Added "rpctool", a simple, stand-alone tool to send RPC commands to the host software. * vmtoolsd is now preferred in lieu of vmware-guestd; vmware-guestd will most probably be completely removed in the next release. open-vm-tools 2009.02.18 changes: * open-vm-tools now depend on glib 2.6.0 as a minimum requirement. * Added vmxnet module for Solaris, and reworked the HGFS module so it works without help from vmware-guestd. * Added implementation of new DnD protocol, which adds a dependency on a C++ compiler and the gtkmm library to vmware-user. * The code from the "core services" has been added to open-vm-tools, including a few tests. vmtoolsd + plugins are now capable of replacing vmware-guestd (vmware-user still needs to have some features ported over), but this code is still not to be considered as stable as the legacy services, so vmware-guestd is still included. * A few fixes for compatibility with non-GNU toolchains, newer Linux kernels and old gcc compilers. open-vm-tools 2009.01.21 changes: * First open source release of the HGFS module for Solaris, under the CDDL. Other modules are expected to be added in the upcoming releases. * Added an implementation of vmblock on top of FUSE; vmware-user still doesn't use this module even if it is available, though. * Linux modules now add the "supported" tag used by Novell in their SLES 10 SP2 release when loading modules. * Fix compilation of modules in newer Linux kernels which don't include $(LINUXINCLUDE) in the compiler flags anymore. open-vm-tools 2008.12.23 changes: * Lots of makefile cleanup with the switch to using libtool archives. * Automatically disable Unity if multimon support is disabled. * Actually build the pvscsi modules. * First bits of the "Core Service" project are starting to show up; the base "vmtools" library was added to the package. It currently is mostly a collection of the existing libraries already shipped with open-vm-tools, plus some extra functionality build on top of glib. Currently no other code in open-vm-tools uses it, so it's optional. * The HGFS driver was fixed for the Linux 2.6.28 kernel. open-vm-tools 2009.11.18 changes: * The pvscsi Linux kernel module has been added (for kernels >= 2.6.8). It provides access to VMware's new paravirtualized SCSI device. * The HGFS driver and user-level code has seen a lot of refactoring to enable more consistent name escaping. The FreeBSD driver now supports symlinks. * The Linux module makefiles now support exporting symbol version files, allowing modules with dependencies (such as vsock, which depends on vmci) to correctly build and load on Linux >= 2.6.26 with CONFIG_MODVERSIONS. * Rudimentary support for dkms. * Assortment of bug fixes. open-vm-tools 2009.10.13 changes: * The vmxnet3 Linux kernel module has been added. This module provides better network performance for the guest. The corresponding virtual hardware is available beginning with Workstation 6.5, though performance benefits are unlikely to be realized until a later VMware product release. The module should work for all kernels beginning with 2.6. * The open-vm-tools no longer depend on libproc-dev. Several people reported this issue (Sourceforge bug 1960947). * Added a command line argument to skip privileged operations during make install (--without-root-privileges). * Guestd now supports backwards time synchronization, though the corresponding hypervisor-side changes are not yet part of any shipping VMware products. * Assortment of bug fixes. open-vm-tools 2009.09.03 changes: * Fixed an issue where open-vm-tools fails to configure when using --without-icu. Thanks to Timo Gurr for reporting the issue (Sourceforge bug 2046262). * Fixed failed build on Ubuntu Intrepid and Fedora 9. Thanks to Nathan Charles for reporting the issue (Sourceforge bug 2048423). * Fixed kernel module build issues on 2.6.27 pre-release kernels. Thanks to Dominique Leuenberger for reporting the issue (Sourceforge bug 2071170). * ...and other bug fixes. open-vm-tools 2008.08.08 changes: * Unity for X11 guests has been added. Unity is implemented within vmware-user and requires no additional setup beyond setting up the vmware-user application itself. Unity should work with Fusion 1.x releases as well as with the upcoming Workstation 6.5 release. Our in-house testing was with Linux guests, and they should mostly work. There is very little standing in the way of FreeBSD/Solaris support, though we've never built or tested Unity for those platforms. * The VMCI Linux kernel module has been added. This module provides high-speed datagram and socket interfaces for guest<->guest and host<->guest communication. It should work for all kernels beginning with 2.4, and for VMware products beginning with Workstation 6.5. * The VMCI sockets Linux kernel module has been added. It provides both datagram and stream socket interfaces to userlevel for use with VMCI. As with VMCI, it should work for kernels 2.4 or later, and for VMware products beginning with Workstation 6.5. * The command-line Toolbox has been added. This application provides the same functionality as the GTK Toolbox, but with a scriptable command-line interface. It also has some statistic retrieval commands that aren't found in the GTK Toolbox. * Fixed compilation of vmsync and vmmemctl Linux kernel modules on 2.6.26. Thanks to Pavol Rusnak for the report (Sourceforge bug 2032683). * Fixed an issue with guestd's nicInfo updating mechanism. Thanks to Jason Lunz for the patch (not tracked on Sourceforge). * Fixed handling of $(DESTDIR) in automake. Thanks to Mike Auty for the patch (Sourceforge bug 2018802). * Fixed build of vmware-user using gtk 1.2. Thanks to Stephen Duncan for the report (Sourceforge bug 2014338). * Fixed compilation of lib/guestApp when using --without-x. Thanks to Martin Preishuber for the report (Sourceforge bug 2013568). * As usual, other bug fixes. open-vm-tools 2008.07.01 changes: * Fixed a backwards time synchronization issue (not tracked on Sourceforge). Thanks to Eric Castan for reporting it. * Fixed an issue where open-vm-tools configured via --without-x didn't compile (not tracked on Sourceforge). Thanks to Mark Foster for reporting the bug. * Other bug fixes. open-vm-tools 2008.06.20 changes: * Fixed Sourceforge bug 1847750 (FreeBSD 7 & 8 builds) and Sourceforge bug 1981632 (build failure on Solaris). This should get open-vm-tools building and running on FreeBSD 7 & 8 and Solaris. Thanks to Martin Blapp for all the FreeBSD patches, and Jonathan Keatley for reporting the Solaris bug. * Fixed Sourceforge bug 1968416 (packet counting in FreeBSD vmxnet). Thanks to Shunsuke SHINOMIYA for reporting this bug. * Fixed Sourceforge bug 1983375 (Cannot specify kernel constraints). You can now pass --without-kernel-modules, --with-kernel-release, and --with-linuxdir to the ./configure script. Thanks to Craig Phillips for reporting this bug. * Other bug fixes. open-vm-tools 2008.06.03 changes: * Added the vmware-user-suid-wrapper application, with implementations for Linux, FreeBSD, and Solaris. This app is needed to make correct use of vmware-user with the vmblock kernel module. It should have been in the previous code refresh, but we accidentally overlooked it. * Fixed Sourceforge bug 1924246: vmhgfs on Linux properly reports the available space on the host. Thanks to Mikhail Krivtsov for reporting the bug. * Fixed Sourceforge bug 1839981: we now have rudimentary `make install` support. On any platform, it should copy files and kernel modules to the location specified at build-time, and on Linux, it will additionally run `depmod -a` to make the kernel modules accessible to modprobe. This change also adds a "--with-pam-prefix" argument to the configure script, which controls the location of guestd's pam files. * Other bug fixes. open-vm-tools 2008.05.15 changes: * guestd no longer starts vmware-user. Packagers will need to use the XDG autostart spec, Xsession drop-in scripts, or other appropriate mechanisms to make sure that vmware-user is started as part of X session initialization. Please see http://open-vm-tools.wiki.sourceforge.net/Packaging for more details. * Bug fixes as usual. open-vm-tools 2008.05.02 changes: * Continued Unicode support. * open-vm-tools now depends on libicu for codeset conversions. If you wish to build open-vm-tools without libicu, pass "--without--icu" when configuring the package. Without libicu, codeset conversions will be done as before, via calls to iconv. * A few more bug fixes. open-vm-tools 2008.04.14 changes: * Update the license stamp on all LGPL files. * Continued Unicode support. * Handle libdumbnet on Debian. * More bug fixes, including a security fix in guestd. open-vm-tools 2008.03.19 changes: * Continued Unicode support. * A few bug fixes. open-vm-tools 2008.03.03 changes: * Bug fixes (including the ability to specify custom LDFLAGS at build time, thanks to Mike Auty). * First cut of HGFSv3 implementation. * Beginnings of DnDv3 implementation. * Add Unicode support all over the code base. open-vm-tools 2008.02.13 changes: * Some bug fixes. open-vm-tools 2008.01.23 changes: * The Linux HGFS kernel module now supports writeback caching, which should yield better performance. * Added a generic Unicode-aware library to ease i18n and l10n work. * A bunch of bug fixes. open-vm-tools 2007.11.15 "Bandsaw" changes: * Kernel modules for FreeBSD, including an experimental port of HGFS to FreeBSD. * Add the vmsync driver on Linux to make VM snapshots consistent. * Added the xferlogs utility, the *-vm-default scripts, and the vm-support script. * Build on a wider variety of systems. * Lots of smaller bug fixes throughout the code. open-vm-tools 2007.09.04 "Axe" changes: * Initial release of open-vm-tools. open-vm-tools-9.4.0-1280544/config/0000755765153500003110000000000012220061621014675 5ustar dtormtsopen-vm-tools-9.4.0-1280544/config/compile0000755765153500003110000001610312220061620016253 0ustar dtormts#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2012-03-05.13; # UTC # Copyright (C) 1999-2012 Free Software Foundation, Inc. # Written by Tom Tromey . # # 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, 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. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # 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-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: open-vm-tools-9.4.0-1280544/config/depcomp0000755765153500003110000005055212220061621016261 0ustar dtormts#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2012-03-27.16; # UTC # Copyright (C) 1999-2012 Free Software Foundation, Inc. # 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, 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 Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # A tabulation character. tab=' ' # A newline character. nl=' ' if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' "$nl" < "$tmpdepfile" | ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependent.h'. # Do two passes, one to just change these to # '$object: dependent.h' and one to simply 'dependent.h:'. sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'. # However on # $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\': # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... # tcc 0.9.26 (FIXME still under development at the moment of writing) # will emit a similar output, but also prepend the continuation lines # with horizontal tabulation characters. "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form 'foo.o: dependent.h', # or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'. # Do two passes, one to just change these to # '$object: dependent.h' and one to simply 'dependent.h:'. sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \ < "$tmpdepfile" > "$depfile" sed ' s/[ '"$tab"'][ '"$tab"']*/ /g s/^ *// s/ *\\*$// s/^[^:]*: *// /^$/d /:$/d s/$/ :/ ' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then # With Tru64 cc, shared objects can also be used to make a # static library. This mechanism is used in libtool 1.4 series to # handle both shared and static libraries in a single compilation. # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. # # With libtool 1.5 this exception was removed, and libtool now # generates 2 separate objects for the 2 libraries. These two # compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 tmpdepfile2=$dir$base.o.d # libtool 1.5 tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.o.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d tmpdepfile4=$dir$base.d "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test "$stat" = 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' "$nl" < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # 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-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: open-vm-tools-9.4.0-1280544/config/install-sh0000755765153500003110000003325512220061620016710 0ustar dtormts#!/bin/sh # install - install a program, script, or datafile scriptversion=2011-11-20.07; # 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 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac 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 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac 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 problematic for 'test' and other utilities. 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 # 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-writable 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 X"$d" = X && 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: open-vm-tools-9.4.0-1280544/config/missing0000755765153500003110000002370312220061620016300 0ustar dtormts#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2012-01-06.18; # UTC # Copyright (C) 1996-2012 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # 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, 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. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi run=: sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' sed_minuso='s/.* -o \([^ ]*\).*/\1/p' # In the cases where this matters, 'missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case $1 in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle 'PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file 'aclocal.m4' autoconf touch file 'configure' autoheader touch file 'config.h.in' autom4te touch the output file, or create a stub one automake touch all 'Makefile.in' files bison create 'y.tab.[ch]', if possible, from existing .[ch] flex create 'lex.yy.c', if possible, from existing .c help2man touch the output file lex create 'lex.yy.c', if possible, from existing .c makeinfo touch the output file yacc create 'y.tab.[ch]', if possible, from existing .[ch] Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: Unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # normalize program name to check for. program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). This is about non-GNU programs, so use $1 not # $program. case $1 in lex*|yacc*) # Not GNU programs, they don't have --version. ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running '$TOOL --version' or '$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case $program in aclocal*) echo 1>&2 "\ WARNING: '$1' is $msg. You should only need it if you modified 'acinclude.m4' or '${configure_ac}'. You might want to install the Automake and Perl packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf*) echo 1>&2 "\ WARNING: '$1' is $msg. You should only need it if you modified '${configure_ac}'. You might want to install the Autoconf and GNU m4 packages. Grab them from any GNU archive site." touch configure ;; autoheader*) echo 1>&2 "\ WARNING: '$1' is $msg. You should only need it if you modified 'acconfig.h' or '${configure_ac}'. You might want to install the Autoconf and GNU m4 packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case $f in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: '$1' is $msg. You should only need it if you modified 'Makefile.am', 'acinclude.m4' or '${configure_ac}'. You might want to install the Automake and Perl packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te*) echo 1>&2 "\ WARNING: '$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get '$1' as part of Autoconf from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison*|yacc*) echo 1>&2 "\ WARNING: '$1' $msg. You should only need it if you modified a '.y' file. You may need the Bison package in order for those modifications to take effect. You can get Bison from any GNU archive site." rm -f y.tab.c y.tab.h if test $# -ne 1; then eval LASTARG=\${$#} case $LASTARG in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.h fi ;; esac fi if test ! -f y.tab.h; then echo >y.tab.h fi if test ! -f y.tab.c; then echo 'main() { return 0; }' >y.tab.c fi ;; lex*|flex*) echo 1>&2 "\ WARNING: '$1' is $msg. You should only need it if you modified a '.l' file. You may need the Flex package in order for those modifications to take effect. You can get Flex from any GNU archive site." rm -f lex.yy.c if test $# -ne 1; then eval LASTARG=\${$#} case $LASTARG in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if test ! -f lex.yy.c; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man*) echo 1>&2 "\ WARNING: '$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the Help2man package in order for those modifications to take effect. You can get Help2man from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit $? fi ;; makeinfo*) echo 1>&2 "\ WARNING: '$1' is $msg. You should only need it if you modified a '.texi' or '.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy 'make' (AIX, DU, IRIX). You might want to install the Texinfo package or the GNU make package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n ' /^@setfilename/{ s/.* \([^ ]*\) *$/\1/ p q }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi # If the file does not exist, the user really needs makeinfo; # let's fail without touching anything. test -f $file || exit 1 touch $file ;; *) echo 1>&2 "\ WARNING: '$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the 'README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing '$1' program." exit 1 ;; esac exit 0 # 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: open-vm-tools-9.4.0-1280544/config/config.sub0000755765153500003110000010532712220061620016667 0ustar dtormts#! /bin/sh # Configuration validation subroutine script. # 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-04-18' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # 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. # 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 ;; hexagon-*) os=-elf ;; 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: open-vm-tools-9.4.0-1280544/config/config.guess0000755765153500003110000012743212220061620017225 0ustar dtormts#! /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-06-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 # 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}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-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-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-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-unknown-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-unknown-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}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-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-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-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-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-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-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`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}-unknown-linux-gnu exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-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}-unknown-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}-unknown-linux-gnu else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-gnueabi else echo ${UNAME_MACHINE}-unknown-linux-gnueabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-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}-unknown-linux-gnu exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-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}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-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}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-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-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-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}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-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-unknown-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}-unknown-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-unknown-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-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-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-unknown-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}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-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-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-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}-unknown-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: open-vm-tools-9.4.0-1280544/config/ltmain.sh0000644765153500003110000105152212220061612016523 0ustar dtormts # 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 -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 ;; 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 ;; -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 open-vm-tools-9.4.0-1280544/AUTHORS0000644765153500003110000000004112220061556014502 0ustar dtormtsThe VMware Guest Components Team open-vm-tools-9.4.0-1280544/vmblockmounter/0000755765153500003110000000000012220061626016504 5ustar dtormtsopen-vm-tools-9.4.0-1280544/vmblockmounter/Makefile.am0000644765153500003110000000302212220061556020537 0ustar dtormts################################################################################ ### Copyright 2011 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ sbin_PROGRAMS = mount.vmblock mount_vmblock_LDADD = mount_vmblock_LDADD += ../lib/stubs/libStubs.la mount_vmblock_SOURCES = mount_vmblock_SOURCES += vmblockmounter.c if FREEBSD install-exec-hook: mv $(DESTDIR)$(sbindir)/mount.vmblock \ $(DESTDIR)$(sbindir)/mount_vmblock -$(MKDIR_P) $(DESTDIR)/sbin -$(LN_S) $(DESTDIR)$(sbindir)/mount_vmblock \ $(DESTDIR)/sbin/mount_vmblock &> /dev/null uninstall-hook: rm -f $(DESTDIR)$(sbindir)/mount_vmblock else install-exec-hook: -$(MKDIR_P) $(DESTDIR)/sbin -$(LN_S) $(DESTDIR)$(sbindir)/mount.vmblock \ $(DESTDIR)/sbin/mount.vmblock &> /dev/null uninstall-hook: rm -f $(DESTDIR)/sbin/mount.vmblock endif !FREEBSD open-vm-tools-9.4.0-1280544/vmblockmounter/vmblockmounter.c0000644765153500003110000001436612220061556021733 0ustar dtormts/********************************************************* * Copyright (C) 2011 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vmblockmounter.c -- * * Helper app for mounting vmblock filesystem on FreeBSD and Solaris. * Linux does not need it as it knows how to mount pseudo-filesystems * without a helper program. */ #define _GNU_SOURCE #include #include #include #if defined(__FreeBSD__) # include # include #endif #include #include #include #include #include #include #include #include "vm_basic_types.h" #include "vm_assert.h" #include "vmblock.h" #include "vmblockmounter_version.h" #include "embed_version.h" VM_EMBED_VERSION(VMBLOCKMOUNTER_VERSION_STRING); #define LOG(format, ...) (beVerbose ? printf(format, ##__VA_ARGS__) : 0) static char *thisProgram; static char *thisProgramBase; static Bool beVerbose = FALSE; /* *----------------------------------------------------------------------------- * * PrintVersion -- * * Displays version. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void PrintVersion(void) { printf("%s version: %s\n", thisProgramBase, VMBLOCKMOUNTER_VERSION_STRING); } /* *----------------------------------------------------------------------------- * * PrintUsage -- * * Displays usage for the vmblock mounting utility. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void PrintUsage(FILE *fd) // IN: File stream to use for output { fprintf(fd, "Usage: %s [-o ]\n", thisProgramBase); fprintf(fd, "Mount the vmblock filesystem at given mount point.\n"); fprintf(fd, "\n"); fprintf(fd, "This command is intended to be run from within /bin/mount by\n"); fprintf(fd, "passing the option '-t %s'. For example:\n", VMBLOCK_FS_NAME); fprintf(fd, " mount -t %s /tmp/VMwareDnD /var/run/vmblock\n", VMBLOCK_FS_NAME); } /*----------------------------------------------------------------------------- * * main -- * * Main entry point. Parses the mount options received, makes a call to * mount(2), and handles the results. * * Results: * Zero on success, non-zero on failure. * * Side effects: * May mount a vmblock filesystem. * *----------------------------------------------------------------------------- */ int main(int argc, // IN char *argv[]) // IN { char c; int i; int result = EXIT_FAILURE; int mntRes = -1; struct stat statBuf; char *sourceDir; char *mountPoint; thisProgram = argv[0]; /* Compute the base name of the program, too. */ thisProgramBase = strrchr(thisProgram, '/'); if (thisProgramBase != NULL) { thisProgramBase++; } else { thisProgramBase = thisProgram; } while ((c = getopt(argc, argv, "hvV")) != -1) { switch (c) { case 'h': PrintUsage(stdout); result = EXIT_SUCCESS; goto out; case 'v': beVerbose = TRUE; break; case 'V': PrintVersion(); result = EXIT_SUCCESS; goto out; case '?': default: PrintUsage(stderr); goto out; } } LOG("Original command line: \"%s", thisProgram); for (i = 1; i < argc; i++) { LOG(" %s", argv[i]); } LOG("\"\n"); /* After getopt_long(3), optind is the first non-option argument. */ if (argc != optind + 2) { fprintf(stderr, "Error: invalid number of arguments\n"); PrintUsage(stderr); goto out; } sourceDir = argv[optind]; mountPoint = argv[optind + 1]; /* Do some sanity checks on our desired mount point. */ if (stat(mountPoint, &statBuf)) { perror("Error: cannot stat mount point"); goto out; } if (S_ISDIR(statBuf.st_mode) == 0) { fprintf(stderr, "Error: mount point \"%s\" is not a directory\n", mountPoint); goto out; } if (access(mountPoint, X_OK) < 0) { fprintf(stderr, "Error: no access rights to mount point \"%s\"\n", mountPoint); goto out; } /* Do the same checks on the source directory. */ if (stat(sourceDir, &statBuf)) { perror("Error: cannot stat source directory"); goto out; } if (S_ISDIR(statBuf.st_mode) == 0) { fprintf(stderr, "Error: source \"%s\" is not a directory\n", sourceDir); goto out; } if (access(sourceDir, X_OK) < 0) { fprintf(stderr, "Error: no access rights to source \"%s\"\n", sourceDir); goto out; } /* Go! */ #if defined(sun) mntRes = mount(sourceDir, mountPoint, MS_DATA, VMBLOCK_FS_NAME); #elif defined(__FreeBSD__) { struct iovec iov[] = { { .iov_base = "fstype", .iov_len = sizeof "fstype" }, { .iov_base = VMBLOCK_FS_NAME, .iov_len = sizeof VMBLOCK_FS_NAME }, { .iov_base = "fspath", .iov_len = sizeof "fspath" }, { .iov_base = mountPoint, .iov_len = strlen(mountPoint) + 1 }, { .iov_base = "target", .iov_len = sizeof "target" }, { .iov_base = sourceDir, .iov_len = strlen(sourceDir) + 1 } }; mntRes = nmount(iov, ARRAYSIZE(iov), MNT_NOSUID); } #else #error "Unsupported OS" #endif if (mntRes) { perror("Error: cannot mount filesystem"); goto out; } result = EXIT_SUCCESS; out: return result; } open-vm-tools-9.4.0-1280544/vmblockmounter/vmblockmounter_version.h0000644765153500003110000000307712220061556023502 0ustar dtormts/********************************************************* * Copyright (C) 2011 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vmblockmounter_version.h -- * * Version definitions for the vmblock mount helper application. */ #ifndef _VMBLOCKMOUNTER_VERSION_H_ #define _VMBLOCKMOUNTER_VERSION_H_ /* * This component's version is coupled with Tools versioning. The effect * is that the version increments with each build, and with each Tools * version bump. If and when it becomes necessary to version the component * manually, make sure that the version is bumped any time the component or * its dependencies are changed. */ #include "vm_tools_version.h" #define VMBLOCKMOUNTER_VERSION_COMMAS TOOLS_VERSION_EXT_CURRENT_CSV #define VMBLOCKMOUNTER_VERSION_STRING TOOLS_VERSION_EXT_CURRENT_STR #endif /* _VMBLOCKMOUNTER_VERSION_H_ */ open-vm-tools-9.4.0-1280544/vmblockmounter/Makefile.in0000644765153500003110000005120212220061626020551 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2011 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ sbin_PROGRAMS = mount.vmblock$(EXEEXT) subdir = vmblockmounter DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(sbindir)" PROGRAMS = $(sbin_PROGRAMS) am_mount_vmblock_OBJECTS = vmblockmounter.$(OBJEXT) mount_vmblock_OBJECTS = $(am_mount_vmblock_OBJECTS) mount_vmblock_DEPENDENCIES = ../lib/stubs/libStubs.la DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(mount_vmblock_SOURCES) DIST_SOURCES = $(mount_vmblock_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ mount_vmblock_LDADD = ../lib/stubs/libStubs.la mount_vmblock_SOURCES = vmblockmounter.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu vmblockmounter/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu vmblockmounter/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ } \ ; done uninstall-sbinPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(sbindir)" && rm -f $$files clean-sbinPROGRAMS: @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list mount.vmblock$(EXEEXT): $(mount_vmblock_OBJECTS) $(mount_vmblock_DEPENDENCIES) $(EXTRA_mount_vmblock_DEPENDENCIES) @rm -f mount.vmblock$(EXEEXT) $(LINK) $(mount_vmblock_OBJECTS) $(mount_vmblock_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmblockmounter.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(sbindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-sbinPROGRAMS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-sbinPROGRAMS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-hook .MAKE: install-am install-exec-am install-strip uninstall-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-sbinPROGRAMS cscopelist ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-exec-hook \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-sbinPROGRAMS install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-hook \ uninstall-sbinPROGRAMS @FREEBSD_TRUE@install-exec-hook: @FREEBSD_TRUE@ mv $(DESTDIR)$(sbindir)/mount.vmblock \ @FREEBSD_TRUE@ $(DESTDIR)$(sbindir)/mount_vmblock @FREEBSD_TRUE@ -$(MKDIR_P) $(DESTDIR)/sbin @FREEBSD_TRUE@ -$(LN_S) $(DESTDIR)$(sbindir)/mount_vmblock \ @FREEBSD_TRUE@ $(DESTDIR)/sbin/mount_vmblock &> /dev/null @FREEBSD_TRUE@uninstall-hook: @FREEBSD_TRUE@ rm -f $(DESTDIR)$(sbindir)/mount_vmblock @FREEBSD_FALSE@install-exec-hook: @FREEBSD_FALSE@ -$(MKDIR_P) $(DESTDIR)/sbin @FREEBSD_FALSE@ -$(LN_S) $(DESTDIR)$(sbindir)/mount.vmblock \ @FREEBSD_FALSE@ $(DESTDIR)/sbin/mount.vmblock &> /dev/null @FREEBSD_FALSE@uninstall-hook: @FREEBSD_FALSE@ rm -f $(DESTDIR)/sbin/mount.vmblock # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/configure.ac0000644765153500003110000011277312220061556015740 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### Configure script for building the VMware OSS Tools. ### ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ ################################################################################ # In addition to the usual environment variables and command line # arguments that a configure script usually takes (CFLAGS, LDFLAGS, # etc.), this script also accepts variables of the form: # # CUSTOM_LIB_CPPFLAGS: compile-time flags for LIB # CUSTOM_LIB_LIBS: link-time flags for LIB # RPCGENFLAGS: extra flags to pass to rpcgen # # The following libraries are currently tested: DNET, FUSE, GLIB2, GMODULE, # GOBJECT, GTHREAD, GTK, GTKMM, ICU, LIBPNG, PAM, PROCPS, URIPARSER, ZLIB # # For the procps library: you can provide the name of the procps library on # your system by defining CUSTOM_PROCPS_NAME. By default the configure script # will try both "-lproc" and "-lproc-3.2.7". ################################################################################ ### ### Initialization ### TOOLS_VERSION="9.4.0" AC_INIT( [open-vm-tools], [9.4.0], [open-vm-tools-devel@lists.sourceforge.net]) # In order to make this configure script auto-detect situations where # people have a 32-bit userland running with a 64-bit kernel, we try to ask # the compiler (assumedly gcc) for its default Target:. # We have to set up $TEST_CC manually, since AC_PROG_CC hasn't yet been run (and can't be until AC_CANONICAL_HOST & AC_CANONICAL_BUILD are run) # The purpose of all this is to set up $host_alias/$build_alias in a more # intelligent way than config.guess currently does. TEST_CC="$CC_FOR_BUILD" test -z "$TEST_CC" && TEST_CC="$HOST_CC" test -z "$TEST_CC" && TEST_CC="$CC" if test -n "$TEST_CC" -a -z "$host_alias"; then host_alias="`$TEST_CC -dumpmachine`" if test -z "$build_alias" -a -n "$host_alias"; then build_alias="$host_alias" fi fi unset TEST_CC # checkvm/checkvm.c has no special significance - we just need to pass in a file that # helps autoconf verify that it really has found the source tree. AC_CONFIG_SRCDIR([checkvm/checkvm.c]) # Keep the top-level directory tidy by putting auxiliary build tools and local # macros in separate subdirectories. AC_CONFIG_AUX_DIR([config]) AC_CONFIG_MACRO_DIR([m4]) AC_CANONICAL_HOST AC_CANONICAL_BUILD # Quote the regular expressions case "$host_cpu" in [i[3456]86]) userSpaceBitness="32" ;; [x86_64]) userSpaceBitness="64" ;; [*]) AC_MSG_ERROR([Unknown architecture.]) ;; esac # Operational arguments. AC_ARG_WITH([root-privileges], [AS_HELP_STRING([--without-root-privileges], [does not perform any operations that require root privileges])], [], [with_root_privileges=yes]) # Kernel arguments. # The kernel args have to go here otherwise the KERNEL_RELEASE won't be visible # to getOsVersion() AC_ARG_WITH([kernel-modules], [AS_HELP_STRING([--without-kernel-modules], [does not compile or install the kernel modules])], [], [with_kernel_modules=yes]) AC_ARG_WITH([kernel-release], [AS_HELP_STRING([--with-kernel-release], [specifies the kernel release you want to build against])], [KERNEL_RELEASE="$withval"], [KERNEL_RELEASE=`uname -r`]) AC_ARG_WITH([linuxdir], [AS_HELP_STRING([--with-linuxdir], [specifies the Linux directory you want to use])], [LINUXDIR="$withval"], [LINUXDIR=/lib/modules/$KERNEL_RELEASE]) # Turn the uname output into something we can run comparisons on. getOsVersion() { major_version="`echo $KERNEL_RELEASE | cut -f1 -d. | cut -f1 -d-`" minor_version="`echo $KERNEL_RELEASE | cut -f2 -d. | cut -f1 -d-`" micro_version="`echo $KERNEL_RELEASE | cut -f3 -d. | cut -f1 -d-`" printf '%02d%02d%03d' $major_version $minor_version $micro_version } case "$host_os" in [linux*]) os="linux" ;; [freebsd*]) os="freebsd" ;; [solaris*]) os="solaris" ;; [*]) AC_MSG_WARN([This is an untested and unsupported Operating System. Proceed at your own peril.]) ;; esac osVersion="`getOsVersion`" if test "$with_kernel_modules" = "yes"; then case "$os" in linux) if test "$osVersion" -lt 206009; then AC_MSG_ERROR([Kernels prior to 2.6.9 are not supported in this release of open-vm-tools. Configure using --without-kernel-modules to suppress building kernel drivers.]) fi if test ! -d "$LINUXDIR/kernel/"; then AC_MSG_ERROR([$LINUXDIR/kernel does not exist]) fi LINUXINCLUDE="$LINUXDIR/build/include" if test ! -d "$LINUXINCLUDE"; then AC_MSG_ERROR([Can't find include dir under $LINUXDIR]) fi ;; freebsd) freebsd_sysdir=/usr/src/sys if test -n "$SYSDIR"; then freebsd_sysdir="$SYSDIR" fi if test ! -f "$freebsd_sysdir/conf/kmod.mk"; then AC_MSG_ERROR([FreeBSD kernel tree not found. Please install the kernel sources (or provide the location using SYSDIR) or configure using --without-kernel-modules.]) fi ;; esac fi # Arguments for disabling individual open-vm-tools features or libraries. AC_ARG_ENABLE( multimon, AS_HELP_STRING( [--disable-multimon], [disables multimon, enabled by default]), [enable_multimon="$enableval"], [enable_multimon="yes"]) AC_ARG_WITH( gtk2, AS_HELP_STRING( [--without-gtk2], [compiles without Gtk 2.0]), [with_gtk2="$withval"], [with_gtk2="yes"]) AC_ARG_WITH( gtkmm, AS_HELP_STRING( [--without-gtkmm], [compiles without Gtkmm, sigc++, and related libs]), [with_gtkmm="$withval"], [with_gtkmm="yes"]) AC_ARG_ENABLE( docs, AS_HELP_STRING( [--disable-docs], [disables generation of API documentation; by default, docs are built if doxygen is available.]), [enable_docs="$enableval"], [enable_docs="yes"]) AC_ARG_ENABLE( tests, AS_HELP_STRING( [--disable-tests], [disable compilation of test code.]), [enable_tests="$enableval"], [enable_tests="auto"]) AM_INIT_AUTOMAKE ### ### Constants ### # These need to be declared after initialization. # Some of our macro call-sites require changes to # CPPFLAGS/CFLAGS/LDFLAGS. In such places, we save the original value # of CPPFLAGS/CFLAGS/LDFLAGS before the macro call and restore it when # the call is done. We must perform this save at each macro site, # because CPPFLAGS/CFLAGS/LDFLAGS may change over the course of # configuration. # # CPPFLAGS is intended for preprocessor options (-D and -I mainly) # CFLAGS is intended for compiler options (-O, -f, -W, and so forth) CPPFLAGS="$CPPFLAGS -DUSING_AUTOCONF=1 -DOPEN_VM_TOOLS" ### ### Programs ### # C preprocessor and compiler. AC_PROG_CPP AC_PROG_CC # C++ compiler. Note that unlike AC_PROG_CC, this call does not trigger an # error if no C++ compiler was found; it'll just set the variable CXX to 'g++'. AC_PROG_CXX # This allows features like per-target compiler flags. I.e., you can compile # one copy of the same sources twice with different flags. (See lib/guestApp # for an example.) AM_PROG_CC_C_O # Needed for the various install and uninstall hooks. AC_PROG_INSTALL AC_PROG_SED AC_PROG_LN_S AC_PROG_MKDIR_P # Needed for creating the archives in lib/ and the shared libraries. AC_PROG_LIBTOOL if test "$ac_cv_prog_AR" = false; then AC_MSG_ERROR([The 'ar' utility was not found. Please put ar on the path.]) fi # We use pkg-config to set up the cflags and libs for gtk. AC_CHECK_PROG( [HAVE_PKG_CONFIG], [pkg-config], [yes], [no]) if test "$GCC" != "yes"; then AC_MSG_ERROR([Only GCC is currently supported. Please put gcc in the path.]) fi ### ### Libraries ### AC_PATH_XTRA # # Check for libintl.h. When configuring using "--without-x", /usr/local/include # may not be added to the include path, so code that use glib's i18n functions # would fail to compile because it can't find libintl.h. # AC_CHECK_HEADER([libintl.h], [], [have_libintl=no], []) if test "$have_libintl" = "no"; then unset ac_cv_header_libintl_h CPPFLAGS="$CPPFLAGS -I/usr/local/include" AC_CHECK_HEADER([libintl.h], [], [AC_MSG_ERROR([libintl.h not found. Make sure you have the gettext headers installed.])], []) fi # # Check for glib 2.6.0 or greater. # AC_VMW_CHECK_LIB([glib-2.0], [GLIB2], [glib-2.0], [], [2.6.0], [glib.h], [g_key_file_new], [], [AC_MSG_ERROR([glib >= 2.6.0 is required.])]) AC_VMW_CHECK_LIB([gmodule-2.0], [GMODULE], [gmodule-2.0], [], [2.6.0], [], [], [], [AC_MSG_ERROR([gmodule >= 2.6.0 is required.])]) AC_VMW_CHECK_LIB([gobject-2.0], [GOBJECT], [gobject-2.0], [], [2.6.0], [glib-object.h], [], [], [AC_MSG_ERROR([gobject >= 2.6.0 is required.])]) AC_VMW_CHECK_LIB([gthread-2.0], [GTHREAD], [gthread-2.0], [], [2.6.0], [], [], [], [AC_MSG_ERROR([glib >= 2.6.0 is required.])]) AC_CHECK_PROG([have_genmarshal], [glib-genmarshal], [yes], [no]) if test "$have_genmarshal" != "yes"; then AC_MSG_ERROR([glib-genmarshal is required; make sure it's available in your path.]) fi # # Parts of our Linux code require more recent version of glib # if test "$os" = "linux"; then AC_VMW_CHECK_LIB([glib-2.0], [GLIB2], [glib-2.0], [], [2.14.0], [glib.h], [g_regex_new], [have_glib_2_14=yes], [AC_MSG_WARN([glib is not recent enough, some features will be disabled.])]) fi # # Check for fuse. # AC_VMW_CHECK_LIB([fuse], [FUSE], [fuse], [], [], [fuse.h], [fuse_main], [have_fuse=yes], [have_fuse=no; AC_MSG_WARN([Fuse is missing, vmblock-fuse will be disabled.])]) # # Check for PAM. # AC_ARG_WITH([pam], [AS_HELP_STRING([--without-pam], [compiles without PAM support.])], [], [with_pam=yes]) if test "$with_pam" = "yes"; then AC_VMW_DEFAULT_FLAGS([PAM]) AC_VMW_CHECK_LIB([pam], [PAM], [], [], [], [security/pam_appl.h], [pam_start], [PAM_CPPFLAGS="$PAM_CPPFLAGS -DUSE_PAM"], [AC_VMW_LIB_ERROR([PAM], [pam])]) fi # # Check for CUnit and disable test code if not available. # if test "$enable_tests" = "auto" -o "$enable_tests" = "yes"; then AC_VMW_DEFAULT_FLAGS([CUNIT]) AC_VMW_CHECK_LIB([cunit], [CUNIT], [], [], [], [CUnit/CUnit.h], [CU_initialize_registry], [have_cunit=yes], [have_cunit=no]) if test "$have_cunit" = "no"; then if test "$enable_tests" = "yes"; then AC_VMW_LIB_ERROR([CUNIT], [cunit]) else AC_MSG_WARN([CUnit not found, tests won't be compiled.]) fi fi fi # If the user explicitly disables X11, then don't try to detect the X-related libraries if test "$have_x" = "disabled"; then enable_multimon="no" elif test "$have_x" != "yes"; then AC_MSG_ERROR( [The X11 libraries were not found. Please configure without X11 (using --without-x), or install the libX11 devel package(s).]) else CPPFLAGS="$CPPFLAGS $X_CFLAGS" COMMON_XLIBS="$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS" AC_CHECK_LIB( [Xext], [XeviQueryVersion], [COMMON_XLIBS="-lXext $COMMON_XLIBS"], [AC_MSG_ERROR( [libXext not found. Please configure without X11 (using --without-x), or install the libXext devel package(s).])], [$COMMON_XLIBS]) AC_CHECK_HEADER( [X11/extensions/extutil.h], [], [AC_MSG_ERROR( [X11/extensions/extutil.h header not found - you're probably on Solaris 10 or older. Please copy that header file onto your system manually, or configure without X11 (using --without-x).])], [#include #include ]) if test "$enable_multimon" != "no"; then AC_CHECK_LIB( [Xinerama], [XineramaQueryVersion], [COMMON_XLIBS="-lXinerama $COMMON_XLIBS"], [AC_MSG_ERROR( [libXinerama not found. Please configure without multimon (using --disable-multimon), configure without X11 (using --without-x), or install the libXinerama devel package(s).])], [$COMMON_XLIBS]) fi AC_CHECK_LIB( [Xi], [XOpenDevice], [COMMON_XLIBS="-lXi $COMMON_XLIBS"], [AC_MSG_ERROR( [libXi not found. Please configure without X11 (using --without-x), or install the libXi devel package(s).])], [$COMMON_XLIBS]) AC_CHECK_LIB( [Xrender], [XRenderQueryVersion], [COMMON_XLIBS="-lXrender $COMMON_XLIBS"], [AC_MSG_ERROR( [libXrender not found. Please configure without X11 (using --without-x), or install the libXrender devel package(s).])], [$COMMON_XLIBS]) AC_CHECK_LIB( [Xrandr], [XRRQueryVersion], [COMMON_XLIBS="-lXrandr $COMMON_XLIBS"], [AC_MSG_ERROR( [libXrandr not found. Please configure without X11 (using --without-x) or install the libXrandr devel package(s).])], [$COMMON_XLIBS]) AC_CHECK_LIB( [Xtst], [XTestQueryExtension], [COMMON_XLIBS="-lXtst $COMMON_XLIBS"], [AC_MSG_ERROR( [libXtst not found. Please configure without X11 (using --without-x) or install the libXtst devel package(s).])], [$COMMON_XLIBS]) AC_CHECK_LIB( [SM], [SmcOpenConnection], [XSM_LIBS="-lSM -lICE" && have_xsm_lib="yes"], [] [-lICE]) AC_CHECK_HEADERS([X11/SM/SMlib.h X11/ICE/ICElib.h], [have_xsm_header="yes"], [], []) if test "$have_xsm_lib" = "yes" -a "$have_xsm_header" = "yes"; then have_xsm="yes" fi AC_CHECK_LIB( [Xcomposite], [XCompositeQueryExtension], [XCOMPOSITE_LIBS="-lXcomposite"], [have_xcomposite="no"] []) AC_CHECK_HEADERS([X11/extensions/Xcomposite.h], [], [have_xcomposite="no"], []) if test "$have_xcomposite" != "no"; then have_xcomposite="yes" fi # Check whether we have gtk+ 2.0. if test "$with_gtk2" != "no"; then # gdk_display_get_default_group (added in gtk+ 2.4.0) is function currently # needed by vmware-user. AC_VMW_CHECK_LIB([gtk-x11-2.0], [GTK], [gtk+-2.0], [], [2.4.0], [gtk/gtk.h], [gdk_display_get_default_group], [GTK_CPPFLAGS="$GTK_CPPFLAGS -DGTK2"], [AC_MSG_ERROR([Gtk+ 2.0 library not found or too old. Please configure without Gtk+ support (using --without-gtk2) or install the Gtk+ 2.0 devel package.])]) fi # # Check for gtkmm 2.4.0 or greater. # if test "$with_gtkmm" != "no"; then CUSTOM_GTKMM_CPPFLAGS="$CUSTOM_GTKMM_CPPFLAGS $GTK_CPPFLAGS" AC_VMW_CHECK_LIBXX([gtkmm-2.4], [GTKMM], [gtkmm-2.4], [], [2.4.0], [gtkmm.h], [], [GTKMM_CPPFLAGS="$GTKMM_CPPFLAGS -DHAVE_GTKMM"], [AC_MSG_ERROR([gtkmm library not found. Please install the libgtkmm devel package(s), or re-configure using --without-gtkmm.])]) fi fi # End of checks for X libraries AC_CHECK_LIB( [crypt], [crypt], [HAVE_CRYPT="yes"], [AC_MSG_ERROR( [libcrypt not found. Please install the libc/libcrypt devel package(s).])]) AC_CHECK_FUNCS( dlopen, , [AC_CHECK_LIB( dl, dlopen, [VIX_LIBADD="$VIX_LIBADD -ldl" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -ldl"], [AC_MSG_ERROR( [dlopen was not found, but is required for open-vm-tools to function properly. Please contact your OS vendor.])])]) AC_CHECK_FUNCS([ecvt]) AC_CHECK_FUNCS([fcvt]) if test "$os" = "freebsd" -a "$osVersion" -ge 600000; then AC_CHECK_LIB( [thr], [pthread_mutex_init], [THREAD_LIB=-lthr], [AC_MSG_ERROR( [Unable to locate required threading library libthr.])]) else AC_CHECK_LIB( [pthread], [pthread_mutex_init], [THREAD_LIB=-lpthread], [AC_MSG_ERROR( [libpthread not found. Please install the libc/libpthread devel package(s).])]) fi # PAM prefix AC_ARG_WITH([pam-prefix], [AS_HELP_STRING([--with-pam-prefix], [specifies where pam files go. Default is $(sysconfdir)])], [PAM_PREFIX="$withval"], [PAM_PREFIX='$(sysconfdir)']) if test "$os" = "linux"; then AC_ARG_WITH([procps], [AS_HELP_STRING([--without-procps], [compiles without libproc (disables support for meminfo)])], [], [with_procps=yes]) else with_procps="no" fi if test "$with_procps" = "yes"; then if test -z "$CUSTOM_PROCPS_NAME"; then CUSTOM_PROCPS_NAME=proc fi # XXX: no pkg-config and no procps-config means we need to # hard-code a sensible default. if test -z "$CUSTOM_PROCPS_LIBS"; then CUSTOM_PROCPS_LIBS="-L/lib" fi # Some distros provide libproc-${version}.so only, others provide the # libproc.so symlink. Try both to see what sticks (but only try the 3.2.7 # and 3.2.8 versions - adding every possible version here would be a mess). # # Users can help by providing CUSTOM_PROCPS_NAME / CUSTOM_PROCPS_LIBS if # necessary. have_procps=no AC_VMW_CHECK_LIB([$CUSTOM_PROCPS_NAME], [PROCPS], [], [], [], [], [getstat], [ have_procps=yes; ], []) if test "$have_procps" = "no"; then AC_VMW_CHECK_LIB([proc-3.2.8], [PROCPS], [], [], [], [], [getstat], [ have_procps=yes; ], []) fi if test "$have_procps" = "no"; then AC_VMW_CHECK_LIB([proc-3.2.7], [PROCPS], [], [], [], [], [getstat], [], [AC_MSG_ERROR([libproc not found. Please configure without procps (using --without-procps) or install procps - http://procps.sourceforge.net])]) fi fi if test "$with_procps" != "yes"; then AC_DEFINE([NO_PROCPS], 1, [Define to 1 if building without procps.]) fi AC_ARG_WITH([dnet], [AS_HELP_STRING([--without-dnet], [compiles without libdnet (disables support for nicinfo)])], [], [with_dnet=yes]) have_dnet="no" if test "$with_dnet" = "yes"; then # On Debian, dnet is installed via the libdumbnet package. We need to # detect this so that our source files include dumbnet.h instead of # dnet.h, which is part of a different package altogether. AC_VMW_CHECK_LIB([dumbnet], [DNET], [], [dumbnet-config], [], [dumbnet.h], [intf_open], [have_dnet="yes"; AC_DEFINE([DNET_IS_DUMBNET], 1, [Define to 1 if substituting Debian's libdumbnet for libdnet.])], []) if test $have_dnet = "no"; then AC_VMW_CHECK_LIB([dnet], [DNET], [], [dnet-config], [], [dnet.h], [intf_open], [have_dnet="yes"], []) fi if test $have_dnet = "no"; then AC_MSG_ERROR( [dnet-config was not found on your PATH. Please configure without dnet (using --without-dnet) or install dnet - http://libdnet.sourceforge.net]) fi fi if test "$with_dnet" != "yes"; then AC_DEFINE([NO_DNET], 1, [Define to 1 if building without libdnet.]) fi AC_ARG_WITH([icu], [AS_HELP_STRING([--without-icu], [disables support for ICU])], [], [with_icu=yes]) if test "$have_x" = "yes" -o "$with_icu" = "yes"; then AC_CHECK_TOOL([have_cxx], [$CXX], [no]) if test "$have_cxx" = "no"; then AC_MSG_ERROR([C++ compiler not found. Make sure you have a C++ compiler installed or configure without X11 (using --without-x) and without ICU (using --without-icu).]) fi fi if test "$with_icu" = "yes"; then AC_VMW_CHECK_LIBXX([icuuc], [ICU], [], [icu-config], [], [unicode/utf.h], [], [ICU_CPPFLAGS="$ICU_CPPFLAGS -DUSE_ICU"], [AC_MSG_ERROR([ICU library not found. Please configure without ICU (using --without-icu) or install ICU - http://www.icu-project.org])]) # Check whether we have ICU >= 3.8. AC_LANG_PUSH([C++]) AC_MSG_CHECKING([for ucasemap_utf8ToTitle in ICU]) ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $ICU_CPPFLAGS" AC_TRY_COMPILE([#include ], [ (void) &ucasemap_utf8ToTitle; return 0; ], [ ICU_CPPFLAGS="$ICU_CPPFLAGS -DHAVE_ICU_38" AC_MSG_RESULT([yes]) ], [AC_MSG_RESULT([no])]) CPPFLAGS="$ORIGINAL_CPPFLAGS" AC_LANG_POP([C++]) # Easier to give all modules the ICU defines/includes... CPPFLAGS="$CPPFLAGS $ICU_CPPFLAGS" else CPPFLAGS="$CPPFLAGS -DNO_ICU" fi AC_PATH_PROG( [RPCGEN], [rpcgen], [ AC_MSG_ERROR([rpcgen not found. Please install the libc devel package.]) ]) ### ### Headers ### AC_CHECK_HEADERS([crypt.h]) AC_CHECK_HEADERS([inttypes.h]) AC_CHECK_HEADERS([stdint.h]) AC_CHECK_HEADERS([stdlib.h]) AC_CHECK_HEADERS([wchar.h]) AC_CHECK_HEADERS([sys/inttypes.h]) AC_CHECK_HEADERS([sys/io.h]) AC_CHECK_HEADERS([sys/param.h]) # Required to make the sys/user.h check work correctly on FreeBSD AC_CHECK_HEADERS([sys/sysinfo.h]) AC_CHECK_HEADERS([sys/types.h]) AC_CHECK_HEADERS([sys/user.h], [], [], [ #ifdef HAVE_SYS_PARAM_H # include #endif ]) AC_CHECK_HEADERS([sys/vfs.h]) AC_CHECK_HEADERS([syslimits.h]) AC_CHECK_HEADERS([unwind.h]) AC_CHECK_HEADER( [wchar.h], [HAVE_WCHAR_H="yes"], [HAVE_WCHAR_H="no"]) if test "$os" = "linux"; then # Make sure kernel-headers package is installed. AC_CHECK_HEADER( [linux/unistd.h], [], [AC_MSG_ERROR(linux/unistd.h is not found. Please install kernel-headers/linux-userspace-headers/linux-libc-dev package.)]) fi if test "$enable_multimon" != "no"; then AC_CHECK_HEADER( [X11/extensions/panoramiXproto.h], [], [AC_MSG_ERROR( [panoramiXproto.h not found. Please configure without multimon (using --disable-multimon) or install the libXinerama devel package(s).])], [#include #include ]) fi bsdPrintfWrappers=no if test "$os" = "linux"; then AC_CHECK_LIB([c], [ecvt], [bsdPrintfWrappers=yes], []) fi ### ### Typdefs, structs, and compiler quarks. ### AC_HEADER_STDBOOL AC_C_CONST AC_TYPE_UID_T AC_C_INLINE AC_TYPE_MODE_T AC_TYPE_OFF_T AC_TYPE_PID_T AC_TYPE_SIZE_T AC_CHECK_MEMBERS([struct stat.st_rdev]) AC_HEADER_TIME AC_STRUCT_TM AC_C_VOLATILE ### ### Specific features and OS/arch flags / actions ### ### General flags / actions CFLAGS="$CFLAGS -Wall" CFLAGS="$CFLAGS -Werror" # -Wno-unknown-pragmas is due to gcc not understanding '#pragma ident' in Xlib.h on OpenSolaris. for TEST_CFLAG in -Wno-pointer-sign -Wno-unused-value -fno-strict-aliasing \ -Wno-unknown-pragmas -Wno-uninitialized; do AC_MSG_CHECKING([for GCC flag $TEST_CFLAG]) ORIGINAL_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $TEST_CFLAG" NEW_CFLAG="" AC_TRY_COMPILE( [], [ return 0; ], [NEW_CFLAG=" $TEST_CFLAG" AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no)]) CFLAGS="$ORIGINAL_CFLAGS$NEW_CFLAG" done CPPFLAGS="$CPPFLAGS -DVMX86_TOOLS" CPPFLAGS="$CPPFLAGS" # -fvisibility is used by "core service" plugins, but not required. ORIGINAL_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fvisibility=hidden" AC_MSG_CHECKING([for GCC flag -fvisibility]) AC_TRY_COMPILE([], [return 0;], [PLUGIN_CPPFLAGS="-fvisibility=hidden -DGCC_EXPLICIT_EXPORT"; AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no)]) CFLAGS="$ORIGINAL_CFLAGS" # Detect "unused-but-set-variable" gcc warning and disable it. ORIGINAL_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Wno-unused-but-set-variable" AC_MSG_CHECKING([for GCC flag -Wno-unused-but-set-variable]) AC_TRY_COMPILE([], [return 0;], [ORIGINAL_CFLAGS="$ORIGINAL_CFLAGS -Wno-unused-but-set-variable"; AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no)]) CFLAGS="$ORIGINAL_CFLAGS" BUILDDIR="`pwd`" INCLUDE_DIR="`cd $srcdir; pwd`/lib/include" BLD_INCLUDE_DIR="$BUILDDIR/lib/include" CPPFLAGS="-I$INCLUDE_DIR -I$BLD_INCLUDE_DIR $CPPFLAGS" ### ### Documentation. ### if test "$enable_docs" = "yes"; then AC_CHECK_PROG([have_doxygen], [doxygen], [yes], [no]) if test "$have_doxygen" = "no"; then AC_MSG_WARN([doxygen not found; API documentation will not be generated.]) else AC_PATH_PROG([DOT], [dot], []) if test "$DOT" = ""; then HAVE_DOT=NO else DOT=`dirname $DOT` HAVE_DOT=YES fi AC_SUBST([DOT]) AC_SUBST([HAVE_DOT]) AC_PATH_PROG([MSCGEN], [mscgen], [no]) if test "$MSCGEN" != "no"; then MSCGEN_DIR="`dirname $MSCGEN`" else MSCGEN_DIR= fi AC_SUBST([MSCGEN_DIR]) fi fi ### ### OS/arch-specific flags / actions ### MODULES="" MODULES_OS="$os" TARGET_OS="$os" MODULES_DIR="" buildHgfsmounter=no if test "$have_glib_2_14" = "yes"; then CPPFLAGS="$CPPFLAGS -DHAVE_GLIB_REGEX" fi if test "$os" = "linux"; then MODULES_DIR="$LINUXDIR/kernel/" CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64" CPPFLAGS="$CPPFLAGS -D_LARGEFILE64_SOURCE" CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=500" CPPFLAGS="$CPPFLAGS -D_BSD_SOURCE" CPPFLAGS="$CPPFLAGS -D_SVID_SOURCE" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lrt" MODULES="$MODULES vmsync vmci vsock" MODULES="$MODULES vmxnet vmblock vmhgfs" buildHgfsmounter=yes fi if test "$os" = "freebsd"; then LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lkvm" MODULES_DIR="/boot/modules" if test "$osVersion" -ge 302000; then MODULES="$MODULES vmmemctl" fi if test "$osVersion" -ge 409000; then MODULES="$MODULES vmxnet" fi if test "$osVersion" -ge 600000; then MODULES="$MODULES vmblock vmhgfs" buildHgfsmounter=yes fi if test "$with_kernel_modules" = "yes"; then echo "****************************************************************" echo " You are building FreeBSD kernel modules. Make sure you use " echo " 'make' to build open-vm-tools, and not GNU make ('gmake'). " echo "****************************************************************" fi fi if test "$os" = "solaris"; then LIB_IMPERSONATE_CPPFLAGS="$LIB_IMPERSONATE_CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS" LIB_USER_CPPFLAGS="$LIB_USER_CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lsocket" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lnsl" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lresolv" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lrpcsvc" # Setup defines to identify the OS version. if test "$osVersion" -eq 509000; then CPPFLAGS="$CPPFLAGS -DSOL9" fi if test "$osVersion" -eq 510000; then CPPFLAGS="$CPPFLAGS -DSOL10" fi if test "$osVersion" -eq 511000; then CPPFLAGS="$CPPFLAGS -DSOL11" fi MODULES="$MODULES vmxnet vmmemctl" # HGFS and vmblock need Solaris 10 at least. if test "$osVersion" -ge 510000; then MODULES="$MODULES vmhgfs vmblock" fi # vmxnet3 is built on Solaris 10 / 11 only if GLDv3 is installed. if test "$osVersion" -gt 510000; then AC_CHECK_HEADER( [sys/mac.h], [MODULES="$MODULES vmxnet3"], [AC_MSG_WARN([GLDv3 (sys/mac.h) is not installed, vmxnet3 will not be compiled.])]) fi if test "$with_kernel_modules" = "yes"; then echo "****************************************************************" echo " You are building Solaris kernel modules. Make sure you use " echo " GNU make to build open-vm-tools. " echo "****************************************************************" fi fi AM_CONDITIONAL(BUILD_HGFSMOUNTER, test "$buildHgfsmounter" = "yes") AM_CONDITIONAL(LINUX, test "$os" = "linux") AM_CONDITIONAL(SOLARIS, test "$os" = "solaris") AM_CONDITIONAL(FREEBSD, test "$os" = "freebsd") AM_CONDITIONAL(FREEBSD_CUSTOM_SYSDIR, test "$os" = "freebsd" -a -n "$SYSDIR") AM_CONDITIONAL(THIRTY_TWO_BIT_USERSPACE, test "$userSpaceBitness" = "32") AM_CONDITIONAL(HAVE_X11, test "$have_x" = "yes") AM_CONDITIONAL(HAVE_ICU, test "$with_icu" = "yes") AM_CONDITIONAL(WITH_KERNEL_MODULES, test "$with_kernel_modules" = "yes") AM_CONDITIONAL(HAVE_XSM, test "$have_xsm" = "yes") AM_CONDITIONAL(HAVE_XCOMPOSITE, test "$have_xcomposite" = "yes") AM_CONDITIONAL(ENABLE_TESTS, test "$have_cunit" = "yes") AM_CONDITIONAL(WITH_ROOT_PRIVILEGES, test "$with_root_privileges" = "yes") AM_CONDITIONAL(HAVE_DNET, test "$have_dnet" = "yes") AM_CONDITIONAL(HAVE_DOXYGEN, test "$have_doxygen" = "yes") AM_CONDITIONAL(HAVE_FUSE, test "$have_fuse" = "yes") AM_CONDITIONAL(HAVE_GNU_LD, test "$with_gnu_ld" = "yes") AM_CONDITIONAL(HAVE_GTKMM, test "$have_x" = "yes" -a "$with_gtkmm" = "yes") AM_CONDITIONAL(HAVE_PAM, test "$with_pam" = "yes") AM_CONDITIONAL(USE_SLASH_PROC, test "os" = "linux" -a "$have_glib_2_14" = "yes") AM_CONDITIONAL(USE_PRINTF_WRAPPERS, test "$bsdPrintfWrappers" = "yes") if test "$have_xsm" != "yes"; then AC_DEFINE([NO_XSM], 1, []) fi if test "$have_xcomposite" != "yes"; then AC_DEFINE([NO_XCOMPOSITE]) fi ### Feature-specific flags / actions # Combine where possible # If control reaches this point and multimon is still enabled, then we know # all of the tests for required components have passed and it's safe to allow # multimon. Otherwise, it should be disabled. if test "$enable_multimon" = "no"; then # XXX: For consistency, change this to ENABLE_MULTIMON. This will require # some additional code cleanup. AC_DEFINE([NO_MULTIMON], 1, [Define to 1 if building without multimon support.]) fi LIB_AUTH_CPPFLAGS="$LIB_AUTH_CPPFLAGS $PAM_CPPFLAGS" if test "$HAVE_CRYPT" = "yes"; then LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lcrypt" VIX_LIBADD="$VIX_LIBADD -lcrypt" fi LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD $THREAD_LIB" VIX_LIBADD="$VIX_LIBADD $THREAD_LIB" ### Core Services definitions. HGFS_LIBS="$BUILDDIR/libhgfs/libhgfs.la" VMTOOLS_LIBS="$BUILDDIR/libvmtools/libvmtools.la $GLIB2_LIBS" VMTOOLS_CPPFLAGS="-DVMTOOLS_USE_GLIB $GLIB2_CPPFLAGS" PLUGIN_CPPFLAGS="$VMTOOLS_CPPFLAGS $PLUGIN_CPPFLAGS" PLUGIN_LDFLAGS="-Wl,-z,defs -Wl,-lc -shared -module -avoid-version" # In Solaris, the XDR-related functions are not in libc like in Linux and # FreeBSD, so binaries need to be linked to some extra libraries. XDR_LIBS= if test "$os" = "solaris"; then XDR_LIBS="-lnsl -lrpcsvc" fi # Installation directories for core services plugins. TEST_PLUGIN_INSTALLDIR=$datadir/open-vm-tools/tests COMMON_PLUGIN_INSTALLDIR=$libdir/open-vm-tools/plugins/common VMSVC_PLUGIN_INSTALLDIR=$libdir/open-vm-tools/plugins/vmsvc VMUSR_PLUGIN_INSTALLDIR=$libdir/open-vm-tools/plugins/vmusr # General definitions INSTVMSG='$(SHELL) $(top_srcdir)/scripts/build/instvmsg.sh' RPCGEN_WRAPPER='$(SHELL) $(top_builddir)/scripts/build/rpcgen_wrapper.sh' ### General substs AC_SUBST([HGFS_LIBS]) AC_SUBST([TOOLS_VERSION]) AC_SUBST([TARGET_OS]) AC_SUBST([KERNEL_RELEASE]) AC_SUBST([LINUXINCLUDE]) AC_SUBST([MODULES_OS]) AC_SUBST([MODULES_DIR]) AC_SUBST([MODULES]) AC_SUBST([COMMON_XLIBS]) AC_SUBST([XSM_LIBS]) AC_SUBST([XCOMPOSITE_LIBS]) AC_SUBST([PAM_PREFIX]) AC_SUBST([PLUGIN_CPPFLAGS]) AC_SUBST([PLUGIN_LDFLAGS]) AC_SUBST([VMTOOLS_CPPFLAGS]) AC_SUBST([VMTOOLS_LIBS]) AC_SUBST([RPCGENFLAGS]) AC_SUBST([XDR_LIBS]) AC_SUBST([TEST_PLUGIN_INSTALLDIR]) AC_SUBST([COMMON_PLUGIN_INSTALLDIR]) AC_SUBST([VMSVC_PLUGIN_INSTALLDIR]) AC_SUBST([VMUSR_PLUGIN_INSTALLDIR]) if test "$os" = "freebsd" -a -n "$SYSDIR"; then # If SYSDIR is not defined, AC_SUBST expands to nothing, so we need something # inside this block. true AC_SUBST([SYSDIR]) fi AC_SUBST([INSTVMSG]) AC_SUBST([RPCGEN_WRAPPER]) ### Lib substs AC_SUBST([LIB_AUTH_CPPFLAGS]) AC_SUBST([LIB_IMPERSONATE_CPPFLAGS]) AC_SUBST([LIB_USER_CPPFLAGS]) AC_SUBST([LIBVMTOOLS_LIBADD]) ### Program substs AC_SUBST([VIX_LIBADD]) ### ### Create the Makefiles ### AC_CONFIG_FILES([ \ Makefile \ lib/Makefile \ lib/appUtil/Makefile \ lib/auth/Makefile \ lib/backdoor/Makefile \ lib/dict/Makefile \ lib/dynxdr/Makefile \ lib/err/Makefile \ lib/file/Makefile \ lib/foundryMsg/Makefile \ lib/glibUtils/Makefile \ lib/guestApp/Makefile \ lib/guestRpc/Makefile \ lib/hgfs/Makefile \ lib/hgfsBd/Makefile \ lib/hgfsHelper/Makefile \ lib/hgfsServer/Makefile \ lib/hgfsServerManagerGuest/Makefile \ lib/hgfsServerPolicyGuest/Makefile \ lib/impersonate/Makefile \ lib/lock/Makefile \ lib/message/Makefile \ lib/misc/Makefile \ lib/netUtil/Makefile \ lib/panic/Makefile \ lib/panicDefault/Makefile \ lib/printer/Makefile \ lib/procMgr/Makefile \ lib/rpcChannel/Makefile \ lib/rpcIn/Makefile \ lib/rpcOut/Makefile \ lib/rpcVmx/Makefile \ lib/slashProc/Makefile \ lib/string/Makefile \ lib/stubs/Makefile \ lib/syncDriver/Makefile \ lib/system/Makefile \ lib/unicode/Makefile \ lib/user/Makefile \ lib/vmCheck/Makefile \ lib/vmSignal/Makefile \ lib/wiper/Makefile \ lib/xdg/Makefile \ services/Makefile \ services/vmtoolsd/Makefile \ services/plugins/Makefile \ services/plugins/desktopEvents/Makefile \ services/plugins/dndcp/Makefile \ services/plugins/guestInfo/Makefile \ services/plugins/guestInfo/getlib/Makefile \ services/plugins/hgfsServer/Makefile \ services/plugins/powerOps/Makefile \ services/plugins/resolutionSet/Makefile \ services/plugins/timeSync/Makefile \ services/plugins/vix/Makefile \ services/plugins/vmbackup/Makefile \ vmware-user-suid-wrapper/Makefile \ toolbox/Makefile \ hgfsclient/Makefile \ hgfsmounter/Makefile \ checkvm/Makefile \ rpctool/Makefile \ libguestlib/Makefile \ libguestlib/vmguestlib.pc \ libhgfs/Makefile \ libvmtools/Makefile \ xferlogs/Makefile \ modules/Makefile \ vmblock-fuse/Makefile \ vmblockmounter/Makefile \ tests/Makefile \ tests/vmrpcdbg/Makefile \ tests/testDebug/Makefile \ tests/testPlugin/Makefile \ tests/testVmblock/Makefile \ docs/Makefile \ docs/api/Makefile \ scripts/Makefile \ scripts/build/rpcgen_wrapper.sh \ ]) ### ### Output ### AC_OUTPUT open-vm-tools-9.4.0-1280544/libguestlib/0000755765153500003110000000000012220061624015740 5ustar dtormtsopen-vm-tools-9.4.0-1280544/libguestlib/vmguestlib_version.h0000644765153500003110000000301312220061556022040 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vmguestlib_version.h -- * * Version definitions for GuestLib. */ #ifndef _VMGUESTLIB_VERSION_H_ #define _VMGUESTLIB_VERSION_H_ /* * This component's version is coupled with Tools versioning. The effect * is that the version increments with each build, and with each Tools * version bump. If and when it becomes necessary to version the component * manually, make sure that the version is bumped any time the component or * its dependencies are changed. */ #include "vm_tools_version.h" #define VMGUESTLIB_VERSION_COMMAS TOOLS_VERSION_EXT_CURRENT_CSV #define VMGUESTLIB_VERSION_STRING TOOLS_VERSION_EXT_CURRENT_STR #endif /* _VMGUESTLIB_VERSION_H_ */ open-vm-tools-9.4.0-1280544/libguestlib/vmGuestLib.c0000644765153500003110000014210312220061556020172 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * Implementation of the guestlib library. */ #include #include #include #include "vmware.h" #include "vmGuestLib.h" #include "vmGuestLibInt.h" #include "str.h" #include "rpcout.h" #include "vmcheck.h" #include "util.h" #include "debug.h" #include "strutil.h" #include "guestlibV3.h" #include "guestlibIoctl.h" #include "dynxdr.h" #include "xdrutil.h" #include "ctype.h" #define GUESTLIB_NAME "VMware Guest API" /* * These are client side data structures, separate from the wire data formats * (VMGuestLibDataV[23]). */ /* Layout of the buffer holding the variable length array of V3 statistics. */ typedef struct { GuestLibV3StatCount numStats; GuestLibV3Stat stats[0]; } VMGuestLibStatisticsV3; /* Layout of the handle that holds information about the statistics. */ typedef struct { uint32 version; VMSessionId sessionId; /* * Statistics. * * dataSize is the size of the buffer pointed to by 'data'. * For v2 protocol: * - 'data' points to VMGuestLibDataV2 struct, * For v3 protocol: * - 'data' points to VMGuestLibStatisticsV3 struct. */ size_t dataSize; void *data; } VMGuestLibHandleType; #define HANDLE_VERSION(h) (((VMGuestLibHandleType *)(h))->version) #define HANDLE_SESSIONID(h) (((VMGuestLibHandleType *)(h))->sessionId) #define HANDLE_DATA(h) (((VMGuestLibHandleType *)(h))->data) #define HANDLE_DATASIZE(h) (((VMGuestLibHandleType *)(h))->dataSize) #define VMGUESTLIB_GETSTAT_V2(HANDLE, ERROR, OUTPTR, FIELDNAME) \ do { \ VMGuestLibDataV2 *_dataV2 = HANDLE_DATA(HANDLE); \ ASSERT(HANDLE_VERSION(HANDLE) == 2); \ if (!_dataV2->FIELDNAME.valid) { \ (ERROR) = VMGUESTLIB_ERROR_NOT_AVAILABLE; \ break; \ } \ *(OUTPTR) = _dataV2->FIELDNAME.value; \ (ERROR) = VMGUESTLIB_ERROR_SUCCESS; \ } while (0) #define VMGUESTLIB_GETSTAT_V3(HANDLE, ERROR, OUTPTR, FIELDNAME, STATID) \ do { \ void *_data; \ GuestLibV3Stat _stat; \ \ (ERROR) = VMGuestLibCheckArgs((HANDLE), (OUTPTR), &_data); \ if (VMGUESTLIB_ERROR_SUCCESS != (ERROR)) { \ break; \ } \ ASSERT(HANDLE_VERSION(HANDLE) == 3); \ (ERROR) = VMGuestLibGetStatisticsV3((HANDLE), (STATID), &_stat); \ if ((ERROR) != VMGUESTLIB_ERROR_SUCCESS) { \ break; \ } \ if (!_stat.GuestLibV3Stat_u.FIELDNAME.valid) { \ (ERROR) = VMGUESTLIB_ERROR_NOT_AVAILABLE; \ break; \ } \ ASSERT(_stat.d == (STATID)); \ if (sizeof *(OUTPTR) < sizeof _stat.GuestLibV3Stat_u.FIELDNAME.value) { \ (ERROR) = VMGUESTLIB_ERROR_BUFFER_TOO_SMALL; \ break; \ } \ *(OUTPTR) = _stat.GuestLibV3Stat_u.FIELDNAME.value; \ (ERROR) = VMGUESTLIB_ERROR_SUCCESS; \ } while (0) /* Handle extraction of integral type statistics. */ #define VMGUESTLIB_GETFN_BODY(HANDLE, ERROR, OUTPTR, FIELDNAME, STATID) \ do { \ void *_data; \ \ (ERROR) = VMGuestLibCheckArgs((HANDLE), (OUTPTR), &_data); \ if (VMGUESTLIB_ERROR_SUCCESS != (ERROR)) { \ break; \ } \ if (HANDLE_VERSION(HANDLE) == 2) { \ VMGUESTLIB_GETSTAT_V2(HANDLE, ERROR, OUTPTR, FIELDNAME); \ } else if (HANDLE_VERSION(HANDLE) == 3) { \ VMGUESTLIB_GETSTAT_V3(HANDLE, ERROR, OUTPTR, FIELDNAME, STATID); \ } \ } while (0) /* *----------------------------------------------------------------------------- * * VMGuestLib_GetErrorText -- * * Get the English text explanation for a given GuestLib error code. * * Results: * The error string for the given error code. * * Side effects: * None * *----------------------------------------------------------------------------- */ char const * VMGuestLib_GetErrorText(VMGuestLibError error) // IN: Error code { switch (error) { case VMGUESTLIB_ERROR_SUCCESS: return "No error"; case VMGUESTLIB_ERROR_NOT_RUNNING_IN_VM: return GUESTLIB_NAME " is not running in a Virtual Machine"; case VMGUESTLIB_ERROR_NOT_ENABLED: return GUESTLIB_NAME " is not enabled on the host"; case VMGUESTLIB_ERROR_NOT_AVAILABLE: return "This value is not available on this host"; case VMGUESTLIB_ERROR_NO_INFO: return "VMGuestLib_UpdateInfo() has not been called"; case VMGUESTLIB_ERROR_MEMORY: return "There is not enough system memory"; case VMGUESTLIB_ERROR_BUFFER_TOO_SMALL: return "The provided memory buffer is too small"; case VMGUESTLIB_ERROR_INVALID_HANDLE: return "The provided handle is invalid"; case VMGUESTLIB_ERROR_INVALID_ARG: return "One or more arguments were invalid"; case VMGUESTLIB_ERROR_OTHER: return "Other error"; case VMGUESTLIB_ERROR_UNSUPPORTED_VERSION: return "Host does not support this request."; default: ASSERT(FALSE); // We want to catch this case in debug builds. return "Other error"; } NOT_REACHED(); } /* *----------------------------------------------------------------------------- * * VMGuestLibCheckArgs -- * * Helper function to factor out common argument checking code. * * If VMGUESTLIB_ERROR_SUCCESS is returned, args are valid and *data * now points to the valid struct. * * Results: * Error indicating results * * Side effects: * None * *----------------------------------------------------------------------------- */ static VMGuestLibError VMGuestLibCheckArgs(VMGuestLibHandle handle, // IN void *outArg, // IN void **data) // OUT { ASSERT(data); if (NULL == handle) { return VMGUESTLIB_ERROR_INVALID_HANDLE; } if (NULL == outArg) { return VMGUESTLIB_ERROR_INVALID_ARG; } *data = HANDLE_DATA(handle); if (0 == HANDLE_SESSIONID(handle)) { return VMGUESTLIB_ERROR_NO_INFO; } return VMGUESTLIB_ERROR_SUCCESS; } /* *----------------------------------------------------------------------------- * * VMGuestLib_OpenHandle -- * * Obtain a handle for use with GuestLib. Allocates resources and * returns a handle that should be released using * VMGuestLib_CloseHandle(). * * Results: * VMGuestLibError * * Side effects: * Resources are allocated. * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_OpenHandle(VMGuestLibHandle *handle) // OUT { VMGuestLibHandleType *data; if (!VmCheck_IsVirtualWorld()) { Debug("VMGuestLib_OpenHandle: Not in a VM.\n"); return VMGUESTLIB_ERROR_NOT_RUNNING_IN_VM; } if (NULL == handle) { return VMGUESTLIB_ERROR_INVALID_ARG; } data = Util_SafeCalloc(1, sizeof *data); if (!data) { Debug("VMGuestLib_OpenHandle: Unable to allocate memory\n"); return VMGUESTLIB_ERROR_MEMORY; } *handle = (VMGuestLibHandle)data; return VMGUESTLIB_ERROR_SUCCESS; } /* *----------------------------------------------------------------------------- * * VMGuestLib_CloseHandle -- * * Release resources associated with a handle obtained from * VMGuestLib_OpenHandle(). Handle is invalid after return * from this call. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_CloseHandle(VMGuestLibHandle handle) // IN { void *data; if (NULL == handle) { return VMGUESTLIB_ERROR_INVALID_HANDLE; } data = HANDLE_DATA(handle); if (data != NULL && HANDLE_SESSIONID(handle) != 0 && HANDLE_VERSION(handle) == 3) { VMGuestLibStatisticsV3 *v3stats = data; GuestLibV3StatCount count; for (count = 0; count < v3stats->numStats; count++) { VMX_XDR_FREE(xdr_GuestLibV3Stat, &v3stats->stats[count]); } } free(data); /* Be paranoid. */ HANDLE_DATA(handle) = NULL; free(handle); return VMGUESTLIB_ERROR_SUCCESS; } /* *----------------------------------------------------------------------------- * * VMGuestLibUpdateInfo -- * * Retrieve the bundle of stats over the backdoor and update the pointer to * the Guestlib info in the handle. * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ static VMGuestLibError VMGuestLibUpdateInfo(VMGuestLibHandle handle) // IN { char *reply = NULL; size_t replyLen; VMGuestLibError ret = VMGUESTLIB_ERROR_INVALID_ARG; uint32 hostVersion = HANDLE_VERSION(handle); /* * Starting with the highest supported protocol (major) version, negotiate * down to the highest host supported version. Host supports minimum version * 2. */ if (hostVersion == 0) { hostVersion = VMGUESTLIB_DATA_VERSION; } do { char commandBuf[64]; unsigned int index = 0; /* Free the last reply when retrying. */ free(reply); reply = NULL; /* * Construct command string with the command name and the version * of the data struct that we want. */ Str_Sprintf(commandBuf, sizeof commandBuf, "%s %d", VMGUESTLIB_BACKDOOR_COMMAND_STRING, hostVersion); /* Send the request. */ if (RpcOut_sendOne(&reply, &replyLen, commandBuf)) { VMGuestLibDataV2 *v2reply = (VMGuestLibDataV2 *)reply; VMSessionId sessionId = HANDLE_SESSIONID(handle); ASSERT(hostVersion == v2reply->hdr.version); if (sessionId != 0 && sessionId != v2reply->hdr.sessionId) { /* Renegotiate protocol if sessionId changed. */ hostVersion = VMGUESTLIB_DATA_VERSION; HANDLE_SESSIONID(handle) = 0; continue; } ret = VMGUESTLIB_ERROR_SUCCESS; break; } /* * Host is older and doesn't support the requested protocol version. * Request the highest version the host supports. */ Debug("Failed to retrieve info: %s\n", reply ? reply : "NULL"); if (hostVersion == 2 || Str_Strncmp(reply, "Unknown command", sizeof "Unknown command") == 0) { /* * Host does not support this feature. Older (v2) host would return * "Unsupported version" if it doesn't recognize the requested version. * * XXX: Maybe use another error code for this case where the host * product doesn't support this feature? */ ret = VMGUESTLIB_ERROR_NOT_ENABLED; break; } else if (hostVersion == 3) { /* * Host supports v2 at a minimum. If request for v3 fails, then just use * v2, since v2 host does not send the highest supported version in the * reply. */ hostVersion = 2; HANDLE_SESSIONID(handle) = 0; continue; } else if (!StrUtil_GetNextUintToken(&hostVersion, &index, reply, ":")) { /* * v3 and onwards, the host returns the highest major version it supports, * if the requested version is not supported. So parse out the host * version from the reply and return error if it didn't. */ Debug("Bad reply received from host.\n"); ret = VMGUESTLIB_ERROR_OTHER; break; } ASSERT(hostVersion < VMGUESTLIB_DATA_VERSION); } while (ret != VMGUESTLIB_ERROR_SUCCESS); if (ret != VMGUESTLIB_ERROR_SUCCESS) { goto done; } /* Sanity check the results. */ if (replyLen < sizeof hostVersion) { Debug("Unable to retrieve version\n"); ret = VMGUESTLIB_ERROR_OTHER; goto done; } if (hostVersion == 2) { VMGuestLibDataV2 *v2reply = (VMGuestLibDataV2 *)reply; size_t dataSize = sizeof *v2reply; /* More sanity checks. */ if (v2reply->hdr.version != hostVersion) { Debug("Incorrect data version returned\n"); ret = VMGUESTLIB_ERROR_OTHER; goto done; } if (replyLen != dataSize) { Debug("Incorrect data size returned\n"); ret = VMGUESTLIB_ERROR_OTHER; goto done; } /* Store the reply in the handle. */ HANDLE_VERSION(handle) = v2reply->hdr.version; HANDLE_SESSIONID(handle) = v2reply->hdr.sessionId; if (HANDLE_DATASIZE(handle) < dataSize) { /* [Re]alloc if the local handle buffer is not big enough. */ free(HANDLE_DATA(handle)); HANDLE_DATA(handle) = Util_SafeCalloc(1, dataSize); HANDLE_DATASIZE(handle) = dataSize; } memcpy(HANDLE_DATA(handle), reply, replyLen); /* Make sure resourcePoolPath is NUL terminated. */ v2reply = HANDLE_DATA(handle); v2reply->resourcePoolPath.value[sizeof v2reply->resourcePoolPath.value - 1] = '\0'; ret = VMGUESTLIB_ERROR_SUCCESS; } else if (hostVersion == 3) { VMGuestLibDataV3 *v3reply = (VMGuestLibDataV3 *)reply; size_t dataSize; XDR xdrs; GuestLibV3StatCount count; VMGuestLibStatisticsV3 *v3stats; /* More sanity checks. */ if (v3reply->hdr.version != hostVersion) { Debug("Incorrect data version returned\n"); ret = VMGUESTLIB_ERROR_OTHER; goto done; } if (replyLen < sizeof *v3reply) { Debug("Incorrect data size returned\n"); ret = VMGUESTLIB_ERROR_OTHER; goto done; } /* 0. Copy the reply version and sessionId to the handle. */ HANDLE_VERSION(handle) = v3reply->hdr.version; HANDLE_SESSIONID(handle) = v3reply->hdr.sessionId; /* * 1. Retrieve the length of the statistics array from the XDR encoded * part of the reply. */ xdrmem_create(&xdrs, v3reply->data, v3reply->dataSize, XDR_DECODE); if (!xdr_GuestLibV3StatCount(&xdrs, &count)) { xdr_destroy(&xdrs); goto done; } if (count >= GUESTLIB_MAX_STATISTIC_ID) { /* * Host has more than we can process. So process only what this side * can. */ count = GUESTLIB_MAX_STATISTIC_ID - 1; } /* 2. [Re]alloc if the local handle buffer is not big enough. */ dataSize = sizeof *v3stats + (count * sizeof (GuestLibV3Stat)); if (HANDLE_DATASIZE(handle) < dataSize) { free(HANDLE_DATA(handle)); HANDLE_DATA(handle) = Util_SafeCalloc(1, dataSize); HANDLE_DATASIZE(handle) = dataSize; } /* 3. Unmarshal the array of statistics. */ v3stats = HANDLE_DATA(handle); v3stats->numStats = count; for (count = 0; count < v3stats->numStats; count++) { GuestLibV3TypeIds statId = count + 1; /* Unmarshal the statistic. */ if (!xdr_GuestLibV3Stat(&xdrs, &v3stats->stats[count])) { break; } /* Host sends all the V3 statistics it supports, in order. */ if (v3stats->stats[count].d != statId) { break; } } if (count >= v3stats->numStats) { ret = VMGUESTLIB_ERROR_SUCCESS; } else { /* * Error while unmarshalling. Deep-free already unmarshalled * statistics and invalidate the data in the handle. */ GuestLibV3StatCount c; for (c = 0; c < count; c++) { VMX_XDR_FREE(xdr_GuestLibV3Stat, &v3stats->stats[c]); } HANDLE_SESSIONID(handle) = 0; } /* 4. Free resources. */ xdr_destroy(&xdrs); } else { /* * Host should never reply with a higher version protocol than requested. */ ret = VMGUESTLIB_ERROR_OTHER; } done: free(reply); return ret; } /* *----------------------------------------------------------------------------- * * VMGuestLib_UpdateInfo -- * * Update VMGuestLib's internal info state. * * Results: * VMGuestLibError * * Side effects: * Previous stat values will be overwritten. * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_UpdateInfo(VMGuestLibHandle handle) // IN { VMGuestLibError error; if (NULL == handle) { return VMGUESTLIB_ERROR_INVALID_HANDLE; } /* * We check for virtual world in VMGuestLib_OpenHandle, so we don't * need to do the test again here. */ error = VMGuestLibUpdateInfo(handle); if (error != VMGUESTLIB_ERROR_SUCCESS) { Debug("VMGuestLibUpdateInfo failed: %d\n", error); HANDLE_SESSIONID(handle) = 0; return error; } return VMGUESTLIB_ERROR_SUCCESS; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetSessionId -- * * Retrieve the session ID for this virtual machine. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetSessionId(VMGuestLibHandle handle, // IN VMSessionId *id) // OUT { void *data; VMGuestLibError error; error = VMGuestLibCheckArgs(handle, id, &data); if (VMGUESTLIB_ERROR_SUCCESS != error) { return error; } *id = HANDLE_SESSIONID(handle); return VMGUESTLIB_ERROR_SUCCESS; } /* *----------------------------------------------------------------------------- * * VMGuestLibGetStatisticsV3 -- * * Accessor helper to retrieve the requested V3 statistic. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ static VMGuestLibError VMGuestLibGetStatisticsV3(VMGuestLibHandle handle, // IN GuestLibV3TypeIds statId, // IN GuestLibV3Stat *outStat) // OUT { VMGuestLibStatisticsV3 *stats = HANDLE_DATA(handle); uint32 statIdx = statId - 1; /* * Check that the requested statistic is supported by the host. V3 host sends * all the available statistics, in order. So any statistics that were added * to this version of guestlib, but unsupported by the host, would not be * sent by the host. */ if (statIdx >= stats->numStats) { return VMGUESTLIB_ERROR_UNSUPPORTED_VERSION; } memcpy(outStat, &stats->stats[statIdx], sizeof *outStat); return VMGUESTLIB_ERROR_SUCCESS; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetCpuReservationMHz -- * * Retrieve CPU min speed. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetCpuReservationMHz(VMGuestLibHandle handle, // IN uint32 *cpuReservationMHz) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETFN_BODY(handle, error, cpuReservationMHz, cpuReservationMHz, GUESTLIB_CPU_RESERVATION_MHZ); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetCpuLimitMHz -- * * Retrieve CPU max speed. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetCpuLimitMHz(VMGuestLibHandle handle, // IN uint32 *cpuLimitMHz) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETFN_BODY(handle, error, cpuLimitMHz, cpuLimitMHz, GUESTLIB_CPU_LIMIT_MHZ); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetCpuShares -- * * Retrieve CPU shares. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetCpuShares(VMGuestLibHandle handle, // IN uint32 *cpuShares) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETFN_BODY(handle, error, cpuShares, cpuShares, GUESTLIB_CPU_SHARES); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetCpuUsedMs -- * * Retrieve CPU used time. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetCpuUsedMs(VMGuestLibHandle handle, // IN uint64 *cpuUsedMs) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETFN_BODY(handle, error, cpuUsedMs, cpuUsedMs, GUESTLIB_CPU_USED_MS); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetHostProcessorSpeed -- * * Retrieve host processor speed. This can be used along with * CpuUsedMs and elapsed time to estimate approximate effective * VM CPU speed over a time interval. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetHostProcessorSpeed(VMGuestLibHandle handle, // IN uint32 *mhz) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETFN_BODY(handle, error, mhz, hostMHz, GUESTLIB_HOST_MHZ); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetMemReservationMB -- * * Retrieve min memory. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetMemReservationMB(VMGuestLibHandle handle, // IN uint32 *memReservationMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETFN_BODY(handle, error, memReservationMB, memReservationMB, GUESTLIB_MEM_RESERVATION_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetMemLimitMB -- * * Retrieve max memory. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetMemLimitMB(VMGuestLibHandle handle, // IN uint32 *memLimitMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETFN_BODY(handle, error, memLimitMB, memLimitMB, GUESTLIB_MEM_LIMIT_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetMemShares -- * * Retrieve memory shares. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetMemShares(VMGuestLibHandle handle, // IN uint32 *memShares) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETFN_BODY(handle, error, memShares, memShares, GUESTLIB_MEM_SHARES); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetMemMappedMB -- * * Retrieve mapped memory. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetMemMappedMB(VMGuestLibHandle handle, // IN uint32 *memMappedMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETFN_BODY(handle, error, memMappedMB, memMappedMB, GUESTLIB_MEM_MAPPED_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetMemActiveMB -- * * Retrieve active memory. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetMemActiveMB(VMGuestLibHandle handle, // IN uint32 *memActiveMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETFN_BODY(handle, error, memActiveMB, memActiveMB, GUESTLIB_MEM_ACTIVE_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetMemOverheadMB -- * * Retrieve overhead memory. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetMemOverheadMB(VMGuestLibHandle handle, // IN uint32 *memOverheadMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETFN_BODY(handle, error, memOverheadMB, memOverheadMB, GUESTLIB_MEM_OVERHEAD_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetMemBalloonedMB -- * * Retrieve ballooned memory. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetMemBalloonedMB(VMGuestLibHandle handle, // IN uint32 *memBalloonedMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETFN_BODY(handle, error, memBalloonedMB, memBalloonedMB, GUESTLIB_MEM_BALLOONED_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetMemSwappedMB -- * * Retrieve swapped memory. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetMemSwappedMB(VMGuestLibHandle handle, // IN uint32 *memSwappedMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETFN_BODY(handle, error, memSwappedMB, memSwappedMB, GUESTLIB_MEM_SWAPPED_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetMemSharedMB -- * * Retrieve shared memory. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetMemSharedMB(VMGuestLibHandle handle, // IN uint32 *memSharedMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETFN_BODY(handle, error, memSharedMB, memSharedMB, GUESTLIB_MEM_SHARED_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetMemSharedSavedMB -- * * Retrieve shared saved memory. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetMemSharedSavedMB(VMGuestLibHandle handle, // IN uint32 *memSharedSavedMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETFN_BODY(handle, error, memSharedSavedMB, memSharedSavedMB, GUESTLIB_MEM_SHARED_SAVED_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetMemUsedMB -- * * Retrieve used memory. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetMemUsedMB(VMGuestLibHandle handle, // IN uint32 *memUsedMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETFN_BODY(handle, error, memUsedMB, memUsedMB, GUESTLIB_MEM_USED_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetElapsedMs -- * * Retrieve elapsed time on the host. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetElapsedMs(VMGuestLibHandle handle, // IN uint64 *elapsedMs) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETFN_BODY(handle, error, elapsedMs, elapsedMs, GUESTLIB_ELAPSED_MS); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetResourcePoolPath -- * * Retrieve Resource Pool Path. * * pathBuffer is a pointer to a buffer that will receive the * resource pool path string. bufferSize is a pointer to the * size of the pathBuffer in bytes. If bufferSize is not large * enough to accomodate the path and NUL terminator, then * VMGUESTLIB_ERROR_BUFFER_TOO_SMALL is returned and bufferSize * contains the amount of memory needed (in bytes). * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetResourcePoolPath(VMGuestLibHandle handle, // IN size_t *bufferSize, // IN/OUT char *pathBuffer) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; do { size_t size; if (NULL == handle) { error = VMGUESTLIB_ERROR_INVALID_HANDLE; break; } if (NULL == bufferSize || NULL == pathBuffer) { error = VMGUESTLIB_ERROR_INVALID_ARG; break; } if (0 == HANDLE_SESSIONID(handle)) { error = VMGUESTLIB_ERROR_NO_INFO; break; } if (HANDLE_VERSION(handle) == 2) { VMGuestLibDataV2 *dataV2; dataV2 = (VMGuestLibDataV2 *)HANDLE_DATA(handle); if (!dataV2->resourcePoolPath.valid) { error = VMGUESTLIB_ERROR_NOT_AVAILABLE; break; } /* * Check buffer size. It's safe to use strlen because we squash the * final byte of resourcePoolPath in VMGuestLibUpdateInfo. */ size = strlen(dataV2->resourcePoolPath.value) + 1; if (*bufferSize < size) { *bufferSize = size; error = VMGUESTLIB_ERROR_BUFFER_TOO_SMALL; break; } memcpy(pathBuffer, dataV2->resourcePoolPath.value, size); error = VMGUESTLIB_ERROR_SUCCESS; } else if (HANDLE_VERSION(handle) == 3) { VMGuestLibStatisticsV3 *stats = HANDLE_DATA(handle); GuestLibV3Stat *stat = &stats->stats[GUESTLIB_RESOURCE_POOL_PATH - 1]; if (!stat->GuestLibV3Stat_u.resourcePoolPath.valid) { error = VMGUESTLIB_ERROR_NOT_AVAILABLE; break; } size = strlen(stat->GuestLibV3Stat_u.resourcePoolPath.value) + 1; if (*bufferSize < size) { *bufferSize = size; error = VMGUESTLIB_ERROR_BUFFER_TOO_SMALL; break; } memcpy(pathBuffer, stat->GuestLibV3Stat_u.resourcePoolPath.value, size); error = VMGUESTLIB_ERROR_SUCCESS; } } while (0); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetCpuStolenMs -- * * Retrieve CPU stolen. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetCpuStolenMs(VMGuestLibHandle handle, // IN uint64 *cpuStolenMs) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETSTAT_V3(handle, error, cpuStolenMs, cpuStolenMs, GUESTLIB_CPU_STOLEN_MS); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetMemTargetSizeMB -- * * Retrieve Memory Target Size. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetMemTargetSizeMB(VMGuestLibHandle handle, // IN uint64 *memTargetSizeMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETSTAT_V3(handle, error, memTargetSizeMB, memTargetSizeMB, GUESTLIB_MEM_TARGET_SIZE_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetHostNumCpuCores -- * * Number of physical CPU cores on the host machine. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetHostNumCpuCores(VMGuestLibHandle handle, // IN uint32 *hostNumCpuCores) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETSTAT_V3(handle, error, hostNumCpuCores, hostCpuNumCores, GUESTLIB_HOST_CPU_NUM_CORES); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetHostCpuUsedMs -- * * Total CPU time used by host. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetHostCpuUsedMs(VMGuestLibHandle handle, // IN uint64 *hostCpuUsedMs) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETSTAT_V3(handle, error, hostCpuUsedMs, hostCpuUsedMs, GUESTLIB_HOST_CPU_USED_MS); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetHostMemSwappedMB -- * * Total swapped out memory on the host. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetHostMemSwappedMB(VMGuestLibHandle handle, // IN uint64 *hostMemSwappedMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETSTAT_V3(handle, error, hostMemSwappedMB, hostMemSwappedMB, GUESTLIB_HOST_MEM_SWAPPED_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetHostMemSharedMB -- * * Total COW (Copy-On-Write) memory on host. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetHostMemSharedMB(VMGuestLibHandle handle, // IN uint64 *hostMemSharedMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETSTAT_V3(handle, error, hostMemSharedMB, hostMemSharedMB, GUESTLIB_HOST_MEM_SHARED_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetHostMemUsedMB -- * * Total consumed memory on host. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetHostMemUsedMB(VMGuestLibHandle handle, // IN uint64 *hostMemUsedMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETSTAT_V3(handle, error, hostMemUsedMB, hostMemUsedMB, GUESTLIB_HOST_MEM_USED_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetHostMemPhysMB -- * * Total memory available to host OS kernel. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetHostMemPhysMB(VMGuestLibHandle handle, // IN uint64 *hostMemPhysMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETSTAT_V3(handle, error, hostMemPhysMB, hostMemPhysMB, GUESTLIB_HOST_MEM_PHYS_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetHostMemPhysFreeMB -- * * Total phsyical memory free on host. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetHostMemPhysFreeMB(VMGuestLibHandle handle, // IN uint64 *hostMemPhysFreeMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETSTAT_V3(handle, error, hostMemPhysFreeMB, hostMemPhysFreeMB, GUESTLIB_HOST_MEM_PHYS_FREE_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetHostMemUsedMB -- * * Total host kernel memory overhead. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetHostMemKernOvhdMB(VMGuestLibHandle handle, // IN uint64 *hostMemKernOvhdMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETSTAT_V3(handle, error, hostMemKernOvhdMB, hostMemKernOvhdMB, GUESTLIB_HOST_MEM_KERN_OVHD_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetHostMemMappedMB -- * * Total mapped memory on host. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetHostMemMappedMB(VMGuestLibHandle handle, // IN uint64 *hostMemMappedMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETSTAT_V3(handle, error, hostMemMappedMB, hostMemMappedMB, GUESTLIB_HOST_MEM_MAPPED_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetHostMemUnmappedMB -- * * Total unmapped memory on host. * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetHostMemUnmappedMB(VMGuestLibHandle handle, // IN uint64 *hostMemUnmappedMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETSTAT_V3(handle, error, hostMemUnmappedMB, hostMemUnmappedMB, GUESTLIB_HOST_MEM_UNMAPPED_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetMemZippedMB -- * * Total zipped VM memory * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetMemZippedMB(VMGuestLibHandle handle, // IN uint32 *memZippedMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETSTAT_V3(handle, error, memZippedMB, memZippedMB, GUESTLIB_MEM_ZIPPED_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetMemZipSavedMB -- * * Total memopry saved by zipping VM memory * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetMemZipSavedMB(VMGuestLibHandle handle, // IN uint32 *memZipSavedMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETSTAT_V3(handle, error, memZipSavedMB, memZipSavedMB, GUESTLIB_MEM_ZIPSAVED_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetMemLLSwappedMB -- * * VM memory swapped to SSD * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetMemLLSwappedMB(VMGuestLibHandle handle, // IN uint32 *memLLSwappedMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETSTAT_V3(handle, error, memLLSwappedMB, memLLSwappedMB, GUESTLIB_MEM_LLSWAPPED_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetMemSwapTargetMB -- * * VM memory swap target * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetMemSwapTargetMB(VMGuestLibHandle handle, // IN uint32 *memSwapTargetMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETSTAT_V3(handle, error, memSwapTargetMB, memSwapTargetMB, GUESTLIB_MEM_SWAP_TARGET_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetMemBalloonTargetMB -- * * VM memory balloon target size * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetMemBalloonTargetMB(VMGuestLibHandle handle, // IN uint32 *memBalloonTargetMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETSTAT_V3(handle, error, memBalloonTargetMB, memBalloonTargetMB, GUESTLIB_MEM_BALLOON_TARGET_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLib_GetMemBalloonMaxMB -- * * VM memory balloon limit * * Results: * VMGuestLibError * * Side effects: * None * *----------------------------------------------------------------------------- */ VMGuestLibError VMGuestLib_GetMemBalloonMaxMB(VMGuestLibHandle handle, // IN uint32 *memBalloonMaxMB) // OUT { VMGuestLibError error = VMGUESTLIB_ERROR_OTHER; VMGUESTLIB_GETSTAT_V3(handle, error, memBalloonMaxMB, memBalloonMaxMB, GUESTLIB_MEM_BALLOON_MAX_MB); return error; } /* *----------------------------------------------------------------------------- * * VMGuestLibIoctl -- * * Marshal and invoke the guestlib ioctl. * * Results: * TRUE on success, FALSE otherwise (reply contains error detail, if * provided) * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool VMGuestLibIoctl(const GuestLibIoctlParam *param, char **reply, size_t *replySize) { XDR xdrs; Bool ret; static const char *request = VMGUESTLIB_IOCTL_COMMAND_STRING " "; if (param == NULL || param->d >= GUESTLIB_IOCTL_MAX) { return FALSE; } if (NULL == DynXdr_Create(&xdrs)) { return FALSE; } if (!DynXdr_AppendRaw(&xdrs, request, strlen(request)) || !xdr_GuestLibIoctlParam(&xdrs, (GuestLibIoctlParam *)param)) { DynXdr_Destroy(&xdrs, TRUE); return FALSE; } ret = RpcOut_SendOneRaw(DynXdr_Get(&xdrs), xdr_getpos(&xdrs), reply, replySize); DynXdr_Destroy(&xdrs, TRUE); return ret; } /* *----------------------------------------------------------------------------- * * VMGuestLib_AtomicUpdateCookie -- * * Atomically update a cookie on the host. * * Results: * TRUE on success, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool VMGuestLib_AtomicUpdateCookie(const char *src, // IN const char *dst, // IN char **reply, // OUT size_t *replySize) // OUT { GuestLibIoctlParam param; ASSERT(src != NULL); ASSERT(dst != NULL); param.d = GUESTLIB_IOCTL_ATOMIC_UPDATE_COOKIE; param.GuestLibIoctlParam_u.atomicUpdateCookie.src = (char *)src; param.GuestLibIoctlParam_u.atomicUpdateCookie.dst = (char *)dst; return VMGuestLibIoctl(¶m, reply, replySize); } open-vm-tools-9.4.0-1280544/libguestlib/vmGuestLibInt.h0000644765153500003110000001264512220061556020661 0ustar dtormts/********************************************************* * Copyright (C) 2003 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _VM_GUEST_LIB_INT_H_ #define _VM_GUEST_LIB_INT_H_ #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #include "vmware.h" #include "vmGuestLib.h" /* * Backdoor string for retrieving guestlib info */ #define VMGUESTLIB_BACKDOOR_COMMAND_STRING "guestlib.info.get" /* * Current version of the VMGuestLibData structure */ #define VMGUESTLIB_DATA_VERSION 3 /* Stat types with a valid bit per stat. */ typedef struct { Bool valid; // Indicates whether this stat is valid on this system uint32 value; // Actual stat value. } StatUint32; /* * This structure comes from the backdoor and hence uses 32-bit * natural packing, which is 4-byte aligned. When moved over to * 64-bit VMs it becomes 8-byte aligned. To avoid this varying * padding, adding the 3-byte "padding" field and using pack(1) * to make sure we always have 4-byte alignment. */ typedef #include "vmware_pack_begin.h" struct { Bool valid; // Indicates whether this stat is valid on this system uint8 padding[3]; uint64 value; // Actual stat value. } #include "vmware_pack_end.h" StatUint64; /* * This is version 1 of the data structure GuestLib uses to obtain * stats over the backdoor from the VMX/VMKernel. It is deprecated. */ #if 0 typedef #include "vmware_pack_begin.h" struct VMGuestLibDataV1 { uint32 version; VMSessionId sessionId; /* Statistics */ /* CPU statistics */ uint32 cpuReservationMHz; uint32 cpuLimitMHz; uint32 cpuShares; uint64 cpuUsedMs; /* Host processor speed */ uint32 hostMHz; /* Memory statistics */ uint32 memReservationMB; uint32 memLimitMB; uint32 memShares; uint32 memMappedMB; uint32 memActiveMB; uint32 memOverheadMB; uint32 memBalloonedMB; uint32 memSwappedMB; /* Elapsed time */ uint64 elapsedMs; /* * Resource pool path. See groupPathName in Sched_GuestLibInfo, * defined in VMKernel's sched_ext.h. This needs to be at least * as big as SCHED_GROUP_PATHNAME_LEN. */ char resourcePoolPath[512]; } #include "vmware_pack_end.h" VMGuestLibDataV1; #endif // #if 0 typedef #include "vmware_pack_begin.h" struct { uint32 version; VMSessionId sessionId; } #include "vmware_pack_end.h" VMGuestLibHeader; /* * This is version 2 of the data structure GuestLib uses to obtain * stats over the backdoor from the VMX/VMKernel. It is not * exposed to users of the GuestLib API. */ typedef #include "vmware_pack_begin.h" struct VMGuestLibDataV2 { /* Header */ VMGuestLibHeader hdr; /* Statistics */ /* CPU statistics */ StatUint32 cpuReservationMHz; StatUint32 cpuLimitMHz; StatUint32 cpuShares; StatUint64 cpuUsedMs; /* Host processor speed */ StatUint32 hostMHz; /* Memory statistics */ StatUint32 memReservationMB; StatUint32 memLimitMB; StatUint32 memShares; StatUint32 memMappedMB; StatUint32 memActiveMB; StatUint32 memOverheadMB; StatUint32 memBalloonedMB; StatUint32 memSwappedMB; StatUint32 memSharedMB; StatUint32 memSharedSavedMB; StatUint32 memUsedMB; /* Elapsed time */ StatUint64 elapsedMs; /* * Resource pool path. See groupPathName in Sched_GuestLibInfo, * defined in VMKernel's sched_ext.h. This needs to be at least * as big as SCHED_GROUP_PATHNAME_LEN. */ struct { Bool valid; char value[512]; } resourcePoolPath; } #include "vmware_pack_end.h" VMGuestLibDataV2; /* * This is version 3 of the data structure GuestLib uses to obtain stats over * the backdoor from the VMX/VMKernel. It is not exposed to users of the * GuestLib API. This struct is sent on the wire. * * The buffer contains a variable length array of statistics, that are * marshalled from XDR spec generated code. Each data field has a discriminant * preceding the payload, which enables the client to detect fields that it * doesn't recognize. * * V3 is a superset of V2 and a major protocol change. Any extensions to the * wire protocol that just add statistics, can do so within V3. Just update the * .x file to add a new discriminant for the union, at the end of the list. V3 * clients may assume that the fields are ordered on the wire in increasing order * of the discriminant list. So, a client may stop processing at the first * unrecognized field. V3 payload contains all available guestlib statistics * supported by the host. */ typedef #include "vmware_pack_begin.h" struct VMGuestLibDataV3 { /* Header */ VMGuestLibHeader hdr; /* Statistics */ uint32 dataSize; char data[0]; } #include "vmware_pack_end.h" VMGuestLibDataV3; #endif /* _VM_GUEST_LIB_INT_H_ */ open-vm-tools-9.4.0-1280544/libguestlib/COPYING0000644765153500003110000006347112220061556017012 0ustar dtormts GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! open-vm-tools-9.4.0-1280544/libguestlib/Makefile.am0000644765153500003110000000467612220061556020015 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ lib_LTLIBRARIES = libguestlib.la AM_CFLAGS = AM_CFLAGS += -I$(top_builddir)/include libguestlib_la_LIBADD = libguestlib_la_LIBADD += @VMTOOLS_LIBS@ libguestlib_la_SOURCES = libguestlib_la_SOURCES += guestlibV3_xdr.c libguestlib_la_SOURCES += guestlibIoctl_xdr.c libguestlib_la_SOURCES += vmGuestLib.c libguestlib_la_LDFLAGS = # We require GCC, so we're fine passing compiler-specific flags. # Needed for OS's that don't link shared libraries against libc by default, e.g. FreeBSD libguestlib_la_LDFLAGS += -Wl,-lc libguestlib_includedir = $(includedir)/vmGuestLib libguestlib_include_HEADERS = libguestlib_include_HEADERS += $(top_srcdir)/lib/include/includeCheck.h libguestlib_include_HEADERS += $(top_srcdir)/lib/include/vmGuestLib.h libguestlib_include_HEADERS += $(top_srcdir)/lib/include/vmSessionId.h libguestlib_include_HEADERS += $(top_srcdir)/lib/include/vm_basic_types.h BUILT_SOURCES = BUILT_SOURCES += guestlibV3.h BUILT_SOURCES += guestlibV3_xdr.c BUILT_SOURCES += guestlibIoctl.h BUILT_SOURCES += guestlibIoctl_xdr.c CLEANFILES = CLEANFILES += $(BUILT_SOURCES) CFLAGS += -Wno-unused EXTRA_DIST = vmguestlib.pc.in pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = vmguestlib.pc $(pkgconfig_DATA): $(top_builddir)/config.status guestlibIoctl.h: guestlibIoctl.x @RPCGEN_WRAPPER@ libguestlib/guestlibIoctl.x $@ guestlibIoctl_xdr.c: guestlibIoctl.x guestlibIoctl.h @RPCGEN_WRAPPER@ libguestlib/guestlibIoctl.x $@ guestlibV3.h: guestlibV3.x @RPCGEN_WRAPPER@ libguestlib/guestlibV3.x $@ guestlibV3_xdr.c: guestlibV3.x guestlibV3.h @RPCGEN_WRAPPER@ libguestlib/guestlibV3.x $@ open-vm-tools-9.4.0-1280544/libguestlib/vmguestlib.pc.in0000644765153500003110000000050412220061556021055 0ustar dtormts# VMware GuestLib pkgconfig data. prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: VMware GuestLib Description: Library for retrieving information from VMware hosts. Version: @VERSION@ Libs: -L${libdir} -lguestlib Cflags: -I${includedir}/vmGuestLib open-vm-tools-9.4.0-1280544/libguestlib/guestlibIoctl.x0000644765153500003110000000365212220061556020754 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * guestlibIoctl.x -- * * Data structures that encode the information exchanged over guestlib * client ioctl and VMX . */ /* The GuestRpc command string. */ const VMGUESTLIB_IOCTL_COMMAND_STRING = "guestlib.ioctl"; const GUESTLIB_IOCTL_ATOMIC_UPDATE_COOKIE_LENGTH = 256; enum GuestLibAtomicUpdateStatus { GUESTLIB_ATOMIC_UPDATE_OK_SUCCESS = 0, GUESTLIB_ATOMIC_UPDATE_OK_FAIL = 1, GUESTLIB_ATOMIC_UPDATE_EBADPARAM = 2, GUESTLIB_ATOMIC_UPDATE_EUNAVAILABLE = 3, GUESTLIB_ATOMIC_UPDATE_EUNKNOWN = 4 }; /* All supported ioctl ids */ enum GuestLibIoctlId { GUESTLIB_IOCTL_ATOMIC_UPDATE_COOKIE = 1, GUESTLIB_IOCTL_MAX = 2 }; /* Parameters for AtomicUpdateCookie ioctl. */ struct GuestLibIoctlAtomicUpdateCookie { string src; string dst; }; /* Struct for all supported ioctls */ union GuestLibIoctlParam switch (GuestLibIoctlId d) { case GUESTLIB_IOCTL_ATOMIC_UPDATE_COOKIE: struct GuestLibIoctlAtomicUpdateCookie atomicUpdateCookie; }; open-vm-tools-9.4.0-1280544/libguestlib/guestlibV3.x0000644765153500003110000001442512220061556020172 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * guestlibV3.x -- * * Data structures that encode the information sent from VMX to Guest upon a * Guestlib protocol v3 request. */ struct GuestLibV3StatUint32 { Bool valid; uint32 value; }; struct GuestLibV3StatUint64 { Bool valid; uint64 value; }; const GUESTLIBV3_STRING_SIZE = 512; struct GuestLibV3String { Bool valid; string value; }; struct GuestLibV3ByteArray { Bool valid; opaque value<>; }; typedef uint32 GuestLibV3StatCount; enum GuestLibV3TypeIds { /* V2 statistics */ GUESTLIB_TYPE_RESERVED = 0, GUESTLIB_CPU_RESERVATION_MHZ = 1, GUESTLIB_CPU_LIMIT_MHZ = 2, GUESTLIB_CPU_SHARES = 3, GUESTLIB_CPU_USED_MS = 4, GUESTLIB_HOST_MHZ = 5, GUESTLIB_MEM_RESERVATION_MB = 6, GUESTLIB_MEM_LIMIT_MB = 7, GUESTLIB_MEM_SHARES = 8, GUESTLIB_MEM_MAPPED_MB = 9, GUESTLIB_MEM_ACTIVE_MB = 10, GUESTLIB_MEM_OVERHEAD_MB = 11, GUESTLIB_MEM_BALLOONED_MB = 12, GUESTLIB_MEM_SWAPPED_MB = 13, GUESTLIB_MEM_SHARED_MB = 14, GUESTLIB_MEM_SHARED_SAVED_MB = 15, GUESTLIB_MEM_USED_MB = 16, GUESTLIB_ELAPSED_MS = 17, GUESTLIB_RESOURCE_POOL_PATH = 18, GUESTLIB_CPU_STOLEN_MS = 19, GUESTLIB_MEM_TARGET_SIZE_MB = 20, /* Host specific counters. */ GUESTLIB_HOST_CPU_NUM_CORES = 21, GUESTLIB_HOST_CPU_USED_MS = 22, GUESTLIB_HOST_MEM_SWAPPED_MB = 23, GUESTLIB_HOST_MEM_SHARED_MB = 24, GUESTLIB_HOST_MEM_USED_MB = 25, GUESTLIB_HOST_MEM_PHYS_MB = 26, GUESTLIB_HOST_MEM_PHYS_FREE_MB = 27, GUESTLIB_HOST_MEM_KERN_OVHD_MB = 28, GUESTLIB_HOST_MEM_MAPPED_MB = 29, GUESTLIB_HOST_MEM_UNMAPPED_MB = 30, /* Counters added in ESX5.0 */ GUESTLIB_MEM_ZIPPED_MB = 31, GUESTLIB_MEM_ZIPSAVED_MB = 32, GUESTLIB_MEM_LLSWAPPED_MB = 33, GUESTLIB_MEM_SWAP_TARGET_MB = 34, GUESTLIB_MEM_BALLOON_TARGET_MB = 35, GUESTLIB_MEM_BALLOON_MAX_MB = 36, GUESTLIB_RESOURCE_POOL_PATH_LONG = 37, /*------ Add any new statistics above this line. ------- */ /*------ Bump this when adding to this list. -------*/ GUESTLIB_MAX_STATISTIC_ID = 38 }; union GuestLibV3Stat switch (GuestLibV3TypeIds d) { case GUESTLIB_CPU_RESERVATION_MHZ: struct GuestLibV3StatUint32 cpuReservationMHz; case GUESTLIB_CPU_LIMIT_MHZ: struct GuestLibV3StatUint32 cpuLimitMHz; case GUESTLIB_CPU_SHARES: struct GuestLibV3StatUint32 cpuShares; case GUESTLIB_CPU_USED_MS: struct GuestLibV3StatUint64 cpuUsedMs; case GUESTLIB_HOST_MHZ: struct GuestLibV3StatUint32 hostMHz; case GUESTLIB_MEM_RESERVATION_MB: struct GuestLibV3StatUint32 memReservationMB; case GUESTLIB_MEM_LIMIT_MB: struct GuestLibV3StatUint32 memLimitMB; case GUESTLIB_MEM_SHARES: struct GuestLibV3StatUint32 memShares; case GUESTLIB_MEM_MAPPED_MB: struct GuestLibV3StatUint32 memMappedMB; case GUESTLIB_MEM_ACTIVE_MB: struct GuestLibV3StatUint32 memActiveMB; case GUESTLIB_MEM_OVERHEAD_MB: struct GuestLibV3StatUint32 memOverheadMB; case GUESTLIB_MEM_BALLOONED_MB: struct GuestLibV3StatUint32 memBalloonedMB; case GUESTLIB_MEM_SWAPPED_MB: struct GuestLibV3StatUint32 memSwappedMB; case GUESTLIB_MEM_SHARED_MB: struct GuestLibV3StatUint32 memSharedMB; case GUESTLIB_MEM_SHARED_SAVED_MB: struct GuestLibV3StatUint32 memSharedSavedMB; case GUESTLIB_MEM_USED_MB: struct GuestLibV3StatUint32 memUsedMB; case GUESTLIB_ELAPSED_MS: struct GuestLibV3StatUint64 elapsedMs; case GUESTLIB_RESOURCE_POOL_PATH: struct GuestLibV3String resourcePoolPath; case GUESTLIB_CPU_STOLEN_MS: struct GuestLibV3StatUint64 cpuStolenMs; case GUESTLIB_MEM_TARGET_SIZE_MB: struct GuestLibV3StatUint64 memTargetSizeMB; case GUESTLIB_HOST_CPU_NUM_CORES: struct GuestLibV3StatUint32 hostCpuNumCores; case GUESTLIB_HOST_CPU_USED_MS: struct GuestLibV3StatUint64 hostCpuUsedMs; case GUESTLIB_HOST_MEM_SWAPPED_MB: struct GuestLibV3StatUint64 hostMemSwappedMB; case GUESTLIB_HOST_MEM_SHARED_MB: struct GuestLibV3StatUint64 hostMemSharedMB; case GUESTLIB_HOST_MEM_USED_MB: struct GuestLibV3StatUint64 hostMemUsedMB; case GUESTLIB_HOST_MEM_PHYS_MB: struct GuestLibV3StatUint64 hostMemPhysMB; case GUESTLIB_HOST_MEM_PHYS_FREE_MB: struct GuestLibV3StatUint64 hostMemPhysFreeMB; case GUESTLIB_HOST_MEM_KERN_OVHD_MB: struct GuestLibV3StatUint64 hostMemKernOvhdMB; case GUESTLIB_HOST_MEM_MAPPED_MB: struct GuestLibV3StatUint64 hostMemMappedMB; case GUESTLIB_HOST_MEM_UNMAPPED_MB: struct GuestLibV3StatUint64 hostMemUnmappedMB; case GUESTLIB_MEM_ZIPPED_MB: struct GuestLibV3StatUint32 memZippedMB; case GUESTLIB_MEM_ZIPSAVED_MB: struct GuestLibV3StatUint32 memZipSavedMB; case GUESTLIB_MEM_LLSWAPPED_MB: struct GuestLibV3StatUint32 memLLSwappedMB; case GUESTLIB_MEM_SWAP_TARGET_MB: struct GuestLibV3StatUint32 memSwapTargetMB; case GUESTLIB_MEM_BALLOON_TARGET_MB: struct GuestLibV3StatUint32 memBalloonTargetMB; case GUESTLIB_MEM_BALLOON_MAX_MB: struct GuestLibV3StatUint32 memBalloonMaxMB; case GUESTLIB_RESOURCE_POOL_PATH_LONG: struct GuestLibV3ByteArray resourcePoolPathLong; }; open-vm-tools-9.4.0-1280544/libguestlib/Makefile.in0000644765153500003110000006065012220061624020014 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = libguestlib DIST_COMMON = $(libguestlib_include_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/vmguestlib.pc.in \ $(top_srcdir)/config/depcomp COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = vmguestlib.pc CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \ "$(DESTDIR)$(libguestlib_includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libguestlib_la_DEPENDENCIES = am_libguestlib_la_OBJECTS = guestlibV3_xdr.lo guestlibIoctl_xdr.lo \ vmGuestLib.lo libguestlib_la_OBJECTS = $(am_libguestlib_la_OBJECTS) libguestlib_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libguestlib_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libguestlib_la_SOURCES) DIST_SOURCES = $(libguestlib_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(pkgconfig_DATA) HEADERS = $(libguestlib_include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ -Wno-unused COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ lib_LTLIBRARIES = libguestlib.la AM_CFLAGS = -I$(top_builddir)/include libguestlib_la_LIBADD = @VMTOOLS_LIBS@ libguestlib_la_SOURCES = guestlibV3_xdr.c guestlibIoctl_xdr.c \ vmGuestLib.c # We require GCC, so we're fine passing compiler-specific flags. # Needed for OS's that don't link shared libraries against libc by default, e.g. FreeBSD libguestlib_la_LDFLAGS = -Wl,-lc libguestlib_includedir = $(includedir)/vmGuestLib libguestlib_include_HEADERS = \ $(top_srcdir)/lib/include/includeCheck.h \ $(top_srcdir)/lib/include/vmGuestLib.h \ $(top_srcdir)/lib/include/vmSessionId.h \ $(top_srcdir)/lib/include/vm_basic_types.h BUILT_SOURCES = guestlibV3.h guestlibV3_xdr.c guestlibIoctl.h \ guestlibIoctl_xdr.c CLEANFILES = $(BUILT_SOURCES) EXTRA_DIST = vmguestlib.pc.in pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = vmguestlib.pc all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libguestlib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu libguestlib/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): vmguestlib.pc: $(top_builddir)/config.status $(srcdir)/vmguestlib.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libguestlib.la: $(libguestlib_la_OBJECTS) $(libguestlib_la_DEPENDENCIES) $(EXTRA_libguestlib_la_DEPENDENCIES) $(libguestlib_la_LINK) -rpath $(libdir) $(libguestlib_la_OBJECTS) $(libguestlib_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/guestlibIoctl_xdr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/guestlibV3_xdr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmGuestLib.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) install-libguestlib_includeHEADERS: $(libguestlib_include_HEADERS) @$(NORMAL_INSTALL) @list='$(libguestlib_include_HEADERS)'; test -n "$(libguestlib_includedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(libguestlib_includedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libguestlib_includedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libguestlib_includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(libguestlib_includedir)" || exit $$?; \ done uninstall-libguestlib_includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(libguestlib_include_HEADERS)'; test -n "$(libguestlib_includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(libguestlib_includedir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(libguestlib_includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-libguestlib_includeHEADERS \ install-pkgconfigDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES \ uninstall-libguestlib_includeHEADERS uninstall-pkgconfigDATA .MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool cscopelist ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am \ install-libLTLIBRARIES install-libguestlib_includeHEADERS \ install-man install-pdf install-pdf-am install-pkgconfigDATA \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-libLTLIBRARIES \ uninstall-libguestlib_includeHEADERS uninstall-pkgconfigDATA $(pkgconfig_DATA): $(top_builddir)/config.status guestlibIoctl.h: guestlibIoctl.x @RPCGEN_WRAPPER@ libguestlib/guestlibIoctl.x $@ guestlibIoctl_xdr.c: guestlibIoctl.x guestlibIoctl.h @RPCGEN_WRAPPER@ libguestlib/guestlibIoctl.x $@ guestlibV3.h: guestlibV3.x @RPCGEN_WRAPPER@ libguestlib/guestlibV3.x $@ guestlibV3_xdr.c: guestlibV3.x guestlibV3.h @RPCGEN_WRAPPER@ libguestlib/guestlibV3.x $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/vmware-user-suid-wrapper/0000755765153500003110000000000012220061626020332 5ustar dtormtsopen-vm-tools-9.4.0-1280544/vmware-user-suid-wrapper/wrapper.h0000644765153500003110000000462012220061556022167 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * wrapper.h -- * * Platform independent definitions for the VMware User Agent setuid * wrapper. */ #ifndef _WRAPPER_H_ #define _WRAPPER_H_ #include #include #include "vm_basic_types.h" #include "vmblock.h" #define progname "vmware-user" #define Error(fmt, args...) fprintf(stderr, "%s: " fmt, progname, ##args); /* * XXX Document official VMware Tools releases vs. Open VM Tools and the * use of the locations database in the former vs. compile-time pathing * in the latter. */ #ifdef USES_LOCATIONS_DB # define LOCATIONS_PATH "/etc/vmware-tools/locations" /* * Locations DB query selector. Values in this enum are used as array * indexes, so any updates to this enum must follow updating * main.c::queryMappings. */ typedef enum { QUERY_LIBDIR = 0, /* Ask for "LIBDIR" */ QUERY_BINDIR, /* Ask for "BINDIR" */ QUERY_SBINDIR, /* Ask for "SBINDIR" */ QUERY_MAX /* Upper limit -- Insert other queries above only. */ } Selector; #else # ifndef VMTOOLSD_PATH # error This program requires either USES_LOCATIONS_DB or VMTOOLSD_PATH. # endif // ifndef VMTOOLSD_PATH #endif // ifdef USES_LOCATIONS_DB /* * Global functions */ extern Bool CompatExec(const char *, char * const [], char * const []); extern Bool BuildExecPath(char *, size_t); /* See above re: USES_LOCATIONS_DB. */ #ifdef USES_LOCATIONS_DB extern Bool QueryLocationsDB(const char *, Selector, char *, size_t); #endif // ifdef USES_LOCATIONS_DB #endif // ifndef _WRAPPER_H_ open-vm-tools-9.4.0-1280544/vmware-user-suid-wrapper/COPYING0000644765153500003110000006347112220061556021402 0ustar dtormts GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! open-vm-tools-9.4.0-1280544/vmware-user-suid-wrapper/Makefile.am0000644765153500003110000000301512220061556022367 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ bin_PROGRAMS = vmware-user-suid-wrapper AM_CPPFLAGS = AM_CPPFLAGS += -DVMTOOLSD_PATH=\"$(bindir)/vmtoolsd\" vmware_user_suid_wrapper_SOURCES = vmware_user_suid_wrapper_SOURCES += main.c vmware_user_suid_wrapper_SOURCES += wrapper-@TARGET_OS@.c vmware_user_suid_wrapper_LDADD = vmware_user_suid_wrapper_LDADD += ../lib/vmSignal/libVmSignal.la desktopfile = vmware-user.desktop desktopfilesrc = $(top_srcdir)/vmware-user-suid-wrapper/vmware-user.desktop.in autostartdir = $(sysconfdir)/xdg/autostart autostart_DATA = $(desktopfile) CLEANFILES = $(desktopfile) $(desktopfile): $(desktopfilesrc) sed 's,_bindir_,$(bindir),' $(desktopfilesrc) > $(desktopfile) open-vm-tools-9.4.0-1280544/vmware-user-suid-wrapper/main.c0000644765153500003110000001703612220061556021433 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * main.c -- * * This program is run as root to prepare the system for vmware-user. It * unmounts the vmblock file system, unloads the vmblock module, then * reloads the module, mounts the file system, and opens a file descriptor * that vmware-user can use to add and remove blocks. This must all * happen as root since we cannot allow any random process to add and * remove blocks in the blocking file system. */ #if !defined(sun) && !defined(__FreeBSD__) && !defined(linux) # error This program is not supported on your platform. #endif #include #include #include #include #include #include #include #include #include #include "vmware.h" #include "vmblock.h" #include "vmsignal.h" #include "wrapper.h" #include "wrapper_version.h" #include "embed_version.h" VM_EMBED_VERSION(WRAPPER_VERSION_STRING); /* * Local functions (prototypes) */ static void MaskSignals(void); static Bool StartVMwareUser(char *const envp[]); /* *---------------------------------------------------------------------------- * * main -- * * On platforms where this wrapper manages the vmblock module: * Unmounts vmblock and unloads the module, then reloads the module, * and remounts the file system, then starts vmware-user as described * below. * * This program is the only point at which vmblock is stopped or * started. This means we must always unload the module to ensure that * we are using the newest installed version (since an upgrade could * have occurred since the last time this program ran). * * On all platforms: * Acquires the vmblock control file descriptor, drops privileges, then * starts vmware-user. * * Results: * EXIT_SUCCESS on success and EXIT_FAILURE on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int main(int argc, char *argv[], char *envp[]) { MaskSignals(); if (!StartVMwareUser(envp)) { Error("failed to start vmware-user\n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } /* * Local functions (definitions) */ /* *----------------------------------------------------------------------------- * * MaskSignals -- * * Sets SIG_IGN as the handler for SIGUSR1 and SIGUSR2 which may arrive * prematurely from our services script. See bug 542135. * * Results: * Returns if applicable signals are blocked. * Exits with EXIT_FAILURE otherwise. * * Side effects: * SIG_IGN disposition persists across execve(). These signals will * remain masked until vmware-user defines its own handlers. * *----------------------------------------------------------------------------- */ static void MaskSignals(void) { int const signals[] = { SIGUSR1, SIGUSR2 }; struct sigaction olds[ARRAYSIZE(signals)]; if (Signal_SetGroupHandler(signals, olds, ARRAYSIZE(signals), SIG_IGN) == 0) { /* Signal_SetGroupHandler will write error message to stderr. */ exit(EXIT_FAILURE); } } /* *---------------------------------------------------------------------------- * * StartVMwareUser -- * * Obtains the library directory from the Tools locations database, then * opens a file descriptor (while still root) to add and remove blocks, * drops privilege to the real uid of this process, and finally starts * vmware-user. * * Results: * Parent: TRUE on success, FALSE on failure. * Child: FALSE on failure, no return on success. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static Bool StartVMwareUser(char *const envp[]) { pid_t pid; uid_t uid; gid_t gid; int fd = -1; int ret; char path[MAXPATHLEN]; char *argv[6]; size_t idx = 0; if (!BuildExecPath(path, sizeof path)) { return FALSE; } /* * Now create a child process, obtain a file descriptor as root, downgrade * privilege, and run vmware-user. */ pid = fork(); if (pid == -1) { Error("fork failed: %s\n", strerror(errno)); return FALSE; } else if (pid != 0) { /* Parent */ return TRUE; } /* Child */ /* * We know the file system is mounted and want to keep this suid * root wrapper as small as possible, so here we directly open(2) the * "device" instead of calling DnD_InitializeBlocking() and bringing along * a whole host of libs. */ fd = open(VMBLOCK_FUSE_DEVICE, VMBLOCK_FUSE_DEVICE_MODE); if (fd < 0) { fd = open(VMBLOCK_DEVICE, VMBLOCK_DEVICE_MODE); } uid = getuid(); gid = getgid(); if ((setreuid(uid, uid) != 0) || (setregid(gid, gid) != 0)) { Error("could not drop privileges: %s\n", strerror(errno)); if (fd != -1) { close(fd); } return FALSE; } /* * Since vmware-user provides features that don't depend on vmblock, we * invoke vmware-user even if we couldn't obtain a file descriptor or we * can't parse the descriptor to pass as an argument. We set up the * argument vector accordingly. */ argv[idx++] = path; argv[idx++] = "-n"; argv[idx++] = "vmusr"; if (fd < 0) { Error("could not open %s\n", VMBLOCK_DEVICE); } else { char fdStr[8]; ret = snprintf(fdStr, sizeof fdStr, "%d", fd); if (ret == 0 || ret >= sizeof fdStr) { Error("could not parse file descriptor (%d)\n", fd); } else { argv[idx++] = "--blockFd"; argv[idx++] = fdStr; } } argv[idx++] = NULL; CompatExec(path, argv, envp); /* * CompatExec, if successful, doesn't return. I.e., we're here only * if CompatExec fails. */ Error("could not execute %s: %s\n", path, strerror(errno)); _exit(EXIT_FAILURE); } #ifndef USES_LOCATIONS_DB /* *----------------------------------------------------------------------------- * * BuildExecPath -- * * Writes the path to vmware-user to execPath. This version, as opposed * to the versions in $platform/wrapper.c, is only used when the locations * database isn't used. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool BuildExecPath(char *execPath, // OUT: Buffer to store executable's path size_t execPathSize) // IN : size of execPath buffer { if (execPathSize < sizeof VMTOOLSD_PATH) { return FALSE; } strcpy(execPath, VMTOOLSD_PATH); return TRUE; } #endif // ifndef USES_LOCATIONS_DB open-vm-tools-9.4.0-1280544/vmware-user-suid-wrapper/wrapper-solaris.c0000644765153500003110000000556112220061556023641 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * wrapper.c -- * * Platform dependent code for the VMware User Agent setuid wrapper. */ #include #include #include #include #include #include "wrapper.h" /* * Global functions */ #ifdef USES_LOCATIONS_DB /* *----------------------------------------------------------------------------- * * BuildExecPath -- * * Mount the VMBlock file system. * * Results: * TRUE on success, FALSE otherwise * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool BuildExecPath(char *execPath, // OUT: Path to executable for isaexec() size_t execPathSize) // IN : size of execPath buffer { /* * The locations database is the only path that's fixed, and it contains the * paths to all the other paths selected during Tools configuration. The * locations database file is only writable by root, so we can trust it. */ if (!QueryLocationsDB(LOCATIONS_PATH, QUERY_LIBDIR, execPath, execPathSize)) { Error("could not obtain LIBDIR\n"); return FALSE; } /* * The wrapper script now emulates the work done by the isaexec command hence * we will simply call execve(2) below and allow the wrapper to do the rest. */ if (strlcat(execPath, "/bin/vmware-user-wrapper", execPathSize) >= execPathSize) { Error("could not construct program filename\n"); return FALSE; } return TRUE; } #endif // ifdef USES_LOCATIONS_DB /* *---------------------------------------------------------------------------- * * CompatExec -- * * Simple platform-dependent isaexec() wrapper. * * Results: * False. * * Side effects: * Ideally, this function should not return. * *---------------------------------------------------------------------------- */ Bool CompatExec(const char *path, char * const argv[], char * const envp[]) { execve(path, argv, envp); return FALSE; } open-vm-tools-9.4.0-1280544/vmware-user-suid-wrapper/wrapper-linux.c0000644765153500003110000000767212220061556023331 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * wrapper.c -- * * Platform specific code for the VMware User Agent setuid wrapper. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "vmware.h" #include "wrapper.h" /* * Global functions */ #ifdef USES_LOCATIONS_DB /* *----------------------------------------------------------------------------- * * BuildExecPath -- * * Determine & return path of vmware-user for use by execve(2). * * Results: * TRUE on success, FALSE otherwise * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool BuildExecPath(char *execPath, // OUT: Buffer to store executable's path size_t execPathSize) // IN : size of execPath buffer { char tmpPath[MAXPATHLEN]; int execLen; /* * The locations database is the only path that's fixed, and it contains the * paths to all the other paths selected during Tools configuration. The * locations database file is only writable by root, so we can trust it. */ if (!QueryLocationsDB(LOCATIONS_PATH, QUERY_SBINDIR, tmpPath, sizeof tmpPath)) { Error("could not obtain SBINDIR\n"); return FALSE; } if (strlen(tmpPath) + strlen("/vmtoolsd") + 1 > sizeof tmpPath) { Error("could not construct program filename\n"); return FALSE; } strcat(tmpPath, "/vmtoolsd"); /* * From readlink(2), "The readlink() system call does not append a NUL * character to buf." (NB: This breaks if user ever replaces the symlink * with the target.) */ if ((execLen = readlink(tmpPath, execPath, execPathSize - 1)) == -1) { Error("could not resolve symlink: %s\n", strerror(errno)); return FALSE; } execPath[execLen] = '\0'; /* * Now make sure that the target is actually part of our "trusted" * directory. (Check that execPath has LIBDIR as a prefix and does * not contain "..".) */ if (!QueryLocationsDB(LOCATIONS_PATH, QUERY_LIBDIR, tmpPath, sizeof tmpPath)) { Error("could not obtain LIBDIR\n"); return FALSE; } if ((strncmp(execPath, tmpPath, strlen(tmpPath)) != 0) || (strstr(execPath, "..") != NULL)) { Error("vmware-user path untrusted\n"); return FALSE; } return TRUE; } #endif // ifdef USES_LOCATIONS_DB /* *---------------------------------------------------------------------------- * * CompatExec -- * * Simple platform-dependent execve() wrapper. * * Results: * False. * * Side effects: * This function may not return. * *---------------------------------------------------------------------------- */ Bool CompatExec(const char *path, // IN: path to executable char * const argv[], // IN: argument vector (see execve) char * const envp[]) // IN: environment vector (see execve) { execve(path, argv, envp); return FALSE; } open-vm-tools-9.4.0-1280544/vmware-user-suid-wrapper/wrapper_version.h0000644765153500003110000000301512220061556023731 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * wrapper_version.h -- * * Version definitions for the vmware-user SUID wrapper. */ #ifndef _WRAPPER_VERSION_H_ #define _WRAPPER_VERSION_H_ /* * This component's version is coupled with Tools versioning. The effect * is that the version increments with each build, and with each Tools * version bump. If and when it becomes necessary to version the component * manually, make sure that the version is bumped any time the component or * its dependencies are changed. */ #include "vm_tools_version.h" #define WRAPPER_VERSION_COMMAS TOOLS_VERSION_EXT_CURRENT_CSV #define WRAPPER_VERSION_STRING TOOLS_VERSION_EXT_CURRENT_STR #endif /* _WRAPPER_VERSION_H_ */ open-vm-tools-9.4.0-1280544/vmware-user-suid-wrapper/wrapper-freebsd.c0000644765153500003110000000723312220061556023575 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * wrapper.c -- * * Platform specific code for the VMware User Agent setuid wrapper. */ #include #include #include #include #include #include "vmware.h" #include "wrapper.h" /* * Global functions */ #ifdef USES_LOCATIONS_DB /* *----------------------------------------------------------------------------- * * BuildExecPath -- * * Determine & return path of vmware-user for use by execve(2). * * Results: * TRUE on success, FALSE otherwise * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool BuildExecPath(char *execPath, // OUT: Buffer to store executable's path size_t execPathSize) // IN : size of execPath buffer { char tmpPath[MAXPATHLEN]; int execLen; /* * The locations database is the only path that's fixed, and it contains the * paths to all the other paths selected during Tools configuration. The * locations database file is only writable by root, so we can trust it. */ if (!QueryLocationsDB(LOCATIONS_PATH, QUERY_BINDIR, tmpPath, sizeof tmpPath)) { Error("could not obtain BINDIR\n"); return FALSE; } if (strlcat(tmpPath, "/vmware-user-wrapper", sizeof tmpPath) >= sizeof tmpPath) { Error("could not construct program filename\n"); return FALSE; } /* * From readlink(2), "The readlink() system call does not append a NUL * character to buf." (NB: This breaks if user ever replaces the symlink * with the target.) */ if ((execLen = readlink(tmpPath, execPath, execPathSize - 1)) == -1) { Error("could not resolve symlink: %s\n", strerror(errno)); return FALSE; } execPath[execLen] = '\0'; /* * Now make sure that the target is actually part of our "trusted" * directory. (Check that execPath has LIBDIR as a prefix and does * not contain "..".) */ if (!QueryLocationsDB(LOCATIONS_PATH, QUERY_LIBDIR, tmpPath, sizeof tmpPath)) { Error("could not obtain LIBDIR\n"); return FALSE; } if ((strncmp(execPath, tmpPath, strlen(tmpPath)) != 0) || (strstr(execPath, "..") != NULL)) { Error("vmware-user path untrusted\n"); return FALSE; } return TRUE; } #endif // ifdef USES_LOCATIONS_DB /* *---------------------------------------------------------------------------- * * CompatExec -- * * Simple platform-dependent execve() wrapper. * * Results: * False. * * Side effects: * This function may not return. * *---------------------------------------------------------------------------- */ Bool CompatExec(const char *path, char * const argv[], char * const envp[]) { execve(path, argv, envp); return FALSE; } open-vm-tools-9.4.0-1280544/vmware-user-suid-wrapper/vmware-user.desktop.in0000644765153500003110000000033612220061556024613 0ustar dtormts[Desktop Entry] Type=Application Encoding=UTF-8 Exec=_bindir_/vmware-user-suid-wrapper Name=VMware User Agent # KDE bug 190522: KDE does not autostart items with NoDisplay=true... # NoDisplay=true X-KDE-autostart-phase=1 open-vm-tools-9.4.0-1280544/vmware-user-suid-wrapper/Makefile.in0000644765153500003110000005522512220061626022410 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = vmware-user-suid-wrapper$(EXEEXT) subdir = vmware-user-suid-wrapper DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(autostartdir)" PROGRAMS = $(bin_PROGRAMS) am_vmware_user_suid_wrapper_OBJECTS = main.$(OBJEXT) \ wrapper-@TARGET_OS@.$(OBJEXT) vmware_user_suid_wrapper_OBJECTS = \ $(am_vmware_user_suid_wrapper_OBJECTS) vmware_user_suid_wrapper_DEPENDENCIES = \ ../lib/vmSignal/libVmSignal.la DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(vmware_user_suid_wrapper_SOURCES) DIST_SOURCES = $(vmware_user_suid_wrapper_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } DATA = $(autostart_DATA) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -DVMTOOLSD_PATH=\"$(bindir)/vmtoolsd\" vmware_user_suid_wrapper_SOURCES = main.c wrapper-@TARGET_OS@.c vmware_user_suid_wrapper_LDADD = ../lib/vmSignal/libVmSignal.la desktopfile = vmware-user.desktop desktopfilesrc = $(top_srcdir)/vmware-user-suid-wrapper/vmware-user.desktop.in autostartdir = $(sysconfdir)/xdg/autostart autostart_DATA = $(desktopfile) CLEANFILES = $(desktopfile) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu vmware-user-suid-wrapper/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu vmware-user-suid-wrapper/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list vmware-user-suid-wrapper$(EXEEXT): $(vmware_user_suid_wrapper_OBJECTS) $(vmware_user_suid_wrapper_DEPENDENCIES) $(EXTRA_vmware_user_suid_wrapper_DEPENDENCIES) @rm -f vmware-user-suid-wrapper$(EXEEXT) $(LINK) $(vmware_user_suid_wrapper_OBJECTS) $(vmware_user_suid_wrapper_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrapper-@TARGET_OS@.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-autostartDATA: $(autostart_DATA) @$(NORMAL_INSTALL) @list='$(autostart_DATA)'; test -n "$(autostartdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(autostartdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(autostartdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(autostartdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(autostartdir)" || exit $$?; \ done uninstall-autostartDATA: @$(NORMAL_UNINSTALL) @list='$(autostart_DATA)'; test -n "$(autostartdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(autostartdir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(DATA) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(autostartdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-autostartDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-autostartDATA uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libtool cscopelist ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-autostartDATA install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-autostartDATA \ uninstall-binPROGRAMS $(desktopfile): $(desktopfilesrc) sed 's,_bindir_,$(bindir),' $(desktopfilesrc) > $(desktopfile) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/autom4te.cache/0000755765153500003110000000000012220061620016233 5ustar dtormtsopen-vm-tools-9.4.0-1280544/autom4te.cache/output.10000644765153500003110000300566312220061620017672 0ustar dtormts@%:@! /bin/sh @%:@ Guess values for system-dependent variables and create Makefiles. @%:@ Generated by GNU Autoconf 2.69 for open-vm-tools 9.4.0. @%:@ @%:@ Report bugs to . @%:@ @%:@ @%:@ 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 and $0: open-vm-tools-devel@lists.sourceforge.net about your $0: system, 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 @S|@? 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 "@S|@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 @S|@as_val. Take advantage of shells that can avoid forks. The arguments @%:@ must be portable across @S|@(()) 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 @S|@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=. LIB@&t@OBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='open-vm-tools' PACKAGE_TARNAME='open-vm-tools' PACKAGE_VERSION='9.4.0' PACKAGE_STRING='open-vm-tools 9.4.0' PACKAGE_BUGREPORT='open-vm-tools-devel@lists.sourceforge.net' PACKAGE_URL='' ac_unique_file="checkvm/checkvm.c" # 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_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIB@&t@OBJS VIX_LIBADD LIBVMTOOLS_LIBADD LIB_USER_CPPFLAGS LIB_IMPERSONATE_CPPFLAGS LIB_AUTH_CPPFLAGS RPCGEN_WRAPPER INSTVMSG SYSDIR VMUSR_PLUGIN_INSTALLDIR VMSVC_PLUGIN_INSTALLDIR COMMON_PLUGIN_INSTALLDIR TEST_PLUGIN_INSTALLDIR XDR_LIBS RPCGENFLAGS VMTOOLS_LIBS VMTOOLS_CPPFLAGS PLUGIN_LDFLAGS PLUGIN_CPPFLAGS PAM_PREFIX XCOMPOSITE_LIBS XSM_LIBS COMMON_XLIBS MODULES MODULES_DIR MODULES_OS LINUXINCLUDE KERNEL_RELEASE TARGET_OS TOOLS_VERSION HGFS_LIBS USE_PRINTF_WRAPPERS_FALSE USE_PRINTF_WRAPPERS_TRUE USE_SLASH_PROC_FALSE USE_SLASH_PROC_TRUE HAVE_PAM_FALSE HAVE_PAM_TRUE HAVE_GTKMM_FALSE HAVE_GTKMM_TRUE HAVE_GNU_LD_FALSE HAVE_GNU_LD_TRUE HAVE_FUSE_FALSE HAVE_FUSE_TRUE HAVE_DOXYGEN_FALSE HAVE_DOXYGEN_TRUE HAVE_DNET_FALSE HAVE_DNET_TRUE WITH_ROOT_PRIVILEGES_FALSE WITH_ROOT_PRIVILEGES_TRUE ENABLE_TESTS_FALSE ENABLE_TESTS_TRUE HAVE_XCOMPOSITE_FALSE HAVE_XCOMPOSITE_TRUE HAVE_XSM_FALSE HAVE_XSM_TRUE WITH_KERNEL_MODULES_FALSE WITH_KERNEL_MODULES_TRUE HAVE_ICU_FALSE HAVE_ICU_TRUE HAVE_X11_FALSE HAVE_X11_TRUE THIRTY_TWO_BIT_USERSPACE_FALSE THIRTY_TWO_BIT_USERSPACE_TRUE FREEBSD_CUSTOM_SYSDIR_FALSE FREEBSD_CUSTOM_SYSDIR_TRUE FREEBSD_FALSE FREEBSD_TRUE SOLARIS_FALSE SOLARIS_TRUE LINUX_FALSE LINUX_TRUE BUILD_HGFSMOUNTER_FALSE BUILD_HGFSMOUNTER_TRUE MSCGEN_DIR MSCGEN HAVE_DOT DOT have_doxygen RPCGEN ICU_LIBS ICU_CPPFLAGS have_cxx DNET_LIBS DNET_CPPFLAGS PROCPS_LIBS PROCPS_CPPFLAGS GTKMM_LIBS GTKMM_CPPFLAGS GTK_LIBS GTK_CPPFLAGS CUNIT_LIBS CUNIT_CPPFLAGS PAM_LIBS PAM_CPPFLAGS FUSE_LIBS FUSE_CPPFLAGS have_genmarshal GTHREAD_LIBS GTHREAD_CPPFLAGS GOBJECT_LIBS GOBJECT_CPPFLAGS GMODULE_LIBS GMODULE_CPPFLAGS GLIB2_LIBS GLIB2_CPPFLAGS ac_vmw_lib_cfg X_EXTRA_LIBS X_LIBS X_PRE_LIBS X_CFLAGS XMKMF HAVE_PKG_CONFIG CXXCPP OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR DLLTOOL OBJDUMP NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP LIBTOOL LN_S SED am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM host_os host_vendor host_cpu host build_os build_vendor build_cpu build 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='' ac_user_opts=' enable_option_checking with_root_privileges with_kernel_modules with_kernel_release with_linuxdir enable_multimon with_gtk2 with_gtkmm enable_docs enable_tests enable_dependency_tracking enable_shared enable_static with_pic enable_fast_install with_gnu_ld with_sysroot enable_libtool_lock with_x with_pam with_pam_prefix with_procps with_dnet with_icu ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP CXX CXXFLAGS CCC 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 open-vm-tools 9.4.0 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 @<:@@S|@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/open-vm-tools@:>@ --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names 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 open-vm-tools 9.4.0:";; 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] --disable-multimon disables multimon, enabled by default --disable-docs disables generation of API documentation; by default, docs are built if doxygen is available. --disable-tests disable compilation of test code. --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-shared@<:@=PKGS@:>@ build shared libraries @<:@default=yes@:>@ --enable-static@<:@=PKGS@:>@ build static libraries @<:@default=yes@:>@ --enable-fast-install@<:@=PKGS@:>@ optimize for fast installation @<:@default=yes@:>@ --disable-libtool-lock avoid locking (might break parallel builds) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --without-root-privileges does not perform any operations that require root privileges --without-kernel-modules does not compile or install the kernel modules --with-kernel-release specifies the kernel release you want to build against --with-linuxdir specifies the Linux directory you want to use --without-gtk2 compiles without Gtk 2.0 --without-gtkmm compiles without Gtkmm, sigc++, and related libs --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-x use the X Window System --without-pam compiles without PAM support. --with-pam-prefix specifies where pam files go. Default is @S|@(sysconfdir) --without-procps compiles without libproc (disables support for meminfo) --without-dnet compiles without libdnet (disables support for nicinfo) --without-icu disables support for ICU 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 CPP C preprocessor CXX C++ compiler command CXXFLAGS C++ compiler flags 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 . _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 open-vm-tools configure 9.4.0 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.@S|@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_c_try_cpp LINENO @%:@ ---------------------- @%:@ Try to preprocess conftest.@S|@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_cxx_try_compile LINENO @%:@ ---------------------------- @%:@ Try to compile conftest.@S|@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_link LINENO @%:@ ----------------------- @%:@ Try to link conftest.@S|@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.@S|@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.@S|@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.@S|@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_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;} ( $as_echo "## -------------------------------------------------------- ## ## Report this to open-vm-tools-devel@lists.sourceforge.net ## ## -------------------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&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_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;} ( $as_echo "## -------------------------------------------------------- ## ## Report this to open-vm-tools-devel@lists.sourceforge.net ## ## -------------------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&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 @%:@ 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_member LINENO AGGR MEMBER VAR INCLUDES @%:@ ---------------------------------------------------- @%:@ Tries to find if the field MEMBER exists in type AGGR, after including @%:@ INCLUDES, setting cache variable VAR accordingly. ac_fn_c_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$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 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 open-vm-tools $as_me 9.4.0, 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 # 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 # In order to make this configure script auto-detect situations where # people have a 32-bit userland running with a 64-bit kernel, we try to ask # the compiler (assumedly gcc) for its default Target:. # We have to set up $TEST_CC manually, since AC_PROG_CC hasn't yet been run (and can't be until AC_CANONICAL_HOST & AC_CANONICAL_BUILD are run) # The purpose of all this is to set up $host_alias/$build_alias in a more # intelligent way than config.guess currently does. TEST_CC="$CC_FOR_BUILD" test -z "$TEST_CC" && TEST_CC="$HOST_CC" test -z "$TEST_CC" && TEST_CC="$CC" if test -n "$TEST_CC" -a -z "$host_alias"; then host_alias="`$TEST_CC -dumpmachine`" if test -z "$build_alias" -a -n "$host_alias"; then build_alias="$host_alias" fi fi unset TEST_CC # checkvm/checkvm.c has no special significance - we just need to pass in a file that # helps autoconf verify that it really has found the source tree. # Keep the top-level directory tidy by putting auxiliary build tools and local # macros in separate subdirectories. ac_aux_dir= for ac_dir in config "$srcdir"/config; 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 config \"$srcdir\"/config" "$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. # 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 # Quote the regular expressions case "$host_cpu" in i[3456]86) userSpaceBitness="32" ;; x86_64) userSpaceBitness="64" ;; *) as_fn_error $? "Unknown architecture." "$LINENO" 5 ;; esac # Operational arguments. @%:@ Check whether --with-root-privileges was given. if test "${with_root_privileges+set}" = set; then : withval=$with_root_privileges; else with_root_privileges=yes fi # Kernel arguments. # The kernel args have to go here otherwise the KERNEL_RELEASE won't be visible # to getOsVersion() @%:@ Check whether --with-kernel-modules was given. if test "${with_kernel_modules+set}" = set; then : withval=$with_kernel_modules; else with_kernel_modules=yes fi @%:@ Check whether --with-kernel-release was given. if test "${with_kernel_release+set}" = set; then : withval=$with_kernel_release; KERNEL_RELEASE="$withval" else KERNEL_RELEASE=`uname -r` fi @%:@ Check whether --with-linuxdir was given. if test "${with_linuxdir+set}" = set; then : withval=$with_linuxdir; LINUXDIR="$withval" else LINUXDIR=/lib/modules/$KERNEL_RELEASE fi # Turn the uname output into something we can run comparisons on. getOsVersion() { major_version="`echo $KERNEL_RELEASE | cut -f1 -d. | cut -f1 -d-`" minor_version="`echo $KERNEL_RELEASE | cut -f2 -d. | cut -f1 -d-`" micro_version="`echo $KERNEL_RELEASE | cut -f3 -d. | cut -f1 -d-`" printf '%02d%02d%03d' $major_version $minor_version $micro_version } case "$host_os" in linux*) os="linux" ;; freebsd*) os="freebsd" ;; solaris*) os="solaris" ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: This is an untested and unsupported Operating System. Proceed at your own peril." >&5 $as_echo "$as_me: WARNING: This is an untested and unsupported Operating System. Proceed at your own peril." >&2;} ;; esac osVersion="`getOsVersion`" if test "$with_kernel_modules" = "yes"; then case "$os" in linux) if test "$osVersion" -lt 206009; then as_fn_error $? "Kernels prior to 2.6.9 are not supported in this release of open-vm-tools. Configure using --without-kernel-modules to suppress building kernel drivers." "$LINENO" 5 fi if test ! -d "$LINUXDIR/kernel/"; then as_fn_error $? "$LINUXDIR/kernel does not exist" "$LINENO" 5 fi LINUXINCLUDE="$LINUXDIR/build/include" if test ! -d "$LINUXINCLUDE"; then as_fn_error $? "Can't find include dir under $LINUXDIR" "$LINENO" 5 fi ;; freebsd) freebsd_sysdir=/usr/src/sys if test -n "$SYSDIR"; then freebsd_sysdir="$SYSDIR" fi if test ! -f "$freebsd_sysdir/conf/kmod.mk"; then as_fn_error $? "FreeBSD kernel tree not found. Please install the kernel sources (or provide the location using SYSDIR) or configure using --without-kernel-modules." "$LINENO" 5 fi ;; esac fi # Arguments for disabling individual open-vm-tools features or libraries. @%:@ Check whether --enable-multimon was given. if test "${enable_multimon+set}" = set; then : enableval=$enable_multimon; enable_multimon="$enableval" else enable_multimon="yes" fi @%:@ Check whether --with-gtk2 was given. if test "${with_gtk2+set}" = set; then : withval=$with_gtk2; with_gtk2="$withval" else with_gtk2="yes" fi @%:@ Check whether --with-gtkmm was given. if test "${with_gtkmm+set}" = set; then : withval=$with_gtkmm; with_gtkmm="$withval" else with_gtkmm="yes" fi @%:@ Check whether --enable-docs was given. if test "${enable_docs+set}" = set; then : enableval=$enable_docs; enable_docs="$enableval" else enable_docs="yes" fi @%:@ Check whether --enable-tests was given. if test "${enable_tests+set}" = set; then : enableval=$enable_tests; enable_tests="$enableval" else enable_tests="auto" fi am__api_version='1.12' # 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' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then 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 fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P 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. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } 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 { $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 rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='open-vm-tools' VERSION='9.4.0' cat >>confdefs.h <<_ACEOF @%:@define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF @%:@define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' ### ### Constants ### # These need to be declared after initialization. # Some of our macro call-sites require changes to # CPPFLAGS/CFLAGS/LDFLAGS. In such places, we save the original value # of CPPFLAGS/CFLAGS/LDFLAGS before the macro call and restore it when # the call is done. We must perform this save at each macro site, # because CPPFLAGS/CFLAGS/LDFLAGS may change over the course of # configuration. # # CPPFLAGS is intended for preprocessor options (-D and -I mainly) # CFLAGS is intended for compiler options (-O, -f, -W, and so forth) CPPFLAGS="$CPPFLAGS -DUSING_AUTOCONF=1 -DOPEN_VM_TOOLS" ### ### Programs ### # C preprocessor and compiler. DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf @%:@ Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= 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 -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 depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= 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 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 { $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 depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi # C++ compiler. Note that unlike AC_PROG_CC, this call does not trigger an # error if no C++ compiler was found; it'll just set the variable CXX to 'g++'. 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 depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi # This allows features like per-target compiler flags. I.e., you can compile # one copy of the same sources twice with different flags. (See lib/guestApp # for an example.) 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 # FIXME: we rely on the cache variable name because # there is no other way. set dummy $CC am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o if test "$am_t" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi # Needed for the various install and uninstall hooks. { $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 { $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 # Needed for creating the archives in lib/ and the shared libraries. 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" # 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 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" { $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; } # 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@&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_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 enable_dlopen=no enable_win32_dll=no @%:@ 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=yes fi @%:@ 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@&t@ -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@&t@ -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 # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # 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="$sys_lib_dlsearch_path_spec $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@&t@ -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@&t@ -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 # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # 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="$sys_lib_dlsearch_path_spec $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: if test "$ac_cv_prog_AR" = false; then as_fn_error $? "The 'ar' utility was not found. Please put ar on the path." "$LINENO" 5 fi # We use pkg-config to set up the cflags and libs for gtk. # 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_prog_HAVE_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$HAVE_PKG_CONFIG"; then ac_cv_prog_HAVE_PKG_CONFIG="$HAVE_PKG_CONFIG" # 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_HAVE_PKG_CONFIG="yes" $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_prog_HAVE_PKG_CONFIG" && ac_cv_prog_HAVE_PKG_CONFIG="no" fi fi HAVE_PKG_CONFIG=$ac_cv_prog_HAVE_PKG_CONFIG if test -n "$HAVE_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_PKG_CONFIG" >&5 $as_echo "$HAVE_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$GCC" != "yes"; then as_fn_error $? "Only GCC is currently supported. Please put gcc in the path." "$LINENO" 5 fi ### ### Libraries ### { $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 # # Check for libintl.h. When configuring using "--without-x", /usr/local/include # may not be added to the include path, so code that use glib's i18n functions # would fail to compile because it can't find libintl.h. # ac_fn_c_check_header_mongrel "$LINENO" "libintl.h" "ac_cv_header_libintl_h" "$ac_includes_default" if test "x$ac_cv_header_libintl_h" = xyes; then : else have_libintl=no fi if test "$have_libintl" = "no"; then unset ac_cv_header_libintl_h CPPFLAGS="$CPPFLAGS -I/usr/local/include" ac_fn_c_check_header_mongrel "$LINENO" "libintl.h" "ac_cv_header_libintl_h" "$ac_includes_default" if test "x$ac_cv_header_libintl_h" = xyes; then : else as_fn_error $? "libintl.h not found. Make sure you have the gettext headers installed." "$LINENO" 5 fi fi # # Check for glib 2.6.0 or greater. # if test -z "glib-2.0"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GLIB2"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GLIB2_CPPFLAGS}" || test -n "${CUSTOM_GLIB2_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GLIB2_LIBS} -lglib-2.0" if test -n "glib.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GLIB2_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "glib.h" "ac_cv_header_glib_h" "$ac_includes_default" if test "x$ac_cv_header_glib_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "g_key_file_new"; then ac_vmw_function=g_key_file_new else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_glib-2.0_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lglib-2.0" >&5 $as_echo_n "checking for $ac_vmw_function in -lglib-2.0... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lglib-2.0 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GLIB2_CPPFLAGS="${CUSTOM_GLIB2_CPPFLAGS}" GLIB2_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "glib-2.0"; then if test -n "2.6.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glib-2.0 >= 2.6.0 (via pkg-config)" >&5 $as_echo_n "checking for glib-2.0 >= 2.6.0 (via pkg-config)... " >&6; } if pkg-config --exists 'glib-2.0 >= 2.6.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glib-2.0 (via pkg-config)" >&5 $as_echo_n "checking for glib-2.0 (via pkg-config)... " >&6; } if pkg-config --exists 'glib-2.0'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags glib-2.0`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs glib-2.0`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GLIB2_CPPFLAGS="$ac_vmw_cppflags" GLIB2_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GLIB2_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GLIB2_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GLIB2_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GLIB2_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true else true as_fn_error $? "glib >= 2.6.0 is required." "$LINENO" 5 fi if test -z "gmodule-2.0"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GMODULE"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GMODULE_CPPFLAGS}" || test -n "${CUSTOM_GMODULE_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GMODULE_LIBS} -lgmodule-2.0" if test -n ""; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GMODULE_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default" if test "x$ac_cv_header_" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n ""; then ac_vmw_function= else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_gmodule-2.0_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lgmodule-2.0" >&5 $as_echo_n "checking for $ac_vmw_function in -lgmodule-2.0... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgmodule-2.0 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GMODULE_CPPFLAGS="${CUSTOM_GMODULE_CPPFLAGS}" GMODULE_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "gmodule-2.0"; then if test -n "2.6.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gmodule-2.0 >= 2.6.0 (via pkg-config)" >&5 $as_echo_n "checking for gmodule-2.0 >= 2.6.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gmodule-2.0 >= 2.6.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gmodule-2.0 (via pkg-config)" >&5 $as_echo_n "checking for gmodule-2.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gmodule-2.0'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags gmodule-2.0`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs gmodule-2.0`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GMODULE_CPPFLAGS="$ac_vmw_cppflags" GMODULE_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GMODULE_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GMODULE_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GMODULE_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GMODULE_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true else true as_fn_error $? "gmodule >= 2.6.0 is required." "$LINENO" 5 fi if test -z "gobject-2.0"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GOBJECT"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GOBJECT_CPPFLAGS}" || test -n "${CUSTOM_GOBJECT_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GOBJECT_LIBS} -lgobject-2.0" if test -n "glib-object.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GOBJECT_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "glib-object.h" "ac_cv_header_glib_object_h" "$ac_includes_default" if test "x$ac_cv_header_glib_object_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n ""; then ac_vmw_function= else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_gobject-2.0_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lgobject-2.0" >&5 $as_echo_n "checking for $ac_vmw_function in -lgobject-2.0... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgobject-2.0 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GOBJECT_CPPFLAGS="${CUSTOM_GOBJECT_CPPFLAGS}" GOBJECT_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "gobject-2.0"; then if test -n "2.6.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gobject-2.0 >= 2.6.0 (via pkg-config)" >&5 $as_echo_n "checking for gobject-2.0 >= 2.6.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gobject-2.0 >= 2.6.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gobject-2.0 (via pkg-config)" >&5 $as_echo_n "checking for gobject-2.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gobject-2.0'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags gobject-2.0`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs gobject-2.0`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GOBJECT_CPPFLAGS="$ac_vmw_cppflags" GOBJECT_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GOBJECT_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GOBJECT_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GOBJECT_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GOBJECT_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true else true as_fn_error $? "gobject >= 2.6.0 is required." "$LINENO" 5 fi if test -z "gthread-2.0"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GTHREAD"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GTHREAD_CPPFLAGS}" || test -n "${CUSTOM_GTHREAD_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GTHREAD_LIBS} -lgthread-2.0" if test -n ""; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GTHREAD_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default" if test "x$ac_cv_header_" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n ""; then ac_vmw_function= else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_gthread-2.0_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lgthread-2.0" >&5 $as_echo_n "checking for $ac_vmw_function in -lgthread-2.0... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgthread-2.0 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GTHREAD_CPPFLAGS="${CUSTOM_GTHREAD_CPPFLAGS}" GTHREAD_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "gthread-2.0"; then if test -n "2.6.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gthread-2.0 >= 2.6.0 (via pkg-config)" >&5 $as_echo_n "checking for gthread-2.0 >= 2.6.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gthread-2.0 >= 2.6.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gthread-2.0 (via pkg-config)" >&5 $as_echo_n "checking for gthread-2.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gthread-2.0'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags gthread-2.0`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs gthread-2.0`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GTHREAD_CPPFLAGS="$ac_vmw_cppflags" GTHREAD_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GTHREAD_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GTHREAD_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GTHREAD_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GTHREAD_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true else true as_fn_error $? "glib >= 2.6.0 is required." "$LINENO" 5 fi # Extract the first word of "glib-genmarshal", so it can be a program name with args. set dummy glib-genmarshal; 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_have_genmarshal+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$have_genmarshal"; then ac_cv_prog_have_genmarshal="$have_genmarshal" # 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_have_genmarshal="yes" $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_prog_have_genmarshal" && ac_cv_prog_have_genmarshal="no" fi fi have_genmarshal=$ac_cv_prog_have_genmarshal if test -n "$have_genmarshal"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_genmarshal" >&5 $as_echo "$have_genmarshal" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$have_genmarshal" != "yes"; then as_fn_error $? "glib-genmarshal is required; make sure it's available in your path." "$LINENO" 5 fi # # Parts of our Linux code require more recent version of glib # if test "$os" = "linux"; then if test -z "glib-2.0"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GLIB2"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GLIB2_CPPFLAGS}" || test -n "${CUSTOM_GLIB2_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GLIB2_LIBS} -lglib-2.0" if test -n "glib.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GLIB2_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "glib.h" "ac_cv_header_glib_h" "$ac_includes_default" if test "x$ac_cv_header_glib_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "g_regex_new"; then ac_vmw_function=g_regex_new else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_glib-2.0_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lglib-2.0" >&5 $as_echo_n "checking for $ac_vmw_function in -lglib-2.0... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lglib-2.0 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GLIB2_CPPFLAGS="${CUSTOM_GLIB2_CPPFLAGS}" GLIB2_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "glib-2.0"; then if test -n "2.14.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glib-2.0 >= 2.14.0 (via pkg-config)" >&5 $as_echo_n "checking for glib-2.0 >= 2.14.0 (via pkg-config)... " >&6; } if pkg-config --exists 'glib-2.0 >= 2.14.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glib-2.0 (via pkg-config)" >&5 $as_echo_n "checking for glib-2.0 (via pkg-config)... " >&6; } if pkg-config --exists 'glib-2.0'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags glib-2.0`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs glib-2.0`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GLIB2_CPPFLAGS="$ac_vmw_cppflags" GLIB2_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GLIB2_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GLIB2_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GLIB2_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GLIB2_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_glib_2_14=yes else true { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: glib is not recent enough, some features will be disabled." >&5 $as_echo "$as_me: WARNING: glib is not recent enough, some features will be disabled." >&2;} fi fi # # Check for fuse. # if test -z "fuse"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "FUSE"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_FUSE_CPPFLAGS}" || test -n "${CUSTOM_FUSE_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_FUSE_LIBS} -lfuse" if test -n "fuse.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_FUSE_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "fuse.h" "ac_cv_header_fuse_h" "$ac_includes_default" if test "x$ac_cv_header_fuse_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "fuse_main"; then ac_vmw_function=fuse_main else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_fuse_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lfuse" >&5 $as_echo_n "checking for $ac_vmw_function in -lfuse... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lfuse $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then FUSE_CPPFLAGS="${CUSTOM_FUSE_CPPFLAGS}" FUSE_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "fuse"; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fuse >= (via pkg-config)" >&5 $as_echo_n "checking for fuse >= (via pkg-config)... " >&6; } if pkg-config --exists 'fuse >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fuse (via pkg-config)" >&5 $as_echo_n "checking for fuse (via pkg-config)... " >&6; } if pkg-config --exists 'fuse'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags fuse`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs fuse`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } FUSE_CPPFLAGS="$ac_vmw_cppflags" FUSE_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then FUSE_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" FUSE_LIBS="`$ac_vmw_lib_cfg --ldflags`" else FUSE_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" FUSE_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_fuse=yes else true have_fuse=no; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Fuse is missing, vmblock-fuse will be disabled." >&5 $as_echo "$as_me: WARNING: Fuse is missing, vmblock-fuse will be disabled." >&2;} fi # # Check for PAM. # @%:@ Check whether --with-pam was given. if test "${with_pam+set}" = set; then : withval=$with_pam; else with_pam=yes fi if test "$with_pam" = "yes"; then if test -z "$CUSTOM_PAM_CPPFLAGS"; then if test "$os" = freebsd; then CUSTOM_PAM_CPPFLAGS="-I/usr/local/include" else CUSTOM_PAM_CPPFLAGS="-I/usr/include" fi if test -n ""; then CUSTOM_PAM_CPPFLAGS="${CUSTOM_PAM_CPPFLAGS}/" fi fi if test -z "pam"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "PAM"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_PAM_CPPFLAGS}" || test -n "${CUSTOM_PAM_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_PAM_LIBS} -lpam" if test -n "security/pam_appl.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_PAM_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "security/pam_appl.h" "ac_cv_header_security_pam_appl_h" "$ac_includes_default" if test "x$ac_cv_header_security_pam_appl_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "pam_start"; then ac_vmw_function=pam_start else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_pam_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lpam" >&5 $as_echo_n "checking for $ac_vmw_function in -lpam... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpam $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then PAM_CPPFLAGS="${CUSTOM_PAM_CPPFLAGS}" PAM_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } PAM_CPPFLAGS="$ac_vmw_cppflags" PAM_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then PAM_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" PAM_LIBS="`$ac_vmw_lib_cfg --ldflags`" else PAM_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" PAM_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true PAM_CPPFLAGS="$PAM_CPPFLAGS -DUSE_PAM" else true feature="" if test -z "$feature"; then feature="PAM" fi as_fn_error $? "Cannot find PAM library. Please configure without $feature (using --without-pam), or install the PAM libraries and devel package(s)." "$LINENO" 5 fi fi # # Check for CUnit and disable test code if not available. # if test "$enable_tests" = "auto" -o "$enable_tests" = "yes"; then if test -z "$CUSTOM_CUNIT_CPPFLAGS"; then if test "$os" = freebsd; then CUSTOM_CUNIT_CPPFLAGS="-I/usr/local/include" else CUSTOM_CUNIT_CPPFLAGS="-I/usr/include" fi if test -n ""; then CUSTOM_CUNIT_CPPFLAGS="${CUSTOM_CUNIT_CPPFLAGS}/" fi fi if test -z "cunit"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "CUNIT"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_CUNIT_CPPFLAGS}" || test -n "${CUSTOM_CUNIT_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_CUNIT_LIBS} -lcunit" if test -n "CUnit/CUnit.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_CUNIT_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "CUnit/CUnit.h" "ac_cv_header_CUnit_CUnit_h" "$ac_includes_default" if test "x$ac_cv_header_CUnit_CUnit_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "CU_initialize_registry"; then ac_vmw_function=CU_initialize_registry else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_cunit_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lcunit" >&5 $as_echo_n "checking for $ac_vmw_function in -lcunit... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcunit $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then CUNIT_CPPFLAGS="${CUSTOM_CUNIT_CPPFLAGS}" CUNIT_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CUNIT_CPPFLAGS="$ac_vmw_cppflags" CUNIT_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then CUNIT_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" CUNIT_LIBS="`$ac_vmw_lib_cfg --ldflags`" else CUNIT_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" CUNIT_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_cunit=yes else true have_cunit=no fi if test "$have_cunit" = "no"; then if test "$enable_tests" = "yes"; then feature="" if test -z "$feature"; then feature="CUNIT" fi as_fn_error $? "Cannot find CUNIT library. Please configure without $feature (using --without-cunit), or install the CUNIT libraries and devel package(s)." "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: CUnit not found, tests won't be compiled." >&5 $as_echo "$as_me: WARNING: CUnit not found, tests won't be compiled." >&2;} fi fi fi # If the user explicitly disables X11, then don't try to detect the X-related libraries if test "$have_x" = "disabled"; then enable_multimon="no" elif test "$have_x" != "yes"; then as_fn_error $? "The X11 libraries were not found. Please configure without X11 (using --without-x), or install the libX11 devel package(s)." "$LINENO" 5 else CPPFLAGS="$CPPFLAGS $X_CFLAGS" COMMON_XLIBS="$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XeviQueryVersion in -lXext" >&5 $as_echo_n "checking for XeviQueryVersion in -lXext... " >&6; } if ${ac_cv_lib_Xext_XeviQueryVersion+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXext $COMMON_XLIBS $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 XeviQueryVersion (); int main () { return XeviQueryVersion (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xext_XeviQueryVersion=yes else ac_cv_lib_Xext_XeviQueryVersion=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_Xext_XeviQueryVersion" >&5 $as_echo "$ac_cv_lib_Xext_XeviQueryVersion" >&6; } if test "x$ac_cv_lib_Xext_XeviQueryVersion" = xyes; then : COMMON_XLIBS="-lXext $COMMON_XLIBS" else as_fn_error $? "libXext not found. Please configure without X11 (using --without-x), or install the libXext devel package(s)." "$LINENO" 5 fi ac_fn_c_check_header_compile "$LINENO" "X11/extensions/extutil.h" "ac_cv_header_X11_extensions_extutil_h" "#include #include " if test "x$ac_cv_header_X11_extensions_extutil_h" = xyes; then : else as_fn_error $? "X11/extensions/extutil.h header not found - you're probably on Solaris 10 or older. Please copy that header file onto your system manually, or configure without X11 (using --without-x)." "$LINENO" 5 fi if test "$enable_multimon" != "no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XineramaQueryVersion in -lXinerama" >&5 $as_echo_n "checking for XineramaQueryVersion in -lXinerama... " >&6; } if ${ac_cv_lib_Xinerama_XineramaQueryVersion+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXinerama $COMMON_XLIBS $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 XineramaQueryVersion (); int main () { return XineramaQueryVersion (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xinerama_XineramaQueryVersion=yes else ac_cv_lib_Xinerama_XineramaQueryVersion=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_Xinerama_XineramaQueryVersion" >&5 $as_echo "$ac_cv_lib_Xinerama_XineramaQueryVersion" >&6; } if test "x$ac_cv_lib_Xinerama_XineramaQueryVersion" = xyes; then : COMMON_XLIBS="-lXinerama $COMMON_XLIBS" else as_fn_error $? "libXinerama not found. Please configure without multimon (using --disable-multimon), configure without X11 (using --without-x), or install the libXinerama devel package(s)." "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XOpenDevice in -lXi" >&5 $as_echo_n "checking for XOpenDevice in -lXi... " >&6; } if ${ac_cv_lib_Xi_XOpenDevice+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXi $COMMON_XLIBS $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 XOpenDevice (); int main () { return XOpenDevice (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xi_XOpenDevice=yes else ac_cv_lib_Xi_XOpenDevice=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_Xi_XOpenDevice" >&5 $as_echo "$ac_cv_lib_Xi_XOpenDevice" >&6; } if test "x$ac_cv_lib_Xi_XOpenDevice" = xyes; then : COMMON_XLIBS="-lXi $COMMON_XLIBS" else as_fn_error $? "libXi not found. Please configure without X11 (using --without-x), or install the libXi devel package(s)." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XRenderQueryVersion in -lXrender" >&5 $as_echo_n "checking for XRenderQueryVersion in -lXrender... " >&6; } if ${ac_cv_lib_Xrender_XRenderQueryVersion+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXrender $COMMON_XLIBS $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 XRenderQueryVersion (); int main () { return XRenderQueryVersion (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xrender_XRenderQueryVersion=yes else ac_cv_lib_Xrender_XRenderQueryVersion=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_Xrender_XRenderQueryVersion" >&5 $as_echo "$ac_cv_lib_Xrender_XRenderQueryVersion" >&6; } if test "x$ac_cv_lib_Xrender_XRenderQueryVersion" = xyes; then : COMMON_XLIBS="-lXrender $COMMON_XLIBS" else as_fn_error $? "libXrender not found. Please configure without X11 (using --without-x), or install the libXrender devel package(s)." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XRRQueryVersion in -lXrandr" >&5 $as_echo_n "checking for XRRQueryVersion in -lXrandr... " >&6; } if ${ac_cv_lib_Xrandr_XRRQueryVersion+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXrandr $COMMON_XLIBS $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 XRRQueryVersion (); int main () { return XRRQueryVersion (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xrandr_XRRQueryVersion=yes else ac_cv_lib_Xrandr_XRRQueryVersion=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_Xrandr_XRRQueryVersion" >&5 $as_echo "$ac_cv_lib_Xrandr_XRRQueryVersion" >&6; } if test "x$ac_cv_lib_Xrandr_XRRQueryVersion" = xyes; then : COMMON_XLIBS="-lXrandr $COMMON_XLIBS" else as_fn_error $? "libXrandr not found. Please configure without X11 (using --without-x) or install the libXrandr devel package(s)." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XTestQueryExtension in -lXtst" >&5 $as_echo_n "checking for XTestQueryExtension in -lXtst... " >&6; } if ${ac_cv_lib_Xtst_XTestQueryExtension+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXtst $COMMON_XLIBS $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 XTestQueryExtension (); int main () { return XTestQueryExtension (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xtst_XTestQueryExtension=yes else ac_cv_lib_Xtst_XTestQueryExtension=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_Xtst_XTestQueryExtension" >&5 $as_echo "$ac_cv_lib_Xtst_XTestQueryExtension" >&6; } if test "x$ac_cv_lib_Xtst_XTestQueryExtension" = xyes; then : COMMON_XLIBS="-lXtst $COMMON_XLIBS" else as_fn_error $? "libXtst not found. Please configure without X11 (using --without-x) or install the libXtst devel package(s)." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SmcOpenConnection in -lSM" >&5 $as_echo_n "checking for SmcOpenConnection in -lSM... " >&6; } if ${ac_cv_lib_SM_SmcOpenConnection+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lSM $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 SmcOpenConnection (); int main () { return SmcOpenConnection (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_SM_SmcOpenConnection=yes else ac_cv_lib_SM_SmcOpenConnection=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_SM_SmcOpenConnection" >&5 $as_echo "$ac_cv_lib_SM_SmcOpenConnection" >&6; } if test "x$ac_cv_lib_SM_SmcOpenConnection" = xyes; then : XSM_LIBS="-lSM -lICE" && have_xsm_lib="yes" else -lICE fi for ac_header in X11/SM/SMlib.h X11/ICE/ICElib.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 have_xsm_header="yes" fi done if test "$have_xsm_lib" = "yes" -a "$have_xsm_header" = "yes"; then have_xsm="yes" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XCompositeQueryExtension in -lXcomposite" >&5 $as_echo_n "checking for XCompositeQueryExtension in -lXcomposite... " >&6; } if ${ac_cv_lib_Xcomposite_XCompositeQueryExtension+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXcomposite $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 XCompositeQueryExtension (); int main () { return XCompositeQueryExtension (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xcomposite_XCompositeQueryExtension=yes else ac_cv_lib_Xcomposite_XCompositeQueryExtension=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_Xcomposite_XCompositeQueryExtension" >&5 $as_echo "$ac_cv_lib_Xcomposite_XCompositeQueryExtension" >&6; } if test "x$ac_cv_lib_Xcomposite_XCompositeQueryExtension" = xyes; then : XCOMPOSITE_LIBS="-lXcomposite" else have_xcomposite="no" fi for ac_header in X11/extensions/Xcomposite.h do : ac_fn_c_check_header_mongrel "$LINENO" "X11/extensions/Xcomposite.h" "ac_cv_header_X11_extensions_Xcomposite_h" "$ac_includes_default" if test "x$ac_cv_header_X11_extensions_Xcomposite_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_X11_EXTENSIONS_XCOMPOSITE_H 1 _ACEOF else have_xcomposite="no" fi done if test "$have_xcomposite" != "no"; then have_xcomposite="yes" fi # Check whether we have gtk+ 2.0. if test "$with_gtk2" != "no"; then # gdk_display_get_default_group (added in gtk+ 2.4.0) is function currently # needed by vmware-user. if test -z "gtk-x11-2.0"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GTK"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GTK_CPPFLAGS}" || test -n "${CUSTOM_GTK_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GTK_LIBS} -lgtk-x11-2.0" if test -n "gtk/gtk.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GTK_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "gtk/gtk.h" "ac_cv_header_gtk_gtk_h" "$ac_includes_default" if test "x$ac_cv_header_gtk_gtk_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "gdk_display_get_default_group"; then ac_vmw_function=gdk_display_get_default_group else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_gtk-x11-2.0_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lgtk-x11-2.0" >&5 $as_echo_n "checking for $ac_vmw_function in -lgtk-x11-2.0... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgtk-x11-2.0 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GTK_CPPFLAGS="${CUSTOM_GTK_CPPFLAGS}" GTK_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "gtk+-2.0"; then if test -n "2.4.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gtk+-2.0 >= 2.4.0 (via pkg-config)" >&5 $as_echo_n "checking for gtk+-2.0 >= 2.4.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gtk+-2.0 >= 2.4.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gtk+-2.0 (via pkg-config)" >&5 $as_echo_n "checking for gtk+-2.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gtk+-2.0'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags gtk+-2.0`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs gtk+-2.0`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GTK_CPPFLAGS="$ac_vmw_cppflags" GTK_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GTK_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GTK_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GTK_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GTK_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true GTK_CPPFLAGS="$GTK_CPPFLAGS -DGTK2" else true as_fn_error $? "Gtk+ 2.0 library not found or too old. Please configure without Gtk+ support (using --without-gtk2) or install the Gtk+ 2.0 devel package." "$LINENO" 5 fi fi # # Check for gtkmm 2.4.0 or greater. # if test "$with_gtkmm" != "no"; then CUSTOM_GTKMM_CPPFLAGS="$CUSTOM_GTKMM_CPPFLAGS $GTK_CPPFLAGS" 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 "gtkmm-2.4"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GTKMM"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GTKMM_CPPFLAGS}" || test -n "${CUSTOM_GTKMM_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GTKMM_LIBS} -lgtkmm-2.4" if test -n "gtkmm.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GTKMM_CPPFLAGS} $CPPFLAGS" ac_fn_cxx_check_header_mongrel "$LINENO" "gtkmm.h" "ac_cv_header_gtkmm_h" "$ac_includes_default" if test "x$ac_cv_header_gtkmm_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n ""; then ac_vmw_function= else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_gtkmm-2.4_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lgtkmm-2.4" >&5 $as_echo_n "checking for $ac_vmw_function in -lgtkmm-2.4... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgtkmm-2.4 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GTKMM_CPPFLAGS="${CUSTOM_GTKMM_CPPFLAGS}" GTKMM_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "gtkmm-2.4"; then if test -n "2.4.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gtkmm-2.4 >= 2.4.0 (via pkg-config)" >&5 $as_echo_n "checking for gtkmm-2.4 >= 2.4.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gtkmm-2.4 >= 2.4.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gtkmm-2.4 (via pkg-config)" >&5 $as_echo_n "checking for gtkmm-2.4 (via pkg-config)... " >&6; } if pkg-config --exists 'gtkmm-2.4'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags gtkmm-2.4`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs gtkmm-2.4`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GTKMM_CPPFLAGS="$ac_vmw_cppflags" GTKMM_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GTKMM_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GTKMM_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GTKMM_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GTKMM_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true GTKMM_CPPFLAGS="$GTKMM_CPPFLAGS -DHAVE_GTKMM" else true as_fn_error $? "gtkmm library not found. Please install the libgtkmm devel package(s), or re-configure using --without-gtkmm." "$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 fi fi # End of checks for X libraries { $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 : HAVE_CRYPT="yes" else as_fn_error $? "libcrypt not found. Please install the libc/libcrypt devel package(s)." "$LINENO" 5 fi for ac_func in dlopen do : ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_DLOPEN 1 _ACEOF 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 : VIX_LIBADD="$VIX_LIBADD -ldl" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -ldl" else as_fn_error $? "dlopen was not found, but is required for open-vm-tools to function properly. Please contact your OS vendor." "$LINENO" 5 fi fi done for ac_func in ecvt do : ac_fn_c_check_func "$LINENO" "ecvt" "ac_cv_func_ecvt" if test "x$ac_cv_func_ecvt" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_ECVT 1 _ACEOF fi done for ac_func in fcvt do : ac_fn_c_check_func "$LINENO" "fcvt" "ac_cv_func_fcvt" if test "x$ac_cv_func_fcvt" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_FCVT 1 _ACEOF fi done if test "$os" = "freebsd" -a "$osVersion" -ge 600000; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lthr" >&5 $as_echo_n "checking for pthread_mutex_init in -lthr... " >&6; } if ${ac_cv_lib_thr_pthread_mutex_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lthr $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_mutex_init (); int main () { return pthread_mutex_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_thr_pthread_mutex_init=yes else ac_cv_lib_thr_pthread_mutex_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_thr_pthread_mutex_init" >&5 $as_echo "$ac_cv_lib_thr_pthread_mutex_init" >&6; } if test "x$ac_cv_lib_thr_pthread_mutex_init" = xyes; then : THREAD_LIB=-lthr else as_fn_error $? "Unable to locate required threading library libthr." "$LINENO" 5 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthread" >&5 $as_echo_n "checking for pthread_mutex_init in -lpthread... " >&6; } if ${ac_cv_lib_pthread_pthread_mutex_init+:} 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_mutex_init (); int main () { return pthread_mutex_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread_pthread_mutex_init=yes else ac_cv_lib_pthread_pthread_mutex_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_pthread_pthread_mutex_init" >&5 $as_echo "$ac_cv_lib_pthread_pthread_mutex_init" >&6; } if test "x$ac_cv_lib_pthread_pthread_mutex_init" = xyes; then : THREAD_LIB=-lpthread else as_fn_error $? "libpthread not found. Please install the libc/libpthread devel package(s)." "$LINENO" 5 fi fi # PAM prefix @%:@ Check whether --with-pam-prefix was given. if test "${with_pam_prefix+set}" = set; then : withval=$with_pam_prefix; PAM_PREFIX="$withval" else PAM_PREFIX='$(sysconfdir)' fi if test "$os" = "linux"; then @%:@ Check whether --with-procps was given. if test "${with_procps+set}" = set; then : withval=$with_procps; else with_procps=yes fi else with_procps="no" fi if test "$with_procps" = "yes"; then if test -z "$CUSTOM_PROCPS_NAME"; then CUSTOM_PROCPS_NAME=proc fi # XXX: no pkg-config and no procps-config means we need to # hard-code a sensible default. if test -z "$CUSTOM_PROCPS_LIBS"; then CUSTOM_PROCPS_LIBS="-L/lib" fi # Some distros provide libproc-${version}.so only, others provide the # libproc.so symlink. Try both to see what sticks (but only try the 3.2.7 # and 3.2.8 versions - adding every possible version here would be a mess). # # Users can help by providing CUSTOM_PROCPS_NAME / CUSTOM_PROCPS_LIBS if # necessary. have_procps=no if test -z "$CUSTOM_PROCPS_NAME"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "PROCPS"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_PROCPS_CPPFLAGS}" || test -n "${CUSTOM_PROCPS_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_PROCPS_LIBS} -l$CUSTOM_PROCPS_NAME" if test -n ""; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_PROCPS_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default" if test "x$ac_cv_header_" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "getstat"; then ac_vmw_function=getstat else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_$CUSTOM_PROCPS_NAME''_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -l$CUSTOM_PROCPS_NAME" >&5 $as_echo_n "checking for $ac_vmw_function in -l$CUSTOM_PROCPS_NAME... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-l$CUSTOM_PROCPS_NAME $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then PROCPS_CPPFLAGS="${CUSTOM_PROCPS_CPPFLAGS}" PROCPS_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } PROCPS_CPPFLAGS="$ac_vmw_cppflags" PROCPS_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then PROCPS_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" PROCPS_LIBS="`$ac_vmw_lib_cfg --ldflags`" else PROCPS_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" PROCPS_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_procps=yes; else true fi if test "$have_procps" = "no"; then if test -z "proc-3.2.8"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "PROCPS"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_PROCPS_CPPFLAGS}" || test -n "${CUSTOM_PROCPS_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_PROCPS_LIBS} -lproc-3.2.8" if test -n ""; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_PROCPS_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default" if test "x$ac_cv_header_" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "getstat"; then ac_vmw_function=getstat else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_proc-3.2.8_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lproc-3.2.8" >&5 $as_echo_n "checking for $ac_vmw_function in -lproc-3.2.8... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lproc-3.2.8 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then PROCPS_CPPFLAGS="${CUSTOM_PROCPS_CPPFLAGS}" PROCPS_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } PROCPS_CPPFLAGS="$ac_vmw_cppflags" PROCPS_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then PROCPS_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" PROCPS_LIBS="`$ac_vmw_lib_cfg --ldflags`" else PROCPS_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" PROCPS_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_procps=yes; else true fi fi if test "$have_procps" = "no"; then if test -z "proc-3.2.7"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "PROCPS"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_PROCPS_CPPFLAGS}" || test -n "${CUSTOM_PROCPS_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_PROCPS_LIBS} -lproc-3.2.7" if test -n ""; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_PROCPS_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default" if test "x$ac_cv_header_" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "getstat"; then ac_vmw_function=getstat else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_proc-3.2.7_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lproc-3.2.7" >&5 $as_echo_n "checking for $ac_vmw_function in -lproc-3.2.7... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lproc-3.2.7 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then PROCPS_CPPFLAGS="${CUSTOM_PROCPS_CPPFLAGS}" PROCPS_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } PROCPS_CPPFLAGS="$ac_vmw_cppflags" PROCPS_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then PROCPS_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" PROCPS_LIBS="`$ac_vmw_lib_cfg --ldflags`" else PROCPS_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" PROCPS_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true else true as_fn_error $? "libproc not found. Please configure without procps (using --without-procps) or install procps - http://procps.sourceforge.net" "$LINENO" 5 fi fi fi if test "$with_procps" != "yes"; then $as_echo "@%:@define NO_PROCPS 1" >>confdefs.h fi @%:@ Check whether --with-dnet was given. if test "${with_dnet+set}" = set; then : withval=$with_dnet; else with_dnet=yes fi have_dnet="no" if test "$with_dnet" = "yes"; then # On Debian, dnet is installed via the libdumbnet package. We need to # detect this so that our source files include dumbnet.h instead of # dnet.h, which is part of a different package altogether. if test -z "dumbnet"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "DNET"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_DNET_CPPFLAGS}" || test -n "${CUSTOM_DNET_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_DNET_LIBS} -ldumbnet" if test -n "dumbnet.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_DNET_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "dumbnet.h" "ac_cv_header_dumbnet_h" "$ac_includes_default" if test "x$ac_cv_header_dumbnet_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "intf_open"; then ac_vmw_function=intf_open else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_dumbnet_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -ldumbnet" >&5 $as_echo_n "checking for $ac_vmw_function in -ldumbnet... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldumbnet $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then DNET_CPPFLAGS="${CUSTOM_DNET_CPPFLAGS}" DNET_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } DNET_CPPFLAGS="$ac_vmw_cppflags" DNET_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n "dumbnet-config"; then # Extract the first word of "dumbnet-config", so it can be a program name with args. set dummy dumbnet-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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then DNET_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" DNET_LIBS="`$ac_vmw_lib_cfg --ldflags`" else DNET_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" DNET_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_dnet="yes"; $as_echo "@%:@define DNET_IS_DUMBNET 1" >>confdefs.h else true fi if test $have_dnet = "no"; then if test -z "dnet"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "DNET"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_DNET_CPPFLAGS}" || test -n "${CUSTOM_DNET_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_DNET_LIBS} -ldnet" if test -n "dnet.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_DNET_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "dnet.h" "ac_cv_header_dnet_h" "$ac_includes_default" if test "x$ac_cv_header_dnet_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "intf_open"; then ac_vmw_function=intf_open else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_dnet_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -ldnet" >&5 $as_echo_n "checking for $ac_vmw_function in -ldnet... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then DNET_CPPFLAGS="${CUSTOM_DNET_CPPFLAGS}" DNET_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } DNET_CPPFLAGS="$ac_vmw_cppflags" DNET_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n "dnet-config"; then # Extract the first word of "dnet-config", so it can be a program name with args. set dummy dnet-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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then DNET_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" DNET_LIBS="`$ac_vmw_lib_cfg --ldflags`" else DNET_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" DNET_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_dnet="yes" else true fi fi if test $have_dnet = "no"; then as_fn_error $? "dnet-config was not found on your PATH. Please configure without dnet (using --without-dnet) or install dnet - http://libdnet.sourceforge.net" "$LINENO" 5 fi fi if test "$with_dnet" != "yes"; then $as_echo "@%:@define NO_DNET 1" >>confdefs.h fi @%:@ Check whether --with-icu was given. if test "${with_icu+set}" = set; then : withval=$with_icu; else with_icu=yes fi if test "$have_x" = "yes" -o "$with_icu" = "yes"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}$CXX", so it can be a program name with args. set dummy ${ac_tool_prefix}$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_prog_have_cxx+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$have_cxx"; then ac_cv_prog_have_cxx="$have_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_have_cxx="${ac_tool_prefix}$CXX" $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 have_cxx=$ac_cv_prog_have_cxx if test -n "$have_cxx"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_cxx" >&5 $as_echo "$have_cxx" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_have_cxx"; then ac_ct_have_cxx=$have_cxx # 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_prog_ac_ct_have_cxx+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_have_cxx"; then ac_cv_prog_ac_ct_have_cxx="$ac_ct_have_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_have_cxx="$CXX" $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_have_cxx=$ac_cv_prog_ac_ct_have_cxx if test -n "$ac_ct_have_cxx"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_have_cxx" >&5 $as_echo "$ac_ct_have_cxx" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_have_cxx" = x; then have_cxx="no" 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 have_cxx=$ac_ct_have_cxx fi else have_cxx="$ac_cv_prog_have_cxx" fi if test "$have_cxx" = "no"; then as_fn_error $? "C++ compiler not found. Make sure you have a C++ compiler installed or configure without X11 (using --without-x) and without ICU (using --without-icu)." "$LINENO" 5 fi fi if test "$with_icu" = "yes"; 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 if test -z "icuuc"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "ICU"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_ICU_CPPFLAGS}" || test -n "${CUSTOM_ICU_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_ICU_LIBS} -licuuc" if test -n "unicode/utf.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_ICU_CPPFLAGS} $CPPFLAGS" ac_fn_cxx_check_header_mongrel "$LINENO" "unicode/utf.h" "ac_cv_header_unicode_utf_h" "$ac_includes_default" if test "x$ac_cv_header_unicode_utf_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n ""; then ac_vmw_function= else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_icuuc_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -licuuc" >&5 $as_echo_n "checking for $ac_vmw_function in -licuuc... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-licuuc $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then ICU_CPPFLAGS="${CUSTOM_ICU_CPPFLAGS}" ICU_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ICU_CPPFLAGS="$ac_vmw_cppflags" ICU_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n "icu-config"; then # Extract the first word of "icu-config", so it can be a program name with args. set dummy icu-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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then ICU_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" ICU_LIBS="`$ac_vmw_lib_cfg --ldflags`" else ICU_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" ICU_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true ICU_CPPFLAGS="$ICU_CPPFLAGS -DUSE_ICU" else true as_fn_error $? "ICU library not found. Please configure without ICU (using --without-icu) or install ICU - http://www.icu-project.org" "$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 # Check whether we have ICU >= 3.8. 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 ucasemap_utf8ToTitle in ICU" >&5 $as_echo_n "checking for ucasemap_utf8ToTitle in ICU... " >&6; } ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $ICU_CPPFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { (void) &ucasemap_utf8ToTitle; return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ICU_CPPFLAGS="$ICU_CPPFLAGS -DHAVE_ICU_38" { $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 CPPFLAGS="$ORIGINAL_CPPFLAGS" 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 # Easier to give all modules the ICU defines/includes... CPPFLAGS="$CPPFLAGS $ICU_CPPFLAGS" else CPPFLAGS="$CPPFLAGS -DNO_ICU" fi # Extract the first word of "rpcgen", so it can be a program name with args. set dummy rpcgen; 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_RPCGEN+:} false; then : $as_echo_n "(cached) " >&6 else case $RPCGEN in [\\/]* | ?:[\\/]*) ac_cv_path_RPCGEN="$RPCGEN" # 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_RPCGEN="$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_RPCGEN" && ac_cv_path_RPCGEN=" as_fn_error $? "rpcgen not found. Please install the libc devel package." "$LINENO" 5 " ;; esac fi RPCGEN=$ac_cv_path_RPCGEN if test -n "$RPCGEN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RPCGEN" >&5 $as_echo "$RPCGEN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ### ### Headers ### for ac_header in crypt.h do : ac_fn_c_check_header_mongrel "$LINENO" "crypt.h" "ac_cv_header_crypt_h" "$ac_includes_default" if test "x$ac_cv_header_crypt_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_CRYPT_H 1 _ACEOF fi done for ac_header in inttypes.h do : ac_fn_c_check_header_mongrel "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default" if test "x$ac_cv_header_inttypes_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_INTTYPES_H 1 _ACEOF fi done 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 for ac_header in stdlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" if test "x$ac_cv_header_stdlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_STDLIB_H 1 _ACEOF fi done for ac_header in wchar.h do : ac_fn_c_check_header_mongrel "$LINENO" "wchar.h" "ac_cv_header_wchar_h" "$ac_includes_default" if test "x$ac_cv_header_wchar_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_WCHAR_H 1 _ACEOF fi done for ac_header in sys/inttypes.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/inttypes.h" "ac_cv_header_sys_inttypes_h" "$ac_includes_default" if test "x$ac_cv_header_sys_inttypes_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_INTTYPES_H 1 _ACEOF fi done for ac_header in sys/io.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/io.h" "ac_cv_header_sys_io_h" "$ac_includes_default" if test "x$ac_cv_header_sys_io_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_IO_H 1 _ACEOF fi done for ac_header in sys/param.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default" if test "x$ac_cv_header_sys_param_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_PARAM_H 1 _ACEOF fi done # Required to make the sys/user.h check work correctly on FreeBSD for ac_header in sys/sysinfo.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/sysinfo.h" "ac_cv_header_sys_sysinfo_h" "$ac_includes_default" if test "x$ac_cv_header_sys_sysinfo_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_SYSINFO_H 1 _ACEOF fi done for ac_header in sys/types.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default" if test "x$ac_cv_header_sys_types_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_TYPES_H 1 _ACEOF fi done for ac_header in sys/user.h do : ac_fn_c_check_header_compile "$LINENO" "sys/user.h" "ac_cv_header_sys_user_h" " #ifdef HAVE_SYS_PARAM_H # include #endif " if test "x$ac_cv_header_sys_user_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_USER_H 1 _ACEOF fi done for ac_header in sys/vfs.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/vfs.h" "ac_cv_header_sys_vfs_h" "$ac_includes_default" if test "x$ac_cv_header_sys_vfs_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_VFS_H 1 _ACEOF fi done for ac_header in syslimits.h do : ac_fn_c_check_header_mongrel "$LINENO" "syslimits.h" "ac_cv_header_syslimits_h" "$ac_includes_default" if test "x$ac_cv_header_syslimits_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYSLIMITS_H 1 _ACEOF fi done for ac_header in unwind.h do : ac_fn_c_check_header_mongrel "$LINENO" "unwind.h" "ac_cv_header_unwind_h" "$ac_includes_default" if test "x$ac_cv_header_unwind_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_UNWIND_H 1 _ACEOF fi done ac_fn_c_check_header_mongrel "$LINENO" "wchar.h" "ac_cv_header_wchar_h" "$ac_includes_default" if test "x$ac_cv_header_wchar_h" = xyes; then : HAVE_WCHAR_H="yes" else HAVE_WCHAR_H="no" fi if test "$os" = "linux"; then # Make sure kernel-headers package is installed. ac_fn_c_check_header_mongrel "$LINENO" "linux/unistd.h" "ac_cv_header_linux_unistd_h" "$ac_includes_default" if test "x$ac_cv_header_linux_unistd_h" = xyes; then : else as_fn_error $? "linux/unistd.h is not found. Please install kernel-headers/linux-userspace-headers/linux-libc-dev package." "$LINENO" 5 fi fi if test "$enable_multimon" != "no"; then ac_fn_c_check_header_compile "$LINENO" "X11/extensions/panoramiXproto.h" "ac_cv_header_X11_extensions_panoramiXproto_h" "#include #include " if test "x$ac_cv_header_X11_extensions_panoramiXproto_h" = xyes; then : else as_fn_error $? "panoramiXproto.h not found. Please configure without multimon (using --disable-multimon) or install the libXinerama devel package(s)." "$LINENO" 5 fi fi bsdPrintfWrappers=no if test "$os" = "linux"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ecvt in -lc" >&5 $as_echo_n "checking for ecvt in -lc... " >&6; } if ${ac_cv_lib_c_ecvt+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc $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 ecvt (); int main () { return ecvt (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_c_ecvt=yes else ac_cv_lib_c_ecvt=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_ecvt" >&5 $as_echo "$ac_cv_lib_c_ecvt" >&6; } if test "x$ac_cv_lib_c_ecvt" = xyes; then : bsdPrintfWrappers=yes fi fi ### ### Typdefs, structs, and compiler quarks. ### { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } if ${ac_cv_header_stdbool_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef bool "error: bool is not defined" #endif #ifndef false "error: false is not defined" #endif #if false "error: false is not 0" #endif #ifndef true "error: true is not defined" #endif #if true != 1 "error: true is not 1" #endif #ifndef __bool_true_false_are_defined "error: __bool_true_false_are_defined is not defined" #endif struct s { _Bool s: 1; _Bool t; } s; char a[true == 1 ? 1 : -1]; char b[false == 0 ? 1 : -1]; char c[__bool_true_false_are_defined == 1 ? 1 : -1]; char d[(bool) 0.5 == true ? 1 : -1]; /* See body of main program for 'e'. */ char f[(_Bool) 0.0 == false ? 1 : -1]; char g[true]; char h[sizeof (_Bool)]; char i[sizeof s.t]; enum { j = false, k = true, l = false * true, m = true * 256 }; /* The following fails for HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ _Bool n[m]; char o[sizeof n == m * sizeof n[0] ? 1 : -1]; char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; /* Catch a bug in an HP-UX C compiler. See http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html */ _Bool q = true; _Bool *pq = &q; int main () { bool e = &s; *pq |= q; *pq |= ! q; /* Refer to every declared value, to avoid compiler optimizations. */ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + !m + !n + !o + !p + !q + !pq); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdbool_h=yes else ac_cv_header_stdbool_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_stdbool_h" >&5 $as_echo "$ac_cv_header_stdbool_h" >&6; } ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" if test "x$ac_cv_type__Bool" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE__BOOL 1 _ACEOF fi if test $ac_cv_header_stdbool_h = yes; then $as_echo "@%:@define HAVE_STDBOOL_H 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 { $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 { $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" "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 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" "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" "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_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 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 { $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 working volatile" >&5 $as_echo_n "checking for working volatile... " >&6; } if ${ac_cv_c_volatile+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { volatile int x; int * volatile y = (int *) 0; return !x && !y; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_volatile=yes else ac_cv_c_volatile=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_volatile" >&5 $as_echo "$ac_cv_c_volatile" >&6; } if test $ac_cv_c_volatile = no; then $as_echo "@%:@define volatile /**/" >>confdefs.h fi ### ### Specific features and OS/arch flags / actions ### ### General flags / actions CFLAGS="$CFLAGS -Wall" CFLAGS="$CFLAGS -Werror" # -Wno-unknown-pragmas is due to gcc not understanding '#pragma ident' in Xlib.h on OpenSolaris. for TEST_CFLAG in -Wno-pointer-sign -Wno-unused-value -fno-strict-aliasing \ -Wno-unknown-pragmas -Wno-uninitialized; do { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC flag $TEST_CFLAG" >&5 $as_echo_n "checking for GCC flag $TEST_CFLAG... " >&6; } ORIGINAL_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $TEST_CFLAG" NEW_CFLAG="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : NEW_CFLAG=" $TEST_CFLAG" { $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 CFLAGS="$ORIGINAL_CFLAGS$NEW_CFLAG" done CPPFLAGS="$CPPFLAGS -DVMX86_TOOLS" CPPFLAGS="$CPPFLAGS" # -fvisibility is used by "core service" plugins, but not required. ORIGINAL_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fvisibility=hidden" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC flag -fvisibility" >&5 $as_echo_n "checking for GCC flag -fvisibility... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : PLUGIN_CPPFLAGS="-fvisibility=hidden -DGCC_EXPLICIT_EXPORT"; { $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 CFLAGS="$ORIGINAL_CFLAGS" # Detect "unused-but-set-variable" gcc warning and disable it. ORIGINAL_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Wno-unused-but-set-variable" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC flag -Wno-unused-but-set-variable" >&5 $as_echo_n "checking for GCC flag -Wno-unused-but-set-variable... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ORIGINAL_CFLAGS="$ORIGINAL_CFLAGS -Wno-unused-but-set-variable"; { $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 CFLAGS="$ORIGINAL_CFLAGS" BUILDDIR="`pwd`" INCLUDE_DIR="`cd $srcdir; pwd`/lib/include" BLD_INCLUDE_DIR="$BUILDDIR/lib/include" CPPFLAGS="-I$INCLUDE_DIR -I$BLD_INCLUDE_DIR $CPPFLAGS" ### ### Documentation. ### if test "$enable_docs" = "yes"; then # Extract the first word of "doxygen", so it can be a program name with args. set dummy doxygen; 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_have_doxygen+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$have_doxygen"; then ac_cv_prog_have_doxygen="$have_doxygen" # 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_have_doxygen="yes" $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_prog_have_doxygen" && ac_cv_prog_have_doxygen="no" fi fi have_doxygen=$ac_cv_prog_have_doxygen if test -n "$have_doxygen"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_doxygen" >&5 $as_echo "$have_doxygen" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$have_doxygen" = "no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: doxygen not found; API documentation will not be generated." >&5 $as_echo "$as_me: WARNING: doxygen not found; API documentation will not be generated." >&2;} else # Extract the first word of "dot", so it can be a program name with args. set dummy dot; 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_DOT+:} false; then : $as_echo_n "(cached) " >&6 else case $DOT in [\\/]* | ?:[\\/]*) ac_cv_path_DOT="$DOT" # 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_DOT="$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 DOT=$ac_cv_path_DOT if test -n "$DOT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOT" >&5 $as_echo "$DOT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$DOT" = ""; then HAVE_DOT=NO else DOT=`dirname $DOT` HAVE_DOT=YES fi # Extract the first word of "mscgen", so it can be a program name with args. set dummy mscgen; 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_MSCGEN+:} false; then : $as_echo_n "(cached) " >&6 else case $MSCGEN in [\\/]* | ?:[\\/]*) ac_cv_path_MSCGEN="$MSCGEN" # 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_MSCGEN="$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_MSCGEN" && ac_cv_path_MSCGEN="no" ;; esac fi MSCGEN=$ac_cv_path_MSCGEN if test -n "$MSCGEN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSCGEN" >&5 $as_echo "$MSCGEN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$MSCGEN" != "no"; then MSCGEN_DIR="`dirname $MSCGEN`" else MSCGEN_DIR= fi fi fi ### ### OS/arch-specific flags / actions ### MODULES="" MODULES_OS="$os" TARGET_OS="$os" MODULES_DIR="" buildHgfsmounter=no if test "$have_glib_2_14" = "yes"; then CPPFLAGS="$CPPFLAGS -DHAVE_GLIB_REGEX" fi if test "$os" = "linux"; then MODULES_DIR="$LINUXDIR/kernel/" CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64" CPPFLAGS="$CPPFLAGS -D_LARGEFILE64_SOURCE" CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=500" CPPFLAGS="$CPPFLAGS -D_BSD_SOURCE" CPPFLAGS="$CPPFLAGS -D_SVID_SOURCE" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lrt" MODULES="$MODULES vmsync vmci vsock" MODULES="$MODULES vmxnet vmblock vmhgfs" buildHgfsmounter=yes fi if test "$os" = "freebsd"; then LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lkvm" MODULES_DIR="/boot/modules" if test "$osVersion" -ge 302000; then MODULES="$MODULES vmmemctl" fi if test "$osVersion" -ge 409000; then MODULES="$MODULES vmxnet" fi if test "$osVersion" -ge 600000; then MODULES="$MODULES vmblock vmhgfs" buildHgfsmounter=yes fi if test "$with_kernel_modules" = "yes"; then echo "****************************************************************" echo " You are building FreeBSD kernel modules. Make sure you use " echo " 'make' to build open-vm-tools, and not GNU make ('gmake'). " echo "****************************************************************" fi fi if test "$os" = "solaris"; then LIB_IMPERSONATE_CPPFLAGS="$LIB_IMPERSONATE_CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS" LIB_USER_CPPFLAGS="$LIB_USER_CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lsocket" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lnsl" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lresolv" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lrpcsvc" # Setup defines to identify the OS version. if test "$osVersion" -eq 509000; then CPPFLAGS="$CPPFLAGS -DSOL9" fi if test "$osVersion" -eq 510000; then CPPFLAGS="$CPPFLAGS -DSOL10" fi if test "$osVersion" -eq 511000; then CPPFLAGS="$CPPFLAGS -DSOL11" fi MODULES="$MODULES vmxnet vmmemctl" # HGFS and vmblock need Solaris 10 at least. if test "$osVersion" -ge 510000; then MODULES="$MODULES vmhgfs vmblock" fi # vmxnet3 is built on Solaris 10 / 11 only if GLDv3 is installed. if test "$osVersion" -gt 510000; then ac_fn_c_check_header_mongrel "$LINENO" "sys/mac.h" "ac_cv_header_sys_mac_h" "$ac_includes_default" if test "x$ac_cv_header_sys_mac_h" = xyes; then : MODULES="$MODULES vmxnet3" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GLDv3 (sys/mac.h) is not installed, vmxnet3 will not be compiled." >&5 $as_echo "$as_me: WARNING: GLDv3 (sys/mac.h) is not installed, vmxnet3 will not be compiled." >&2;} fi fi if test "$with_kernel_modules" = "yes"; then echo "****************************************************************" echo " You are building Solaris kernel modules. Make sure you use " echo " GNU make to build open-vm-tools. " echo "****************************************************************" fi fi if test "$buildHgfsmounter" = "yes"; then BUILD_HGFSMOUNTER_TRUE= BUILD_HGFSMOUNTER_FALSE='#' else BUILD_HGFSMOUNTER_TRUE='#' BUILD_HGFSMOUNTER_FALSE= fi if test "$os" = "linux"; then LINUX_TRUE= LINUX_FALSE='#' else LINUX_TRUE='#' LINUX_FALSE= fi if test "$os" = "solaris"; then SOLARIS_TRUE= SOLARIS_FALSE='#' else SOLARIS_TRUE='#' SOLARIS_FALSE= fi if test "$os" = "freebsd"; then FREEBSD_TRUE= FREEBSD_FALSE='#' else FREEBSD_TRUE='#' FREEBSD_FALSE= fi if test "$os" = "freebsd" -a -n "$SYSDIR"; then FREEBSD_CUSTOM_SYSDIR_TRUE= FREEBSD_CUSTOM_SYSDIR_FALSE='#' else FREEBSD_CUSTOM_SYSDIR_TRUE='#' FREEBSD_CUSTOM_SYSDIR_FALSE= fi if test "$userSpaceBitness" = "32"; then THIRTY_TWO_BIT_USERSPACE_TRUE= THIRTY_TWO_BIT_USERSPACE_FALSE='#' else THIRTY_TWO_BIT_USERSPACE_TRUE='#' THIRTY_TWO_BIT_USERSPACE_FALSE= fi if test "$have_x" = "yes"; then HAVE_X11_TRUE= HAVE_X11_FALSE='#' else HAVE_X11_TRUE='#' HAVE_X11_FALSE= fi if test "$with_icu" = "yes"; then HAVE_ICU_TRUE= HAVE_ICU_FALSE='#' else HAVE_ICU_TRUE='#' HAVE_ICU_FALSE= fi if test "$with_kernel_modules" = "yes"; then WITH_KERNEL_MODULES_TRUE= WITH_KERNEL_MODULES_FALSE='#' else WITH_KERNEL_MODULES_TRUE='#' WITH_KERNEL_MODULES_FALSE= fi if test "$have_xsm" = "yes"; then HAVE_XSM_TRUE= HAVE_XSM_FALSE='#' else HAVE_XSM_TRUE='#' HAVE_XSM_FALSE= fi if test "$have_xcomposite" = "yes"; then HAVE_XCOMPOSITE_TRUE= HAVE_XCOMPOSITE_FALSE='#' else HAVE_XCOMPOSITE_TRUE='#' HAVE_XCOMPOSITE_FALSE= fi if test "$have_cunit" = "yes"; then ENABLE_TESTS_TRUE= ENABLE_TESTS_FALSE='#' else ENABLE_TESTS_TRUE='#' ENABLE_TESTS_FALSE= fi if test "$with_root_privileges" = "yes"; then WITH_ROOT_PRIVILEGES_TRUE= WITH_ROOT_PRIVILEGES_FALSE='#' else WITH_ROOT_PRIVILEGES_TRUE='#' WITH_ROOT_PRIVILEGES_FALSE= fi if test "$have_dnet" = "yes"; then HAVE_DNET_TRUE= HAVE_DNET_FALSE='#' else HAVE_DNET_TRUE='#' HAVE_DNET_FALSE= fi if test "$have_doxygen" = "yes"; then HAVE_DOXYGEN_TRUE= HAVE_DOXYGEN_FALSE='#' else HAVE_DOXYGEN_TRUE='#' HAVE_DOXYGEN_FALSE= fi if test "$have_fuse" = "yes"; then HAVE_FUSE_TRUE= HAVE_FUSE_FALSE='#' else HAVE_FUSE_TRUE='#' HAVE_FUSE_FALSE= fi if test "$with_gnu_ld" = "yes"; then HAVE_GNU_LD_TRUE= HAVE_GNU_LD_FALSE='#' else HAVE_GNU_LD_TRUE='#' HAVE_GNU_LD_FALSE= fi if test "$have_x" = "yes" -a "$with_gtkmm" = "yes"; then HAVE_GTKMM_TRUE= HAVE_GTKMM_FALSE='#' else HAVE_GTKMM_TRUE='#' HAVE_GTKMM_FALSE= fi if test "$with_pam" = "yes"; then HAVE_PAM_TRUE= HAVE_PAM_FALSE='#' else HAVE_PAM_TRUE='#' HAVE_PAM_FALSE= fi if test "os" = "linux" -a "$have_glib_2_14" = "yes"; then USE_SLASH_PROC_TRUE= USE_SLASH_PROC_FALSE='#' else USE_SLASH_PROC_TRUE='#' USE_SLASH_PROC_FALSE= fi if test "$bsdPrintfWrappers" = "yes"; then USE_PRINTF_WRAPPERS_TRUE= USE_PRINTF_WRAPPERS_FALSE='#' else USE_PRINTF_WRAPPERS_TRUE='#' USE_PRINTF_WRAPPERS_FALSE= fi if test "$have_xsm" != "yes"; then $as_echo "@%:@define NO_XSM 1" >>confdefs.h fi if test "$have_xcomposite" != "yes"; then $as_echo "@%:@define NO_XCOMPOSITE 1" >>confdefs.h fi ### Feature-specific flags / actions # Combine where possible # If control reaches this point and multimon is still enabled, then we know # all of the tests for required components have passed and it's safe to allow # multimon. Otherwise, it should be disabled. if test "$enable_multimon" = "no"; then # XXX: For consistency, change this to ENABLE_MULTIMON. This will require # some additional code cleanup. $as_echo "@%:@define NO_MULTIMON 1" >>confdefs.h fi LIB_AUTH_CPPFLAGS="$LIB_AUTH_CPPFLAGS $PAM_CPPFLAGS" if test "$HAVE_CRYPT" = "yes"; then LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lcrypt" VIX_LIBADD="$VIX_LIBADD -lcrypt" fi LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD $THREAD_LIB" VIX_LIBADD="$VIX_LIBADD $THREAD_LIB" ### Core Services definitions. HGFS_LIBS="$BUILDDIR/libhgfs/libhgfs.la" VMTOOLS_LIBS="$BUILDDIR/libvmtools/libvmtools.la $GLIB2_LIBS" VMTOOLS_CPPFLAGS="-DVMTOOLS_USE_GLIB $GLIB2_CPPFLAGS" PLUGIN_CPPFLAGS="$VMTOOLS_CPPFLAGS $PLUGIN_CPPFLAGS" PLUGIN_LDFLAGS="-Wl,-z,defs -Wl,-lc -shared -module -avoid-version" # In Solaris, the XDR-related functions are not in libc like in Linux and # FreeBSD, so binaries need to be linked to some extra libraries. XDR_LIBS= if test "$os" = "solaris"; then XDR_LIBS="-lnsl -lrpcsvc" fi # Installation directories for core services plugins. TEST_PLUGIN_INSTALLDIR=$datadir/open-vm-tools/tests COMMON_PLUGIN_INSTALLDIR=$libdir/open-vm-tools/plugins/common VMSVC_PLUGIN_INSTALLDIR=$libdir/open-vm-tools/plugins/vmsvc VMUSR_PLUGIN_INSTALLDIR=$libdir/open-vm-tools/plugins/vmusr # General definitions INSTVMSG='$(SHELL) $(top_srcdir)/scripts/build/instvmsg.sh' RPCGEN_WRAPPER='$(SHELL) $(top_builddir)/scripts/build/rpcgen_wrapper.sh' ### General substs if test "$os" = "freebsd" -a -n "$SYSDIR"; then # If SYSDIR is not defined, AC_SUBST expands to nothing, so we need something # inside this block. true fi ### Lib substs ### Program substs ### ### Create the Makefiles ### ac_config_files="$ac_config_files Makefile lib/Makefile lib/appUtil/Makefile lib/auth/Makefile lib/backdoor/Makefile lib/dict/Makefile lib/dynxdr/Makefile lib/err/Makefile lib/file/Makefile lib/foundryMsg/Makefile lib/glibUtils/Makefile lib/guestApp/Makefile lib/guestRpc/Makefile lib/hgfs/Makefile lib/hgfsBd/Makefile lib/hgfsHelper/Makefile lib/hgfsServer/Makefile lib/hgfsServerManagerGuest/Makefile lib/hgfsServerPolicyGuest/Makefile lib/impersonate/Makefile lib/lock/Makefile lib/message/Makefile lib/misc/Makefile lib/netUtil/Makefile lib/panic/Makefile lib/panicDefault/Makefile lib/printer/Makefile lib/procMgr/Makefile lib/rpcChannel/Makefile lib/rpcIn/Makefile lib/rpcOut/Makefile lib/rpcVmx/Makefile lib/slashProc/Makefile lib/string/Makefile lib/stubs/Makefile lib/syncDriver/Makefile lib/system/Makefile lib/unicode/Makefile lib/user/Makefile lib/vmCheck/Makefile lib/vmSignal/Makefile lib/wiper/Makefile lib/xdg/Makefile services/Makefile services/vmtoolsd/Makefile services/plugins/Makefile services/plugins/desktopEvents/Makefile services/plugins/dndcp/Makefile services/plugins/guestInfo/Makefile services/plugins/guestInfo/getlib/Makefile services/plugins/hgfsServer/Makefile services/plugins/powerOps/Makefile services/plugins/resolutionSet/Makefile services/plugins/timeSync/Makefile services/plugins/vix/Makefile services/plugins/vmbackup/Makefile vmware-user-suid-wrapper/Makefile toolbox/Makefile hgfsclient/Makefile hgfsmounter/Makefile checkvm/Makefile rpctool/Makefile libguestlib/Makefile libguestlib/vmguestlib.pc libhgfs/Makefile libvmtools/Makefile xferlogs/Makefile modules/Makefile vmblock-fuse/Makefile vmblockmounter/Makefile tests/Makefile tests/vmrpcdbg/Makefile tests/testDebug/Makefile tests/testPlugin/Makefile tests/testVmblock/Makefile docs/Makefile docs/api/Makefile scripts/Makefile scripts/build/rpcgen_wrapper.sh" ### ### Output ### 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}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIB@&t@OBJS; 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 LIB@&t@OBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_HGFSMOUNTER_TRUE}" && test -z "${BUILD_HGFSMOUNTER_FALSE}"; then as_fn_error $? "conditional \"BUILD_HGFSMOUNTER\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${LINUX_TRUE}" && test -z "${LINUX_FALSE}"; then as_fn_error $? "conditional \"LINUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${SOLARIS_TRUE}" && test -z "${SOLARIS_FALSE}"; then as_fn_error $? "conditional \"SOLARIS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${FREEBSD_TRUE}" && test -z "${FREEBSD_FALSE}"; then as_fn_error $? "conditional \"FREEBSD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${FREEBSD_CUSTOM_SYSDIR_TRUE}" && test -z "${FREEBSD_CUSTOM_SYSDIR_FALSE}"; then as_fn_error $? "conditional \"FREEBSD_CUSTOM_SYSDIR\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${THIRTY_TWO_BIT_USERSPACE_TRUE}" && test -z "${THIRTY_TWO_BIT_USERSPACE_FALSE}"; then as_fn_error $? "conditional \"THIRTY_TWO_BIT_USERSPACE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_X11_TRUE}" && test -z "${HAVE_X11_FALSE}"; then as_fn_error $? "conditional \"HAVE_X11\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_ICU_TRUE}" && test -z "${HAVE_ICU_FALSE}"; then as_fn_error $? "conditional \"HAVE_ICU\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_KERNEL_MODULES_TRUE}" && test -z "${WITH_KERNEL_MODULES_FALSE}"; then as_fn_error $? "conditional \"WITH_KERNEL_MODULES\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_XSM_TRUE}" && test -z "${HAVE_XSM_FALSE}"; then as_fn_error $? "conditional \"HAVE_XSM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_XCOMPOSITE_TRUE}" && test -z "${HAVE_XCOMPOSITE_FALSE}"; then as_fn_error $? "conditional \"HAVE_XCOMPOSITE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_TESTS_TRUE}" && test -z "${ENABLE_TESTS_FALSE}"; then as_fn_error $? "conditional \"ENABLE_TESTS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_ROOT_PRIVILEGES_TRUE}" && test -z "${WITH_ROOT_PRIVILEGES_FALSE}"; then as_fn_error $? "conditional \"WITH_ROOT_PRIVILEGES\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_DNET_TRUE}" && test -z "${HAVE_DNET_FALSE}"; then as_fn_error $? "conditional \"HAVE_DNET\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_DOXYGEN_TRUE}" && test -z "${HAVE_DOXYGEN_FALSE}"; then as_fn_error $? "conditional \"HAVE_DOXYGEN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_FUSE_TRUE}" && test -z "${HAVE_FUSE_FALSE}"; then as_fn_error $? "conditional \"HAVE_FUSE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_GNU_LD_TRUE}" && test -z "${HAVE_GNU_LD_FALSE}"; then as_fn_error $? "conditional \"HAVE_GNU_LD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_GTKMM_TRUE}" && test -z "${HAVE_GTKMM_FALSE}"; then as_fn_error $? "conditional \"HAVE_GTKMM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_PAM_TRUE}" && test -z "${HAVE_PAM_FALSE}"; then as_fn_error $? "conditional \"HAVE_PAM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${USE_SLASH_PROC_TRUE}" && test -z "${USE_SLASH_PROC_FALSE}"; then as_fn_error $? "conditional \"USE_SLASH_PROC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${USE_PRINTF_WRAPPERS_TRUE}" && test -z "${USE_PRINTF_WRAPPERS_FALSE}"; then as_fn_error $? "conditional \"USE_PRINTF_WRAPPERS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${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 @S|@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 @S|@? 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 @S|@as_val. Take advantage of shells that can avoid forks. The arguments @%:@ must be portable across @S|@(()) 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 "@S|@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 open-vm-tools $as_me 9.4.0, 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 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" 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 Configuration files: $config_files Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ open-vm-tools config.status 9.4.0 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' MKDIR_P='$MKDIR_P' 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;; --he | --h | --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 # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # 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' _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 "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; "lib/appUtil/Makefile") CONFIG_FILES="$CONFIG_FILES lib/appUtil/Makefile" ;; "lib/auth/Makefile") CONFIG_FILES="$CONFIG_FILES lib/auth/Makefile" ;; "lib/backdoor/Makefile") CONFIG_FILES="$CONFIG_FILES lib/backdoor/Makefile" ;; "lib/dict/Makefile") CONFIG_FILES="$CONFIG_FILES lib/dict/Makefile" ;; "lib/dynxdr/Makefile") CONFIG_FILES="$CONFIG_FILES lib/dynxdr/Makefile" ;; "lib/err/Makefile") CONFIG_FILES="$CONFIG_FILES lib/err/Makefile" ;; "lib/file/Makefile") CONFIG_FILES="$CONFIG_FILES lib/file/Makefile" ;; "lib/foundryMsg/Makefile") CONFIG_FILES="$CONFIG_FILES lib/foundryMsg/Makefile" ;; "lib/glibUtils/Makefile") CONFIG_FILES="$CONFIG_FILES lib/glibUtils/Makefile" ;; "lib/guestApp/Makefile") CONFIG_FILES="$CONFIG_FILES lib/guestApp/Makefile" ;; "lib/guestRpc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/guestRpc/Makefile" ;; "lib/hgfs/Makefile") CONFIG_FILES="$CONFIG_FILES lib/hgfs/Makefile" ;; "lib/hgfsBd/Makefile") CONFIG_FILES="$CONFIG_FILES lib/hgfsBd/Makefile" ;; "lib/hgfsHelper/Makefile") CONFIG_FILES="$CONFIG_FILES lib/hgfsHelper/Makefile" ;; "lib/hgfsServer/Makefile") CONFIG_FILES="$CONFIG_FILES lib/hgfsServer/Makefile" ;; "lib/hgfsServerManagerGuest/Makefile") CONFIG_FILES="$CONFIG_FILES lib/hgfsServerManagerGuest/Makefile" ;; "lib/hgfsServerPolicyGuest/Makefile") CONFIG_FILES="$CONFIG_FILES lib/hgfsServerPolicyGuest/Makefile" ;; "lib/impersonate/Makefile") CONFIG_FILES="$CONFIG_FILES lib/impersonate/Makefile" ;; "lib/lock/Makefile") CONFIG_FILES="$CONFIG_FILES lib/lock/Makefile" ;; "lib/message/Makefile") CONFIG_FILES="$CONFIG_FILES lib/message/Makefile" ;; "lib/misc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/misc/Makefile" ;; "lib/netUtil/Makefile") CONFIG_FILES="$CONFIG_FILES lib/netUtil/Makefile" ;; "lib/panic/Makefile") CONFIG_FILES="$CONFIG_FILES lib/panic/Makefile" ;; "lib/panicDefault/Makefile") CONFIG_FILES="$CONFIG_FILES lib/panicDefault/Makefile" ;; "lib/printer/Makefile") CONFIG_FILES="$CONFIG_FILES lib/printer/Makefile" ;; "lib/procMgr/Makefile") CONFIG_FILES="$CONFIG_FILES lib/procMgr/Makefile" ;; "lib/rpcChannel/Makefile") CONFIG_FILES="$CONFIG_FILES lib/rpcChannel/Makefile" ;; "lib/rpcIn/Makefile") CONFIG_FILES="$CONFIG_FILES lib/rpcIn/Makefile" ;; "lib/rpcOut/Makefile") CONFIG_FILES="$CONFIG_FILES lib/rpcOut/Makefile" ;; "lib/rpcVmx/Makefile") CONFIG_FILES="$CONFIG_FILES lib/rpcVmx/Makefile" ;; "lib/slashProc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/slashProc/Makefile" ;; "lib/string/Makefile") CONFIG_FILES="$CONFIG_FILES lib/string/Makefile" ;; "lib/stubs/Makefile") CONFIG_FILES="$CONFIG_FILES lib/stubs/Makefile" ;; "lib/syncDriver/Makefile") CONFIG_FILES="$CONFIG_FILES lib/syncDriver/Makefile" ;; "lib/system/Makefile") CONFIG_FILES="$CONFIG_FILES lib/system/Makefile" ;; "lib/unicode/Makefile") CONFIG_FILES="$CONFIG_FILES lib/unicode/Makefile" ;; "lib/user/Makefile") CONFIG_FILES="$CONFIG_FILES lib/user/Makefile" ;; "lib/vmCheck/Makefile") CONFIG_FILES="$CONFIG_FILES lib/vmCheck/Makefile" ;; "lib/vmSignal/Makefile") CONFIG_FILES="$CONFIG_FILES lib/vmSignal/Makefile" ;; "lib/wiper/Makefile") CONFIG_FILES="$CONFIG_FILES lib/wiper/Makefile" ;; "lib/xdg/Makefile") CONFIG_FILES="$CONFIG_FILES lib/xdg/Makefile" ;; "services/Makefile") CONFIG_FILES="$CONFIG_FILES services/Makefile" ;; "services/vmtoolsd/Makefile") CONFIG_FILES="$CONFIG_FILES services/vmtoolsd/Makefile" ;; "services/plugins/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/Makefile" ;; "services/plugins/desktopEvents/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/desktopEvents/Makefile" ;; "services/plugins/dndcp/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/dndcp/Makefile" ;; "services/plugins/guestInfo/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/guestInfo/Makefile" ;; "services/plugins/guestInfo/getlib/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/guestInfo/getlib/Makefile" ;; "services/plugins/hgfsServer/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/hgfsServer/Makefile" ;; "services/plugins/powerOps/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/powerOps/Makefile" ;; "services/plugins/resolutionSet/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/resolutionSet/Makefile" ;; "services/plugins/timeSync/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/timeSync/Makefile" ;; "services/plugins/vix/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/vix/Makefile" ;; "services/plugins/vmbackup/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/vmbackup/Makefile" ;; "vmware-user-suid-wrapper/Makefile") CONFIG_FILES="$CONFIG_FILES vmware-user-suid-wrapper/Makefile" ;; "toolbox/Makefile") CONFIG_FILES="$CONFIG_FILES toolbox/Makefile" ;; "hgfsclient/Makefile") CONFIG_FILES="$CONFIG_FILES hgfsclient/Makefile" ;; "hgfsmounter/Makefile") CONFIG_FILES="$CONFIG_FILES hgfsmounter/Makefile" ;; "checkvm/Makefile") CONFIG_FILES="$CONFIG_FILES checkvm/Makefile" ;; "rpctool/Makefile") CONFIG_FILES="$CONFIG_FILES rpctool/Makefile" ;; "libguestlib/Makefile") CONFIG_FILES="$CONFIG_FILES libguestlib/Makefile" ;; "libguestlib/vmguestlib.pc") CONFIG_FILES="$CONFIG_FILES libguestlib/vmguestlib.pc" ;; "libhgfs/Makefile") CONFIG_FILES="$CONFIG_FILES libhgfs/Makefile" ;; "libvmtools/Makefile") CONFIG_FILES="$CONFIG_FILES libvmtools/Makefile" ;; "xferlogs/Makefile") CONFIG_FILES="$CONFIG_FILES xferlogs/Makefile" ;; "modules/Makefile") CONFIG_FILES="$CONFIG_FILES modules/Makefile" ;; "vmblock-fuse/Makefile") CONFIG_FILES="$CONFIG_FILES vmblock-fuse/Makefile" ;; "vmblockmounter/Makefile") CONFIG_FILES="$CONFIG_FILES vmblockmounter/Makefile" ;; "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; "tests/vmrpcdbg/Makefile") CONFIG_FILES="$CONFIG_FILES tests/vmrpcdbg/Makefile" ;; "tests/testDebug/Makefile") CONFIG_FILES="$CONFIG_FILES tests/testDebug/Makefile" ;; "tests/testPlugin/Makefile") CONFIG_FILES="$CONFIG_FILES tests/testPlugin/Makefile" ;; "tests/testVmblock/Makefile") CONFIG_FILES="$CONFIG_FILES tests/testVmblock/Makefile" ;; "docs/Makefile") CONFIG_FILES="$CONFIG_FILES docs/Makefile" ;; "docs/api/Makefile") CONFIG_FILES="$CONFIG_FILES docs/api/Makefile" ;; "scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;; "scripts/build/rpcgen_wrapper.sh") CONFIG_FILES="$CONFIG_FILES scripts/build/rpcgen_wrapper.sh" ;; *) 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_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 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 { 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 = "" } { 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 } print line } _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" eval set X " :F $CONFIG_FILES :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 ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; 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 s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$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 ;; :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 "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "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 ;; 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 open-vm-tools-9.4.0-1280544/autom4te.cache/output.20000644765153500003110000300566312220061615017677 0ustar dtormts@%:@! /bin/sh @%:@ Guess values for system-dependent variables and create Makefiles. @%:@ Generated by GNU Autoconf 2.69 for open-vm-tools 9.4.0. @%:@ @%:@ Report bugs to . @%:@ @%:@ @%:@ 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 and $0: open-vm-tools-devel@lists.sourceforge.net about your $0: system, 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 @S|@? 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 "@S|@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 @S|@as_val. Take advantage of shells that can avoid forks. The arguments @%:@ must be portable across @S|@(()) 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 @S|@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=. LIB@&t@OBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='open-vm-tools' PACKAGE_TARNAME='open-vm-tools' PACKAGE_VERSION='9.4.0' PACKAGE_STRING='open-vm-tools 9.4.0' PACKAGE_BUGREPORT='open-vm-tools-devel@lists.sourceforge.net' PACKAGE_URL='' ac_unique_file="checkvm/checkvm.c" # 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_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIB@&t@OBJS VIX_LIBADD LIBVMTOOLS_LIBADD LIB_USER_CPPFLAGS LIB_IMPERSONATE_CPPFLAGS LIB_AUTH_CPPFLAGS RPCGEN_WRAPPER INSTVMSG SYSDIR VMUSR_PLUGIN_INSTALLDIR VMSVC_PLUGIN_INSTALLDIR COMMON_PLUGIN_INSTALLDIR TEST_PLUGIN_INSTALLDIR XDR_LIBS RPCGENFLAGS VMTOOLS_LIBS VMTOOLS_CPPFLAGS PLUGIN_LDFLAGS PLUGIN_CPPFLAGS PAM_PREFIX XCOMPOSITE_LIBS XSM_LIBS COMMON_XLIBS MODULES MODULES_DIR MODULES_OS LINUXINCLUDE KERNEL_RELEASE TARGET_OS TOOLS_VERSION HGFS_LIBS USE_PRINTF_WRAPPERS_FALSE USE_PRINTF_WRAPPERS_TRUE USE_SLASH_PROC_FALSE USE_SLASH_PROC_TRUE HAVE_PAM_FALSE HAVE_PAM_TRUE HAVE_GTKMM_FALSE HAVE_GTKMM_TRUE HAVE_GNU_LD_FALSE HAVE_GNU_LD_TRUE HAVE_FUSE_FALSE HAVE_FUSE_TRUE HAVE_DOXYGEN_FALSE HAVE_DOXYGEN_TRUE HAVE_DNET_FALSE HAVE_DNET_TRUE WITH_ROOT_PRIVILEGES_FALSE WITH_ROOT_PRIVILEGES_TRUE ENABLE_TESTS_FALSE ENABLE_TESTS_TRUE HAVE_XCOMPOSITE_FALSE HAVE_XCOMPOSITE_TRUE HAVE_XSM_FALSE HAVE_XSM_TRUE WITH_KERNEL_MODULES_FALSE WITH_KERNEL_MODULES_TRUE HAVE_ICU_FALSE HAVE_ICU_TRUE HAVE_X11_FALSE HAVE_X11_TRUE THIRTY_TWO_BIT_USERSPACE_FALSE THIRTY_TWO_BIT_USERSPACE_TRUE FREEBSD_CUSTOM_SYSDIR_FALSE FREEBSD_CUSTOM_SYSDIR_TRUE FREEBSD_FALSE FREEBSD_TRUE SOLARIS_FALSE SOLARIS_TRUE LINUX_FALSE LINUX_TRUE BUILD_HGFSMOUNTER_FALSE BUILD_HGFSMOUNTER_TRUE MSCGEN_DIR MSCGEN HAVE_DOT DOT have_doxygen RPCGEN ICU_LIBS ICU_CPPFLAGS have_cxx DNET_LIBS DNET_CPPFLAGS PROCPS_LIBS PROCPS_CPPFLAGS GTKMM_LIBS GTKMM_CPPFLAGS GTK_LIBS GTK_CPPFLAGS CUNIT_LIBS CUNIT_CPPFLAGS PAM_LIBS PAM_CPPFLAGS FUSE_LIBS FUSE_CPPFLAGS have_genmarshal GTHREAD_LIBS GTHREAD_CPPFLAGS GOBJECT_LIBS GOBJECT_CPPFLAGS GMODULE_LIBS GMODULE_CPPFLAGS GLIB2_LIBS GLIB2_CPPFLAGS ac_vmw_lib_cfg X_EXTRA_LIBS X_LIBS X_PRE_LIBS X_CFLAGS XMKMF HAVE_PKG_CONFIG CXXCPP OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR DLLTOOL OBJDUMP NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP LIBTOOL LN_S SED am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM host_os host_vendor host_cpu host build_os build_vendor build_cpu build 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='' ac_user_opts=' enable_option_checking with_root_privileges with_kernel_modules with_kernel_release with_linuxdir enable_multimon with_gtk2 with_gtkmm enable_docs enable_tests enable_dependency_tracking enable_shared enable_static with_pic enable_fast_install with_gnu_ld with_sysroot enable_libtool_lock with_x with_pam with_pam_prefix with_procps with_dnet with_icu ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP CXX CXXFLAGS CCC 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 open-vm-tools 9.4.0 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 @<:@@S|@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/open-vm-tools@:>@ --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names 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 open-vm-tools 9.4.0:";; 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] --disable-multimon disables multimon, enabled by default --disable-docs disables generation of API documentation; by default, docs are built if doxygen is available. --disable-tests disable compilation of test code. --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-shared@<:@=PKGS@:>@ build shared libraries @<:@default=yes@:>@ --enable-static@<:@=PKGS@:>@ build static libraries @<:@default=yes@:>@ --enable-fast-install@<:@=PKGS@:>@ optimize for fast installation @<:@default=yes@:>@ --disable-libtool-lock avoid locking (might break parallel builds) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --without-root-privileges does not perform any operations that require root privileges --without-kernel-modules does not compile or install the kernel modules --with-kernel-release specifies the kernel release you want to build against --with-linuxdir specifies the Linux directory you want to use --without-gtk2 compiles without Gtk 2.0 --without-gtkmm compiles without Gtkmm, sigc++, and related libs --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-x use the X Window System --without-pam compiles without PAM support. --with-pam-prefix specifies where pam files go. Default is @S|@(sysconfdir) --without-procps compiles without libproc (disables support for meminfo) --without-dnet compiles without libdnet (disables support for nicinfo) --without-icu disables support for ICU 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 CPP C preprocessor CXX C++ compiler command CXXFLAGS C++ compiler flags 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 . _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 open-vm-tools configure 9.4.0 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.@S|@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_c_try_cpp LINENO @%:@ ---------------------- @%:@ Try to preprocess conftest.@S|@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_cxx_try_compile LINENO @%:@ ---------------------------- @%:@ Try to compile conftest.@S|@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_link LINENO @%:@ ----------------------- @%:@ Try to link conftest.@S|@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.@S|@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.@S|@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.@S|@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_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;} ( $as_echo "## -------------------------------------------------------- ## ## Report this to open-vm-tools-devel@lists.sourceforge.net ## ## -------------------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&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_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;} ( $as_echo "## -------------------------------------------------------- ## ## Report this to open-vm-tools-devel@lists.sourceforge.net ## ## -------------------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&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 @%:@ 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_member LINENO AGGR MEMBER VAR INCLUDES @%:@ ---------------------------------------------------- @%:@ Tries to find if the field MEMBER exists in type AGGR, after including @%:@ INCLUDES, setting cache variable VAR accordingly. ac_fn_c_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$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 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 open-vm-tools $as_me 9.4.0, 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 # 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 # In order to make this configure script auto-detect situations where # people have a 32-bit userland running with a 64-bit kernel, we try to ask # the compiler (assumedly gcc) for its default Target:. # We have to set up $TEST_CC manually, since AC_PROG_CC hasn't yet been run (and can't be until AC_CANONICAL_HOST & AC_CANONICAL_BUILD are run) # The purpose of all this is to set up $host_alias/$build_alias in a more # intelligent way than config.guess currently does. TEST_CC="$CC_FOR_BUILD" test -z "$TEST_CC" && TEST_CC="$HOST_CC" test -z "$TEST_CC" && TEST_CC="$CC" if test -n "$TEST_CC" -a -z "$host_alias"; then host_alias="`$TEST_CC -dumpmachine`" if test -z "$build_alias" -a -n "$host_alias"; then build_alias="$host_alias" fi fi unset TEST_CC # checkvm/checkvm.c has no special significance - we just need to pass in a file that # helps autoconf verify that it really has found the source tree. # Keep the top-level directory tidy by putting auxiliary build tools and local # macros in separate subdirectories. ac_aux_dir= for ac_dir in config "$srcdir"/config; 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 config \"$srcdir\"/config" "$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. # 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 # Quote the regular expressions case "$host_cpu" in i[3456]86) userSpaceBitness="32" ;; x86_64) userSpaceBitness="64" ;; *) as_fn_error $? "Unknown architecture." "$LINENO" 5 ;; esac # Operational arguments. @%:@ Check whether --with-root-privileges was given. if test "${with_root_privileges+set}" = set; then : withval=$with_root_privileges; else with_root_privileges=yes fi # Kernel arguments. # The kernel args have to go here otherwise the KERNEL_RELEASE won't be visible # to getOsVersion() @%:@ Check whether --with-kernel-modules was given. if test "${with_kernel_modules+set}" = set; then : withval=$with_kernel_modules; else with_kernel_modules=yes fi @%:@ Check whether --with-kernel-release was given. if test "${with_kernel_release+set}" = set; then : withval=$with_kernel_release; KERNEL_RELEASE="$withval" else KERNEL_RELEASE=`uname -r` fi @%:@ Check whether --with-linuxdir was given. if test "${with_linuxdir+set}" = set; then : withval=$with_linuxdir; LINUXDIR="$withval" else LINUXDIR=/lib/modules/$KERNEL_RELEASE fi # Turn the uname output into something we can run comparisons on. getOsVersion() { major_version="`echo $KERNEL_RELEASE | cut -f1 -d. | cut -f1 -d-`" minor_version="`echo $KERNEL_RELEASE | cut -f2 -d. | cut -f1 -d-`" micro_version="`echo $KERNEL_RELEASE | cut -f3 -d. | cut -f1 -d-`" printf '%02d%02d%03d' $major_version $minor_version $micro_version } case "$host_os" in linux*) os="linux" ;; freebsd*) os="freebsd" ;; solaris*) os="solaris" ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: This is an untested and unsupported Operating System. Proceed at your own peril." >&5 $as_echo "$as_me: WARNING: This is an untested and unsupported Operating System. Proceed at your own peril." >&2;} ;; esac osVersion="`getOsVersion`" if test "$with_kernel_modules" = "yes"; then case "$os" in linux) if test "$osVersion" -lt 206009; then as_fn_error $? "Kernels prior to 2.6.9 are not supported in this release of open-vm-tools. Configure using --without-kernel-modules to suppress building kernel drivers." "$LINENO" 5 fi if test ! -d "$LINUXDIR/kernel/"; then as_fn_error $? "$LINUXDIR/kernel does not exist" "$LINENO" 5 fi LINUXINCLUDE="$LINUXDIR/build/include" if test ! -d "$LINUXINCLUDE"; then as_fn_error $? "Can't find include dir under $LINUXDIR" "$LINENO" 5 fi ;; freebsd) freebsd_sysdir=/usr/src/sys if test -n "$SYSDIR"; then freebsd_sysdir="$SYSDIR" fi if test ! -f "$freebsd_sysdir/conf/kmod.mk"; then as_fn_error $? "FreeBSD kernel tree not found. Please install the kernel sources (or provide the location using SYSDIR) or configure using --without-kernel-modules." "$LINENO" 5 fi ;; esac fi # Arguments for disabling individual open-vm-tools features or libraries. @%:@ Check whether --enable-multimon was given. if test "${enable_multimon+set}" = set; then : enableval=$enable_multimon; enable_multimon="$enableval" else enable_multimon="yes" fi @%:@ Check whether --with-gtk2 was given. if test "${with_gtk2+set}" = set; then : withval=$with_gtk2; with_gtk2="$withval" else with_gtk2="yes" fi @%:@ Check whether --with-gtkmm was given. if test "${with_gtkmm+set}" = set; then : withval=$with_gtkmm; with_gtkmm="$withval" else with_gtkmm="yes" fi @%:@ Check whether --enable-docs was given. if test "${enable_docs+set}" = set; then : enableval=$enable_docs; enable_docs="$enableval" else enable_docs="yes" fi @%:@ Check whether --enable-tests was given. if test "${enable_tests+set}" = set; then : enableval=$enable_tests; enable_tests="$enableval" else enable_tests="auto" fi am__api_version='1.12' # 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' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then 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 fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P 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. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } 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 { $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 rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='open-vm-tools' VERSION='9.4.0' cat >>confdefs.h <<_ACEOF @%:@define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF @%:@define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' ### ### Constants ### # These need to be declared after initialization. # Some of our macro call-sites require changes to # CPPFLAGS/CFLAGS/LDFLAGS. In such places, we save the original value # of CPPFLAGS/CFLAGS/LDFLAGS before the macro call and restore it when # the call is done. We must perform this save at each macro site, # because CPPFLAGS/CFLAGS/LDFLAGS may change over the course of # configuration. # # CPPFLAGS is intended for preprocessor options (-D and -I mainly) # CFLAGS is intended for compiler options (-O, -f, -W, and so forth) CPPFLAGS="$CPPFLAGS -DUSING_AUTOCONF=1 -DOPEN_VM_TOOLS" ### ### Programs ### # C preprocessor and compiler. DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf @%:@ Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= 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 -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 depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= 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 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 { $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 depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi # C++ compiler. Note that unlike AC_PROG_CC, this call does not trigger an # error if no C++ compiler was found; it'll just set the variable CXX to 'g++'. 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 depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi # This allows features like per-target compiler flags. I.e., you can compile # one copy of the same sources twice with different flags. (See lib/guestApp # for an example.) 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 # FIXME: we rely on the cache variable name because # there is no other way. set dummy $CC am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o if test "$am_t" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi # Needed for the various install and uninstall hooks. { $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 { $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 # Needed for creating the archives in lib/ and the shared libraries. 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" # 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 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" { $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; } # 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@&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_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 enable_dlopen=no enable_win32_dll=no @%:@ 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=yes fi @%:@ 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@&t@ -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@&t@ -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 # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # 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="$sys_lib_dlsearch_path_spec $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@&t@ -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@&t@ -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 # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # 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="$sys_lib_dlsearch_path_spec $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: if test "$ac_cv_prog_AR" = false; then as_fn_error $? "The 'ar' utility was not found. Please put ar on the path." "$LINENO" 5 fi # We use pkg-config to set up the cflags and libs for gtk. # 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_prog_HAVE_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$HAVE_PKG_CONFIG"; then ac_cv_prog_HAVE_PKG_CONFIG="$HAVE_PKG_CONFIG" # 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_HAVE_PKG_CONFIG="yes" $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_prog_HAVE_PKG_CONFIG" && ac_cv_prog_HAVE_PKG_CONFIG="no" fi fi HAVE_PKG_CONFIG=$ac_cv_prog_HAVE_PKG_CONFIG if test -n "$HAVE_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_PKG_CONFIG" >&5 $as_echo "$HAVE_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$GCC" != "yes"; then as_fn_error $? "Only GCC is currently supported. Please put gcc in the path." "$LINENO" 5 fi ### ### Libraries ### { $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 # # Check for libintl.h. When configuring using "--without-x", /usr/local/include # may not be added to the include path, so code that use glib's i18n functions # would fail to compile because it can't find libintl.h. # ac_fn_c_check_header_mongrel "$LINENO" "libintl.h" "ac_cv_header_libintl_h" "$ac_includes_default" if test "x$ac_cv_header_libintl_h" = xyes; then : else have_libintl=no fi if test "$have_libintl" = "no"; then unset ac_cv_header_libintl_h CPPFLAGS="$CPPFLAGS -I/usr/local/include" ac_fn_c_check_header_mongrel "$LINENO" "libintl.h" "ac_cv_header_libintl_h" "$ac_includes_default" if test "x$ac_cv_header_libintl_h" = xyes; then : else as_fn_error $? "libintl.h not found. Make sure you have the gettext headers installed." "$LINENO" 5 fi fi # # Check for glib 2.6.0 or greater. # if test -z "glib-2.0"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GLIB2"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GLIB2_CPPFLAGS}" || test -n "${CUSTOM_GLIB2_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GLIB2_LIBS} -lglib-2.0" if test -n "glib.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GLIB2_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "glib.h" "ac_cv_header_glib_h" "$ac_includes_default" if test "x$ac_cv_header_glib_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "g_key_file_new"; then ac_vmw_function=g_key_file_new else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_glib-2.0_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lglib-2.0" >&5 $as_echo_n "checking for $ac_vmw_function in -lglib-2.0... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lglib-2.0 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GLIB2_CPPFLAGS="${CUSTOM_GLIB2_CPPFLAGS}" GLIB2_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "glib-2.0"; then if test -n "2.6.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glib-2.0 >= 2.6.0 (via pkg-config)" >&5 $as_echo_n "checking for glib-2.0 >= 2.6.0 (via pkg-config)... " >&6; } if pkg-config --exists 'glib-2.0 >= 2.6.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glib-2.0 (via pkg-config)" >&5 $as_echo_n "checking for glib-2.0 (via pkg-config)... " >&6; } if pkg-config --exists 'glib-2.0'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags glib-2.0`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs glib-2.0`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GLIB2_CPPFLAGS="$ac_vmw_cppflags" GLIB2_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GLIB2_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GLIB2_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GLIB2_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GLIB2_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true else true as_fn_error $? "glib >= 2.6.0 is required." "$LINENO" 5 fi if test -z "gmodule-2.0"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GMODULE"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GMODULE_CPPFLAGS}" || test -n "${CUSTOM_GMODULE_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GMODULE_LIBS} -lgmodule-2.0" if test -n ""; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GMODULE_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default" if test "x$ac_cv_header_" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n ""; then ac_vmw_function= else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_gmodule-2.0_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lgmodule-2.0" >&5 $as_echo_n "checking for $ac_vmw_function in -lgmodule-2.0... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgmodule-2.0 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GMODULE_CPPFLAGS="${CUSTOM_GMODULE_CPPFLAGS}" GMODULE_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "gmodule-2.0"; then if test -n "2.6.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gmodule-2.0 >= 2.6.0 (via pkg-config)" >&5 $as_echo_n "checking for gmodule-2.0 >= 2.6.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gmodule-2.0 >= 2.6.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gmodule-2.0 (via pkg-config)" >&5 $as_echo_n "checking for gmodule-2.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gmodule-2.0'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags gmodule-2.0`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs gmodule-2.0`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GMODULE_CPPFLAGS="$ac_vmw_cppflags" GMODULE_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GMODULE_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GMODULE_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GMODULE_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GMODULE_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true else true as_fn_error $? "gmodule >= 2.6.0 is required." "$LINENO" 5 fi if test -z "gobject-2.0"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GOBJECT"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GOBJECT_CPPFLAGS}" || test -n "${CUSTOM_GOBJECT_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GOBJECT_LIBS} -lgobject-2.0" if test -n "glib-object.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GOBJECT_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "glib-object.h" "ac_cv_header_glib_object_h" "$ac_includes_default" if test "x$ac_cv_header_glib_object_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n ""; then ac_vmw_function= else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_gobject-2.0_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lgobject-2.0" >&5 $as_echo_n "checking for $ac_vmw_function in -lgobject-2.0... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgobject-2.0 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GOBJECT_CPPFLAGS="${CUSTOM_GOBJECT_CPPFLAGS}" GOBJECT_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "gobject-2.0"; then if test -n "2.6.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gobject-2.0 >= 2.6.0 (via pkg-config)" >&5 $as_echo_n "checking for gobject-2.0 >= 2.6.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gobject-2.0 >= 2.6.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gobject-2.0 (via pkg-config)" >&5 $as_echo_n "checking for gobject-2.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gobject-2.0'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags gobject-2.0`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs gobject-2.0`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GOBJECT_CPPFLAGS="$ac_vmw_cppflags" GOBJECT_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GOBJECT_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GOBJECT_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GOBJECT_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GOBJECT_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true else true as_fn_error $? "gobject >= 2.6.0 is required." "$LINENO" 5 fi if test -z "gthread-2.0"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GTHREAD"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GTHREAD_CPPFLAGS}" || test -n "${CUSTOM_GTHREAD_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GTHREAD_LIBS} -lgthread-2.0" if test -n ""; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GTHREAD_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default" if test "x$ac_cv_header_" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n ""; then ac_vmw_function= else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_gthread-2.0_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lgthread-2.0" >&5 $as_echo_n "checking for $ac_vmw_function in -lgthread-2.0... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgthread-2.0 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GTHREAD_CPPFLAGS="${CUSTOM_GTHREAD_CPPFLAGS}" GTHREAD_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "gthread-2.0"; then if test -n "2.6.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gthread-2.0 >= 2.6.0 (via pkg-config)" >&5 $as_echo_n "checking for gthread-2.0 >= 2.6.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gthread-2.0 >= 2.6.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gthread-2.0 (via pkg-config)" >&5 $as_echo_n "checking for gthread-2.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gthread-2.0'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags gthread-2.0`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs gthread-2.0`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GTHREAD_CPPFLAGS="$ac_vmw_cppflags" GTHREAD_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GTHREAD_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GTHREAD_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GTHREAD_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GTHREAD_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true else true as_fn_error $? "glib >= 2.6.0 is required." "$LINENO" 5 fi # Extract the first word of "glib-genmarshal", so it can be a program name with args. set dummy glib-genmarshal; 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_have_genmarshal+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$have_genmarshal"; then ac_cv_prog_have_genmarshal="$have_genmarshal" # 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_have_genmarshal="yes" $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_prog_have_genmarshal" && ac_cv_prog_have_genmarshal="no" fi fi have_genmarshal=$ac_cv_prog_have_genmarshal if test -n "$have_genmarshal"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_genmarshal" >&5 $as_echo "$have_genmarshal" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$have_genmarshal" != "yes"; then as_fn_error $? "glib-genmarshal is required; make sure it's available in your path." "$LINENO" 5 fi # # Parts of our Linux code require more recent version of glib # if test "$os" = "linux"; then if test -z "glib-2.0"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GLIB2"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GLIB2_CPPFLAGS}" || test -n "${CUSTOM_GLIB2_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GLIB2_LIBS} -lglib-2.0" if test -n "glib.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GLIB2_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "glib.h" "ac_cv_header_glib_h" "$ac_includes_default" if test "x$ac_cv_header_glib_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "g_regex_new"; then ac_vmw_function=g_regex_new else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_glib-2.0_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lglib-2.0" >&5 $as_echo_n "checking for $ac_vmw_function in -lglib-2.0... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lglib-2.0 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GLIB2_CPPFLAGS="${CUSTOM_GLIB2_CPPFLAGS}" GLIB2_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "glib-2.0"; then if test -n "2.14.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glib-2.0 >= 2.14.0 (via pkg-config)" >&5 $as_echo_n "checking for glib-2.0 >= 2.14.0 (via pkg-config)... " >&6; } if pkg-config --exists 'glib-2.0 >= 2.14.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glib-2.0 (via pkg-config)" >&5 $as_echo_n "checking for glib-2.0 (via pkg-config)... " >&6; } if pkg-config --exists 'glib-2.0'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags glib-2.0`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs glib-2.0`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GLIB2_CPPFLAGS="$ac_vmw_cppflags" GLIB2_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GLIB2_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GLIB2_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GLIB2_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GLIB2_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_glib_2_14=yes else true { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: glib is not recent enough, some features will be disabled." >&5 $as_echo "$as_me: WARNING: glib is not recent enough, some features will be disabled." >&2;} fi fi # # Check for fuse. # if test -z "fuse"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "FUSE"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_FUSE_CPPFLAGS}" || test -n "${CUSTOM_FUSE_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_FUSE_LIBS} -lfuse" if test -n "fuse.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_FUSE_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "fuse.h" "ac_cv_header_fuse_h" "$ac_includes_default" if test "x$ac_cv_header_fuse_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "fuse_main"; then ac_vmw_function=fuse_main else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_fuse_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lfuse" >&5 $as_echo_n "checking for $ac_vmw_function in -lfuse... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lfuse $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then FUSE_CPPFLAGS="${CUSTOM_FUSE_CPPFLAGS}" FUSE_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "fuse"; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fuse >= (via pkg-config)" >&5 $as_echo_n "checking for fuse >= (via pkg-config)... " >&6; } if pkg-config --exists 'fuse >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fuse (via pkg-config)" >&5 $as_echo_n "checking for fuse (via pkg-config)... " >&6; } if pkg-config --exists 'fuse'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags fuse`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs fuse`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } FUSE_CPPFLAGS="$ac_vmw_cppflags" FUSE_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then FUSE_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" FUSE_LIBS="`$ac_vmw_lib_cfg --ldflags`" else FUSE_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" FUSE_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_fuse=yes else true have_fuse=no; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Fuse is missing, vmblock-fuse will be disabled." >&5 $as_echo "$as_me: WARNING: Fuse is missing, vmblock-fuse will be disabled." >&2;} fi # # Check for PAM. # @%:@ Check whether --with-pam was given. if test "${with_pam+set}" = set; then : withval=$with_pam; else with_pam=yes fi if test "$with_pam" = "yes"; then if test -z "$CUSTOM_PAM_CPPFLAGS"; then if test "$os" = freebsd; then CUSTOM_PAM_CPPFLAGS="-I/usr/local/include" else CUSTOM_PAM_CPPFLAGS="-I/usr/include" fi if test -n ""; then CUSTOM_PAM_CPPFLAGS="${CUSTOM_PAM_CPPFLAGS}/" fi fi if test -z "pam"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "PAM"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_PAM_CPPFLAGS}" || test -n "${CUSTOM_PAM_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_PAM_LIBS} -lpam" if test -n "security/pam_appl.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_PAM_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "security/pam_appl.h" "ac_cv_header_security_pam_appl_h" "$ac_includes_default" if test "x$ac_cv_header_security_pam_appl_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "pam_start"; then ac_vmw_function=pam_start else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_pam_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lpam" >&5 $as_echo_n "checking for $ac_vmw_function in -lpam... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpam $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then PAM_CPPFLAGS="${CUSTOM_PAM_CPPFLAGS}" PAM_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } PAM_CPPFLAGS="$ac_vmw_cppflags" PAM_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then PAM_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" PAM_LIBS="`$ac_vmw_lib_cfg --ldflags`" else PAM_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" PAM_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true PAM_CPPFLAGS="$PAM_CPPFLAGS -DUSE_PAM" else true feature="" if test -z "$feature"; then feature="PAM" fi as_fn_error $? "Cannot find PAM library. Please configure without $feature (using --without-pam), or install the PAM libraries and devel package(s)." "$LINENO" 5 fi fi # # Check for CUnit and disable test code if not available. # if test "$enable_tests" = "auto" -o "$enable_tests" = "yes"; then if test -z "$CUSTOM_CUNIT_CPPFLAGS"; then if test "$os" = freebsd; then CUSTOM_CUNIT_CPPFLAGS="-I/usr/local/include" else CUSTOM_CUNIT_CPPFLAGS="-I/usr/include" fi if test -n ""; then CUSTOM_CUNIT_CPPFLAGS="${CUSTOM_CUNIT_CPPFLAGS}/" fi fi if test -z "cunit"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "CUNIT"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_CUNIT_CPPFLAGS}" || test -n "${CUSTOM_CUNIT_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_CUNIT_LIBS} -lcunit" if test -n "CUnit/CUnit.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_CUNIT_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "CUnit/CUnit.h" "ac_cv_header_CUnit_CUnit_h" "$ac_includes_default" if test "x$ac_cv_header_CUnit_CUnit_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "CU_initialize_registry"; then ac_vmw_function=CU_initialize_registry else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_cunit_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lcunit" >&5 $as_echo_n "checking for $ac_vmw_function in -lcunit... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcunit $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then CUNIT_CPPFLAGS="${CUSTOM_CUNIT_CPPFLAGS}" CUNIT_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CUNIT_CPPFLAGS="$ac_vmw_cppflags" CUNIT_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then CUNIT_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" CUNIT_LIBS="`$ac_vmw_lib_cfg --ldflags`" else CUNIT_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" CUNIT_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_cunit=yes else true have_cunit=no fi if test "$have_cunit" = "no"; then if test "$enable_tests" = "yes"; then feature="" if test -z "$feature"; then feature="CUNIT" fi as_fn_error $? "Cannot find CUNIT library. Please configure without $feature (using --without-cunit), or install the CUNIT libraries and devel package(s)." "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: CUnit not found, tests won't be compiled." >&5 $as_echo "$as_me: WARNING: CUnit not found, tests won't be compiled." >&2;} fi fi fi # If the user explicitly disables X11, then don't try to detect the X-related libraries if test "$have_x" = "disabled"; then enable_multimon="no" elif test "$have_x" != "yes"; then as_fn_error $? "The X11 libraries were not found. Please configure without X11 (using --without-x), or install the libX11 devel package(s)." "$LINENO" 5 else CPPFLAGS="$CPPFLAGS $X_CFLAGS" COMMON_XLIBS="$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XeviQueryVersion in -lXext" >&5 $as_echo_n "checking for XeviQueryVersion in -lXext... " >&6; } if ${ac_cv_lib_Xext_XeviQueryVersion+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXext $COMMON_XLIBS $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 XeviQueryVersion (); int main () { return XeviQueryVersion (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xext_XeviQueryVersion=yes else ac_cv_lib_Xext_XeviQueryVersion=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_Xext_XeviQueryVersion" >&5 $as_echo "$ac_cv_lib_Xext_XeviQueryVersion" >&6; } if test "x$ac_cv_lib_Xext_XeviQueryVersion" = xyes; then : COMMON_XLIBS="-lXext $COMMON_XLIBS" else as_fn_error $? "libXext not found. Please configure without X11 (using --without-x), or install the libXext devel package(s)." "$LINENO" 5 fi ac_fn_c_check_header_compile "$LINENO" "X11/extensions/extutil.h" "ac_cv_header_X11_extensions_extutil_h" "#include #include " if test "x$ac_cv_header_X11_extensions_extutil_h" = xyes; then : else as_fn_error $? "X11/extensions/extutil.h header not found - you're probably on Solaris 10 or older. Please copy that header file onto your system manually, or configure without X11 (using --without-x)." "$LINENO" 5 fi if test "$enable_multimon" != "no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XineramaQueryVersion in -lXinerama" >&5 $as_echo_n "checking for XineramaQueryVersion in -lXinerama... " >&6; } if ${ac_cv_lib_Xinerama_XineramaQueryVersion+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXinerama $COMMON_XLIBS $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 XineramaQueryVersion (); int main () { return XineramaQueryVersion (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xinerama_XineramaQueryVersion=yes else ac_cv_lib_Xinerama_XineramaQueryVersion=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_Xinerama_XineramaQueryVersion" >&5 $as_echo "$ac_cv_lib_Xinerama_XineramaQueryVersion" >&6; } if test "x$ac_cv_lib_Xinerama_XineramaQueryVersion" = xyes; then : COMMON_XLIBS="-lXinerama $COMMON_XLIBS" else as_fn_error $? "libXinerama not found. Please configure without multimon (using --disable-multimon), configure without X11 (using --without-x), or install the libXinerama devel package(s)." "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XOpenDevice in -lXi" >&5 $as_echo_n "checking for XOpenDevice in -lXi... " >&6; } if ${ac_cv_lib_Xi_XOpenDevice+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXi $COMMON_XLIBS $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 XOpenDevice (); int main () { return XOpenDevice (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xi_XOpenDevice=yes else ac_cv_lib_Xi_XOpenDevice=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_Xi_XOpenDevice" >&5 $as_echo "$ac_cv_lib_Xi_XOpenDevice" >&6; } if test "x$ac_cv_lib_Xi_XOpenDevice" = xyes; then : COMMON_XLIBS="-lXi $COMMON_XLIBS" else as_fn_error $? "libXi not found. Please configure without X11 (using --without-x), or install the libXi devel package(s)." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XRenderQueryVersion in -lXrender" >&5 $as_echo_n "checking for XRenderQueryVersion in -lXrender... " >&6; } if ${ac_cv_lib_Xrender_XRenderQueryVersion+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXrender $COMMON_XLIBS $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 XRenderQueryVersion (); int main () { return XRenderQueryVersion (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xrender_XRenderQueryVersion=yes else ac_cv_lib_Xrender_XRenderQueryVersion=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_Xrender_XRenderQueryVersion" >&5 $as_echo "$ac_cv_lib_Xrender_XRenderQueryVersion" >&6; } if test "x$ac_cv_lib_Xrender_XRenderQueryVersion" = xyes; then : COMMON_XLIBS="-lXrender $COMMON_XLIBS" else as_fn_error $? "libXrender not found. Please configure without X11 (using --without-x), or install the libXrender devel package(s)." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XRRQueryVersion in -lXrandr" >&5 $as_echo_n "checking for XRRQueryVersion in -lXrandr... " >&6; } if ${ac_cv_lib_Xrandr_XRRQueryVersion+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXrandr $COMMON_XLIBS $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 XRRQueryVersion (); int main () { return XRRQueryVersion (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xrandr_XRRQueryVersion=yes else ac_cv_lib_Xrandr_XRRQueryVersion=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_Xrandr_XRRQueryVersion" >&5 $as_echo "$ac_cv_lib_Xrandr_XRRQueryVersion" >&6; } if test "x$ac_cv_lib_Xrandr_XRRQueryVersion" = xyes; then : COMMON_XLIBS="-lXrandr $COMMON_XLIBS" else as_fn_error $? "libXrandr not found. Please configure without X11 (using --without-x) or install the libXrandr devel package(s)." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XTestQueryExtension in -lXtst" >&5 $as_echo_n "checking for XTestQueryExtension in -lXtst... " >&6; } if ${ac_cv_lib_Xtst_XTestQueryExtension+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXtst $COMMON_XLIBS $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 XTestQueryExtension (); int main () { return XTestQueryExtension (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xtst_XTestQueryExtension=yes else ac_cv_lib_Xtst_XTestQueryExtension=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_Xtst_XTestQueryExtension" >&5 $as_echo "$ac_cv_lib_Xtst_XTestQueryExtension" >&6; } if test "x$ac_cv_lib_Xtst_XTestQueryExtension" = xyes; then : COMMON_XLIBS="-lXtst $COMMON_XLIBS" else as_fn_error $? "libXtst not found. Please configure without X11 (using --without-x) or install the libXtst devel package(s)." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SmcOpenConnection in -lSM" >&5 $as_echo_n "checking for SmcOpenConnection in -lSM... " >&6; } if ${ac_cv_lib_SM_SmcOpenConnection+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lSM $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 SmcOpenConnection (); int main () { return SmcOpenConnection (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_SM_SmcOpenConnection=yes else ac_cv_lib_SM_SmcOpenConnection=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_SM_SmcOpenConnection" >&5 $as_echo "$ac_cv_lib_SM_SmcOpenConnection" >&6; } if test "x$ac_cv_lib_SM_SmcOpenConnection" = xyes; then : XSM_LIBS="-lSM -lICE" && have_xsm_lib="yes" else -lICE fi for ac_header in X11/SM/SMlib.h X11/ICE/ICElib.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 have_xsm_header="yes" fi done if test "$have_xsm_lib" = "yes" -a "$have_xsm_header" = "yes"; then have_xsm="yes" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XCompositeQueryExtension in -lXcomposite" >&5 $as_echo_n "checking for XCompositeQueryExtension in -lXcomposite... " >&6; } if ${ac_cv_lib_Xcomposite_XCompositeQueryExtension+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXcomposite $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 XCompositeQueryExtension (); int main () { return XCompositeQueryExtension (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xcomposite_XCompositeQueryExtension=yes else ac_cv_lib_Xcomposite_XCompositeQueryExtension=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_Xcomposite_XCompositeQueryExtension" >&5 $as_echo "$ac_cv_lib_Xcomposite_XCompositeQueryExtension" >&6; } if test "x$ac_cv_lib_Xcomposite_XCompositeQueryExtension" = xyes; then : XCOMPOSITE_LIBS="-lXcomposite" else have_xcomposite="no" fi for ac_header in X11/extensions/Xcomposite.h do : ac_fn_c_check_header_mongrel "$LINENO" "X11/extensions/Xcomposite.h" "ac_cv_header_X11_extensions_Xcomposite_h" "$ac_includes_default" if test "x$ac_cv_header_X11_extensions_Xcomposite_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_X11_EXTENSIONS_XCOMPOSITE_H 1 _ACEOF else have_xcomposite="no" fi done if test "$have_xcomposite" != "no"; then have_xcomposite="yes" fi # Check whether we have gtk+ 2.0. if test "$with_gtk2" != "no"; then # gdk_display_get_default_group (added in gtk+ 2.4.0) is function currently # needed by vmware-user. if test -z "gtk-x11-2.0"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GTK"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GTK_CPPFLAGS}" || test -n "${CUSTOM_GTK_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GTK_LIBS} -lgtk-x11-2.0" if test -n "gtk/gtk.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GTK_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "gtk/gtk.h" "ac_cv_header_gtk_gtk_h" "$ac_includes_default" if test "x$ac_cv_header_gtk_gtk_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "gdk_display_get_default_group"; then ac_vmw_function=gdk_display_get_default_group else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_gtk-x11-2.0_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lgtk-x11-2.0" >&5 $as_echo_n "checking for $ac_vmw_function in -lgtk-x11-2.0... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgtk-x11-2.0 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GTK_CPPFLAGS="${CUSTOM_GTK_CPPFLAGS}" GTK_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "gtk+-2.0"; then if test -n "2.4.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gtk+-2.0 >= 2.4.0 (via pkg-config)" >&5 $as_echo_n "checking for gtk+-2.0 >= 2.4.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gtk+-2.0 >= 2.4.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gtk+-2.0 (via pkg-config)" >&5 $as_echo_n "checking for gtk+-2.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gtk+-2.0'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags gtk+-2.0`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs gtk+-2.0`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GTK_CPPFLAGS="$ac_vmw_cppflags" GTK_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GTK_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GTK_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GTK_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GTK_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true GTK_CPPFLAGS="$GTK_CPPFLAGS -DGTK2" else true as_fn_error $? "Gtk+ 2.0 library not found or too old. Please configure without Gtk+ support (using --without-gtk2) or install the Gtk+ 2.0 devel package." "$LINENO" 5 fi fi # # Check for gtkmm 2.4.0 or greater. # if test "$with_gtkmm" != "no"; then CUSTOM_GTKMM_CPPFLAGS="$CUSTOM_GTKMM_CPPFLAGS $GTK_CPPFLAGS" 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 "gtkmm-2.4"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GTKMM"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GTKMM_CPPFLAGS}" || test -n "${CUSTOM_GTKMM_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GTKMM_LIBS} -lgtkmm-2.4" if test -n "gtkmm.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GTKMM_CPPFLAGS} $CPPFLAGS" ac_fn_cxx_check_header_mongrel "$LINENO" "gtkmm.h" "ac_cv_header_gtkmm_h" "$ac_includes_default" if test "x$ac_cv_header_gtkmm_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n ""; then ac_vmw_function= else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_gtkmm-2.4_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lgtkmm-2.4" >&5 $as_echo_n "checking for $ac_vmw_function in -lgtkmm-2.4... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgtkmm-2.4 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GTKMM_CPPFLAGS="${CUSTOM_GTKMM_CPPFLAGS}" GTKMM_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "gtkmm-2.4"; then if test -n "2.4.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gtkmm-2.4 >= 2.4.0 (via pkg-config)" >&5 $as_echo_n "checking for gtkmm-2.4 >= 2.4.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gtkmm-2.4 >= 2.4.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gtkmm-2.4 (via pkg-config)" >&5 $as_echo_n "checking for gtkmm-2.4 (via pkg-config)... " >&6; } if pkg-config --exists 'gtkmm-2.4'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags gtkmm-2.4`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs gtkmm-2.4`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GTKMM_CPPFLAGS="$ac_vmw_cppflags" GTKMM_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GTKMM_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GTKMM_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GTKMM_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GTKMM_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true GTKMM_CPPFLAGS="$GTKMM_CPPFLAGS -DHAVE_GTKMM" else true as_fn_error $? "gtkmm library not found. Please install the libgtkmm devel package(s), or re-configure using --without-gtkmm." "$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 fi fi # End of checks for X libraries { $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 : HAVE_CRYPT="yes" else as_fn_error $? "libcrypt not found. Please install the libc/libcrypt devel package(s)." "$LINENO" 5 fi for ac_func in dlopen do : ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_DLOPEN 1 _ACEOF 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 : VIX_LIBADD="$VIX_LIBADD -ldl" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -ldl" else as_fn_error $? "dlopen was not found, but is required for open-vm-tools to function properly. Please contact your OS vendor." "$LINENO" 5 fi fi done for ac_func in ecvt do : ac_fn_c_check_func "$LINENO" "ecvt" "ac_cv_func_ecvt" if test "x$ac_cv_func_ecvt" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_ECVT 1 _ACEOF fi done for ac_func in fcvt do : ac_fn_c_check_func "$LINENO" "fcvt" "ac_cv_func_fcvt" if test "x$ac_cv_func_fcvt" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_FCVT 1 _ACEOF fi done if test "$os" = "freebsd" -a "$osVersion" -ge 600000; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lthr" >&5 $as_echo_n "checking for pthread_mutex_init in -lthr... " >&6; } if ${ac_cv_lib_thr_pthread_mutex_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lthr $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_mutex_init (); int main () { return pthread_mutex_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_thr_pthread_mutex_init=yes else ac_cv_lib_thr_pthread_mutex_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_thr_pthread_mutex_init" >&5 $as_echo "$ac_cv_lib_thr_pthread_mutex_init" >&6; } if test "x$ac_cv_lib_thr_pthread_mutex_init" = xyes; then : THREAD_LIB=-lthr else as_fn_error $? "Unable to locate required threading library libthr." "$LINENO" 5 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthread" >&5 $as_echo_n "checking for pthread_mutex_init in -lpthread... " >&6; } if ${ac_cv_lib_pthread_pthread_mutex_init+:} 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_mutex_init (); int main () { return pthread_mutex_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread_pthread_mutex_init=yes else ac_cv_lib_pthread_pthread_mutex_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_pthread_pthread_mutex_init" >&5 $as_echo "$ac_cv_lib_pthread_pthread_mutex_init" >&6; } if test "x$ac_cv_lib_pthread_pthread_mutex_init" = xyes; then : THREAD_LIB=-lpthread else as_fn_error $? "libpthread not found. Please install the libc/libpthread devel package(s)." "$LINENO" 5 fi fi # PAM prefix @%:@ Check whether --with-pam-prefix was given. if test "${with_pam_prefix+set}" = set; then : withval=$with_pam_prefix; PAM_PREFIX="$withval" else PAM_PREFIX='$(sysconfdir)' fi if test "$os" = "linux"; then @%:@ Check whether --with-procps was given. if test "${with_procps+set}" = set; then : withval=$with_procps; else with_procps=yes fi else with_procps="no" fi if test "$with_procps" = "yes"; then if test -z "$CUSTOM_PROCPS_NAME"; then CUSTOM_PROCPS_NAME=proc fi # XXX: no pkg-config and no procps-config means we need to # hard-code a sensible default. if test -z "$CUSTOM_PROCPS_LIBS"; then CUSTOM_PROCPS_LIBS="-L/lib" fi # Some distros provide libproc-${version}.so only, others provide the # libproc.so symlink. Try both to see what sticks (but only try the 3.2.7 # and 3.2.8 versions - adding every possible version here would be a mess). # # Users can help by providing CUSTOM_PROCPS_NAME / CUSTOM_PROCPS_LIBS if # necessary. have_procps=no if test -z "$CUSTOM_PROCPS_NAME"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "PROCPS"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_PROCPS_CPPFLAGS}" || test -n "${CUSTOM_PROCPS_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_PROCPS_LIBS} -l$CUSTOM_PROCPS_NAME" if test -n ""; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_PROCPS_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default" if test "x$ac_cv_header_" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "getstat"; then ac_vmw_function=getstat else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_$CUSTOM_PROCPS_NAME''_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -l$CUSTOM_PROCPS_NAME" >&5 $as_echo_n "checking for $ac_vmw_function in -l$CUSTOM_PROCPS_NAME... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-l$CUSTOM_PROCPS_NAME $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then PROCPS_CPPFLAGS="${CUSTOM_PROCPS_CPPFLAGS}" PROCPS_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } PROCPS_CPPFLAGS="$ac_vmw_cppflags" PROCPS_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then PROCPS_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" PROCPS_LIBS="`$ac_vmw_lib_cfg --ldflags`" else PROCPS_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" PROCPS_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_procps=yes; else true fi if test "$have_procps" = "no"; then if test -z "proc-3.2.8"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "PROCPS"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_PROCPS_CPPFLAGS}" || test -n "${CUSTOM_PROCPS_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_PROCPS_LIBS} -lproc-3.2.8" if test -n ""; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_PROCPS_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default" if test "x$ac_cv_header_" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "getstat"; then ac_vmw_function=getstat else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_proc-3.2.8_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lproc-3.2.8" >&5 $as_echo_n "checking for $ac_vmw_function in -lproc-3.2.8... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lproc-3.2.8 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then PROCPS_CPPFLAGS="${CUSTOM_PROCPS_CPPFLAGS}" PROCPS_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } PROCPS_CPPFLAGS="$ac_vmw_cppflags" PROCPS_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then PROCPS_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" PROCPS_LIBS="`$ac_vmw_lib_cfg --ldflags`" else PROCPS_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" PROCPS_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_procps=yes; else true fi fi if test "$have_procps" = "no"; then if test -z "proc-3.2.7"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "PROCPS"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_PROCPS_CPPFLAGS}" || test -n "${CUSTOM_PROCPS_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_PROCPS_LIBS} -lproc-3.2.7" if test -n ""; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_PROCPS_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default" if test "x$ac_cv_header_" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "getstat"; then ac_vmw_function=getstat else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_proc-3.2.7_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lproc-3.2.7" >&5 $as_echo_n "checking for $ac_vmw_function in -lproc-3.2.7... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lproc-3.2.7 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then PROCPS_CPPFLAGS="${CUSTOM_PROCPS_CPPFLAGS}" PROCPS_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } PROCPS_CPPFLAGS="$ac_vmw_cppflags" PROCPS_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then PROCPS_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" PROCPS_LIBS="`$ac_vmw_lib_cfg --ldflags`" else PROCPS_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" PROCPS_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true else true as_fn_error $? "libproc not found. Please configure without procps (using --without-procps) or install procps - http://procps.sourceforge.net" "$LINENO" 5 fi fi fi if test "$with_procps" != "yes"; then $as_echo "@%:@define NO_PROCPS 1" >>confdefs.h fi @%:@ Check whether --with-dnet was given. if test "${with_dnet+set}" = set; then : withval=$with_dnet; else with_dnet=yes fi have_dnet="no" if test "$with_dnet" = "yes"; then # On Debian, dnet is installed via the libdumbnet package. We need to # detect this so that our source files include dumbnet.h instead of # dnet.h, which is part of a different package altogether. if test -z "dumbnet"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "DNET"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_DNET_CPPFLAGS}" || test -n "${CUSTOM_DNET_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_DNET_LIBS} -ldumbnet" if test -n "dumbnet.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_DNET_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "dumbnet.h" "ac_cv_header_dumbnet_h" "$ac_includes_default" if test "x$ac_cv_header_dumbnet_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "intf_open"; then ac_vmw_function=intf_open else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_dumbnet_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -ldumbnet" >&5 $as_echo_n "checking for $ac_vmw_function in -ldumbnet... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldumbnet $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then DNET_CPPFLAGS="${CUSTOM_DNET_CPPFLAGS}" DNET_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } DNET_CPPFLAGS="$ac_vmw_cppflags" DNET_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n "dumbnet-config"; then # Extract the first word of "dumbnet-config", so it can be a program name with args. set dummy dumbnet-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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then DNET_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" DNET_LIBS="`$ac_vmw_lib_cfg --ldflags`" else DNET_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" DNET_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_dnet="yes"; $as_echo "@%:@define DNET_IS_DUMBNET 1" >>confdefs.h else true fi if test $have_dnet = "no"; then if test -z "dnet"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "DNET"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_DNET_CPPFLAGS}" || test -n "${CUSTOM_DNET_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_DNET_LIBS} -ldnet" if test -n "dnet.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_DNET_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "dnet.h" "ac_cv_header_dnet_h" "$ac_includes_default" if test "x$ac_cv_header_dnet_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "intf_open"; then ac_vmw_function=intf_open else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_dnet_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -ldnet" >&5 $as_echo_n "checking for $ac_vmw_function in -ldnet... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then DNET_CPPFLAGS="${CUSTOM_DNET_CPPFLAGS}" DNET_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } DNET_CPPFLAGS="$ac_vmw_cppflags" DNET_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n "dnet-config"; then # Extract the first word of "dnet-config", so it can be a program name with args. set dummy dnet-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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then DNET_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" DNET_LIBS="`$ac_vmw_lib_cfg --ldflags`" else DNET_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" DNET_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_dnet="yes" else true fi fi if test $have_dnet = "no"; then as_fn_error $? "dnet-config was not found on your PATH. Please configure without dnet (using --without-dnet) or install dnet - http://libdnet.sourceforge.net" "$LINENO" 5 fi fi if test "$with_dnet" != "yes"; then $as_echo "@%:@define NO_DNET 1" >>confdefs.h fi @%:@ Check whether --with-icu was given. if test "${with_icu+set}" = set; then : withval=$with_icu; else with_icu=yes fi if test "$have_x" = "yes" -o "$with_icu" = "yes"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}$CXX", so it can be a program name with args. set dummy ${ac_tool_prefix}$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_prog_have_cxx+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$have_cxx"; then ac_cv_prog_have_cxx="$have_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_have_cxx="${ac_tool_prefix}$CXX" $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 have_cxx=$ac_cv_prog_have_cxx if test -n "$have_cxx"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_cxx" >&5 $as_echo "$have_cxx" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_have_cxx"; then ac_ct_have_cxx=$have_cxx # 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_prog_ac_ct_have_cxx+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_have_cxx"; then ac_cv_prog_ac_ct_have_cxx="$ac_ct_have_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_have_cxx="$CXX" $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_have_cxx=$ac_cv_prog_ac_ct_have_cxx if test -n "$ac_ct_have_cxx"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_have_cxx" >&5 $as_echo "$ac_ct_have_cxx" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_have_cxx" = x; then have_cxx="no" 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 have_cxx=$ac_ct_have_cxx fi else have_cxx="$ac_cv_prog_have_cxx" fi if test "$have_cxx" = "no"; then as_fn_error $? "C++ compiler not found. Make sure you have a C++ compiler installed or configure without X11 (using --without-x) and without ICU (using --without-icu)." "$LINENO" 5 fi fi if test "$with_icu" = "yes"; 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 if test -z "icuuc"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "ICU"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_ICU_CPPFLAGS}" || test -n "${CUSTOM_ICU_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_ICU_LIBS} -licuuc" if test -n "unicode/utf.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_ICU_CPPFLAGS} $CPPFLAGS" ac_fn_cxx_check_header_mongrel "$LINENO" "unicode/utf.h" "ac_cv_header_unicode_utf_h" "$ac_includes_default" if test "x$ac_cv_header_unicode_utf_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n ""; then ac_vmw_function= else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_icuuc_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -licuuc" >&5 $as_echo_n "checking for $ac_vmw_function in -licuuc... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-licuuc $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then ICU_CPPFLAGS="${CUSTOM_ICU_CPPFLAGS}" ICU_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ICU_CPPFLAGS="$ac_vmw_cppflags" ICU_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n "icu-config"; then # Extract the first word of "icu-config", so it can be a program name with args. set dummy icu-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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then ICU_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" ICU_LIBS="`$ac_vmw_lib_cfg --ldflags`" else ICU_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" ICU_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true ICU_CPPFLAGS="$ICU_CPPFLAGS -DUSE_ICU" else true as_fn_error $? "ICU library not found. Please configure without ICU (using --without-icu) or install ICU - http://www.icu-project.org" "$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 # Check whether we have ICU >= 3.8. 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 ucasemap_utf8ToTitle in ICU" >&5 $as_echo_n "checking for ucasemap_utf8ToTitle in ICU... " >&6; } ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $ICU_CPPFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { (void) &ucasemap_utf8ToTitle; return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ICU_CPPFLAGS="$ICU_CPPFLAGS -DHAVE_ICU_38" { $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 CPPFLAGS="$ORIGINAL_CPPFLAGS" 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 # Easier to give all modules the ICU defines/includes... CPPFLAGS="$CPPFLAGS $ICU_CPPFLAGS" else CPPFLAGS="$CPPFLAGS -DNO_ICU" fi # Extract the first word of "rpcgen", so it can be a program name with args. set dummy rpcgen; 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_RPCGEN+:} false; then : $as_echo_n "(cached) " >&6 else case $RPCGEN in [\\/]* | ?:[\\/]*) ac_cv_path_RPCGEN="$RPCGEN" # 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_RPCGEN="$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_RPCGEN" && ac_cv_path_RPCGEN=" as_fn_error $? "rpcgen not found. Please install the libc devel package." "$LINENO" 5 " ;; esac fi RPCGEN=$ac_cv_path_RPCGEN if test -n "$RPCGEN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RPCGEN" >&5 $as_echo "$RPCGEN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ### ### Headers ### for ac_header in crypt.h do : ac_fn_c_check_header_mongrel "$LINENO" "crypt.h" "ac_cv_header_crypt_h" "$ac_includes_default" if test "x$ac_cv_header_crypt_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_CRYPT_H 1 _ACEOF fi done for ac_header in inttypes.h do : ac_fn_c_check_header_mongrel "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default" if test "x$ac_cv_header_inttypes_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_INTTYPES_H 1 _ACEOF fi done 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 for ac_header in stdlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" if test "x$ac_cv_header_stdlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_STDLIB_H 1 _ACEOF fi done for ac_header in wchar.h do : ac_fn_c_check_header_mongrel "$LINENO" "wchar.h" "ac_cv_header_wchar_h" "$ac_includes_default" if test "x$ac_cv_header_wchar_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_WCHAR_H 1 _ACEOF fi done for ac_header in sys/inttypes.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/inttypes.h" "ac_cv_header_sys_inttypes_h" "$ac_includes_default" if test "x$ac_cv_header_sys_inttypes_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_INTTYPES_H 1 _ACEOF fi done for ac_header in sys/io.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/io.h" "ac_cv_header_sys_io_h" "$ac_includes_default" if test "x$ac_cv_header_sys_io_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_IO_H 1 _ACEOF fi done for ac_header in sys/param.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default" if test "x$ac_cv_header_sys_param_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_PARAM_H 1 _ACEOF fi done # Required to make the sys/user.h check work correctly on FreeBSD for ac_header in sys/sysinfo.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/sysinfo.h" "ac_cv_header_sys_sysinfo_h" "$ac_includes_default" if test "x$ac_cv_header_sys_sysinfo_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_SYSINFO_H 1 _ACEOF fi done for ac_header in sys/types.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default" if test "x$ac_cv_header_sys_types_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_TYPES_H 1 _ACEOF fi done for ac_header in sys/user.h do : ac_fn_c_check_header_compile "$LINENO" "sys/user.h" "ac_cv_header_sys_user_h" " #ifdef HAVE_SYS_PARAM_H # include #endif " if test "x$ac_cv_header_sys_user_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_USER_H 1 _ACEOF fi done for ac_header in sys/vfs.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/vfs.h" "ac_cv_header_sys_vfs_h" "$ac_includes_default" if test "x$ac_cv_header_sys_vfs_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_VFS_H 1 _ACEOF fi done for ac_header in syslimits.h do : ac_fn_c_check_header_mongrel "$LINENO" "syslimits.h" "ac_cv_header_syslimits_h" "$ac_includes_default" if test "x$ac_cv_header_syslimits_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYSLIMITS_H 1 _ACEOF fi done for ac_header in unwind.h do : ac_fn_c_check_header_mongrel "$LINENO" "unwind.h" "ac_cv_header_unwind_h" "$ac_includes_default" if test "x$ac_cv_header_unwind_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_UNWIND_H 1 _ACEOF fi done ac_fn_c_check_header_mongrel "$LINENO" "wchar.h" "ac_cv_header_wchar_h" "$ac_includes_default" if test "x$ac_cv_header_wchar_h" = xyes; then : HAVE_WCHAR_H="yes" else HAVE_WCHAR_H="no" fi if test "$os" = "linux"; then # Make sure kernel-headers package is installed. ac_fn_c_check_header_mongrel "$LINENO" "linux/unistd.h" "ac_cv_header_linux_unistd_h" "$ac_includes_default" if test "x$ac_cv_header_linux_unistd_h" = xyes; then : else as_fn_error $? "linux/unistd.h is not found. Please install kernel-headers/linux-userspace-headers/linux-libc-dev package." "$LINENO" 5 fi fi if test "$enable_multimon" != "no"; then ac_fn_c_check_header_compile "$LINENO" "X11/extensions/panoramiXproto.h" "ac_cv_header_X11_extensions_panoramiXproto_h" "#include #include " if test "x$ac_cv_header_X11_extensions_panoramiXproto_h" = xyes; then : else as_fn_error $? "panoramiXproto.h not found. Please configure without multimon (using --disable-multimon) or install the libXinerama devel package(s)." "$LINENO" 5 fi fi bsdPrintfWrappers=no if test "$os" = "linux"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ecvt in -lc" >&5 $as_echo_n "checking for ecvt in -lc... " >&6; } if ${ac_cv_lib_c_ecvt+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc $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 ecvt (); int main () { return ecvt (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_c_ecvt=yes else ac_cv_lib_c_ecvt=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_ecvt" >&5 $as_echo "$ac_cv_lib_c_ecvt" >&6; } if test "x$ac_cv_lib_c_ecvt" = xyes; then : bsdPrintfWrappers=yes fi fi ### ### Typdefs, structs, and compiler quarks. ### { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } if ${ac_cv_header_stdbool_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef bool "error: bool is not defined" #endif #ifndef false "error: false is not defined" #endif #if false "error: false is not 0" #endif #ifndef true "error: true is not defined" #endif #if true != 1 "error: true is not 1" #endif #ifndef __bool_true_false_are_defined "error: __bool_true_false_are_defined is not defined" #endif struct s { _Bool s: 1; _Bool t; } s; char a[true == 1 ? 1 : -1]; char b[false == 0 ? 1 : -1]; char c[__bool_true_false_are_defined == 1 ? 1 : -1]; char d[(bool) 0.5 == true ? 1 : -1]; /* See body of main program for 'e'. */ char f[(_Bool) 0.0 == false ? 1 : -1]; char g[true]; char h[sizeof (_Bool)]; char i[sizeof s.t]; enum { j = false, k = true, l = false * true, m = true * 256 }; /* The following fails for HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ _Bool n[m]; char o[sizeof n == m * sizeof n[0] ? 1 : -1]; char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; /* Catch a bug in an HP-UX C compiler. See http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html */ _Bool q = true; _Bool *pq = &q; int main () { bool e = &s; *pq |= q; *pq |= ! q; /* Refer to every declared value, to avoid compiler optimizations. */ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + !m + !n + !o + !p + !q + !pq); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdbool_h=yes else ac_cv_header_stdbool_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_stdbool_h" >&5 $as_echo "$ac_cv_header_stdbool_h" >&6; } ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" if test "x$ac_cv_type__Bool" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE__BOOL 1 _ACEOF fi if test $ac_cv_header_stdbool_h = yes; then $as_echo "@%:@define HAVE_STDBOOL_H 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 { $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 { $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" "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 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" "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" "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_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 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 { $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 working volatile" >&5 $as_echo_n "checking for working volatile... " >&6; } if ${ac_cv_c_volatile+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { volatile int x; int * volatile y = (int *) 0; return !x && !y; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_volatile=yes else ac_cv_c_volatile=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_volatile" >&5 $as_echo "$ac_cv_c_volatile" >&6; } if test $ac_cv_c_volatile = no; then $as_echo "@%:@define volatile /**/" >>confdefs.h fi ### ### Specific features and OS/arch flags / actions ### ### General flags / actions CFLAGS="$CFLAGS -Wall" CFLAGS="$CFLAGS -Werror" # -Wno-unknown-pragmas is due to gcc not understanding '#pragma ident' in Xlib.h on OpenSolaris. for TEST_CFLAG in -Wno-pointer-sign -Wno-unused-value -fno-strict-aliasing \ -Wno-unknown-pragmas -Wno-uninitialized; do { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC flag $TEST_CFLAG" >&5 $as_echo_n "checking for GCC flag $TEST_CFLAG... " >&6; } ORIGINAL_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $TEST_CFLAG" NEW_CFLAG="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : NEW_CFLAG=" $TEST_CFLAG" { $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 CFLAGS="$ORIGINAL_CFLAGS$NEW_CFLAG" done CPPFLAGS="$CPPFLAGS -DVMX86_TOOLS" CPPFLAGS="$CPPFLAGS" # -fvisibility is used by "core service" plugins, but not required. ORIGINAL_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fvisibility=hidden" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC flag -fvisibility" >&5 $as_echo_n "checking for GCC flag -fvisibility... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : PLUGIN_CPPFLAGS="-fvisibility=hidden -DGCC_EXPLICIT_EXPORT"; { $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 CFLAGS="$ORIGINAL_CFLAGS" # Detect "unused-but-set-variable" gcc warning and disable it. ORIGINAL_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Wno-unused-but-set-variable" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC flag -Wno-unused-but-set-variable" >&5 $as_echo_n "checking for GCC flag -Wno-unused-but-set-variable... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ORIGINAL_CFLAGS="$ORIGINAL_CFLAGS -Wno-unused-but-set-variable"; { $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 CFLAGS="$ORIGINAL_CFLAGS" BUILDDIR="`pwd`" INCLUDE_DIR="`cd $srcdir; pwd`/lib/include" BLD_INCLUDE_DIR="$BUILDDIR/lib/include" CPPFLAGS="-I$INCLUDE_DIR -I$BLD_INCLUDE_DIR $CPPFLAGS" ### ### Documentation. ### if test "$enable_docs" = "yes"; then # Extract the first word of "doxygen", so it can be a program name with args. set dummy doxygen; 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_have_doxygen+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$have_doxygen"; then ac_cv_prog_have_doxygen="$have_doxygen" # 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_have_doxygen="yes" $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_prog_have_doxygen" && ac_cv_prog_have_doxygen="no" fi fi have_doxygen=$ac_cv_prog_have_doxygen if test -n "$have_doxygen"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_doxygen" >&5 $as_echo "$have_doxygen" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$have_doxygen" = "no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: doxygen not found; API documentation will not be generated." >&5 $as_echo "$as_me: WARNING: doxygen not found; API documentation will not be generated." >&2;} else # Extract the first word of "dot", so it can be a program name with args. set dummy dot; 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_DOT+:} false; then : $as_echo_n "(cached) " >&6 else case $DOT in [\\/]* | ?:[\\/]*) ac_cv_path_DOT="$DOT" # 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_DOT="$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 DOT=$ac_cv_path_DOT if test -n "$DOT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOT" >&5 $as_echo "$DOT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$DOT" = ""; then HAVE_DOT=NO else DOT=`dirname $DOT` HAVE_DOT=YES fi # Extract the first word of "mscgen", so it can be a program name with args. set dummy mscgen; 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_MSCGEN+:} false; then : $as_echo_n "(cached) " >&6 else case $MSCGEN in [\\/]* | ?:[\\/]*) ac_cv_path_MSCGEN="$MSCGEN" # 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_MSCGEN="$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_MSCGEN" && ac_cv_path_MSCGEN="no" ;; esac fi MSCGEN=$ac_cv_path_MSCGEN if test -n "$MSCGEN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSCGEN" >&5 $as_echo "$MSCGEN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$MSCGEN" != "no"; then MSCGEN_DIR="`dirname $MSCGEN`" else MSCGEN_DIR= fi fi fi ### ### OS/arch-specific flags / actions ### MODULES="" MODULES_OS="$os" TARGET_OS="$os" MODULES_DIR="" buildHgfsmounter=no if test "$have_glib_2_14" = "yes"; then CPPFLAGS="$CPPFLAGS -DHAVE_GLIB_REGEX" fi if test "$os" = "linux"; then MODULES_DIR="$LINUXDIR/kernel/" CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64" CPPFLAGS="$CPPFLAGS -D_LARGEFILE64_SOURCE" CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=500" CPPFLAGS="$CPPFLAGS -D_BSD_SOURCE" CPPFLAGS="$CPPFLAGS -D_SVID_SOURCE" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lrt" MODULES="$MODULES vmsync vmci vsock" MODULES="$MODULES vmxnet vmblock vmhgfs" buildHgfsmounter=yes fi if test "$os" = "freebsd"; then LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lkvm" MODULES_DIR="/boot/modules" if test "$osVersion" -ge 302000; then MODULES="$MODULES vmmemctl" fi if test "$osVersion" -ge 409000; then MODULES="$MODULES vmxnet" fi if test "$osVersion" -ge 600000; then MODULES="$MODULES vmblock vmhgfs" buildHgfsmounter=yes fi if test "$with_kernel_modules" = "yes"; then echo "****************************************************************" echo " You are building FreeBSD kernel modules. Make sure you use " echo " 'make' to build open-vm-tools, and not GNU make ('gmake'). " echo "****************************************************************" fi fi if test "$os" = "solaris"; then LIB_IMPERSONATE_CPPFLAGS="$LIB_IMPERSONATE_CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS" LIB_USER_CPPFLAGS="$LIB_USER_CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lsocket" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lnsl" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lresolv" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lrpcsvc" # Setup defines to identify the OS version. if test "$osVersion" -eq 509000; then CPPFLAGS="$CPPFLAGS -DSOL9" fi if test "$osVersion" -eq 510000; then CPPFLAGS="$CPPFLAGS -DSOL10" fi if test "$osVersion" -eq 511000; then CPPFLAGS="$CPPFLAGS -DSOL11" fi MODULES="$MODULES vmxnet vmmemctl" # HGFS and vmblock need Solaris 10 at least. if test "$osVersion" -ge 510000; then MODULES="$MODULES vmhgfs vmblock" fi # vmxnet3 is built on Solaris 10 / 11 only if GLDv3 is installed. if test "$osVersion" -gt 510000; then ac_fn_c_check_header_mongrel "$LINENO" "sys/mac.h" "ac_cv_header_sys_mac_h" "$ac_includes_default" if test "x$ac_cv_header_sys_mac_h" = xyes; then : MODULES="$MODULES vmxnet3" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GLDv3 (sys/mac.h) is not installed, vmxnet3 will not be compiled." >&5 $as_echo "$as_me: WARNING: GLDv3 (sys/mac.h) is not installed, vmxnet3 will not be compiled." >&2;} fi fi if test "$with_kernel_modules" = "yes"; then echo "****************************************************************" echo " You are building Solaris kernel modules. Make sure you use " echo " GNU make to build open-vm-tools. " echo "****************************************************************" fi fi if test "$buildHgfsmounter" = "yes"; then BUILD_HGFSMOUNTER_TRUE= BUILD_HGFSMOUNTER_FALSE='#' else BUILD_HGFSMOUNTER_TRUE='#' BUILD_HGFSMOUNTER_FALSE= fi if test "$os" = "linux"; then LINUX_TRUE= LINUX_FALSE='#' else LINUX_TRUE='#' LINUX_FALSE= fi if test "$os" = "solaris"; then SOLARIS_TRUE= SOLARIS_FALSE='#' else SOLARIS_TRUE='#' SOLARIS_FALSE= fi if test "$os" = "freebsd"; then FREEBSD_TRUE= FREEBSD_FALSE='#' else FREEBSD_TRUE='#' FREEBSD_FALSE= fi if test "$os" = "freebsd" -a -n "$SYSDIR"; then FREEBSD_CUSTOM_SYSDIR_TRUE= FREEBSD_CUSTOM_SYSDIR_FALSE='#' else FREEBSD_CUSTOM_SYSDIR_TRUE='#' FREEBSD_CUSTOM_SYSDIR_FALSE= fi if test "$userSpaceBitness" = "32"; then THIRTY_TWO_BIT_USERSPACE_TRUE= THIRTY_TWO_BIT_USERSPACE_FALSE='#' else THIRTY_TWO_BIT_USERSPACE_TRUE='#' THIRTY_TWO_BIT_USERSPACE_FALSE= fi if test "$have_x" = "yes"; then HAVE_X11_TRUE= HAVE_X11_FALSE='#' else HAVE_X11_TRUE='#' HAVE_X11_FALSE= fi if test "$with_icu" = "yes"; then HAVE_ICU_TRUE= HAVE_ICU_FALSE='#' else HAVE_ICU_TRUE='#' HAVE_ICU_FALSE= fi if test "$with_kernel_modules" = "yes"; then WITH_KERNEL_MODULES_TRUE= WITH_KERNEL_MODULES_FALSE='#' else WITH_KERNEL_MODULES_TRUE='#' WITH_KERNEL_MODULES_FALSE= fi if test "$have_xsm" = "yes"; then HAVE_XSM_TRUE= HAVE_XSM_FALSE='#' else HAVE_XSM_TRUE='#' HAVE_XSM_FALSE= fi if test "$have_xcomposite" = "yes"; then HAVE_XCOMPOSITE_TRUE= HAVE_XCOMPOSITE_FALSE='#' else HAVE_XCOMPOSITE_TRUE='#' HAVE_XCOMPOSITE_FALSE= fi if test "$have_cunit" = "yes"; then ENABLE_TESTS_TRUE= ENABLE_TESTS_FALSE='#' else ENABLE_TESTS_TRUE='#' ENABLE_TESTS_FALSE= fi if test "$with_root_privileges" = "yes"; then WITH_ROOT_PRIVILEGES_TRUE= WITH_ROOT_PRIVILEGES_FALSE='#' else WITH_ROOT_PRIVILEGES_TRUE='#' WITH_ROOT_PRIVILEGES_FALSE= fi if test "$have_dnet" = "yes"; then HAVE_DNET_TRUE= HAVE_DNET_FALSE='#' else HAVE_DNET_TRUE='#' HAVE_DNET_FALSE= fi if test "$have_doxygen" = "yes"; then HAVE_DOXYGEN_TRUE= HAVE_DOXYGEN_FALSE='#' else HAVE_DOXYGEN_TRUE='#' HAVE_DOXYGEN_FALSE= fi if test "$have_fuse" = "yes"; then HAVE_FUSE_TRUE= HAVE_FUSE_FALSE='#' else HAVE_FUSE_TRUE='#' HAVE_FUSE_FALSE= fi if test "$with_gnu_ld" = "yes"; then HAVE_GNU_LD_TRUE= HAVE_GNU_LD_FALSE='#' else HAVE_GNU_LD_TRUE='#' HAVE_GNU_LD_FALSE= fi if test "$have_x" = "yes" -a "$with_gtkmm" = "yes"; then HAVE_GTKMM_TRUE= HAVE_GTKMM_FALSE='#' else HAVE_GTKMM_TRUE='#' HAVE_GTKMM_FALSE= fi if test "$with_pam" = "yes"; then HAVE_PAM_TRUE= HAVE_PAM_FALSE='#' else HAVE_PAM_TRUE='#' HAVE_PAM_FALSE= fi if test "os" = "linux" -a "$have_glib_2_14" = "yes"; then USE_SLASH_PROC_TRUE= USE_SLASH_PROC_FALSE='#' else USE_SLASH_PROC_TRUE='#' USE_SLASH_PROC_FALSE= fi if test "$bsdPrintfWrappers" = "yes"; then USE_PRINTF_WRAPPERS_TRUE= USE_PRINTF_WRAPPERS_FALSE='#' else USE_PRINTF_WRAPPERS_TRUE='#' USE_PRINTF_WRAPPERS_FALSE= fi if test "$have_xsm" != "yes"; then $as_echo "@%:@define NO_XSM 1" >>confdefs.h fi if test "$have_xcomposite" != "yes"; then $as_echo "@%:@define NO_XCOMPOSITE 1" >>confdefs.h fi ### Feature-specific flags / actions # Combine where possible # If control reaches this point and multimon is still enabled, then we know # all of the tests for required components have passed and it's safe to allow # multimon. Otherwise, it should be disabled. if test "$enable_multimon" = "no"; then # XXX: For consistency, change this to ENABLE_MULTIMON. This will require # some additional code cleanup. $as_echo "@%:@define NO_MULTIMON 1" >>confdefs.h fi LIB_AUTH_CPPFLAGS="$LIB_AUTH_CPPFLAGS $PAM_CPPFLAGS" if test "$HAVE_CRYPT" = "yes"; then LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lcrypt" VIX_LIBADD="$VIX_LIBADD -lcrypt" fi LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD $THREAD_LIB" VIX_LIBADD="$VIX_LIBADD $THREAD_LIB" ### Core Services definitions. HGFS_LIBS="$BUILDDIR/libhgfs/libhgfs.la" VMTOOLS_LIBS="$BUILDDIR/libvmtools/libvmtools.la $GLIB2_LIBS" VMTOOLS_CPPFLAGS="-DVMTOOLS_USE_GLIB $GLIB2_CPPFLAGS" PLUGIN_CPPFLAGS="$VMTOOLS_CPPFLAGS $PLUGIN_CPPFLAGS" PLUGIN_LDFLAGS="-Wl,-z,defs -Wl,-lc -shared -module -avoid-version" # In Solaris, the XDR-related functions are not in libc like in Linux and # FreeBSD, so binaries need to be linked to some extra libraries. XDR_LIBS= if test "$os" = "solaris"; then XDR_LIBS="-lnsl -lrpcsvc" fi # Installation directories for core services plugins. TEST_PLUGIN_INSTALLDIR=$datadir/open-vm-tools/tests COMMON_PLUGIN_INSTALLDIR=$libdir/open-vm-tools/plugins/common VMSVC_PLUGIN_INSTALLDIR=$libdir/open-vm-tools/plugins/vmsvc VMUSR_PLUGIN_INSTALLDIR=$libdir/open-vm-tools/plugins/vmusr # General definitions INSTVMSG='$(SHELL) $(top_srcdir)/scripts/build/instvmsg.sh' RPCGEN_WRAPPER='$(SHELL) $(top_builddir)/scripts/build/rpcgen_wrapper.sh' ### General substs if test "$os" = "freebsd" -a -n "$SYSDIR"; then # If SYSDIR is not defined, AC_SUBST expands to nothing, so we need something # inside this block. true fi ### Lib substs ### Program substs ### ### Create the Makefiles ### ac_config_files="$ac_config_files Makefile lib/Makefile lib/appUtil/Makefile lib/auth/Makefile lib/backdoor/Makefile lib/dict/Makefile lib/dynxdr/Makefile lib/err/Makefile lib/file/Makefile lib/foundryMsg/Makefile lib/glibUtils/Makefile lib/guestApp/Makefile lib/guestRpc/Makefile lib/hgfs/Makefile lib/hgfsBd/Makefile lib/hgfsHelper/Makefile lib/hgfsServer/Makefile lib/hgfsServerManagerGuest/Makefile lib/hgfsServerPolicyGuest/Makefile lib/impersonate/Makefile lib/lock/Makefile lib/message/Makefile lib/misc/Makefile lib/netUtil/Makefile lib/panic/Makefile lib/panicDefault/Makefile lib/printer/Makefile lib/procMgr/Makefile lib/rpcChannel/Makefile lib/rpcIn/Makefile lib/rpcOut/Makefile lib/rpcVmx/Makefile lib/slashProc/Makefile lib/string/Makefile lib/stubs/Makefile lib/syncDriver/Makefile lib/system/Makefile lib/unicode/Makefile lib/user/Makefile lib/vmCheck/Makefile lib/vmSignal/Makefile lib/wiper/Makefile lib/xdg/Makefile services/Makefile services/vmtoolsd/Makefile services/plugins/Makefile services/plugins/desktopEvents/Makefile services/plugins/dndcp/Makefile services/plugins/guestInfo/Makefile services/plugins/guestInfo/getlib/Makefile services/plugins/hgfsServer/Makefile services/plugins/powerOps/Makefile services/plugins/resolutionSet/Makefile services/plugins/timeSync/Makefile services/plugins/vix/Makefile services/plugins/vmbackup/Makefile vmware-user-suid-wrapper/Makefile toolbox/Makefile hgfsclient/Makefile hgfsmounter/Makefile checkvm/Makefile rpctool/Makefile libguestlib/Makefile libguestlib/vmguestlib.pc libhgfs/Makefile libvmtools/Makefile xferlogs/Makefile modules/Makefile vmblock-fuse/Makefile vmblockmounter/Makefile tests/Makefile tests/vmrpcdbg/Makefile tests/testDebug/Makefile tests/testPlugin/Makefile tests/testVmblock/Makefile docs/Makefile docs/api/Makefile scripts/Makefile scripts/build/rpcgen_wrapper.sh" ### ### Output ### 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}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIB@&t@OBJS; 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 LIB@&t@OBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_HGFSMOUNTER_TRUE}" && test -z "${BUILD_HGFSMOUNTER_FALSE}"; then as_fn_error $? "conditional \"BUILD_HGFSMOUNTER\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${LINUX_TRUE}" && test -z "${LINUX_FALSE}"; then as_fn_error $? "conditional \"LINUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${SOLARIS_TRUE}" && test -z "${SOLARIS_FALSE}"; then as_fn_error $? "conditional \"SOLARIS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${FREEBSD_TRUE}" && test -z "${FREEBSD_FALSE}"; then as_fn_error $? "conditional \"FREEBSD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${FREEBSD_CUSTOM_SYSDIR_TRUE}" && test -z "${FREEBSD_CUSTOM_SYSDIR_FALSE}"; then as_fn_error $? "conditional \"FREEBSD_CUSTOM_SYSDIR\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${THIRTY_TWO_BIT_USERSPACE_TRUE}" && test -z "${THIRTY_TWO_BIT_USERSPACE_FALSE}"; then as_fn_error $? "conditional \"THIRTY_TWO_BIT_USERSPACE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_X11_TRUE}" && test -z "${HAVE_X11_FALSE}"; then as_fn_error $? "conditional \"HAVE_X11\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_ICU_TRUE}" && test -z "${HAVE_ICU_FALSE}"; then as_fn_error $? "conditional \"HAVE_ICU\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_KERNEL_MODULES_TRUE}" && test -z "${WITH_KERNEL_MODULES_FALSE}"; then as_fn_error $? "conditional \"WITH_KERNEL_MODULES\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_XSM_TRUE}" && test -z "${HAVE_XSM_FALSE}"; then as_fn_error $? "conditional \"HAVE_XSM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_XCOMPOSITE_TRUE}" && test -z "${HAVE_XCOMPOSITE_FALSE}"; then as_fn_error $? "conditional \"HAVE_XCOMPOSITE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_TESTS_TRUE}" && test -z "${ENABLE_TESTS_FALSE}"; then as_fn_error $? "conditional \"ENABLE_TESTS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_ROOT_PRIVILEGES_TRUE}" && test -z "${WITH_ROOT_PRIVILEGES_FALSE}"; then as_fn_error $? "conditional \"WITH_ROOT_PRIVILEGES\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_DNET_TRUE}" && test -z "${HAVE_DNET_FALSE}"; then as_fn_error $? "conditional \"HAVE_DNET\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_DOXYGEN_TRUE}" && test -z "${HAVE_DOXYGEN_FALSE}"; then as_fn_error $? "conditional \"HAVE_DOXYGEN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_FUSE_TRUE}" && test -z "${HAVE_FUSE_FALSE}"; then as_fn_error $? "conditional \"HAVE_FUSE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_GNU_LD_TRUE}" && test -z "${HAVE_GNU_LD_FALSE}"; then as_fn_error $? "conditional \"HAVE_GNU_LD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_GTKMM_TRUE}" && test -z "${HAVE_GTKMM_FALSE}"; then as_fn_error $? "conditional \"HAVE_GTKMM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_PAM_TRUE}" && test -z "${HAVE_PAM_FALSE}"; then as_fn_error $? "conditional \"HAVE_PAM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${USE_SLASH_PROC_TRUE}" && test -z "${USE_SLASH_PROC_FALSE}"; then as_fn_error $? "conditional \"USE_SLASH_PROC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${USE_PRINTF_WRAPPERS_TRUE}" && test -z "${USE_PRINTF_WRAPPERS_FALSE}"; then as_fn_error $? "conditional \"USE_PRINTF_WRAPPERS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${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 @S|@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 @S|@? 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 @S|@as_val. Take advantage of shells that can avoid forks. The arguments @%:@ must be portable across @S|@(()) 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 "@S|@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 open-vm-tools $as_me 9.4.0, 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 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" 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 Configuration files: $config_files Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ open-vm-tools config.status 9.4.0 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' MKDIR_P='$MKDIR_P' 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;; --he | --h | --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 # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # 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' _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 "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; "lib/appUtil/Makefile") CONFIG_FILES="$CONFIG_FILES lib/appUtil/Makefile" ;; "lib/auth/Makefile") CONFIG_FILES="$CONFIG_FILES lib/auth/Makefile" ;; "lib/backdoor/Makefile") CONFIG_FILES="$CONFIG_FILES lib/backdoor/Makefile" ;; "lib/dict/Makefile") CONFIG_FILES="$CONFIG_FILES lib/dict/Makefile" ;; "lib/dynxdr/Makefile") CONFIG_FILES="$CONFIG_FILES lib/dynxdr/Makefile" ;; "lib/err/Makefile") CONFIG_FILES="$CONFIG_FILES lib/err/Makefile" ;; "lib/file/Makefile") CONFIG_FILES="$CONFIG_FILES lib/file/Makefile" ;; "lib/foundryMsg/Makefile") CONFIG_FILES="$CONFIG_FILES lib/foundryMsg/Makefile" ;; "lib/glibUtils/Makefile") CONFIG_FILES="$CONFIG_FILES lib/glibUtils/Makefile" ;; "lib/guestApp/Makefile") CONFIG_FILES="$CONFIG_FILES lib/guestApp/Makefile" ;; "lib/guestRpc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/guestRpc/Makefile" ;; "lib/hgfs/Makefile") CONFIG_FILES="$CONFIG_FILES lib/hgfs/Makefile" ;; "lib/hgfsBd/Makefile") CONFIG_FILES="$CONFIG_FILES lib/hgfsBd/Makefile" ;; "lib/hgfsHelper/Makefile") CONFIG_FILES="$CONFIG_FILES lib/hgfsHelper/Makefile" ;; "lib/hgfsServer/Makefile") CONFIG_FILES="$CONFIG_FILES lib/hgfsServer/Makefile" ;; "lib/hgfsServerManagerGuest/Makefile") CONFIG_FILES="$CONFIG_FILES lib/hgfsServerManagerGuest/Makefile" ;; "lib/hgfsServerPolicyGuest/Makefile") CONFIG_FILES="$CONFIG_FILES lib/hgfsServerPolicyGuest/Makefile" ;; "lib/impersonate/Makefile") CONFIG_FILES="$CONFIG_FILES lib/impersonate/Makefile" ;; "lib/lock/Makefile") CONFIG_FILES="$CONFIG_FILES lib/lock/Makefile" ;; "lib/message/Makefile") CONFIG_FILES="$CONFIG_FILES lib/message/Makefile" ;; "lib/misc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/misc/Makefile" ;; "lib/netUtil/Makefile") CONFIG_FILES="$CONFIG_FILES lib/netUtil/Makefile" ;; "lib/panic/Makefile") CONFIG_FILES="$CONFIG_FILES lib/panic/Makefile" ;; "lib/panicDefault/Makefile") CONFIG_FILES="$CONFIG_FILES lib/panicDefault/Makefile" ;; "lib/printer/Makefile") CONFIG_FILES="$CONFIG_FILES lib/printer/Makefile" ;; "lib/procMgr/Makefile") CONFIG_FILES="$CONFIG_FILES lib/procMgr/Makefile" ;; "lib/rpcChannel/Makefile") CONFIG_FILES="$CONFIG_FILES lib/rpcChannel/Makefile" ;; "lib/rpcIn/Makefile") CONFIG_FILES="$CONFIG_FILES lib/rpcIn/Makefile" ;; "lib/rpcOut/Makefile") CONFIG_FILES="$CONFIG_FILES lib/rpcOut/Makefile" ;; "lib/rpcVmx/Makefile") CONFIG_FILES="$CONFIG_FILES lib/rpcVmx/Makefile" ;; "lib/slashProc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/slashProc/Makefile" ;; "lib/string/Makefile") CONFIG_FILES="$CONFIG_FILES lib/string/Makefile" ;; "lib/stubs/Makefile") CONFIG_FILES="$CONFIG_FILES lib/stubs/Makefile" ;; "lib/syncDriver/Makefile") CONFIG_FILES="$CONFIG_FILES lib/syncDriver/Makefile" ;; "lib/system/Makefile") CONFIG_FILES="$CONFIG_FILES lib/system/Makefile" ;; "lib/unicode/Makefile") CONFIG_FILES="$CONFIG_FILES lib/unicode/Makefile" ;; "lib/user/Makefile") CONFIG_FILES="$CONFIG_FILES lib/user/Makefile" ;; "lib/vmCheck/Makefile") CONFIG_FILES="$CONFIG_FILES lib/vmCheck/Makefile" ;; "lib/vmSignal/Makefile") CONFIG_FILES="$CONFIG_FILES lib/vmSignal/Makefile" ;; "lib/wiper/Makefile") CONFIG_FILES="$CONFIG_FILES lib/wiper/Makefile" ;; "lib/xdg/Makefile") CONFIG_FILES="$CONFIG_FILES lib/xdg/Makefile" ;; "services/Makefile") CONFIG_FILES="$CONFIG_FILES services/Makefile" ;; "services/vmtoolsd/Makefile") CONFIG_FILES="$CONFIG_FILES services/vmtoolsd/Makefile" ;; "services/plugins/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/Makefile" ;; "services/plugins/desktopEvents/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/desktopEvents/Makefile" ;; "services/plugins/dndcp/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/dndcp/Makefile" ;; "services/plugins/guestInfo/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/guestInfo/Makefile" ;; "services/plugins/guestInfo/getlib/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/guestInfo/getlib/Makefile" ;; "services/plugins/hgfsServer/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/hgfsServer/Makefile" ;; "services/plugins/powerOps/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/powerOps/Makefile" ;; "services/plugins/resolutionSet/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/resolutionSet/Makefile" ;; "services/plugins/timeSync/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/timeSync/Makefile" ;; "services/plugins/vix/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/vix/Makefile" ;; "services/plugins/vmbackup/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/vmbackup/Makefile" ;; "vmware-user-suid-wrapper/Makefile") CONFIG_FILES="$CONFIG_FILES vmware-user-suid-wrapper/Makefile" ;; "toolbox/Makefile") CONFIG_FILES="$CONFIG_FILES toolbox/Makefile" ;; "hgfsclient/Makefile") CONFIG_FILES="$CONFIG_FILES hgfsclient/Makefile" ;; "hgfsmounter/Makefile") CONFIG_FILES="$CONFIG_FILES hgfsmounter/Makefile" ;; "checkvm/Makefile") CONFIG_FILES="$CONFIG_FILES checkvm/Makefile" ;; "rpctool/Makefile") CONFIG_FILES="$CONFIG_FILES rpctool/Makefile" ;; "libguestlib/Makefile") CONFIG_FILES="$CONFIG_FILES libguestlib/Makefile" ;; "libguestlib/vmguestlib.pc") CONFIG_FILES="$CONFIG_FILES libguestlib/vmguestlib.pc" ;; "libhgfs/Makefile") CONFIG_FILES="$CONFIG_FILES libhgfs/Makefile" ;; "libvmtools/Makefile") CONFIG_FILES="$CONFIG_FILES libvmtools/Makefile" ;; "xferlogs/Makefile") CONFIG_FILES="$CONFIG_FILES xferlogs/Makefile" ;; "modules/Makefile") CONFIG_FILES="$CONFIG_FILES modules/Makefile" ;; "vmblock-fuse/Makefile") CONFIG_FILES="$CONFIG_FILES vmblock-fuse/Makefile" ;; "vmblockmounter/Makefile") CONFIG_FILES="$CONFIG_FILES vmblockmounter/Makefile" ;; "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; "tests/vmrpcdbg/Makefile") CONFIG_FILES="$CONFIG_FILES tests/vmrpcdbg/Makefile" ;; "tests/testDebug/Makefile") CONFIG_FILES="$CONFIG_FILES tests/testDebug/Makefile" ;; "tests/testPlugin/Makefile") CONFIG_FILES="$CONFIG_FILES tests/testPlugin/Makefile" ;; "tests/testVmblock/Makefile") CONFIG_FILES="$CONFIG_FILES tests/testVmblock/Makefile" ;; "docs/Makefile") CONFIG_FILES="$CONFIG_FILES docs/Makefile" ;; "docs/api/Makefile") CONFIG_FILES="$CONFIG_FILES docs/api/Makefile" ;; "scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;; "scripts/build/rpcgen_wrapper.sh") CONFIG_FILES="$CONFIG_FILES scripts/build/rpcgen_wrapper.sh" ;; *) 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_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 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 { 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 = "" } { 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 } print line } _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" eval set X " :F $CONFIG_FILES :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 ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; 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 s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$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 ;; :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 "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "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 ;; 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 open-vm-tools-9.4.0-1280544/autom4te.cache/output.00000644765153500003110000300566312220061611017671 0ustar dtormts@%:@! /bin/sh @%:@ Guess values for system-dependent variables and create Makefiles. @%:@ Generated by GNU Autoconf 2.69 for open-vm-tools 9.4.0. @%:@ @%:@ Report bugs to . @%:@ @%:@ @%:@ 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 and $0: open-vm-tools-devel@lists.sourceforge.net about your $0: system, 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 @S|@? 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 "@S|@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 @S|@as_val. Take advantage of shells that can avoid forks. The arguments @%:@ must be portable across @S|@(()) 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 @S|@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=. LIB@&t@OBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='open-vm-tools' PACKAGE_TARNAME='open-vm-tools' PACKAGE_VERSION='9.4.0' PACKAGE_STRING='open-vm-tools 9.4.0' PACKAGE_BUGREPORT='open-vm-tools-devel@lists.sourceforge.net' PACKAGE_URL='' ac_unique_file="checkvm/checkvm.c" # 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_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIB@&t@OBJS VIX_LIBADD LIBVMTOOLS_LIBADD LIB_USER_CPPFLAGS LIB_IMPERSONATE_CPPFLAGS LIB_AUTH_CPPFLAGS RPCGEN_WRAPPER INSTVMSG SYSDIR VMUSR_PLUGIN_INSTALLDIR VMSVC_PLUGIN_INSTALLDIR COMMON_PLUGIN_INSTALLDIR TEST_PLUGIN_INSTALLDIR XDR_LIBS RPCGENFLAGS VMTOOLS_LIBS VMTOOLS_CPPFLAGS PLUGIN_LDFLAGS PLUGIN_CPPFLAGS PAM_PREFIX XCOMPOSITE_LIBS XSM_LIBS COMMON_XLIBS MODULES MODULES_DIR MODULES_OS LINUXINCLUDE KERNEL_RELEASE TARGET_OS TOOLS_VERSION HGFS_LIBS USE_PRINTF_WRAPPERS_FALSE USE_PRINTF_WRAPPERS_TRUE USE_SLASH_PROC_FALSE USE_SLASH_PROC_TRUE HAVE_PAM_FALSE HAVE_PAM_TRUE HAVE_GTKMM_FALSE HAVE_GTKMM_TRUE HAVE_GNU_LD_FALSE HAVE_GNU_LD_TRUE HAVE_FUSE_FALSE HAVE_FUSE_TRUE HAVE_DOXYGEN_FALSE HAVE_DOXYGEN_TRUE HAVE_DNET_FALSE HAVE_DNET_TRUE WITH_ROOT_PRIVILEGES_FALSE WITH_ROOT_PRIVILEGES_TRUE ENABLE_TESTS_FALSE ENABLE_TESTS_TRUE HAVE_XCOMPOSITE_FALSE HAVE_XCOMPOSITE_TRUE HAVE_XSM_FALSE HAVE_XSM_TRUE WITH_KERNEL_MODULES_FALSE WITH_KERNEL_MODULES_TRUE HAVE_ICU_FALSE HAVE_ICU_TRUE HAVE_X11_FALSE HAVE_X11_TRUE THIRTY_TWO_BIT_USERSPACE_FALSE THIRTY_TWO_BIT_USERSPACE_TRUE FREEBSD_CUSTOM_SYSDIR_FALSE FREEBSD_CUSTOM_SYSDIR_TRUE FREEBSD_FALSE FREEBSD_TRUE SOLARIS_FALSE SOLARIS_TRUE LINUX_FALSE LINUX_TRUE BUILD_HGFSMOUNTER_FALSE BUILD_HGFSMOUNTER_TRUE MSCGEN_DIR MSCGEN HAVE_DOT DOT have_doxygen RPCGEN ICU_LIBS ICU_CPPFLAGS have_cxx DNET_LIBS DNET_CPPFLAGS PROCPS_LIBS PROCPS_CPPFLAGS GTKMM_LIBS GTKMM_CPPFLAGS GTK_LIBS GTK_CPPFLAGS CUNIT_LIBS CUNIT_CPPFLAGS PAM_LIBS PAM_CPPFLAGS FUSE_LIBS FUSE_CPPFLAGS have_genmarshal GTHREAD_LIBS GTHREAD_CPPFLAGS GOBJECT_LIBS GOBJECT_CPPFLAGS GMODULE_LIBS GMODULE_CPPFLAGS GLIB2_LIBS GLIB2_CPPFLAGS ac_vmw_lib_cfg X_EXTRA_LIBS X_LIBS X_PRE_LIBS X_CFLAGS XMKMF HAVE_PKG_CONFIG CXXCPP OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR DLLTOOL OBJDUMP NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP LIBTOOL LN_S SED am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM host_os host_vendor host_cpu host build_os build_vendor build_cpu build 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='' ac_user_opts=' enable_option_checking with_root_privileges with_kernel_modules with_kernel_release with_linuxdir enable_multimon with_gtk2 with_gtkmm enable_docs enable_tests enable_dependency_tracking enable_shared enable_static with_pic enable_fast_install with_gnu_ld with_sysroot enable_libtool_lock with_x with_pam with_pam_prefix with_procps with_dnet with_icu ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP CXX CXXFLAGS CCC 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 open-vm-tools 9.4.0 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 @<:@@S|@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/open-vm-tools@:>@ --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names 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 open-vm-tools 9.4.0:";; 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] --disable-multimon disables multimon, enabled by default --disable-docs disables generation of API documentation; by default, docs are built if doxygen is available. --disable-tests disable compilation of test code. --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-shared@<:@=PKGS@:>@ build shared libraries @<:@default=yes@:>@ --enable-static@<:@=PKGS@:>@ build static libraries @<:@default=yes@:>@ --enable-fast-install@<:@=PKGS@:>@ optimize for fast installation @<:@default=yes@:>@ --disable-libtool-lock avoid locking (might break parallel builds) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --without-root-privileges does not perform any operations that require root privileges --without-kernel-modules does not compile or install the kernel modules --with-kernel-release specifies the kernel release you want to build against --with-linuxdir specifies the Linux directory you want to use --without-gtk2 compiles without Gtk 2.0 --without-gtkmm compiles without Gtkmm, sigc++, and related libs --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-x use the X Window System --without-pam compiles without PAM support. --with-pam-prefix specifies where pam files go. Default is @S|@(sysconfdir) --without-procps compiles without libproc (disables support for meminfo) --without-dnet compiles without libdnet (disables support for nicinfo) --without-icu disables support for ICU 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 CPP C preprocessor CXX C++ compiler command CXXFLAGS C++ compiler flags 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 . _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 open-vm-tools configure 9.4.0 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.@S|@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_c_try_cpp LINENO @%:@ ---------------------- @%:@ Try to preprocess conftest.@S|@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_cxx_try_compile LINENO @%:@ ---------------------------- @%:@ Try to compile conftest.@S|@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_link LINENO @%:@ ----------------------- @%:@ Try to link conftest.@S|@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.@S|@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.@S|@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.@S|@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_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;} ( $as_echo "## -------------------------------------------------------- ## ## Report this to open-vm-tools-devel@lists.sourceforge.net ## ## -------------------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&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_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;} ( $as_echo "## -------------------------------------------------------- ## ## Report this to open-vm-tools-devel@lists.sourceforge.net ## ## -------------------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&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 @%:@ 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_member LINENO AGGR MEMBER VAR INCLUDES @%:@ ---------------------------------------------------- @%:@ Tries to find if the field MEMBER exists in type AGGR, after including @%:@ INCLUDES, setting cache variable VAR accordingly. ac_fn_c_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$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 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 open-vm-tools $as_me 9.4.0, 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 # 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 # In order to make this configure script auto-detect situations where # people have a 32-bit userland running with a 64-bit kernel, we try to ask # the compiler (assumedly gcc) for its default Target:. # We have to set up $TEST_CC manually, since AC_PROG_CC hasn't yet been run (and can't be until AC_CANONICAL_HOST & AC_CANONICAL_BUILD are run) # The purpose of all this is to set up $host_alias/$build_alias in a more # intelligent way than config.guess currently does. TEST_CC="$CC_FOR_BUILD" test -z "$TEST_CC" && TEST_CC="$HOST_CC" test -z "$TEST_CC" && TEST_CC="$CC" if test -n "$TEST_CC" -a -z "$host_alias"; then host_alias="`$TEST_CC -dumpmachine`" if test -z "$build_alias" -a -n "$host_alias"; then build_alias="$host_alias" fi fi unset TEST_CC # checkvm/checkvm.c has no special significance - we just need to pass in a file that # helps autoconf verify that it really has found the source tree. # Keep the top-level directory tidy by putting auxiliary build tools and local # macros in separate subdirectories. ac_aux_dir= for ac_dir in config "$srcdir"/config; 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 config \"$srcdir\"/config" "$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. # 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 # Quote the regular expressions case "$host_cpu" in i[3456]86) userSpaceBitness="32" ;; x86_64) userSpaceBitness="64" ;; *) as_fn_error $? "Unknown architecture." "$LINENO" 5 ;; esac # Operational arguments. @%:@ Check whether --with-root-privileges was given. if test "${with_root_privileges+set}" = set; then : withval=$with_root_privileges; else with_root_privileges=yes fi # Kernel arguments. # The kernel args have to go here otherwise the KERNEL_RELEASE won't be visible # to getOsVersion() @%:@ Check whether --with-kernel-modules was given. if test "${with_kernel_modules+set}" = set; then : withval=$with_kernel_modules; else with_kernel_modules=yes fi @%:@ Check whether --with-kernel-release was given. if test "${with_kernel_release+set}" = set; then : withval=$with_kernel_release; KERNEL_RELEASE="$withval" else KERNEL_RELEASE=`uname -r` fi @%:@ Check whether --with-linuxdir was given. if test "${with_linuxdir+set}" = set; then : withval=$with_linuxdir; LINUXDIR="$withval" else LINUXDIR=/lib/modules/$KERNEL_RELEASE fi # Turn the uname output into something we can run comparisons on. getOsVersion() { major_version="`echo $KERNEL_RELEASE | cut -f1 -d. | cut -f1 -d-`" minor_version="`echo $KERNEL_RELEASE | cut -f2 -d. | cut -f1 -d-`" micro_version="`echo $KERNEL_RELEASE | cut -f3 -d. | cut -f1 -d-`" printf '%02d%02d%03d' $major_version $minor_version $micro_version } case "$host_os" in linux*) os="linux" ;; freebsd*) os="freebsd" ;; solaris*) os="solaris" ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: This is an untested and unsupported Operating System. Proceed at your own peril." >&5 $as_echo "$as_me: WARNING: This is an untested and unsupported Operating System. Proceed at your own peril." >&2;} ;; esac osVersion="`getOsVersion`" if test "$with_kernel_modules" = "yes"; then case "$os" in linux) if test "$osVersion" -lt 206009; then as_fn_error $? "Kernels prior to 2.6.9 are not supported in this release of open-vm-tools. Configure using --without-kernel-modules to suppress building kernel drivers." "$LINENO" 5 fi if test ! -d "$LINUXDIR/kernel/"; then as_fn_error $? "$LINUXDIR/kernel does not exist" "$LINENO" 5 fi LINUXINCLUDE="$LINUXDIR/build/include" if test ! -d "$LINUXINCLUDE"; then as_fn_error $? "Can't find include dir under $LINUXDIR" "$LINENO" 5 fi ;; freebsd) freebsd_sysdir=/usr/src/sys if test -n "$SYSDIR"; then freebsd_sysdir="$SYSDIR" fi if test ! -f "$freebsd_sysdir/conf/kmod.mk"; then as_fn_error $? "FreeBSD kernel tree not found. Please install the kernel sources (or provide the location using SYSDIR) or configure using --without-kernel-modules." "$LINENO" 5 fi ;; esac fi # Arguments for disabling individual open-vm-tools features or libraries. @%:@ Check whether --enable-multimon was given. if test "${enable_multimon+set}" = set; then : enableval=$enable_multimon; enable_multimon="$enableval" else enable_multimon="yes" fi @%:@ Check whether --with-gtk2 was given. if test "${with_gtk2+set}" = set; then : withval=$with_gtk2; with_gtk2="$withval" else with_gtk2="yes" fi @%:@ Check whether --with-gtkmm was given. if test "${with_gtkmm+set}" = set; then : withval=$with_gtkmm; with_gtkmm="$withval" else with_gtkmm="yes" fi @%:@ Check whether --enable-docs was given. if test "${enable_docs+set}" = set; then : enableval=$enable_docs; enable_docs="$enableval" else enable_docs="yes" fi @%:@ Check whether --enable-tests was given. if test "${enable_tests+set}" = set; then : enableval=$enable_tests; enable_tests="$enableval" else enable_tests="auto" fi am__api_version='1.12' # 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' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then 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 fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P 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. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } 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 { $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 rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='open-vm-tools' VERSION='9.4.0' cat >>confdefs.h <<_ACEOF @%:@define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF @%:@define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' ### ### Constants ### # These need to be declared after initialization. # Some of our macro call-sites require changes to # CPPFLAGS/CFLAGS/LDFLAGS. In such places, we save the original value # of CPPFLAGS/CFLAGS/LDFLAGS before the macro call and restore it when # the call is done. We must perform this save at each macro site, # because CPPFLAGS/CFLAGS/LDFLAGS may change over the course of # configuration. # # CPPFLAGS is intended for preprocessor options (-D and -I mainly) # CFLAGS is intended for compiler options (-O, -f, -W, and so forth) CPPFLAGS="$CPPFLAGS -DUSING_AUTOCONF=1 -DOPEN_VM_TOOLS" ### ### Programs ### # C preprocessor and compiler. DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf @%:@ Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= 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 -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 depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= 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 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 { $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 depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi # C++ compiler. Note that unlike AC_PROG_CC, this call does not trigger an # error if no C++ compiler was found; it'll just set the variable CXX to 'g++'. 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 depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi # This allows features like per-target compiler flags. I.e., you can compile # one copy of the same sources twice with different flags. (See lib/guestApp # for an example.) 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 # FIXME: we rely on the cache variable name because # there is no other way. set dummy $CC am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o if test "$am_t" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi # Needed for the various install and uninstall hooks. { $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 { $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 # Needed for creating the archives in lib/ and the shared libraries. 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" # 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 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" { $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; } # 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@&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_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 enable_dlopen=no enable_win32_dll=no @%:@ 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=yes fi @%:@ 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@&t@ -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@&t@ -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 # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # 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="$sys_lib_dlsearch_path_spec $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@&t@ -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@&t@ -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 # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # 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="$sys_lib_dlsearch_path_spec $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: if test "$ac_cv_prog_AR" = false; then as_fn_error $? "The 'ar' utility was not found. Please put ar on the path." "$LINENO" 5 fi # We use pkg-config to set up the cflags and libs for gtk. # 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_prog_HAVE_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$HAVE_PKG_CONFIG"; then ac_cv_prog_HAVE_PKG_CONFIG="$HAVE_PKG_CONFIG" # 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_HAVE_PKG_CONFIG="yes" $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_prog_HAVE_PKG_CONFIG" && ac_cv_prog_HAVE_PKG_CONFIG="no" fi fi HAVE_PKG_CONFIG=$ac_cv_prog_HAVE_PKG_CONFIG if test -n "$HAVE_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_PKG_CONFIG" >&5 $as_echo "$HAVE_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$GCC" != "yes"; then as_fn_error $? "Only GCC is currently supported. Please put gcc in the path." "$LINENO" 5 fi ### ### Libraries ### { $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 # # Check for libintl.h. When configuring using "--without-x", /usr/local/include # may not be added to the include path, so code that use glib's i18n functions # would fail to compile because it can't find libintl.h. # ac_fn_c_check_header_mongrel "$LINENO" "libintl.h" "ac_cv_header_libintl_h" "$ac_includes_default" if test "x$ac_cv_header_libintl_h" = xyes; then : else have_libintl=no fi if test "$have_libintl" = "no"; then unset ac_cv_header_libintl_h CPPFLAGS="$CPPFLAGS -I/usr/local/include" ac_fn_c_check_header_mongrel "$LINENO" "libintl.h" "ac_cv_header_libintl_h" "$ac_includes_default" if test "x$ac_cv_header_libintl_h" = xyes; then : else as_fn_error $? "libintl.h not found. Make sure you have the gettext headers installed." "$LINENO" 5 fi fi # # Check for glib 2.6.0 or greater. # if test -z "glib-2.0"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GLIB2"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GLIB2_CPPFLAGS}" || test -n "${CUSTOM_GLIB2_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GLIB2_LIBS} -lglib-2.0" if test -n "glib.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GLIB2_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "glib.h" "ac_cv_header_glib_h" "$ac_includes_default" if test "x$ac_cv_header_glib_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "g_key_file_new"; then ac_vmw_function=g_key_file_new else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_glib-2.0_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lglib-2.0" >&5 $as_echo_n "checking for $ac_vmw_function in -lglib-2.0... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lglib-2.0 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GLIB2_CPPFLAGS="${CUSTOM_GLIB2_CPPFLAGS}" GLIB2_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "glib-2.0"; then if test -n "2.6.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glib-2.0 >= 2.6.0 (via pkg-config)" >&5 $as_echo_n "checking for glib-2.0 >= 2.6.0 (via pkg-config)... " >&6; } if pkg-config --exists 'glib-2.0 >= 2.6.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glib-2.0 (via pkg-config)" >&5 $as_echo_n "checking for glib-2.0 (via pkg-config)... " >&6; } if pkg-config --exists 'glib-2.0'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags glib-2.0`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs glib-2.0`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GLIB2_CPPFLAGS="$ac_vmw_cppflags" GLIB2_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GLIB2_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GLIB2_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GLIB2_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GLIB2_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true else true as_fn_error $? "glib >= 2.6.0 is required." "$LINENO" 5 fi if test -z "gmodule-2.0"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GMODULE"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GMODULE_CPPFLAGS}" || test -n "${CUSTOM_GMODULE_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GMODULE_LIBS} -lgmodule-2.0" if test -n ""; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GMODULE_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default" if test "x$ac_cv_header_" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n ""; then ac_vmw_function= else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_gmodule-2.0_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lgmodule-2.0" >&5 $as_echo_n "checking for $ac_vmw_function in -lgmodule-2.0... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgmodule-2.0 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GMODULE_CPPFLAGS="${CUSTOM_GMODULE_CPPFLAGS}" GMODULE_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "gmodule-2.0"; then if test -n "2.6.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gmodule-2.0 >= 2.6.0 (via pkg-config)" >&5 $as_echo_n "checking for gmodule-2.0 >= 2.6.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gmodule-2.0 >= 2.6.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gmodule-2.0 (via pkg-config)" >&5 $as_echo_n "checking for gmodule-2.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gmodule-2.0'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags gmodule-2.0`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs gmodule-2.0`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GMODULE_CPPFLAGS="$ac_vmw_cppflags" GMODULE_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GMODULE_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GMODULE_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GMODULE_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GMODULE_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true else true as_fn_error $? "gmodule >= 2.6.0 is required." "$LINENO" 5 fi if test -z "gobject-2.0"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GOBJECT"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GOBJECT_CPPFLAGS}" || test -n "${CUSTOM_GOBJECT_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GOBJECT_LIBS} -lgobject-2.0" if test -n "glib-object.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GOBJECT_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "glib-object.h" "ac_cv_header_glib_object_h" "$ac_includes_default" if test "x$ac_cv_header_glib_object_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n ""; then ac_vmw_function= else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_gobject-2.0_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lgobject-2.0" >&5 $as_echo_n "checking for $ac_vmw_function in -lgobject-2.0... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgobject-2.0 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GOBJECT_CPPFLAGS="${CUSTOM_GOBJECT_CPPFLAGS}" GOBJECT_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "gobject-2.0"; then if test -n "2.6.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gobject-2.0 >= 2.6.0 (via pkg-config)" >&5 $as_echo_n "checking for gobject-2.0 >= 2.6.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gobject-2.0 >= 2.6.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gobject-2.0 (via pkg-config)" >&5 $as_echo_n "checking for gobject-2.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gobject-2.0'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags gobject-2.0`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs gobject-2.0`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GOBJECT_CPPFLAGS="$ac_vmw_cppflags" GOBJECT_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GOBJECT_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GOBJECT_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GOBJECT_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GOBJECT_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true else true as_fn_error $? "gobject >= 2.6.0 is required." "$LINENO" 5 fi if test -z "gthread-2.0"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GTHREAD"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GTHREAD_CPPFLAGS}" || test -n "${CUSTOM_GTHREAD_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GTHREAD_LIBS} -lgthread-2.0" if test -n ""; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GTHREAD_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default" if test "x$ac_cv_header_" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n ""; then ac_vmw_function= else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_gthread-2.0_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lgthread-2.0" >&5 $as_echo_n "checking for $ac_vmw_function in -lgthread-2.0... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgthread-2.0 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GTHREAD_CPPFLAGS="${CUSTOM_GTHREAD_CPPFLAGS}" GTHREAD_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "gthread-2.0"; then if test -n "2.6.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gthread-2.0 >= 2.6.0 (via pkg-config)" >&5 $as_echo_n "checking for gthread-2.0 >= 2.6.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gthread-2.0 >= 2.6.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gthread-2.0 (via pkg-config)" >&5 $as_echo_n "checking for gthread-2.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gthread-2.0'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags gthread-2.0`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs gthread-2.0`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GTHREAD_CPPFLAGS="$ac_vmw_cppflags" GTHREAD_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GTHREAD_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GTHREAD_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GTHREAD_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GTHREAD_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true else true as_fn_error $? "glib >= 2.6.0 is required." "$LINENO" 5 fi # Extract the first word of "glib-genmarshal", so it can be a program name with args. set dummy glib-genmarshal; 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_have_genmarshal+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$have_genmarshal"; then ac_cv_prog_have_genmarshal="$have_genmarshal" # 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_have_genmarshal="yes" $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_prog_have_genmarshal" && ac_cv_prog_have_genmarshal="no" fi fi have_genmarshal=$ac_cv_prog_have_genmarshal if test -n "$have_genmarshal"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_genmarshal" >&5 $as_echo "$have_genmarshal" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$have_genmarshal" != "yes"; then as_fn_error $? "glib-genmarshal is required; make sure it's available in your path." "$LINENO" 5 fi # # Parts of our Linux code require more recent version of glib # if test "$os" = "linux"; then if test -z "glib-2.0"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GLIB2"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GLIB2_CPPFLAGS}" || test -n "${CUSTOM_GLIB2_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GLIB2_LIBS} -lglib-2.0" if test -n "glib.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GLIB2_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "glib.h" "ac_cv_header_glib_h" "$ac_includes_default" if test "x$ac_cv_header_glib_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "g_regex_new"; then ac_vmw_function=g_regex_new else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_glib-2.0_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lglib-2.0" >&5 $as_echo_n "checking for $ac_vmw_function in -lglib-2.0... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lglib-2.0 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GLIB2_CPPFLAGS="${CUSTOM_GLIB2_CPPFLAGS}" GLIB2_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "glib-2.0"; then if test -n "2.14.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glib-2.0 >= 2.14.0 (via pkg-config)" >&5 $as_echo_n "checking for glib-2.0 >= 2.14.0 (via pkg-config)... " >&6; } if pkg-config --exists 'glib-2.0 >= 2.14.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glib-2.0 (via pkg-config)" >&5 $as_echo_n "checking for glib-2.0 (via pkg-config)... " >&6; } if pkg-config --exists 'glib-2.0'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags glib-2.0`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs glib-2.0`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GLIB2_CPPFLAGS="$ac_vmw_cppflags" GLIB2_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GLIB2_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GLIB2_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GLIB2_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GLIB2_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_glib_2_14=yes else true { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: glib is not recent enough, some features will be disabled." >&5 $as_echo "$as_me: WARNING: glib is not recent enough, some features will be disabled." >&2;} fi fi # # Check for fuse. # if test -z "fuse"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "FUSE"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_FUSE_CPPFLAGS}" || test -n "${CUSTOM_FUSE_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_FUSE_LIBS} -lfuse" if test -n "fuse.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_FUSE_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "fuse.h" "ac_cv_header_fuse_h" "$ac_includes_default" if test "x$ac_cv_header_fuse_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "fuse_main"; then ac_vmw_function=fuse_main else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_fuse_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lfuse" >&5 $as_echo_n "checking for $ac_vmw_function in -lfuse... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lfuse $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then FUSE_CPPFLAGS="${CUSTOM_FUSE_CPPFLAGS}" FUSE_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "fuse"; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fuse >= (via pkg-config)" >&5 $as_echo_n "checking for fuse >= (via pkg-config)... " >&6; } if pkg-config --exists 'fuse >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fuse (via pkg-config)" >&5 $as_echo_n "checking for fuse (via pkg-config)... " >&6; } if pkg-config --exists 'fuse'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags fuse`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs fuse`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } FUSE_CPPFLAGS="$ac_vmw_cppflags" FUSE_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then FUSE_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" FUSE_LIBS="`$ac_vmw_lib_cfg --ldflags`" else FUSE_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" FUSE_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_fuse=yes else true have_fuse=no; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Fuse is missing, vmblock-fuse will be disabled." >&5 $as_echo "$as_me: WARNING: Fuse is missing, vmblock-fuse will be disabled." >&2;} fi # # Check for PAM. # @%:@ Check whether --with-pam was given. if test "${with_pam+set}" = set; then : withval=$with_pam; else with_pam=yes fi if test "$with_pam" = "yes"; then if test -z "$CUSTOM_PAM_CPPFLAGS"; then if test "$os" = freebsd; then CUSTOM_PAM_CPPFLAGS="-I/usr/local/include" else CUSTOM_PAM_CPPFLAGS="-I/usr/include" fi if test -n ""; then CUSTOM_PAM_CPPFLAGS="${CUSTOM_PAM_CPPFLAGS}/" fi fi if test -z "pam"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "PAM"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_PAM_CPPFLAGS}" || test -n "${CUSTOM_PAM_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_PAM_LIBS} -lpam" if test -n "security/pam_appl.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_PAM_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "security/pam_appl.h" "ac_cv_header_security_pam_appl_h" "$ac_includes_default" if test "x$ac_cv_header_security_pam_appl_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "pam_start"; then ac_vmw_function=pam_start else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_pam_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lpam" >&5 $as_echo_n "checking for $ac_vmw_function in -lpam... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpam $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then PAM_CPPFLAGS="${CUSTOM_PAM_CPPFLAGS}" PAM_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } PAM_CPPFLAGS="$ac_vmw_cppflags" PAM_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then PAM_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" PAM_LIBS="`$ac_vmw_lib_cfg --ldflags`" else PAM_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" PAM_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true PAM_CPPFLAGS="$PAM_CPPFLAGS -DUSE_PAM" else true feature="" if test -z "$feature"; then feature="PAM" fi as_fn_error $? "Cannot find PAM library. Please configure without $feature (using --without-pam), or install the PAM libraries and devel package(s)." "$LINENO" 5 fi fi # # Check for CUnit and disable test code if not available. # if test "$enable_tests" = "auto" -o "$enable_tests" = "yes"; then if test -z "$CUSTOM_CUNIT_CPPFLAGS"; then if test "$os" = freebsd; then CUSTOM_CUNIT_CPPFLAGS="-I/usr/local/include" else CUSTOM_CUNIT_CPPFLAGS="-I/usr/include" fi if test -n ""; then CUSTOM_CUNIT_CPPFLAGS="${CUSTOM_CUNIT_CPPFLAGS}/" fi fi if test -z "cunit"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "CUNIT"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_CUNIT_CPPFLAGS}" || test -n "${CUSTOM_CUNIT_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_CUNIT_LIBS} -lcunit" if test -n "CUnit/CUnit.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_CUNIT_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "CUnit/CUnit.h" "ac_cv_header_CUnit_CUnit_h" "$ac_includes_default" if test "x$ac_cv_header_CUnit_CUnit_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "CU_initialize_registry"; then ac_vmw_function=CU_initialize_registry else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_cunit_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lcunit" >&5 $as_echo_n "checking for $ac_vmw_function in -lcunit... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcunit $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then CUNIT_CPPFLAGS="${CUSTOM_CUNIT_CPPFLAGS}" CUNIT_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CUNIT_CPPFLAGS="$ac_vmw_cppflags" CUNIT_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then CUNIT_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" CUNIT_LIBS="`$ac_vmw_lib_cfg --ldflags`" else CUNIT_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" CUNIT_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_cunit=yes else true have_cunit=no fi if test "$have_cunit" = "no"; then if test "$enable_tests" = "yes"; then feature="" if test -z "$feature"; then feature="CUNIT" fi as_fn_error $? "Cannot find CUNIT library. Please configure without $feature (using --without-cunit), or install the CUNIT libraries and devel package(s)." "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: CUnit not found, tests won't be compiled." >&5 $as_echo "$as_me: WARNING: CUnit not found, tests won't be compiled." >&2;} fi fi fi # If the user explicitly disables X11, then don't try to detect the X-related libraries if test "$have_x" = "disabled"; then enable_multimon="no" elif test "$have_x" != "yes"; then as_fn_error $? "The X11 libraries were not found. Please configure without X11 (using --without-x), or install the libX11 devel package(s)." "$LINENO" 5 else CPPFLAGS="$CPPFLAGS $X_CFLAGS" COMMON_XLIBS="$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XeviQueryVersion in -lXext" >&5 $as_echo_n "checking for XeviQueryVersion in -lXext... " >&6; } if ${ac_cv_lib_Xext_XeviQueryVersion+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXext $COMMON_XLIBS $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 XeviQueryVersion (); int main () { return XeviQueryVersion (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xext_XeviQueryVersion=yes else ac_cv_lib_Xext_XeviQueryVersion=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_Xext_XeviQueryVersion" >&5 $as_echo "$ac_cv_lib_Xext_XeviQueryVersion" >&6; } if test "x$ac_cv_lib_Xext_XeviQueryVersion" = xyes; then : COMMON_XLIBS="-lXext $COMMON_XLIBS" else as_fn_error $? "libXext not found. Please configure without X11 (using --without-x), or install the libXext devel package(s)." "$LINENO" 5 fi ac_fn_c_check_header_compile "$LINENO" "X11/extensions/extutil.h" "ac_cv_header_X11_extensions_extutil_h" "#include #include " if test "x$ac_cv_header_X11_extensions_extutil_h" = xyes; then : else as_fn_error $? "X11/extensions/extutil.h header not found - you're probably on Solaris 10 or older. Please copy that header file onto your system manually, or configure without X11 (using --without-x)." "$LINENO" 5 fi if test "$enable_multimon" != "no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XineramaQueryVersion in -lXinerama" >&5 $as_echo_n "checking for XineramaQueryVersion in -lXinerama... " >&6; } if ${ac_cv_lib_Xinerama_XineramaQueryVersion+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXinerama $COMMON_XLIBS $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 XineramaQueryVersion (); int main () { return XineramaQueryVersion (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xinerama_XineramaQueryVersion=yes else ac_cv_lib_Xinerama_XineramaQueryVersion=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_Xinerama_XineramaQueryVersion" >&5 $as_echo "$ac_cv_lib_Xinerama_XineramaQueryVersion" >&6; } if test "x$ac_cv_lib_Xinerama_XineramaQueryVersion" = xyes; then : COMMON_XLIBS="-lXinerama $COMMON_XLIBS" else as_fn_error $? "libXinerama not found. Please configure without multimon (using --disable-multimon), configure without X11 (using --without-x), or install the libXinerama devel package(s)." "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XOpenDevice in -lXi" >&5 $as_echo_n "checking for XOpenDevice in -lXi... " >&6; } if ${ac_cv_lib_Xi_XOpenDevice+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXi $COMMON_XLIBS $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 XOpenDevice (); int main () { return XOpenDevice (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xi_XOpenDevice=yes else ac_cv_lib_Xi_XOpenDevice=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_Xi_XOpenDevice" >&5 $as_echo "$ac_cv_lib_Xi_XOpenDevice" >&6; } if test "x$ac_cv_lib_Xi_XOpenDevice" = xyes; then : COMMON_XLIBS="-lXi $COMMON_XLIBS" else as_fn_error $? "libXi not found. Please configure without X11 (using --without-x), or install the libXi devel package(s)." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XRenderQueryVersion in -lXrender" >&5 $as_echo_n "checking for XRenderQueryVersion in -lXrender... " >&6; } if ${ac_cv_lib_Xrender_XRenderQueryVersion+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXrender $COMMON_XLIBS $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 XRenderQueryVersion (); int main () { return XRenderQueryVersion (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xrender_XRenderQueryVersion=yes else ac_cv_lib_Xrender_XRenderQueryVersion=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_Xrender_XRenderQueryVersion" >&5 $as_echo "$ac_cv_lib_Xrender_XRenderQueryVersion" >&6; } if test "x$ac_cv_lib_Xrender_XRenderQueryVersion" = xyes; then : COMMON_XLIBS="-lXrender $COMMON_XLIBS" else as_fn_error $? "libXrender not found. Please configure without X11 (using --without-x), or install the libXrender devel package(s)." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XRRQueryVersion in -lXrandr" >&5 $as_echo_n "checking for XRRQueryVersion in -lXrandr... " >&6; } if ${ac_cv_lib_Xrandr_XRRQueryVersion+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXrandr $COMMON_XLIBS $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 XRRQueryVersion (); int main () { return XRRQueryVersion (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xrandr_XRRQueryVersion=yes else ac_cv_lib_Xrandr_XRRQueryVersion=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_Xrandr_XRRQueryVersion" >&5 $as_echo "$ac_cv_lib_Xrandr_XRRQueryVersion" >&6; } if test "x$ac_cv_lib_Xrandr_XRRQueryVersion" = xyes; then : COMMON_XLIBS="-lXrandr $COMMON_XLIBS" else as_fn_error $? "libXrandr not found. Please configure without X11 (using --without-x) or install the libXrandr devel package(s)." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XTestQueryExtension in -lXtst" >&5 $as_echo_n "checking for XTestQueryExtension in -lXtst... " >&6; } if ${ac_cv_lib_Xtst_XTestQueryExtension+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXtst $COMMON_XLIBS $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 XTestQueryExtension (); int main () { return XTestQueryExtension (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xtst_XTestQueryExtension=yes else ac_cv_lib_Xtst_XTestQueryExtension=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_Xtst_XTestQueryExtension" >&5 $as_echo "$ac_cv_lib_Xtst_XTestQueryExtension" >&6; } if test "x$ac_cv_lib_Xtst_XTestQueryExtension" = xyes; then : COMMON_XLIBS="-lXtst $COMMON_XLIBS" else as_fn_error $? "libXtst not found. Please configure without X11 (using --without-x) or install the libXtst devel package(s)." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SmcOpenConnection in -lSM" >&5 $as_echo_n "checking for SmcOpenConnection in -lSM... " >&6; } if ${ac_cv_lib_SM_SmcOpenConnection+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lSM $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 SmcOpenConnection (); int main () { return SmcOpenConnection (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_SM_SmcOpenConnection=yes else ac_cv_lib_SM_SmcOpenConnection=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_SM_SmcOpenConnection" >&5 $as_echo "$ac_cv_lib_SM_SmcOpenConnection" >&6; } if test "x$ac_cv_lib_SM_SmcOpenConnection" = xyes; then : XSM_LIBS="-lSM -lICE" && have_xsm_lib="yes" else -lICE fi for ac_header in X11/SM/SMlib.h X11/ICE/ICElib.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 have_xsm_header="yes" fi done if test "$have_xsm_lib" = "yes" -a "$have_xsm_header" = "yes"; then have_xsm="yes" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XCompositeQueryExtension in -lXcomposite" >&5 $as_echo_n "checking for XCompositeQueryExtension in -lXcomposite... " >&6; } if ${ac_cv_lib_Xcomposite_XCompositeQueryExtension+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXcomposite $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 XCompositeQueryExtension (); int main () { return XCompositeQueryExtension (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xcomposite_XCompositeQueryExtension=yes else ac_cv_lib_Xcomposite_XCompositeQueryExtension=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_Xcomposite_XCompositeQueryExtension" >&5 $as_echo "$ac_cv_lib_Xcomposite_XCompositeQueryExtension" >&6; } if test "x$ac_cv_lib_Xcomposite_XCompositeQueryExtension" = xyes; then : XCOMPOSITE_LIBS="-lXcomposite" else have_xcomposite="no" fi for ac_header in X11/extensions/Xcomposite.h do : ac_fn_c_check_header_mongrel "$LINENO" "X11/extensions/Xcomposite.h" "ac_cv_header_X11_extensions_Xcomposite_h" "$ac_includes_default" if test "x$ac_cv_header_X11_extensions_Xcomposite_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_X11_EXTENSIONS_XCOMPOSITE_H 1 _ACEOF else have_xcomposite="no" fi done if test "$have_xcomposite" != "no"; then have_xcomposite="yes" fi # Check whether we have gtk+ 2.0. if test "$with_gtk2" != "no"; then # gdk_display_get_default_group (added in gtk+ 2.4.0) is function currently # needed by vmware-user. if test -z "gtk-x11-2.0"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GTK"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GTK_CPPFLAGS}" || test -n "${CUSTOM_GTK_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GTK_LIBS} -lgtk-x11-2.0" if test -n "gtk/gtk.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GTK_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "gtk/gtk.h" "ac_cv_header_gtk_gtk_h" "$ac_includes_default" if test "x$ac_cv_header_gtk_gtk_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "gdk_display_get_default_group"; then ac_vmw_function=gdk_display_get_default_group else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_gtk-x11-2.0_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lgtk-x11-2.0" >&5 $as_echo_n "checking for $ac_vmw_function in -lgtk-x11-2.0... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgtk-x11-2.0 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GTK_CPPFLAGS="${CUSTOM_GTK_CPPFLAGS}" GTK_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "gtk+-2.0"; then if test -n "2.4.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gtk+-2.0 >= 2.4.0 (via pkg-config)" >&5 $as_echo_n "checking for gtk+-2.0 >= 2.4.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gtk+-2.0 >= 2.4.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gtk+-2.0 (via pkg-config)" >&5 $as_echo_n "checking for gtk+-2.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gtk+-2.0'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags gtk+-2.0`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs gtk+-2.0`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GTK_CPPFLAGS="$ac_vmw_cppflags" GTK_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GTK_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GTK_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GTK_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GTK_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true GTK_CPPFLAGS="$GTK_CPPFLAGS -DGTK2" else true as_fn_error $? "Gtk+ 2.0 library not found or too old. Please configure without Gtk+ support (using --without-gtk2) or install the Gtk+ 2.0 devel package." "$LINENO" 5 fi fi # # Check for gtkmm 2.4.0 or greater. # if test "$with_gtkmm" != "no"; then CUSTOM_GTKMM_CPPFLAGS="$CUSTOM_GTKMM_CPPFLAGS $GTK_CPPFLAGS" 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 "gtkmm-2.4"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "GTKMM"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_GTKMM_CPPFLAGS}" || test -n "${CUSTOM_GTKMM_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_GTKMM_LIBS} -lgtkmm-2.4" if test -n "gtkmm.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_GTKMM_CPPFLAGS} $CPPFLAGS" ac_fn_cxx_check_header_mongrel "$LINENO" "gtkmm.h" "ac_cv_header_gtkmm_h" "$ac_includes_default" if test "x$ac_cv_header_gtkmm_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n ""; then ac_vmw_function= else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_gtkmm-2.4_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lgtkmm-2.4" >&5 $as_echo_n "checking for $ac_vmw_function in -lgtkmm-2.4... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgtkmm-2.4 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then GTKMM_CPPFLAGS="${CUSTOM_GTKMM_CPPFLAGS}" GTKMM_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "gtkmm-2.4"; then if test -n "2.4.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gtkmm-2.4 >= 2.4.0 (via pkg-config)" >&5 $as_echo_n "checking for gtkmm-2.4 >= 2.4.0 (via pkg-config)... " >&6; } if pkg-config --exists 'gtkmm-2.4 >= 2.4.0'; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gtkmm-2.4 (via pkg-config)" >&5 $as_echo_n "checking for gtkmm-2.4 (via pkg-config)... " >&6; } if pkg-config --exists 'gtkmm-2.4'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags gtkmm-2.4`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs gtkmm-2.4`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GTKMM_CPPFLAGS="$ac_vmw_cppflags" GTKMM_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then GTKMM_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" GTKMM_LIBS="`$ac_vmw_lib_cfg --ldflags`" else GTKMM_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" GTKMM_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true GTKMM_CPPFLAGS="$GTKMM_CPPFLAGS -DHAVE_GTKMM" else true as_fn_error $? "gtkmm library not found. Please install the libgtkmm devel package(s), or re-configure using --without-gtkmm." "$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 fi fi # End of checks for X libraries { $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 : HAVE_CRYPT="yes" else as_fn_error $? "libcrypt not found. Please install the libc/libcrypt devel package(s)." "$LINENO" 5 fi for ac_func in dlopen do : ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_DLOPEN 1 _ACEOF 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 : VIX_LIBADD="$VIX_LIBADD -ldl" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -ldl" else as_fn_error $? "dlopen was not found, but is required for open-vm-tools to function properly. Please contact your OS vendor." "$LINENO" 5 fi fi done for ac_func in ecvt do : ac_fn_c_check_func "$LINENO" "ecvt" "ac_cv_func_ecvt" if test "x$ac_cv_func_ecvt" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_ECVT 1 _ACEOF fi done for ac_func in fcvt do : ac_fn_c_check_func "$LINENO" "fcvt" "ac_cv_func_fcvt" if test "x$ac_cv_func_fcvt" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_FCVT 1 _ACEOF fi done if test "$os" = "freebsd" -a "$osVersion" -ge 600000; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lthr" >&5 $as_echo_n "checking for pthread_mutex_init in -lthr... " >&6; } if ${ac_cv_lib_thr_pthread_mutex_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lthr $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_mutex_init (); int main () { return pthread_mutex_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_thr_pthread_mutex_init=yes else ac_cv_lib_thr_pthread_mutex_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_thr_pthread_mutex_init" >&5 $as_echo "$ac_cv_lib_thr_pthread_mutex_init" >&6; } if test "x$ac_cv_lib_thr_pthread_mutex_init" = xyes; then : THREAD_LIB=-lthr else as_fn_error $? "Unable to locate required threading library libthr." "$LINENO" 5 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthread" >&5 $as_echo_n "checking for pthread_mutex_init in -lpthread... " >&6; } if ${ac_cv_lib_pthread_pthread_mutex_init+:} 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_mutex_init (); int main () { return pthread_mutex_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread_pthread_mutex_init=yes else ac_cv_lib_pthread_pthread_mutex_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_pthread_pthread_mutex_init" >&5 $as_echo "$ac_cv_lib_pthread_pthread_mutex_init" >&6; } if test "x$ac_cv_lib_pthread_pthread_mutex_init" = xyes; then : THREAD_LIB=-lpthread else as_fn_error $? "libpthread not found. Please install the libc/libpthread devel package(s)." "$LINENO" 5 fi fi # PAM prefix @%:@ Check whether --with-pam-prefix was given. if test "${with_pam_prefix+set}" = set; then : withval=$with_pam_prefix; PAM_PREFIX="$withval" else PAM_PREFIX='$(sysconfdir)' fi if test "$os" = "linux"; then @%:@ Check whether --with-procps was given. if test "${with_procps+set}" = set; then : withval=$with_procps; else with_procps=yes fi else with_procps="no" fi if test "$with_procps" = "yes"; then if test -z "$CUSTOM_PROCPS_NAME"; then CUSTOM_PROCPS_NAME=proc fi # XXX: no pkg-config and no procps-config means we need to # hard-code a sensible default. if test -z "$CUSTOM_PROCPS_LIBS"; then CUSTOM_PROCPS_LIBS="-L/lib" fi # Some distros provide libproc-${version}.so only, others provide the # libproc.so symlink. Try both to see what sticks (but only try the 3.2.7 # and 3.2.8 versions - adding every possible version here would be a mess). # # Users can help by providing CUSTOM_PROCPS_NAME / CUSTOM_PROCPS_LIBS if # necessary. have_procps=no if test -z "$CUSTOM_PROCPS_NAME"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "PROCPS"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_PROCPS_CPPFLAGS}" || test -n "${CUSTOM_PROCPS_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_PROCPS_LIBS} -l$CUSTOM_PROCPS_NAME" if test -n ""; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_PROCPS_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default" if test "x$ac_cv_header_" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "getstat"; then ac_vmw_function=getstat else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_$CUSTOM_PROCPS_NAME''_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -l$CUSTOM_PROCPS_NAME" >&5 $as_echo_n "checking for $ac_vmw_function in -l$CUSTOM_PROCPS_NAME... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-l$CUSTOM_PROCPS_NAME $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then PROCPS_CPPFLAGS="${CUSTOM_PROCPS_CPPFLAGS}" PROCPS_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } PROCPS_CPPFLAGS="$ac_vmw_cppflags" PROCPS_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then PROCPS_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" PROCPS_LIBS="`$ac_vmw_lib_cfg --ldflags`" else PROCPS_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" PROCPS_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_procps=yes; else true fi if test "$have_procps" = "no"; then if test -z "proc-3.2.8"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "PROCPS"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_PROCPS_CPPFLAGS}" || test -n "${CUSTOM_PROCPS_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_PROCPS_LIBS} -lproc-3.2.8" if test -n ""; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_PROCPS_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default" if test "x$ac_cv_header_" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "getstat"; then ac_vmw_function=getstat else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_proc-3.2.8_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lproc-3.2.8" >&5 $as_echo_n "checking for $ac_vmw_function in -lproc-3.2.8... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lproc-3.2.8 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then PROCPS_CPPFLAGS="${CUSTOM_PROCPS_CPPFLAGS}" PROCPS_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } PROCPS_CPPFLAGS="$ac_vmw_cppflags" PROCPS_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then PROCPS_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" PROCPS_LIBS="`$ac_vmw_lib_cfg --ldflags`" else PROCPS_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" PROCPS_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_procps=yes; else true fi fi if test "$have_procps" = "no"; then if test -z "proc-3.2.7"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "PROCPS"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_PROCPS_CPPFLAGS}" || test -n "${CUSTOM_PROCPS_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_PROCPS_LIBS} -lproc-3.2.7" if test -n ""; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_PROCPS_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default" if test "x$ac_cv_header_" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "getstat"; then ac_vmw_function=getstat else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_proc-3.2.7_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -lproc-3.2.7" >&5 $as_echo_n "checking for $ac_vmw_function in -lproc-3.2.7... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lproc-3.2.7 $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then PROCPS_CPPFLAGS="${CUSTOM_PROCPS_CPPFLAGS}" PROCPS_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } PROCPS_CPPFLAGS="$ac_vmw_cppflags" PROCPS_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n ""; then # Extract the first word of "", so it can be a program name with args. set dummy ; 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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then PROCPS_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" PROCPS_LIBS="`$ac_vmw_lib_cfg --ldflags`" else PROCPS_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" PROCPS_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true else true as_fn_error $? "libproc not found. Please configure without procps (using --without-procps) or install procps - http://procps.sourceforge.net" "$LINENO" 5 fi fi fi if test "$with_procps" != "yes"; then $as_echo "@%:@define NO_PROCPS 1" >>confdefs.h fi @%:@ Check whether --with-dnet was given. if test "${with_dnet+set}" = set; then : withval=$with_dnet; else with_dnet=yes fi have_dnet="no" if test "$with_dnet" = "yes"; then # On Debian, dnet is installed via the libdumbnet package. We need to # detect this so that our source files include dumbnet.h instead of # dnet.h, which is part of a different package altogether. if test -z "dumbnet"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "DNET"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_DNET_CPPFLAGS}" || test -n "${CUSTOM_DNET_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_DNET_LIBS} -ldumbnet" if test -n "dumbnet.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_DNET_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "dumbnet.h" "ac_cv_header_dumbnet_h" "$ac_includes_default" if test "x$ac_cv_header_dumbnet_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "intf_open"; then ac_vmw_function=intf_open else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_dumbnet_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -ldumbnet" >&5 $as_echo_n "checking for $ac_vmw_function in -ldumbnet... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldumbnet $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then DNET_CPPFLAGS="${CUSTOM_DNET_CPPFLAGS}" DNET_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } DNET_CPPFLAGS="$ac_vmw_cppflags" DNET_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n "dumbnet-config"; then # Extract the first word of "dumbnet-config", so it can be a program name with args. set dummy dumbnet-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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then DNET_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" DNET_LIBS="`$ac_vmw_lib_cfg --ldflags`" else DNET_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" DNET_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_dnet="yes"; $as_echo "@%:@define DNET_IS_DUMBNET 1" >>confdefs.h else true fi if test $have_dnet = "no"; then if test -z "dnet"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "DNET"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_DNET_CPPFLAGS}" || test -n "${CUSTOM_DNET_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_DNET_LIBS} -ldnet" if test -n "dnet.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_DNET_CPPFLAGS} $CPPFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "dnet.h" "ac_cv_header_dnet_h" "$ac_includes_default" if test "x$ac_cv_header_dnet_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "intf_open"; then ac_vmw_function=intf_open else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_dnet_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -ldnet" >&5 $as_echo_n "checking for $ac_vmw_function in -ldnet... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then DNET_CPPFLAGS="${CUSTOM_DNET_CPPFLAGS}" DNET_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } DNET_CPPFLAGS="$ac_vmw_cppflags" DNET_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n "dnet-config"; then # Extract the first word of "dnet-config", so it can be a program name with args. set dummy dnet-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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then DNET_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" DNET_LIBS="`$ac_vmw_lib_cfg --ldflags`" else DNET_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" DNET_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true have_dnet="yes" else true fi fi if test $have_dnet = "no"; then as_fn_error $? "dnet-config was not found on your PATH. Please configure without dnet (using --without-dnet) or install dnet - http://libdnet.sourceforge.net" "$LINENO" 5 fi fi if test "$with_dnet" != "yes"; then $as_echo "@%:@define NO_DNET 1" >>confdefs.h fi @%:@ Check whether --with-icu was given. if test "${with_icu+set}" = set; then : withval=$with_icu; else with_icu=yes fi if test "$have_x" = "yes" -o "$with_icu" = "yes"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}$CXX", so it can be a program name with args. set dummy ${ac_tool_prefix}$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_prog_have_cxx+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$have_cxx"; then ac_cv_prog_have_cxx="$have_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_have_cxx="${ac_tool_prefix}$CXX" $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 have_cxx=$ac_cv_prog_have_cxx if test -n "$have_cxx"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_cxx" >&5 $as_echo "$have_cxx" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_have_cxx"; then ac_ct_have_cxx=$have_cxx # 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_prog_ac_ct_have_cxx+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_have_cxx"; then ac_cv_prog_ac_ct_have_cxx="$ac_ct_have_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_have_cxx="$CXX" $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_have_cxx=$ac_cv_prog_ac_ct_have_cxx if test -n "$ac_ct_have_cxx"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_have_cxx" >&5 $as_echo "$ac_ct_have_cxx" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_have_cxx" = x; then have_cxx="no" 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 have_cxx=$ac_ct_have_cxx fi else have_cxx="$ac_cv_prog_have_cxx" fi if test "$have_cxx" = "no"; then as_fn_error $? "C++ compiler not found. Make sure you have a C++ compiler installed or configure without X11 (using --without-x) and without ICU (using --without-icu)." "$LINENO" 5 fi fi if test "$with_icu" = "yes"; 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 if test -z "icuuc"; then as_fn_error $? "'library' parameter is required.'" "$LINENO" 5 fi if test -z "ICU"; then as_fn_error $? "'lvar' parameter is required.'" "$LINENO" 5 fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_ICU_CPPFLAGS}" || test -n "${CUSTOM_ICU_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_ICU_LIBS} -licuuc" if test -n "unicode/utf.h"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_ICU_CPPFLAGS} $CPPFLAGS" ac_fn_cxx_check_header_mongrel "$LINENO" "unicode/utf.h" "ac_cv_header_unicode_utf_h" "$ac_includes_default" if test "x$ac_cv_header_unicode_utf_h" = xyes; then : ac_vmw_have_lib_header=1 fi CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n ""; then ac_vmw_function= else ac_vmw_function=strlen fi as_ac_Lib=`$as_echo "ac_cv_lib_icuuc_$ac_vmw_function" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_vmw_function in -licuuc" >&5 $as_echo_n "checking for $ac_vmw_function in -licuuc... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-licuuc $ac_vmw_custom_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 $ac_vmw_function (); int main () { return $ac_vmw_function (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : ac_vmw_have_lib_func=1 fi fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then ICU_CPPFLAGS="${CUSTOM_ICU_CPPFLAGS}" ICU_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n ""; then if test -n ""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for >= (via pkg-config)" >&5 $as_echo_n "checking for >= (via pkg-config)... " >&6; } if pkg-config --exists ' >= '; then ac_vmw_have_lib=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (via pkg-config)" >&5 $as_echo_n "checking for (via pkg-config)... " >&6; } if pkg-config --exists ''; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags `" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs `" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ICU_CPPFLAGS="$ac_vmw_cppflags" ICU_LIBS="$ac_vmw_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 fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n "icu-config"; then # Extract the first word of "icu-config", so it can be a program name with args. set dummy icu-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_ac_vmw_lib_cfg+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_vmw_lib_cfg in [\\/]* | ?:[\\/]*) ac_cv_path_ac_vmw_lib_cfg="$ac_vmw_lib_cfg" # 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_ac_vmw_lib_cfg="$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_ac_vmw_lib_cfg" && ac_cv_path_ac_vmw_lib_cfg="no" ;; esac fi ac_vmw_lib_cfg=$ac_cv_path_ac_vmw_lib_cfg if test -n "$ac_vmw_lib_cfg"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_vmw_lib_cfg" >&5 $as_echo "$ac_vmw_lib_cfg" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then ICU_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" ICU_LIBS="`$ac_vmw_lib_cfg --ldflags`" else ICU_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" ICU_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then true ICU_CPPFLAGS="$ICU_CPPFLAGS -DUSE_ICU" else true as_fn_error $? "ICU library not found. Please configure without ICU (using --without-icu) or install ICU - http://www.icu-project.org" "$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 # Check whether we have ICU >= 3.8. 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 ucasemap_utf8ToTitle in ICU" >&5 $as_echo_n "checking for ucasemap_utf8ToTitle in ICU... " >&6; } ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $ICU_CPPFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { (void) &ucasemap_utf8ToTitle; return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ICU_CPPFLAGS="$ICU_CPPFLAGS -DHAVE_ICU_38" { $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 CPPFLAGS="$ORIGINAL_CPPFLAGS" 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 # Easier to give all modules the ICU defines/includes... CPPFLAGS="$CPPFLAGS $ICU_CPPFLAGS" else CPPFLAGS="$CPPFLAGS -DNO_ICU" fi # Extract the first word of "rpcgen", so it can be a program name with args. set dummy rpcgen; 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_RPCGEN+:} false; then : $as_echo_n "(cached) " >&6 else case $RPCGEN in [\\/]* | ?:[\\/]*) ac_cv_path_RPCGEN="$RPCGEN" # 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_RPCGEN="$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_RPCGEN" && ac_cv_path_RPCGEN=" as_fn_error $? "rpcgen not found. Please install the libc devel package." "$LINENO" 5 " ;; esac fi RPCGEN=$ac_cv_path_RPCGEN if test -n "$RPCGEN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RPCGEN" >&5 $as_echo "$RPCGEN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ### ### Headers ### for ac_header in crypt.h do : ac_fn_c_check_header_mongrel "$LINENO" "crypt.h" "ac_cv_header_crypt_h" "$ac_includes_default" if test "x$ac_cv_header_crypt_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_CRYPT_H 1 _ACEOF fi done for ac_header in inttypes.h do : ac_fn_c_check_header_mongrel "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default" if test "x$ac_cv_header_inttypes_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_INTTYPES_H 1 _ACEOF fi done 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 for ac_header in stdlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" if test "x$ac_cv_header_stdlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_STDLIB_H 1 _ACEOF fi done for ac_header in wchar.h do : ac_fn_c_check_header_mongrel "$LINENO" "wchar.h" "ac_cv_header_wchar_h" "$ac_includes_default" if test "x$ac_cv_header_wchar_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_WCHAR_H 1 _ACEOF fi done for ac_header in sys/inttypes.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/inttypes.h" "ac_cv_header_sys_inttypes_h" "$ac_includes_default" if test "x$ac_cv_header_sys_inttypes_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_INTTYPES_H 1 _ACEOF fi done for ac_header in sys/io.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/io.h" "ac_cv_header_sys_io_h" "$ac_includes_default" if test "x$ac_cv_header_sys_io_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_IO_H 1 _ACEOF fi done for ac_header in sys/param.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default" if test "x$ac_cv_header_sys_param_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_PARAM_H 1 _ACEOF fi done # Required to make the sys/user.h check work correctly on FreeBSD for ac_header in sys/sysinfo.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/sysinfo.h" "ac_cv_header_sys_sysinfo_h" "$ac_includes_default" if test "x$ac_cv_header_sys_sysinfo_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_SYSINFO_H 1 _ACEOF fi done for ac_header in sys/types.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default" if test "x$ac_cv_header_sys_types_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_TYPES_H 1 _ACEOF fi done for ac_header in sys/user.h do : ac_fn_c_check_header_compile "$LINENO" "sys/user.h" "ac_cv_header_sys_user_h" " #ifdef HAVE_SYS_PARAM_H # include #endif " if test "x$ac_cv_header_sys_user_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_USER_H 1 _ACEOF fi done for ac_header in sys/vfs.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/vfs.h" "ac_cv_header_sys_vfs_h" "$ac_includes_default" if test "x$ac_cv_header_sys_vfs_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYS_VFS_H 1 _ACEOF fi done for ac_header in syslimits.h do : ac_fn_c_check_header_mongrel "$LINENO" "syslimits.h" "ac_cv_header_syslimits_h" "$ac_includes_default" if test "x$ac_cv_header_syslimits_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_SYSLIMITS_H 1 _ACEOF fi done for ac_header in unwind.h do : ac_fn_c_check_header_mongrel "$LINENO" "unwind.h" "ac_cv_header_unwind_h" "$ac_includes_default" if test "x$ac_cv_header_unwind_h" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE_UNWIND_H 1 _ACEOF fi done ac_fn_c_check_header_mongrel "$LINENO" "wchar.h" "ac_cv_header_wchar_h" "$ac_includes_default" if test "x$ac_cv_header_wchar_h" = xyes; then : HAVE_WCHAR_H="yes" else HAVE_WCHAR_H="no" fi if test "$os" = "linux"; then # Make sure kernel-headers package is installed. ac_fn_c_check_header_mongrel "$LINENO" "linux/unistd.h" "ac_cv_header_linux_unistd_h" "$ac_includes_default" if test "x$ac_cv_header_linux_unistd_h" = xyes; then : else as_fn_error $? "linux/unistd.h is not found. Please install kernel-headers/linux-userspace-headers/linux-libc-dev package." "$LINENO" 5 fi fi if test "$enable_multimon" != "no"; then ac_fn_c_check_header_compile "$LINENO" "X11/extensions/panoramiXproto.h" "ac_cv_header_X11_extensions_panoramiXproto_h" "#include #include " if test "x$ac_cv_header_X11_extensions_panoramiXproto_h" = xyes; then : else as_fn_error $? "panoramiXproto.h not found. Please configure without multimon (using --disable-multimon) or install the libXinerama devel package(s)." "$LINENO" 5 fi fi bsdPrintfWrappers=no if test "$os" = "linux"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ecvt in -lc" >&5 $as_echo_n "checking for ecvt in -lc... " >&6; } if ${ac_cv_lib_c_ecvt+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc $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 ecvt (); int main () { return ecvt (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_c_ecvt=yes else ac_cv_lib_c_ecvt=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_ecvt" >&5 $as_echo "$ac_cv_lib_c_ecvt" >&6; } if test "x$ac_cv_lib_c_ecvt" = xyes; then : bsdPrintfWrappers=yes fi fi ### ### Typdefs, structs, and compiler quarks. ### { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } if ${ac_cv_header_stdbool_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef bool "error: bool is not defined" #endif #ifndef false "error: false is not defined" #endif #if false "error: false is not 0" #endif #ifndef true "error: true is not defined" #endif #if true != 1 "error: true is not 1" #endif #ifndef __bool_true_false_are_defined "error: __bool_true_false_are_defined is not defined" #endif struct s { _Bool s: 1; _Bool t; } s; char a[true == 1 ? 1 : -1]; char b[false == 0 ? 1 : -1]; char c[__bool_true_false_are_defined == 1 ? 1 : -1]; char d[(bool) 0.5 == true ? 1 : -1]; /* See body of main program for 'e'. */ char f[(_Bool) 0.0 == false ? 1 : -1]; char g[true]; char h[sizeof (_Bool)]; char i[sizeof s.t]; enum { j = false, k = true, l = false * true, m = true * 256 }; /* The following fails for HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ _Bool n[m]; char o[sizeof n == m * sizeof n[0] ? 1 : -1]; char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; /* Catch a bug in an HP-UX C compiler. See http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html */ _Bool q = true; _Bool *pq = &q; int main () { bool e = &s; *pq |= q; *pq |= ! q; /* Refer to every declared value, to avoid compiler optimizations. */ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + !m + !n + !o + !p + !q + !pq); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdbool_h=yes else ac_cv_header_stdbool_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_stdbool_h" >&5 $as_echo "$ac_cv_header_stdbool_h" >&6; } ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" if test "x$ac_cv_type__Bool" = xyes; then : cat >>confdefs.h <<_ACEOF @%:@define HAVE__BOOL 1 _ACEOF fi if test $ac_cv_header_stdbool_h = yes; then $as_echo "@%:@define HAVE_STDBOOL_H 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 { $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 { $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" "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 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" "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" "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_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 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 { $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 working volatile" >&5 $as_echo_n "checking for working volatile... " >&6; } if ${ac_cv_c_volatile+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { volatile int x; int * volatile y = (int *) 0; return !x && !y; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_volatile=yes else ac_cv_c_volatile=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_volatile" >&5 $as_echo "$ac_cv_c_volatile" >&6; } if test $ac_cv_c_volatile = no; then $as_echo "@%:@define volatile /**/" >>confdefs.h fi ### ### Specific features and OS/arch flags / actions ### ### General flags / actions CFLAGS="$CFLAGS -Wall" CFLAGS="$CFLAGS -Werror" # -Wno-unknown-pragmas is due to gcc not understanding '#pragma ident' in Xlib.h on OpenSolaris. for TEST_CFLAG in -Wno-pointer-sign -Wno-unused-value -fno-strict-aliasing \ -Wno-unknown-pragmas -Wno-uninitialized; do { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC flag $TEST_CFLAG" >&5 $as_echo_n "checking for GCC flag $TEST_CFLAG... " >&6; } ORIGINAL_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $TEST_CFLAG" NEW_CFLAG="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : NEW_CFLAG=" $TEST_CFLAG" { $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 CFLAGS="$ORIGINAL_CFLAGS$NEW_CFLAG" done CPPFLAGS="$CPPFLAGS -DVMX86_TOOLS" CPPFLAGS="$CPPFLAGS" # -fvisibility is used by "core service" plugins, but not required. ORIGINAL_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fvisibility=hidden" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC flag -fvisibility" >&5 $as_echo_n "checking for GCC flag -fvisibility... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : PLUGIN_CPPFLAGS="-fvisibility=hidden -DGCC_EXPLICIT_EXPORT"; { $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 CFLAGS="$ORIGINAL_CFLAGS" # Detect "unused-but-set-variable" gcc warning and disable it. ORIGINAL_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Wno-unused-but-set-variable" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC flag -Wno-unused-but-set-variable" >&5 $as_echo_n "checking for GCC flag -Wno-unused-but-set-variable... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ORIGINAL_CFLAGS="$ORIGINAL_CFLAGS -Wno-unused-but-set-variable"; { $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 CFLAGS="$ORIGINAL_CFLAGS" BUILDDIR="`pwd`" INCLUDE_DIR="`cd $srcdir; pwd`/lib/include" BLD_INCLUDE_DIR="$BUILDDIR/lib/include" CPPFLAGS="-I$INCLUDE_DIR -I$BLD_INCLUDE_DIR $CPPFLAGS" ### ### Documentation. ### if test "$enable_docs" = "yes"; then # Extract the first word of "doxygen", so it can be a program name with args. set dummy doxygen; 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_have_doxygen+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$have_doxygen"; then ac_cv_prog_have_doxygen="$have_doxygen" # 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_have_doxygen="yes" $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_prog_have_doxygen" && ac_cv_prog_have_doxygen="no" fi fi have_doxygen=$ac_cv_prog_have_doxygen if test -n "$have_doxygen"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_doxygen" >&5 $as_echo "$have_doxygen" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$have_doxygen" = "no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: doxygen not found; API documentation will not be generated." >&5 $as_echo "$as_me: WARNING: doxygen not found; API documentation will not be generated." >&2;} else # Extract the first word of "dot", so it can be a program name with args. set dummy dot; 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_DOT+:} false; then : $as_echo_n "(cached) " >&6 else case $DOT in [\\/]* | ?:[\\/]*) ac_cv_path_DOT="$DOT" # 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_DOT="$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 DOT=$ac_cv_path_DOT if test -n "$DOT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOT" >&5 $as_echo "$DOT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$DOT" = ""; then HAVE_DOT=NO else DOT=`dirname $DOT` HAVE_DOT=YES fi # Extract the first word of "mscgen", so it can be a program name with args. set dummy mscgen; 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_MSCGEN+:} false; then : $as_echo_n "(cached) " >&6 else case $MSCGEN in [\\/]* | ?:[\\/]*) ac_cv_path_MSCGEN="$MSCGEN" # 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_MSCGEN="$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_MSCGEN" && ac_cv_path_MSCGEN="no" ;; esac fi MSCGEN=$ac_cv_path_MSCGEN if test -n "$MSCGEN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSCGEN" >&5 $as_echo "$MSCGEN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$MSCGEN" != "no"; then MSCGEN_DIR="`dirname $MSCGEN`" else MSCGEN_DIR= fi fi fi ### ### OS/arch-specific flags / actions ### MODULES="" MODULES_OS="$os" TARGET_OS="$os" MODULES_DIR="" buildHgfsmounter=no if test "$have_glib_2_14" = "yes"; then CPPFLAGS="$CPPFLAGS -DHAVE_GLIB_REGEX" fi if test "$os" = "linux"; then MODULES_DIR="$LINUXDIR/kernel/" CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64" CPPFLAGS="$CPPFLAGS -D_LARGEFILE64_SOURCE" CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=500" CPPFLAGS="$CPPFLAGS -D_BSD_SOURCE" CPPFLAGS="$CPPFLAGS -D_SVID_SOURCE" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lrt" MODULES="$MODULES vmsync vmci vsock" MODULES="$MODULES vmxnet vmblock vmhgfs" buildHgfsmounter=yes fi if test "$os" = "freebsd"; then LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lkvm" MODULES_DIR="/boot/modules" if test "$osVersion" -ge 302000; then MODULES="$MODULES vmmemctl" fi if test "$osVersion" -ge 409000; then MODULES="$MODULES vmxnet" fi if test "$osVersion" -ge 600000; then MODULES="$MODULES vmblock vmhgfs" buildHgfsmounter=yes fi if test "$with_kernel_modules" = "yes"; then echo "****************************************************************" echo " You are building FreeBSD kernel modules. Make sure you use " echo " 'make' to build open-vm-tools, and not GNU make ('gmake'). " echo "****************************************************************" fi fi if test "$os" = "solaris"; then LIB_IMPERSONATE_CPPFLAGS="$LIB_IMPERSONATE_CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS" LIB_USER_CPPFLAGS="$LIB_USER_CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lsocket" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lnsl" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lresolv" LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lrpcsvc" # Setup defines to identify the OS version. if test "$osVersion" -eq 509000; then CPPFLAGS="$CPPFLAGS -DSOL9" fi if test "$osVersion" -eq 510000; then CPPFLAGS="$CPPFLAGS -DSOL10" fi if test "$osVersion" -eq 511000; then CPPFLAGS="$CPPFLAGS -DSOL11" fi MODULES="$MODULES vmxnet vmmemctl" # HGFS and vmblock need Solaris 10 at least. if test "$osVersion" -ge 510000; then MODULES="$MODULES vmhgfs vmblock" fi # vmxnet3 is built on Solaris 10 / 11 only if GLDv3 is installed. if test "$osVersion" -gt 510000; then ac_fn_c_check_header_mongrel "$LINENO" "sys/mac.h" "ac_cv_header_sys_mac_h" "$ac_includes_default" if test "x$ac_cv_header_sys_mac_h" = xyes; then : MODULES="$MODULES vmxnet3" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GLDv3 (sys/mac.h) is not installed, vmxnet3 will not be compiled." >&5 $as_echo "$as_me: WARNING: GLDv3 (sys/mac.h) is not installed, vmxnet3 will not be compiled." >&2;} fi fi if test "$with_kernel_modules" = "yes"; then echo "****************************************************************" echo " You are building Solaris kernel modules. Make sure you use " echo " GNU make to build open-vm-tools. " echo "****************************************************************" fi fi if test "$buildHgfsmounter" = "yes"; then BUILD_HGFSMOUNTER_TRUE= BUILD_HGFSMOUNTER_FALSE='#' else BUILD_HGFSMOUNTER_TRUE='#' BUILD_HGFSMOUNTER_FALSE= fi if test "$os" = "linux"; then LINUX_TRUE= LINUX_FALSE='#' else LINUX_TRUE='#' LINUX_FALSE= fi if test "$os" = "solaris"; then SOLARIS_TRUE= SOLARIS_FALSE='#' else SOLARIS_TRUE='#' SOLARIS_FALSE= fi if test "$os" = "freebsd"; then FREEBSD_TRUE= FREEBSD_FALSE='#' else FREEBSD_TRUE='#' FREEBSD_FALSE= fi if test "$os" = "freebsd" -a -n "$SYSDIR"; then FREEBSD_CUSTOM_SYSDIR_TRUE= FREEBSD_CUSTOM_SYSDIR_FALSE='#' else FREEBSD_CUSTOM_SYSDIR_TRUE='#' FREEBSD_CUSTOM_SYSDIR_FALSE= fi if test "$userSpaceBitness" = "32"; then THIRTY_TWO_BIT_USERSPACE_TRUE= THIRTY_TWO_BIT_USERSPACE_FALSE='#' else THIRTY_TWO_BIT_USERSPACE_TRUE='#' THIRTY_TWO_BIT_USERSPACE_FALSE= fi if test "$have_x" = "yes"; then HAVE_X11_TRUE= HAVE_X11_FALSE='#' else HAVE_X11_TRUE='#' HAVE_X11_FALSE= fi if test "$with_icu" = "yes"; then HAVE_ICU_TRUE= HAVE_ICU_FALSE='#' else HAVE_ICU_TRUE='#' HAVE_ICU_FALSE= fi if test "$with_kernel_modules" = "yes"; then WITH_KERNEL_MODULES_TRUE= WITH_KERNEL_MODULES_FALSE='#' else WITH_KERNEL_MODULES_TRUE='#' WITH_KERNEL_MODULES_FALSE= fi if test "$have_xsm" = "yes"; then HAVE_XSM_TRUE= HAVE_XSM_FALSE='#' else HAVE_XSM_TRUE='#' HAVE_XSM_FALSE= fi if test "$have_xcomposite" = "yes"; then HAVE_XCOMPOSITE_TRUE= HAVE_XCOMPOSITE_FALSE='#' else HAVE_XCOMPOSITE_TRUE='#' HAVE_XCOMPOSITE_FALSE= fi if test "$have_cunit" = "yes"; then ENABLE_TESTS_TRUE= ENABLE_TESTS_FALSE='#' else ENABLE_TESTS_TRUE='#' ENABLE_TESTS_FALSE= fi if test "$with_root_privileges" = "yes"; then WITH_ROOT_PRIVILEGES_TRUE= WITH_ROOT_PRIVILEGES_FALSE='#' else WITH_ROOT_PRIVILEGES_TRUE='#' WITH_ROOT_PRIVILEGES_FALSE= fi if test "$have_dnet" = "yes"; then HAVE_DNET_TRUE= HAVE_DNET_FALSE='#' else HAVE_DNET_TRUE='#' HAVE_DNET_FALSE= fi if test "$have_doxygen" = "yes"; then HAVE_DOXYGEN_TRUE= HAVE_DOXYGEN_FALSE='#' else HAVE_DOXYGEN_TRUE='#' HAVE_DOXYGEN_FALSE= fi if test "$have_fuse" = "yes"; then HAVE_FUSE_TRUE= HAVE_FUSE_FALSE='#' else HAVE_FUSE_TRUE='#' HAVE_FUSE_FALSE= fi if test "$with_gnu_ld" = "yes"; then HAVE_GNU_LD_TRUE= HAVE_GNU_LD_FALSE='#' else HAVE_GNU_LD_TRUE='#' HAVE_GNU_LD_FALSE= fi if test "$have_x" = "yes" -a "$with_gtkmm" = "yes"; then HAVE_GTKMM_TRUE= HAVE_GTKMM_FALSE='#' else HAVE_GTKMM_TRUE='#' HAVE_GTKMM_FALSE= fi if test "$with_pam" = "yes"; then HAVE_PAM_TRUE= HAVE_PAM_FALSE='#' else HAVE_PAM_TRUE='#' HAVE_PAM_FALSE= fi if test "os" = "linux" -a "$have_glib_2_14" = "yes"; then USE_SLASH_PROC_TRUE= USE_SLASH_PROC_FALSE='#' else USE_SLASH_PROC_TRUE='#' USE_SLASH_PROC_FALSE= fi if test "$bsdPrintfWrappers" = "yes"; then USE_PRINTF_WRAPPERS_TRUE= USE_PRINTF_WRAPPERS_FALSE='#' else USE_PRINTF_WRAPPERS_TRUE='#' USE_PRINTF_WRAPPERS_FALSE= fi if test "$have_xsm" != "yes"; then $as_echo "@%:@define NO_XSM 1" >>confdefs.h fi if test "$have_xcomposite" != "yes"; then $as_echo "@%:@define NO_XCOMPOSITE 1" >>confdefs.h fi ### Feature-specific flags / actions # Combine where possible # If control reaches this point and multimon is still enabled, then we know # all of the tests for required components have passed and it's safe to allow # multimon. Otherwise, it should be disabled. if test "$enable_multimon" = "no"; then # XXX: For consistency, change this to ENABLE_MULTIMON. This will require # some additional code cleanup. $as_echo "@%:@define NO_MULTIMON 1" >>confdefs.h fi LIB_AUTH_CPPFLAGS="$LIB_AUTH_CPPFLAGS $PAM_CPPFLAGS" if test "$HAVE_CRYPT" = "yes"; then LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lcrypt" VIX_LIBADD="$VIX_LIBADD -lcrypt" fi LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD $THREAD_LIB" VIX_LIBADD="$VIX_LIBADD $THREAD_LIB" ### Core Services definitions. HGFS_LIBS="$BUILDDIR/libhgfs/libhgfs.la" VMTOOLS_LIBS="$BUILDDIR/libvmtools/libvmtools.la $GLIB2_LIBS" VMTOOLS_CPPFLAGS="-DVMTOOLS_USE_GLIB $GLIB2_CPPFLAGS" PLUGIN_CPPFLAGS="$VMTOOLS_CPPFLAGS $PLUGIN_CPPFLAGS" PLUGIN_LDFLAGS="-Wl,-z,defs -Wl,-lc -shared -module -avoid-version" # In Solaris, the XDR-related functions are not in libc like in Linux and # FreeBSD, so binaries need to be linked to some extra libraries. XDR_LIBS= if test "$os" = "solaris"; then XDR_LIBS="-lnsl -lrpcsvc" fi # Installation directories for core services plugins. TEST_PLUGIN_INSTALLDIR=$datadir/open-vm-tools/tests COMMON_PLUGIN_INSTALLDIR=$libdir/open-vm-tools/plugins/common VMSVC_PLUGIN_INSTALLDIR=$libdir/open-vm-tools/plugins/vmsvc VMUSR_PLUGIN_INSTALLDIR=$libdir/open-vm-tools/plugins/vmusr # General definitions INSTVMSG='$(SHELL) $(top_srcdir)/scripts/build/instvmsg.sh' RPCGEN_WRAPPER='$(SHELL) $(top_builddir)/scripts/build/rpcgen_wrapper.sh' ### General substs if test "$os" = "freebsd" -a -n "$SYSDIR"; then # If SYSDIR is not defined, AC_SUBST expands to nothing, so we need something # inside this block. true fi ### Lib substs ### Program substs ### ### Create the Makefiles ### ac_config_files="$ac_config_files Makefile lib/Makefile lib/appUtil/Makefile lib/auth/Makefile lib/backdoor/Makefile lib/dict/Makefile lib/dynxdr/Makefile lib/err/Makefile lib/file/Makefile lib/foundryMsg/Makefile lib/glibUtils/Makefile lib/guestApp/Makefile lib/guestRpc/Makefile lib/hgfs/Makefile lib/hgfsBd/Makefile lib/hgfsHelper/Makefile lib/hgfsServer/Makefile lib/hgfsServerManagerGuest/Makefile lib/hgfsServerPolicyGuest/Makefile lib/impersonate/Makefile lib/lock/Makefile lib/message/Makefile lib/misc/Makefile lib/netUtil/Makefile lib/panic/Makefile lib/panicDefault/Makefile lib/printer/Makefile lib/procMgr/Makefile lib/rpcChannel/Makefile lib/rpcIn/Makefile lib/rpcOut/Makefile lib/rpcVmx/Makefile lib/slashProc/Makefile lib/string/Makefile lib/stubs/Makefile lib/syncDriver/Makefile lib/system/Makefile lib/unicode/Makefile lib/user/Makefile lib/vmCheck/Makefile lib/vmSignal/Makefile lib/wiper/Makefile lib/xdg/Makefile services/Makefile services/vmtoolsd/Makefile services/plugins/Makefile services/plugins/desktopEvents/Makefile services/plugins/dndcp/Makefile services/plugins/guestInfo/Makefile services/plugins/guestInfo/getlib/Makefile services/plugins/hgfsServer/Makefile services/plugins/powerOps/Makefile services/plugins/resolutionSet/Makefile services/plugins/timeSync/Makefile services/plugins/vix/Makefile services/plugins/vmbackup/Makefile vmware-user-suid-wrapper/Makefile toolbox/Makefile hgfsclient/Makefile hgfsmounter/Makefile checkvm/Makefile rpctool/Makefile libguestlib/Makefile libguestlib/vmguestlib.pc libhgfs/Makefile libvmtools/Makefile xferlogs/Makefile modules/Makefile vmblock-fuse/Makefile vmblockmounter/Makefile tests/Makefile tests/vmrpcdbg/Makefile tests/testDebug/Makefile tests/testPlugin/Makefile tests/testVmblock/Makefile docs/Makefile docs/api/Makefile scripts/Makefile scripts/build/rpcgen_wrapper.sh" ### ### Output ### 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}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIB@&t@OBJS; 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 LIB@&t@OBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_HGFSMOUNTER_TRUE}" && test -z "${BUILD_HGFSMOUNTER_FALSE}"; then as_fn_error $? "conditional \"BUILD_HGFSMOUNTER\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${LINUX_TRUE}" && test -z "${LINUX_FALSE}"; then as_fn_error $? "conditional \"LINUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${SOLARIS_TRUE}" && test -z "${SOLARIS_FALSE}"; then as_fn_error $? "conditional \"SOLARIS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${FREEBSD_TRUE}" && test -z "${FREEBSD_FALSE}"; then as_fn_error $? "conditional \"FREEBSD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${FREEBSD_CUSTOM_SYSDIR_TRUE}" && test -z "${FREEBSD_CUSTOM_SYSDIR_FALSE}"; then as_fn_error $? "conditional \"FREEBSD_CUSTOM_SYSDIR\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${THIRTY_TWO_BIT_USERSPACE_TRUE}" && test -z "${THIRTY_TWO_BIT_USERSPACE_FALSE}"; then as_fn_error $? "conditional \"THIRTY_TWO_BIT_USERSPACE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_X11_TRUE}" && test -z "${HAVE_X11_FALSE}"; then as_fn_error $? "conditional \"HAVE_X11\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_ICU_TRUE}" && test -z "${HAVE_ICU_FALSE}"; then as_fn_error $? "conditional \"HAVE_ICU\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_KERNEL_MODULES_TRUE}" && test -z "${WITH_KERNEL_MODULES_FALSE}"; then as_fn_error $? "conditional \"WITH_KERNEL_MODULES\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_XSM_TRUE}" && test -z "${HAVE_XSM_FALSE}"; then as_fn_error $? "conditional \"HAVE_XSM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_XCOMPOSITE_TRUE}" && test -z "${HAVE_XCOMPOSITE_FALSE}"; then as_fn_error $? "conditional \"HAVE_XCOMPOSITE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_TESTS_TRUE}" && test -z "${ENABLE_TESTS_FALSE}"; then as_fn_error $? "conditional \"ENABLE_TESTS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_ROOT_PRIVILEGES_TRUE}" && test -z "${WITH_ROOT_PRIVILEGES_FALSE}"; then as_fn_error $? "conditional \"WITH_ROOT_PRIVILEGES\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_DNET_TRUE}" && test -z "${HAVE_DNET_FALSE}"; then as_fn_error $? "conditional \"HAVE_DNET\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_DOXYGEN_TRUE}" && test -z "${HAVE_DOXYGEN_FALSE}"; then as_fn_error $? "conditional \"HAVE_DOXYGEN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_FUSE_TRUE}" && test -z "${HAVE_FUSE_FALSE}"; then as_fn_error $? "conditional \"HAVE_FUSE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_GNU_LD_TRUE}" && test -z "${HAVE_GNU_LD_FALSE}"; then as_fn_error $? "conditional \"HAVE_GNU_LD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_GTKMM_TRUE}" && test -z "${HAVE_GTKMM_FALSE}"; then as_fn_error $? "conditional \"HAVE_GTKMM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_PAM_TRUE}" && test -z "${HAVE_PAM_FALSE}"; then as_fn_error $? "conditional \"HAVE_PAM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${USE_SLASH_PROC_TRUE}" && test -z "${USE_SLASH_PROC_FALSE}"; then as_fn_error $? "conditional \"USE_SLASH_PROC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${USE_PRINTF_WRAPPERS_TRUE}" && test -z "${USE_PRINTF_WRAPPERS_FALSE}"; then as_fn_error $? "conditional \"USE_PRINTF_WRAPPERS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${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 @S|@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 @S|@? 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 @S|@as_val. Take advantage of shells that can avoid forks. The arguments @%:@ must be portable across @S|@(()) 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 "@S|@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 open-vm-tools $as_me 9.4.0, 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 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" 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 Configuration files: $config_files Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ open-vm-tools config.status 9.4.0 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' MKDIR_P='$MKDIR_P' 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;; --he | --h | --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 # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # 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' _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 "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; "lib/appUtil/Makefile") CONFIG_FILES="$CONFIG_FILES lib/appUtil/Makefile" ;; "lib/auth/Makefile") CONFIG_FILES="$CONFIG_FILES lib/auth/Makefile" ;; "lib/backdoor/Makefile") CONFIG_FILES="$CONFIG_FILES lib/backdoor/Makefile" ;; "lib/dict/Makefile") CONFIG_FILES="$CONFIG_FILES lib/dict/Makefile" ;; "lib/dynxdr/Makefile") CONFIG_FILES="$CONFIG_FILES lib/dynxdr/Makefile" ;; "lib/err/Makefile") CONFIG_FILES="$CONFIG_FILES lib/err/Makefile" ;; "lib/file/Makefile") CONFIG_FILES="$CONFIG_FILES lib/file/Makefile" ;; "lib/foundryMsg/Makefile") CONFIG_FILES="$CONFIG_FILES lib/foundryMsg/Makefile" ;; "lib/glibUtils/Makefile") CONFIG_FILES="$CONFIG_FILES lib/glibUtils/Makefile" ;; "lib/guestApp/Makefile") CONFIG_FILES="$CONFIG_FILES lib/guestApp/Makefile" ;; "lib/guestRpc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/guestRpc/Makefile" ;; "lib/hgfs/Makefile") CONFIG_FILES="$CONFIG_FILES lib/hgfs/Makefile" ;; "lib/hgfsBd/Makefile") CONFIG_FILES="$CONFIG_FILES lib/hgfsBd/Makefile" ;; "lib/hgfsHelper/Makefile") CONFIG_FILES="$CONFIG_FILES lib/hgfsHelper/Makefile" ;; "lib/hgfsServer/Makefile") CONFIG_FILES="$CONFIG_FILES lib/hgfsServer/Makefile" ;; "lib/hgfsServerManagerGuest/Makefile") CONFIG_FILES="$CONFIG_FILES lib/hgfsServerManagerGuest/Makefile" ;; "lib/hgfsServerPolicyGuest/Makefile") CONFIG_FILES="$CONFIG_FILES lib/hgfsServerPolicyGuest/Makefile" ;; "lib/impersonate/Makefile") CONFIG_FILES="$CONFIG_FILES lib/impersonate/Makefile" ;; "lib/lock/Makefile") CONFIG_FILES="$CONFIG_FILES lib/lock/Makefile" ;; "lib/message/Makefile") CONFIG_FILES="$CONFIG_FILES lib/message/Makefile" ;; "lib/misc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/misc/Makefile" ;; "lib/netUtil/Makefile") CONFIG_FILES="$CONFIG_FILES lib/netUtil/Makefile" ;; "lib/panic/Makefile") CONFIG_FILES="$CONFIG_FILES lib/panic/Makefile" ;; "lib/panicDefault/Makefile") CONFIG_FILES="$CONFIG_FILES lib/panicDefault/Makefile" ;; "lib/printer/Makefile") CONFIG_FILES="$CONFIG_FILES lib/printer/Makefile" ;; "lib/procMgr/Makefile") CONFIG_FILES="$CONFIG_FILES lib/procMgr/Makefile" ;; "lib/rpcChannel/Makefile") CONFIG_FILES="$CONFIG_FILES lib/rpcChannel/Makefile" ;; "lib/rpcIn/Makefile") CONFIG_FILES="$CONFIG_FILES lib/rpcIn/Makefile" ;; "lib/rpcOut/Makefile") CONFIG_FILES="$CONFIG_FILES lib/rpcOut/Makefile" ;; "lib/rpcVmx/Makefile") CONFIG_FILES="$CONFIG_FILES lib/rpcVmx/Makefile" ;; "lib/slashProc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/slashProc/Makefile" ;; "lib/string/Makefile") CONFIG_FILES="$CONFIG_FILES lib/string/Makefile" ;; "lib/stubs/Makefile") CONFIG_FILES="$CONFIG_FILES lib/stubs/Makefile" ;; "lib/syncDriver/Makefile") CONFIG_FILES="$CONFIG_FILES lib/syncDriver/Makefile" ;; "lib/system/Makefile") CONFIG_FILES="$CONFIG_FILES lib/system/Makefile" ;; "lib/unicode/Makefile") CONFIG_FILES="$CONFIG_FILES lib/unicode/Makefile" ;; "lib/user/Makefile") CONFIG_FILES="$CONFIG_FILES lib/user/Makefile" ;; "lib/vmCheck/Makefile") CONFIG_FILES="$CONFIG_FILES lib/vmCheck/Makefile" ;; "lib/vmSignal/Makefile") CONFIG_FILES="$CONFIG_FILES lib/vmSignal/Makefile" ;; "lib/wiper/Makefile") CONFIG_FILES="$CONFIG_FILES lib/wiper/Makefile" ;; "lib/xdg/Makefile") CONFIG_FILES="$CONFIG_FILES lib/xdg/Makefile" ;; "services/Makefile") CONFIG_FILES="$CONFIG_FILES services/Makefile" ;; "services/vmtoolsd/Makefile") CONFIG_FILES="$CONFIG_FILES services/vmtoolsd/Makefile" ;; "services/plugins/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/Makefile" ;; "services/plugins/desktopEvents/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/desktopEvents/Makefile" ;; "services/plugins/dndcp/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/dndcp/Makefile" ;; "services/plugins/guestInfo/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/guestInfo/Makefile" ;; "services/plugins/guestInfo/getlib/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/guestInfo/getlib/Makefile" ;; "services/plugins/hgfsServer/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/hgfsServer/Makefile" ;; "services/plugins/powerOps/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/powerOps/Makefile" ;; "services/plugins/resolutionSet/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/resolutionSet/Makefile" ;; "services/plugins/timeSync/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/timeSync/Makefile" ;; "services/plugins/vix/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/vix/Makefile" ;; "services/plugins/vmbackup/Makefile") CONFIG_FILES="$CONFIG_FILES services/plugins/vmbackup/Makefile" ;; "vmware-user-suid-wrapper/Makefile") CONFIG_FILES="$CONFIG_FILES vmware-user-suid-wrapper/Makefile" ;; "toolbox/Makefile") CONFIG_FILES="$CONFIG_FILES toolbox/Makefile" ;; "hgfsclient/Makefile") CONFIG_FILES="$CONFIG_FILES hgfsclient/Makefile" ;; "hgfsmounter/Makefile") CONFIG_FILES="$CONFIG_FILES hgfsmounter/Makefile" ;; "checkvm/Makefile") CONFIG_FILES="$CONFIG_FILES checkvm/Makefile" ;; "rpctool/Makefile") CONFIG_FILES="$CONFIG_FILES rpctool/Makefile" ;; "libguestlib/Makefile") CONFIG_FILES="$CONFIG_FILES libguestlib/Makefile" ;; "libguestlib/vmguestlib.pc") CONFIG_FILES="$CONFIG_FILES libguestlib/vmguestlib.pc" ;; "libhgfs/Makefile") CONFIG_FILES="$CONFIG_FILES libhgfs/Makefile" ;; "libvmtools/Makefile") CONFIG_FILES="$CONFIG_FILES libvmtools/Makefile" ;; "xferlogs/Makefile") CONFIG_FILES="$CONFIG_FILES xferlogs/Makefile" ;; "modules/Makefile") CONFIG_FILES="$CONFIG_FILES modules/Makefile" ;; "vmblock-fuse/Makefile") CONFIG_FILES="$CONFIG_FILES vmblock-fuse/Makefile" ;; "vmblockmounter/Makefile") CONFIG_FILES="$CONFIG_FILES vmblockmounter/Makefile" ;; "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; "tests/vmrpcdbg/Makefile") CONFIG_FILES="$CONFIG_FILES tests/vmrpcdbg/Makefile" ;; "tests/testDebug/Makefile") CONFIG_FILES="$CONFIG_FILES tests/testDebug/Makefile" ;; "tests/testPlugin/Makefile") CONFIG_FILES="$CONFIG_FILES tests/testPlugin/Makefile" ;; "tests/testVmblock/Makefile") CONFIG_FILES="$CONFIG_FILES tests/testVmblock/Makefile" ;; "docs/Makefile") CONFIG_FILES="$CONFIG_FILES docs/Makefile" ;; "docs/api/Makefile") CONFIG_FILES="$CONFIG_FILES docs/api/Makefile" ;; "scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;; "scripts/build/rpcgen_wrapper.sh") CONFIG_FILES="$CONFIG_FILES scripts/build/rpcgen_wrapper.sh" ;; *) 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_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 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 { 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 = "" } { 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 } print line } _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" eval set X " :F $CONFIG_FILES :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 ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; 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 s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$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 ;; :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 "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "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 ;; 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 open-vm-tools-9.4.0-1280544/autom4te.cache/traces.10000644765153500003110000023775512220061620017621 0ustar dtormtsm4trace:aclocal.m4:1008: -1- m4_include([m4/libtool.m4]) m4trace:aclocal.m4:1009: -1- m4_include([m4/ltoptions.m4]) m4trace:aclocal.m4:1010: -1- m4_include([m4/ltsugar.m4]) m4trace:aclocal.m4:1011: -1- m4_include([m4/ltversion.m4]) m4trace:aclocal.m4:1012: -1- m4_include([m4/lt~obsolete.m4]) m4trace:aclocal.m4:1013: -1- m4_include([m4/vmtools.m4]) m4trace:configure.ac:43: -1- AC_INIT([open-vm-tools], [9.4.0], [open-vm-tools-devel@lists.sourceforge.net]) m4trace:configure.ac:43: -1- m4_pattern_forbid([^_?A[CHUM]_]) m4trace:configure.ac:43: -1- m4_pattern_forbid([_AC_]) m4trace:configure.ac:43: -1- m4_pattern_forbid([^LIBOBJS$], [do not use LIBOBJS directly, use AC_LIBOBJ (see section `AC_LIBOBJ vs LIBOBJS']) m4trace:configure.ac:43: -1- m4_pattern_allow([^AS_FLAGS$]) m4trace:configure.ac:43: -1- m4_pattern_forbid([^_?m4_]) m4trace:configure.ac:43: -1- m4_pattern_forbid([^dnl$]) m4trace:configure.ac:43: -1- m4_pattern_forbid([^_?AS_]) m4trace:configure.ac:43: -1- AC_SUBST([SHELL]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([SHELL]) m4trace:configure.ac:43: -1- m4_pattern_allow([^SHELL$]) m4trace:configure.ac:43: -1- AC_SUBST([PATH_SEPARATOR]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([PATH_SEPARATOR]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PATH_SEPARATOR$]) m4trace:configure.ac:43: -1- AC_SUBST([PACKAGE_NAME], [m4_ifdef([AC_PACKAGE_NAME], ['AC_PACKAGE_NAME'])]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([PACKAGE_NAME]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_NAME$]) m4trace:configure.ac:43: -1- AC_SUBST([PACKAGE_TARNAME], [m4_ifdef([AC_PACKAGE_TARNAME], ['AC_PACKAGE_TARNAME'])]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([PACKAGE_TARNAME]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_TARNAME$]) m4trace:configure.ac:43: -1- AC_SUBST([PACKAGE_VERSION], [m4_ifdef([AC_PACKAGE_VERSION], ['AC_PACKAGE_VERSION'])]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([PACKAGE_VERSION]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_VERSION$]) m4trace:configure.ac:43: -1- AC_SUBST([PACKAGE_STRING], [m4_ifdef([AC_PACKAGE_STRING], ['AC_PACKAGE_STRING'])]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([PACKAGE_STRING]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_STRING$]) m4trace:configure.ac:43: -1- AC_SUBST([PACKAGE_BUGREPORT], [m4_ifdef([AC_PACKAGE_BUGREPORT], ['AC_PACKAGE_BUGREPORT'])]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([PACKAGE_BUGREPORT]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$]) m4trace:configure.ac:43: -1- AC_SUBST([PACKAGE_URL], [m4_ifdef([AC_PACKAGE_URL], ['AC_PACKAGE_URL'])]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([PACKAGE_URL]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_URL$]) m4trace:configure.ac:43: -1- AC_SUBST([exec_prefix], [NONE]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([exec_prefix]) m4trace:configure.ac:43: -1- m4_pattern_allow([^exec_prefix$]) m4trace:configure.ac:43: -1- AC_SUBST([prefix], [NONE]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([prefix]) m4trace:configure.ac:43: -1- m4_pattern_allow([^prefix$]) m4trace:configure.ac:43: -1- AC_SUBST([program_transform_name], [s,x,x,]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([program_transform_name]) m4trace:configure.ac:43: -1- m4_pattern_allow([^program_transform_name$]) m4trace:configure.ac:43: -1- AC_SUBST([bindir], ['${exec_prefix}/bin']) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([bindir]) m4trace:configure.ac:43: -1- m4_pattern_allow([^bindir$]) m4trace:configure.ac:43: -1- AC_SUBST([sbindir], ['${exec_prefix}/sbin']) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([sbindir]) m4trace:configure.ac:43: -1- m4_pattern_allow([^sbindir$]) m4trace:configure.ac:43: -1- AC_SUBST([libexecdir], ['${exec_prefix}/libexec']) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([libexecdir]) m4trace:configure.ac:43: -1- m4_pattern_allow([^libexecdir$]) m4trace:configure.ac:43: -1- AC_SUBST([datarootdir], ['${prefix}/share']) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([datarootdir]) m4trace:configure.ac:43: -1- m4_pattern_allow([^datarootdir$]) m4trace:configure.ac:43: -1- AC_SUBST([datadir], ['${datarootdir}']) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([datadir]) m4trace:configure.ac:43: -1- m4_pattern_allow([^datadir$]) m4trace:configure.ac:43: -1- AC_SUBST([sysconfdir], ['${prefix}/etc']) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([sysconfdir]) m4trace:configure.ac:43: -1- m4_pattern_allow([^sysconfdir$]) m4trace:configure.ac:43: -1- AC_SUBST([sharedstatedir], ['${prefix}/com']) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([sharedstatedir]) m4trace:configure.ac:43: -1- m4_pattern_allow([^sharedstatedir$]) m4trace:configure.ac:43: -1- AC_SUBST([localstatedir], ['${prefix}/var']) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([localstatedir]) m4trace:configure.ac:43: -1- m4_pattern_allow([^localstatedir$]) m4trace:configure.ac:43: -1- AC_SUBST([includedir], ['${prefix}/include']) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([includedir]) m4trace:configure.ac:43: -1- m4_pattern_allow([^includedir$]) m4trace:configure.ac:43: -1- AC_SUBST([oldincludedir], ['/usr/include']) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([oldincludedir]) m4trace:configure.ac:43: -1- m4_pattern_allow([^oldincludedir$]) m4trace:configure.ac:43: -1- AC_SUBST([docdir], [m4_ifset([AC_PACKAGE_TARNAME], ['${datarootdir}/doc/${PACKAGE_TARNAME}'], ['${datarootdir}/doc/${PACKAGE}'])]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([docdir]) m4trace:configure.ac:43: -1- m4_pattern_allow([^docdir$]) m4trace:configure.ac:43: -1- AC_SUBST([infodir], ['${datarootdir}/info']) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([infodir]) m4trace:configure.ac:43: -1- m4_pattern_allow([^infodir$]) m4trace:configure.ac:43: -1- AC_SUBST([htmldir], ['${docdir}']) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([htmldir]) m4trace:configure.ac:43: -1- m4_pattern_allow([^htmldir$]) m4trace:configure.ac:43: -1- AC_SUBST([dvidir], ['${docdir}']) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([dvidir]) m4trace:configure.ac:43: -1- m4_pattern_allow([^dvidir$]) m4trace:configure.ac:43: -1- AC_SUBST([pdfdir], ['${docdir}']) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([pdfdir]) m4trace:configure.ac:43: -1- m4_pattern_allow([^pdfdir$]) m4trace:configure.ac:43: -1- AC_SUBST([psdir], ['${docdir}']) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([psdir]) m4trace:configure.ac:43: -1- m4_pattern_allow([^psdir$]) m4trace:configure.ac:43: -1- AC_SUBST([libdir], ['${exec_prefix}/lib']) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([libdir]) m4trace:configure.ac:43: -1- m4_pattern_allow([^libdir$]) m4trace:configure.ac:43: -1- AC_SUBST([localedir], ['${datarootdir}/locale']) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([localedir]) m4trace:configure.ac:43: -1- m4_pattern_allow([^localedir$]) m4trace:configure.ac:43: -1- AC_SUBST([mandir], ['${datarootdir}/man']) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([mandir]) m4trace:configure.ac:43: -1- m4_pattern_allow([^mandir$]) m4trace:configure.ac:43: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_NAME]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_NAME$]) m4trace:configure.ac:43: -1- AH_OUTPUT([PACKAGE_NAME], [/* Define to the full name of this package. */ @%:@undef PACKAGE_NAME]) m4trace:configure.ac:43: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_TARNAME]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_TARNAME$]) m4trace:configure.ac:43: -1- AH_OUTPUT([PACKAGE_TARNAME], [/* Define to the one symbol short name of this package. */ @%:@undef PACKAGE_TARNAME]) m4trace:configure.ac:43: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_VERSION]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_VERSION$]) m4trace:configure.ac:43: -1- AH_OUTPUT([PACKAGE_VERSION], [/* Define to the version of this package. */ @%:@undef PACKAGE_VERSION]) m4trace:configure.ac:43: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_STRING]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_STRING$]) m4trace:configure.ac:43: -1- AH_OUTPUT([PACKAGE_STRING], [/* Define to the full name and version of this package. */ @%:@undef PACKAGE_STRING]) m4trace:configure.ac:43: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_BUGREPORT]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$]) m4trace:configure.ac:43: -1- AH_OUTPUT([PACKAGE_BUGREPORT], [/* Define to the address where bug reports for this package should be sent. */ @%:@undef PACKAGE_BUGREPORT]) m4trace:configure.ac:43: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_URL]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_URL$]) m4trace:configure.ac:43: -1- AH_OUTPUT([PACKAGE_URL], [/* Define to the home page for this package. */ @%:@undef PACKAGE_URL]) m4trace:configure.ac:43: -1- AC_SUBST([DEFS]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([DEFS]) m4trace:configure.ac:43: -1- m4_pattern_allow([^DEFS$]) m4trace:configure.ac:43: -1- AC_SUBST([ECHO_C]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([ECHO_C]) m4trace:configure.ac:43: -1- m4_pattern_allow([^ECHO_C$]) m4trace:configure.ac:43: -1- AC_SUBST([ECHO_N]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([ECHO_N]) m4trace:configure.ac:43: -1- m4_pattern_allow([^ECHO_N$]) m4trace:configure.ac:43: -1- AC_SUBST([ECHO_T]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([ECHO_T]) m4trace:configure.ac:43: -1- m4_pattern_allow([^ECHO_T$]) m4trace:configure.ac:43: -1- AC_SUBST([LIBS]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([LIBS]) m4trace:configure.ac:43: -1- m4_pattern_allow([^LIBS$]) m4trace:configure.ac:43: -1- AC_SUBST([build_alias]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([build_alias]) m4trace:configure.ac:43: -1- m4_pattern_allow([^build_alias$]) m4trace:configure.ac:43: -1- AC_SUBST([host_alias]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([host_alias]) m4trace:configure.ac:43: -1- m4_pattern_allow([^host_alias$]) m4trace:configure.ac:43: -1- AC_SUBST([target_alias]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([target_alias]) m4trace:configure.ac:43: -1- m4_pattern_allow([^target_alias$]) m4trace:configure.ac:71: -1- AC_CONFIG_AUX_DIR([config]) m4trace:configure.ac:74: -1- AC_CANONICAL_HOST m4trace:configure.ac:74: -1- AC_CANONICAL_BUILD m4trace:configure.ac:74: -1- AC_REQUIRE_AUX_FILE([config.sub]) m4trace:configure.ac:74: -1- AC_REQUIRE_AUX_FILE([config.guess]) m4trace:configure.ac:74: -1- AC_SUBST([build], [$ac_cv_build]) m4trace:configure.ac:74: -1- AC_SUBST_TRACE([build]) m4trace:configure.ac:74: -1- m4_pattern_allow([^build$]) m4trace:configure.ac:74: -1- AC_SUBST([build_cpu], [$[1]]) m4trace:configure.ac:74: -1- AC_SUBST_TRACE([build_cpu]) m4trace:configure.ac:74: -1- m4_pattern_allow([^build_cpu$]) m4trace:configure.ac:74: -1- AC_SUBST([build_vendor], [$[2]]) m4trace:configure.ac:74: -1- AC_SUBST_TRACE([build_vendor]) m4trace:configure.ac:74: -1- m4_pattern_allow([^build_vendor$]) m4trace:configure.ac:74: -1- AC_SUBST([build_os]) m4trace:configure.ac:74: -1- AC_SUBST_TRACE([build_os]) m4trace:configure.ac:74: -1- m4_pattern_allow([^build_os$]) m4trace:configure.ac:74: -1- AC_SUBST([host], [$ac_cv_host]) m4trace:configure.ac:74: -1- AC_SUBST_TRACE([host]) m4trace:configure.ac:74: -1- m4_pattern_allow([^host$]) m4trace:configure.ac:74: -1- AC_SUBST([host_cpu], [$[1]]) m4trace:configure.ac:74: -1- AC_SUBST_TRACE([host_cpu]) m4trace:configure.ac:74: -1- m4_pattern_allow([^host_cpu$]) m4trace:configure.ac:74: -1- AC_SUBST([host_vendor], [$[2]]) m4trace:configure.ac:74: -1- AC_SUBST_TRACE([host_vendor]) m4trace:configure.ac:74: -1- m4_pattern_allow([^host_vendor$]) m4trace:configure.ac:74: -1- AC_SUBST([host_os]) m4trace:configure.ac:74: -1- AC_SUBST_TRACE([host_os]) m4trace:configure.ac:74: -1- m4_pattern_allow([^host_os$]) m4trace:configure.ac:75: -1- AC_CANONICAL_BUILD m4trace:configure.ac:210: -1- AM_INIT_AUTOMAKE m4trace:configure.ac:210: -1- m4_pattern_allow([^AM_[A-Z]+FLAGS$]) m4trace:configure.ac:210: -1- AM_AUTOMAKE_VERSION([1.12.2]) m4trace:configure.ac:210: -1- AC_REQUIRE_AUX_FILE([install-sh]) m4trace:configure.ac:210: -1- AC_SUBST([INSTALL_PROGRAM]) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([INSTALL_PROGRAM]) m4trace:configure.ac:210: -1- m4_pattern_allow([^INSTALL_PROGRAM$]) m4trace:configure.ac:210: -1- AC_SUBST([INSTALL_SCRIPT]) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([INSTALL_SCRIPT]) m4trace:configure.ac:210: -1- m4_pattern_allow([^INSTALL_SCRIPT$]) m4trace:configure.ac:210: -1- AC_SUBST([INSTALL_DATA]) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([INSTALL_DATA]) m4trace:configure.ac:210: -1- m4_pattern_allow([^INSTALL_DATA$]) m4trace:configure.ac:210: -1- AC_SUBST([am__isrc], [' -I$(srcdir)']) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([am__isrc]) m4trace:configure.ac:210: -1- m4_pattern_allow([^am__isrc$]) m4trace:configure.ac:210: -1- _AM_SUBST_NOTMAKE([am__isrc]) m4trace:configure.ac:210: -1- AC_SUBST([CYGPATH_W]) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([CYGPATH_W]) m4trace:configure.ac:210: -1- m4_pattern_allow([^CYGPATH_W$]) m4trace:configure.ac:210: -1- AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME']) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([PACKAGE]) m4trace:configure.ac:210: -1- m4_pattern_allow([^PACKAGE$]) m4trace:configure.ac:210: -1- AC_SUBST([VERSION], ['AC_PACKAGE_VERSION']) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([VERSION]) m4trace:configure.ac:210: -1- m4_pattern_allow([^VERSION$]) m4trace:configure.ac:210: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE]) m4trace:configure.ac:210: -1- m4_pattern_allow([^PACKAGE$]) m4trace:configure.ac:210: -1- AH_OUTPUT([PACKAGE], [/* Name of package */ @%:@undef PACKAGE]) m4trace:configure.ac:210: -1- AC_DEFINE_TRACE_LITERAL([VERSION]) m4trace:configure.ac:210: -1- m4_pattern_allow([^VERSION$]) m4trace:configure.ac:210: -1- AH_OUTPUT([VERSION], [/* Version number of package */ @%:@undef VERSION]) m4trace:configure.ac:210: -1- AC_REQUIRE_AUX_FILE([missing]) m4trace:configure.ac:210: -1- AC_SUBST([ACLOCAL]) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([ACLOCAL]) m4trace:configure.ac:210: -1- m4_pattern_allow([^ACLOCAL$]) m4trace:configure.ac:210: -1- AC_SUBST([AUTOCONF]) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([AUTOCONF]) m4trace:configure.ac:210: -1- m4_pattern_allow([^AUTOCONF$]) m4trace:configure.ac:210: -1- AC_SUBST([AUTOMAKE]) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([AUTOMAKE]) m4trace:configure.ac:210: -1- m4_pattern_allow([^AUTOMAKE$]) m4trace:configure.ac:210: -1- AC_SUBST([AUTOHEADER]) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([AUTOHEADER]) m4trace:configure.ac:210: -1- m4_pattern_allow([^AUTOHEADER$]) m4trace:configure.ac:210: -1- AC_SUBST([MAKEINFO]) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([MAKEINFO]) m4trace:configure.ac:210: -1- m4_pattern_allow([^MAKEINFO$]) m4trace:configure.ac:210: -1- AC_SUBST([install_sh]) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([install_sh]) m4trace:configure.ac:210: -1- m4_pattern_allow([^install_sh$]) m4trace:configure.ac:210: -1- AC_SUBST([STRIP]) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([STRIP]) m4trace:configure.ac:210: -1- m4_pattern_allow([^STRIP$]) m4trace:configure.ac:210: -1- AC_SUBST([INSTALL_STRIP_PROGRAM]) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([INSTALL_STRIP_PROGRAM]) m4trace:configure.ac:210: -1- m4_pattern_allow([^INSTALL_STRIP_PROGRAM$]) m4trace:configure.ac:210: -1- AC_REQUIRE_AUX_FILE([install-sh]) m4trace:configure.ac:210: -1- AC_SUBST([MKDIR_P]) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([MKDIR_P]) m4trace:configure.ac:210: -1- m4_pattern_allow([^MKDIR_P$]) m4trace:configure.ac:210: -1- AC_SUBST([mkdir_p], ['$(MKDIR_P)']) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([mkdir_p]) m4trace:configure.ac:210: -1- m4_pattern_allow([^mkdir_p$]) m4trace:configure.ac:210: -1- AC_SUBST([AWK]) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([AWK]) m4trace:configure.ac:210: -1- m4_pattern_allow([^AWK$]) m4trace:configure.ac:210: -1- AC_SUBST([SET_MAKE]) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([SET_MAKE]) m4trace:configure.ac:210: -1- m4_pattern_allow([^SET_MAKE$]) m4trace:configure.ac:210: -1- AC_SUBST([am__leading_dot]) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([am__leading_dot]) m4trace:configure.ac:210: -1- m4_pattern_allow([^am__leading_dot$]) m4trace:configure.ac:210: -1- AC_SUBST([AMTAR], ['$${TAR-tar}']) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([AMTAR]) m4trace:configure.ac:210: -1- m4_pattern_allow([^AMTAR$]) m4trace:configure.ac:210: -1- AC_SUBST([am__tar]) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([am__tar]) m4trace:configure.ac:210: -1- m4_pattern_allow([^am__tar$]) m4trace:configure.ac:210: -1- AC_SUBST([am__untar]) m4trace:configure.ac:210: -1- AC_SUBST_TRACE([am__untar]) m4trace:configure.ac:210: -1- m4_pattern_allow([^am__untar$]) m4trace:configure.ac:233: -1- AC_SUBST([CC]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:233: -1- AC_SUBST([CFLAGS]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([CFLAGS]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CFLAGS$]) m4trace:configure.ac:233: -1- AC_SUBST([LDFLAGS]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([LDFLAGS]) m4trace:configure.ac:233: -1- m4_pattern_allow([^LDFLAGS$]) m4trace:configure.ac:233: -1- AC_SUBST([LIBS]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([LIBS]) m4trace:configure.ac:233: -1- m4_pattern_allow([^LIBS$]) m4trace:configure.ac:233: -1- AC_SUBST([CPPFLAGS]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([CPPFLAGS]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:233: -1- AC_SUBST([CC]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:233: -1- AC_SUBST([CC]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:233: -1- AC_SUBST([CC]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:233: -1- AC_SUBST([CC]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:233: -1- AC_SUBST([ac_ct_CC]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([ac_ct_CC]) m4trace:configure.ac:233: -1- m4_pattern_allow([^ac_ct_CC$]) m4trace:configure.ac:233: -1- AC_SUBST([EXEEXT], [$ac_cv_exeext]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([EXEEXT]) m4trace:configure.ac:233: -1- m4_pattern_allow([^EXEEXT$]) m4trace:configure.ac:233: -1- AC_SUBST([OBJEXT], [$ac_cv_objext]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([OBJEXT]) m4trace:configure.ac:233: -1- m4_pattern_allow([^OBJEXT$]) m4trace:configure.ac:233: -1- AC_SUBST([DEPDIR], ["${am__leading_dot}deps"]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([DEPDIR]) m4trace:configure.ac:233: -1- m4_pattern_allow([^DEPDIR$]) m4trace:configure.ac:233: -1- AC_SUBST([am__include]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([am__include]) m4trace:configure.ac:233: -1- m4_pattern_allow([^am__include$]) m4trace:configure.ac:233: -1- AC_SUBST([am__quote]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([am__quote]) m4trace:configure.ac:233: -1- m4_pattern_allow([^am__quote$]) m4trace:configure.ac:233: -1- AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) m4trace:configure.ac:233: -1- AC_SUBST([AMDEP_TRUE]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([AMDEP_TRUE]) m4trace:configure.ac:233: -1- m4_pattern_allow([^AMDEP_TRUE$]) m4trace:configure.ac:233: -1- AC_SUBST([AMDEP_FALSE]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([AMDEP_FALSE]) m4trace:configure.ac:233: -1- m4_pattern_allow([^AMDEP_FALSE$]) m4trace:configure.ac:233: -1- _AM_SUBST_NOTMAKE([AMDEP_TRUE]) m4trace:configure.ac:233: -1- _AM_SUBST_NOTMAKE([AMDEP_FALSE]) m4trace:configure.ac:233: -1- AC_SUBST([AMDEPBACKSLASH]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([AMDEPBACKSLASH]) m4trace:configure.ac:233: -1- m4_pattern_allow([^AMDEPBACKSLASH$]) m4trace:configure.ac:233: -1- _AM_SUBST_NOTMAKE([AMDEPBACKSLASH]) m4trace:configure.ac:233: -1- AC_SUBST([am__nodep]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([am__nodep]) m4trace:configure.ac:233: -1- m4_pattern_allow([^am__nodep$]) m4trace:configure.ac:233: -1- _AM_SUBST_NOTMAKE([am__nodep]) m4trace:configure.ac:233: -1- AC_SUBST([CCDEPMODE], [depmode=$am_cv_CC_dependencies_compiler_type]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([CCDEPMODE]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CCDEPMODE$]) m4trace:configure.ac:233: -1- AM_CONDITIONAL([am__fastdepCC], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3]) m4trace:configure.ac:233: -1- AC_SUBST([am__fastdepCC_TRUE]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([am__fastdepCC_TRUE]) m4trace:configure.ac:233: -1- m4_pattern_allow([^am__fastdepCC_TRUE$]) m4trace:configure.ac:233: -1- AC_SUBST([am__fastdepCC_FALSE]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([am__fastdepCC_FALSE]) m4trace:configure.ac:233: -1- m4_pattern_allow([^am__fastdepCC_FALSE$]) m4trace:configure.ac:233: -1- _AM_SUBST_NOTMAKE([am__fastdepCC_TRUE]) m4trace:configure.ac:233: -1- _AM_SUBST_NOTMAKE([am__fastdepCC_FALSE]) m4trace:configure.ac:233: -1- AC_SUBST([CPP]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([CPP]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CPP$]) m4trace:configure.ac:233: -1- AC_SUBST([CPPFLAGS]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([CPPFLAGS]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:233: -1- AC_SUBST([CPP]) m4trace:configure.ac:233: -1- AC_SUBST_TRACE([CPP]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CPP$]) m4trace:configure.ac:234: -1- AC_SUBST([CC]) m4trace:configure.ac:234: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:234: -1- AC_SUBST([CFLAGS]) m4trace:configure.ac:234: -1- AC_SUBST_TRACE([CFLAGS]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CFLAGS$]) m4trace:configure.ac:234: -1- AC_SUBST([LDFLAGS]) m4trace:configure.ac:234: -1- AC_SUBST_TRACE([LDFLAGS]) m4trace:configure.ac:234: -1- m4_pattern_allow([^LDFLAGS$]) m4trace:configure.ac:234: -1- AC_SUBST([LIBS]) m4trace:configure.ac:234: -1- AC_SUBST_TRACE([LIBS]) m4trace:configure.ac:234: -1- m4_pattern_allow([^LIBS$]) m4trace:configure.ac:234: -1- AC_SUBST([CPPFLAGS]) m4trace:configure.ac:234: -1- AC_SUBST_TRACE([CPPFLAGS]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:234: -1- AC_SUBST([CC]) m4trace:configure.ac:234: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:234: -1- AC_SUBST([CC]) m4trace:configure.ac:234: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:234: -1- AC_SUBST([CC]) m4trace:configure.ac:234: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:234: -1- AC_SUBST([CC]) m4trace:configure.ac:234: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:234: -1- AC_SUBST([ac_ct_CC]) m4trace:configure.ac:234: -1- AC_SUBST_TRACE([ac_ct_CC]) m4trace:configure.ac:234: -1- m4_pattern_allow([^ac_ct_CC$]) m4trace:configure.ac:234: -1- AC_SUBST([CCDEPMODE], [depmode=$am_cv_CC_dependencies_compiler_type]) m4trace:configure.ac:234: -1- AC_SUBST_TRACE([CCDEPMODE]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CCDEPMODE$]) m4trace:configure.ac:234: -1- AM_CONDITIONAL([am__fastdepCC], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3]) m4trace:configure.ac:234: -1- AC_SUBST([am__fastdepCC_TRUE]) m4trace:configure.ac:234: -1- AC_SUBST_TRACE([am__fastdepCC_TRUE]) m4trace:configure.ac:234: -1- m4_pattern_allow([^am__fastdepCC_TRUE$]) m4trace:configure.ac:234: -1- AC_SUBST([am__fastdepCC_FALSE]) m4trace:configure.ac:234: -1- AC_SUBST_TRACE([am__fastdepCC_FALSE]) m4trace:configure.ac:234: -1- m4_pattern_allow([^am__fastdepCC_FALSE$]) m4trace:configure.ac:234: -1- _AM_SUBST_NOTMAKE([am__fastdepCC_TRUE]) m4trace:configure.ac:234: -1- _AM_SUBST_NOTMAKE([am__fastdepCC_FALSE]) m4trace:configure.ac:238: -1- AC_SUBST([CXX]) m4trace:configure.ac:238: -1- AC_SUBST_TRACE([CXX]) m4trace:configure.ac:238: -1- m4_pattern_allow([^CXX$]) m4trace:configure.ac:238: -1- AC_SUBST([CXXFLAGS]) m4trace:configure.ac:238: -1- AC_SUBST_TRACE([CXXFLAGS]) m4trace:configure.ac:238: -1- m4_pattern_allow([^CXXFLAGS$]) m4trace:configure.ac:238: -1- AC_SUBST([LDFLAGS]) m4trace:configure.ac:238: -1- AC_SUBST_TRACE([LDFLAGS]) m4trace:configure.ac:238: -1- m4_pattern_allow([^LDFLAGS$]) m4trace:configure.ac:238: -1- AC_SUBST([LIBS]) m4trace:configure.ac:238: -1- AC_SUBST_TRACE([LIBS]) m4trace:configure.ac:238: -1- m4_pattern_allow([^LIBS$]) m4trace:configure.ac:238: -1- AC_SUBST([CPPFLAGS]) m4trace:configure.ac:238: -1- AC_SUBST_TRACE([CPPFLAGS]) m4trace:configure.ac:238: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:238: -1- AC_SUBST([CXX]) m4trace:configure.ac:238: -1- AC_SUBST_TRACE([CXX]) m4trace:configure.ac:238: -1- m4_pattern_allow([^CXX$]) m4trace:configure.ac:238: -1- AC_SUBST([ac_ct_CXX]) m4trace:configure.ac:238: -1- AC_SUBST_TRACE([ac_ct_CXX]) m4trace:configure.ac:238: -1- m4_pattern_allow([^ac_ct_CXX$]) m4trace:configure.ac:238: -1- AC_SUBST([CXXDEPMODE], [depmode=$am_cv_CXX_dependencies_compiler_type]) m4trace:configure.ac:238: -1- AC_SUBST_TRACE([CXXDEPMODE]) m4trace:configure.ac:238: -1- m4_pattern_allow([^CXXDEPMODE$]) m4trace:configure.ac:238: -1- AM_CONDITIONAL([am__fastdepCXX], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3]) m4trace:configure.ac:238: -1- AC_SUBST([am__fastdepCXX_TRUE]) m4trace:configure.ac:238: -1- AC_SUBST_TRACE([am__fastdepCXX_TRUE]) m4trace:configure.ac:238: -1- m4_pattern_allow([^am__fastdepCXX_TRUE$]) m4trace:configure.ac:238: -1- AC_SUBST([am__fastdepCXX_FALSE]) m4trace:configure.ac:238: -1- AC_SUBST_TRACE([am__fastdepCXX_FALSE]) m4trace:configure.ac:238: -1- m4_pattern_allow([^am__fastdepCXX_FALSE$]) m4trace:configure.ac:238: -1- _AM_SUBST_NOTMAKE([am__fastdepCXX_TRUE]) m4trace:configure.ac:238: -1- _AM_SUBST_NOTMAKE([am__fastdepCXX_FALSE]) m4trace:configure.ac:243: -1- AM_PROG_CC_C_O m4trace:configure.ac:243: -1- AC_DEFINE_TRACE_LITERAL([NO_MINUS_C_MINUS_O]) m4trace:configure.ac:243: -1- m4_pattern_allow([^NO_MINUS_C_MINUS_O$]) m4trace:configure.ac:243: -1- AH_OUTPUT([NO_MINUS_C_MINUS_O], [/* Define to 1 if your C compiler doesn\'t accept -c and -o together. */ @%:@undef NO_MINUS_C_MINUS_O]) m4trace:configure.ac:243: -1- AC_REQUIRE_AUX_FILE([compile]) m4trace:configure.ac:247: -1- AC_SUBST([SED]) m4trace:configure.ac:247: -1- AC_SUBST_TRACE([SED]) m4trace:configure.ac:247: -1- m4_pattern_allow([^SED$]) m4trace:configure.ac:248: -1- AC_SUBST([LN_S], [$as_ln_s]) m4trace:configure.ac:248: -1- AC_SUBST_TRACE([LN_S]) m4trace:configure.ac:248: -1- m4_pattern_allow([^LN_S$]) m4trace:configure.ac:252: -1- AC_PROG_LIBTOOL m4trace:configure.ac:252: -1- _m4_warn([obsolete], [The macro `AC_PROG_LIBTOOL' is obsolete. You should run autoupdate.], [m4/libtool.m4:107: AC_PROG_LIBTOOL is expanded from... configure.ac:252: the top level]) m4trace:configure.ac:252: -1- LT_INIT m4trace:configure.ac:252: -1- m4_pattern_forbid([^_?LT_[A-Z_]+$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$]) m4trace:configure.ac:252: -1- AC_REQUIRE_AUX_FILE([ltmain.sh]) m4trace:configure.ac:252: -1- AC_SUBST([LIBTOOL]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([LIBTOOL]) m4trace:configure.ac:252: -1- m4_pattern_allow([^LIBTOOL$]) m4trace:configure.ac:252: -1- AC_SUBST([SED]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([SED]) m4trace:configure.ac:252: -1- m4_pattern_allow([^SED$]) m4trace:configure.ac:252: -1- AC_SUBST([GREP]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([GREP]) m4trace:configure.ac:252: -1- m4_pattern_allow([^GREP$]) m4trace:configure.ac:252: -1- AC_SUBST([EGREP]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([EGREP]) m4trace:configure.ac:252: -1- m4_pattern_allow([^EGREP$]) m4trace:configure.ac:252: -1- AC_SUBST([FGREP]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([FGREP]) m4trace:configure.ac:252: -1- m4_pattern_allow([^FGREP$]) m4trace:configure.ac:252: -1- AC_SUBST([GREP]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([GREP]) m4trace:configure.ac:252: -1- m4_pattern_allow([^GREP$]) m4trace:configure.ac:252: -1- AC_SUBST([LD]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([LD]) m4trace:configure.ac:252: -1- m4_pattern_allow([^LD$]) m4trace:configure.ac:252: -1- AC_SUBST([DUMPBIN]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([DUMPBIN]) m4trace:configure.ac:252: -1- m4_pattern_allow([^DUMPBIN$]) m4trace:configure.ac:252: -1- AC_SUBST([ac_ct_DUMPBIN]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([ac_ct_DUMPBIN]) m4trace:configure.ac:252: -1- m4_pattern_allow([^ac_ct_DUMPBIN$]) m4trace:configure.ac:252: -1- AC_SUBST([DUMPBIN]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([DUMPBIN]) m4trace:configure.ac:252: -1- m4_pattern_allow([^DUMPBIN$]) m4trace:configure.ac:252: -1- AC_SUBST([NM]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([NM]) m4trace:configure.ac:252: -1- m4_pattern_allow([^NM$]) m4trace:configure.ac:252: -1- AC_SUBST([OBJDUMP]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([OBJDUMP]) m4trace:configure.ac:252: -1- m4_pattern_allow([^OBJDUMP$]) m4trace:configure.ac:252: -1- AC_SUBST([OBJDUMP]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([OBJDUMP]) m4trace:configure.ac:252: -1- m4_pattern_allow([^OBJDUMP$]) m4trace:configure.ac:252: -1- AC_SUBST([DLLTOOL]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([DLLTOOL]) m4trace:configure.ac:252: -1- m4_pattern_allow([^DLLTOOL$]) m4trace:configure.ac:252: -1- AC_SUBST([DLLTOOL]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([DLLTOOL]) m4trace:configure.ac:252: -1- m4_pattern_allow([^DLLTOOL$]) m4trace:configure.ac:252: -1- AC_SUBST([AR]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([AR]) m4trace:configure.ac:252: -1- m4_pattern_allow([^AR$]) m4trace:configure.ac:252: -1- AC_SUBST([ac_ct_AR]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([ac_ct_AR]) m4trace:configure.ac:252: -1- m4_pattern_allow([^ac_ct_AR$]) m4trace:configure.ac:252: -1- AC_SUBST([STRIP]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([STRIP]) m4trace:configure.ac:252: -1- m4_pattern_allow([^STRIP$]) m4trace:configure.ac:252: -1- AC_SUBST([RANLIB]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([RANLIB]) m4trace:configure.ac:252: -1- m4_pattern_allow([^RANLIB$]) m4trace:configure.ac:252: -1- m4_pattern_allow([LT_OBJDIR]) m4trace:configure.ac:252: -1- AC_DEFINE_TRACE_LITERAL([LT_OBJDIR]) m4trace:configure.ac:252: -1- m4_pattern_allow([^LT_OBJDIR$]) m4trace:configure.ac:252: -1- AH_OUTPUT([LT_OBJDIR], [/* Define to the sub-directory in which libtool stores uninstalled libraries. */ @%:@undef LT_OBJDIR]) m4trace:configure.ac:252: -1- LT_SUPPORTED_TAG([CC]) m4trace:configure.ac:252: -1- AC_SUBST([MANIFEST_TOOL]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([MANIFEST_TOOL]) m4trace:configure.ac:252: -1- m4_pattern_allow([^MANIFEST_TOOL$]) m4trace:configure.ac:252: -1- AC_SUBST([DSYMUTIL]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([DSYMUTIL]) m4trace:configure.ac:252: -1- m4_pattern_allow([^DSYMUTIL$]) m4trace:configure.ac:252: -1- AC_SUBST([NMEDIT]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([NMEDIT]) m4trace:configure.ac:252: -1- m4_pattern_allow([^NMEDIT$]) m4trace:configure.ac:252: -1- AC_SUBST([LIPO]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([LIPO]) m4trace:configure.ac:252: -1- m4_pattern_allow([^LIPO$]) m4trace:configure.ac:252: -1- AC_SUBST([OTOOL]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([OTOOL]) m4trace:configure.ac:252: -1- m4_pattern_allow([^OTOOL$]) m4trace:configure.ac:252: -1- AC_SUBST([OTOOL64]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([OTOOL64]) m4trace:configure.ac:252: -1- m4_pattern_allow([^OTOOL64$]) m4trace:configure.ac:252: -1- AH_OUTPUT([HAVE_DLFCN_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_DLFCN_H]) m4trace:configure.ac:252: -1- AC_DEFINE_TRACE_LITERAL([STDC_HEADERS]) m4trace:configure.ac:252: -1- m4_pattern_allow([^STDC_HEADERS$]) m4trace:configure.ac:252: -1- AH_OUTPUT([STDC_HEADERS], [/* Define to 1 if you have the ANSI C header files. */ @%:@undef STDC_HEADERS]) m4trace:configure.ac:252: -1- AH_OUTPUT([HAVE_SYS_TYPES_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_SYS_TYPES_H]) m4trace:configure.ac:252: -1- AH_OUTPUT([HAVE_SYS_STAT_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_SYS_STAT_H]) m4trace:configure.ac:252: -1- AH_OUTPUT([HAVE_STDLIB_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_STDLIB_H]) m4trace:configure.ac:252: -1- AH_OUTPUT([HAVE_STRING_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_STRING_H]) m4trace:configure.ac:252: -1- AH_OUTPUT([HAVE_MEMORY_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_MEMORY_H]) m4trace:configure.ac:252: -1- AH_OUTPUT([HAVE_STRINGS_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_STRINGS_H]) m4trace:configure.ac:252: -1- AH_OUTPUT([HAVE_INTTYPES_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_INTTYPES_H]) m4trace:configure.ac:252: -1- AH_OUTPUT([HAVE_STDINT_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_STDINT_H]) m4trace:configure.ac:252: -1- AH_OUTPUT([HAVE_UNISTD_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_UNISTD_H]) m4trace:configure.ac:252: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DLFCN_H]) m4trace:configure.ac:252: -1- m4_pattern_allow([^HAVE_DLFCN_H$]) m4trace:configure.ac:252: -1- LT_SUPPORTED_TAG([CXX]) m4trace:configure.ac:252: -1- AC_SUBST([CXXCPP]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([CXXCPP]) m4trace:configure.ac:252: -1- m4_pattern_allow([^CXXCPP$]) m4trace:configure.ac:252: -1- AC_SUBST([CPPFLAGS]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([CPPFLAGS]) m4trace:configure.ac:252: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:252: -1- AC_SUBST([CXXCPP]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([CXXCPP]) m4trace:configure.ac:252: -1- m4_pattern_allow([^CXXCPP$]) m4trace:configure.ac:252: -1- AC_SUBST([LD]) m4trace:configure.ac:252: -1- AC_SUBST_TRACE([LD]) m4trace:configure.ac:252: -1- m4_pattern_allow([^LD$]) m4trace:configure.ac:258: -1- AC_SUBST([HAVE_PKG_CONFIG]) m4trace:configure.ac:258: -1- AC_SUBST_TRACE([HAVE_PKG_CONFIG]) m4trace:configure.ac:258: -1- m4_pattern_allow([^HAVE_PKG_CONFIG$]) m4trace:configure.ac:272: -1- AC_SUBST([XMKMF]) m4trace:configure.ac:272: -1- AC_SUBST_TRACE([XMKMF]) m4trace:configure.ac:272: -1- m4_pattern_allow([^XMKMF$]) m4trace:configure.ac:272: -1- AC_DEFINE_TRACE_LITERAL([X_DISPLAY_MISSING]) m4trace:configure.ac:272: -1- m4_pattern_allow([^X_DISPLAY_MISSING$]) m4trace:configure.ac:272: -1- AH_OUTPUT([X_DISPLAY_MISSING], [/* Define to 1 if the X Window System is missing or not being used. */ @%:@undef X_DISPLAY_MISSING]) m4trace:configure.ac:272: -1- AC_SUBST([X_CFLAGS]) m4trace:configure.ac:272: -1- AC_SUBST_TRACE([X_CFLAGS]) m4trace:configure.ac:272: -1- m4_pattern_allow([^X_CFLAGS$]) m4trace:configure.ac:272: -1- AC_SUBST([X_PRE_LIBS]) m4trace:configure.ac:272: -1- AC_SUBST_TRACE([X_PRE_LIBS]) m4trace:configure.ac:272: -1- m4_pattern_allow([^X_PRE_LIBS$]) m4trace:configure.ac:272: -1- AC_SUBST([X_LIBS]) m4trace:configure.ac:272: -1- AC_SUBST_TRACE([X_LIBS]) m4trace:configure.ac:272: -1- m4_pattern_allow([^X_LIBS$]) m4trace:configure.ac:272: -1- AC_SUBST([X_EXTRA_LIBS]) m4trace:configure.ac:272: -1- AC_SUBST_TRACE([X_EXTRA_LIBS]) m4trace:configure.ac:272: -1- m4_pattern_allow([^X_EXTRA_LIBS$]) m4trace:configure.ac:295: -1- AC_SUBST([ac_vmw_lib_cfg]) m4trace:configure.ac:295: -1- AC_SUBST_TRACE([ac_vmw_lib_cfg]) m4trace:configure.ac:295: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:295: -1- AC_SUBST([GLIB2_CPPFLAGS]) m4trace:configure.ac:295: -1- AC_SUBST_TRACE([GLIB2_CPPFLAGS]) m4trace:configure.ac:295: -1- m4_pattern_allow([^GLIB2_CPPFLAGS$]) m4trace:configure.ac:295: -1- AC_SUBST([GLIB2_LIBS]) m4trace:configure.ac:295: -1- AC_SUBST_TRACE([GLIB2_LIBS]) m4trace:configure.ac:295: -1- m4_pattern_allow([^GLIB2_LIBS$]) m4trace:configure.ac:304: -1- AC_SUBST([ac_vmw_lib_cfg]) m4trace:configure.ac:304: -1- AC_SUBST_TRACE([ac_vmw_lib_cfg]) m4trace:configure.ac:304: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:304: -1- AC_SUBST([GMODULE_CPPFLAGS]) m4trace:configure.ac:304: -1- AC_SUBST_TRACE([GMODULE_CPPFLAGS]) m4trace:configure.ac:304: -1- m4_pattern_allow([^GMODULE_CPPFLAGS$]) m4trace:configure.ac:304: -1- AC_SUBST([GMODULE_LIBS]) m4trace:configure.ac:304: -1- AC_SUBST_TRACE([GMODULE_LIBS]) m4trace:configure.ac:304: -1- m4_pattern_allow([^GMODULE_LIBS$]) m4trace:configure.ac:313: -1- AC_SUBST([ac_vmw_lib_cfg]) m4trace:configure.ac:313: -1- AC_SUBST_TRACE([ac_vmw_lib_cfg]) m4trace:configure.ac:313: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:313: -1- AC_SUBST([GOBJECT_CPPFLAGS]) m4trace:configure.ac:313: -1- AC_SUBST_TRACE([GOBJECT_CPPFLAGS]) m4trace:configure.ac:313: -1- m4_pattern_allow([^GOBJECT_CPPFLAGS$]) m4trace:configure.ac:313: -1- AC_SUBST([GOBJECT_LIBS]) m4trace:configure.ac:313: -1- AC_SUBST_TRACE([GOBJECT_LIBS]) m4trace:configure.ac:313: -1- m4_pattern_allow([^GOBJECT_LIBS$]) m4trace:configure.ac:322: -1- AC_SUBST([ac_vmw_lib_cfg]) m4trace:configure.ac:322: -1- AC_SUBST_TRACE([ac_vmw_lib_cfg]) m4trace:configure.ac:322: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:322: -1- AC_SUBST([GTHREAD_CPPFLAGS]) m4trace:configure.ac:322: -1- AC_SUBST_TRACE([GTHREAD_CPPFLAGS]) m4trace:configure.ac:322: -1- m4_pattern_allow([^GTHREAD_CPPFLAGS$]) m4trace:configure.ac:322: -1- AC_SUBST([GTHREAD_LIBS]) m4trace:configure.ac:322: -1- AC_SUBST_TRACE([GTHREAD_LIBS]) m4trace:configure.ac:322: -1- m4_pattern_allow([^GTHREAD_LIBS$]) m4trace:configure.ac:331: -1- AC_SUBST([have_genmarshal]) m4trace:configure.ac:331: -1- AC_SUBST_TRACE([have_genmarshal]) m4trace:configure.ac:331: -1- m4_pattern_allow([^have_genmarshal$]) m4trace:configure.ac:344: -1- AC_SUBST([ac_vmw_lib_cfg]) m4trace:configure.ac:344: -1- AC_SUBST_TRACE([ac_vmw_lib_cfg]) m4trace:configure.ac:344: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:344: -1- AC_SUBST([GLIB2_CPPFLAGS]) m4trace:configure.ac:344: -1- AC_SUBST_TRACE([GLIB2_CPPFLAGS]) m4trace:configure.ac:344: -1- m4_pattern_allow([^GLIB2_CPPFLAGS$]) m4trace:configure.ac:344: -1- AC_SUBST([GLIB2_LIBS]) m4trace:configure.ac:344: -1- AC_SUBST_TRACE([GLIB2_LIBS]) m4trace:configure.ac:344: -1- m4_pattern_allow([^GLIB2_LIBS$]) m4trace:configure.ac:358: -1- AC_SUBST([ac_vmw_lib_cfg]) m4trace:configure.ac:358: -1- AC_SUBST_TRACE([ac_vmw_lib_cfg]) m4trace:configure.ac:358: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:358: -1- AC_SUBST([FUSE_CPPFLAGS]) m4trace:configure.ac:358: -1- AC_SUBST_TRACE([FUSE_CPPFLAGS]) m4trace:configure.ac:358: -1- m4_pattern_allow([^FUSE_CPPFLAGS$]) m4trace:configure.ac:358: -1- AC_SUBST([FUSE_LIBS]) m4trace:configure.ac:358: -1- AC_SUBST_TRACE([FUSE_LIBS]) m4trace:configure.ac:358: -1- m4_pattern_allow([^FUSE_LIBS$]) m4trace:configure.ac:380: -1- AC_SUBST([ac_vmw_lib_cfg]) m4trace:configure.ac:380: -1- AC_SUBST_TRACE([ac_vmw_lib_cfg]) m4trace:configure.ac:380: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:380: -1- AC_SUBST([PAM_CPPFLAGS]) m4trace:configure.ac:380: -1- AC_SUBST_TRACE([PAM_CPPFLAGS]) m4trace:configure.ac:380: -1- m4_pattern_allow([^PAM_CPPFLAGS$]) m4trace:configure.ac:380: -1- AC_SUBST([PAM_LIBS]) m4trace:configure.ac:380: -1- AC_SUBST_TRACE([PAM_LIBS]) m4trace:configure.ac:380: -1- m4_pattern_allow([^PAM_LIBS$]) m4trace:configure.ac:396: -1- AC_SUBST([ac_vmw_lib_cfg]) m4trace:configure.ac:396: -1- AC_SUBST_TRACE([ac_vmw_lib_cfg]) m4trace:configure.ac:396: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:396: -1- AC_SUBST([CUNIT_CPPFLAGS]) m4trace:configure.ac:396: -1- AC_SUBST_TRACE([CUNIT_CPPFLAGS]) m4trace:configure.ac:396: -1- m4_pattern_allow([^CUNIT_CPPFLAGS$]) m4trace:configure.ac:396: -1- AC_SUBST([CUNIT_LIBS]) m4trace:configure.ac:396: -1- AC_SUBST_TRACE([CUNIT_LIBS]) m4trace:configure.ac:396: -1- m4_pattern_allow([^CUNIT_LIBS$]) m4trace:configure.ac:489: -1- AH_OUTPUT([HAVE_X11_SM_SMLIB_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_X11_SM_SMLIB_H]) m4trace:configure.ac:489: -1- AH_OUTPUT([HAVE_X11_ICE_ICELIB_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_X11_ICE_ICELIB_H]) m4trace:configure.ac:503: -1- AH_OUTPUT([HAVE_X11_EXTENSIONS_XCOMPOSITE_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_X11_EXTENSIONS_XCOMPOSITE_H]) m4trace:configure.ac:503: -1- AC_DEFINE_TRACE_LITERAL([HAVE_X11_EXTENSIONS_XCOMPOSITE_H]) m4trace:configure.ac:503: -1- m4_pattern_allow([^HAVE_X11_EXTENSIONS_XCOMPOSITE_H$]) m4trace:configure.ac:515: -1- AC_SUBST([ac_vmw_lib_cfg]) m4trace:configure.ac:515: -1- AC_SUBST_TRACE([ac_vmw_lib_cfg]) m4trace:configure.ac:515: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:515: -1- AC_SUBST([GTK_CPPFLAGS]) m4trace:configure.ac:515: -1- AC_SUBST_TRACE([GTK_CPPFLAGS]) m4trace:configure.ac:515: -1- m4_pattern_allow([^GTK_CPPFLAGS$]) m4trace:configure.ac:515: -1- AC_SUBST([GTK_LIBS]) m4trace:configure.ac:515: -1- AC_SUBST_TRACE([GTK_LIBS]) m4trace:configure.ac:515: -1- m4_pattern_allow([^GTK_LIBS$]) m4trace:configure.ac:532: -1- AC_SUBST([ac_vmw_lib_cfg]) m4trace:configure.ac:532: -1- AC_SUBST_TRACE([ac_vmw_lib_cfg]) m4trace:configure.ac:532: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:532: -1- AC_SUBST([GTKMM_CPPFLAGS]) m4trace:configure.ac:532: -1- AC_SUBST_TRACE([GTKMM_CPPFLAGS]) m4trace:configure.ac:532: -1- m4_pattern_allow([^GTKMM_CPPFLAGS$]) m4trace:configure.ac:532: -1- AC_SUBST([GTKMM_LIBS]) m4trace:configure.ac:532: -1- AC_SUBST_TRACE([GTKMM_LIBS]) m4trace:configure.ac:532: -1- m4_pattern_allow([^GTKMM_LIBS$]) m4trace:configure.ac:551: -1- AH_OUTPUT([HAVE_DLOPEN], [/* Define to 1 if you have the `dlopen\' function. */ @%:@undef HAVE_DLOPEN]) m4trace:configure.ac:551: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DLOPEN]) m4trace:configure.ac:551: -1- m4_pattern_allow([^HAVE_DLOPEN$]) m4trace:configure.ac:562: -1- AH_OUTPUT([HAVE_ECVT], [/* Define to 1 if you have the `ecvt\' function. */ @%:@undef HAVE_ECVT]) m4trace:configure.ac:562: -1- AC_DEFINE_TRACE_LITERAL([HAVE_ECVT]) m4trace:configure.ac:562: -1- m4_pattern_allow([^HAVE_ECVT$]) m4trace:configure.ac:563: -1- AH_OUTPUT([HAVE_FCVT], [/* Define to 1 if you have the `fcvt\' function. */ @%:@undef HAVE_FCVT]) m4trace:configure.ac:563: -1- AC_DEFINE_TRACE_LITERAL([HAVE_FCVT]) m4trace:configure.ac:563: -1- m4_pattern_allow([^HAVE_FCVT$]) m4trace:configure.ac:617: -1- AC_SUBST([ac_vmw_lib_cfg]) m4trace:configure.ac:617: -1- AC_SUBST_TRACE([ac_vmw_lib_cfg]) m4trace:configure.ac:617: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:617: -1- AC_SUBST([PROCPS_CPPFLAGS]) m4trace:configure.ac:617: -1- AC_SUBST_TRACE([PROCPS_CPPFLAGS]) m4trace:configure.ac:617: -1- m4_pattern_allow([^PROCPS_CPPFLAGS$]) m4trace:configure.ac:617: -1- AC_SUBST([PROCPS_LIBS]) m4trace:configure.ac:617: -1- AC_SUBST_TRACE([PROCPS_LIBS]) m4trace:configure.ac:617: -1- m4_pattern_allow([^PROCPS_LIBS$]) m4trace:configure.ac:630: -1- AC_SUBST([ac_vmw_lib_cfg]) m4trace:configure.ac:630: -1- AC_SUBST_TRACE([ac_vmw_lib_cfg]) m4trace:configure.ac:630: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:630: -1- AC_SUBST([PROCPS_CPPFLAGS]) m4trace:configure.ac:630: -1- AC_SUBST_TRACE([PROCPS_CPPFLAGS]) m4trace:configure.ac:630: -1- m4_pattern_allow([^PROCPS_CPPFLAGS$]) m4trace:configure.ac:630: -1- AC_SUBST([PROCPS_LIBS]) m4trace:configure.ac:630: -1- AC_SUBST_TRACE([PROCPS_LIBS]) m4trace:configure.ac:630: -1- m4_pattern_allow([^PROCPS_LIBS$]) m4trace:configure.ac:644: -1- AC_SUBST([ac_vmw_lib_cfg]) m4trace:configure.ac:644: -1- AC_SUBST_TRACE([ac_vmw_lib_cfg]) m4trace:configure.ac:644: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:644: -1- AC_SUBST([PROCPS_CPPFLAGS]) m4trace:configure.ac:644: -1- AC_SUBST_TRACE([PROCPS_CPPFLAGS]) m4trace:configure.ac:644: -1- m4_pattern_allow([^PROCPS_CPPFLAGS$]) m4trace:configure.ac:644: -1- AC_SUBST([PROCPS_LIBS]) m4trace:configure.ac:644: -1- AC_SUBST_TRACE([PROCPS_LIBS]) m4trace:configure.ac:644: -1- m4_pattern_allow([^PROCPS_LIBS$]) m4trace:configure.ac:657: -1- AC_DEFINE_TRACE_LITERAL([NO_PROCPS]) m4trace:configure.ac:657: -1- m4_pattern_allow([^NO_PROCPS$]) m4trace:configure.ac:657: -1- AH_OUTPUT([NO_PROCPS], [/* Define to 1 if building without procps. */ @%:@undef NO_PROCPS]) m4trace:configure.ac:671: -1- AC_SUBST([ac_vmw_lib_cfg]) m4trace:configure.ac:671: -1- AC_SUBST_TRACE([ac_vmw_lib_cfg]) m4trace:configure.ac:671: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:671: -1- AC_SUBST([DNET_CPPFLAGS]) m4trace:configure.ac:671: -1- AC_SUBST_TRACE([DNET_CPPFLAGS]) m4trace:configure.ac:671: -1- m4_pattern_allow([^DNET_CPPFLAGS$]) m4trace:configure.ac:671: -1- AC_SUBST([DNET_LIBS]) m4trace:configure.ac:671: -1- AC_SUBST_TRACE([DNET_LIBS]) m4trace:configure.ac:671: -1- m4_pattern_allow([^DNET_LIBS$]) m4trace:configure.ac:671: -1- AC_DEFINE_TRACE_LITERAL([DNET_IS_DUMBNET]) m4trace:configure.ac:671: -1- m4_pattern_allow([^DNET_IS_DUMBNET$]) m4trace:configure.ac:671: -1- AH_OUTPUT([DNET_IS_DUMBNET], [/* Define to 1 if substituting Debian\'s libdumbnet for libdnet. */ @%:@undef DNET_IS_DUMBNET]) m4trace:configure.ac:683: -1- AC_SUBST([ac_vmw_lib_cfg]) m4trace:configure.ac:683: -1- AC_SUBST_TRACE([ac_vmw_lib_cfg]) m4trace:configure.ac:683: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:683: -1- AC_SUBST([DNET_CPPFLAGS]) m4trace:configure.ac:683: -1- AC_SUBST_TRACE([DNET_CPPFLAGS]) m4trace:configure.ac:683: -1- m4_pattern_allow([^DNET_CPPFLAGS$]) m4trace:configure.ac:683: -1- AC_SUBST([DNET_LIBS]) m4trace:configure.ac:683: -1- AC_SUBST_TRACE([DNET_LIBS]) m4trace:configure.ac:683: -1- m4_pattern_allow([^DNET_LIBS$]) m4trace:configure.ac:701: -1- AC_DEFINE_TRACE_LITERAL([NO_DNET]) m4trace:configure.ac:701: -1- m4_pattern_allow([^NO_DNET$]) m4trace:configure.ac:701: -1- AH_OUTPUT([NO_DNET], [/* Define to 1 if building without libdnet. */ @%:@undef NO_DNET]) m4trace:configure.ac:711: -1- AC_SUBST([have_cxx]) m4trace:configure.ac:711: -1- AC_SUBST_TRACE([have_cxx]) m4trace:configure.ac:711: -1- m4_pattern_allow([^have_cxx$]) m4trace:configure.ac:718: -1- AC_SUBST([ac_vmw_lib_cfg]) m4trace:configure.ac:718: -1- AC_SUBST_TRACE([ac_vmw_lib_cfg]) m4trace:configure.ac:718: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:718: -1- AC_SUBST([ICU_CPPFLAGS]) m4trace:configure.ac:718: -1- AC_SUBST_TRACE([ICU_CPPFLAGS]) m4trace:configure.ac:718: -1- m4_pattern_allow([^ICU_CPPFLAGS$]) m4trace:configure.ac:718: -1- AC_SUBST([ICU_LIBS]) m4trace:configure.ac:718: -1- AC_SUBST_TRACE([ICU_LIBS]) m4trace:configure.ac:718: -1- m4_pattern_allow([^ICU_LIBS$]) m4trace:configure.ac:732: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from... configure.ac:732: the top level]) m4trace:configure.ac:751: -1- AC_SUBST([RPCGEN]) m4trace:configure.ac:751: -1- AC_SUBST_TRACE([RPCGEN]) m4trace:configure.ac:751: -1- m4_pattern_allow([^RPCGEN$]) m4trace:configure.ac:760: -1- AH_OUTPUT([HAVE_CRYPT_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_CRYPT_H]) m4trace:configure.ac:760: -1- AC_DEFINE_TRACE_LITERAL([HAVE_CRYPT_H]) m4trace:configure.ac:760: -1- m4_pattern_allow([^HAVE_CRYPT_H$]) m4trace:configure.ac:761: -1- AH_OUTPUT([HAVE_INTTYPES_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_INTTYPES_H]) m4trace:configure.ac:761: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INTTYPES_H]) m4trace:configure.ac:761: -1- m4_pattern_allow([^HAVE_INTTYPES_H$]) m4trace:configure.ac:762: -1- AH_OUTPUT([HAVE_STDINT_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_STDINT_H]) m4trace:configure.ac:762: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STDINT_H]) m4trace:configure.ac:762: -1- m4_pattern_allow([^HAVE_STDINT_H$]) m4trace:configure.ac:763: -1- AH_OUTPUT([HAVE_STDLIB_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_STDLIB_H]) m4trace:configure.ac:763: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STDLIB_H]) m4trace:configure.ac:763: -1- m4_pattern_allow([^HAVE_STDLIB_H$]) m4trace:configure.ac:764: -1- AH_OUTPUT([HAVE_WCHAR_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_WCHAR_H]) m4trace:configure.ac:764: -1- AC_DEFINE_TRACE_LITERAL([HAVE_WCHAR_H]) m4trace:configure.ac:764: -1- m4_pattern_allow([^HAVE_WCHAR_H$]) m4trace:configure.ac:765: -1- AH_OUTPUT([HAVE_SYS_INTTYPES_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_SYS_INTTYPES_H]) m4trace:configure.ac:765: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_INTTYPES_H]) m4trace:configure.ac:765: -1- m4_pattern_allow([^HAVE_SYS_INTTYPES_H$]) m4trace:configure.ac:766: -1- AH_OUTPUT([HAVE_SYS_IO_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_SYS_IO_H]) m4trace:configure.ac:766: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_IO_H]) m4trace:configure.ac:766: -1- m4_pattern_allow([^HAVE_SYS_IO_H$]) m4trace:configure.ac:767: -1- AH_OUTPUT([HAVE_SYS_PARAM_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_SYS_PARAM_H]) m4trace:configure.ac:767: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_PARAM_H]) m4trace:configure.ac:767: -1- m4_pattern_allow([^HAVE_SYS_PARAM_H$]) m4trace:configure.ac:768: -1- AH_OUTPUT([HAVE_SYS_SYSINFO_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_SYS_SYSINFO_H]) m4trace:configure.ac:768: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_SYSINFO_H]) m4trace:configure.ac:768: -1- m4_pattern_allow([^HAVE_SYS_SYSINFO_H$]) m4trace:configure.ac:769: -1- AH_OUTPUT([HAVE_SYS_TYPES_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_SYS_TYPES_H]) m4trace:configure.ac:769: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_TYPES_H]) m4trace:configure.ac:769: -1- m4_pattern_allow([^HAVE_SYS_TYPES_H$]) m4trace:configure.ac:770: -1- AH_OUTPUT([HAVE_SYS_USER_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_SYS_USER_H]) m4trace:configure.ac:770: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_USER_H]) m4trace:configure.ac:770: -1- m4_pattern_allow([^HAVE_SYS_USER_H$]) m4trace:configure.ac:778: -1- AH_OUTPUT([HAVE_SYS_VFS_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_SYS_VFS_H]) m4trace:configure.ac:778: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_VFS_H]) m4trace:configure.ac:778: -1- m4_pattern_allow([^HAVE_SYS_VFS_H$]) m4trace:configure.ac:779: -1- AH_OUTPUT([HAVE_SYSLIMITS_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_SYSLIMITS_H]) m4trace:configure.ac:779: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SYSLIMITS_H]) m4trace:configure.ac:779: -1- m4_pattern_allow([^HAVE_SYSLIMITS_H$]) m4trace:configure.ac:780: -1- AH_OUTPUT([HAVE_UNWIND_H], [/* Define to 1 if you have the header file. */ @%:@undef HAVE_UNWIND_H]) m4trace:configure.ac:780: -1- AC_DEFINE_TRACE_LITERAL([HAVE_UNWIND_H]) m4trace:configure.ac:780: -1- m4_pattern_allow([^HAVE_UNWIND_H$]) m4trace:configure.ac:816: -1- AC_DEFINE_TRACE_LITERAL([HAVE__BOOL]) m4trace:configure.ac:816: -1- m4_pattern_allow([^HAVE__BOOL$]) m4trace:configure.ac:816: -1- AH_OUTPUT([HAVE__BOOL], [/* Define to 1 if the system has the type `_Bool\'. */ @%:@undef HAVE__BOOL]) m4trace:configure.ac:816: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STDBOOL_H]) m4trace:configure.ac:816: -1- m4_pattern_allow([^HAVE_STDBOOL_H$]) m4trace:configure.ac:816: -1- AH_OUTPUT([HAVE_STDBOOL_H], [/* Define to 1 if stdbool.h conforms to C99. */ @%:@undef HAVE_STDBOOL_H]) m4trace:configure.ac:817: -1- AC_DEFINE_TRACE_LITERAL([const]) m4trace:configure.ac:817: -1- m4_pattern_allow([^const$]) m4trace:configure.ac:817: -1- AH_OUTPUT([const], [/* Define to empty if `const\' does not conform to ANSI C. */ @%:@undef const]) m4trace:configure.ac:818: -1- AC_DEFINE_TRACE_LITERAL([uid_t]) m4trace:configure.ac:818: -1- m4_pattern_allow([^uid_t$]) m4trace:configure.ac:818: -1- AH_OUTPUT([uid_t], [/* Define to `int\' if doesn\'t define. */ @%:@undef uid_t]) m4trace:configure.ac:818: -1- AC_DEFINE_TRACE_LITERAL([gid_t]) m4trace:configure.ac:818: -1- m4_pattern_allow([^gid_t$]) m4trace:configure.ac:818: -1- AH_OUTPUT([gid_t], [/* Define to `int\' if doesn\'t define. */ @%:@undef gid_t]) m4trace:configure.ac:819: -1- AH_OUTPUT([inline], [/* 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]) m4trace:configure.ac:820: -1- AC_DEFINE_TRACE_LITERAL([mode_t]) m4trace:configure.ac:820: -1- m4_pattern_allow([^mode_t$]) m4trace:configure.ac:820: -1- AH_OUTPUT([mode_t], [/* Define to `int\' if does not define. */ @%:@undef mode_t]) m4trace:configure.ac:821: -1- AC_DEFINE_TRACE_LITERAL([off_t]) m4trace:configure.ac:821: -1- m4_pattern_allow([^off_t$]) m4trace:configure.ac:821: -1- AH_OUTPUT([off_t], [/* Define to `long int\' if does not define. */ @%:@undef off_t]) m4trace:configure.ac:822: -1- AC_DEFINE_TRACE_LITERAL([pid_t]) m4trace:configure.ac:822: -1- m4_pattern_allow([^pid_t$]) m4trace:configure.ac:822: -1- AH_OUTPUT([pid_t], [/* Define to `int\' if does not define. */ @%:@undef pid_t]) m4trace:configure.ac:823: -1- AC_DEFINE_TRACE_LITERAL([size_t]) m4trace:configure.ac:823: -1- m4_pattern_allow([^size_t$]) m4trace:configure.ac:823: -1- AH_OUTPUT([size_t], [/* Define to `unsigned int\' if does not define. */ @%:@undef size_t]) m4trace:configure.ac:824: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRUCT_STAT_ST_RDEV]) m4trace:configure.ac:824: -1- m4_pattern_allow([^HAVE_STRUCT_STAT_ST_RDEV$]) m4trace:configure.ac:824: -1- AH_OUTPUT([HAVE_STRUCT_STAT_ST_RDEV], [/* Define to 1 if `st_rdev\' is a member of `struct stat\'. */ @%:@undef HAVE_STRUCT_STAT_ST_RDEV]) m4trace:configure.ac:825: -1- AC_DEFINE_TRACE_LITERAL([TIME_WITH_SYS_TIME]) m4trace:configure.ac:825: -1- m4_pattern_allow([^TIME_WITH_SYS_TIME$]) m4trace:configure.ac:825: -1- AH_OUTPUT([TIME_WITH_SYS_TIME], [/* Define to 1 if you can safely include both and . */ @%:@undef TIME_WITH_SYS_TIME]) m4trace:configure.ac:826: -1- AC_DEFINE_TRACE_LITERAL([TM_IN_SYS_TIME]) m4trace:configure.ac:826: -1- m4_pattern_allow([^TM_IN_SYS_TIME$]) m4trace:configure.ac:826: -1- AH_OUTPUT([TM_IN_SYS_TIME], [/* Define to 1 if your declares `struct tm\'. */ @%:@undef TM_IN_SYS_TIME]) m4trace:configure.ac:827: -1- AC_DEFINE_TRACE_LITERAL([volatile]) m4trace:configure.ac:827: -1- m4_pattern_allow([^volatile$]) m4trace:configure.ac:827: -1- AH_OUTPUT([volatile], [/* Define to empty if the keyword `volatile\' does not work. Warning: valid code using `volatile\' can become incorrect without. Disable with care. */ @%:@undef volatile]) m4trace:configure.ac:844: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from... configure.ac:844: the top level]) m4trace:configure.ac:861: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from... configure.ac:861: the top level]) m4trace:configure.ac:872: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from... configure.ac:872: the top level]) m4trace:configure.ac:891: -1- AC_SUBST([have_doxygen]) m4trace:configure.ac:891: -1- AC_SUBST_TRACE([have_doxygen]) m4trace:configure.ac:891: -1- m4_pattern_allow([^have_doxygen$]) m4trace:configure.ac:898: -1- AC_SUBST([DOT]) m4trace:configure.ac:898: -1- AC_SUBST_TRACE([DOT]) m4trace:configure.ac:898: -1- m4_pattern_allow([^DOT$]) m4trace:configure.ac:905: -1- AC_SUBST([DOT]) m4trace:configure.ac:905: -1- AC_SUBST_TRACE([DOT]) m4trace:configure.ac:905: -1- m4_pattern_allow([^DOT$]) m4trace:configure.ac:906: -1- AC_SUBST([HAVE_DOT]) m4trace:configure.ac:906: -1- AC_SUBST_TRACE([HAVE_DOT]) m4trace:configure.ac:906: -1- m4_pattern_allow([^HAVE_DOT$]) m4trace:configure.ac:908: -1- AC_SUBST([MSCGEN]) m4trace:configure.ac:908: -1- AC_SUBST_TRACE([MSCGEN]) m4trace:configure.ac:908: -1- m4_pattern_allow([^MSCGEN$]) m4trace:configure.ac:916: -1- AC_SUBST([MSCGEN_DIR]) m4trace:configure.ac:916: -1- AC_SUBST_TRACE([MSCGEN_DIR]) m4trace:configure.ac:916: -1- m4_pattern_allow([^MSCGEN_DIR$]) m4trace:configure.ac:1016: -1- AM_CONDITIONAL([BUILD_HGFSMOUNTER], [test "$buildHgfsmounter" = "yes"]) m4trace:configure.ac:1016: -1- AC_SUBST([BUILD_HGFSMOUNTER_TRUE]) m4trace:configure.ac:1016: -1- AC_SUBST_TRACE([BUILD_HGFSMOUNTER_TRUE]) m4trace:configure.ac:1016: -1- m4_pattern_allow([^BUILD_HGFSMOUNTER_TRUE$]) m4trace:configure.ac:1016: -1- AC_SUBST([BUILD_HGFSMOUNTER_FALSE]) m4trace:configure.ac:1016: -1- AC_SUBST_TRACE([BUILD_HGFSMOUNTER_FALSE]) m4trace:configure.ac:1016: -1- m4_pattern_allow([^BUILD_HGFSMOUNTER_FALSE$]) m4trace:configure.ac:1016: -1- _AM_SUBST_NOTMAKE([BUILD_HGFSMOUNTER_TRUE]) m4trace:configure.ac:1016: -1- _AM_SUBST_NOTMAKE([BUILD_HGFSMOUNTER_FALSE]) m4trace:configure.ac:1017: -1- AM_CONDITIONAL([LINUX], [test "$os" = "linux"]) m4trace:configure.ac:1017: -1- AC_SUBST([LINUX_TRUE]) m4trace:configure.ac:1017: -1- AC_SUBST_TRACE([LINUX_TRUE]) m4trace:configure.ac:1017: -1- m4_pattern_allow([^LINUX_TRUE$]) m4trace:configure.ac:1017: -1- AC_SUBST([LINUX_FALSE]) m4trace:configure.ac:1017: -1- AC_SUBST_TRACE([LINUX_FALSE]) m4trace:configure.ac:1017: -1- m4_pattern_allow([^LINUX_FALSE$]) m4trace:configure.ac:1017: -1- _AM_SUBST_NOTMAKE([LINUX_TRUE]) m4trace:configure.ac:1017: -1- _AM_SUBST_NOTMAKE([LINUX_FALSE]) m4trace:configure.ac:1018: -1- AM_CONDITIONAL([SOLARIS], [test "$os" = "solaris"]) m4trace:configure.ac:1018: -1- AC_SUBST([SOLARIS_TRUE]) m4trace:configure.ac:1018: -1- AC_SUBST_TRACE([SOLARIS_TRUE]) m4trace:configure.ac:1018: -1- m4_pattern_allow([^SOLARIS_TRUE$]) m4trace:configure.ac:1018: -1- AC_SUBST([SOLARIS_FALSE]) m4trace:configure.ac:1018: -1- AC_SUBST_TRACE([SOLARIS_FALSE]) m4trace:configure.ac:1018: -1- m4_pattern_allow([^SOLARIS_FALSE$]) m4trace:configure.ac:1018: -1- _AM_SUBST_NOTMAKE([SOLARIS_TRUE]) m4trace:configure.ac:1018: -1- _AM_SUBST_NOTMAKE([SOLARIS_FALSE]) m4trace:configure.ac:1019: -1- AM_CONDITIONAL([FREEBSD], [test "$os" = "freebsd"]) m4trace:configure.ac:1019: -1- AC_SUBST([FREEBSD_TRUE]) m4trace:configure.ac:1019: -1- AC_SUBST_TRACE([FREEBSD_TRUE]) m4trace:configure.ac:1019: -1- m4_pattern_allow([^FREEBSD_TRUE$]) m4trace:configure.ac:1019: -1- AC_SUBST([FREEBSD_FALSE]) m4trace:configure.ac:1019: -1- AC_SUBST_TRACE([FREEBSD_FALSE]) m4trace:configure.ac:1019: -1- m4_pattern_allow([^FREEBSD_FALSE$]) m4trace:configure.ac:1019: -1- _AM_SUBST_NOTMAKE([FREEBSD_TRUE]) m4trace:configure.ac:1019: -1- _AM_SUBST_NOTMAKE([FREEBSD_FALSE]) m4trace:configure.ac:1020: -1- AM_CONDITIONAL([FREEBSD_CUSTOM_SYSDIR], [test "$os" = "freebsd" -a -n "$SYSDIR"]) m4trace:configure.ac:1020: -1- AC_SUBST([FREEBSD_CUSTOM_SYSDIR_TRUE]) m4trace:configure.ac:1020: -1- AC_SUBST_TRACE([FREEBSD_CUSTOM_SYSDIR_TRUE]) m4trace:configure.ac:1020: -1- m4_pattern_allow([^FREEBSD_CUSTOM_SYSDIR_TRUE$]) m4trace:configure.ac:1020: -1- AC_SUBST([FREEBSD_CUSTOM_SYSDIR_FALSE]) m4trace:configure.ac:1020: -1- AC_SUBST_TRACE([FREEBSD_CUSTOM_SYSDIR_FALSE]) m4trace:configure.ac:1020: -1- m4_pattern_allow([^FREEBSD_CUSTOM_SYSDIR_FALSE$]) m4trace:configure.ac:1020: -1- _AM_SUBST_NOTMAKE([FREEBSD_CUSTOM_SYSDIR_TRUE]) m4trace:configure.ac:1020: -1- _AM_SUBST_NOTMAKE([FREEBSD_CUSTOM_SYSDIR_FALSE]) m4trace:configure.ac:1021: -1- AM_CONDITIONAL([THIRTY_TWO_BIT_USERSPACE], [test "$userSpaceBitness" = "32"]) m4trace:configure.ac:1021: -1- AC_SUBST([THIRTY_TWO_BIT_USERSPACE_TRUE]) m4trace:configure.ac:1021: -1- AC_SUBST_TRACE([THIRTY_TWO_BIT_USERSPACE_TRUE]) m4trace:configure.ac:1021: -1- m4_pattern_allow([^THIRTY_TWO_BIT_USERSPACE_TRUE$]) m4trace:configure.ac:1021: -1- AC_SUBST([THIRTY_TWO_BIT_USERSPACE_FALSE]) m4trace:configure.ac:1021: -1- AC_SUBST_TRACE([THIRTY_TWO_BIT_USERSPACE_FALSE]) m4trace:configure.ac:1021: -1- m4_pattern_allow([^THIRTY_TWO_BIT_USERSPACE_FALSE$]) m4trace:configure.ac:1021: -1- _AM_SUBST_NOTMAKE([THIRTY_TWO_BIT_USERSPACE_TRUE]) m4trace:configure.ac:1021: -1- _AM_SUBST_NOTMAKE([THIRTY_TWO_BIT_USERSPACE_FALSE]) m4trace:configure.ac:1022: -1- AM_CONDITIONAL([HAVE_X11], [test "$have_x" = "yes"]) m4trace:configure.ac:1022: -1- AC_SUBST([HAVE_X11_TRUE]) m4trace:configure.ac:1022: -1- AC_SUBST_TRACE([HAVE_X11_TRUE]) m4trace:configure.ac:1022: -1- m4_pattern_allow([^HAVE_X11_TRUE$]) m4trace:configure.ac:1022: -1- AC_SUBST([HAVE_X11_FALSE]) m4trace:configure.ac:1022: -1- AC_SUBST_TRACE([HAVE_X11_FALSE]) m4trace:configure.ac:1022: -1- m4_pattern_allow([^HAVE_X11_FALSE$]) m4trace:configure.ac:1022: -1- _AM_SUBST_NOTMAKE([HAVE_X11_TRUE]) m4trace:configure.ac:1022: -1- _AM_SUBST_NOTMAKE([HAVE_X11_FALSE]) m4trace:configure.ac:1023: -1- AM_CONDITIONAL([HAVE_ICU], [test "$with_icu" = "yes"]) m4trace:configure.ac:1023: -1- AC_SUBST([HAVE_ICU_TRUE]) m4trace:configure.ac:1023: -1- AC_SUBST_TRACE([HAVE_ICU_TRUE]) m4trace:configure.ac:1023: -1- m4_pattern_allow([^HAVE_ICU_TRUE$]) m4trace:configure.ac:1023: -1- AC_SUBST([HAVE_ICU_FALSE]) m4trace:configure.ac:1023: -1- AC_SUBST_TRACE([HAVE_ICU_FALSE]) m4trace:configure.ac:1023: -1- m4_pattern_allow([^HAVE_ICU_FALSE$]) m4trace:configure.ac:1023: -1- _AM_SUBST_NOTMAKE([HAVE_ICU_TRUE]) m4trace:configure.ac:1023: -1- _AM_SUBST_NOTMAKE([HAVE_ICU_FALSE]) m4trace:configure.ac:1024: -1- AM_CONDITIONAL([WITH_KERNEL_MODULES], [test "$with_kernel_modules" = "yes"]) m4trace:configure.ac:1024: -1- AC_SUBST([WITH_KERNEL_MODULES_TRUE]) m4trace:configure.ac:1024: -1- AC_SUBST_TRACE([WITH_KERNEL_MODULES_TRUE]) m4trace:configure.ac:1024: -1- m4_pattern_allow([^WITH_KERNEL_MODULES_TRUE$]) m4trace:configure.ac:1024: -1- AC_SUBST([WITH_KERNEL_MODULES_FALSE]) m4trace:configure.ac:1024: -1- AC_SUBST_TRACE([WITH_KERNEL_MODULES_FALSE]) m4trace:configure.ac:1024: -1- m4_pattern_allow([^WITH_KERNEL_MODULES_FALSE$]) m4trace:configure.ac:1024: -1- _AM_SUBST_NOTMAKE([WITH_KERNEL_MODULES_TRUE]) m4trace:configure.ac:1024: -1- _AM_SUBST_NOTMAKE([WITH_KERNEL_MODULES_FALSE]) m4trace:configure.ac:1025: -1- AM_CONDITIONAL([HAVE_XSM], [test "$have_xsm" = "yes"]) m4trace:configure.ac:1025: -1- AC_SUBST([HAVE_XSM_TRUE]) m4trace:configure.ac:1025: -1- AC_SUBST_TRACE([HAVE_XSM_TRUE]) m4trace:configure.ac:1025: -1- m4_pattern_allow([^HAVE_XSM_TRUE$]) m4trace:configure.ac:1025: -1- AC_SUBST([HAVE_XSM_FALSE]) m4trace:configure.ac:1025: -1- AC_SUBST_TRACE([HAVE_XSM_FALSE]) m4trace:configure.ac:1025: -1- m4_pattern_allow([^HAVE_XSM_FALSE$]) m4trace:configure.ac:1025: -1- _AM_SUBST_NOTMAKE([HAVE_XSM_TRUE]) m4trace:configure.ac:1025: -1- _AM_SUBST_NOTMAKE([HAVE_XSM_FALSE]) m4trace:configure.ac:1026: -1- AM_CONDITIONAL([HAVE_XCOMPOSITE], [test "$have_xcomposite" = "yes"]) m4trace:configure.ac:1026: -1- AC_SUBST([HAVE_XCOMPOSITE_TRUE]) m4trace:configure.ac:1026: -1- AC_SUBST_TRACE([HAVE_XCOMPOSITE_TRUE]) m4trace:configure.ac:1026: -1- m4_pattern_allow([^HAVE_XCOMPOSITE_TRUE$]) m4trace:configure.ac:1026: -1- AC_SUBST([HAVE_XCOMPOSITE_FALSE]) m4trace:configure.ac:1026: -1- AC_SUBST_TRACE([HAVE_XCOMPOSITE_FALSE]) m4trace:configure.ac:1026: -1- m4_pattern_allow([^HAVE_XCOMPOSITE_FALSE$]) m4trace:configure.ac:1026: -1- _AM_SUBST_NOTMAKE([HAVE_XCOMPOSITE_TRUE]) m4trace:configure.ac:1026: -1- _AM_SUBST_NOTMAKE([HAVE_XCOMPOSITE_FALSE]) m4trace:configure.ac:1027: -1- AM_CONDITIONAL([ENABLE_TESTS], [test "$have_cunit" = "yes"]) m4trace:configure.ac:1027: -1- AC_SUBST([ENABLE_TESTS_TRUE]) m4trace:configure.ac:1027: -1- AC_SUBST_TRACE([ENABLE_TESTS_TRUE]) m4trace:configure.ac:1027: -1- m4_pattern_allow([^ENABLE_TESTS_TRUE$]) m4trace:configure.ac:1027: -1- AC_SUBST([ENABLE_TESTS_FALSE]) m4trace:configure.ac:1027: -1- AC_SUBST_TRACE([ENABLE_TESTS_FALSE]) m4trace:configure.ac:1027: -1- m4_pattern_allow([^ENABLE_TESTS_FALSE$]) m4trace:configure.ac:1027: -1- _AM_SUBST_NOTMAKE([ENABLE_TESTS_TRUE]) m4trace:configure.ac:1027: -1- _AM_SUBST_NOTMAKE([ENABLE_TESTS_FALSE]) m4trace:configure.ac:1028: -1- AM_CONDITIONAL([WITH_ROOT_PRIVILEGES], [test "$with_root_privileges" = "yes"]) m4trace:configure.ac:1028: -1- AC_SUBST([WITH_ROOT_PRIVILEGES_TRUE]) m4trace:configure.ac:1028: -1- AC_SUBST_TRACE([WITH_ROOT_PRIVILEGES_TRUE]) m4trace:configure.ac:1028: -1- m4_pattern_allow([^WITH_ROOT_PRIVILEGES_TRUE$]) m4trace:configure.ac:1028: -1- AC_SUBST([WITH_ROOT_PRIVILEGES_FALSE]) m4trace:configure.ac:1028: -1- AC_SUBST_TRACE([WITH_ROOT_PRIVILEGES_FALSE]) m4trace:configure.ac:1028: -1- m4_pattern_allow([^WITH_ROOT_PRIVILEGES_FALSE$]) m4trace:configure.ac:1028: -1- _AM_SUBST_NOTMAKE([WITH_ROOT_PRIVILEGES_TRUE]) m4trace:configure.ac:1028: -1- _AM_SUBST_NOTMAKE([WITH_ROOT_PRIVILEGES_FALSE]) m4trace:configure.ac:1029: -1- AM_CONDITIONAL([HAVE_DNET], [test "$have_dnet" = "yes"]) m4trace:configure.ac:1029: -1- AC_SUBST([HAVE_DNET_TRUE]) m4trace:configure.ac:1029: -1- AC_SUBST_TRACE([HAVE_DNET_TRUE]) m4trace:configure.ac:1029: -1- m4_pattern_allow([^HAVE_DNET_TRUE$]) m4trace:configure.ac:1029: -1- AC_SUBST([HAVE_DNET_FALSE]) m4trace:configure.ac:1029: -1- AC_SUBST_TRACE([HAVE_DNET_FALSE]) m4trace:configure.ac:1029: -1- m4_pattern_allow([^HAVE_DNET_FALSE$]) m4trace:configure.ac:1029: -1- _AM_SUBST_NOTMAKE([HAVE_DNET_TRUE]) m4trace:configure.ac:1029: -1- _AM_SUBST_NOTMAKE([HAVE_DNET_FALSE]) m4trace:configure.ac:1030: -1- AM_CONDITIONAL([HAVE_DOXYGEN], [test "$have_doxygen" = "yes"]) m4trace:configure.ac:1030: -1- AC_SUBST([HAVE_DOXYGEN_TRUE]) m4trace:configure.ac:1030: -1- AC_SUBST_TRACE([HAVE_DOXYGEN_TRUE]) m4trace:configure.ac:1030: -1- m4_pattern_allow([^HAVE_DOXYGEN_TRUE$]) m4trace:configure.ac:1030: -1- AC_SUBST([HAVE_DOXYGEN_FALSE]) m4trace:configure.ac:1030: -1- AC_SUBST_TRACE([HAVE_DOXYGEN_FALSE]) m4trace:configure.ac:1030: -1- m4_pattern_allow([^HAVE_DOXYGEN_FALSE$]) m4trace:configure.ac:1030: -1- _AM_SUBST_NOTMAKE([HAVE_DOXYGEN_TRUE]) m4trace:configure.ac:1030: -1- _AM_SUBST_NOTMAKE([HAVE_DOXYGEN_FALSE]) m4trace:configure.ac:1031: -1- AM_CONDITIONAL([HAVE_FUSE], [test "$have_fuse" = "yes"]) m4trace:configure.ac:1031: -1- AC_SUBST([HAVE_FUSE_TRUE]) m4trace:configure.ac:1031: -1- AC_SUBST_TRACE([HAVE_FUSE_TRUE]) m4trace:configure.ac:1031: -1- m4_pattern_allow([^HAVE_FUSE_TRUE$]) m4trace:configure.ac:1031: -1- AC_SUBST([HAVE_FUSE_FALSE]) m4trace:configure.ac:1031: -1- AC_SUBST_TRACE([HAVE_FUSE_FALSE]) m4trace:configure.ac:1031: -1- m4_pattern_allow([^HAVE_FUSE_FALSE$]) m4trace:configure.ac:1031: -1- _AM_SUBST_NOTMAKE([HAVE_FUSE_TRUE]) m4trace:configure.ac:1031: -1- _AM_SUBST_NOTMAKE([HAVE_FUSE_FALSE]) m4trace:configure.ac:1032: -1- AM_CONDITIONAL([HAVE_GNU_LD], [test "$with_gnu_ld" = "yes"]) m4trace:configure.ac:1032: -1- AC_SUBST([HAVE_GNU_LD_TRUE]) m4trace:configure.ac:1032: -1- AC_SUBST_TRACE([HAVE_GNU_LD_TRUE]) m4trace:configure.ac:1032: -1- m4_pattern_allow([^HAVE_GNU_LD_TRUE$]) m4trace:configure.ac:1032: -1- AC_SUBST([HAVE_GNU_LD_FALSE]) m4trace:configure.ac:1032: -1- AC_SUBST_TRACE([HAVE_GNU_LD_FALSE]) m4trace:configure.ac:1032: -1- m4_pattern_allow([^HAVE_GNU_LD_FALSE$]) m4trace:configure.ac:1032: -1- _AM_SUBST_NOTMAKE([HAVE_GNU_LD_TRUE]) m4trace:configure.ac:1032: -1- _AM_SUBST_NOTMAKE([HAVE_GNU_LD_FALSE]) m4trace:configure.ac:1033: -1- AM_CONDITIONAL([HAVE_GTKMM], [test "$have_x" = "yes" -a "$with_gtkmm" = "yes"]) m4trace:configure.ac:1033: -1- AC_SUBST([HAVE_GTKMM_TRUE]) m4trace:configure.ac:1033: -1- AC_SUBST_TRACE([HAVE_GTKMM_TRUE]) m4trace:configure.ac:1033: -1- m4_pattern_allow([^HAVE_GTKMM_TRUE$]) m4trace:configure.ac:1033: -1- AC_SUBST([HAVE_GTKMM_FALSE]) m4trace:configure.ac:1033: -1- AC_SUBST_TRACE([HAVE_GTKMM_FALSE]) m4trace:configure.ac:1033: -1- m4_pattern_allow([^HAVE_GTKMM_FALSE$]) m4trace:configure.ac:1033: -1- _AM_SUBST_NOTMAKE([HAVE_GTKMM_TRUE]) m4trace:configure.ac:1033: -1- _AM_SUBST_NOTMAKE([HAVE_GTKMM_FALSE]) m4trace:configure.ac:1034: -1- AM_CONDITIONAL([HAVE_PAM], [test "$with_pam" = "yes"]) m4trace:configure.ac:1034: -1- AC_SUBST([HAVE_PAM_TRUE]) m4trace:configure.ac:1034: -1- AC_SUBST_TRACE([HAVE_PAM_TRUE]) m4trace:configure.ac:1034: -1- m4_pattern_allow([^HAVE_PAM_TRUE$]) m4trace:configure.ac:1034: -1- AC_SUBST([HAVE_PAM_FALSE]) m4trace:configure.ac:1034: -1- AC_SUBST_TRACE([HAVE_PAM_FALSE]) m4trace:configure.ac:1034: -1- m4_pattern_allow([^HAVE_PAM_FALSE$]) m4trace:configure.ac:1034: -1- _AM_SUBST_NOTMAKE([HAVE_PAM_TRUE]) m4trace:configure.ac:1034: -1- _AM_SUBST_NOTMAKE([HAVE_PAM_FALSE]) m4trace:configure.ac:1035: -1- AM_CONDITIONAL([USE_SLASH_PROC], [test "os" = "linux" -a "$have_glib_2_14" = "yes"]) m4trace:configure.ac:1035: -1- AC_SUBST([USE_SLASH_PROC_TRUE]) m4trace:configure.ac:1035: -1- AC_SUBST_TRACE([USE_SLASH_PROC_TRUE]) m4trace:configure.ac:1035: -1- m4_pattern_allow([^USE_SLASH_PROC_TRUE$]) m4trace:configure.ac:1035: -1- AC_SUBST([USE_SLASH_PROC_FALSE]) m4trace:configure.ac:1035: -1- AC_SUBST_TRACE([USE_SLASH_PROC_FALSE]) m4trace:configure.ac:1035: -1- m4_pattern_allow([^USE_SLASH_PROC_FALSE$]) m4trace:configure.ac:1035: -1- _AM_SUBST_NOTMAKE([USE_SLASH_PROC_TRUE]) m4trace:configure.ac:1035: -1- _AM_SUBST_NOTMAKE([USE_SLASH_PROC_FALSE]) m4trace:configure.ac:1036: -1- AM_CONDITIONAL([USE_PRINTF_WRAPPERS], [test "$bsdPrintfWrappers" = "yes"]) m4trace:configure.ac:1036: -1- AC_SUBST([USE_PRINTF_WRAPPERS_TRUE]) m4trace:configure.ac:1036: -1- AC_SUBST_TRACE([USE_PRINTF_WRAPPERS_TRUE]) m4trace:configure.ac:1036: -1- m4_pattern_allow([^USE_PRINTF_WRAPPERS_TRUE$]) m4trace:configure.ac:1036: -1- AC_SUBST([USE_PRINTF_WRAPPERS_FALSE]) m4trace:configure.ac:1036: -1- AC_SUBST_TRACE([USE_PRINTF_WRAPPERS_FALSE]) m4trace:configure.ac:1036: -1- m4_pattern_allow([^USE_PRINTF_WRAPPERS_FALSE$]) m4trace:configure.ac:1036: -1- _AM_SUBST_NOTMAKE([USE_PRINTF_WRAPPERS_TRUE]) m4trace:configure.ac:1036: -1- _AM_SUBST_NOTMAKE([USE_PRINTF_WRAPPERS_FALSE]) m4trace:configure.ac:1039: -1- AC_DEFINE_TRACE_LITERAL([NO_XSM]) m4trace:configure.ac:1039: -1- m4_pattern_allow([^NO_XSM$]) m4trace:configure.ac:1043: -1- AC_DEFINE_TRACE_LITERAL([NO_XCOMPOSITE]) m4trace:configure.ac:1043: -1- m4_pattern_allow([^NO_XCOMPOSITE$]) m4trace:configure.ac:1055: -1- AC_DEFINE_TRACE_LITERAL([NO_MULTIMON]) m4trace:configure.ac:1055: -1- m4_pattern_allow([^NO_MULTIMON$]) m4trace:configure.ac:1055: -1- AH_OUTPUT([NO_MULTIMON], [/* Define to 1 if building without multimon support. */ @%:@undef NO_MULTIMON]) m4trace:configure.ac:1097: -1- AC_SUBST([HGFS_LIBS]) m4trace:configure.ac:1097: -1- AC_SUBST_TRACE([HGFS_LIBS]) m4trace:configure.ac:1097: -1- m4_pattern_allow([^HGFS_LIBS$]) m4trace:configure.ac:1098: -1- AC_SUBST([TOOLS_VERSION]) m4trace:configure.ac:1098: -1- AC_SUBST_TRACE([TOOLS_VERSION]) m4trace:configure.ac:1098: -1- m4_pattern_allow([^TOOLS_VERSION$]) m4trace:configure.ac:1099: -1- AC_SUBST([TARGET_OS]) m4trace:configure.ac:1099: -1- AC_SUBST_TRACE([TARGET_OS]) m4trace:configure.ac:1099: -1- m4_pattern_allow([^TARGET_OS$]) m4trace:configure.ac:1100: -1- AC_SUBST([KERNEL_RELEASE]) m4trace:configure.ac:1100: -1- AC_SUBST_TRACE([KERNEL_RELEASE]) m4trace:configure.ac:1100: -1- m4_pattern_allow([^KERNEL_RELEASE$]) m4trace:configure.ac:1101: -1- AC_SUBST([LINUXINCLUDE]) m4trace:configure.ac:1101: -1- AC_SUBST_TRACE([LINUXINCLUDE]) m4trace:configure.ac:1101: -1- m4_pattern_allow([^LINUXINCLUDE$]) m4trace:configure.ac:1102: -1- AC_SUBST([MODULES_OS]) m4trace:configure.ac:1102: -1- AC_SUBST_TRACE([MODULES_OS]) m4trace:configure.ac:1102: -1- m4_pattern_allow([^MODULES_OS$]) m4trace:configure.ac:1103: -1- AC_SUBST([MODULES_DIR]) m4trace:configure.ac:1103: -1- AC_SUBST_TRACE([MODULES_DIR]) m4trace:configure.ac:1103: -1- m4_pattern_allow([^MODULES_DIR$]) m4trace:configure.ac:1104: -1- AC_SUBST([MODULES]) m4trace:configure.ac:1104: -1- AC_SUBST_TRACE([MODULES]) m4trace:configure.ac:1104: -1- m4_pattern_allow([^MODULES$]) m4trace:configure.ac:1105: -1- AC_SUBST([COMMON_XLIBS]) m4trace:configure.ac:1105: -1- AC_SUBST_TRACE([COMMON_XLIBS]) m4trace:configure.ac:1105: -1- m4_pattern_allow([^COMMON_XLIBS$]) m4trace:configure.ac:1106: -1- AC_SUBST([XSM_LIBS]) m4trace:configure.ac:1106: -1- AC_SUBST_TRACE([XSM_LIBS]) m4trace:configure.ac:1106: -1- m4_pattern_allow([^XSM_LIBS$]) m4trace:configure.ac:1107: -1- AC_SUBST([XCOMPOSITE_LIBS]) m4trace:configure.ac:1107: -1- AC_SUBST_TRACE([XCOMPOSITE_LIBS]) m4trace:configure.ac:1107: -1- m4_pattern_allow([^XCOMPOSITE_LIBS$]) m4trace:configure.ac:1108: -1- AC_SUBST([PAM_PREFIX]) m4trace:configure.ac:1108: -1- AC_SUBST_TRACE([PAM_PREFIX]) m4trace:configure.ac:1108: -1- m4_pattern_allow([^PAM_PREFIX$]) m4trace:configure.ac:1109: -1- AC_SUBST([PLUGIN_CPPFLAGS]) m4trace:configure.ac:1109: -1- AC_SUBST_TRACE([PLUGIN_CPPFLAGS]) m4trace:configure.ac:1109: -1- m4_pattern_allow([^PLUGIN_CPPFLAGS$]) m4trace:configure.ac:1110: -1- AC_SUBST([PLUGIN_LDFLAGS]) m4trace:configure.ac:1110: -1- AC_SUBST_TRACE([PLUGIN_LDFLAGS]) m4trace:configure.ac:1110: -1- m4_pattern_allow([^PLUGIN_LDFLAGS$]) m4trace:configure.ac:1111: -1- AC_SUBST([VMTOOLS_CPPFLAGS]) m4trace:configure.ac:1111: -1- AC_SUBST_TRACE([VMTOOLS_CPPFLAGS]) m4trace:configure.ac:1111: -1- m4_pattern_allow([^VMTOOLS_CPPFLAGS$]) m4trace:configure.ac:1112: -1- AC_SUBST([VMTOOLS_LIBS]) m4trace:configure.ac:1112: -1- AC_SUBST_TRACE([VMTOOLS_LIBS]) m4trace:configure.ac:1112: -1- m4_pattern_allow([^VMTOOLS_LIBS$]) m4trace:configure.ac:1113: -1- AC_SUBST([RPCGENFLAGS]) m4trace:configure.ac:1113: -1- AC_SUBST_TRACE([RPCGENFLAGS]) m4trace:configure.ac:1113: -1- m4_pattern_allow([^RPCGENFLAGS$]) m4trace:configure.ac:1114: -1- AC_SUBST([XDR_LIBS]) m4trace:configure.ac:1114: -1- AC_SUBST_TRACE([XDR_LIBS]) m4trace:configure.ac:1114: -1- m4_pattern_allow([^XDR_LIBS$]) m4trace:configure.ac:1115: -1- AC_SUBST([TEST_PLUGIN_INSTALLDIR]) m4trace:configure.ac:1115: -1- AC_SUBST_TRACE([TEST_PLUGIN_INSTALLDIR]) m4trace:configure.ac:1115: -1- m4_pattern_allow([^TEST_PLUGIN_INSTALLDIR$]) m4trace:configure.ac:1116: -1- AC_SUBST([COMMON_PLUGIN_INSTALLDIR]) m4trace:configure.ac:1116: -1- AC_SUBST_TRACE([COMMON_PLUGIN_INSTALLDIR]) m4trace:configure.ac:1116: -1- m4_pattern_allow([^COMMON_PLUGIN_INSTALLDIR$]) m4trace:configure.ac:1117: -1- AC_SUBST([VMSVC_PLUGIN_INSTALLDIR]) m4trace:configure.ac:1117: -1- AC_SUBST_TRACE([VMSVC_PLUGIN_INSTALLDIR]) m4trace:configure.ac:1117: -1- m4_pattern_allow([^VMSVC_PLUGIN_INSTALLDIR$]) m4trace:configure.ac:1118: -1- AC_SUBST([VMUSR_PLUGIN_INSTALLDIR]) m4trace:configure.ac:1118: -1- AC_SUBST_TRACE([VMUSR_PLUGIN_INSTALLDIR]) m4trace:configure.ac:1118: -1- m4_pattern_allow([^VMUSR_PLUGIN_INSTALLDIR$]) m4trace:configure.ac:1123: -1- AC_SUBST([SYSDIR]) m4trace:configure.ac:1123: -1- AC_SUBST_TRACE([SYSDIR]) m4trace:configure.ac:1123: -1- m4_pattern_allow([^SYSDIR$]) m4trace:configure.ac:1125: -1- AC_SUBST([INSTVMSG]) m4trace:configure.ac:1125: -1- AC_SUBST_TRACE([INSTVMSG]) m4trace:configure.ac:1125: -1- m4_pattern_allow([^INSTVMSG$]) m4trace:configure.ac:1126: -1- AC_SUBST([RPCGEN_WRAPPER]) m4trace:configure.ac:1126: -1- AC_SUBST_TRACE([RPCGEN_WRAPPER]) m4trace:configure.ac:1126: -1- m4_pattern_allow([^RPCGEN_WRAPPER$]) m4trace:configure.ac:1130: -1- AC_SUBST([LIB_AUTH_CPPFLAGS]) m4trace:configure.ac:1130: -1- AC_SUBST_TRACE([LIB_AUTH_CPPFLAGS]) m4trace:configure.ac:1130: -1- m4_pattern_allow([^LIB_AUTH_CPPFLAGS$]) m4trace:configure.ac:1131: -1- AC_SUBST([LIB_IMPERSONATE_CPPFLAGS]) m4trace:configure.ac:1131: -1- AC_SUBST_TRACE([LIB_IMPERSONATE_CPPFLAGS]) m4trace:configure.ac:1131: -1- m4_pattern_allow([^LIB_IMPERSONATE_CPPFLAGS$]) m4trace:configure.ac:1132: -1- AC_SUBST([LIB_USER_CPPFLAGS]) m4trace:configure.ac:1132: -1- AC_SUBST_TRACE([LIB_USER_CPPFLAGS]) m4trace:configure.ac:1132: -1- m4_pattern_allow([^LIB_USER_CPPFLAGS$]) m4trace:configure.ac:1133: -1- AC_SUBST([LIBVMTOOLS_LIBADD]) m4trace:configure.ac:1133: -1- AC_SUBST_TRACE([LIBVMTOOLS_LIBADD]) m4trace:configure.ac:1133: -1- m4_pattern_allow([^LIBVMTOOLS_LIBADD$]) m4trace:configure.ac:1137: -1- AC_SUBST([VIX_LIBADD]) m4trace:configure.ac:1137: -1- AC_SUBST_TRACE([VIX_LIBADD]) m4trace:configure.ac:1137: -1- m4_pattern_allow([^VIX_LIBADD$]) m4trace:configure.ac:1142: -1- AC_CONFIG_FILES([ \ Makefile \ lib/Makefile \ lib/appUtil/Makefile \ lib/auth/Makefile \ lib/backdoor/Makefile \ lib/dict/Makefile \ lib/dynxdr/Makefile \ lib/err/Makefile \ lib/file/Makefile \ lib/foundryMsg/Makefile \ lib/glibUtils/Makefile \ lib/guestApp/Makefile \ lib/guestRpc/Makefile \ lib/hgfs/Makefile \ lib/hgfsBd/Makefile \ lib/hgfsHelper/Makefile \ lib/hgfsServer/Makefile \ lib/hgfsServerManagerGuest/Makefile \ lib/hgfsServerPolicyGuest/Makefile \ lib/impersonate/Makefile \ lib/lock/Makefile \ lib/message/Makefile \ lib/misc/Makefile \ lib/netUtil/Makefile \ lib/panic/Makefile \ lib/panicDefault/Makefile \ lib/printer/Makefile \ lib/procMgr/Makefile \ lib/rpcChannel/Makefile \ lib/rpcIn/Makefile \ lib/rpcOut/Makefile \ lib/rpcVmx/Makefile \ lib/slashProc/Makefile \ lib/string/Makefile \ lib/stubs/Makefile \ lib/syncDriver/Makefile \ lib/system/Makefile \ lib/unicode/Makefile \ lib/user/Makefile \ lib/vmCheck/Makefile \ lib/vmSignal/Makefile \ lib/wiper/Makefile \ lib/xdg/Makefile \ services/Makefile \ services/vmtoolsd/Makefile \ services/plugins/Makefile \ services/plugins/desktopEvents/Makefile \ services/plugins/dndcp/Makefile \ services/plugins/guestInfo/Makefile \ services/plugins/guestInfo/getlib/Makefile \ services/plugins/hgfsServer/Makefile \ services/plugins/powerOps/Makefile \ services/plugins/resolutionSet/Makefile \ services/plugins/timeSync/Makefile \ services/plugins/vix/Makefile \ services/plugins/vmbackup/Makefile \ vmware-user-suid-wrapper/Makefile \ toolbox/Makefile \ hgfsclient/Makefile \ hgfsmounter/Makefile \ checkvm/Makefile \ rpctool/Makefile \ libguestlib/Makefile \ libguestlib/vmguestlib.pc \ libhgfs/Makefile \ libvmtools/Makefile \ xferlogs/Makefile \ modules/Makefile \ vmblock-fuse/Makefile \ vmblockmounter/Makefile \ tests/Makefile \ tests/vmrpcdbg/Makefile \ tests/testDebug/Makefile \ tests/testPlugin/Makefile \ tests/testVmblock/Makefile \ docs/Makefile \ docs/api/Makefile \ scripts/Makefile \ scripts/build/rpcgen_wrapper.sh \ ]) m4trace:configure.ac:1227: -1- AC_SUBST([LIB@&t@OBJS], [$ac_libobjs]) m4trace:configure.ac:1227: -1- AC_SUBST_TRACE([LIB@&t@OBJS]) m4trace:configure.ac:1227: -1- m4_pattern_allow([^LIB@&t@OBJS$]) m4trace:configure.ac:1227: -1- AC_SUBST([LTLIBOBJS], [$ac_ltlibobjs]) m4trace:configure.ac:1227: -1- AC_SUBST_TRACE([LTLIBOBJS]) m4trace:configure.ac:1227: -1- m4_pattern_allow([^LTLIBOBJS$]) m4trace:configure.ac:1227: -1- AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"]) m4trace:configure.ac:1227: -1- AC_SUBST([am__EXEEXT_TRUE]) m4trace:configure.ac:1227: -1- AC_SUBST_TRACE([am__EXEEXT_TRUE]) m4trace:configure.ac:1227: -1- m4_pattern_allow([^am__EXEEXT_TRUE$]) m4trace:configure.ac:1227: -1- AC_SUBST([am__EXEEXT_FALSE]) m4trace:configure.ac:1227: -1- AC_SUBST_TRACE([am__EXEEXT_FALSE]) m4trace:configure.ac:1227: -1- m4_pattern_allow([^am__EXEEXT_FALSE$]) m4trace:configure.ac:1227: -1- _AM_SUBST_NOTMAKE([am__EXEEXT_TRUE]) m4trace:configure.ac:1227: -1- _AM_SUBST_NOTMAKE([am__EXEEXT_FALSE]) m4trace:configure.ac:1227: -1- AC_SUBST_TRACE([top_builddir]) m4trace:configure.ac:1227: -1- AC_SUBST_TRACE([top_build_prefix]) m4trace:configure.ac:1227: -1- AC_SUBST_TRACE([srcdir]) m4trace:configure.ac:1227: -1- AC_SUBST_TRACE([abs_srcdir]) m4trace:configure.ac:1227: -1- AC_SUBST_TRACE([top_srcdir]) m4trace:configure.ac:1227: -1- AC_SUBST_TRACE([abs_top_srcdir]) m4trace:configure.ac:1227: -1- AC_SUBST_TRACE([builddir]) m4trace:configure.ac:1227: -1- AC_SUBST_TRACE([abs_builddir]) m4trace:configure.ac:1227: -1- AC_SUBST_TRACE([abs_top_builddir]) m4trace:configure.ac:1227: -1- AC_SUBST_TRACE([INSTALL]) m4trace:configure.ac:1227: -1- AC_SUBST_TRACE([MKDIR_P]) m4trace:configure.ac:1227: -1- AC_REQUIRE_AUX_FILE([ltmain.sh]) open-vm-tools-9.4.0-1280544/autom4te.cache/requests0000644765153500003110000006140612220061620020040 0ustar dtormts# This file was generated. # It contains the lists of macros which have been traced. # It can be safely removed. @request = ( bless( [ '0', 1, [ '/usr/share/autoconf' ], [ '/usr/share/autoconf/autoconf/autoconf.m4f', '/usr/share/aclocal/argz.m4', '/usr/share/aclocal/libtool.m4', '/usr/share/aclocal/ltdl.m4', '/usr/share/aclocal/ltoptions.m4', '/usr/share/aclocal/ltsugar.m4', '/usr/share/aclocal/ltversion.m4', '/usr/share/aclocal/lt~obsolete.m4', '/usr/share/aclocal-1.12/amversion.m4', '/usr/share/aclocal-1.12/auxdir.m4', '/usr/share/aclocal-1.12/cond.m4', '/usr/share/aclocal-1.12/depend.m4', '/usr/share/aclocal-1.12/depout.m4', '/usr/share/aclocal-1.12/init.m4', '/usr/share/aclocal-1.12/install-sh.m4', '/usr/share/aclocal-1.12/lead-dot.m4', '/usr/share/aclocal-1.12/make.m4', '/usr/share/aclocal-1.12/minuso.m4', '/usr/share/aclocal-1.12/missing.m4', '/usr/share/aclocal-1.12/options.m4', '/usr/share/aclocal-1.12/runlog.m4', '/usr/share/aclocal-1.12/sanity.m4', '/usr/share/aclocal-1.12/silent.m4', '/usr/share/aclocal-1.12/strip.m4', '/usr/share/aclocal-1.12/substnot.m4', '/usr/share/aclocal-1.12/tar.m4', 'm4/vmtools.m4', 'configure.ac' ], { 'AM_ENABLE_STATIC' => 1, 'AC_LIBTOOL_LANG_RC_CONFIG' => 1, '_LT_AC_SHELL_INIT' => 1, 'AC_DEFUN' => 1, 'AC_PROG_LIBTOOL' => 1, '_LT_AC_LANG_CXX_CONFIG' => 1, 'AM_AUTOMAKE_VERSION' => 1, 'AM_SUBST_NOTMAKE' => 1, 'AM_MISSING_PROG' => 1, 'AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH' => 1, '_LT_AC_LANG_C_CONFIG' => 1, 'AM_PROG_INSTALL_STRIP' => 1, '_m4_warn' => 1, 'AC_VMW_CHECK_LIB' => 1, 'AC_LIBTOOL_OBJDIR' => 1, 'gl_FUNC_ARGZ' => 1, 'LTOBSOLETE_VERSION' => 1, 'AM_SANITY_CHECK' => 1, 'AC_LIBTOOL_LANG_GCJ_CONFIG' => 1, 'AC_LIBTOOL_PROG_COMPILER_PIC' => 1, 'LT_LIB_M' => 1, '_LT_AC_CHECK_DLFCN' => 1, 'AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE' => 1, 'LTSUGAR_VERSION' => 1, '_LT_PROG_LTMAIN' => 1, 'LT_SYS_SYMBOL_USCORE' => 1, '_AM_PROG_TAR' => 1, 'AC_LIBTOOL_GCJ' => 1, '_LT_WITH_SYSROOT' => 1, 'LT_FUNC_DLSYM_USCORE' => 1, 'LT_SYS_DLOPEN_DEPLIBS' => 1, '_LT_AC_LANG_F77' => 1, 'AC_LIBTOOL_CONFIG' => 1, 'AC_LTDL_DLLIB' => 1, '_AM_SUBST_NOTMAKE' => 1, '_AM_AUTOCONF_VERSION' => 1, 'AM_DISABLE_SHARED' => 1, '_LT_PROG_ECHO_BACKSLASH' => 1, '_LTDL_SETUP' => 1, 'AM_PROG_LIBTOOL' => 1, '_LT_AC_LANG_CXX' => 1, 'AM_PROG_LD' => 1, '_LT_AC_FILE_LTDLL_C' => 1, 'AC_LIB_LTDL' => 1, 'AU_DEFUN' => 1, 'AC_PROG_NM' => 1, 'AC_LIBTOOL_DLOPEN' => 1, 'AC_PROG_LD' => 1, 'AC_PROG_LD_GNU' => 1, 'AC_ENABLE_FAST_INSTALL' => 1, 'AC_LIBTOOL_FC' => 1, 'LTDL_CONVENIENCE' => 1, '_AM_SET_OPTION' => 1, 'AC_LTDL_PREOPEN' => 1, '_LT_LINKER_BOILERPLATE' => 1, '_LT_PREPARE_SED_QUOTE_VARS' => 1, 'AC_LIBTOOL_LANG_CXX_CONFIG' => 1, 'AC_LIBTOOL_PROG_CC_C_O' => 1, 'gl_PREREQ_ARGZ' => 1, 'LT_SUPPORTED_TAG' => 1, 'AM_OUTPUT_DEPENDENCY_COMMANDS' => 1, 'LT_PROG_RC' => 1, 'LT_SYS_MODULE_EXT' => 1, 'AC_DEFUN_ONCE' => 1, '_LT_AC_LANG_GCJ' => 1, 'AC_VMW_CHECK_LIBXX' => 1, 'AC_LTDL_OBJDIR' => 1, '_LT_PATH_TOOL_PREFIX' => 1, 'AC_LIBTOOL_RC' => 1, '_LT_AC_PROG_ECHO_BACKSLASH' => 1, 'AC_DISABLE_FAST_INSTALL' => 1, 'AM_SILENT_RULES' => 1, 'include' => 1, '_LT_AC_TRY_DLOPEN_SELF' => 1, '_LT_AC_SYS_LIBPATH_AIX' => 1, 'LT_AC_PROG_SED' => 1, 'AM_ENABLE_SHARED' => 1, 'LTDL_INSTALLABLE' => 1, '_LT_AC_LANG_GCJ_CONFIG' => 1, 'AC_ENABLE_SHARED' => 1, '_LT_REQUIRED_DARWIN_CHECKS' => 1, 'AC_LIBTOOL_SYS_HARD_LINK_LOCKS' => 1, 'AC_ENABLE_STATIC' => 1, '_LT_AC_TAGVAR' => 1, 'AM_PROG_CC_C_O' => 1, 'AC_LIBTOOL_LANG_F77_CONFIG' => 1, 'AM_CONDITIONAL' => 1, 'LT_LIB_DLLOAD' => 1, 'LTVERSION_VERSION' => 1, '_LT_PROG_CXX' => 1, '_LT_PROG_F77' => 1, 'LTDL_INIT' => 1, 'm4_include' => 1, 'AC_VMW_LIB_ERROR' => 1, 'AM_PROG_INSTALL_SH' => 1, 'AC_PROG_EGREP' => 1, 'AC_PATH_MAGIC' => 1, '_AC_AM_CONFIG_HEADER_HOOK' => 1, 'AC_LTDL_SYSSEARCHPATH' => 1, 'AM_MAKE_INCLUDE' => 1, 'LT_CMD_MAX_LEN' => 1, '_LT_AC_TAGCONFIG' => 1, 'm4_pattern_forbid' => 1, '_LT_LINKER_OPTION' => 1, 'AC_LIBTOOL_COMPILER_OPTION' => 1, 'AC_DISABLE_SHARED' => 1, '_LT_COMPILER_BOILERPLATE' => 1, 'AC_LIBTOOL_WIN32_DLL' => 1, 'AC_LIBTOOL_SETUP' => 1, 'AC_PROG_LD_RELOAD_FLAG' => 1, 'AC_LTDL_DLSYM_USCORE' => 1, 'AM_MISSING_HAS_RUN' => 1, 'LT_LANG' => 1, 'LT_SYS_DLSEARCH_PATH' => 1, 'LT_CONFIG_LTDL_DIR' => 1, 'AC_LIBTOOL_DLOPEN_SELF' => 1, 'LT_OUTPUT' => 1, 'AC_LIBTOOL_PROG_LD_SHLIBS' => 1, 'AC_VMW_CHECK_X11_LIB' => 1, 'AC_WITH_LTDL' => 1, 'AC_LIBTOOL_LINKER_OPTION' => 1, 'LT_AC_PROG_RC' => 1, 'AC_LIBTOOL_CXX' => 1, 'LT_INIT' => 1, 'LT_AC_PROG_GCJ' => 1, 'LT_SYS_DLOPEN_SELF' => 1, '_LT_AC_PROG_CXXCPP' => 1, 'AM_DEP_TRACK' => 1, 'AM_DISABLE_STATIC' => 1, '_AC_PROG_LIBTOOL' => 1, '_AM_IF_OPTION' => 1, 'AC_PATH_TOOL_PREFIX' => 1, 'm4_pattern_allow' => 1, 'AC_LIBTOOL_F77' => 1, 'AM_SET_LEADING_DOT' => 1, '_LT_PROG_FC' => 1, 'LT_AC_PROG_EGREP' => 1, '_AM_DEPENDENCIES' => 1, 'AC_LIBTOOL_LANG_C_CONFIG' => 1, 'LTOPTIONS_VERSION' => 1, '_LT_AC_SYS_COMPILER' => 1, 'AM_PROG_NM' => 1, 'AC_LIBLTDL_CONVENIENCE' => 1, 'AC_DEPLIBS_CHECK_METHOD' => 1, 'AC_LIBLTDL_INSTALLABLE' => 1, 'AM_SET_CURRENT_AUTOMAKE_VERSION' => 1, 'AC_LTDL_ENABLE_INSTALL' => 1, 'LT_PROG_GCJ' => 1, 'AC_LIBTOOL_SYS_DYNAMIC_LINKER' => 1, 'AM_INIT_AUTOMAKE' => 1, 'AC_DISABLE_STATIC' => 1, 'LT_PATH_NM' => 1, 'AC_LTDL_SHLIBEXT' => 1, '_LT_AC_LOCK' => 1, '_LT_AC_LANG_RC_CONFIG' => 1, 'LT_PROG_GO' => 1, 'LT_SYS_MODULE_PATH' => 1, 'LT_WITH_LTDL' => 1, 'AC_LIBTOOL_POSTDEP_PREDEP' => 1, 'AC_LTDL_SHLIBPATH' => 1, 'AM_AUX_DIR_EXPAND' => 1, 'AC_LIBTOOL_PROG_COMPILER_NO_RTTI' => 1, '_LT_AC_LANG_F77_CONFIG' => 1, '_LT_COMPILER_OPTION' => 1, '_AM_SET_OPTIONS' => 1, 'AC_VMW_DEFAULT_FLAGS' => 1, 'AM_RUN_LOG' => 1, '_AM_OUTPUT_DEPENDENCY_COMMANDS' => 1, 'AC_LIBTOOL_PICMODE' => 1, 'AC_LTDL_SYS_DLOPEN_DEPLIBS' => 1, 'AC_LIBTOOL_SYS_OLD_ARCHIVE' => 1, 'AC_CHECK_LIBM' => 1, 'LT_PATH_LD' => 1, 'AC_LIBTOOL_SYS_LIB_STRIP' => 1, '_AM_MANGLE_OPTION' => 1, 'AC_LIBTOOL_SYS_MAX_CMD_LEN' => 1, 'AC_LTDL_SYMBOL_USCORE' => 1, 'AM_SET_DEPDIR' => 1, '_LT_CC_BASENAME' => 1, '_LT_LIBOBJ' => 1 } ], 'Autom4te::Request' ), bless( [ '1', 1, [ '/usr/share/autoconf' ], [ '/usr/share/autoconf/autoconf/autoconf.m4f', 'aclocal.m4', 'configure.ac' ], { 'AM_PROG_F77_C_O' => 1, '_LT_AC_TAGCONFIG' => 1, 'AC_INIT' => 1, 'm4_pattern_forbid' => 1, 'AC_CANONICAL_TARGET' => 1, '_AM_COND_IF' => 1, 'AC_CONFIG_LIBOBJ_DIR' => 1, 'AC_SUBST' => 1, 'AC_CANONICAL_HOST' => 1, 'AC_FC_SRCEXT' => 1, 'AC_PROG_LIBTOOL' => 1, 'AM_PROG_MKDIR_P' => 1, 'AM_INIT_AUTOMAKE' => 1, 'AC_CONFIG_SUBDIRS' => 1, 'AM_PATH_GUILE' => 1, 'AM_AUTOMAKE_VERSION' => 1, 'LT_CONFIG_LTDL_DIR' => 1, 'AC_CONFIG_LINKS' => 1, 'AC_REQUIRE_AUX_FILE' => 1, 'LT_SUPPORTED_TAG' => 1, 'm4_sinclude' => 1, 'AM_MAINTAINER_MODE' => 1, 'AM_NLS' => 1, 'AC_FC_PP_DEFINE' => 1, 'AM_GNU_GETTEXT_INTL_SUBDIR' => 1, '_m4_warn' => 1, 'AM_MAKEFILE_INCLUDE' => 1, 'AM_PROG_CXX_C_O' => 1, '_AM_MAKEFILE_INCLUDE' => 1, '_AM_COND_ENDIF' => 1, 'AM_ENABLE_MULTILIB' => 1, 'AM_SILENT_RULES' => 1, 'AM_PROG_MOC' => 1, 'AC_CONFIG_FILES' => 1, 'include' => 1, 'LT_INIT' => 1, 'AM_GNU_GETTEXT' => 1, 'AM_PROG_AR' => 1, 'AC_LIBSOURCE' => 1, 'AC_CANONICAL_BUILD' => 1, 'AM_PROG_FC_C_O' => 1, 'AC_FC_FREEFORM' => 1, 'AC_FC_PP_SRCEXT' => 1, 'AH_OUTPUT' => 1, 'AC_CONFIG_AUX_DIR' => 1, '_AM_SUBST_NOTMAKE' => 1, 'm4_pattern_allow' => 1, 'AM_PROG_CC_C_O' => 1, 'sinclude' => 1, 'AM_CONDITIONAL' => 1, 'AC_CANONICAL_SYSTEM' => 1, 'AM_XGETTEXT_OPTION' => 1, 'AC_CONFIG_HEADERS' => 1, 'AC_DEFINE_TRACE_LITERAL' => 1, 'AM_POT_TOOLS' => 1, 'm4_include' => 1, '_AM_COND_ELSE' => 1, 'AC_SUBST_TRACE' => 1 } ], 'Autom4te::Request' ), bless( [ '2', 1, [ '/usr/share/autoconf' ], [ '/usr/share/autoconf/autoconf/autoconf.m4f', '/usr/share/aclocal/argz.m4', '/usr/share/aclocal/ltdl.m4', '/usr/share/aclocal-1.12/amversion.m4', '/usr/share/aclocal-1.12/auxdir.m4', '/usr/share/aclocal-1.12/cond.m4', '/usr/share/aclocal-1.12/depend.m4', '/usr/share/aclocal-1.12/depout.m4', '/usr/share/aclocal-1.12/init.m4', '/usr/share/aclocal-1.12/install-sh.m4', '/usr/share/aclocal-1.12/lead-dot.m4', '/usr/share/aclocal-1.12/make.m4', '/usr/share/aclocal-1.12/minuso.m4', '/usr/share/aclocal-1.12/missing.m4', '/usr/share/aclocal-1.12/options.m4', '/usr/share/aclocal-1.12/runlog.m4', '/usr/share/aclocal-1.12/sanity.m4', '/usr/share/aclocal-1.12/silent.m4', '/usr/share/aclocal-1.12/strip.m4', '/usr/share/aclocal-1.12/substnot.m4', '/usr/share/aclocal-1.12/tar.m4', 'm4/libtool.m4', 'm4/ltoptions.m4', 'm4/ltsugar.m4', 'm4/ltversion.m4', 'm4/lt~obsolete.m4', 'm4/vmtools.m4', 'configure.ac' ], { 'AM_ENABLE_STATIC' => 1, 'AC_LIBTOOL_LANG_RC_CONFIG' => 1, '_LT_AC_SHELL_INIT' => 1, 'AC_DEFUN' => 1, 'AC_PROG_LIBTOOL' => 1, '_LT_AC_LANG_CXX_CONFIG' => 1, 'AM_AUTOMAKE_VERSION' => 1, 'AM_SUBST_NOTMAKE' => 1, 'AM_MISSING_PROG' => 1, 'AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH' => 1, '_LT_AC_LANG_C_CONFIG' => 1, 'AM_PROG_INSTALL_STRIP' => 1, '_m4_warn' => 1, 'AC_VMW_CHECK_LIB' => 1, 'AC_LIBTOOL_OBJDIR' => 1, 'gl_FUNC_ARGZ' => 1, 'LTOBSOLETE_VERSION' => 1, 'AM_SANITY_CHECK' => 1, 'AC_LIBTOOL_LANG_GCJ_CONFIG' => 1, 'AC_LIBTOOL_PROG_COMPILER_PIC' => 1, 'LT_LIB_M' => 1, '_LT_AC_CHECK_DLFCN' => 1, 'AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE' => 1, 'LTSUGAR_VERSION' => 1, '_LT_PROG_LTMAIN' => 1, 'LT_SYS_SYMBOL_USCORE' => 1, '_AM_PROG_TAR' => 1, 'AC_LIBTOOL_GCJ' => 1, '_LT_WITH_SYSROOT' => 1, 'LT_FUNC_DLSYM_USCORE' => 1, 'LT_SYS_DLOPEN_DEPLIBS' => 1, '_LT_AC_LANG_F77' => 1, 'AC_LIBTOOL_CONFIG' => 1, 'AC_LTDL_DLLIB' => 1, '_AM_SUBST_NOTMAKE' => 1, '_AM_AUTOCONF_VERSION' => 1, 'AM_DISABLE_SHARED' => 1, '_LT_PROG_ECHO_BACKSLASH' => 1, '_LTDL_SETUP' => 1, 'AM_PROG_LIBTOOL' => 1, '_LT_AC_LANG_CXX' => 1, 'AM_PROG_LD' => 1, '_LT_AC_FILE_LTDLL_C' => 1, 'AC_LIB_LTDL' => 1, 'AU_DEFUN' => 1, 'AC_PROG_NM' => 1, 'AC_LIBTOOL_DLOPEN' => 1, 'AC_PROG_LD' => 1, 'AC_PROG_LD_GNU' => 1, 'AC_ENABLE_FAST_INSTALL' => 1, 'AC_LIBTOOL_FC' => 1, 'LTDL_CONVENIENCE' => 1, '_AM_SET_OPTION' => 1, 'AC_LTDL_PREOPEN' => 1, '_LT_LINKER_BOILERPLATE' => 1, '_LT_PREPARE_SED_QUOTE_VARS' => 1, 'AC_LIBTOOL_LANG_CXX_CONFIG' => 1, 'AC_LIBTOOL_PROG_CC_C_O' => 1, 'gl_PREREQ_ARGZ' => 1, 'LT_SUPPORTED_TAG' => 1, 'AM_OUTPUT_DEPENDENCY_COMMANDS' => 1, 'LT_PROG_RC' => 1, 'LT_SYS_MODULE_EXT' => 1, 'AC_DEFUN_ONCE' => 1, '_LT_AC_LANG_GCJ' => 1, 'AC_VMW_CHECK_LIBXX' => 1, 'AC_LTDL_OBJDIR' => 1, '_LT_PATH_TOOL_PREFIX' => 1, 'AC_LIBTOOL_RC' => 1, '_LT_AC_PROG_ECHO_BACKSLASH' => 1, 'AC_DISABLE_FAST_INSTALL' => 1, 'AM_SILENT_RULES' => 1, 'include' => 1, '_LT_AC_TRY_DLOPEN_SELF' => 1, '_LT_AC_SYS_LIBPATH_AIX' => 1, 'LT_AC_PROG_SED' => 1, 'AM_ENABLE_SHARED' => 1, 'LTDL_INSTALLABLE' => 1, '_LT_AC_LANG_GCJ_CONFIG' => 1, 'AC_ENABLE_SHARED' => 1, '_LT_REQUIRED_DARWIN_CHECKS' => 1, 'AC_LIBTOOL_SYS_HARD_LINK_LOCKS' => 1, 'AC_ENABLE_STATIC' => 1, '_LT_AC_TAGVAR' => 1, 'AM_PROG_CC_C_O' => 1, 'AC_LIBTOOL_LANG_F77_CONFIG' => 1, 'AM_CONDITIONAL' => 1, 'LT_LIB_DLLOAD' => 1, 'LTVERSION_VERSION' => 1, '_LT_PROG_CXX' => 1, '_LT_PROG_F77' => 1, 'LTDL_INIT' => 1, 'm4_include' => 1, 'AC_VMW_LIB_ERROR' => 1, 'AM_PROG_INSTALL_SH' => 1, 'AC_PROG_EGREP' => 1, 'AC_PATH_MAGIC' => 1, '_AC_AM_CONFIG_HEADER_HOOK' => 1, 'AC_LTDL_SYSSEARCHPATH' => 1, 'AM_MAKE_INCLUDE' => 1, 'LT_CMD_MAX_LEN' => 1, '_LT_AC_TAGCONFIG' => 1, 'm4_pattern_forbid' => 1, '_LT_LINKER_OPTION' => 1, 'AC_LIBTOOL_COMPILER_OPTION' => 1, 'AC_DISABLE_SHARED' => 1, '_LT_COMPILER_BOILERPLATE' => 1, 'AC_LIBTOOL_WIN32_DLL' => 1, 'AC_LIBTOOL_SETUP' => 1, 'AC_PROG_LD_RELOAD_FLAG' => 1, 'AC_LTDL_DLSYM_USCORE' => 1, 'AM_MISSING_HAS_RUN' => 1, 'LT_LANG' => 1, 'LT_SYS_DLSEARCH_PATH' => 1, 'LT_CONFIG_LTDL_DIR' => 1, 'AC_LIBTOOL_DLOPEN_SELF' => 1, 'LT_OUTPUT' => 1, 'AC_LIBTOOL_PROG_LD_SHLIBS' => 1, 'AC_VMW_CHECK_X11_LIB' => 1, 'AC_WITH_LTDL' => 1, 'AC_LIBTOOL_LINKER_OPTION' => 1, 'LT_AC_PROG_RC' => 1, 'AC_LIBTOOL_CXX' => 1, 'LT_INIT' => 1, 'LT_AC_PROG_GCJ' => 1, 'LT_SYS_DLOPEN_SELF' => 1, 'AM_DISABLE_STATIC' => 1, '_LT_AC_PROG_CXXCPP' => 1, 'AM_DEP_TRACK' => 1, '_AC_PROG_LIBTOOL' => 1, '_AM_IF_OPTION' => 1, 'AC_PATH_TOOL_PREFIX' => 1, 'm4_pattern_allow' => 1, 'AC_LIBTOOL_F77' => 1, 'AM_SET_LEADING_DOT' => 1, '_LT_PROG_FC' => 1, 'LT_AC_PROG_EGREP' => 1, '_AM_DEPENDENCIES' => 1, 'AC_LIBTOOL_LANG_C_CONFIG' => 1, 'LTOPTIONS_VERSION' => 1, '_LT_AC_SYS_COMPILER' => 1, 'AM_PROG_NM' => 1, 'AC_LIBLTDL_CONVENIENCE' => 1, 'AC_DEPLIBS_CHECK_METHOD' => 1, 'AC_LIBLTDL_INSTALLABLE' => 1, 'AM_SET_CURRENT_AUTOMAKE_VERSION' => 1, 'AC_LTDL_ENABLE_INSTALL' => 1, 'LT_PROG_GCJ' => 1, 'AC_LIBTOOL_SYS_DYNAMIC_LINKER' => 1, 'AM_INIT_AUTOMAKE' => 1, 'AC_DISABLE_STATIC' => 1, 'LT_PATH_NM' => 1, 'AC_LTDL_SHLIBEXT' => 1, '_LT_AC_LOCK' => 1, '_LT_AC_LANG_RC_CONFIG' => 1, 'LT_PROG_GO' => 1, 'LT_SYS_MODULE_PATH' => 1, 'LT_WITH_LTDL' => 1, 'AC_LIBTOOL_POSTDEP_PREDEP' => 1, 'AC_LTDL_SHLIBPATH' => 1, 'AM_AUX_DIR_EXPAND' => 1, 'AC_LIBTOOL_PROG_COMPILER_NO_RTTI' => 1, '_LT_AC_LANG_F77_CONFIG' => 1, '_LT_COMPILER_OPTION' => 1, '_AM_SET_OPTIONS' => 1, 'AC_VMW_DEFAULT_FLAGS' => 1, 'AM_RUN_LOG' => 1, '_AM_OUTPUT_DEPENDENCY_COMMANDS' => 1, 'AC_LIBTOOL_PICMODE' => 1, 'AC_LTDL_SYS_DLOPEN_DEPLIBS' => 1, 'AC_LIBTOOL_SYS_OLD_ARCHIVE' => 1, 'AC_CHECK_LIBM' => 1, 'LT_PATH_LD' => 1, 'AC_LIBTOOL_SYS_LIB_STRIP' => 1, '_AM_MANGLE_OPTION' => 1, 'AC_LIBTOOL_SYS_MAX_CMD_LEN' => 1, 'AC_LTDL_SYMBOL_USCORE' => 1, 'AM_SET_DEPDIR' => 1, '_LT_CC_BASENAME' => 1, '_LT_LIBOBJ' => 1 } ], 'Autom4te::Request' ) ); open-vm-tools-9.4.0-1280544/autom4te.cache/traces.00000644765153500003110000041236112220061611017604 0ustar dtormtsm4trace:/usr/share/aclocal/argz.m4:12: -1- AC_DEFUN([gl_FUNC_ARGZ], [gl_PREREQ_ARGZ AC_CHECK_HEADERS([argz.h], [], [], [AC_INCLUDES_DEFAULT]) AC_CHECK_TYPES([error_t], [], [AC_DEFINE([error_t], [int], [Define to a type to use for `error_t' if it is not otherwise available.]) AC_DEFINE([__error_t_defined], [1], [Define so that glibc/gnulib argp.h does not typedef error_t.])], [#if defined(HAVE_ARGZ_H) # include #endif]) ARGZ_H= AC_CHECK_FUNCS([argz_add argz_append argz_count argz_create_sep argz_insert \ argz_next argz_stringify], [], [ARGZ_H=argz.h; AC_LIBOBJ([argz])]) dnl if have system argz functions, allow forced use of dnl libltdl-supplied implementation (and default to do so dnl on "known bad" systems). Could use a runtime check, but dnl (a) detecting malloc issues is notoriously unreliable dnl (b) only known system that declares argz functions, dnl provides them, yet they are broken, is cygwin dnl releases prior to 16-Mar-2007 (1.5.24 and earlier) dnl So, it's more straightforward simply to special case dnl this for known bad systems. AS_IF([test -z "$ARGZ_H"], [AC_CACHE_CHECK( [if argz actually works], [lt_cv_sys_argz_works], [[case $host_os in #( *cygwin*) lt_cv_sys_argz_works=no if test "$cross_compiling" != no; then lt_cv_sys_argz_works="guessing no" else lt_sed_extract_leading_digits='s/^\([0-9\.]*\).*/\1/' save_IFS=$IFS IFS=-. set x `uname -r | sed -e "$lt_sed_extract_leading_digits"` IFS=$save_IFS lt_os_major=${2-0} lt_os_minor=${3-0} lt_os_micro=${4-0} if test "$lt_os_major" -gt 1 \ || { test "$lt_os_major" -eq 1 \ && { test "$lt_os_minor" -gt 5 \ || { test "$lt_os_minor" -eq 5 \ && test "$lt_os_micro" -gt 24; }; }; }; then lt_cv_sys_argz_works=yes fi fi ;; #( *) lt_cv_sys_argz_works=yes ;; esac]]) AS_IF([test "$lt_cv_sys_argz_works" = yes], [AC_DEFINE([HAVE_WORKING_ARGZ], 1, [This value is set to 1 to indicate that the system argz facility works])], [ARGZ_H=argz.h AC_LIBOBJ([argz])])]) AC_SUBST([ARGZ_H]) ]) m4trace:/usr/share/aclocal/argz.m4:79: -1- AC_DEFUN([gl_PREREQ_ARGZ], [:]) m4trace:/usr/share/aclocal/libtool.m4:69: -1- 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]) ]) m4trace:/usr/share/aclocal/libtool.m4:107: -1- AU_DEFUN([AC_PROG_LIBTOOL], [m4_if($#, 0, [LT_INIT], [LT_INIT($@)])]) m4trace:/usr/share/aclocal/libtool.m4:107: -1- AC_DEFUN([AC_PROG_LIBTOOL], [AC_DIAGNOSE([obsolete], [The macro `AC_PROG_LIBTOOL' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_INIT], [LT_INIT($@)])]) m4trace:/usr/share/aclocal/libtool.m4:108: -1- AU_DEFUN([AM_PROG_LIBTOOL], [m4_if($#, 0, [LT_INIT], [LT_INIT($@)])]) m4trace:/usr/share/aclocal/libtool.m4:108: -1- AC_DEFUN([AM_PROG_LIBTOOL], [AC_DIAGNOSE([obsolete], [The macro `AM_PROG_LIBTOOL' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_INIT], [LT_INIT($@)])]) m4trace:/usr/share/aclocal/libtool.m4:609: -1- 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) ]) m4trace:/usr/share/aclocal/libtool.m4:790: -1- AC_DEFUN([LT_SUPPORTED_TAG], []) m4trace:/usr/share/aclocal/libtool.m4:801: -1- 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 ]) m4trace:/usr/share/aclocal/libtool.m4:893: -1- AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) m4trace:/usr/share/aclocal/libtool.m4:893: -1- AC_DEFUN([AC_LIBTOOL_CXX], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_CXX' is obsolete. You should run autoupdate.])dnl LT_LANG(C++)]) m4trace:/usr/share/aclocal/libtool.m4:894: -1- AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) m4trace:/usr/share/aclocal/libtool.m4:894: -1- AC_DEFUN([AC_LIBTOOL_F77], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_F77' is obsolete. You should run autoupdate.])dnl LT_LANG(Fortran 77)]) m4trace:/usr/share/aclocal/libtool.m4:895: -1- AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) m4trace:/usr/share/aclocal/libtool.m4:895: -1- AC_DEFUN([AC_LIBTOOL_FC], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_FC' is obsolete. You should run autoupdate.])dnl LT_LANG(Fortran)]) m4trace:/usr/share/aclocal/libtool.m4:896: -1- AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) m4trace:/usr/share/aclocal/libtool.m4:896: -1- AC_DEFUN([AC_LIBTOOL_GCJ], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_GCJ' is obsolete. You should run autoupdate.])dnl LT_LANG(Java)]) m4trace:/usr/share/aclocal/libtool.m4:897: -1- AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) m4trace:/usr/share/aclocal/libtool.m4:897: -1- AC_DEFUN([AC_LIBTOOL_RC], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_RC' is obsolete. You should run autoupdate.])dnl LT_LANG(Windows Resource)]) m4trace:/usr/share/aclocal/libtool.m4:1225: -1- 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.])]) m4trace:/usr/share/aclocal/libtool.m4:1502: -1- 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 ]) m4trace:/usr/share/aclocal/libtool.m4:1544: -1- AU_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [m4_if($#, 0, [_LT_COMPILER_OPTION], [_LT_COMPILER_OPTION($@)])]) m4trace:/usr/share/aclocal/libtool.m4:1544: -1- AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_COMPILER_OPTION' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [_LT_COMPILER_OPTION], [_LT_COMPILER_OPTION($@)])]) m4trace:/usr/share/aclocal/libtool.m4:1553: -1- 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 ]) m4trace:/usr/share/aclocal/libtool.m4:1588: -1- AU_DEFUN([AC_LIBTOOL_LINKER_OPTION], [m4_if($#, 0, [_LT_LINKER_OPTION], [_LT_LINKER_OPTION($@)])]) m4trace:/usr/share/aclocal/libtool.m4:1588: -1- AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_LINKER_OPTION' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [_LT_LINKER_OPTION], [_LT_LINKER_OPTION($@)])]) m4trace:/usr/share/aclocal/libtool.m4:1595: -1- 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?]) ]) m4trace:/usr/share/aclocal/libtool.m4:1733: -1- AU_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [m4_if($#, 0, [LT_CMD_MAX_LEN], [LT_CMD_MAX_LEN($@)])]) m4trace:/usr/share/aclocal/libtool.m4:1733: -1- AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_SYS_MAX_CMD_LEN' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_CMD_MAX_LEN], [LT_CMD_MAX_LEN($@)])]) m4trace:/usr/share/aclocal/libtool.m4:1844: -1- 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]) ]) m4trace:/usr/share/aclocal/libtool.m4:1961: -1- AU_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [m4_if($#, 0, [LT_SYS_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF($@)])]) m4trace:/usr/share/aclocal/libtool.m4:1961: -1- AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_DLOPEN_SELF' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_SYS_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF($@)])]) m4trace:/usr/share/aclocal/libtool.m4:2934: -1- 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 ]) m4trace:/usr/share/aclocal/libtool.m4:2996: -1- AU_DEFUN([AC_PATH_TOOL_PREFIX], [m4_if($#, 0, [_LT_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX($@)])]) m4trace:/usr/share/aclocal/libtool.m4:2996: -1- AC_DEFUN([AC_PATH_TOOL_PREFIX], [AC_DIAGNOSE([obsolete], [The macro `AC_PATH_TOOL_PREFIX' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [_LT_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX($@)])]) m4trace:/usr/share/aclocal/libtool.m4:3019: -1- 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 | 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*]) ]) m4trace:/usr/share/aclocal/libtool.m4:3493: -1- AU_DEFUN([AM_PROG_NM], [m4_if($#, 0, [LT_PATH_NM], [LT_PATH_NM($@)])]) m4trace:/usr/share/aclocal/libtool.m4:3493: -1- AC_DEFUN([AM_PROG_NM], [AC_DIAGNOSE([obsolete], [The macro `AM_PROG_NM' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_PATH_NM], [LT_PATH_NM($@)])]) m4trace:/usr/share/aclocal/libtool.m4:3494: -1- AU_DEFUN([AC_PROG_NM], [m4_if($#, 0, [LT_PATH_NM], [LT_PATH_NM($@)])]) m4trace:/usr/share/aclocal/libtool.m4:3494: -1- AC_DEFUN([AC_PROG_NM], [AC_DIAGNOSE([obsolete], [The macro `AC_PROG_NM' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_PATH_NM], [LT_PATH_NM($@)])]) m4trace:/usr/share/aclocal/libtool.m4:3564: -1- 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]) ]) m4trace:/usr/share/aclocal/libtool.m4:3583: -1- AU_DEFUN([AC_CHECK_LIBM], [m4_if($#, 0, [LT_LIB_M], [LT_LIB_M($@)])]) m4trace:/usr/share/aclocal/libtool.m4:3583: -1- AC_DEFUN([AC_CHECK_LIBM], [AC_DIAGNOSE([obsolete], [The macro `AC_CHECK_LIBM' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_LIB_M], [LT_LIB_M($@)])]) m4trace:/usr/share/aclocal/libtool.m4:7626: -1- 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 ]) m4trace:/usr/share/aclocal/libtool.m4:7635: -1- AU_DEFUN([LT_AC_PROG_GCJ], [m4_if($#, 0, [LT_PROG_GCJ], [LT_PROG_GCJ($@)])]) m4trace:/usr/share/aclocal/libtool.m4:7635: -1- AC_DEFUN([LT_AC_PROG_GCJ], [AC_DIAGNOSE([obsolete], [The macro `LT_AC_PROG_GCJ' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_PROG_GCJ], [LT_PROG_GCJ($@)])]) m4trace:/usr/share/aclocal/libtool.m4:7642: -1- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) m4trace:/usr/share/aclocal/libtool.m4:7649: -1- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) m4trace:/usr/share/aclocal/libtool.m4:7654: -1- AU_DEFUN([LT_AC_PROG_RC], [m4_if($#, 0, [LT_PROG_RC], [LT_PROG_RC($@)])]) m4trace:/usr/share/aclocal/libtool.m4:7654: -1- AC_DEFUN([LT_AC_PROG_RC], [AC_DIAGNOSE([obsolete], [The macro `LT_AC_PROG_RC' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_PROG_RC], [LT_PROG_RC($@)])]) m4trace:/usr/share/aclocal/libtool.m4:7774: -1- AU_DEFUN([LT_AC_PROG_SED], [m4_if($#, 0, [AC_PROG_SED], [AC_PROG_SED($@)])]) m4trace:/usr/share/aclocal/libtool.m4:7774: -1- AC_DEFUN([LT_AC_PROG_SED], [AC_DIAGNOSE([obsolete], [The macro `LT_AC_PROG_SED' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [AC_PROG_SED], [AC_PROG_SED($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:16: -1- AC_DEFUN([LT_CONFIG_LTDL_DIR], [AC_BEFORE([$0], [LTDL_INIT]) _$0($*) ]) m4trace:/usr/share/aclocal/ltdl.m4:68: -1- 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() ]) m4trace:/usr/share/aclocal/ltdl.m4:81: -1- AU_DEFUN([AC_LIBLTDL_CONVENIENCE], [_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) _LTDL_CONVENIENCE]) m4trace:/usr/share/aclocal/ltdl.m4:81: -1- AC_DEFUN([AC_LIBLTDL_CONVENIENCE], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBLTDL_CONVENIENCE' is obsolete. You should run autoupdate.])dnl _LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) _LTDL_CONVENIENCE]) m4trace:/usr/share/aclocal/ltdl.m4:124: -1- 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() ]) m4trace:/usr/share/aclocal/ltdl.m4:137: -1- AU_DEFUN([AC_LIBLTDL_INSTALLABLE], [_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) _LTDL_INSTALLABLE]) m4trace:/usr/share/aclocal/ltdl.m4:137: -1- AC_DEFUN([AC_LIBLTDL_INSTALLABLE], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBLTDL_INSTALLABLE' is obsolete. You should run autoupdate.])dnl _LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) _LTDL_INSTALLABLE]) m4trace:/usr/share/aclocal/ltdl.m4:213: -1- AC_DEFUN([_LT_LIBOBJ], [ m4_pattern_allow([^_LT_LIBOBJS$]) _LT_LIBOBJS="$_LT_LIBOBJS $1.$ac_objext" ]) m4trace:/usr/share/aclocal/ltdl.m4:226: -1- 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]) ]) m4trace:/usr/share/aclocal/ltdl.m4:352: -1- AU_DEFUN([AC_LIB_LTDL], [LTDL_INIT($@)]) m4trace:/usr/share/aclocal/ltdl.m4:352: -1- AC_DEFUN([AC_LIB_LTDL], [AC_DIAGNOSE([obsolete], [The macro `AC_LIB_LTDL' is obsolete. You should run autoupdate.])dnl LTDL_INIT($@)]) m4trace:/usr/share/aclocal/ltdl.m4:353: -1- AU_DEFUN([AC_WITH_LTDL], [LTDL_INIT($@)]) m4trace:/usr/share/aclocal/ltdl.m4:353: -1- AC_DEFUN([AC_WITH_LTDL], [AC_DIAGNOSE([obsolete], [The macro `AC_WITH_LTDL' is obsolete. You should run autoupdate.])dnl LTDL_INIT($@)]) m4trace:/usr/share/aclocal/ltdl.m4:354: -1- AU_DEFUN([LT_WITH_LTDL], [LTDL_INIT($@)]) m4trace:/usr/share/aclocal/ltdl.m4:354: -1- AC_DEFUN([LT_WITH_LTDL], [AC_DIAGNOSE([obsolete], [The macro `LT_WITH_LTDL' is obsolete. You should run autoupdate.])dnl LTDL_INIT($@)]) m4trace:/usr/share/aclocal/ltdl.m4:367: -1- 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]) ]) m4trace:/usr/share/aclocal/ltdl.m4:443: -1- 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 ]) m4trace:/usr/share/aclocal/ltdl.m4:542: -1- AU_DEFUN([AC_LTDL_SYS_DLOPEN_DEPLIBS], [m4_if($#, 0, [LT_SYS_DLOPEN_DEPLIBS], [LT_SYS_DLOPEN_DEPLIBS($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:542: -1- AC_DEFUN([AC_LTDL_SYS_DLOPEN_DEPLIBS], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_SYS_DLOPEN_DEPLIBS' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_SYS_DLOPEN_DEPLIBS], [LT_SYS_DLOPEN_DEPLIBS($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:549: -1- 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 ]) m4trace:/usr/share/aclocal/ltdl.m4:572: -1- AU_DEFUN([AC_LTDL_SHLIBEXT], [m4_if($#, 0, [LT_SYS_MODULE_EXT], [LT_SYS_MODULE_EXT($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:572: -1- AC_DEFUN([AC_LTDL_SHLIBEXT], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_SHLIBEXT' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_SYS_MODULE_EXT], [LT_SYS_MODULE_EXT($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:579: -1- 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 ]) m4trace:/usr/share/aclocal/ltdl.m4:591: -1- AU_DEFUN([AC_LTDL_SHLIBPATH], [m4_if($#, 0, [LT_SYS_MODULE_PATH], [LT_SYS_MODULE_PATH($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:591: -1- AC_DEFUN([AC_LTDL_SHLIBPATH], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_SHLIBPATH' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_SYS_MODULE_PATH], [LT_SYS_MODULE_PATH($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:598: -1- 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 ]) m4trace:/usr/share/aclocal/ltdl.m4:619: -1- AU_DEFUN([AC_LTDL_SYSSEARCHPATH], [m4_if($#, 0, [LT_SYS_DLSEARCH_PATH], [LT_SYS_DLSEARCH_PATH($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:619: -1- AC_DEFUN([AC_LTDL_SYSSEARCHPATH], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_SYSSEARCHPATH' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_SYS_DLSEARCH_PATH], [LT_SYS_DLSEARCH_PATH($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:645: -1- 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 ]) m4trace:/usr/share/aclocal/ltdl.m4:738: -1- AU_DEFUN([AC_LTDL_DLLIB], [m4_if($#, 0, [LT_LIB_DLLOAD], [LT_LIB_DLLOAD($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:738: -1- AC_DEFUN([AC_LTDL_DLLIB], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_DLLIB' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_LIB_DLLOAD], [LT_LIB_DLLOAD($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:746: -1- 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]) ]) m4trace:/usr/share/aclocal/ltdl.m4:783: -1- AU_DEFUN([AC_LTDL_SYMBOL_USCORE], [m4_if($#, 0, [LT_SYS_SYMBOL_USCORE], [LT_SYS_SYMBOL_USCORE($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:783: -1- AC_DEFUN([AC_LTDL_SYMBOL_USCORE], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_SYMBOL_USCORE' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_SYS_SYMBOL_USCORE], [LT_SYS_SYMBOL_USCORE($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:790: -1- 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 ]) m4trace:/usr/share/aclocal/ltdl.m4:815: -1- AU_DEFUN([AC_LTDL_DLSYM_USCORE], [m4_if($#, 0, [LT_FUNC_DLSYM_USCORE], [LT_FUNC_DLSYM_USCORE($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:815: -1- AC_DEFUN([AC_LTDL_DLSYM_USCORE], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_DLSYM_USCORE' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_FUNC_DLSYM_USCORE], [LT_FUNC_DLSYM_USCORE($@)])]) m4trace:/usr/share/aclocal/ltoptions.m4:14: -1- AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) m4trace:/usr/share/aclocal/ltoptions.m4:111: -1- 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.]) ]) m4trace:/usr/share/aclocal/ltoptions.m4:111: -1- AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_DLOPEN' is obsolete. You should run autoupdate.])dnl _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.]) ]) m4trace:/usr/share/aclocal/ltoptions.m4:146: -1- 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.]) ]) m4trace:/usr/share/aclocal/ltoptions.m4:146: -1- AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_WIN32_DLL' is obsolete. You should run autoupdate.])dnl 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.]) ]) m4trace:/usr/share/aclocal/ltoptions.m4:195: -1- AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) m4trace:/usr/share/aclocal/ltoptions.m4:199: -1- AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) m4trace:/usr/share/aclocal/ltoptions.m4:203: -1- AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) m4trace:/usr/share/aclocal/ltoptions.m4:203: -1- AC_DEFUN([AM_ENABLE_SHARED], [AC_DIAGNOSE([obsolete], [The macro `AM_ENABLE_SHARED' is obsolete. You should run autoupdate.])dnl AC_ENABLE_SHARED($@)]) m4trace:/usr/share/aclocal/ltoptions.m4:204: -1- AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) m4trace:/usr/share/aclocal/ltoptions.m4:204: -1- AC_DEFUN([AM_DISABLE_SHARED], [AC_DIAGNOSE([obsolete], [The macro `AM_DISABLE_SHARED' is obsolete. You should run autoupdate.])dnl AC_DISABLE_SHARED($@)]) m4trace:/usr/share/aclocal/ltoptions.m4:249: -1- AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) m4trace:/usr/share/aclocal/ltoptions.m4:253: -1- AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) m4trace:/usr/share/aclocal/ltoptions.m4:257: -1- AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) m4trace:/usr/share/aclocal/ltoptions.m4:257: -1- AC_DEFUN([AM_ENABLE_STATIC], [AC_DIAGNOSE([obsolete], [The macro `AM_ENABLE_STATIC' is obsolete. You should run autoupdate.])dnl AC_ENABLE_STATIC($@)]) m4trace:/usr/share/aclocal/ltoptions.m4:258: -1- AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) m4trace:/usr/share/aclocal/ltoptions.m4:258: -1- AC_DEFUN([AM_DISABLE_STATIC], [AC_DIAGNOSE([obsolete], [The macro `AM_DISABLE_STATIC' is obsolete. You should run autoupdate.])dnl AC_DISABLE_STATIC($@)]) m4trace:/usr/share/aclocal/ltoptions.m4:303: -1- 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.]) ]) m4trace:/usr/share/aclocal/ltoptions.m4:303: -1- AC_DEFUN([AC_ENABLE_FAST_INSTALL], [AC_DIAGNOSE([obsolete], [The macro `AC_ENABLE_FAST_INSTALL' is obsolete. You should run autoupdate.])dnl _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.]) ]) m4trace:/usr/share/aclocal/ltoptions.m4:310: -1- 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.]) ]) m4trace:/usr/share/aclocal/ltoptions.m4:310: -1- AC_DEFUN([AC_DISABLE_FAST_INSTALL], [AC_DIAGNOSE([obsolete], [The macro `AC_DISABLE_FAST_INSTALL' is obsolete. You should run autoupdate.])dnl _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.]) ]) m4trace:/usr/share/aclocal/ltoptions.m4:358: -1- 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.]) ]) m4trace:/usr/share/aclocal/ltoptions.m4:358: -1- AC_DEFUN([AC_LIBTOOL_PICMODE], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_PICMODE' is obsolete. You should run autoupdate.])dnl _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.]) ]) m4trace:/usr/share/aclocal/ltsugar.m4:13: -1- AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) m4trace:/usr/share/aclocal/ltversion.m4:18: -1- 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) ]) m4trace:/usr/share/aclocal/lt~obsolete.m4:36: -1- AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4trace:/usr/share/aclocal/lt~obsolete.m4:40: -1- AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH]) m4trace:/usr/share/aclocal/lt~obsolete.m4:41: -1- AC_DEFUN([_LT_AC_SHELL_INIT]) m4trace:/usr/share/aclocal/lt~obsolete.m4:42: -1- AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX]) m4trace:/usr/share/aclocal/lt~obsolete.m4:44: -1- AC_DEFUN([_LT_AC_TAGVAR]) m4trace:/usr/share/aclocal/lt~obsolete.m4:45: -1- AC_DEFUN([AC_LTDL_ENABLE_INSTALL]) m4trace:/usr/share/aclocal/lt~obsolete.m4:46: -1- AC_DEFUN([AC_LTDL_PREOPEN]) m4trace:/usr/share/aclocal/lt~obsolete.m4:47: -1- AC_DEFUN([_LT_AC_SYS_COMPILER]) m4trace:/usr/share/aclocal/lt~obsolete.m4:48: -1- AC_DEFUN([_LT_AC_LOCK]) m4trace:/usr/share/aclocal/lt~obsolete.m4:49: -1- AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE]) m4trace:/usr/share/aclocal/lt~obsolete.m4:50: -1- AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF]) m4trace:/usr/share/aclocal/lt~obsolete.m4:51: -1- AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O]) m4trace:/usr/share/aclocal/lt~obsolete.m4:52: -1- AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS]) m4trace:/usr/share/aclocal/lt~obsolete.m4:53: -1- AC_DEFUN([AC_LIBTOOL_OBJDIR]) m4trace:/usr/share/aclocal/lt~obsolete.m4:54: -1- AC_DEFUN([AC_LTDL_OBJDIR]) m4trace:/usr/share/aclocal/lt~obsolete.m4:55: -1- AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH]) m4trace:/usr/share/aclocal/lt~obsolete.m4:56: -1- AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP]) m4trace:/usr/share/aclocal/lt~obsolete.m4:57: -1- AC_DEFUN([AC_PATH_MAGIC]) m4trace:/usr/share/aclocal/lt~obsolete.m4:58: -1- AC_DEFUN([AC_PROG_LD_GNU]) m4trace:/usr/share/aclocal/lt~obsolete.m4:59: -1- AC_DEFUN([AC_PROG_LD_RELOAD_FLAG]) m4trace:/usr/share/aclocal/lt~obsolete.m4:60: -1- AC_DEFUN([AC_DEPLIBS_CHECK_METHOD]) m4trace:/usr/share/aclocal/lt~obsolete.m4:61: -1- AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI]) m4trace:/usr/share/aclocal/lt~obsolete.m4:62: -1- AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE]) m4trace:/usr/share/aclocal/lt~obsolete.m4:63: -1- AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC]) m4trace:/usr/share/aclocal/lt~obsolete.m4:64: -1- AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS]) m4trace:/usr/share/aclocal/lt~obsolete.m4:65: -1- AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP]) m4trace:/usr/share/aclocal/lt~obsolete.m4:66: -1- AC_DEFUN([LT_AC_PROG_EGREP]) m4trace:/usr/share/aclocal/lt~obsolete.m4:71: -1- AC_DEFUN([_AC_PROG_LIBTOOL]) m4trace:/usr/share/aclocal/lt~obsolete.m4:72: -1- AC_DEFUN([AC_LIBTOOL_SETUP]) m4trace:/usr/share/aclocal/lt~obsolete.m4:73: -1- AC_DEFUN([_LT_AC_CHECK_DLFCN]) m4trace:/usr/share/aclocal/lt~obsolete.m4:74: -1- AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER]) m4trace:/usr/share/aclocal/lt~obsolete.m4:75: -1- AC_DEFUN([_LT_AC_TAGCONFIG]) m4trace:/usr/share/aclocal/lt~obsolete.m4:77: -1- AC_DEFUN([_LT_AC_LANG_CXX]) m4trace:/usr/share/aclocal/lt~obsolete.m4:78: -1- AC_DEFUN([_LT_AC_LANG_F77]) m4trace:/usr/share/aclocal/lt~obsolete.m4:79: -1- AC_DEFUN([_LT_AC_LANG_GCJ]) m4trace:/usr/share/aclocal/lt~obsolete.m4:80: -1- AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG]) m4trace:/usr/share/aclocal/lt~obsolete.m4:81: -1- AC_DEFUN([_LT_AC_LANG_C_CONFIG]) m4trace:/usr/share/aclocal/lt~obsolete.m4:82: -1- AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG]) m4trace:/usr/share/aclocal/lt~obsolete.m4:83: -1- AC_DEFUN([_LT_AC_LANG_CXX_CONFIG]) m4trace:/usr/share/aclocal/lt~obsolete.m4:84: -1- AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG]) m4trace:/usr/share/aclocal/lt~obsolete.m4:85: -1- AC_DEFUN([_LT_AC_LANG_F77_CONFIG]) m4trace:/usr/share/aclocal/lt~obsolete.m4:86: -1- AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG]) m4trace:/usr/share/aclocal/lt~obsolete.m4:87: -1- AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG]) m4trace:/usr/share/aclocal/lt~obsolete.m4:88: -1- AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG]) m4trace:/usr/share/aclocal/lt~obsolete.m4:89: -1- AC_DEFUN([_LT_AC_LANG_RC_CONFIG]) m4trace:/usr/share/aclocal/lt~obsolete.m4:90: -1- AC_DEFUN([AC_LIBTOOL_CONFIG]) m4trace:/usr/share/aclocal/lt~obsolete.m4:91: -1- AC_DEFUN([_LT_AC_FILE_LTDLL_C]) m4trace:/usr/share/aclocal/lt~obsolete.m4:93: -1- AC_DEFUN([_LT_AC_PROG_CXXCPP]) m4trace:/usr/share/aclocal/lt~obsolete.m4:96: -1- AC_DEFUN([_LT_PROG_F77]) m4trace:/usr/share/aclocal/lt~obsolete.m4:97: -1- AC_DEFUN([_LT_PROG_FC]) m4trace:/usr/share/aclocal/lt~obsolete.m4:98: -1- AC_DEFUN([_LT_PROG_CXX]) m4trace:/usr/share/aclocal-1.12/amversion.m4:16: -1- AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.12' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.12.2], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) m4trace:/usr/share/aclocal-1.12/amversion.m4:35: -1- AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.12.2])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) m4trace:/usr/share/aclocal-1.12/auxdir.m4:49: -1- AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) m4trace:/usr/share/aclocal-1.12/cond.m4:14: -1- AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) m4trace:/usr/share/aclocal-1.12/depend.m4:27: -1- AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) m4trace:/usr/share/aclocal-1.12/depend.m4:164: -1- AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) m4trace:/usr/share/aclocal-1.12/depend.m4:172: -1- AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) m4trace:/usr/share/aclocal-1.12/depout.m4:13: -1- AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ]) m4trace:/usr/share/aclocal-1.12/depout.m4:72: -1- AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) m4trace:/usr/share/aclocal-1.12/init.m4:25: -1- AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.62])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated. For more info, see: http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_INIT_AUTOMAKE-invocation]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl dnl Support for Objective C++ was only introduced in Autoconf 2.65, dnl but we still cater to Autoconf 2.62. m4_ifdef([AC_PROG_OBJCXX], [AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])])dnl ]) _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl dnl The 'parallel-tests' driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) m4trace:/usr/share/aclocal-1.12/init.m4:142: -1- AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) m4trace:/usr/share/aclocal-1.12/install-sh.m4:13: -1- AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) m4trace:/usr/share/aclocal-1.12/lead-dot.m4:12: -1- AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) m4trace:/usr/share/aclocal-1.12/make.m4:14: -1- AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) m4trace:/usr/share/aclocal-1.12/minuso.m4:13: -1- AC_DEFUN([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC_C_O])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl # FIXME: we rely on the cache variable name because # there is no other way. set dummy $CC am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o if test "$am_t" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi dnl Make sure AC_PROG_CC is never called again, or it will override our dnl setting of CC. m4_define([AC_PROG_CC], [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) ]) m4trace:/usr/share/aclocal-1.12/missing.m4:13: -1- AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) m4trace:/usr/share/aclocal-1.12/missing.m4:23: -1- AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) m4trace:/usr/share/aclocal-1.12/options.m4:13: -1- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) m4trace:/usr/share/aclocal-1.12/options.m4:19: -1- AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) m4trace:/usr/share/aclocal-1.12/options.m4:25: -1- AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) m4trace:/usr/share/aclocal-1.12/options.m4:31: -1- AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) m4trace:/usr/share/aclocal-1.12/runlog.m4:14: -1- AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) m4trace:/usr/share/aclocal-1.12/sanity.m4:13: -1- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) m4trace:/usr/share/aclocal-1.12/silent.m4:14: -1- AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) m4trace:/usr/share/aclocal-1.12/strip.m4:19: -1- AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) m4trace:/usr/share/aclocal-1.12/substnot.m4:14: -1- AC_DEFUN([_AM_SUBST_NOTMAKE]) m4trace:/usr/share/aclocal-1.12/substnot.m4:19: -1- AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) m4trace:/usr/share/aclocal-1.12/tar.m4:24: -1- AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of '-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) m4trace:m4/vmtools.m4:53: -1- AC_DEFUN([AC_VMW_CHECK_LIB], [ AC_REQUIRE([AC_CHECK_LIB]) dnl AC_REQUIRE([AC_CHECK_HEADER]) dnl if test -z "$1"; then AC_MSG_ERROR(['library' parameter is required.']) fi if test -z "$2"; then AC_MSG_ERROR(['lvar' parameter is required.']) fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_$2_CPPFLAGS}" || test -n "${CUSTOM_$2_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_$2_LIBS} -l$1" if test -n "$6"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_$2_CPPFLAGS} $CPPFLAGS" AC_CHECK_HEADER([$6], [ac_vmw_have_lib_header=1]) CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "$7"; then ac_vmw_function=$7 else ac_vmw_function=strlen fi AC_CHECK_LIB( [$1], [$ac_vmw_function], [ac_vmw_have_lib_func=1], [], [$ac_vmw_custom_libs]) fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then $2_CPPFLAGS="${CUSTOM_$2_CPPFLAGS}" $2_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "$3"; then if test -n "$5"; then AC_MSG_CHECKING([for $3 >= $5 (via pkg-config)]) if pkg-config --exists '$3 >= $5'; then ac_vmw_have_lib=1 fi else AC_MSG_CHECKING([for $3 (via pkg-config)]) if pkg-config --exists '$3'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags $3`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs $3`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then AC_MSG_RESULT([yes]) $2_CPPFLAGS="$ac_vmw_cppflags" $2_LIBS="$ac_vmw_libs" else AC_MSG_RESULT([no]) fi else AC_MSG_RESULT([no]) fi fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n "$4"; then AC_PATH_PROG([ac_vmw_lib_cfg], [$4], [no]) if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then $2_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" $2_LIBS="`$ac_vmw_lib_cfg --ldflags`" else $2_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" $2_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then AC_SUBST([$2_CPPFLAGS]) AC_SUBST([$2_LIBS]) true $8 else true $9 fi ]) m4trace:m4/vmtools.m4:205: -1- AC_DEFUN([AC_VMW_CHECK_LIBXX], [ AC_REQUIRE([AC_VMW_CHECK_LIB]) AC_LANG_PUSH([C++]) AC_VMW_CHECK_LIB([$1], [$2], [$3], [$4], [$5], [$6], [$7], [$8], [$9]) AC_LANG_POP([C++]) ]) m4trace:m4/vmtools.m4:227: -1- AC_DEFUN([AC_VMW_CHECK_X11_LIB], [ have_header=1 if test -n "$2"; then AC_CHECK_HEADER( [X11/extensions/scrnsaver.h], [], [ have_header=0; $4 ], []) fi if test $have_header = 1; then AC_CHECK_LIB( [$1], [$3], [COMMON_XLIBS="-l$1 $COMMON_XLIBS"], [$4], [$COMMON_XLIBS]) fi ]) m4trace:m4/vmtools.m4:260: -1- AC_DEFUN([AC_VMW_LIB_ERROR], [ feature="$3" if test -z "$feature"; then feature="$1" fi AC_MSG_ERROR([Cannot find $1 library. Please configure without $feature (using --without-$2), or install the $1 libraries and devel package(s).]) ]) m4trace:m4/vmtools.m4:279: -1- AC_DEFUN([AC_VMW_DEFAULT_FLAGS], [ if test -z "$CUSTOM_$1_CPPFLAGS"; then if test "$os" = freebsd; then CUSTOM_$1_CPPFLAGS="-I/usr/local/include" else CUSTOM_$1_CPPFLAGS="-I/usr/include" fi if test -n "$2"; then CUSTOM_$1_CPPFLAGS="${CUSTOM_$1_CPPFLAGS}/$2" fi fi ]) m4trace:configure.ac:43: -1- m4_pattern_forbid([^_?A[CHUM]_]) m4trace:configure.ac:43: -1- m4_pattern_forbid([_AC_]) m4trace:configure.ac:43: -1- m4_pattern_forbid([^LIBOBJS$], [do not use LIBOBJS directly, use AC_LIBOBJ (see section `AC_LIBOBJ vs LIBOBJS']) m4trace:configure.ac:43: -1- m4_pattern_allow([^AS_FLAGS$]) m4trace:configure.ac:43: -1- m4_pattern_forbid([^_?m4_]) m4trace:configure.ac:43: -1- m4_pattern_forbid([^dnl$]) m4trace:configure.ac:43: -1- m4_pattern_forbid([^_?AS_]) m4trace:configure.ac:43: -1- m4_pattern_allow([^SHELL$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PATH_SEPARATOR$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_NAME$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_TARNAME$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_VERSION$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_STRING$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_URL$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^exec_prefix$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^prefix$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^program_transform_name$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^bindir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^sbindir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^libexecdir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^datarootdir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^datadir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^sysconfdir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^sharedstatedir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^localstatedir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^includedir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^oldincludedir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^docdir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^infodir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^htmldir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^dvidir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^pdfdir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^psdir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^libdir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^localedir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^mandir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_NAME$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_TARNAME$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_VERSION$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_STRING$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_URL$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^DEFS$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^ECHO_C$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^ECHO_N$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^ECHO_T$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^LIBS$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^build_alias$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^host_alias$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^target_alias$]) m4trace:configure.ac:74: -1- m4_pattern_allow([^build$]) m4trace:configure.ac:74: -1- m4_pattern_allow([^build_cpu$]) m4trace:configure.ac:74: -1- m4_pattern_allow([^build_vendor$]) m4trace:configure.ac:74: -1- m4_pattern_allow([^build_os$]) m4trace:configure.ac:74: -1- m4_pattern_allow([^host$]) m4trace:configure.ac:74: -1- m4_pattern_allow([^host_cpu$]) m4trace:configure.ac:74: -1- m4_pattern_allow([^host_vendor$]) m4trace:configure.ac:74: -1- m4_pattern_allow([^host_os$]) m4trace:configure.ac:210: -1- AM_INIT_AUTOMAKE m4trace:configure.ac:210: -1- m4_pattern_allow([^AM_[A-Z]+FLAGS$]) m4trace:configure.ac:210: -1- AM_SET_CURRENT_AUTOMAKE_VERSION m4trace:configure.ac:210: -1- AM_AUTOMAKE_VERSION([1.12.2]) m4trace:configure.ac:210: -1- _AM_AUTOCONF_VERSION([2.69]) m4trace:configure.ac:210: -1- m4_pattern_allow([^INSTALL_PROGRAM$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^INSTALL_SCRIPT$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^INSTALL_DATA$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^am__isrc$]) m4trace:configure.ac:210: -1- _AM_SUBST_NOTMAKE([am__isrc]) m4trace:configure.ac:210: -1- m4_pattern_allow([^CYGPATH_W$]) m4trace:configure.ac:210: -1- _AM_SET_OPTIONS([]) m4trace:configure.ac:210: -1- m4_pattern_allow([^PACKAGE$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^VERSION$]) m4trace:configure.ac:210: -1- _AM_IF_OPTION([no-define], [], [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])]) m4trace:configure.ac:210: -2- _AM_MANGLE_OPTION([no-define]) m4trace:configure.ac:210: -1- m4_pattern_allow([^PACKAGE$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^VERSION$]) m4trace:configure.ac:210: -1- AM_SANITY_CHECK m4trace:configure.ac:210: -1- AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) m4trace:configure.ac:210: -1- AM_MISSING_HAS_RUN m4trace:configure.ac:210: -1- AM_AUX_DIR_EXPAND m4trace:configure.ac:210: -1- m4_pattern_allow([^ACLOCAL$]) m4trace:configure.ac:210: -1- AM_MISSING_PROG([AUTOCONF], [autoconf]) m4trace:configure.ac:210: -1- m4_pattern_allow([^AUTOCONF$]) m4trace:configure.ac:210: -1- AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) m4trace:configure.ac:210: -1- m4_pattern_allow([^AUTOMAKE$]) m4trace:configure.ac:210: -1- AM_MISSING_PROG([AUTOHEADER], [autoheader]) m4trace:configure.ac:210: -1- m4_pattern_allow([^AUTOHEADER$]) m4trace:configure.ac:210: -1- AM_MISSING_PROG([MAKEINFO], [makeinfo]) m4trace:configure.ac:210: -1- m4_pattern_allow([^MAKEINFO$]) m4trace:configure.ac:210: -1- AM_PROG_INSTALL_SH m4trace:configure.ac:210: -1- m4_pattern_allow([^install_sh$]) m4trace:configure.ac:210: -1- AM_PROG_INSTALL_STRIP m4trace:configure.ac:210: -1- m4_pattern_allow([^STRIP$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^INSTALL_STRIP_PROGRAM$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^MKDIR_P$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^mkdir_p$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^AWK$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^SET_MAKE$]) m4trace:configure.ac:210: -1- AM_SET_LEADING_DOT m4trace:configure.ac:210: -1- m4_pattern_allow([^am__leading_dot$]) m4trace:configure.ac:210: -1- _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) m4trace:configure.ac:210: -2- _AM_MANGLE_OPTION([tar-ustar]) m4trace:configure.ac:210: -1- _AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])]) m4trace:configure.ac:210: -2- _AM_MANGLE_OPTION([tar-pax]) m4trace:configure.ac:210: -1- _AM_PROG_TAR([v7]) m4trace:configure.ac:210: -1- m4_pattern_allow([^AMTAR$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^am__tar$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^am__untar$]) m4trace:configure.ac:210: -1- _AM_IF_OPTION([no-dependencies], [], [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl dnl Support for Objective C++ was only introduced in Autoconf 2.65, dnl but we still cater to Autoconf 2.62. m4_ifdef([AC_PROG_OBJCXX], [AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])])dnl ]) m4trace:configure.ac:210: -2- _AM_MANGLE_OPTION([no-dependencies]) m4trace:configure.ac:210: -1- _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])]) m4trace:configure.ac:210: -2- _AM_MANGLE_OPTION([silent-rules]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CFLAGS$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^LDFLAGS$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^LIBS$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^ac_ct_CC$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^EXEEXT$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^OBJEXT$]) m4trace:configure.ac:233: -1- _AM_DEPENDENCIES([CC]) m4trace:configure.ac:233: -1- AM_SET_DEPDIR m4trace:configure.ac:233: -1- m4_pattern_allow([^DEPDIR$]) m4trace:configure.ac:233: -1- AM_OUTPUT_DEPENDENCY_COMMANDS m4trace:configure.ac:233: -1- AM_MAKE_INCLUDE m4trace:configure.ac:233: -1- m4_pattern_allow([^am__include$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^am__quote$]) m4trace:configure.ac:233: -1- AM_DEP_TRACK m4trace:configure.ac:233: -1- AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) m4trace:configure.ac:233: -1- m4_pattern_allow([^AMDEP_TRUE$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^AMDEP_FALSE$]) m4trace:configure.ac:233: -1- _AM_SUBST_NOTMAKE([AMDEP_TRUE]) m4trace:configure.ac:233: -1- _AM_SUBST_NOTMAKE([AMDEP_FALSE]) m4trace:configure.ac:233: -1- m4_pattern_allow([^AMDEPBACKSLASH$]) m4trace:configure.ac:233: -1- _AM_SUBST_NOTMAKE([AMDEPBACKSLASH]) m4trace:configure.ac:233: -1- m4_pattern_allow([^am__nodep$]) m4trace:configure.ac:233: -1- _AM_SUBST_NOTMAKE([am__nodep]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CCDEPMODE$]) m4trace:configure.ac:233: -1- AM_CONDITIONAL([am__fastdepCC], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3]) m4trace:configure.ac:233: -1- m4_pattern_allow([^am__fastdepCC_TRUE$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^am__fastdepCC_FALSE$]) m4trace:configure.ac:233: -1- _AM_SUBST_NOTMAKE([am__fastdepCC_TRUE]) m4trace:configure.ac:233: -1- _AM_SUBST_NOTMAKE([am__fastdepCC_FALSE]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CPP$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CPP$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CFLAGS$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^LDFLAGS$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^LIBS$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^ac_ct_CC$]) m4trace:configure.ac:234: -1- _AM_DEPENDENCIES([CC]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CCDEPMODE$]) m4trace:configure.ac:234: -1- AM_CONDITIONAL([am__fastdepCC], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3]) m4trace:configure.ac:234: -1- m4_pattern_allow([^am__fastdepCC_TRUE$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^am__fastdepCC_FALSE$]) m4trace:configure.ac:234: -1- _AM_SUBST_NOTMAKE([am__fastdepCC_TRUE]) m4trace:configure.ac:234: -1- _AM_SUBST_NOTMAKE([am__fastdepCC_FALSE]) m4trace:configure.ac:238: -1- m4_pattern_allow([^CXX$]) m4trace:configure.ac:238: -1- m4_pattern_allow([^CXXFLAGS$]) m4trace:configure.ac:238: -1- m4_pattern_allow([^LDFLAGS$]) m4trace:configure.ac:238: -1- m4_pattern_allow([^LIBS$]) m4trace:configure.ac:238: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:238: -1- m4_pattern_allow([^CXX$]) m4trace:configure.ac:238: -1- m4_pattern_allow([^ac_ct_CXX$]) m4trace:configure.ac:238: -1- _AM_DEPENDENCIES([CXX]) m4trace:configure.ac:238: -1- m4_pattern_allow([^CXXDEPMODE$]) m4trace:configure.ac:238: -1- AM_CONDITIONAL([am__fastdepCXX], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3]) m4trace:configure.ac:238: -1- m4_pattern_allow([^am__fastdepCXX_TRUE$]) m4trace:configure.ac:238: -1- m4_pattern_allow([^am__fastdepCXX_FALSE$]) m4trace:configure.ac:238: -1- _AM_SUBST_NOTMAKE([am__fastdepCXX_TRUE]) m4trace:configure.ac:238: -1- _AM_SUBST_NOTMAKE([am__fastdepCXX_FALSE]) m4trace:configure.ac:243: -1- AM_PROG_CC_C_O m4trace:configure.ac:243: -1- m4_pattern_allow([^NO_MINUS_C_MINUS_O$]) m4trace:configure.ac:247: -1- m4_pattern_allow([^SED$]) m4trace:configure.ac:248: -1- m4_pattern_allow([^LN_S$]) m4trace:configure.ac:252: -1- AC_PROG_LIBTOOL m4trace:configure.ac:252: -1- _m4_warn([obsolete], [The macro `AC_PROG_LIBTOOL' is obsolete. You should run autoupdate.], [/usr/share/aclocal/libtool.m4:107: AC_PROG_LIBTOOL is expanded from... configure.ac:252: the top level]) m4trace:configure.ac:252: -1- LT_INIT m4trace:configure.ac:252: -1- m4_pattern_forbid([^_?LT_[A-Z_]+$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$]) m4trace:configure.ac:252: -1- LTOPTIONS_VERSION m4trace:configure.ac:252: -1- LTSUGAR_VERSION m4trace:configure.ac:252: -1- LTVERSION_VERSION m4trace:configure.ac:252: -1- LTOBSOLETE_VERSION m4trace:configure.ac:252: -1- _LT_PROG_LTMAIN m4trace:configure.ac:252: -1- m4_pattern_allow([^LIBTOOL$]) m4trace:configure.ac:252: -1- _LT_PREPARE_SED_QUOTE_VARS m4trace:configure.ac:252: -1- _LT_PROG_ECHO_BACKSLASH m4trace:configure.ac:252: -1- LT_PATH_LD m4trace:configure.ac:252: -1- m4_pattern_allow([^SED$]) m4trace:configure.ac:252: -1- AC_PROG_EGREP m4trace:configure.ac:252: -1- m4_pattern_allow([^GREP$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^EGREP$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^FGREP$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^GREP$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^LD$]) m4trace:configure.ac:252: -1- LT_PATH_NM m4trace:configure.ac:252: -1- m4_pattern_allow([^DUMPBIN$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^ac_ct_DUMPBIN$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^DUMPBIN$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^NM$]) m4trace:configure.ac:252: -1- LT_CMD_MAX_LEN m4trace:configure.ac:252: -1- m4_pattern_allow([^OBJDUMP$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^OBJDUMP$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^DLLTOOL$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^DLLTOOL$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^AR$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^ac_ct_AR$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^STRIP$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^RANLIB$]) m4trace:configure.ac:252: -1- _LT_WITH_SYSROOT m4trace:configure.ac:252: -1- m4_pattern_allow([LT_OBJDIR]) m4trace:configure.ac:252: -1- m4_pattern_allow([^LT_OBJDIR$]) m4trace:configure.ac:252: -1- _LT_CC_BASENAME([$compiler]) m4trace:configure.ac:252: -1- _LT_PATH_TOOL_PREFIX([${ac_tool_prefix}file], [/usr/bin$PATH_SEPARATOR$PATH]) m4trace:configure.ac:252: -1- _LT_PATH_TOOL_PREFIX([file], [/usr/bin$PATH_SEPARATOR$PATH]) m4trace:configure.ac:252: -1- LT_SUPPORTED_TAG([CC]) m4trace:configure.ac:252: -1- _LT_COMPILER_BOILERPLATE m4trace:configure.ac:252: -1- _LT_LINKER_BOILERPLATE m4trace:configure.ac:252: -1- _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, )="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, ) -fno-rtti -fno-exceptions"]) m4trace:configure.ac:252: -1- _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, ) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, )], [$_LT_TAGVAR(lt_prog_compiler_pic, )@&t@m4_if([],[],[ -DPIC],[m4_if([],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, ) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, )=" $_LT_TAGVAR(lt_prog_compiler_pic, )" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, )= _LT_TAGVAR(lt_prog_compiler_can_build_shared, )=no]) m4trace:configure.ac:252: -1- _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], [lt_cv_prog_compiler_static_works], [$lt_tmp_static_flag], [], [_LT_TAGVAR(lt_prog_compiler_static, )=]) m4trace:configure.ac:252: -1- m4_pattern_allow([^MANIFEST_TOOL$]) m4trace:configure.ac:252: -1- _LT_REQUIRED_DARWIN_CHECKS m4trace:configure.ac:252: -1- m4_pattern_allow([^DSYMUTIL$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^NMEDIT$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^LIPO$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^OTOOL$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^OTOOL64$]) m4trace:configure.ac:252: -1- _LT_LINKER_OPTION([if $CC understands -b], [lt_cv_prog_compiler__b], [-b], [_LT_TAGVAR(archive_cmds, )='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, )='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags']) m4trace:configure.ac:252: -1- LT_SYS_DLOPEN_SELF m4trace:configure.ac:252: -1- m4_pattern_allow([^STDC_HEADERS$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^HAVE_DLFCN_H$]) m4trace:configure.ac:252: -1- LT_LANG([CXX]) m4trace:configure.ac:252: -1- LT_SUPPORTED_TAG([CXX]) m4trace:configure.ac:252: -1- m4_pattern_allow([^CXXCPP$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^CXXCPP$]) m4trace:configure.ac:252: -1- _LT_COMPILER_BOILERPLATE m4trace:configure.ac:252: -1- _LT_LINKER_BOILERPLATE m4trace:configure.ac:252: -1- _LT_CC_BASENAME([$compiler]) m4trace:configure.ac:252: -1- LT_PATH_LD m4trace:configure.ac:252: -1- m4_pattern_allow([^LD$]) m4trace:configure.ac:252: -1- _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, CXX) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, CXX)], [$_LT_TAGVAR(lt_prog_compiler_pic, CXX)@&t@m4_if([CXX],[],[ -DPIC],[m4_if([CXX],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, CXX) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, CXX)=" $_LT_TAGVAR(lt_prog_compiler_pic, CXX)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, CXX)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, CXX)=no]) m4trace:configure.ac:252: -1- _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], [lt_cv_prog_compiler_static_works_CXX], [$lt_tmp_static_flag], [], [_LT_TAGVAR(lt_prog_compiler_static, CXX)=]) m4trace:configure.ac:258: -1- m4_pattern_allow([^HAVE_PKG_CONFIG$]) m4trace:configure.ac:272: -1- m4_pattern_allow([^XMKMF$]) m4trace:configure.ac:272: -1- m4_pattern_allow([^X_DISPLAY_MISSING$]) m4trace:configure.ac:272: -1- m4_pattern_allow([^X_CFLAGS$]) m4trace:configure.ac:272: -1- m4_pattern_allow([^X_PRE_LIBS$]) m4trace:configure.ac:272: -1- m4_pattern_allow([^X_LIBS$]) m4trace:configure.ac:272: -1- m4_pattern_allow([^X_EXTRA_LIBS$]) m4trace:configure.ac:295: -1- AC_VMW_CHECK_LIB([glib-2.0], [GLIB2], [glib-2.0], [], [2.6.0], [glib.h], [g_key_file_new], [], [AC_MSG_ERROR([glib >= 2.6.0 is required.])]) m4trace:configure.ac:295: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:295: -1- m4_pattern_allow([^GLIB2_CPPFLAGS$]) m4trace:configure.ac:295: -1- m4_pattern_allow([^GLIB2_LIBS$]) m4trace:configure.ac:304: -1- AC_VMW_CHECK_LIB([gmodule-2.0], [GMODULE], [gmodule-2.0], [], [2.6.0], [], [], [], [AC_MSG_ERROR([gmodule >= 2.6.0 is required.])]) m4trace:configure.ac:304: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:304: -1- m4_pattern_allow([^GMODULE_CPPFLAGS$]) m4trace:configure.ac:304: -1- m4_pattern_allow([^GMODULE_LIBS$]) m4trace:configure.ac:313: -1- AC_VMW_CHECK_LIB([gobject-2.0], [GOBJECT], [gobject-2.0], [], [2.6.0], [glib-object.h], [], [], [AC_MSG_ERROR([gobject >= 2.6.0 is required.])]) m4trace:configure.ac:313: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:313: -1- m4_pattern_allow([^GOBJECT_CPPFLAGS$]) m4trace:configure.ac:313: -1- m4_pattern_allow([^GOBJECT_LIBS$]) m4trace:configure.ac:322: -1- AC_VMW_CHECK_LIB([gthread-2.0], [GTHREAD], [gthread-2.0], [], [2.6.0], [], [], [], [AC_MSG_ERROR([glib >= 2.6.0 is required.])]) m4trace:configure.ac:322: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:322: -1- m4_pattern_allow([^GTHREAD_CPPFLAGS$]) m4trace:configure.ac:322: -1- m4_pattern_allow([^GTHREAD_LIBS$]) m4trace:configure.ac:331: -1- m4_pattern_allow([^have_genmarshal$]) m4trace:configure.ac:344: -1- AC_VMW_CHECK_LIB([glib-2.0], [GLIB2], [glib-2.0], [], [2.14.0], [glib.h], [g_regex_new], [have_glib_2_14=yes], [AC_MSG_WARN([glib is not recent enough, some features will be disabled.])]) m4trace:configure.ac:344: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:344: -1- m4_pattern_allow([^GLIB2_CPPFLAGS$]) m4trace:configure.ac:344: -1- m4_pattern_allow([^GLIB2_LIBS$]) m4trace:configure.ac:358: -1- AC_VMW_CHECK_LIB([fuse], [FUSE], [fuse], [], [], [fuse.h], [fuse_main], [have_fuse=yes], [have_fuse=no; AC_MSG_WARN([Fuse is missing, vmblock-fuse will be disabled.])]) m4trace:configure.ac:358: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:358: -1- m4_pattern_allow([^FUSE_CPPFLAGS$]) m4trace:configure.ac:358: -1- m4_pattern_allow([^FUSE_LIBS$]) m4trace:configure.ac:379: -1- AC_VMW_DEFAULT_FLAGS([PAM]) m4trace:configure.ac:380: -1- AC_VMW_CHECK_LIB([pam], [PAM], [], [], [], [security/pam_appl.h], [pam_start], [PAM_CPPFLAGS="$PAM_CPPFLAGS -DUSE_PAM"], [AC_VMW_LIB_ERROR([PAM], [pam])]) m4trace:configure.ac:380: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:380: -1- m4_pattern_allow([^PAM_CPPFLAGS$]) m4trace:configure.ac:380: -1- m4_pattern_allow([^PAM_LIBS$]) m4trace:configure.ac:380: -1- AC_VMW_LIB_ERROR([PAM], [pam]) m4trace:configure.ac:395: -1- AC_VMW_DEFAULT_FLAGS([CUNIT]) m4trace:configure.ac:396: -1- AC_VMW_CHECK_LIB([cunit], [CUNIT], [], [], [], [CUnit/CUnit.h], [CU_initialize_registry], [have_cunit=yes], [have_cunit=no]) m4trace:configure.ac:396: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:396: -1- m4_pattern_allow([^CUNIT_CPPFLAGS$]) m4trace:configure.ac:396: -1- m4_pattern_allow([^CUNIT_LIBS$]) m4trace:configure.ac:407: -1- AC_VMW_LIB_ERROR([CUNIT], [cunit]) m4trace:configure.ac:503: -1- m4_pattern_allow([^HAVE_X11_EXTENSIONS_XCOMPOSITE_H$]) m4trace:configure.ac:515: -1- AC_VMW_CHECK_LIB([gtk-x11-2.0], [GTK], [gtk+-2.0], [], [2.4.0], [gtk/gtk.h], [gdk_display_get_default_group], [GTK_CPPFLAGS="$GTK_CPPFLAGS -DGTK2"], [AC_MSG_ERROR([Gtk+ 2.0 library not found or too old. Please configure without Gtk+ support (using --without-gtk2) or install the Gtk+ 2.0 devel package.])]) m4trace:configure.ac:515: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:515: -1- m4_pattern_allow([^GTK_CPPFLAGS$]) m4trace:configure.ac:515: -1- m4_pattern_allow([^GTK_LIBS$]) m4trace:configure.ac:532: -1- AC_VMW_CHECK_LIBXX([gtkmm-2.4], [GTKMM], [gtkmm-2.4], [], [2.4.0], [gtkmm.h], [], [GTKMM_CPPFLAGS="$GTKMM_CPPFLAGS -DHAVE_GTKMM"], [AC_MSG_ERROR([gtkmm library not found. Please install the libgtkmm devel package(s), or re-configure using --without-gtkmm.])]) m4trace:configure.ac:532: -1- AC_VMW_CHECK_LIB([gtkmm-2.4], [GTKMM], [gtkmm-2.4], [], [2.4.0], [gtkmm.h], [], [GTKMM_CPPFLAGS="$GTKMM_CPPFLAGS -DHAVE_GTKMM"], [AC_MSG_ERROR([gtkmm library not found. Please install the libgtkmm devel package(s), or re-configure using --without-gtkmm.])]) m4trace:configure.ac:532: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:532: -1- m4_pattern_allow([^GTKMM_CPPFLAGS$]) m4trace:configure.ac:532: -1- m4_pattern_allow([^GTKMM_LIBS$]) m4trace:configure.ac:551: -1- m4_pattern_allow([^HAVE_DLOPEN$]) m4trace:configure.ac:562: -1- m4_pattern_allow([^HAVE_ECVT$]) m4trace:configure.ac:563: -1- m4_pattern_allow([^HAVE_FCVT$]) m4trace:configure.ac:617: -1- AC_VMW_CHECK_LIB([$CUSTOM_PROCPS_NAME], [PROCPS], [], [], [], [], [getstat], [ have_procps=yes; ], []) m4trace:configure.ac:617: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:617: -1- m4_pattern_allow([^PROCPS_CPPFLAGS$]) m4trace:configure.ac:617: -1- m4_pattern_allow([^PROCPS_LIBS$]) m4trace:configure.ac:630: -1- AC_VMW_CHECK_LIB([proc-3.2.8], [PROCPS], [], [], [], [], [getstat], [ have_procps=yes; ], []) m4trace:configure.ac:630: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:630: -1- m4_pattern_allow([^PROCPS_CPPFLAGS$]) m4trace:configure.ac:630: -1- m4_pattern_allow([^PROCPS_LIBS$]) m4trace:configure.ac:644: -1- AC_VMW_CHECK_LIB([proc-3.2.7], [PROCPS], [], [], [], [], [getstat], [], [AC_MSG_ERROR([libproc not found. Please configure without procps (using --without-procps) or install procps - http://procps.sourceforge.net])]) m4trace:configure.ac:644: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:644: -1- m4_pattern_allow([^PROCPS_CPPFLAGS$]) m4trace:configure.ac:644: -1- m4_pattern_allow([^PROCPS_LIBS$]) m4trace:configure.ac:657: -1- m4_pattern_allow([^NO_PROCPS$]) m4trace:configure.ac:671: -1- AC_VMW_CHECK_LIB([dumbnet], [DNET], [], [dumbnet-config], [], [dumbnet.h], [intf_open], [have_dnet="yes"; AC_DEFINE([DNET_IS_DUMBNET], 1, [Define to 1 if substituting Debian's libdumbnet for libdnet.])], []) m4trace:configure.ac:671: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:671: -1- m4_pattern_allow([^DNET_CPPFLAGS$]) m4trace:configure.ac:671: -1- m4_pattern_allow([^DNET_LIBS$]) m4trace:configure.ac:671: -1- m4_pattern_allow([^DNET_IS_DUMBNET$]) m4trace:configure.ac:683: -1- AC_VMW_CHECK_LIB([dnet], [DNET], [], [dnet-config], [], [dnet.h], [intf_open], [have_dnet="yes"], []) m4trace:configure.ac:683: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:683: -1- m4_pattern_allow([^DNET_CPPFLAGS$]) m4trace:configure.ac:683: -1- m4_pattern_allow([^DNET_LIBS$]) m4trace:configure.ac:701: -1- m4_pattern_allow([^NO_DNET$]) m4trace:configure.ac:711: -1- m4_pattern_allow([^have_cxx$]) m4trace:configure.ac:718: -1- AC_VMW_CHECK_LIBXX([icuuc], [ICU], [], [icu-config], [], [unicode/utf.h], [], [ICU_CPPFLAGS="$ICU_CPPFLAGS -DUSE_ICU"], [AC_MSG_ERROR([ICU library not found. Please configure without ICU (using --without-icu) or install ICU - http://www.icu-project.org])]) m4trace:configure.ac:718: -1- AC_VMW_CHECK_LIB([icuuc], [ICU], [], [icu-config], [], [unicode/utf.h], [], [ICU_CPPFLAGS="$ICU_CPPFLAGS -DUSE_ICU"], [AC_MSG_ERROR([ICU library not found. Please configure without ICU (using --without-icu) or install ICU - http://www.icu-project.org])]) m4trace:configure.ac:718: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:718: -1- m4_pattern_allow([^ICU_CPPFLAGS$]) m4trace:configure.ac:718: -1- m4_pattern_allow([^ICU_LIBS$]) m4trace:configure.ac:732: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from... configure.ac:732: the top level]) m4trace:configure.ac:751: -1- m4_pattern_allow([^RPCGEN$]) m4trace:configure.ac:760: -1- m4_pattern_allow([^HAVE_CRYPT_H$]) m4trace:configure.ac:761: -1- m4_pattern_allow([^HAVE_INTTYPES_H$]) m4trace:configure.ac:762: -1- m4_pattern_allow([^HAVE_STDINT_H$]) m4trace:configure.ac:763: -1- m4_pattern_allow([^HAVE_STDLIB_H$]) m4trace:configure.ac:764: -1- m4_pattern_allow([^HAVE_WCHAR_H$]) m4trace:configure.ac:765: -1- m4_pattern_allow([^HAVE_SYS_INTTYPES_H$]) m4trace:configure.ac:766: -1- m4_pattern_allow([^HAVE_SYS_IO_H$]) m4trace:configure.ac:767: -1- m4_pattern_allow([^HAVE_SYS_PARAM_H$]) m4trace:configure.ac:768: -1- m4_pattern_allow([^HAVE_SYS_SYSINFO_H$]) m4trace:configure.ac:769: -1- m4_pattern_allow([^HAVE_SYS_TYPES_H$]) m4trace:configure.ac:770: -1- m4_pattern_allow([^HAVE_SYS_USER_H$]) m4trace:configure.ac:778: -1- m4_pattern_allow([^HAVE_SYS_VFS_H$]) m4trace:configure.ac:779: -1- m4_pattern_allow([^HAVE_SYSLIMITS_H$]) m4trace:configure.ac:780: -1- m4_pattern_allow([^HAVE_UNWIND_H$]) m4trace:configure.ac:816: -1- m4_pattern_allow([^HAVE__BOOL$]) m4trace:configure.ac:816: -1- m4_pattern_allow([^HAVE_STDBOOL_H$]) m4trace:configure.ac:817: -1- m4_pattern_allow([^const$]) m4trace:configure.ac:818: -1- m4_pattern_allow([^uid_t$]) m4trace:configure.ac:818: -1- m4_pattern_allow([^gid_t$]) m4trace:configure.ac:820: -1- m4_pattern_allow([^mode_t$]) m4trace:configure.ac:821: -1- m4_pattern_allow([^off_t$]) m4trace:configure.ac:822: -1- m4_pattern_allow([^pid_t$]) m4trace:configure.ac:823: -1- m4_pattern_allow([^size_t$]) m4trace:configure.ac:824: -1- m4_pattern_allow([^HAVE_STRUCT_STAT_ST_RDEV$]) m4trace:configure.ac:825: -1- m4_pattern_allow([^TIME_WITH_SYS_TIME$]) m4trace:configure.ac:826: -1- m4_pattern_allow([^TM_IN_SYS_TIME$]) m4trace:configure.ac:827: -1- m4_pattern_allow([^volatile$]) m4trace:configure.ac:844: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from... configure.ac:844: the top level]) m4trace:configure.ac:861: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from... configure.ac:861: the top level]) m4trace:configure.ac:872: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from... configure.ac:872: the top level]) m4trace:configure.ac:891: -1- m4_pattern_allow([^have_doxygen$]) m4trace:configure.ac:898: -1- m4_pattern_allow([^DOT$]) m4trace:configure.ac:905: -1- m4_pattern_allow([^DOT$]) m4trace:configure.ac:906: -1- m4_pattern_allow([^HAVE_DOT$]) m4trace:configure.ac:908: -1- m4_pattern_allow([^MSCGEN$]) m4trace:configure.ac:916: -1- m4_pattern_allow([^MSCGEN_DIR$]) m4trace:configure.ac:1016: -1- AM_CONDITIONAL([BUILD_HGFSMOUNTER], [test "$buildHgfsmounter" = "yes"]) m4trace:configure.ac:1016: -1- m4_pattern_allow([^BUILD_HGFSMOUNTER_TRUE$]) m4trace:configure.ac:1016: -1- m4_pattern_allow([^BUILD_HGFSMOUNTER_FALSE$]) m4trace:configure.ac:1016: -1- _AM_SUBST_NOTMAKE([BUILD_HGFSMOUNTER_TRUE]) m4trace:configure.ac:1016: -1- _AM_SUBST_NOTMAKE([BUILD_HGFSMOUNTER_FALSE]) m4trace:configure.ac:1017: -1- AM_CONDITIONAL([LINUX], [test "$os" = "linux"]) m4trace:configure.ac:1017: -1- m4_pattern_allow([^LINUX_TRUE$]) m4trace:configure.ac:1017: -1- m4_pattern_allow([^LINUX_FALSE$]) m4trace:configure.ac:1017: -1- _AM_SUBST_NOTMAKE([LINUX_TRUE]) m4trace:configure.ac:1017: -1- _AM_SUBST_NOTMAKE([LINUX_FALSE]) m4trace:configure.ac:1018: -1- AM_CONDITIONAL([SOLARIS], [test "$os" = "solaris"]) m4trace:configure.ac:1018: -1- m4_pattern_allow([^SOLARIS_TRUE$]) m4trace:configure.ac:1018: -1- m4_pattern_allow([^SOLARIS_FALSE$]) m4trace:configure.ac:1018: -1- _AM_SUBST_NOTMAKE([SOLARIS_TRUE]) m4trace:configure.ac:1018: -1- _AM_SUBST_NOTMAKE([SOLARIS_FALSE]) m4trace:configure.ac:1019: -1- AM_CONDITIONAL([FREEBSD], [test "$os" = "freebsd"]) m4trace:configure.ac:1019: -1- m4_pattern_allow([^FREEBSD_TRUE$]) m4trace:configure.ac:1019: -1- m4_pattern_allow([^FREEBSD_FALSE$]) m4trace:configure.ac:1019: -1- _AM_SUBST_NOTMAKE([FREEBSD_TRUE]) m4trace:configure.ac:1019: -1- _AM_SUBST_NOTMAKE([FREEBSD_FALSE]) m4trace:configure.ac:1020: -1- AM_CONDITIONAL([FREEBSD_CUSTOM_SYSDIR], [test "$os" = "freebsd" -a -n "$SYSDIR"]) m4trace:configure.ac:1020: -1- m4_pattern_allow([^FREEBSD_CUSTOM_SYSDIR_TRUE$]) m4trace:configure.ac:1020: -1- m4_pattern_allow([^FREEBSD_CUSTOM_SYSDIR_FALSE$]) m4trace:configure.ac:1020: -1- _AM_SUBST_NOTMAKE([FREEBSD_CUSTOM_SYSDIR_TRUE]) m4trace:configure.ac:1020: -1- _AM_SUBST_NOTMAKE([FREEBSD_CUSTOM_SYSDIR_FALSE]) m4trace:configure.ac:1021: -1- AM_CONDITIONAL([THIRTY_TWO_BIT_USERSPACE], [test "$userSpaceBitness" = "32"]) m4trace:configure.ac:1021: -1- m4_pattern_allow([^THIRTY_TWO_BIT_USERSPACE_TRUE$]) m4trace:configure.ac:1021: -1- m4_pattern_allow([^THIRTY_TWO_BIT_USERSPACE_FALSE$]) m4trace:configure.ac:1021: -1- _AM_SUBST_NOTMAKE([THIRTY_TWO_BIT_USERSPACE_TRUE]) m4trace:configure.ac:1021: -1- _AM_SUBST_NOTMAKE([THIRTY_TWO_BIT_USERSPACE_FALSE]) m4trace:configure.ac:1022: -1- AM_CONDITIONAL([HAVE_X11], [test "$have_x" = "yes"]) m4trace:configure.ac:1022: -1- m4_pattern_allow([^HAVE_X11_TRUE$]) m4trace:configure.ac:1022: -1- m4_pattern_allow([^HAVE_X11_FALSE$]) m4trace:configure.ac:1022: -1- _AM_SUBST_NOTMAKE([HAVE_X11_TRUE]) m4trace:configure.ac:1022: -1- _AM_SUBST_NOTMAKE([HAVE_X11_FALSE]) m4trace:configure.ac:1023: -1- AM_CONDITIONAL([HAVE_ICU], [test "$with_icu" = "yes"]) m4trace:configure.ac:1023: -1- m4_pattern_allow([^HAVE_ICU_TRUE$]) m4trace:configure.ac:1023: -1- m4_pattern_allow([^HAVE_ICU_FALSE$]) m4trace:configure.ac:1023: -1- _AM_SUBST_NOTMAKE([HAVE_ICU_TRUE]) m4trace:configure.ac:1023: -1- _AM_SUBST_NOTMAKE([HAVE_ICU_FALSE]) m4trace:configure.ac:1024: -1- AM_CONDITIONAL([WITH_KERNEL_MODULES], [test "$with_kernel_modules" = "yes"]) m4trace:configure.ac:1024: -1- m4_pattern_allow([^WITH_KERNEL_MODULES_TRUE$]) m4trace:configure.ac:1024: -1- m4_pattern_allow([^WITH_KERNEL_MODULES_FALSE$]) m4trace:configure.ac:1024: -1- _AM_SUBST_NOTMAKE([WITH_KERNEL_MODULES_TRUE]) m4trace:configure.ac:1024: -1- _AM_SUBST_NOTMAKE([WITH_KERNEL_MODULES_FALSE]) m4trace:configure.ac:1025: -1- AM_CONDITIONAL([HAVE_XSM], [test "$have_xsm" = "yes"]) m4trace:configure.ac:1025: -1- m4_pattern_allow([^HAVE_XSM_TRUE$]) m4trace:configure.ac:1025: -1- m4_pattern_allow([^HAVE_XSM_FALSE$]) m4trace:configure.ac:1025: -1- _AM_SUBST_NOTMAKE([HAVE_XSM_TRUE]) m4trace:configure.ac:1025: -1- _AM_SUBST_NOTMAKE([HAVE_XSM_FALSE]) m4trace:configure.ac:1026: -1- AM_CONDITIONAL([HAVE_XCOMPOSITE], [test "$have_xcomposite" = "yes"]) m4trace:configure.ac:1026: -1- m4_pattern_allow([^HAVE_XCOMPOSITE_TRUE$]) m4trace:configure.ac:1026: -1- m4_pattern_allow([^HAVE_XCOMPOSITE_FALSE$]) m4trace:configure.ac:1026: -1- _AM_SUBST_NOTMAKE([HAVE_XCOMPOSITE_TRUE]) m4trace:configure.ac:1026: -1- _AM_SUBST_NOTMAKE([HAVE_XCOMPOSITE_FALSE]) m4trace:configure.ac:1027: -1- AM_CONDITIONAL([ENABLE_TESTS], [test "$have_cunit" = "yes"]) m4trace:configure.ac:1027: -1- m4_pattern_allow([^ENABLE_TESTS_TRUE$]) m4trace:configure.ac:1027: -1- m4_pattern_allow([^ENABLE_TESTS_FALSE$]) m4trace:configure.ac:1027: -1- _AM_SUBST_NOTMAKE([ENABLE_TESTS_TRUE]) m4trace:configure.ac:1027: -1- _AM_SUBST_NOTMAKE([ENABLE_TESTS_FALSE]) m4trace:configure.ac:1028: -1- AM_CONDITIONAL([WITH_ROOT_PRIVILEGES], [test "$with_root_privileges" = "yes"]) m4trace:configure.ac:1028: -1- m4_pattern_allow([^WITH_ROOT_PRIVILEGES_TRUE$]) m4trace:configure.ac:1028: -1- m4_pattern_allow([^WITH_ROOT_PRIVILEGES_FALSE$]) m4trace:configure.ac:1028: -1- _AM_SUBST_NOTMAKE([WITH_ROOT_PRIVILEGES_TRUE]) m4trace:configure.ac:1028: -1- _AM_SUBST_NOTMAKE([WITH_ROOT_PRIVILEGES_FALSE]) m4trace:configure.ac:1029: -1- AM_CONDITIONAL([HAVE_DNET], [test "$have_dnet" = "yes"]) m4trace:configure.ac:1029: -1- m4_pattern_allow([^HAVE_DNET_TRUE$]) m4trace:configure.ac:1029: -1- m4_pattern_allow([^HAVE_DNET_FALSE$]) m4trace:configure.ac:1029: -1- _AM_SUBST_NOTMAKE([HAVE_DNET_TRUE]) m4trace:configure.ac:1029: -1- _AM_SUBST_NOTMAKE([HAVE_DNET_FALSE]) m4trace:configure.ac:1030: -1- AM_CONDITIONAL([HAVE_DOXYGEN], [test "$have_doxygen" = "yes"]) m4trace:configure.ac:1030: -1- m4_pattern_allow([^HAVE_DOXYGEN_TRUE$]) m4trace:configure.ac:1030: -1- m4_pattern_allow([^HAVE_DOXYGEN_FALSE$]) m4trace:configure.ac:1030: -1- _AM_SUBST_NOTMAKE([HAVE_DOXYGEN_TRUE]) m4trace:configure.ac:1030: -1- _AM_SUBST_NOTMAKE([HAVE_DOXYGEN_FALSE]) m4trace:configure.ac:1031: -1- AM_CONDITIONAL([HAVE_FUSE], [test "$have_fuse" = "yes"]) m4trace:configure.ac:1031: -1- m4_pattern_allow([^HAVE_FUSE_TRUE$]) m4trace:configure.ac:1031: -1- m4_pattern_allow([^HAVE_FUSE_FALSE$]) m4trace:configure.ac:1031: -1- _AM_SUBST_NOTMAKE([HAVE_FUSE_TRUE]) m4trace:configure.ac:1031: -1- _AM_SUBST_NOTMAKE([HAVE_FUSE_FALSE]) m4trace:configure.ac:1032: -1- AM_CONDITIONAL([HAVE_GNU_LD], [test "$with_gnu_ld" = "yes"]) m4trace:configure.ac:1032: -1- m4_pattern_allow([^HAVE_GNU_LD_TRUE$]) m4trace:configure.ac:1032: -1- m4_pattern_allow([^HAVE_GNU_LD_FALSE$]) m4trace:configure.ac:1032: -1- _AM_SUBST_NOTMAKE([HAVE_GNU_LD_TRUE]) m4trace:configure.ac:1032: -1- _AM_SUBST_NOTMAKE([HAVE_GNU_LD_FALSE]) m4trace:configure.ac:1033: -1- AM_CONDITIONAL([HAVE_GTKMM], [test "$have_x" = "yes" -a "$with_gtkmm" = "yes"]) m4trace:configure.ac:1033: -1- m4_pattern_allow([^HAVE_GTKMM_TRUE$]) m4trace:configure.ac:1033: -1- m4_pattern_allow([^HAVE_GTKMM_FALSE$]) m4trace:configure.ac:1033: -1- _AM_SUBST_NOTMAKE([HAVE_GTKMM_TRUE]) m4trace:configure.ac:1033: -1- _AM_SUBST_NOTMAKE([HAVE_GTKMM_FALSE]) m4trace:configure.ac:1034: -1- AM_CONDITIONAL([HAVE_PAM], [test "$with_pam" = "yes"]) m4trace:configure.ac:1034: -1- m4_pattern_allow([^HAVE_PAM_TRUE$]) m4trace:configure.ac:1034: -1- m4_pattern_allow([^HAVE_PAM_FALSE$]) m4trace:configure.ac:1034: -1- _AM_SUBST_NOTMAKE([HAVE_PAM_TRUE]) m4trace:configure.ac:1034: -1- _AM_SUBST_NOTMAKE([HAVE_PAM_FALSE]) m4trace:configure.ac:1035: -1- AM_CONDITIONAL([USE_SLASH_PROC], [test "os" = "linux" -a "$have_glib_2_14" = "yes"]) m4trace:configure.ac:1035: -1- m4_pattern_allow([^USE_SLASH_PROC_TRUE$]) m4trace:configure.ac:1035: -1- m4_pattern_allow([^USE_SLASH_PROC_FALSE$]) m4trace:configure.ac:1035: -1- _AM_SUBST_NOTMAKE([USE_SLASH_PROC_TRUE]) m4trace:configure.ac:1035: -1- _AM_SUBST_NOTMAKE([USE_SLASH_PROC_FALSE]) m4trace:configure.ac:1036: -1- AM_CONDITIONAL([USE_PRINTF_WRAPPERS], [test "$bsdPrintfWrappers" = "yes"]) m4trace:configure.ac:1036: -1- m4_pattern_allow([^USE_PRINTF_WRAPPERS_TRUE$]) m4trace:configure.ac:1036: -1- m4_pattern_allow([^USE_PRINTF_WRAPPERS_FALSE$]) m4trace:configure.ac:1036: -1- _AM_SUBST_NOTMAKE([USE_PRINTF_WRAPPERS_TRUE]) m4trace:configure.ac:1036: -1- _AM_SUBST_NOTMAKE([USE_PRINTF_WRAPPERS_FALSE]) m4trace:configure.ac:1039: -1- m4_pattern_allow([^NO_XSM$]) m4trace:configure.ac:1043: -1- m4_pattern_allow([^NO_XCOMPOSITE$]) m4trace:configure.ac:1055: -1- m4_pattern_allow([^NO_MULTIMON$]) m4trace:configure.ac:1097: -1- m4_pattern_allow([^HGFS_LIBS$]) m4trace:configure.ac:1098: -1- m4_pattern_allow([^TOOLS_VERSION$]) m4trace:configure.ac:1099: -1- m4_pattern_allow([^TARGET_OS$]) m4trace:configure.ac:1100: -1- m4_pattern_allow([^KERNEL_RELEASE$]) m4trace:configure.ac:1101: -1- m4_pattern_allow([^LINUXINCLUDE$]) m4trace:configure.ac:1102: -1- m4_pattern_allow([^MODULES_OS$]) m4trace:configure.ac:1103: -1- m4_pattern_allow([^MODULES_DIR$]) m4trace:configure.ac:1104: -1- m4_pattern_allow([^MODULES$]) m4trace:configure.ac:1105: -1- m4_pattern_allow([^COMMON_XLIBS$]) m4trace:configure.ac:1106: -1- m4_pattern_allow([^XSM_LIBS$]) m4trace:configure.ac:1107: -1- m4_pattern_allow([^XCOMPOSITE_LIBS$]) m4trace:configure.ac:1108: -1- m4_pattern_allow([^PAM_PREFIX$]) m4trace:configure.ac:1109: -1- m4_pattern_allow([^PLUGIN_CPPFLAGS$]) m4trace:configure.ac:1110: -1- m4_pattern_allow([^PLUGIN_LDFLAGS$]) m4trace:configure.ac:1111: -1- m4_pattern_allow([^VMTOOLS_CPPFLAGS$]) m4trace:configure.ac:1112: -1- m4_pattern_allow([^VMTOOLS_LIBS$]) m4trace:configure.ac:1113: -1- m4_pattern_allow([^RPCGENFLAGS$]) m4trace:configure.ac:1114: -1- m4_pattern_allow([^XDR_LIBS$]) m4trace:configure.ac:1115: -1- m4_pattern_allow([^TEST_PLUGIN_INSTALLDIR$]) m4trace:configure.ac:1116: -1- m4_pattern_allow([^COMMON_PLUGIN_INSTALLDIR$]) m4trace:configure.ac:1117: -1- m4_pattern_allow([^VMSVC_PLUGIN_INSTALLDIR$]) m4trace:configure.ac:1118: -1- m4_pattern_allow([^VMUSR_PLUGIN_INSTALLDIR$]) m4trace:configure.ac:1123: -1- m4_pattern_allow([^SYSDIR$]) m4trace:configure.ac:1125: -1- m4_pattern_allow([^INSTVMSG$]) m4trace:configure.ac:1126: -1- m4_pattern_allow([^RPCGEN_WRAPPER$]) m4trace:configure.ac:1130: -1- m4_pattern_allow([^LIB_AUTH_CPPFLAGS$]) m4trace:configure.ac:1131: -1- m4_pattern_allow([^LIB_IMPERSONATE_CPPFLAGS$]) m4trace:configure.ac:1132: -1- m4_pattern_allow([^LIB_USER_CPPFLAGS$]) m4trace:configure.ac:1133: -1- m4_pattern_allow([^LIBVMTOOLS_LIBADD$]) m4trace:configure.ac:1137: -1- m4_pattern_allow([^VIX_LIBADD$]) m4trace:configure.ac:1227: -1- m4_pattern_allow([^LIB@&t@OBJS$]) m4trace:configure.ac:1227: -1- m4_pattern_allow([^LTLIBOBJS$]) m4trace:configure.ac:1227: -1- AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"]) m4trace:configure.ac:1227: -1- m4_pattern_allow([^am__EXEEXT_TRUE$]) m4trace:configure.ac:1227: -1- m4_pattern_allow([^am__EXEEXT_FALSE$]) m4trace:configure.ac:1227: -1- _AM_SUBST_NOTMAKE([am__EXEEXT_TRUE]) m4trace:configure.ac:1227: -1- _AM_SUBST_NOTMAKE([am__EXEEXT_FALSE]) m4trace:configure.ac:1227: -1- _AM_OUTPUT_DEPENDENCY_COMMANDS m4trace:configure.ac:1227: -1- _LT_PROG_LTMAIN open-vm-tools-9.4.0-1280544/autom4te.cache/traces.20000644765153500003110000040624112220061615017612 0ustar dtormtsm4trace:/usr/share/aclocal/argz.m4:12: -1- AC_DEFUN([gl_FUNC_ARGZ], [gl_PREREQ_ARGZ AC_CHECK_HEADERS([argz.h], [], [], [AC_INCLUDES_DEFAULT]) AC_CHECK_TYPES([error_t], [], [AC_DEFINE([error_t], [int], [Define to a type to use for `error_t' if it is not otherwise available.]) AC_DEFINE([__error_t_defined], [1], [Define so that glibc/gnulib argp.h does not typedef error_t.])], [#if defined(HAVE_ARGZ_H) # include #endif]) ARGZ_H= AC_CHECK_FUNCS([argz_add argz_append argz_count argz_create_sep argz_insert \ argz_next argz_stringify], [], [ARGZ_H=argz.h; AC_LIBOBJ([argz])]) dnl if have system argz functions, allow forced use of dnl libltdl-supplied implementation (and default to do so dnl on "known bad" systems). Could use a runtime check, but dnl (a) detecting malloc issues is notoriously unreliable dnl (b) only known system that declares argz functions, dnl provides them, yet they are broken, is cygwin dnl releases prior to 16-Mar-2007 (1.5.24 and earlier) dnl So, it's more straightforward simply to special case dnl this for known bad systems. AS_IF([test -z "$ARGZ_H"], [AC_CACHE_CHECK( [if argz actually works], [lt_cv_sys_argz_works], [[case $host_os in #( *cygwin*) lt_cv_sys_argz_works=no if test "$cross_compiling" != no; then lt_cv_sys_argz_works="guessing no" else lt_sed_extract_leading_digits='s/^\([0-9\.]*\).*/\1/' save_IFS=$IFS IFS=-. set x `uname -r | sed -e "$lt_sed_extract_leading_digits"` IFS=$save_IFS lt_os_major=${2-0} lt_os_minor=${3-0} lt_os_micro=${4-0} if test "$lt_os_major" -gt 1 \ || { test "$lt_os_major" -eq 1 \ && { test "$lt_os_minor" -gt 5 \ || { test "$lt_os_minor" -eq 5 \ && test "$lt_os_micro" -gt 24; }; }; }; then lt_cv_sys_argz_works=yes fi fi ;; #( *) lt_cv_sys_argz_works=yes ;; esac]]) AS_IF([test "$lt_cv_sys_argz_works" = yes], [AC_DEFINE([HAVE_WORKING_ARGZ], 1, [This value is set to 1 to indicate that the system argz facility works])], [ARGZ_H=argz.h AC_LIBOBJ([argz])])]) AC_SUBST([ARGZ_H]) ]) m4trace:/usr/share/aclocal/argz.m4:79: -1- AC_DEFUN([gl_PREREQ_ARGZ], [:]) m4trace:/usr/share/aclocal/ltdl.m4:16: -1- AC_DEFUN([LT_CONFIG_LTDL_DIR], [AC_BEFORE([$0], [LTDL_INIT]) _$0($*) ]) m4trace:/usr/share/aclocal/ltdl.m4:68: -1- 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() ]) m4trace:/usr/share/aclocal/ltdl.m4:81: -1- AU_DEFUN([AC_LIBLTDL_CONVENIENCE], [_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) _LTDL_CONVENIENCE]) m4trace:/usr/share/aclocal/ltdl.m4:81: -1- AC_DEFUN([AC_LIBLTDL_CONVENIENCE], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBLTDL_CONVENIENCE' is obsolete. You should run autoupdate.])dnl _LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) _LTDL_CONVENIENCE]) m4trace:/usr/share/aclocal/ltdl.m4:124: -1- 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() ]) m4trace:/usr/share/aclocal/ltdl.m4:137: -1- AU_DEFUN([AC_LIBLTDL_INSTALLABLE], [_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) _LTDL_INSTALLABLE]) m4trace:/usr/share/aclocal/ltdl.m4:137: -1- AC_DEFUN([AC_LIBLTDL_INSTALLABLE], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBLTDL_INSTALLABLE' is obsolete. You should run autoupdate.])dnl _LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) _LTDL_INSTALLABLE]) m4trace:/usr/share/aclocal/ltdl.m4:213: -1- AC_DEFUN([_LT_LIBOBJ], [ m4_pattern_allow([^_LT_LIBOBJS$]) _LT_LIBOBJS="$_LT_LIBOBJS $1.$ac_objext" ]) m4trace:/usr/share/aclocal/ltdl.m4:226: -1- 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]) ]) m4trace:/usr/share/aclocal/ltdl.m4:352: -1- AU_DEFUN([AC_LIB_LTDL], [LTDL_INIT($@)]) m4trace:/usr/share/aclocal/ltdl.m4:352: -1- AC_DEFUN([AC_LIB_LTDL], [AC_DIAGNOSE([obsolete], [The macro `AC_LIB_LTDL' is obsolete. You should run autoupdate.])dnl LTDL_INIT($@)]) m4trace:/usr/share/aclocal/ltdl.m4:353: -1- AU_DEFUN([AC_WITH_LTDL], [LTDL_INIT($@)]) m4trace:/usr/share/aclocal/ltdl.m4:353: -1- AC_DEFUN([AC_WITH_LTDL], [AC_DIAGNOSE([obsolete], [The macro `AC_WITH_LTDL' is obsolete. You should run autoupdate.])dnl LTDL_INIT($@)]) m4trace:/usr/share/aclocal/ltdl.m4:354: -1- AU_DEFUN([LT_WITH_LTDL], [LTDL_INIT($@)]) m4trace:/usr/share/aclocal/ltdl.m4:354: -1- AC_DEFUN([LT_WITH_LTDL], [AC_DIAGNOSE([obsolete], [The macro `LT_WITH_LTDL' is obsolete. You should run autoupdate.])dnl LTDL_INIT($@)]) m4trace:/usr/share/aclocal/ltdl.m4:367: -1- 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]) ]) m4trace:/usr/share/aclocal/ltdl.m4:443: -1- 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 ]) m4trace:/usr/share/aclocal/ltdl.m4:542: -1- AU_DEFUN([AC_LTDL_SYS_DLOPEN_DEPLIBS], [m4_if($#, 0, [LT_SYS_DLOPEN_DEPLIBS], [LT_SYS_DLOPEN_DEPLIBS($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:542: -1- AC_DEFUN([AC_LTDL_SYS_DLOPEN_DEPLIBS], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_SYS_DLOPEN_DEPLIBS' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_SYS_DLOPEN_DEPLIBS], [LT_SYS_DLOPEN_DEPLIBS($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:549: -1- 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 ]) m4trace:/usr/share/aclocal/ltdl.m4:572: -1- AU_DEFUN([AC_LTDL_SHLIBEXT], [m4_if($#, 0, [LT_SYS_MODULE_EXT], [LT_SYS_MODULE_EXT($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:572: -1- AC_DEFUN([AC_LTDL_SHLIBEXT], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_SHLIBEXT' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_SYS_MODULE_EXT], [LT_SYS_MODULE_EXT($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:579: -1- 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 ]) m4trace:/usr/share/aclocal/ltdl.m4:591: -1- AU_DEFUN([AC_LTDL_SHLIBPATH], [m4_if($#, 0, [LT_SYS_MODULE_PATH], [LT_SYS_MODULE_PATH($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:591: -1- AC_DEFUN([AC_LTDL_SHLIBPATH], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_SHLIBPATH' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_SYS_MODULE_PATH], [LT_SYS_MODULE_PATH($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:598: -1- 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 ]) m4trace:/usr/share/aclocal/ltdl.m4:619: -1- AU_DEFUN([AC_LTDL_SYSSEARCHPATH], [m4_if($#, 0, [LT_SYS_DLSEARCH_PATH], [LT_SYS_DLSEARCH_PATH($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:619: -1- AC_DEFUN([AC_LTDL_SYSSEARCHPATH], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_SYSSEARCHPATH' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_SYS_DLSEARCH_PATH], [LT_SYS_DLSEARCH_PATH($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:645: -1- 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 ]) m4trace:/usr/share/aclocal/ltdl.m4:738: -1- AU_DEFUN([AC_LTDL_DLLIB], [m4_if($#, 0, [LT_LIB_DLLOAD], [LT_LIB_DLLOAD($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:738: -1- AC_DEFUN([AC_LTDL_DLLIB], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_DLLIB' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_LIB_DLLOAD], [LT_LIB_DLLOAD($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:746: -1- 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]) ]) m4trace:/usr/share/aclocal/ltdl.m4:783: -1- AU_DEFUN([AC_LTDL_SYMBOL_USCORE], [m4_if($#, 0, [LT_SYS_SYMBOL_USCORE], [LT_SYS_SYMBOL_USCORE($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:783: -1- AC_DEFUN([AC_LTDL_SYMBOL_USCORE], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_SYMBOL_USCORE' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_SYS_SYMBOL_USCORE], [LT_SYS_SYMBOL_USCORE($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:790: -1- 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 ]) m4trace:/usr/share/aclocal/ltdl.m4:815: -1- AU_DEFUN([AC_LTDL_DLSYM_USCORE], [m4_if($#, 0, [LT_FUNC_DLSYM_USCORE], [LT_FUNC_DLSYM_USCORE($@)])]) m4trace:/usr/share/aclocal/ltdl.m4:815: -1- AC_DEFUN([AC_LTDL_DLSYM_USCORE], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_DLSYM_USCORE' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_FUNC_DLSYM_USCORE], [LT_FUNC_DLSYM_USCORE($@)])]) m4trace:/usr/share/aclocal-1.12/amversion.m4:16: -1- AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.12' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.12.2], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) m4trace:/usr/share/aclocal-1.12/amversion.m4:35: -1- AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.12.2])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) m4trace:/usr/share/aclocal-1.12/auxdir.m4:49: -1- AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) m4trace:/usr/share/aclocal-1.12/cond.m4:14: -1- AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) m4trace:/usr/share/aclocal-1.12/depend.m4:27: -1- AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) m4trace:/usr/share/aclocal-1.12/depend.m4:164: -1- AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) m4trace:/usr/share/aclocal-1.12/depend.m4:172: -1- AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) m4trace:/usr/share/aclocal-1.12/depout.m4:13: -1- AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ]) m4trace:/usr/share/aclocal-1.12/depout.m4:72: -1- AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) m4trace:/usr/share/aclocal-1.12/init.m4:25: -1- AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.62])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated. For more info, see: http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_INIT_AUTOMAKE-invocation]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl dnl Support for Objective C++ was only introduced in Autoconf 2.65, dnl but we still cater to Autoconf 2.62. m4_ifdef([AC_PROG_OBJCXX], [AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])])dnl ]) _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl dnl The 'parallel-tests' driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) m4trace:/usr/share/aclocal-1.12/init.m4:142: -1- AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) m4trace:/usr/share/aclocal-1.12/install-sh.m4:13: -1- AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) m4trace:/usr/share/aclocal-1.12/lead-dot.m4:12: -1- AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) m4trace:/usr/share/aclocal-1.12/make.m4:14: -1- AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) m4trace:/usr/share/aclocal-1.12/minuso.m4:13: -1- AC_DEFUN([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC_C_O])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl # FIXME: we rely on the cache variable name because # there is no other way. set dummy $CC am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o if test "$am_t" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi dnl Make sure AC_PROG_CC is never called again, or it will override our dnl setting of CC. m4_define([AC_PROG_CC], [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) ]) m4trace:/usr/share/aclocal-1.12/missing.m4:13: -1- AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) m4trace:/usr/share/aclocal-1.12/missing.m4:23: -1- AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) m4trace:/usr/share/aclocal-1.12/options.m4:13: -1- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) m4trace:/usr/share/aclocal-1.12/options.m4:19: -1- AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) m4trace:/usr/share/aclocal-1.12/options.m4:25: -1- AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) m4trace:/usr/share/aclocal-1.12/options.m4:31: -1- AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) m4trace:/usr/share/aclocal-1.12/runlog.m4:14: -1- AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) m4trace:/usr/share/aclocal-1.12/sanity.m4:13: -1- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) m4trace:/usr/share/aclocal-1.12/silent.m4:14: -1- AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) m4trace:/usr/share/aclocal-1.12/strip.m4:19: -1- AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) m4trace:/usr/share/aclocal-1.12/substnot.m4:14: -1- AC_DEFUN([_AM_SUBST_NOTMAKE]) m4trace:/usr/share/aclocal-1.12/substnot.m4:19: -1- AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) m4trace:/usr/share/aclocal-1.12/tar.m4:24: -1- AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of '-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) m4trace:m4/libtool.m4:69: -1- 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]) ]) m4trace:m4/libtool.m4:107: -1- AU_DEFUN([AC_PROG_LIBTOOL], [m4_if($#, 0, [LT_INIT], [LT_INIT($@)])]) m4trace:m4/libtool.m4:107: -1- AC_DEFUN([AC_PROG_LIBTOOL], [AC_DIAGNOSE([obsolete], [The macro `AC_PROG_LIBTOOL' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_INIT], [LT_INIT($@)])]) m4trace:m4/libtool.m4:108: -1- AU_DEFUN([AM_PROG_LIBTOOL], [m4_if($#, 0, [LT_INIT], [LT_INIT($@)])]) m4trace:m4/libtool.m4:108: -1- AC_DEFUN([AM_PROG_LIBTOOL], [AC_DIAGNOSE([obsolete], [The macro `AM_PROG_LIBTOOL' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_INIT], [LT_INIT($@)])]) m4trace:m4/libtool.m4:609: -1- 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) ]) m4trace:m4/libtool.m4:790: -1- AC_DEFUN([LT_SUPPORTED_TAG], []) m4trace:m4/libtool.m4:801: -1- 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 ]) m4trace:m4/libtool.m4:893: -1- AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) m4trace:m4/libtool.m4:893: -1- AC_DEFUN([AC_LIBTOOL_CXX], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_CXX' is obsolete. You should run autoupdate.])dnl LT_LANG(C++)]) m4trace:m4/libtool.m4:894: -1- AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) m4trace:m4/libtool.m4:894: -1- AC_DEFUN([AC_LIBTOOL_F77], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_F77' is obsolete. You should run autoupdate.])dnl LT_LANG(Fortran 77)]) m4trace:m4/libtool.m4:895: -1- AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) m4trace:m4/libtool.m4:895: -1- AC_DEFUN([AC_LIBTOOL_FC], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_FC' is obsolete. You should run autoupdate.])dnl LT_LANG(Fortran)]) m4trace:m4/libtool.m4:896: -1- AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) m4trace:m4/libtool.m4:896: -1- AC_DEFUN([AC_LIBTOOL_GCJ], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_GCJ' is obsolete. You should run autoupdate.])dnl LT_LANG(Java)]) m4trace:m4/libtool.m4:897: -1- AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) m4trace:m4/libtool.m4:897: -1- AC_DEFUN([AC_LIBTOOL_RC], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_RC' is obsolete. You should run autoupdate.])dnl LT_LANG(Windows Resource)]) m4trace:m4/libtool.m4:1225: -1- 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.])]) m4trace:m4/libtool.m4:1502: -1- 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 ]) m4trace:m4/libtool.m4:1544: -1- AU_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [m4_if($#, 0, [_LT_COMPILER_OPTION], [_LT_COMPILER_OPTION($@)])]) m4trace:m4/libtool.m4:1544: -1- AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_COMPILER_OPTION' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [_LT_COMPILER_OPTION], [_LT_COMPILER_OPTION($@)])]) m4trace:m4/libtool.m4:1553: -1- 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 ]) m4trace:m4/libtool.m4:1588: -1- AU_DEFUN([AC_LIBTOOL_LINKER_OPTION], [m4_if($#, 0, [_LT_LINKER_OPTION], [_LT_LINKER_OPTION($@)])]) m4trace:m4/libtool.m4:1588: -1- AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_LINKER_OPTION' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [_LT_LINKER_OPTION], [_LT_LINKER_OPTION($@)])]) m4trace:m4/libtool.m4:1595: -1- 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?]) ]) m4trace:m4/libtool.m4:1733: -1- AU_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [m4_if($#, 0, [LT_CMD_MAX_LEN], [LT_CMD_MAX_LEN($@)])]) m4trace:m4/libtool.m4:1733: -1- AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_SYS_MAX_CMD_LEN' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_CMD_MAX_LEN], [LT_CMD_MAX_LEN($@)])]) m4trace:m4/libtool.m4:1844: -1- 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]) ]) m4trace:m4/libtool.m4:1961: -1- AU_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [m4_if($#, 0, [LT_SYS_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF($@)])]) m4trace:m4/libtool.m4:1961: -1- AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_DLOPEN_SELF' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_SYS_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF($@)])]) m4trace:m4/libtool.m4:2934: -1- 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 ]) m4trace:m4/libtool.m4:2996: -1- AU_DEFUN([AC_PATH_TOOL_PREFIX], [m4_if($#, 0, [_LT_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX($@)])]) m4trace:m4/libtool.m4:2996: -1- AC_DEFUN([AC_PATH_TOOL_PREFIX], [AC_DIAGNOSE([obsolete], [The macro `AC_PATH_TOOL_PREFIX' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [_LT_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX($@)])]) m4trace:m4/libtool.m4:3019: -1- 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 | 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*]) ]) m4trace:m4/libtool.m4:3493: -1- AU_DEFUN([AM_PROG_NM], [m4_if($#, 0, [LT_PATH_NM], [LT_PATH_NM($@)])]) m4trace:m4/libtool.m4:3493: -1- AC_DEFUN([AM_PROG_NM], [AC_DIAGNOSE([obsolete], [The macro `AM_PROG_NM' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_PATH_NM], [LT_PATH_NM($@)])]) m4trace:m4/libtool.m4:3494: -1- AU_DEFUN([AC_PROG_NM], [m4_if($#, 0, [LT_PATH_NM], [LT_PATH_NM($@)])]) m4trace:m4/libtool.m4:3494: -1- AC_DEFUN([AC_PROG_NM], [AC_DIAGNOSE([obsolete], [The macro `AC_PROG_NM' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_PATH_NM], [LT_PATH_NM($@)])]) m4trace:m4/libtool.m4:3564: -1- 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]) ]) m4trace:m4/libtool.m4:3583: -1- AU_DEFUN([AC_CHECK_LIBM], [m4_if($#, 0, [LT_LIB_M], [LT_LIB_M($@)])]) m4trace:m4/libtool.m4:3583: -1- AC_DEFUN([AC_CHECK_LIBM], [AC_DIAGNOSE([obsolete], [The macro `AC_CHECK_LIBM' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_LIB_M], [LT_LIB_M($@)])]) m4trace:m4/libtool.m4:7626: -1- 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 ]) m4trace:m4/libtool.m4:7635: -1- AU_DEFUN([LT_AC_PROG_GCJ], [m4_if($#, 0, [LT_PROG_GCJ], [LT_PROG_GCJ($@)])]) m4trace:m4/libtool.m4:7635: -1- AC_DEFUN([LT_AC_PROG_GCJ], [AC_DIAGNOSE([obsolete], [The macro `LT_AC_PROG_GCJ' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_PROG_GCJ], [LT_PROG_GCJ($@)])]) m4trace:m4/libtool.m4:7642: -1- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) m4trace:m4/libtool.m4:7649: -1- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) m4trace:m4/libtool.m4:7654: -1- AU_DEFUN([LT_AC_PROG_RC], [m4_if($#, 0, [LT_PROG_RC], [LT_PROG_RC($@)])]) m4trace:m4/libtool.m4:7654: -1- AC_DEFUN([LT_AC_PROG_RC], [AC_DIAGNOSE([obsolete], [The macro `LT_AC_PROG_RC' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [LT_PROG_RC], [LT_PROG_RC($@)])]) m4trace:m4/libtool.m4:7774: -1- AU_DEFUN([LT_AC_PROG_SED], [m4_if($#, 0, [AC_PROG_SED], [AC_PROG_SED($@)])]) m4trace:m4/libtool.m4:7774: -1- AC_DEFUN([LT_AC_PROG_SED], [AC_DIAGNOSE([obsolete], [The macro `LT_AC_PROG_SED' is obsolete. You should run autoupdate.])dnl m4_if($#, 0, [AC_PROG_SED], [AC_PROG_SED($@)])]) m4trace:m4/ltoptions.m4:14: -1- AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) m4trace:m4/ltoptions.m4:111: -1- 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.]) ]) m4trace:m4/ltoptions.m4:111: -1- AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_DLOPEN' is obsolete. You should run autoupdate.])dnl _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.]) ]) m4trace:m4/ltoptions.m4:146: -1- 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.]) ]) m4trace:m4/ltoptions.m4:146: -1- AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_WIN32_DLL' is obsolete. You should run autoupdate.])dnl 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.]) ]) m4trace:m4/ltoptions.m4:195: -1- AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) m4trace:m4/ltoptions.m4:199: -1- AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) m4trace:m4/ltoptions.m4:203: -1- AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) m4trace:m4/ltoptions.m4:203: -1- AC_DEFUN([AM_ENABLE_SHARED], [AC_DIAGNOSE([obsolete], [The macro `AM_ENABLE_SHARED' is obsolete. You should run autoupdate.])dnl AC_ENABLE_SHARED($@)]) m4trace:m4/ltoptions.m4:204: -1- AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) m4trace:m4/ltoptions.m4:204: -1- AC_DEFUN([AM_DISABLE_SHARED], [AC_DIAGNOSE([obsolete], [The macro `AM_DISABLE_SHARED' is obsolete. You should run autoupdate.])dnl AC_DISABLE_SHARED($@)]) m4trace:m4/ltoptions.m4:249: -1- AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) m4trace:m4/ltoptions.m4:253: -1- AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) m4trace:m4/ltoptions.m4:257: -1- AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) m4trace:m4/ltoptions.m4:257: -1- AC_DEFUN([AM_ENABLE_STATIC], [AC_DIAGNOSE([obsolete], [The macro `AM_ENABLE_STATIC' is obsolete. You should run autoupdate.])dnl AC_ENABLE_STATIC($@)]) m4trace:m4/ltoptions.m4:258: -1- AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) m4trace:m4/ltoptions.m4:258: -1- AC_DEFUN([AM_DISABLE_STATIC], [AC_DIAGNOSE([obsolete], [The macro `AM_DISABLE_STATIC' is obsolete. You should run autoupdate.])dnl AC_DISABLE_STATIC($@)]) m4trace:m4/ltoptions.m4:303: -1- 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.]) ]) m4trace:m4/ltoptions.m4:303: -1- AC_DEFUN([AC_ENABLE_FAST_INSTALL], [AC_DIAGNOSE([obsolete], [The macro `AC_ENABLE_FAST_INSTALL' is obsolete. You should run autoupdate.])dnl _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.]) ]) m4trace:m4/ltoptions.m4:310: -1- 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.]) ]) m4trace:m4/ltoptions.m4:310: -1- AC_DEFUN([AC_DISABLE_FAST_INSTALL], [AC_DIAGNOSE([obsolete], [The macro `AC_DISABLE_FAST_INSTALL' is obsolete. You should run autoupdate.])dnl _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.]) ]) m4trace:m4/ltoptions.m4:358: -1- 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.]) ]) m4trace:m4/ltoptions.m4:358: -1- AC_DEFUN([AC_LIBTOOL_PICMODE], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_PICMODE' is obsolete. You should run autoupdate.])dnl _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.]) ]) m4trace:m4/ltsugar.m4:13: -1- AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) m4trace:m4/ltversion.m4:18: -1- 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) ]) m4trace:m4/lt~obsolete.m4:36: -1- AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4trace:m4/lt~obsolete.m4:40: -1- AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH]) m4trace:m4/lt~obsolete.m4:41: -1- AC_DEFUN([_LT_AC_SHELL_INIT]) m4trace:m4/lt~obsolete.m4:42: -1- AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX]) m4trace:m4/lt~obsolete.m4:44: -1- AC_DEFUN([_LT_AC_TAGVAR]) m4trace:m4/lt~obsolete.m4:45: -1- AC_DEFUN([AC_LTDL_ENABLE_INSTALL]) m4trace:m4/lt~obsolete.m4:46: -1- AC_DEFUN([AC_LTDL_PREOPEN]) m4trace:m4/lt~obsolete.m4:47: -1- AC_DEFUN([_LT_AC_SYS_COMPILER]) m4trace:m4/lt~obsolete.m4:48: -1- AC_DEFUN([_LT_AC_LOCK]) m4trace:m4/lt~obsolete.m4:49: -1- AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE]) m4trace:m4/lt~obsolete.m4:50: -1- AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF]) m4trace:m4/lt~obsolete.m4:51: -1- AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O]) m4trace:m4/lt~obsolete.m4:52: -1- AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS]) m4trace:m4/lt~obsolete.m4:53: -1- AC_DEFUN([AC_LIBTOOL_OBJDIR]) m4trace:m4/lt~obsolete.m4:54: -1- AC_DEFUN([AC_LTDL_OBJDIR]) m4trace:m4/lt~obsolete.m4:55: -1- AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH]) m4trace:m4/lt~obsolete.m4:56: -1- AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP]) m4trace:m4/lt~obsolete.m4:57: -1- AC_DEFUN([AC_PATH_MAGIC]) m4trace:m4/lt~obsolete.m4:58: -1- AC_DEFUN([AC_PROG_LD_GNU]) m4trace:m4/lt~obsolete.m4:59: -1- AC_DEFUN([AC_PROG_LD_RELOAD_FLAG]) m4trace:m4/lt~obsolete.m4:60: -1- AC_DEFUN([AC_DEPLIBS_CHECK_METHOD]) m4trace:m4/lt~obsolete.m4:61: -1- AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI]) m4trace:m4/lt~obsolete.m4:62: -1- AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE]) m4trace:m4/lt~obsolete.m4:63: -1- AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC]) m4trace:m4/lt~obsolete.m4:64: -1- AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS]) m4trace:m4/lt~obsolete.m4:65: -1- AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP]) m4trace:m4/lt~obsolete.m4:66: -1- AC_DEFUN([LT_AC_PROG_EGREP]) m4trace:m4/lt~obsolete.m4:71: -1- AC_DEFUN([_AC_PROG_LIBTOOL]) m4trace:m4/lt~obsolete.m4:72: -1- AC_DEFUN([AC_LIBTOOL_SETUP]) m4trace:m4/lt~obsolete.m4:73: -1- AC_DEFUN([_LT_AC_CHECK_DLFCN]) m4trace:m4/lt~obsolete.m4:74: -1- AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER]) m4trace:m4/lt~obsolete.m4:75: -1- AC_DEFUN([_LT_AC_TAGCONFIG]) m4trace:m4/lt~obsolete.m4:77: -1- AC_DEFUN([_LT_AC_LANG_CXX]) m4trace:m4/lt~obsolete.m4:78: -1- AC_DEFUN([_LT_AC_LANG_F77]) m4trace:m4/lt~obsolete.m4:79: -1- AC_DEFUN([_LT_AC_LANG_GCJ]) m4trace:m4/lt~obsolete.m4:80: -1- AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG]) m4trace:m4/lt~obsolete.m4:81: -1- AC_DEFUN([_LT_AC_LANG_C_CONFIG]) m4trace:m4/lt~obsolete.m4:82: -1- AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG]) m4trace:m4/lt~obsolete.m4:83: -1- AC_DEFUN([_LT_AC_LANG_CXX_CONFIG]) m4trace:m4/lt~obsolete.m4:84: -1- AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG]) m4trace:m4/lt~obsolete.m4:85: -1- AC_DEFUN([_LT_AC_LANG_F77_CONFIG]) m4trace:m4/lt~obsolete.m4:86: -1- AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG]) m4trace:m4/lt~obsolete.m4:87: -1- AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG]) m4trace:m4/lt~obsolete.m4:88: -1- AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG]) m4trace:m4/lt~obsolete.m4:89: -1- AC_DEFUN([_LT_AC_LANG_RC_CONFIG]) m4trace:m4/lt~obsolete.m4:90: -1- AC_DEFUN([AC_LIBTOOL_CONFIG]) m4trace:m4/lt~obsolete.m4:91: -1- AC_DEFUN([_LT_AC_FILE_LTDLL_C]) m4trace:m4/lt~obsolete.m4:93: -1- AC_DEFUN([_LT_AC_PROG_CXXCPP]) m4trace:m4/lt~obsolete.m4:96: -1- AC_DEFUN([_LT_PROG_F77]) m4trace:m4/lt~obsolete.m4:97: -1- AC_DEFUN([_LT_PROG_FC]) m4trace:m4/lt~obsolete.m4:98: -1- AC_DEFUN([_LT_PROG_CXX]) m4trace:m4/vmtools.m4:53: -1- AC_DEFUN([AC_VMW_CHECK_LIB], [ AC_REQUIRE([AC_CHECK_LIB]) dnl AC_REQUIRE([AC_CHECK_HEADER]) dnl if test -z "$1"; then AC_MSG_ERROR(['library' parameter is required.']) fi if test -z "$2"; then AC_MSG_ERROR(['lvar' parameter is required.']) fi ac_vmw_have_lib=0 ac_vmw_have_lib_func=0 ac_vmw_have_lib_header=0 ac_vmw_custom_libs= # # First, try any user-defined CUSTOM_* flags. # if test -n "${CUSTOM_$2_CPPFLAGS}" || test -n "${CUSTOM_$2_LIBS}"; then ac_vmw_custom_libs="${CUSTOM_$2_LIBS} -l$1" if test -n "$6"; then ORIGINAL_CPPFLAGS="$CPPFLAGS" CPPFLAGS="${CUSTOM_$2_CPPFLAGS} $CPPFLAGS" AC_CHECK_HEADER([$6], [ac_vmw_have_lib_header=1]) CPPFLAGS="$ORIGINAL_CPPFLAGS" else ac_vmw_have_lib_header=1 fi # Check a specific function in the library if requested. # If it hasn't, just pick a random function from libc, just to make # sure the linker can find the library being tested. if test $ac_vmw_have_lib_header -eq 1; then if test -n "$7"; then ac_vmw_function=$7 else ac_vmw_function=strlen fi AC_CHECK_LIB( [$1], [$ac_vmw_function], [ac_vmw_have_lib_func=1], [], [$ac_vmw_custom_libs]) fi if test $ac_vmw_have_lib_func -eq 1 && test $ac_vmw_have_lib_header -eq 1; then $2_CPPFLAGS="${CUSTOM_$2_CPPFLAGS}" $2_LIBS="$ac_vmw_custom_libs" ac_vmw_have_lib=1 fi fi # If that didn't work, try with pkg-config. if test $ac_vmw_have_lib -eq 0 && test "$HAVE_PKG_CONFIG" = "yes" && test -n "$3"; then if test -n "$5"; then AC_MSG_CHECKING([for $3 >= $5 (via pkg-config)]) if pkg-config --exists '$3 >= $5'; then ac_vmw_have_lib=1 fi else AC_MSG_CHECKING([for $3 (via pkg-config)]) if pkg-config --exists '$3'; then ac_vmw_have_lib=1 fi fi if test $ac_vmw_have_lib -eq 1; then # Sometimes pkg-config might fail; for example, "pkg-config gtk+-2.0 --cflags" # fails on OpenSolaris B71. So be pessimistic. ac_vmw_cppflags="`pkg-config --cflags $3`" ac_vmw_ret1=$? ac_vmw_libs="`pkg-config --libs $3`" ac_vmw_ret2=$? if test $ac_vmw_ret1 -eq 0 && test $ac_vmw_ret2 -eq 0; then AC_MSG_RESULT([yes]) $2_CPPFLAGS="$ac_vmw_cppflags" $2_LIBS="$ac_vmw_libs" else AC_MSG_RESULT([no]) fi else AC_MSG_RESULT([no]) fi fi # If we still haven't found the lib, try with the library's custom "config" script. # Before checking, flush the AC_PATH_PROG cached variable. unset ac_cv_path_ac_vmw_lib_cfg unset ac_vmw_lib_cfg if test $ac_vmw_have_lib -eq 0 && test -n "$4"; then AC_PATH_PROG([ac_vmw_lib_cfg], [$4], [no]) if test "$ac_vmw_lib_cfg" != "no"; then # XXX: icu-config does not follow the "--cflags" and "--libs" convention, # so single it out here to avoid having to replicate all the rest of the # logic elsewhere. if test `basename "$ac_vmw_lib_cfg"` = "icu-config"; then $2_CPPFLAGS="`$ac_vmw_lib_cfg --cppflags`" $2_LIBS="`$ac_vmw_lib_cfg --ldflags`" else $2_CPPFLAGS="`$ac_vmw_lib_cfg --cflags`" $2_LIBS="`$ac_vmw_lib_cfg --libs`" fi ac_vmw_have_lib=1 fi fi # Finish by executing the user provided action. The call to "true" is needed # because the actions are optional, and we need something inside the block. if test $ac_vmw_have_lib -eq 1; then AC_SUBST([$2_CPPFLAGS]) AC_SUBST([$2_LIBS]) true $8 else true $9 fi ]) m4trace:m4/vmtools.m4:205: -1- AC_DEFUN([AC_VMW_CHECK_LIBXX], [ AC_REQUIRE([AC_VMW_CHECK_LIB]) AC_LANG_PUSH([C++]) AC_VMW_CHECK_LIB([$1], [$2], [$3], [$4], [$5], [$6], [$7], [$8], [$9]) AC_LANG_POP([C++]) ]) m4trace:m4/vmtools.m4:227: -1- AC_DEFUN([AC_VMW_CHECK_X11_LIB], [ have_header=1 if test -n "$2"; then AC_CHECK_HEADER( [X11/extensions/scrnsaver.h], [], [ have_header=0; $4 ], []) fi if test $have_header = 1; then AC_CHECK_LIB( [$1], [$3], [COMMON_XLIBS="-l$1 $COMMON_XLIBS"], [$4], [$COMMON_XLIBS]) fi ]) m4trace:m4/vmtools.m4:260: -1- AC_DEFUN([AC_VMW_LIB_ERROR], [ feature="$3" if test -z "$feature"; then feature="$1" fi AC_MSG_ERROR([Cannot find $1 library. Please configure without $feature (using --without-$2), or install the $1 libraries and devel package(s).]) ]) m4trace:m4/vmtools.m4:279: -1- AC_DEFUN([AC_VMW_DEFAULT_FLAGS], [ if test -z "$CUSTOM_$1_CPPFLAGS"; then if test "$os" = freebsd; then CUSTOM_$1_CPPFLAGS="-I/usr/local/include" else CUSTOM_$1_CPPFLAGS="-I/usr/include" fi if test -n "$2"; then CUSTOM_$1_CPPFLAGS="${CUSTOM_$1_CPPFLAGS}/$2" fi fi ]) m4trace:configure.ac:43: -1- m4_pattern_forbid([^_?A[CHUM]_]) m4trace:configure.ac:43: -1- m4_pattern_forbid([_AC_]) m4trace:configure.ac:43: -1- m4_pattern_forbid([^LIBOBJS$], [do not use LIBOBJS directly, use AC_LIBOBJ (see section `AC_LIBOBJ vs LIBOBJS']) m4trace:configure.ac:43: -1- m4_pattern_allow([^AS_FLAGS$]) m4trace:configure.ac:43: -1- m4_pattern_forbid([^_?m4_]) m4trace:configure.ac:43: -1- m4_pattern_forbid([^dnl$]) m4trace:configure.ac:43: -1- m4_pattern_forbid([^_?AS_]) m4trace:configure.ac:43: -1- m4_pattern_allow([^SHELL$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PATH_SEPARATOR$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_NAME$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_TARNAME$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_VERSION$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_STRING$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_URL$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^exec_prefix$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^prefix$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^program_transform_name$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^bindir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^sbindir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^libexecdir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^datarootdir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^datadir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^sysconfdir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^sharedstatedir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^localstatedir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^includedir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^oldincludedir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^docdir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^infodir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^htmldir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^dvidir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^pdfdir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^psdir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^libdir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^localedir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^mandir$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_NAME$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_TARNAME$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_VERSION$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_STRING$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^PACKAGE_URL$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^DEFS$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^ECHO_C$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^ECHO_N$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^ECHO_T$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^LIBS$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^build_alias$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^host_alias$]) m4trace:configure.ac:43: -1- m4_pattern_allow([^target_alias$]) m4trace:configure.ac:74: -1- m4_pattern_allow([^build$]) m4trace:configure.ac:74: -1- m4_pattern_allow([^build_cpu$]) m4trace:configure.ac:74: -1- m4_pattern_allow([^build_vendor$]) m4trace:configure.ac:74: -1- m4_pattern_allow([^build_os$]) m4trace:configure.ac:74: -1- m4_pattern_allow([^host$]) m4trace:configure.ac:74: -1- m4_pattern_allow([^host_cpu$]) m4trace:configure.ac:74: -1- m4_pattern_allow([^host_vendor$]) m4trace:configure.ac:74: -1- m4_pattern_allow([^host_os$]) m4trace:configure.ac:210: -1- AM_INIT_AUTOMAKE m4trace:configure.ac:210: -1- m4_pattern_allow([^AM_[A-Z]+FLAGS$]) m4trace:configure.ac:210: -1- AM_SET_CURRENT_AUTOMAKE_VERSION m4trace:configure.ac:210: -1- AM_AUTOMAKE_VERSION([1.12.2]) m4trace:configure.ac:210: -1- _AM_AUTOCONF_VERSION([2.69]) m4trace:configure.ac:210: -1- m4_pattern_allow([^INSTALL_PROGRAM$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^INSTALL_SCRIPT$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^INSTALL_DATA$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^am__isrc$]) m4trace:configure.ac:210: -1- _AM_SUBST_NOTMAKE([am__isrc]) m4trace:configure.ac:210: -1- m4_pattern_allow([^CYGPATH_W$]) m4trace:configure.ac:210: -1- _AM_SET_OPTIONS([]) m4trace:configure.ac:210: -1- m4_pattern_allow([^PACKAGE$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^VERSION$]) m4trace:configure.ac:210: -1- _AM_IF_OPTION([no-define], [], [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])]) m4trace:configure.ac:210: -2- _AM_MANGLE_OPTION([no-define]) m4trace:configure.ac:210: -1- m4_pattern_allow([^PACKAGE$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^VERSION$]) m4trace:configure.ac:210: -1- AM_SANITY_CHECK m4trace:configure.ac:210: -1- AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) m4trace:configure.ac:210: -1- AM_MISSING_HAS_RUN m4trace:configure.ac:210: -1- AM_AUX_DIR_EXPAND m4trace:configure.ac:210: -1- m4_pattern_allow([^ACLOCAL$]) m4trace:configure.ac:210: -1- AM_MISSING_PROG([AUTOCONF], [autoconf]) m4trace:configure.ac:210: -1- m4_pattern_allow([^AUTOCONF$]) m4trace:configure.ac:210: -1- AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) m4trace:configure.ac:210: -1- m4_pattern_allow([^AUTOMAKE$]) m4trace:configure.ac:210: -1- AM_MISSING_PROG([AUTOHEADER], [autoheader]) m4trace:configure.ac:210: -1- m4_pattern_allow([^AUTOHEADER$]) m4trace:configure.ac:210: -1- AM_MISSING_PROG([MAKEINFO], [makeinfo]) m4trace:configure.ac:210: -1- m4_pattern_allow([^MAKEINFO$]) m4trace:configure.ac:210: -1- AM_PROG_INSTALL_SH m4trace:configure.ac:210: -1- m4_pattern_allow([^install_sh$]) m4trace:configure.ac:210: -1- AM_PROG_INSTALL_STRIP m4trace:configure.ac:210: -1- m4_pattern_allow([^STRIP$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^INSTALL_STRIP_PROGRAM$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^MKDIR_P$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^mkdir_p$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^AWK$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^SET_MAKE$]) m4trace:configure.ac:210: -1- AM_SET_LEADING_DOT m4trace:configure.ac:210: -1- m4_pattern_allow([^am__leading_dot$]) m4trace:configure.ac:210: -1- _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) m4trace:configure.ac:210: -2- _AM_MANGLE_OPTION([tar-ustar]) m4trace:configure.ac:210: -1- _AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])]) m4trace:configure.ac:210: -2- _AM_MANGLE_OPTION([tar-pax]) m4trace:configure.ac:210: -1- _AM_PROG_TAR([v7]) m4trace:configure.ac:210: -1- m4_pattern_allow([^AMTAR$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^am__tar$]) m4trace:configure.ac:210: -1- m4_pattern_allow([^am__untar$]) m4trace:configure.ac:210: -1- _AM_IF_OPTION([no-dependencies], [], [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl dnl Support for Objective C++ was only introduced in Autoconf 2.65, dnl but we still cater to Autoconf 2.62. m4_ifdef([AC_PROG_OBJCXX], [AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])])dnl ]) m4trace:configure.ac:210: -2- _AM_MANGLE_OPTION([no-dependencies]) m4trace:configure.ac:210: -1- _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])]) m4trace:configure.ac:210: -2- _AM_MANGLE_OPTION([silent-rules]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CFLAGS$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^LDFLAGS$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^LIBS$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^ac_ct_CC$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^EXEEXT$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^OBJEXT$]) m4trace:configure.ac:233: -1- _AM_DEPENDENCIES([CC]) m4trace:configure.ac:233: -1- AM_SET_DEPDIR m4trace:configure.ac:233: -1- m4_pattern_allow([^DEPDIR$]) m4trace:configure.ac:233: -1- AM_OUTPUT_DEPENDENCY_COMMANDS m4trace:configure.ac:233: -1- AM_MAKE_INCLUDE m4trace:configure.ac:233: -1- m4_pattern_allow([^am__include$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^am__quote$]) m4trace:configure.ac:233: -1- AM_DEP_TRACK m4trace:configure.ac:233: -1- AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) m4trace:configure.ac:233: -1- m4_pattern_allow([^AMDEP_TRUE$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^AMDEP_FALSE$]) m4trace:configure.ac:233: -1- _AM_SUBST_NOTMAKE([AMDEP_TRUE]) m4trace:configure.ac:233: -1- _AM_SUBST_NOTMAKE([AMDEP_FALSE]) m4trace:configure.ac:233: -1- m4_pattern_allow([^AMDEPBACKSLASH$]) m4trace:configure.ac:233: -1- _AM_SUBST_NOTMAKE([AMDEPBACKSLASH]) m4trace:configure.ac:233: -1- m4_pattern_allow([^am__nodep$]) m4trace:configure.ac:233: -1- _AM_SUBST_NOTMAKE([am__nodep]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CCDEPMODE$]) m4trace:configure.ac:233: -1- AM_CONDITIONAL([am__fastdepCC], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3]) m4trace:configure.ac:233: -1- m4_pattern_allow([^am__fastdepCC_TRUE$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^am__fastdepCC_FALSE$]) m4trace:configure.ac:233: -1- _AM_SUBST_NOTMAKE([am__fastdepCC_TRUE]) m4trace:configure.ac:233: -1- _AM_SUBST_NOTMAKE([am__fastdepCC_FALSE]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CPP$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:233: -1- m4_pattern_allow([^CPP$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CFLAGS$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^LDFLAGS$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^LIBS$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^ac_ct_CC$]) m4trace:configure.ac:234: -1- _AM_DEPENDENCIES([CC]) m4trace:configure.ac:234: -1- m4_pattern_allow([^CCDEPMODE$]) m4trace:configure.ac:234: -1- AM_CONDITIONAL([am__fastdepCC], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3]) m4trace:configure.ac:234: -1- m4_pattern_allow([^am__fastdepCC_TRUE$]) m4trace:configure.ac:234: -1- m4_pattern_allow([^am__fastdepCC_FALSE$]) m4trace:configure.ac:234: -1- _AM_SUBST_NOTMAKE([am__fastdepCC_TRUE]) m4trace:configure.ac:234: -1- _AM_SUBST_NOTMAKE([am__fastdepCC_FALSE]) m4trace:configure.ac:238: -1- m4_pattern_allow([^CXX$]) m4trace:configure.ac:238: -1- m4_pattern_allow([^CXXFLAGS$]) m4trace:configure.ac:238: -1- m4_pattern_allow([^LDFLAGS$]) m4trace:configure.ac:238: -1- m4_pattern_allow([^LIBS$]) m4trace:configure.ac:238: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:238: -1- m4_pattern_allow([^CXX$]) m4trace:configure.ac:238: -1- m4_pattern_allow([^ac_ct_CXX$]) m4trace:configure.ac:238: -1- _AM_DEPENDENCIES([CXX]) m4trace:configure.ac:238: -1- m4_pattern_allow([^CXXDEPMODE$]) m4trace:configure.ac:238: -1- AM_CONDITIONAL([am__fastdepCXX], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3]) m4trace:configure.ac:238: -1- m4_pattern_allow([^am__fastdepCXX_TRUE$]) m4trace:configure.ac:238: -1- m4_pattern_allow([^am__fastdepCXX_FALSE$]) m4trace:configure.ac:238: -1- _AM_SUBST_NOTMAKE([am__fastdepCXX_TRUE]) m4trace:configure.ac:238: -1- _AM_SUBST_NOTMAKE([am__fastdepCXX_FALSE]) m4trace:configure.ac:243: -1- AM_PROG_CC_C_O m4trace:configure.ac:243: -1- m4_pattern_allow([^NO_MINUS_C_MINUS_O$]) m4trace:configure.ac:247: -1- m4_pattern_allow([^SED$]) m4trace:configure.ac:248: -1- m4_pattern_allow([^LN_S$]) m4trace:configure.ac:252: -1- AC_PROG_LIBTOOL m4trace:configure.ac:252: -1- _m4_warn([obsolete], [The macro `AC_PROG_LIBTOOL' is obsolete. You should run autoupdate.], [m4/libtool.m4:107: AC_PROG_LIBTOOL is expanded from... configure.ac:252: the top level]) m4trace:configure.ac:252: -1- LT_INIT m4trace:configure.ac:252: -1- m4_pattern_forbid([^_?LT_[A-Z_]+$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$]) m4trace:configure.ac:252: -1- LTOPTIONS_VERSION m4trace:configure.ac:252: -1- LTSUGAR_VERSION m4trace:configure.ac:252: -1- LTVERSION_VERSION m4trace:configure.ac:252: -1- LTOBSOLETE_VERSION m4trace:configure.ac:252: -1- _LT_PROG_LTMAIN m4trace:configure.ac:252: -1- m4_pattern_allow([^LIBTOOL$]) m4trace:configure.ac:252: -1- _LT_PREPARE_SED_QUOTE_VARS m4trace:configure.ac:252: -1- _LT_PROG_ECHO_BACKSLASH m4trace:configure.ac:252: -1- LT_PATH_LD m4trace:configure.ac:252: -1- m4_pattern_allow([^SED$]) m4trace:configure.ac:252: -1- AC_PROG_EGREP m4trace:configure.ac:252: -1- m4_pattern_allow([^GREP$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^EGREP$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^FGREP$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^GREP$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^LD$]) m4trace:configure.ac:252: -1- LT_PATH_NM m4trace:configure.ac:252: -1- m4_pattern_allow([^DUMPBIN$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^ac_ct_DUMPBIN$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^DUMPBIN$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^NM$]) m4trace:configure.ac:252: -1- LT_CMD_MAX_LEN m4trace:configure.ac:252: -1- m4_pattern_allow([^OBJDUMP$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^OBJDUMP$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^DLLTOOL$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^DLLTOOL$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^AR$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^ac_ct_AR$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^STRIP$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^RANLIB$]) m4trace:configure.ac:252: -1- _LT_WITH_SYSROOT m4trace:configure.ac:252: -1- m4_pattern_allow([LT_OBJDIR]) m4trace:configure.ac:252: -1- m4_pattern_allow([^LT_OBJDIR$]) m4trace:configure.ac:252: -1- _LT_CC_BASENAME([$compiler]) m4trace:configure.ac:252: -1- _LT_PATH_TOOL_PREFIX([${ac_tool_prefix}file], [/usr/bin$PATH_SEPARATOR$PATH]) m4trace:configure.ac:252: -1- _LT_PATH_TOOL_PREFIX([file], [/usr/bin$PATH_SEPARATOR$PATH]) m4trace:configure.ac:252: -1- LT_SUPPORTED_TAG([CC]) m4trace:configure.ac:252: -1- _LT_COMPILER_BOILERPLATE m4trace:configure.ac:252: -1- _LT_LINKER_BOILERPLATE m4trace:configure.ac:252: -1- _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, )="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, ) -fno-rtti -fno-exceptions"]) m4trace:configure.ac:252: -1- _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, ) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, )], [$_LT_TAGVAR(lt_prog_compiler_pic, )@&t@m4_if([],[],[ -DPIC],[m4_if([],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, ) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, )=" $_LT_TAGVAR(lt_prog_compiler_pic, )" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, )= _LT_TAGVAR(lt_prog_compiler_can_build_shared, )=no]) m4trace:configure.ac:252: -1- _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], [lt_cv_prog_compiler_static_works], [$lt_tmp_static_flag], [], [_LT_TAGVAR(lt_prog_compiler_static, )=]) m4trace:configure.ac:252: -1- m4_pattern_allow([^MANIFEST_TOOL$]) m4trace:configure.ac:252: -1- _LT_REQUIRED_DARWIN_CHECKS m4trace:configure.ac:252: -1- m4_pattern_allow([^DSYMUTIL$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^NMEDIT$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^LIPO$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^OTOOL$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^OTOOL64$]) m4trace:configure.ac:252: -1- _LT_LINKER_OPTION([if $CC understands -b], [lt_cv_prog_compiler__b], [-b], [_LT_TAGVAR(archive_cmds, )='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, )='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags']) m4trace:configure.ac:252: -1- LT_SYS_DLOPEN_SELF m4trace:configure.ac:252: -1- m4_pattern_allow([^STDC_HEADERS$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^HAVE_DLFCN_H$]) m4trace:configure.ac:252: -1- LT_LANG([CXX]) m4trace:configure.ac:252: -1- LT_SUPPORTED_TAG([CXX]) m4trace:configure.ac:252: -1- m4_pattern_allow([^CXXCPP$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:252: -1- m4_pattern_allow([^CXXCPP$]) m4trace:configure.ac:252: -1- _LT_COMPILER_BOILERPLATE m4trace:configure.ac:252: -1- _LT_LINKER_BOILERPLATE m4trace:configure.ac:252: -1- _LT_CC_BASENAME([$compiler]) m4trace:configure.ac:252: -1- LT_PATH_LD m4trace:configure.ac:252: -1- m4_pattern_allow([^LD$]) m4trace:configure.ac:252: -1- _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, CXX) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, CXX)], [$_LT_TAGVAR(lt_prog_compiler_pic, CXX)@&t@m4_if([CXX],[],[ -DPIC],[m4_if([CXX],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, CXX) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, CXX)=" $_LT_TAGVAR(lt_prog_compiler_pic, CXX)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, CXX)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, CXX)=no]) m4trace:configure.ac:252: -1- _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], [lt_cv_prog_compiler_static_works_CXX], [$lt_tmp_static_flag], [], [_LT_TAGVAR(lt_prog_compiler_static, CXX)=]) m4trace:configure.ac:258: -1- m4_pattern_allow([^HAVE_PKG_CONFIG$]) m4trace:configure.ac:272: -1- m4_pattern_allow([^XMKMF$]) m4trace:configure.ac:272: -1- m4_pattern_allow([^X_DISPLAY_MISSING$]) m4trace:configure.ac:272: -1- m4_pattern_allow([^X_CFLAGS$]) m4trace:configure.ac:272: -1- m4_pattern_allow([^X_PRE_LIBS$]) m4trace:configure.ac:272: -1- m4_pattern_allow([^X_LIBS$]) m4trace:configure.ac:272: -1- m4_pattern_allow([^X_EXTRA_LIBS$]) m4trace:configure.ac:295: -1- AC_VMW_CHECK_LIB([glib-2.0], [GLIB2], [glib-2.0], [], [2.6.0], [glib.h], [g_key_file_new], [], [AC_MSG_ERROR([glib >= 2.6.0 is required.])]) m4trace:configure.ac:295: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:295: -1- m4_pattern_allow([^GLIB2_CPPFLAGS$]) m4trace:configure.ac:295: -1- m4_pattern_allow([^GLIB2_LIBS$]) m4trace:configure.ac:304: -1- AC_VMW_CHECK_LIB([gmodule-2.0], [GMODULE], [gmodule-2.0], [], [2.6.0], [], [], [], [AC_MSG_ERROR([gmodule >= 2.6.0 is required.])]) m4trace:configure.ac:304: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:304: -1- m4_pattern_allow([^GMODULE_CPPFLAGS$]) m4trace:configure.ac:304: -1- m4_pattern_allow([^GMODULE_LIBS$]) m4trace:configure.ac:313: -1- AC_VMW_CHECK_LIB([gobject-2.0], [GOBJECT], [gobject-2.0], [], [2.6.0], [glib-object.h], [], [], [AC_MSG_ERROR([gobject >= 2.6.0 is required.])]) m4trace:configure.ac:313: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:313: -1- m4_pattern_allow([^GOBJECT_CPPFLAGS$]) m4trace:configure.ac:313: -1- m4_pattern_allow([^GOBJECT_LIBS$]) m4trace:configure.ac:322: -1- AC_VMW_CHECK_LIB([gthread-2.0], [GTHREAD], [gthread-2.0], [], [2.6.0], [], [], [], [AC_MSG_ERROR([glib >= 2.6.0 is required.])]) m4trace:configure.ac:322: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:322: -1- m4_pattern_allow([^GTHREAD_CPPFLAGS$]) m4trace:configure.ac:322: -1- m4_pattern_allow([^GTHREAD_LIBS$]) m4trace:configure.ac:331: -1- m4_pattern_allow([^have_genmarshal$]) m4trace:configure.ac:344: -1- AC_VMW_CHECK_LIB([glib-2.0], [GLIB2], [glib-2.0], [], [2.14.0], [glib.h], [g_regex_new], [have_glib_2_14=yes], [AC_MSG_WARN([glib is not recent enough, some features will be disabled.])]) m4trace:configure.ac:344: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:344: -1- m4_pattern_allow([^GLIB2_CPPFLAGS$]) m4trace:configure.ac:344: -1- m4_pattern_allow([^GLIB2_LIBS$]) m4trace:configure.ac:358: -1- AC_VMW_CHECK_LIB([fuse], [FUSE], [fuse], [], [], [fuse.h], [fuse_main], [have_fuse=yes], [have_fuse=no; AC_MSG_WARN([Fuse is missing, vmblock-fuse will be disabled.])]) m4trace:configure.ac:358: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:358: -1- m4_pattern_allow([^FUSE_CPPFLAGS$]) m4trace:configure.ac:358: -1- m4_pattern_allow([^FUSE_LIBS$]) m4trace:configure.ac:379: -1- AC_VMW_DEFAULT_FLAGS([PAM]) m4trace:configure.ac:380: -1- AC_VMW_CHECK_LIB([pam], [PAM], [], [], [], [security/pam_appl.h], [pam_start], [PAM_CPPFLAGS="$PAM_CPPFLAGS -DUSE_PAM"], [AC_VMW_LIB_ERROR([PAM], [pam])]) m4trace:configure.ac:380: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:380: -1- m4_pattern_allow([^PAM_CPPFLAGS$]) m4trace:configure.ac:380: -1- m4_pattern_allow([^PAM_LIBS$]) m4trace:configure.ac:380: -1- AC_VMW_LIB_ERROR([PAM], [pam]) m4trace:configure.ac:395: -1- AC_VMW_DEFAULT_FLAGS([CUNIT]) m4trace:configure.ac:396: -1- AC_VMW_CHECK_LIB([cunit], [CUNIT], [], [], [], [CUnit/CUnit.h], [CU_initialize_registry], [have_cunit=yes], [have_cunit=no]) m4trace:configure.ac:396: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:396: -1- m4_pattern_allow([^CUNIT_CPPFLAGS$]) m4trace:configure.ac:396: -1- m4_pattern_allow([^CUNIT_LIBS$]) m4trace:configure.ac:407: -1- AC_VMW_LIB_ERROR([CUNIT], [cunit]) m4trace:configure.ac:503: -1- m4_pattern_allow([^HAVE_X11_EXTENSIONS_XCOMPOSITE_H$]) m4trace:configure.ac:515: -1- AC_VMW_CHECK_LIB([gtk-x11-2.0], [GTK], [gtk+-2.0], [], [2.4.0], [gtk/gtk.h], [gdk_display_get_default_group], [GTK_CPPFLAGS="$GTK_CPPFLAGS -DGTK2"], [AC_MSG_ERROR([Gtk+ 2.0 library not found or too old. Please configure without Gtk+ support (using --without-gtk2) or install the Gtk+ 2.0 devel package.])]) m4trace:configure.ac:515: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:515: -1- m4_pattern_allow([^GTK_CPPFLAGS$]) m4trace:configure.ac:515: -1- m4_pattern_allow([^GTK_LIBS$]) m4trace:configure.ac:532: -1- AC_VMW_CHECK_LIBXX([gtkmm-2.4], [GTKMM], [gtkmm-2.4], [], [2.4.0], [gtkmm.h], [], [GTKMM_CPPFLAGS="$GTKMM_CPPFLAGS -DHAVE_GTKMM"], [AC_MSG_ERROR([gtkmm library not found. Please install the libgtkmm devel package(s), or re-configure using --without-gtkmm.])]) m4trace:configure.ac:532: -1- AC_VMW_CHECK_LIB([gtkmm-2.4], [GTKMM], [gtkmm-2.4], [], [2.4.0], [gtkmm.h], [], [GTKMM_CPPFLAGS="$GTKMM_CPPFLAGS -DHAVE_GTKMM"], [AC_MSG_ERROR([gtkmm library not found. Please install the libgtkmm devel package(s), or re-configure using --without-gtkmm.])]) m4trace:configure.ac:532: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:532: -1- m4_pattern_allow([^GTKMM_CPPFLAGS$]) m4trace:configure.ac:532: -1- m4_pattern_allow([^GTKMM_LIBS$]) m4trace:configure.ac:551: -1- m4_pattern_allow([^HAVE_DLOPEN$]) m4trace:configure.ac:562: -1- m4_pattern_allow([^HAVE_ECVT$]) m4trace:configure.ac:563: -1- m4_pattern_allow([^HAVE_FCVT$]) m4trace:configure.ac:617: -1- AC_VMW_CHECK_LIB([$CUSTOM_PROCPS_NAME], [PROCPS], [], [], [], [], [getstat], [ have_procps=yes; ], []) m4trace:configure.ac:617: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:617: -1- m4_pattern_allow([^PROCPS_CPPFLAGS$]) m4trace:configure.ac:617: -1- m4_pattern_allow([^PROCPS_LIBS$]) m4trace:configure.ac:630: -1- AC_VMW_CHECK_LIB([proc-3.2.8], [PROCPS], [], [], [], [], [getstat], [ have_procps=yes; ], []) m4trace:configure.ac:630: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:630: -1- m4_pattern_allow([^PROCPS_CPPFLAGS$]) m4trace:configure.ac:630: -1- m4_pattern_allow([^PROCPS_LIBS$]) m4trace:configure.ac:644: -1- AC_VMW_CHECK_LIB([proc-3.2.7], [PROCPS], [], [], [], [], [getstat], [], [AC_MSG_ERROR([libproc not found. Please configure without procps (using --without-procps) or install procps - http://procps.sourceforge.net])]) m4trace:configure.ac:644: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:644: -1- m4_pattern_allow([^PROCPS_CPPFLAGS$]) m4trace:configure.ac:644: -1- m4_pattern_allow([^PROCPS_LIBS$]) m4trace:configure.ac:657: -1- m4_pattern_allow([^NO_PROCPS$]) m4trace:configure.ac:671: -1- AC_VMW_CHECK_LIB([dumbnet], [DNET], [], [dumbnet-config], [], [dumbnet.h], [intf_open], [have_dnet="yes"; AC_DEFINE([DNET_IS_DUMBNET], 1, [Define to 1 if substituting Debian's libdumbnet for libdnet.])], []) m4trace:configure.ac:671: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:671: -1- m4_pattern_allow([^DNET_CPPFLAGS$]) m4trace:configure.ac:671: -1- m4_pattern_allow([^DNET_LIBS$]) m4trace:configure.ac:671: -1- m4_pattern_allow([^DNET_IS_DUMBNET$]) m4trace:configure.ac:683: -1- AC_VMW_CHECK_LIB([dnet], [DNET], [], [dnet-config], [], [dnet.h], [intf_open], [have_dnet="yes"], []) m4trace:configure.ac:683: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:683: -1- m4_pattern_allow([^DNET_CPPFLAGS$]) m4trace:configure.ac:683: -1- m4_pattern_allow([^DNET_LIBS$]) m4trace:configure.ac:701: -1- m4_pattern_allow([^NO_DNET$]) m4trace:configure.ac:711: -1- m4_pattern_allow([^have_cxx$]) m4trace:configure.ac:718: -1- AC_VMW_CHECK_LIBXX([icuuc], [ICU], [], [icu-config], [], [unicode/utf.h], [], [ICU_CPPFLAGS="$ICU_CPPFLAGS -DUSE_ICU"], [AC_MSG_ERROR([ICU library not found. Please configure without ICU (using --without-icu) or install ICU - http://www.icu-project.org])]) m4trace:configure.ac:718: -1- AC_VMW_CHECK_LIB([icuuc], [ICU], [], [icu-config], [], [unicode/utf.h], [], [ICU_CPPFLAGS="$ICU_CPPFLAGS -DUSE_ICU"], [AC_MSG_ERROR([ICU library not found. Please configure without ICU (using --without-icu) or install ICU - http://www.icu-project.org])]) m4trace:configure.ac:718: -1- m4_pattern_allow([^ac_vmw_lib_cfg$]) m4trace:configure.ac:718: -1- m4_pattern_allow([^ICU_CPPFLAGS$]) m4trace:configure.ac:718: -1- m4_pattern_allow([^ICU_LIBS$]) m4trace:configure.ac:732: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from... configure.ac:732: the top level]) m4trace:configure.ac:751: -1- m4_pattern_allow([^RPCGEN$]) m4trace:configure.ac:760: -1- m4_pattern_allow([^HAVE_CRYPT_H$]) m4trace:configure.ac:761: -1- m4_pattern_allow([^HAVE_INTTYPES_H$]) m4trace:configure.ac:762: -1- m4_pattern_allow([^HAVE_STDINT_H$]) m4trace:configure.ac:763: -1- m4_pattern_allow([^HAVE_STDLIB_H$]) m4trace:configure.ac:764: -1- m4_pattern_allow([^HAVE_WCHAR_H$]) m4trace:configure.ac:765: -1- m4_pattern_allow([^HAVE_SYS_INTTYPES_H$]) m4trace:configure.ac:766: -1- m4_pattern_allow([^HAVE_SYS_IO_H$]) m4trace:configure.ac:767: -1- m4_pattern_allow([^HAVE_SYS_PARAM_H$]) m4trace:configure.ac:768: -1- m4_pattern_allow([^HAVE_SYS_SYSINFO_H$]) m4trace:configure.ac:769: -1- m4_pattern_allow([^HAVE_SYS_TYPES_H$]) m4trace:configure.ac:770: -1- m4_pattern_allow([^HAVE_SYS_USER_H$]) m4trace:configure.ac:778: -1- m4_pattern_allow([^HAVE_SYS_VFS_H$]) m4trace:configure.ac:779: -1- m4_pattern_allow([^HAVE_SYSLIMITS_H$]) m4trace:configure.ac:780: -1- m4_pattern_allow([^HAVE_UNWIND_H$]) m4trace:configure.ac:816: -1- m4_pattern_allow([^HAVE__BOOL$]) m4trace:configure.ac:816: -1- m4_pattern_allow([^HAVE_STDBOOL_H$]) m4trace:configure.ac:817: -1- m4_pattern_allow([^const$]) m4trace:configure.ac:818: -1- m4_pattern_allow([^uid_t$]) m4trace:configure.ac:818: -1- m4_pattern_allow([^gid_t$]) m4trace:configure.ac:820: -1- m4_pattern_allow([^mode_t$]) m4trace:configure.ac:821: -1- m4_pattern_allow([^off_t$]) m4trace:configure.ac:822: -1- m4_pattern_allow([^pid_t$]) m4trace:configure.ac:823: -1- m4_pattern_allow([^size_t$]) m4trace:configure.ac:824: -1- m4_pattern_allow([^HAVE_STRUCT_STAT_ST_RDEV$]) m4trace:configure.ac:825: -1- m4_pattern_allow([^TIME_WITH_SYS_TIME$]) m4trace:configure.ac:826: -1- m4_pattern_allow([^TM_IN_SYS_TIME$]) m4trace:configure.ac:827: -1- m4_pattern_allow([^volatile$]) m4trace:configure.ac:844: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from... configure.ac:844: the top level]) m4trace:configure.ac:861: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from... configure.ac:861: the top level]) m4trace:configure.ac:872: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from... configure.ac:872: the top level]) m4trace:configure.ac:891: -1- m4_pattern_allow([^have_doxygen$]) m4trace:configure.ac:898: -1- m4_pattern_allow([^DOT$]) m4trace:configure.ac:905: -1- m4_pattern_allow([^DOT$]) m4trace:configure.ac:906: -1- m4_pattern_allow([^HAVE_DOT$]) m4trace:configure.ac:908: -1- m4_pattern_allow([^MSCGEN$]) m4trace:configure.ac:916: -1- m4_pattern_allow([^MSCGEN_DIR$]) m4trace:configure.ac:1016: -1- AM_CONDITIONAL([BUILD_HGFSMOUNTER], [test "$buildHgfsmounter" = "yes"]) m4trace:configure.ac:1016: -1- m4_pattern_allow([^BUILD_HGFSMOUNTER_TRUE$]) m4trace:configure.ac:1016: -1- m4_pattern_allow([^BUILD_HGFSMOUNTER_FALSE$]) m4trace:configure.ac:1016: -1- _AM_SUBST_NOTMAKE([BUILD_HGFSMOUNTER_TRUE]) m4trace:configure.ac:1016: -1- _AM_SUBST_NOTMAKE([BUILD_HGFSMOUNTER_FALSE]) m4trace:configure.ac:1017: -1- AM_CONDITIONAL([LINUX], [test "$os" = "linux"]) m4trace:configure.ac:1017: -1- m4_pattern_allow([^LINUX_TRUE$]) m4trace:configure.ac:1017: -1- m4_pattern_allow([^LINUX_FALSE$]) m4trace:configure.ac:1017: -1- _AM_SUBST_NOTMAKE([LINUX_TRUE]) m4trace:configure.ac:1017: -1- _AM_SUBST_NOTMAKE([LINUX_FALSE]) m4trace:configure.ac:1018: -1- AM_CONDITIONAL([SOLARIS], [test "$os" = "solaris"]) m4trace:configure.ac:1018: -1- m4_pattern_allow([^SOLARIS_TRUE$]) m4trace:configure.ac:1018: -1- m4_pattern_allow([^SOLARIS_FALSE$]) m4trace:configure.ac:1018: -1- _AM_SUBST_NOTMAKE([SOLARIS_TRUE]) m4trace:configure.ac:1018: -1- _AM_SUBST_NOTMAKE([SOLARIS_FALSE]) m4trace:configure.ac:1019: -1- AM_CONDITIONAL([FREEBSD], [test "$os" = "freebsd"]) m4trace:configure.ac:1019: -1- m4_pattern_allow([^FREEBSD_TRUE$]) m4trace:configure.ac:1019: -1- m4_pattern_allow([^FREEBSD_FALSE$]) m4trace:configure.ac:1019: -1- _AM_SUBST_NOTMAKE([FREEBSD_TRUE]) m4trace:configure.ac:1019: -1- _AM_SUBST_NOTMAKE([FREEBSD_FALSE]) m4trace:configure.ac:1020: -1- AM_CONDITIONAL([FREEBSD_CUSTOM_SYSDIR], [test "$os" = "freebsd" -a -n "$SYSDIR"]) m4trace:configure.ac:1020: -1- m4_pattern_allow([^FREEBSD_CUSTOM_SYSDIR_TRUE$]) m4trace:configure.ac:1020: -1- m4_pattern_allow([^FREEBSD_CUSTOM_SYSDIR_FALSE$]) m4trace:configure.ac:1020: -1- _AM_SUBST_NOTMAKE([FREEBSD_CUSTOM_SYSDIR_TRUE]) m4trace:configure.ac:1020: -1- _AM_SUBST_NOTMAKE([FREEBSD_CUSTOM_SYSDIR_FALSE]) m4trace:configure.ac:1021: -1- AM_CONDITIONAL([THIRTY_TWO_BIT_USERSPACE], [test "$userSpaceBitness" = "32"]) m4trace:configure.ac:1021: -1- m4_pattern_allow([^THIRTY_TWO_BIT_USERSPACE_TRUE$]) m4trace:configure.ac:1021: -1- m4_pattern_allow([^THIRTY_TWO_BIT_USERSPACE_FALSE$]) m4trace:configure.ac:1021: -1- _AM_SUBST_NOTMAKE([THIRTY_TWO_BIT_USERSPACE_TRUE]) m4trace:configure.ac:1021: -1- _AM_SUBST_NOTMAKE([THIRTY_TWO_BIT_USERSPACE_FALSE]) m4trace:configure.ac:1022: -1- AM_CONDITIONAL([HAVE_X11], [test "$have_x" = "yes"]) m4trace:configure.ac:1022: -1- m4_pattern_allow([^HAVE_X11_TRUE$]) m4trace:configure.ac:1022: -1- m4_pattern_allow([^HAVE_X11_FALSE$]) m4trace:configure.ac:1022: -1- _AM_SUBST_NOTMAKE([HAVE_X11_TRUE]) m4trace:configure.ac:1022: -1- _AM_SUBST_NOTMAKE([HAVE_X11_FALSE]) m4trace:configure.ac:1023: -1- AM_CONDITIONAL([HAVE_ICU], [test "$with_icu" = "yes"]) m4trace:configure.ac:1023: -1- m4_pattern_allow([^HAVE_ICU_TRUE$]) m4trace:configure.ac:1023: -1- m4_pattern_allow([^HAVE_ICU_FALSE$]) m4trace:configure.ac:1023: -1- _AM_SUBST_NOTMAKE([HAVE_ICU_TRUE]) m4trace:configure.ac:1023: -1- _AM_SUBST_NOTMAKE([HAVE_ICU_FALSE]) m4trace:configure.ac:1024: -1- AM_CONDITIONAL([WITH_KERNEL_MODULES], [test "$with_kernel_modules" = "yes"]) m4trace:configure.ac:1024: -1- m4_pattern_allow([^WITH_KERNEL_MODULES_TRUE$]) m4trace:configure.ac:1024: -1- m4_pattern_allow([^WITH_KERNEL_MODULES_FALSE$]) m4trace:configure.ac:1024: -1- _AM_SUBST_NOTMAKE([WITH_KERNEL_MODULES_TRUE]) m4trace:configure.ac:1024: -1- _AM_SUBST_NOTMAKE([WITH_KERNEL_MODULES_FALSE]) m4trace:configure.ac:1025: -1- AM_CONDITIONAL([HAVE_XSM], [test "$have_xsm" = "yes"]) m4trace:configure.ac:1025: -1- m4_pattern_allow([^HAVE_XSM_TRUE$]) m4trace:configure.ac:1025: -1- m4_pattern_allow([^HAVE_XSM_FALSE$]) m4trace:configure.ac:1025: -1- _AM_SUBST_NOTMAKE([HAVE_XSM_TRUE]) m4trace:configure.ac:1025: -1- _AM_SUBST_NOTMAKE([HAVE_XSM_FALSE]) m4trace:configure.ac:1026: -1- AM_CONDITIONAL([HAVE_XCOMPOSITE], [test "$have_xcomposite" = "yes"]) m4trace:configure.ac:1026: -1- m4_pattern_allow([^HAVE_XCOMPOSITE_TRUE$]) m4trace:configure.ac:1026: -1- m4_pattern_allow([^HAVE_XCOMPOSITE_FALSE$]) m4trace:configure.ac:1026: -1- _AM_SUBST_NOTMAKE([HAVE_XCOMPOSITE_TRUE]) m4trace:configure.ac:1026: -1- _AM_SUBST_NOTMAKE([HAVE_XCOMPOSITE_FALSE]) m4trace:configure.ac:1027: -1- AM_CONDITIONAL([ENABLE_TESTS], [test "$have_cunit" = "yes"]) m4trace:configure.ac:1027: -1- m4_pattern_allow([^ENABLE_TESTS_TRUE$]) m4trace:configure.ac:1027: -1- m4_pattern_allow([^ENABLE_TESTS_FALSE$]) m4trace:configure.ac:1027: -1- _AM_SUBST_NOTMAKE([ENABLE_TESTS_TRUE]) m4trace:configure.ac:1027: -1- _AM_SUBST_NOTMAKE([ENABLE_TESTS_FALSE]) m4trace:configure.ac:1028: -1- AM_CONDITIONAL([WITH_ROOT_PRIVILEGES], [test "$with_root_privileges" = "yes"]) m4trace:configure.ac:1028: -1- m4_pattern_allow([^WITH_ROOT_PRIVILEGES_TRUE$]) m4trace:configure.ac:1028: -1- m4_pattern_allow([^WITH_ROOT_PRIVILEGES_FALSE$]) m4trace:configure.ac:1028: -1- _AM_SUBST_NOTMAKE([WITH_ROOT_PRIVILEGES_TRUE]) m4trace:configure.ac:1028: -1- _AM_SUBST_NOTMAKE([WITH_ROOT_PRIVILEGES_FALSE]) m4trace:configure.ac:1029: -1- AM_CONDITIONAL([HAVE_DNET], [test "$have_dnet" = "yes"]) m4trace:configure.ac:1029: -1- m4_pattern_allow([^HAVE_DNET_TRUE$]) m4trace:configure.ac:1029: -1- m4_pattern_allow([^HAVE_DNET_FALSE$]) m4trace:configure.ac:1029: -1- _AM_SUBST_NOTMAKE([HAVE_DNET_TRUE]) m4trace:configure.ac:1029: -1- _AM_SUBST_NOTMAKE([HAVE_DNET_FALSE]) m4trace:configure.ac:1030: -1- AM_CONDITIONAL([HAVE_DOXYGEN], [test "$have_doxygen" = "yes"]) m4trace:configure.ac:1030: -1- m4_pattern_allow([^HAVE_DOXYGEN_TRUE$]) m4trace:configure.ac:1030: -1- m4_pattern_allow([^HAVE_DOXYGEN_FALSE$]) m4trace:configure.ac:1030: -1- _AM_SUBST_NOTMAKE([HAVE_DOXYGEN_TRUE]) m4trace:configure.ac:1030: -1- _AM_SUBST_NOTMAKE([HAVE_DOXYGEN_FALSE]) m4trace:configure.ac:1031: -1- AM_CONDITIONAL([HAVE_FUSE], [test "$have_fuse" = "yes"]) m4trace:configure.ac:1031: -1- m4_pattern_allow([^HAVE_FUSE_TRUE$]) m4trace:configure.ac:1031: -1- m4_pattern_allow([^HAVE_FUSE_FALSE$]) m4trace:configure.ac:1031: -1- _AM_SUBST_NOTMAKE([HAVE_FUSE_TRUE]) m4trace:configure.ac:1031: -1- _AM_SUBST_NOTMAKE([HAVE_FUSE_FALSE]) m4trace:configure.ac:1032: -1- AM_CONDITIONAL([HAVE_GNU_LD], [test "$with_gnu_ld" = "yes"]) m4trace:configure.ac:1032: -1- m4_pattern_allow([^HAVE_GNU_LD_TRUE$]) m4trace:configure.ac:1032: -1- m4_pattern_allow([^HAVE_GNU_LD_FALSE$]) m4trace:configure.ac:1032: -1- _AM_SUBST_NOTMAKE([HAVE_GNU_LD_TRUE]) m4trace:configure.ac:1032: -1- _AM_SUBST_NOTMAKE([HAVE_GNU_LD_FALSE]) m4trace:configure.ac:1033: -1- AM_CONDITIONAL([HAVE_GTKMM], [test "$have_x" = "yes" -a "$with_gtkmm" = "yes"]) m4trace:configure.ac:1033: -1- m4_pattern_allow([^HAVE_GTKMM_TRUE$]) m4trace:configure.ac:1033: -1- m4_pattern_allow([^HAVE_GTKMM_FALSE$]) m4trace:configure.ac:1033: -1- _AM_SUBST_NOTMAKE([HAVE_GTKMM_TRUE]) m4trace:configure.ac:1033: -1- _AM_SUBST_NOTMAKE([HAVE_GTKMM_FALSE]) m4trace:configure.ac:1034: -1- AM_CONDITIONAL([HAVE_PAM], [test "$with_pam" = "yes"]) m4trace:configure.ac:1034: -1- m4_pattern_allow([^HAVE_PAM_TRUE$]) m4trace:configure.ac:1034: -1- m4_pattern_allow([^HAVE_PAM_FALSE$]) m4trace:configure.ac:1034: -1- _AM_SUBST_NOTMAKE([HAVE_PAM_TRUE]) m4trace:configure.ac:1034: -1- _AM_SUBST_NOTMAKE([HAVE_PAM_FALSE]) m4trace:configure.ac:1035: -1- AM_CONDITIONAL([USE_SLASH_PROC], [test "os" = "linux" -a "$have_glib_2_14" = "yes"]) m4trace:configure.ac:1035: -1- m4_pattern_allow([^USE_SLASH_PROC_TRUE$]) m4trace:configure.ac:1035: -1- m4_pattern_allow([^USE_SLASH_PROC_FALSE$]) m4trace:configure.ac:1035: -1- _AM_SUBST_NOTMAKE([USE_SLASH_PROC_TRUE]) m4trace:configure.ac:1035: -1- _AM_SUBST_NOTMAKE([USE_SLASH_PROC_FALSE]) m4trace:configure.ac:1036: -1- AM_CONDITIONAL([USE_PRINTF_WRAPPERS], [test "$bsdPrintfWrappers" = "yes"]) m4trace:configure.ac:1036: -1- m4_pattern_allow([^USE_PRINTF_WRAPPERS_TRUE$]) m4trace:configure.ac:1036: -1- m4_pattern_allow([^USE_PRINTF_WRAPPERS_FALSE$]) m4trace:configure.ac:1036: -1- _AM_SUBST_NOTMAKE([USE_PRINTF_WRAPPERS_TRUE]) m4trace:configure.ac:1036: -1- _AM_SUBST_NOTMAKE([USE_PRINTF_WRAPPERS_FALSE]) m4trace:configure.ac:1039: -1- m4_pattern_allow([^NO_XSM$]) m4trace:configure.ac:1043: -1- m4_pattern_allow([^NO_XCOMPOSITE$]) m4trace:configure.ac:1055: -1- m4_pattern_allow([^NO_MULTIMON$]) m4trace:configure.ac:1097: -1- m4_pattern_allow([^HGFS_LIBS$]) m4trace:configure.ac:1098: -1- m4_pattern_allow([^TOOLS_VERSION$]) m4trace:configure.ac:1099: -1- m4_pattern_allow([^TARGET_OS$]) m4trace:configure.ac:1100: -1- m4_pattern_allow([^KERNEL_RELEASE$]) m4trace:configure.ac:1101: -1- m4_pattern_allow([^LINUXINCLUDE$]) m4trace:configure.ac:1102: -1- m4_pattern_allow([^MODULES_OS$]) m4trace:configure.ac:1103: -1- m4_pattern_allow([^MODULES_DIR$]) m4trace:configure.ac:1104: -1- m4_pattern_allow([^MODULES$]) m4trace:configure.ac:1105: -1- m4_pattern_allow([^COMMON_XLIBS$]) m4trace:configure.ac:1106: -1- m4_pattern_allow([^XSM_LIBS$]) m4trace:configure.ac:1107: -1- m4_pattern_allow([^XCOMPOSITE_LIBS$]) m4trace:configure.ac:1108: -1- m4_pattern_allow([^PAM_PREFIX$]) m4trace:configure.ac:1109: -1- m4_pattern_allow([^PLUGIN_CPPFLAGS$]) m4trace:configure.ac:1110: -1- m4_pattern_allow([^PLUGIN_LDFLAGS$]) m4trace:configure.ac:1111: -1- m4_pattern_allow([^VMTOOLS_CPPFLAGS$]) m4trace:configure.ac:1112: -1- m4_pattern_allow([^VMTOOLS_LIBS$]) m4trace:configure.ac:1113: -1- m4_pattern_allow([^RPCGENFLAGS$]) m4trace:configure.ac:1114: -1- m4_pattern_allow([^XDR_LIBS$]) m4trace:configure.ac:1115: -1- m4_pattern_allow([^TEST_PLUGIN_INSTALLDIR$]) m4trace:configure.ac:1116: -1- m4_pattern_allow([^COMMON_PLUGIN_INSTALLDIR$]) m4trace:configure.ac:1117: -1- m4_pattern_allow([^VMSVC_PLUGIN_INSTALLDIR$]) m4trace:configure.ac:1118: -1- m4_pattern_allow([^VMUSR_PLUGIN_INSTALLDIR$]) m4trace:configure.ac:1123: -1- m4_pattern_allow([^SYSDIR$]) m4trace:configure.ac:1125: -1- m4_pattern_allow([^INSTVMSG$]) m4trace:configure.ac:1126: -1- m4_pattern_allow([^RPCGEN_WRAPPER$]) m4trace:configure.ac:1130: -1- m4_pattern_allow([^LIB_AUTH_CPPFLAGS$]) m4trace:configure.ac:1131: -1- m4_pattern_allow([^LIB_IMPERSONATE_CPPFLAGS$]) m4trace:configure.ac:1132: -1- m4_pattern_allow([^LIB_USER_CPPFLAGS$]) m4trace:configure.ac:1133: -1- m4_pattern_allow([^LIBVMTOOLS_LIBADD$]) m4trace:configure.ac:1137: -1- m4_pattern_allow([^VIX_LIBADD$]) m4trace:configure.ac:1227: -1- m4_pattern_allow([^LIB@&t@OBJS$]) m4trace:configure.ac:1227: -1- m4_pattern_allow([^LTLIBOBJS$]) m4trace:configure.ac:1227: -1- AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"]) m4trace:configure.ac:1227: -1- m4_pattern_allow([^am__EXEEXT_TRUE$]) m4trace:configure.ac:1227: -1- m4_pattern_allow([^am__EXEEXT_FALSE$]) m4trace:configure.ac:1227: -1- _AM_SUBST_NOTMAKE([am__EXEEXT_TRUE]) m4trace:configure.ac:1227: -1- _AM_SUBST_NOTMAKE([am__EXEEXT_FALSE]) m4trace:configure.ac:1227: -1- _AM_OUTPUT_DEPENDENCY_COMMANDS m4trace:configure.ac:1227: -1- _LT_PROG_LTMAIN open-vm-tools-9.4.0-1280544/services/0000755765153500003110000000000012220061624015256 5ustar dtormtsopen-vm-tools-9.4.0-1280544/services/plugins/0000755765153500003110000000000012220061624016737 5ustar dtormtsopen-vm-tools-9.4.0-1280544/services/plugins/vmbackup/0000755765153500003110000000000012220061625020550 5ustar dtormtsopen-vm-tools-9.4.0-1280544/services/plugins/vmbackup/stateMachine.c0000644765153500003110000007501112220061556023330 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file stateMachine.c * * Implements a generic state machine for executing backup operations * asynchronously. Since VSS is based on an asynchronous polling model, * we're basing all backup operations on a similar model controlled by this * state machine, even if it would be more eficient to use an event-driven * approach in some cases. * * For a description of the state machine, check the README file. * * The sync provider state machine depends on the particular implementation. * For the sync driver, it enables the driver and waits for a "snapshot done" * message before finishing. For the VSS subsystem, the sync provider just * implements a VSS backup cycle. */ #include "vmBackupInt.h" #include "dynxdr.h" #include #include #include "guestApp.h" #include "str.h" #include "strutil.h" #include "util.h" #include "vmBackupSignals.h" #if defined(_WIN32) #include "vmware/guestrpc/guestQuiesce.h" #endif #include "vmware/tools/utils.h" #include "vmware/tools/vmbackup.h" #include "xdrutil.h" #if !defined(__APPLE__) #include "embed_version.h" #include "vmtoolsd_version.h" VM_EMBED_VERSION(VMTOOLSD_VERSION_STRING); #endif #if defined(__linux__) #include #include #include #include "ioplGet.h" #endif #define VMBACKUP_ENQUEUE_EVENT() do { \ gBackupState->timerEvent = g_timeout_source_new(gBackupState->pollPeriod); \ VMTOOLSAPP_ATTACH_SOURCE(gBackupState->ctx, \ gBackupState->timerEvent, \ VmBackupAsyncCallback, \ NULL, \ NULL); \ } while (0) static VmBackupState *gBackupState = NULL; static Bool VmBackupEnableSync(void); /** * Returns a string representation of the given state machine state. * * @param[in] state State of interest. * * @return A string representation of the state. */ static const char * VmBackupGetStateName(VmBackupMState state) { switch (state) { case VMBACKUP_MSTATE_IDLE: return "IDLE"; case VMBACKUP_MSTATE_SCRIPT_FREEZE: return "SCRIPT_FREEZE"; case VMBACKUP_MSTATE_SYNC_FREEZE: return "SYNC_FREEZE"; case VMBACKUP_MSTATE_SYNC_THAW: return "SYNC_THAW"; case VMBACKUP_MSTATE_SCRIPT_THAW: return "SCRIPT_THAW"; case VMBACKUP_MSTATE_SCRIPT_ERROR: return "SCRIPT_ERROR"; case VMBACKUP_MSTATE_SYNC_ERROR: return "SYNC_ERROR"; default: NOT_IMPLEMENTED(); } } /** * Sends a keep alive backup event to the VMX. * * @param[in] clientData Unused. * * @return FALSE */ static gboolean VmBackupKeepAliveCallback(void *clientData) { g_debug("*** %s\n", __FUNCTION__); ASSERT(gBackupState != NULL); g_source_unref(gBackupState->keepAlive); gBackupState->keepAlive = NULL; VmBackup_SendEvent(VMBACKUP_EVENT_KEEP_ALIVE, 0, ""); return FALSE; } /** * Sends a command to the VMX asking it to update VMDB about a new backup event. * This will restart the keep-alive timer. * * @param[in] event The event to set. * @param[in] code Error code. * @param[in] dest Error description. * * @return TRUE on success. */ Bool VmBackup_SendEvent(const char *event, const uint32 code, const char *desc) { Bool success; char *result = NULL; size_t resultLen; gchar *msg; #if defined(__linux__) unsigned int oldLevel; #endif ASSERT(gBackupState != NULL); g_debug("*** %s\n", __FUNCTION__); if (gBackupState->keepAlive != NULL) { g_source_destroy(gBackupState->keepAlive); g_source_unref(gBackupState->keepAlive); } msg = g_strdup_printf(VMBACKUP_PROTOCOL_EVENT_SET" %s %u %s", event, code, desc); g_debug("sending vmbackup event, %s\n", msg); #if defined(__linux__) oldLevel = Iopl_Get(); if (iopl(3) < 0) { g_debug("Error raising the IOPL, %s", strerror(errno)); } #endif success = RpcChannel_Send(gBackupState->ctx->rpc, msg, strlen(msg) + 1, &result, &resultLen); #if defined(__linux__) if (iopl(oldLevel) < 0) { g_debug("Error restoring the IOPL, %s", strerror(errno)); } #endif if (!success) { g_warning("Failed to send vmbackup event to the VMX: %s.\n", result); } vm_free(result); gBackupState->keepAlive = g_timeout_source_new(VMBACKUP_KEEP_ALIVE_PERIOD / 2); VMTOOLSAPP_ATTACH_SOURCE(gBackupState->ctx, gBackupState->keepAlive, VmBackupKeepAliveCallback, NULL, NULL); return success; } /** * Cleans up the backup state object and sends a "done" event to the VMX. */ static void VmBackupFinalize(void) { g_debug("*** %s\n", __FUNCTION__); ASSERT(gBackupState != NULL); if (gBackupState->abortTimer != NULL) { g_source_destroy(gBackupState->abortTimer); g_source_unref(gBackupState->abortTimer); } if (gBackupState->currentOp != NULL) { VmBackup_Cancel(gBackupState->currentOp); VmBackup_Release(gBackupState->currentOp); } VmBackup_SendEvent(VMBACKUP_EVENT_REQUESTOR_DONE, VMBACKUP_SUCCESS, ""); if (gBackupState->timerEvent != NULL) { g_source_destroy(gBackupState->timerEvent); g_source_unref(gBackupState->timerEvent); } if (gBackupState->keepAlive != NULL) { g_source_destroy(gBackupState->keepAlive); g_source_unref(gBackupState->keepAlive); } gBackupState->provider->release(gBackupState->provider); g_free(gBackupState->scriptArg); g_free(gBackupState->volumes); g_free(gBackupState->snapshots); g_free(gBackupState->errorMsg); g_free(gBackupState); gBackupState = NULL; } /** * Starts the execution of the scripts for the given action type. * * @param[in] type Type of scripts being started. * * @return TRUE, unless starting the scripts fails for some reason. */ static Bool VmBackupStartScripts(VmBackupScriptType type) { const char *opName; VmBackupMState nextState; g_debug("*** %s\n", __FUNCTION__); switch (type) { case VMBACKUP_SCRIPT_FREEZE: opName = "VmBackupOnFreeze"; nextState = VMBACKUP_MSTATE_SCRIPT_FREEZE; break; case VMBACKUP_SCRIPT_FREEZE_FAIL: opName = "VmBackupOnFreezeFail"; nextState = VMBACKUP_MSTATE_SCRIPT_ERROR; break; case VMBACKUP_SCRIPT_THAW: opName = "VmBackupOnThaw"; nextState = VMBACKUP_MSTATE_SCRIPT_THAW; break; default: NOT_REACHED(); } if (gBackupState->execScripts && !VmBackup_SetCurrentOp(gBackupState, VmBackup_NewScriptOp(type, gBackupState), NULL, opName)) { VmBackup_SendEvent(VMBACKUP_EVENT_REQUESTOR_ERROR, VMBACKUP_SCRIPT_ERROR, "Error when starting custom quiesce scripts."); return FALSE; } gBackupState->machineState = nextState; return TRUE; } /** * Puts the state machine in the right state when an error occurs. The caller * should check for the state of the backup upon this function returning: if * it's IDLE, it means the backup state should be cleaned up. * * @return Whether the backup operation should be finalized. */ static gboolean VmBackupOnError(void) { switch (gBackupState->machineState) { case VMBACKUP_MSTATE_SCRIPT_FREEZE: case VMBACKUP_MSTATE_SYNC_ERROR: /* Next state is "script error". */ if (!VmBackupStartScripts(VMBACKUP_SCRIPT_FREEZE_FAIL)) { gBackupState->machineState = VMBACKUP_MSTATE_IDLE; } break; case VMBACKUP_MSTATE_SYNC_FREEZE: case VMBACKUP_MSTATE_SYNC_THAW: /* Next state is "sync error". */ gBackupState->pollPeriod = 1000; gBackupState->machineState = VMBACKUP_MSTATE_SYNC_ERROR; g_signal_emit_by_name(gBackupState->ctx->serviceObj, TOOLS_CORE_SIG_IO_FREEZE, gBackupState->ctx, FALSE); break; case VMBACKUP_MSTATE_SCRIPT_THAW: /* Next state is "idle". */ gBackupState->machineState = VMBACKUP_MSTATE_IDLE; break; default: g_error("Unexpected machine state on error: %s\n", VmBackupGetStateName(gBackupState->machineState)); } return (gBackupState->machineState == VMBACKUP_MSTATE_IDLE); } /** * Aborts the current operation, unless we're already in an error state. */ static void VmBackupDoAbort(void) { g_debug("*** %s\n", __FUNCTION__); ASSERT(gBackupState != NULL); if (gBackupState->machineState != VMBACKUP_MSTATE_SCRIPT_ERROR && gBackupState->machineState != VMBACKUP_MSTATE_SYNC_ERROR) { /* Mark the current operation as cancelled. */ if (gBackupState->currentOp != NULL) { VmBackup_Cancel(gBackupState->currentOp); VmBackup_Release(gBackupState->currentOp); gBackupState->currentOp = NULL; } VmBackup_SendEvent(VMBACKUP_EVENT_REQUESTOR_ABORT, VMBACKUP_REMOTE_ABORT, "Quiesce aborted."); /* Transition to the error state. */ if (VmBackupOnError()) { VmBackupFinalize(); } } } /** * Timer callback to abort the current operation. * * @param[in] data Unused. * * @return FALSE */ static gboolean VmBackupAbortTimer(gpointer data) { ASSERT(gBackupState != NULL); g_warning("Aborting backup operation due to timeout."); g_source_unref(gBackupState->abortTimer); gBackupState->abortTimer = NULL; VmBackupDoAbort(); return FALSE; } /** * Callback that checks for the status of the current operation. Calls the * queued operations as needed. * * @param[in] clientData Unused. * * @return FALSE */ static gboolean VmBackupAsyncCallback(void *clientData) { VmBackupOpStatus status = VMBACKUP_STATUS_FINISHED; g_debug("*** %s\n", __FUNCTION__); ASSERT(gBackupState != NULL); g_source_unref(gBackupState->timerEvent); gBackupState->timerEvent = NULL; if (gBackupState->currentOp != NULL) { g_debug("VmBackupAsyncCallback: checking %s\n", gBackupState->currentOpName); status = VmBackup_QueryStatus(gBackupState->currentOp); } switch (status) { case VMBACKUP_STATUS_PENDING: goto exit; case VMBACKUP_STATUS_FINISHED: if (gBackupState->currentOpName != NULL) { g_debug("Async request '%s' completed\n", gBackupState->currentOpName); VmBackup_Release(gBackupState->currentOp); gBackupState->currentOpName = NULL; } gBackupState->currentOp = NULL; break; default: { gchar *msg; if (gBackupState->errorMsg != NULL) { msg = g_strdup_printf("'%s' operation failed: %s", gBackupState->currentOpName, gBackupState->errorMsg); } else { msg = g_strdup_printf("'%s' operation failed.", gBackupState->currentOpName); } VmBackup_SendEvent(VMBACKUP_EVENT_REQUESTOR_ERROR, VMBACKUP_UNEXPECTED_ERROR, msg); g_free(msg); VmBackup_Release(gBackupState->currentOp); gBackupState->currentOp = NULL; VmBackupOnError(); goto exit; } } /* * Keep calling the registered callback until it's either NULL, or * an asynchronous operation is scheduled. */ while (gBackupState->callback != NULL) { VmBackupCallback cb = gBackupState->callback; gBackupState->callback = NULL; if (cb(gBackupState)) { if (gBackupState->currentOp != NULL || gBackupState->forceRequeue) { goto exit; } } else { VmBackupOnError(); goto exit; } } /* * At this point, the current operation can be declared finished, and the * state machine can move to the next state. */ switch (gBackupState->machineState) { case VMBACKUP_MSTATE_SCRIPT_FREEZE: /* Next state is "sync freeze". */ if (!VmBackupEnableSync()) { VmBackupOnError(); } break; case VMBACKUP_MSTATE_SYNC_FREEZE: /* * The SYNC_FREEZE -> SYNC_THAW transition is handled by the RPC callback, * so this case is a no-op. */ break; case VMBACKUP_MSTATE_SYNC_THAW: /* Next state is "script thaw". */ g_signal_emit_by_name(gBackupState->ctx->serviceObj, TOOLS_CORE_SIG_IO_FREEZE, gBackupState->ctx, FALSE); if (!VmBackupStartScripts(VMBACKUP_SCRIPT_THAW)) { VmBackupOnError(); } break; case VMBACKUP_MSTATE_SCRIPT_ERROR: case VMBACKUP_MSTATE_SCRIPT_THAW: /* Next state is "idle". */ gBackupState->machineState = VMBACKUP_MSTATE_IDLE; break; case VMBACKUP_MSTATE_SYNC_ERROR: /* Next state is "script error". */ if (!VmBackupStartScripts(VMBACKUP_SCRIPT_FREEZE_FAIL)) { VmBackupOnError(); } break; default: g_error("Unexpected machine state: %s\n", VmBackupGetStateName(gBackupState->machineState)); } exit: /* If the state machine is back in IDLE, it means the backup operation finished. */ if (gBackupState->machineState == VMBACKUP_MSTATE_IDLE) { VmBackupFinalize(); } else { gBackupState->forceRequeue = FALSE; VMBACKUP_ENQUEUE_EVENT(); } return FALSE; } /** * Calls the sync provider's start function. * * @param[in] state The backup state. * * @return Whether the provider's start callback was successful. */ static Bool VmBackupEnableSync(void) { g_debug("*** %s\n", __FUNCTION__); g_signal_emit_by_name(gBackupState->ctx->serviceObj, TOOLS_CORE_SIG_IO_FREEZE, gBackupState->ctx, TRUE); if (!gBackupState->provider->start(gBackupState, gBackupState->provider->clientData)) { g_signal_emit_by_name(gBackupState->ctx->serviceObj, TOOLS_CORE_SIG_IO_FREEZE, gBackupState->ctx, FALSE); VmBackup_SendEvent(VMBACKUP_EVENT_REQUESTOR_ERROR, VMBACKUP_SYNC_ERROR, "Error when enabling the sync provider."); return FALSE; } gBackupState->machineState = VMBACKUP_MSTATE_SYNC_FREEZE; return TRUE; } /** * Get boolean entry for the key from the config file. * * @param[in] config Config file to read the key from. * @param[in] key Key to look for in the config file. * @param[in] defaultValue Default value if the key is not found. */ static gboolean VmBackupConfigGetBoolean(GKeyFile *config, const char *key, gboolean defValue) { GError *err = NULL; gboolean value = defValue; if (key != NULL) { value = g_key_file_get_boolean(config, "vmbackup", key, &err); if (err != NULL) { g_clear_error(&err); value = defValue; } } return value; } /** * Starts the quiesce operation according to the supplied specification unless * some unexpected error occurs. * * @param[in] data RPC data. * @param[in] forceVss Only allow Vss quiescing or no quiescing. * * @return TRUE on success. */ static gboolean VmBackupStartCommon(RpcInData *data, gboolean forceVss) { GError *err = NULL; ToolsAppCtx *ctx = data->appCtx; VmBackupSyncProvider *provider = NULL; size_t i; /* List of available providers, in order of preference for loading. */ struct SyncProvider { VmBackupSyncProvider *(*ctor)(void); const gchar *cfgEntry; } providers[] = { #if defined(_WIN32) { VmBackup_NewVssProvider, "enableVSS" }, #endif { VmBackup_NewSyncDriverProvider, "enableSyncDriver" }, { VmBackup_NewNullProvider, NULL }, }; if (forceVss) { if (gBackupState->quiesceApps || gBackupState->quiesceFS) { /* If quiescing is requested, only allow VSS provider */ #if defined(_WIN32) if (VmBackupConfigGetBoolean(ctx->config, "enableVSS", TRUE)) { provider = VmBackup_NewVssProvider(); } #endif } else { /* If no quiescing is requested only allow null provider */ provider = VmBackup_NewNullProvider(); } if (provider == NULL) { g_warning("Requested quiescing cannot be initialized."); goto error; } } else { /* Instantiate the sync provider. */ for (i = 0; i < ARRAYSIZE(providers); i++) { struct SyncProvider *sp = &providers[i]; if (VmBackupConfigGetBoolean(ctx->config, sp->cfgEntry, TRUE)) { provider = sp->ctor(); if (provider != NULL) { break; } } } } ASSERT(provider != NULL); /* Instantiate the backup state and start the operation. */ gBackupState->ctx = data->appCtx; gBackupState->pollPeriod = 1000; gBackupState->machineState = VMBACKUP_MSTATE_IDLE; gBackupState->provider = provider; g_debug("Using quiesceApps = %d, quiesceFS = %d, allowHWProvider = %d," "execScripts = %d, scriptArg = %s, timeout = %u\n", gBackupState->quiesceApps, gBackupState->quiesceFS, gBackupState->allowHWProvider, gBackupState->execScripts, (gBackupState->scriptArg != NULL) ? gBackupState->scriptArg : "", gBackupState->timeout); g_debug("Quiescing volumes: %s", (gBackupState->volumes) ? gBackupState->volumes : "(null)"); gBackupState->configDir = GuestApp_GetConfPath(); if (gBackupState->configDir == NULL) { g_warning("Error getting configuration directory."); goto error; } VmBackup_SendEvent(VMBACKUP_EVENT_RESET, VMBACKUP_SUCCESS, ""); if (!VmBackupStartScripts(VMBACKUP_SCRIPT_FREEZE)) { goto error; } /* * VC has a 15 minute timeout for quiesced snapshots. After that timeout, * it just discards the operation and sends an error to the caller. But * Tools can still keep running, blocking any new quiesced snapshot * requests. So we set up our own timer (which is configurable, in case * anyone wants to play with it), so that we abort any ongoing operation * if we also hit that timeout. * * First check if the timeout is specified by the RPC command, if not, * check the tools.conf file, otherwise use the default. * * See bug 506106. */ if (gBackupState->timeout == 0) { gBackupState->timeout = (guint) g_key_file_get_integer( gBackupState->ctx->config, "vmbackup", "timeout", &err); if (err != NULL) { g_clear_error(&err); gBackupState->timeout = 15 * 60; } } /* Treat "0" as no timeout. */ if (gBackupState->timeout != 0) { gBackupState->abortTimer = g_timeout_source_new_seconds(gBackupState->timeout); VMTOOLSAPP_ATTACH_SOURCE(gBackupState->ctx, gBackupState->abortTimer, VmBackupAbortTimer, NULL, NULL); } VMBACKUP_ENQUEUE_EVENT(); return RPCIN_SETRETVALS(data, "", TRUE); error: if (gBackupState->keepAlive != NULL) { g_source_destroy(gBackupState->keepAlive); g_source_unref(gBackupState->keepAlive); gBackupState->keepAlive = NULL; } if (gBackupState->provider) { gBackupState->provider->release(gBackupState->provider); } g_free(gBackupState->scriptArg); g_free(gBackupState->volumes); g_free(gBackupState); gBackupState = NULL; return RPCIN_SETRETVALS(data, "Error initializing quiesce operation.", FALSE); } /* RpcIn callbacks. */ /** * Handler for the "vmbackup.start" message. Starts the "freeze" scripts * unless there's another backup operation going on or some other * unexpected error occurs. * * @param[in] data RPC data. * * @return TRUE on success. */ static gboolean VmBackupStart(RpcInData *data) { g_debug("*** %s\n", __FUNCTION__); if (gBackupState != NULL) { return RPCIN_SETRETVALS(data, "Quiesce operation already in progress.", FALSE); } gBackupState = g_new0(VmBackupState, 1); if (data->argsSize > 0) { int generateManifests = 0; uint32 index = 0; if (StrUtil_GetNextIntToken(&generateManifests, &index, data->args, " ")) { gBackupState->generateManifests = generateManifests; } gBackupState->quiesceApps = TRUE; gBackupState->quiesceFS = TRUE; gBackupState->allowHWProvider = TRUE; gBackupState->execScripts = TRUE; gBackupState->scriptArg = NULL; gBackupState->timeout = 0; /* get volume uuids if provided */ if (data->args[index] != '\0') { gBackupState->volumes = g_strndup(data->args + index, data->argsSize - index); } } return VmBackupStartCommon(data, FALSE); } #if defined(_WIN32) /** * Handler for the "vmbackup.startWithOpts" message. Starts processing the * quiesce operation according to the supplied specification unless there's * another backup operation going on or some other unexpected error occurs. * * . If createManifest is true, the guest generates a manifest about the * application involved during quiescing. * . If quiesceApps is true, the guest involves applications during * quiescing. If quiesceFS is true, the guest performs file system * quiescing. If both quiesceApps and quiesceFS are true, the guest * falls back to file system quiescing if application quiescing is not * supported in the guest. If both quiesceApps and quiesceFS are false, * the guest performs no quiescing but will still run the custom scripts * provided execScripts is true. * . If writableSnapshot is true, the guest assumes that writable snapshot * based quiescing can be performed. * . If execScripts is true, the guest calls pre-freeze and post-thaw * scripts before and after quiescing. * . The scriptArg string is passed to the pre-freeze and post-thaw scripts * as an argument so that the scripts can be configured to perform * actions based this argument. * . The timeout in seconds overrides the default timeout of 15 minutes * that the guest uses to abort a long quiesce operation. If the timeout * is 0, the default timeout is used. * . The volumes argument is a list of diskUuids separated by space. * * @param[in] data RPC data. * * @return TRUE on success. */ static gboolean VmBackupStartWithOpts(RpcInData *data) { GuestQuiesceParams *params; GuestQuiesceParamsV1 *paramsV1; gboolean retval; g_debug("*** %s\n", __FUNCTION__); if (gBackupState != NULL) { return RPCIN_SETRETVALS(data, "Quiesce operation already in progress.", FALSE); } params = (GuestQuiesceParams *)data->args; if (params->ver != GUESTQUIESCEPARAMS_V1) { g_warning("%s: Incompatible quiesce parameter version. \n", __FUNCTION__); return RPCIN_SETRETVALS(data, "Incompatible quiesce parameter version", FALSE); } gBackupState = g_new0(VmBackupState, 1); paramsV1 = params->GuestQuiesceParams_u.guestQuiesceParamsV1; gBackupState->generateManifests = paramsV1->createManifest; gBackupState->quiesceApps = paramsV1->quiesceApps; gBackupState->quiesceFS = paramsV1->quiesceFS; gBackupState->allowHWProvider = paramsV1->writableSnapshot; gBackupState->execScripts = paramsV1->execScripts; gBackupState->scriptArg = g_strndup(paramsV1->scriptArg, strlen(paramsV1->scriptArg)); gBackupState->timeout = paramsV1->timeout; gBackupState->volumes = g_strndup(paramsV1->diskUuids, strlen(paramsV1->diskUuids)); retval = VmBackupStartCommon(data, TRUE); return retval; } #endif /** * Aborts the current operation if one is active, and stops the backup * process. If the sync provider has been activated, tell it to abort * the ongoing operation. * * @param[in] data RPC data. * * @return TRUE */ static gboolean VmBackupAbort(RpcInData *data) { g_debug("*** %s\n", __FUNCTION__); if (gBackupState == NULL) { return RPCIN_SETRETVALS(data, "Error: no quiesce operation in progress", FALSE); } VmBackupDoAbort(); return RPCIN_SETRETVALS(data, "", TRUE); } /** * Notifies the sync provider to thaw the file systems and puts the state * machine in the SYNC_THAW state. * * @param[in] data RPC data. * * @return TRUE */ static gboolean VmBackupSnapshotDone(RpcInData *data) { g_debug("*** %s\n", __FUNCTION__); if (gBackupState == NULL) { return RPCIN_SETRETVALS(data, "Error: no quiesce operation in progress", FALSE); } else if (gBackupState->machineState != VMBACKUP_MSTATE_SYNC_FREEZE) { g_warning("Error: unexpected state for snapshot done message: %s", VmBackupGetStateName(gBackupState->machineState)); return RPCIN_SETRETVALS(data, "Error: unexpected state for quiesce done message.", FALSE); } else { if (data->argsSize > 1) { gBackupState->snapshots = g_strndup(data->args + 1, data->argsSize - 1); } if (!gBackupState->provider->snapshotDone(gBackupState, gBackupState->provider->clientData)) { VmBackup_SendEvent(VMBACKUP_EVENT_REQUESTOR_ERROR, VMBACKUP_SYNC_ERROR, "Error when notifying the sync provider."); if (VmBackupOnError()) { VmBackupFinalize(); } } else { gBackupState->machineState = VMBACKUP_MSTATE_SYNC_THAW; } return RPCIN_SETRETVALS(data, "", TRUE); } } /** * Prints some information about the plugin's state to the log. * * @param[in] src The source object. * @param[in] ctx Unused. * @param[in] data Unused. */ static void VmBackupDumpState(gpointer src, ToolsAppCtx *ctx, gpointer data) { if (gBackupState == NULL) { ToolsCore_LogState(TOOLS_STATE_LOG_PLUGIN, "Backup is idle.\n"); } else { ToolsCore_LogState(TOOLS_STATE_LOG_PLUGIN, "Backup is in state: %s\n", VmBackupGetStateName(gBackupState->machineState)); } } /** * Reset callback. Currently does nothing. * * @param[in] src The source object. * @param[in] ctx Unused. * @param[in] data Unused. */ static void VmBackupReset(gpointer src, ToolsAppCtx *ctx, gpointer data) { } /** * Cleans up the plugin. * * @param[in] src The source object. * @param[in] ctx The app context. * @param[in] data Unused. */ static void VmBackupShutdown(gpointer src, ToolsAppCtx *ctx, gpointer data) { g_debug("*** %s\n", __FUNCTION__); if (gBackupState != NULL) { VmBackupFinalize(); } } /** * Plugin entry point. Initializes internal plugin state. * * @param[in] ctx The app context. * * @return The registration data. Returns NULL if there is no sync provider * available to quiesce the filesystems. */ TOOLS_MODULE_EXPORT ToolsPluginData * ToolsOnLoad(ToolsAppCtx *ctx) { static ToolsPluginData regData = { "vmbackup", NULL, NULL }; RpcChannelCallback rpcs[] = { { VMBACKUP_PROTOCOL_START, VmBackupStart, NULL, NULL, NULL, 0 }, #if defined(_WIN32) /* START_WITH_OPTS command supported only on Windows for now */ { VMBACKUP_PROTOCOL_START_WITH_OPTS, VmBackupStartWithOpts, NULL, xdr_GuestQuiesceParams, NULL, sizeof (GuestQuiesceParams) }, #endif { VMBACKUP_PROTOCOL_ABORT, VmBackupAbort, NULL, NULL, NULL, 0 }, { VMBACKUP_PROTOCOL_SNAPSHOT_DONE, VmBackupSnapshotDone, NULL, NULL, NULL, 0 } }; ToolsPluginSignalCb sigs[] = { { TOOLS_CORE_SIG_DUMP_STATE, VmBackupDumpState, NULL }, { TOOLS_CORE_SIG_RESET, VmBackupReset, NULL }, { TOOLS_CORE_SIG_SHUTDOWN, VmBackupShutdown, NULL }, }; ToolsAppReg regs[] = { { TOOLS_APP_GUESTRPC, VMTools_WrapArray(rpcs, sizeof *rpcs, ARRAYSIZE(rpcs)) }, { TOOLS_APP_SIGNALS, VMTools_WrapArray(sigs, sizeof *sigs, ARRAYSIZE(sigs)) }, }; #if defined(G_PLATFORM_WIN32) /* * If initializing COM fails (unlikely), we'll fallback to the sync driver * or the null provider, depending on the configuration. On success, send * a request to unregister the VMware snapshot provider. */ if (ToolsCore_InitializeCOM(ctx)) { VmBackup_UnregisterSnapshotProvider(); } else { g_warning("Failed to initialize COM, VSS support will be unavailable."); } #endif regData.regs = VMTools_WrapArray(regs, sizeof *regs, ARRAYSIZE(regs)); g_signal_new(TOOLS_CORE_SIG_IO_FREEZE, G_OBJECT_TYPE(ctx->serviceObj), 0, 0, NULL, NULL, g_cclosure_user_marshal_VOID__POINTER_BOOLEAN, G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_BOOLEAN); return ®Data; } open-vm-tools-9.4.0-1280544/services/plugins/vmbackup/nullProvider.c0000644765153500003110000000723412220061556023412 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file nullProvider.c * * Implements a sync provider that doesn't really do anything, so that we can at * least run freeze / thaw scripts if no lower-level freeze functionality is * available. */ #if !defined(_WIN32) # include #endif #include "vmBackupInt.h" /* ****************************************************************************** * VmBackupNullStart -- */ /** * * Calls sync(2) on POSIX systems. Sends the "commit snapshot" event to the * host. * * @param[in] state Backup state. * @param[in] clientData Unused. * * @return Whether successfully sent the signal to the host. * ****************************************************************************** */ static Bool VmBackupNullStart(VmBackupState *state, void *clientData) { #if !defined(_WIN32) /* * This is more of a "let's at least do something" than something that * will actually ensure data integrity... */ sync(); #endif VmBackup_SetCurrentOp(state, NULL, NULL, __FUNCTION__); return VmBackup_SendEvent(VMBACKUP_EVENT_SNAPSHOT_COMMIT, 0, ""); } /* ****************************************************************************** * VmBackupNullSnapshotDone -- */ /** * * Does nothing, just keep the backup state machine alive. * * @param[in] state Backup state. * @param[in] clientData Unused. * * @return TRUE. * ****************************************************************************** */ static Bool VmBackupNullSnapshotDone(VmBackupState *state, void *clientData) { VmBackup_SetCurrentOp(state, NULL, NULL, __FUNCTION__); return TRUE; } /* ****************************************************************************** * VmBackupNullRelease -- */ /** * * Frees memory associated with this sync provider. * * @param[in] provider The provider. * ****************************************************************************** */ static void VmBackupNullRelease(VmBackupSyncProvider *provider) { g_free(provider); } /* ****************************************************************************** * VmBackup_NewNullProvider -- */ /** * * Returns a new null provider. * * @return A VmBackupSyncProvider, never NULL. * ****************************************************************************** */ VmBackupSyncProvider * VmBackup_NewNullProvider(void) { VmBackupSyncProvider *provider; provider = g_new(VmBackupSyncProvider, 1); provider->start = VmBackupNullStart; provider->snapshotDone = VmBackupNullSnapshotDone; provider->release = VmBackupNullRelease; provider->clientData = NULL; return provider; } open-vm-tools-9.4.0-1280544/services/plugins/vmbackup/vmBackupInt.h0000644765153500003110000001425512220061556023156 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file vmBackupInt.h * * Internal definitions used by the vmbackup code. */ #ifndef _VMBACKUPINT_H_ #define _VMBACKUPINT_H_ #define G_LOG_DOMAIN "vmbackup" #include #include "vmware.h" #include "vmware/guestrpc/vmbackup.h" #include "vmware/tools/plugin.h" typedef enum { VMBACKUP_STATUS_PENDING, VMBACKUP_STATUS_FINISHED, VMBACKUP_STATUS_CANCELED, VMBACKUP_STATUS_ERROR } VmBackupOpStatus; typedef enum { VMBACKUP_SCRIPT_FREEZE, VMBACKUP_SCRIPT_FREEZE_FAIL, VMBACKUP_SCRIPT_THAW } VmBackupScriptType; typedef enum { VMBACKUP_MSTATE_IDLE, VMBACKUP_MSTATE_SCRIPT_FREEZE, VMBACKUP_MSTATE_SYNC_FREEZE, VMBACKUP_MSTATE_SYNC_THAW, VMBACKUP_MSTATE_SCRIPT_THAW, VMBACKUP_MSTATE_SCRIPT_ERROR, VMBACKUP_MSTATE_SYNC_ERROR } VmBackupMState; /** * This is a "base struct" for asynchronous operations monitored by the * state machine. Each implementation should provide these three functions * at the start of the struct so that the state machine can properly * interact with it. */ typedef struct VmBackupOp { VmBackupOpStatus (*queryFn)(struct VmBackupOp *); void (*releaseFn)(struct VmBackupOp *); void (*cancelFn)(struct VmBackupOp *); } VmBackupOp; struct VmBackupSyncProvider; /** * Holds information about the current state of the backup operation. * Don't modify the fields directly - rather, use VmBackup_SetCurrentOp, * which does most of the handling needed by users of the state machine. */ typedef struct VmBackupState { ToolsAppCtx *ctx; VmBackupOp *currentOp; const char *currentOpName; char *volumes; char *snapshots; guint pollPeriod; GSource *abortTimer; GSource *timerEvent; GSource *keepAlive; Bool (*callback)(struct VmBackupState *); Bool forceRequeue; Bool generateManifests; Bool quiesceApps; Bool quiesceFS; Bool allowHWProvider; Bool execScripts; char *scriptArg; guint timeout; gpointer clientData; void *scripts; const char *configDir; ssize_t currentScript; gchar *errorMsg; VmBackupMState machineState; struct VmBackupSyncProvider *provider; } VmBackupState; typedef Bool (*VmBackupCallback)(VmBackupState *); typedef Bool (*VmBackupProviderCallback)(VmBackupState *, void *clientData); /** * Defines the interface between the state machine and the implementation * of the "sync provider": either the VSS requestor or the sync driver * provider, currently. */ typedef struct VmBackupSyncProvider { VmBackupProviderCallback start; VmBackupProviderCallback snapshotDone; void (*release)(struct VmBackupSyncProvider *); void *clientData; } VmBackupSyncProvider; /** * Sets the current asynchronous operation being monitored, and an * optional callback for after it's done executing. If the operation * is NULL, the callback is set to execute later (currently, later = 200ms). * * @param[in] state The backup state. * @param[in] op The current op to set. * @param[in] callback Function to call after the operation is finished. * @param[in] currentOpName Operation name, for debugging. * * @return TRUE if @a op is not NULL. */ static INLINE Bool VmBackup_SetCurrentOp(VmBackupState *state, VmBackupOp *op, VmBackupCallback callback, const char *currentOpName) { ASSERT(state != NULL); ASSERT(state->currentOp == NULL); ASSERT(currentOpName != NULL); state->currentOp = op; state->callback = callback; state->currentOpName = currentOpName; state->forceRequeue = (callback != NULL && state->currentOp == NULL); return (op != NULL); } /** * Convenience function to call the operation-specific query function. * * @param[in] op The backup op. * * @return The operation's status. */ static INLINE VmBackupOpStatus VmBackup_QueryStatus(VmBackupOp *op) { ASSERT(op != NULL); return op->queryFn(op); } /** * Convenience function to call the operation-specific cancel function. * Code calling this function should still call VmBackup_QueryStatus() * waiting for it to return a finished status (i.e., something other * than VMBACKUP_STATUS_PENDING). * * @param[in] op The backup op. */ static INLINE void VmBackup_Cancel(VmBackupOp *op) { ASSERT(op != NULL); op->cancelFn(op); } /** * Convenience function to call the operation-specific release function. * Releasing a state object that hasn't finished yet (i.e., * VmBackup_QueryStatus returns VMBACKUP_STATUS_PENDING) can result in * undefined behavior. * * @param[in] op The backup op. */ static INLINE void VmBackup_Release(VmBackupOp *op) { if (op != NULL) { ASSERT(op->releaseFn != NULL); op->releaseFn(op); } } VmBackupSyncProvider * VmBackup_NewNullProvider(void); VmBackupSyncProvider * VmBackup_NewSyncDriverProvider(void); #if defined(G_PLATFORM_WIN32) VmBackupSyncProvider * VmBackup_NewVssProvider(void); void VmBackup_UnregisterSnapshotProvider(void); #endif VmBackupOp * VmBackup_NewScriptOp(VmBackupScriptType freeze, VmBackupState *state); Bool VmBackup_SendEvent(const char *event, const uint32 code, const char *desc); #endif /* _VMBACKUPINT_H_*/ open-vm-tools-9.4.0-1280544/services/plugins/vmbackup/vmBackupSignals.gm0000644765153500003110000000201212220061556024164 0ustar dtormts########################################################## # Copyright (C) 2010 VMware, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public # License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # ########################################################## ## # @file vmBackupSignals.gm # # Defines the custom GClosure marshal functions for the vmbackup signals. # # @see plugin.h # # The "io freeze" signal. VOID:POINTER,BOOLEAN open-vm-tools-9.4.0-1280544/services/plugins/vmbackup/README0000644765153500003110000000314212220061556021433 0ustar dtormtsThis is an attempt to describe the VmBackup state machine using ASCII diagrams. === Main State Machine === The main state machine, implemented in stateMachine.c, works as follows: -------------> IDLE <-----------| | | | | b, e | a | | | | | e \/ | SCRIPT_ERROR <--- SCRIPT_FREEZE | ^ | | | d | b | | e \/ | b, e SYNC_ERROR <----- SYNC_FREEZE | ^ | | | | c | | e \/ | |----------- SYNC_THAW | | | | d | \/ | SCRIPT_THAW -------- The transitions mean the following events / conditions: a. vmbackup.start RPC b. vmbackup operation is finished c. vmbackup.snapshotDone RPC d. sync provider operation is finished e. error condition: runtime error, or vmbackup.abort RPC Sending a vmbackup.start RPC while the state machine is not IDLE causes an error to be returned to the client, but the state machine is not changed. Same behavior occurs for multiple vmbackup.snapshotDone RPCs. Multiple vmbackup.abort messages are ignored. Transitions to IDLE cause the backup operation to be finalized, and a "done" event to be sent to the VMX. Transitions from IDLE cause a "reset" event to be sent to the VMX. open-vm-tools-9.4.0-1280544/services/plugins/vmbackup/COPYING0000644765153500003110000006347112220061556021621 0ustar dtormts GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! open-vm-tools-9.4.0-1280544/services/plugins/vmbackup/Makefile.am0000644765153500003110000000377612220061556022624 0ustar dtormts################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ plugindir = @VMSVC_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libvmbackup.la libvmbackup_la_CPPFLAGS = libvmbackup_la_CPPFLAGS += @PLUGIN_CPPFLAGS@ libvmbackup_la_LDFLAGS = libvmbackup_la_LDFLAGS += @PLUGIN_LDFLAGS@ libvmbackup_la_LIBADD = libvmbackup_la_LIBADD += @GOBJECT_LIBS@ libvmbackup_la_LIBADD += @VMTOOLS_LIBS@ libvmbackup_la_SOURCES = libvmbackup_la_SOURCES += nullProvider.c libvmbackup_la_SOURCES += scriptOps.c libvmbackup_la_SOURCES += stateMachine.c libvmbackup_la_SOURCES += syncDriverOps.c libvmbackup_la_SOURCES += vmBackupSignals.c BUILT_SOURCES = BUILT_SOURCES += vmBackupSignals.c BUILT_SOURCES += vmBackupSignals.h CLEANFILES = CLEANFILES += vmBackupSignals.c CLEANFILES += vmBackupSignals.h EXTRA_DIST = EXTRA_DIST += vmBackupSignals.gm vmBackupSignals.c: $(top_srcdir)/services/plugins/vmbackup/vmBackupSignals.gm glib-genmarshal --body $(top_srcdir)/services/plugins/vmbackup/vmBackupSignals.gm > \ $@ || (rm -f $@ && exit 1) vmBackupSignals.h: $(top_srcdir)/services/plugins/vmbackup/vmBackupSignals.gm glib-genmarshal --header $(top_srcdir)/services/plugins/vmbackup/vmBackupSignals.gm > \ $@ || (rm -f $@ && exit 1) open-vm-tools-9.4.0-1280544/services/plugins/vmbackup/syncDriverOps.c0000644765153500003110000002317312220061556023537 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * syncDriverOps.c -- * * Implements the sync driver provider for the backup state machine. */ #include "vmBackupInt.h" #include "file.h" #include "procMgr.h" #include "syncDriver.h" #include "util.h" #ifdef _WIN32 #include #include #endif typedef struct VmBackupDriverOp { VmBackupOp callbacks; const char *volumes; Bool freeze; Bool canceled; SyncDriverHandle *syncHandle; } VmBackupDriverOp; /* *----------------------------------------------------------------------------- * * VmBackupDriverThaw -- * * Thaws the frozen filesystems, and cleans up internal state kept by the * code. * * Results: * Whether thawing was successful. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool VmBackupDriverThaw(VmBackupDriverOp *op) { Bool success = SyncDriver_Thaw(*op->syncHandle); SyncDriver_CloseHandle(op->syncHandle); return success; } /* *----------------------------------------------------------------------------- * * VmBackupDriverOpQuery -- * * Checks the status of the operation that is enabling or disabling the * sync driver. * * Result * VMBACKUP_STATUS_PENDING: still working. * VMBACKUP_STATUS_FINISHED: done. * VMBACKUP_STATUS_CANCELED: cancel request fulfilled. * VMBACKUP_STATUS_ERROR: oops. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static VmBackupOpStatus VmBackupDriverOpQuery(VmBackupOp *_op) // IN { VmBackupDriverOp *op = (VmBackupDriverOp *) _op; VmBackupOpStatus ret; if (op->freeze) { SyncDriverStatus st = SyncDriver_QueryStatus(*op->syncHandle, 0); g_debug("SyncDriver status: %d\n", st); switch(st) { case SYNCDRIVER_BUSY: ret = VMBACKUP_STATUS_PENDING; break; case SYNCDRIVER_IDLE: if (op->canceled) { VmBackupDriverThaw(op); } /* * This prevents the release callback from freeing the handle, which * will be used when thawing in the POSIX case. */ op->syncHandle = NULL; ret = (op->canceled) ? VMBACKUP_STATUS_CANCELED : VMBACKUP_STATUS_FINISHED; break; default: VmBackupDriverThaw(op); ret = VMBACKUP_STATUS_ERROR; break; } } else { ret = VMBACKUP_STATUS_FINISHED; } return ret; } /* *----------------------------------------------------------------------------- * * VmBackupDriverOpRelease -- * * Cleans up data held by the state object. * * Result * The status of the app. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VmBackupDriverOpRelease(VmBackupOp *_op) // IN { VmBackupDriverOp *op = (VmBackupDriverOp *) _op; free(op->syncHandle); free(op); } /* *----------------------------------------------------------------------------- * * VmBackupDriverOpCancel -- * * Cancel an ongoing sync driver operation. This doesn't actually * cancel the operation, but rather waits for it to finish, since * just killing the worker thread might have undesired side effects. * This will not cancel thaw operations. * * Result * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VmBackupDriverOpCancel(VmBackupOp *_op) // IN { VmBackupDriverOp *op = (VmBackupDriverOp *) _op; op->canceled = TRUE; } /* *----------------------------------------------------------------------------- * * VmBackupNewDriverOp -- * * Enables or disables the sync driver. Note: "volumes" is not copied, * to avoid unnecessary waste of memory, since it's kept in the global * backup state structure. * * Result * A state object, unless some error occurs. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static VmBackupDriverOp * VmBackupNewDriverOp(VmBackupState *state, // IN Bool freeze, // IN SyncDriverHandle *handle, // IN const char *volumes) // IN { Bool success; VmBackupDriverOp *op = NULL; g_return_val_if_fail((handle == NULL || *handle == SYNCDRIVER_INVALID_HANDLE) || !freeze, NULL); op = Util_SafeMalloc(sizeof *op); memset(op, 0, sizeof *op); op->callbacks.queryFn = VmBackupDriverOpQuery; op->callbacks.cancelFn = VmBackupDriverOpCancel; op->callbacks.releaseFn = VmBackupDriverOpRelease; op->freeze = freeze; op->volumes = volumes; op->syncHandle = g_new0(SyncDriverHandle, 1); *op->syncHandle = (handle != NULL) ? *handle : SYNCDRIVER_INVALID_HANDLE; if (freeze) { success = SyncDriver_Freeze(op->volumes, op->syncHandle); } else { success = VmBackupDriverThaw(op); } if (!success) { g_warning("Error %s filesystems.", freeze ? "freezing" : "thawing"); free(op); op = NULL; } return op; } /* *----------------------------------------------------------------------------- * * VmBackupSyncDriverReadyForSnapshot -- * * Sends an event to the VMX indicating that the guest is ready for a * snapshot to be taken (i.e., scripts have run and sync driver is * enabled). * * Result * TRUE, unless sending the message fails. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool VmBackupSyncDriverReadyForSnapshot(VmBackupState *state) { SyncDriverHandle *handle = state->clientData; g_debug("*** %s\n", __FUNCTION__); if (handle != NULL && *handle != SYNCDRIVER_INVALID_HANDLE) { return VmBackup_SendEvent(VMBACKUP_EVENT_SNAPSHOT_COMMIT, 0, ""); } return TRUE; } /* Sync provider implementation. */ /* *----------------------------------------------------------------------------- * * VmBackupSyncDriverStart -- * * Starts an asynchronous operation to enable the sync driver. * * Result * TRUE, unless an error occurs. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool VmBackupSyncDriverStart(VmBackupState *state, void *clientData) { VmBackupDriverOp *op; g_debug("*** %s\n", __FUNCTION__); op = VmBackupNewDriverOp(state, TRUE, NULL, state->volumes); if (op != NULL) { state->clientData = op->syncHandle; } return VmBackup_SetCurrentOp(state, (VmBackupOp *) op, VmBackupSyncDriverReadyForSnapshot, __FUNCTION__); } /* *----------------------------------------------------------------------------- * * VmBackupSyncDriverSnapshotDone -- * * Starts an asynchronous operation to disable the sync driver. * * Result * TRUE, unless an error occurs. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool VmBackupSyncDriverSnapshotDone(VmBackupState *state, void *clientData) { VmBackupDriverOp *op; g_debug("*** %s\n", __FUNCTION__); op = VmBackupNewDriverOp(state, FALSE, state->clientData, NULL); g_free(state->clientData); state->clientData = NULL; return VmBackup_SetCurrentOp(state, (VmBackupOp *) op, NULL, __FUNCTION__); } /* *----------------------------------------------------------------------------- * * VmBackupSyncDriverRelease -- * * Frees the given pointer. * * Result * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VmBackupSyncDriverRelease(struct VmBackupSyncProvider *provider) { free(provider); } /* *----------------------------------------------------------------------------- * * VmBackup_NewSyncDriverProvider -- * * Returns a new VmBackupSyncProvider that will enable the sync driver * as part of the "sync" operation of a backup. * * Result * NULL on error. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VmBackupSyncProvider * VmBackup_NewSyncDriverProvider(void) { VmBackupSyncProvider *provider; if (!SyncDriver_Init()) { g_debug("Error initializing the sync driver.\n"); return NULL; } provider = Util_SafeMalloc(sizeof *provider); provider->start = VmBackupSyncDriverStart; provider->snapshotDone = VmBackupSyncDriverSnapshotDone; provider->release = VmBackupSyncDriverRelease; provider->clientData = NULL; return provider; } open-vm-tools-9.4.0-1280544/services/plugins/vmbackup/scriptOps.c0000644765153500003110000003612212220061556022711 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * scriptOps.c -- * * Functions for handling freeze/thaw scripts. */ #include "vmBackupInt.h" #include #include #include "vm_basic_defs.h" #include "file.h" #include "guestApp.h" #include "procMgr.h" #include "str.h" #include "util.h" /* * These are legacy scripts used before the vmbackup-based backups. To * aid people who will be transitioned to the new scheme after we're * deprecating the old code paths, also check for them when running * freeze / thaw scripts. The paths were hardcoded like this in hostd * before (although they were configurable in hostd's config file), so * there's no point in figuring out the correct Windows directory for * this particular feature. */ #if defined(_WIN32) # define LEGACY_FREEZE_SCRIPT "c:\\windows\\pre-freeze-script.bat" # define LEGACY_THAW_SCRIPT "c:\\windows\\post-thaw-script.bat" #else # define LEGACY_FREEZE_SCRIPT "/usr/sbin/pre-freeze-script" # define LEGACY_THAW_SCRIPT "/usr/sbin/post-thaw-script" #endif typedef struct VmBackupScript { char *path; ProcMgr_AsyncProc *proc; } VmBackupScript; typedef struct VmBackupScriptOp { VmBackupOp callbacks; Bool canceled; Bool thawFailed; VmBackupScriptType type; VmBackupState *state; } VmBackupScriptOp; /* *----------------------------------------------------------------------------- * * VmBackupGetScriptPath -- * * Returns the path where the scripts to be executed reside. * * Result * A string with the requested path. * * Side effects: * Allocates memory for the path. * *----------------------------------------------------------------------------- */ static char * VmBackupGetScriptPath(void) { char *scriptPath = NULL; char *installPath = GuestApp_GetInstallPath(); if (installPath == NULL) { return NULL; } scriptPath = Str_Asprintf(NULL, "%s%s%s", installPath, DIRSEPS, "backupScripts.d"); free(installPath); return scriptPath; } /* *----------------------------------------------------------------------------- * * VmBackupRunNextScript -- * * Runs the next script for the given operation. If thawing (or running * scripts after a failure), this function will try as much as possible * to start a script, meaning that if it fails to start a script it will * try to start the preceding one until one script is run, or it runs out * of scripts to try. * * Results: * -1: an error occurred. * 0: no more scripts to run. * 1: script was started. * * Side effects: * Increments (or decrements) the "current script" index in the backup state. * *----------------------------------------------------------------------------- */ static int VmBackupRunNextScript(VmBackupScriptOp *op) // IN/OUT { const char *scriptOp; int ret = 0; ssize_t index; VmBackupScript *scripts = op->state->scripts; switch (op->type) { case VMBACKUP_SCRIPT_FREEZE: index = ++op->state->currentScript; scriptOp = "freeze"; break; case VMBACKUP_SCRIPT_FREEZE_FAIL: index = --op->state->currentScript; scriptOp = "freezeFail"; break; case VMBACKUP_SCRIPT_THAW: index = --op->state->currentScript; scriptOp = "thaw"; break; default: NOT_REACHED(); } while (index >= 0 && scripts[index].path != NULL) { char *cmd; if (File_IsFile(scripts[index].path)) { if (op->state->scriptArg != NULL) { cmd = Str_Asprintf(NULL, "\"%s\" %s \"%s\"", scripts[index].path, scriptOp, op->state->scriptArg); } else { cmd = Str_Asprintf(NULL, "\"%s\" %s", scripts[index].path, scriptOp); } if (cmd != NULL) { g_debug("Running script: %s\n", cmd); scripts[index].proc = ProcMgr_ExecAsync(cmd, NULL); } else { g_debug("Failed to allocate memory to run script: %s\n", scripts[index].path); scripts[index].proc = NULL; } vm_free(cmd); if (scripts[index].proc == NULL) { if (op->type == VMBACKUP_SCRIPT_FREEZE) { ret = -1; break; } else { op->thawFailed = TRUE; } } else { ret = 1; break; } } if (op->type == VMBACKUP_SCRIPT_FREEZE) { index = ++op->state->currentScript; } else { index = --op->state->currentScript; } /* * This happens if all thaw/fail scripts failed to start. Since the first * entry may be a legacy script (which may not exist), need to check * whether the interesting failure is the first or the second entry in * the script list. */ if (index == -1) { size_t failIdx = 0; if (!File_IsFile(scripts[0].path)) { failIdx = 1; } if (scripts[failIdx].proc == NULL && scripts[failIdx].path != NULL) { ret = -1; } } } return ret; } /* *----------------------------------------------------------------------------- * * VmBackupStringCompare -- * * Comparison function used to sort the script list in ascending order. * * Result * The result of strcmp(str1, str2). * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int VmBackupStringCompare(const void *str1, // IN const void *str2) // IN { return strcmp(* (char * const *) str1,* (char * const *) str2); } /* *----------------------------------------------------------------------------- * * VmBackupScriptOpQuery -- * * Checks the status of the current running script. If the script is * finished, run the next script in the queue or, if no scripts are left, * return a "finished" status. * * Result * The status of the operation. * * Side effects: * Might start a new process. * *----------------------------------------------------------------------------- */ static VmBackupOpStatus VmBackupScriptOpQuery(VmBackupOp *_op) // IN { VmBackupOpStatus ret = VMBACKUP_STATUS_PENDING; VmBackupScriptOp *op = (VmBackupScriptOp *) _op; VmBackupScript *scripts = op->state->scripts; VmBackupScript *currScript = NULL; if (scripts != NULL && op->state->currentScript >= 0) { currScript = &scripts[op->state->currentScript]; } if (op->canceled) { ret = VMBACKUP_STATUS_CANCELED; goto exit; } else if (scripts == NULL || currScript == NULL || currScript->proc == NULL) { ret = VMBACKUP_STATUS_FINISHED; goto exit; } if (!ProcMgr_IsAsyncProcRunning(currScript->proc)) { int exitCode; Bool succeeded; succeeded = (ProcMgr_GetExitCode(currScript->proc, &exitCode) == 0 && exitCode == 0); ProcMgr_Free(currScript->proc); currScript->proc = NULL; /* * If thaw scripts fail, keep running and only notify the failure after * all others have run. */ if (!succeeded) { if (op->type == VMBACKUP_SCRIPT_FREEZE) { ret = VMBACKUP_STATUS_ERROR; goto exit; } else if (op->type == VMBACKUP_SCRIPT_THAW) { op->thawFailed = TRUE; } } switch (VmBackupRunNextScript(op)) { case -1: ret = VMBACKUP_STATUS_ERROR; break; case 0: ret = op->thawFailed ? VMBACKUP_STATUS_ERROR : VMBACKUP_STATUS_FINISHED; break; default: break; } } exit: if (ret == VMBACKUP_STATUS_ERROR) { /* Report the script error to the host */ VmBackup_SendEvent(VMBACKUP_EVENT_REQUESTOR_ERROR, VMBACKUP_SCRIPT_ERROR, "Custom quiesce script failed."); } return ret; } /* *----------------------------------------------------------------------------- * * VmBackupScriptOpRelease -- * * Frees memory allocated for the state object. Behavior is undefined * if the memory is freed before the query function says the operation * if finished. * * Result * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VmBackupScriptOpRelease(VmBackupOp *_op) // IN { size_t i; VmBackupScriptOp *op = (VmBackupScriptOp *) _op; if (op->type != VMBACKUP_SCRIPT_FREEZE && op->state->scripts != NULL) { VmBackupScript *scripts = op->state->scripts; for (i = 0; scripts[i].path != NULL; i++) { free(scripts[i].path); if (scripts[i].proc != NULL) { ProcMgr_Free(scripts[i].proc); } } free(op->state->scripts); op->state->scripts = NULL; op->state->currentScript = 0; } free(op); } /* *----------------------------------------------------------------------------- * * VmBackupScriptOpCancel -- * * Cancels the current operation. Kills any currently running script and * flags the operation as canceled. * * Result * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VmBackupScriptOpCancel(VmBackupOp *_op) // IN { VmBackupScriptOp *op = (VmBackupScriptOp *) _op; VmBackupScript *scripts = op->state->scripts; VmBackupScript *currScript = NULL; ProcMgr_Pid pid; if (scripts != NULL) { currScript = &scripts[op->state->currentScript]; ASSERT(currScript->proc != NULL); pid = ProcMgr_GetPid(currScript->proc); if (!ProcMgr_KillByPid(pid)) { // XXX: what to do in this situation? other than log and cry? } else { int exitCode; ProcMgr_GetExitCode(currScript->proc, &exitCode); } } op->canceled = TRUE; } /* *----------------------------------------------------------------------------- * * VmBackupNewScriptOp -- * * Creates a new state object to monitor the execution of OnFreeze or * OnThaw scripts. This will identify all the scripts in the backup scripts * directory and add them to an execution queue. * * Note: there is some state created when instantianting the "OnFreeze" * scripts which is only released after the "OnThaw" scripts are run. So * the caller has to make sure that thaw (or fail) scripts are run every * time the freeze scripts are run. * * Result * A pointer to the operation state, or NULL on failure. * * Side effects: * If there are scripts to be executed, the first one is started. * *----------------------------------------------------------------------------- */ VmBackupOp * VmBackup_NewScriptOp(VmBackupScriptType type, // IN VmBackupState *state) // IN { Bool fail = FALSE; char **fileList = NULL; char *scriptDir = NULL; int numFiles = 0; size_t i; VmBackupScriptOp *op = NULL; scriptDir = VmBackupGetScriptPath(); if (scriptDir == NULL) { goto exit; } op = calloc(1, sizeof *op); if (op == NULL) { goto exit; } op->state = state; op->type = type; op->callbacks.queryFn = VmBackupScriptOpQuery; op->callbacks.cancelFn = VmBackupScriptOpCancel; op->callbacks.releaseFn = VmBackupScriptOpRelease; g_debug("Trying to run scripts from %s\n", scriptDir); /* * Load the list of scripts to run when freezing. The same list will be * used later in case of failure, or when thawing, in reverse order. * * This logic won't recurse into directories, so only files directly under * the script dir will be considered. * * Legacy scripts will be the first ones to run (or last ones in the * case of thawing). If either the legacy freeze or thaw script * exist, the first entry in the script list will be reserved for * them, and their path might not exist (in case, for example, the * freeze script exists but the thaw script doesn't). */ if (type == VMBACKUP_SCRIPT_FREEZE) { VmBackupScript *scripts = NULL; int legacy = 0; size_t idx = 0; state->scripts = NULL; state->currentScript = 0; if (File_IsFile(LEGACY_FREEZE_SCRIPT) || File_IsFile(LEGACY_THAW_SCRIPT)) { legacy = 1; } if (File_IsDirectory(scriptDir)) { numFiles = File_ListDirectory(scriptDir, &fileList); } if (numFiles + legacy > 0) { scripts = calloc(numFiles + legacy + 1, sizeof *scripts); if (scripts == NULL) { fail = TRUE; goto exit; } /* * VmBackupRunNextScript increments the index, so need to make it point * to "before the first script". */ state->currentScript = -1; state->scripts = scripts; } if (legacy > 0) { scripts[idx++].path = Util_SafeStrdup(LEGACY_FREEZE_SCRIPT); } if (numFiles > 0) { size_t i; if (numFiles > 1) { qsort(fileList, (size_t) numFiles, sizeof *fileList, VmBackupStringCompare); } for (i = 0; i < numFiles; i++) { char *script; script = Str_Asprintf(NULL, "%s%c%s", scriptDir, DIRSEPC, fileList[i]); if (script == NULL) { fail = TRUE; goto exit; } else if (File_IsFile(script)) { scripts[idx++].path = script; } else { free(script); } } } } else if (state->scripts != NULL) { VmBackupScript *scripts = state->scripts; if (strcmp(scripts[0].path, LEGACY_FREEZE_SCRIPT) == 0) { vm_free(scripts[0].path); scripts[0].path = Util_SafeStrdup(LEGACY_THAW_SCRIPT); } } /* * If there are any scripts to be executed, start the first one. If we get to * this point, we won't free the scripts array until VmBackupScriptOpRelease * is called after thawing (or after the sync provider failed and the "fail" * scripts are run). */ fail = (state->scripts != NULL && VmBackupRunNextScript(op) == -1); exit: /* Free the file list. */ for (i = 0; i < numFiles; i++) { free(fileList[i]); } free(fileList); if (fail && op != NULL) { VmBackup_Release((VmBackupOp *) op); op = NULL; } free(scriptDir); return (VmBackupOp *) op; } open-vm-tools-9.4.0-1280544/services/plugins/vmbackup/Makefile.in0000644765153500003110000006651412220061625022631 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = services/plugins/vmbackup DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(plugin_LTLIBRARIES) libvmbackup_la_DEPENDENCIES = am_libvmbackup_la_OBJECTS = libvmbackup_la-nullProvider.lo \ libvmbackup_la-scriptOps.lo libvmbackup_la-stateMachine.lo \ libvmbackup_la-syncDriverOps.lo \ libvmbackup_la-vmBackupSignals.lo libvmbackup_la_OBJECTS = $(am_libvmbackup_la_OBJECTS) libvmbackup_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libvmbackup_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libvmbackup_la_SOURCES) DIST_SOURCES = $(libvmbackup_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ plugindir = @VMSVC_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libvmbackup.la libvmbackup_la_CPPFLAGS = @PLUGIN_CPPFLAGS@ libvmbackup_la_LDFLAGS = @PLUGIN_LDFLAGS@ libvmbackup_la_LIBADD = @GOBJECT_LIBS@ @VMTOOLS_LIBS@ libvmbackup_la_SOURCES = nullProvider.c scriptOps.c stateMachine.c \ syncDriverOps.c vmBackupSignals.c BUILT_SOURCES = vmBackupSignals.c vmBackupSignals.h CLEANFILES = vmBackupSignals.c vmBackupSignals.h EXTRA_DIST = vmBackupSignals.gm all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu services/plugins/vmbackup/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu services/plugins/vmbackup/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ } uninstall-pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ done clean-pluginLTLIBRARIES: -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) @list='$(plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libvmbackup.la: $(libvmbackup_la_OBJECTS) $(libvmbackup_la_DEPENDENCIES) $(EXTRA_libvmbackup_la_DEPENDENCIES) $(libvmbackup_la_LINK) -rpath $(plugindir) $(libvmbackup_la_OBJECTS) $(libvmbackup_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvmbackup_la-nullProvider.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvmbackup_la-scriptOps.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvmbackup_la-stateMachine.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvmbackup_la-syncDriverOps.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvmbackup_la-vmBackupSignals.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libvmbackup_la-nullProvider.lo: nullProvider.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvmbackup_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libvmbackup_la-nullProvider.lo -MD -MP -MF $(DEPDIR)/libvmbackup_la-nullProvider.Tpo -c -o libvmbackup_la-nullProvider.lo `test -f 'nullProvider.c' || echo '$(srcdir)/'`nullProvider.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libvmbackup_la-nullProvider.Tpo $(DEPDIR)/libvmbackup_la-nullProvider.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nullProvider.c' object='libvmbackup_la-nullProvider.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvmbackup_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libvmbackup_la-nullProvider.lo `test -f 'nullProvider.c' || echo '$(srcdir)/'`nullProvider.c libvmbackup_la-scriptOps.lo: scriptOps.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvmbackup_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libvmbackup_la-scriptOps.lo -MD -MP -MF $(DEPDIR)/libvmbackup_la-scriptOps.Tpo -c -o libvmbackup_la-scriptOps.lo `test -f 'scriptOps.c' || echo '$(srcdir)/'`scriptOps.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libvmbackup_la-scriptOps.Tpo $(DEPDIR)/libvmbackup_la-scriptOps.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='scriptOps.c' object='libvmbackup_la-scriptOps.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvmbackup_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libvmbackup_la-scriptOps.lo `test -f 'scriptOps.c' || echo '$(srcdir)/'`scriptOps.c libvmbackup_la-stateMachine.lo: stateMachine.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvmbackup_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libvmbackup_la-stateMachine.lo -MD -MP -MF $(DEPDIR)/libvmbackup_la-stateMachine.Tpo -c -o libvmbackup_la-stateMachine.lo `test -f 'stateMachine.c' || echo '$(srcdir)/'`stateMachine.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libvmbackup_la-stateMachine.Tpo $(DEPDIR)/libvmbackup_la-stateMachine.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='stateMachine.c' object='libvmbackup_la-stateMachine.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvmbackup_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libvmbackup_la-stateMachine.lo `test -f 'stateMachine.c' || echo '$(srcdir)/'`stateMachine.c libvmbackup_la-syncDriverOps.lo: syncDriverOps.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvmbackup_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libvmbackup_la-syncDriverOps.lo -MD -MP -MF $(DEPDIR)/libvmbackup_la-syncDriverOps.Tpo -c -o libvmbackup_la-syncDriverOps.lo `test -f 'syncDriverOps.c' || echo '$(srcdir)/'`syncDriverOps.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libvmbackup_la-syncDriverOps.Tpo $(DEPDIR)/libvmbackup_la-syncDriverOps.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='syncDriverOps.c' object='libvmbackup_la-syncDriverOps.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvmbackup_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libvmbackup_la-syncDriverOps.lo `test -f 'syncDriverOps.c' || echo '$(srcdir)/'`syncDriverOps.c libvmbackup_la-vmBackupSignals.lo: vmBackupSignals.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvmbackup_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libvmbackup_la-vmBackupSignals.lo -MD -MP -MF $(DEPDIR)/libvmbackup_la-vmBackupSignals.Tpo -c -o libvmbackup_la-vmBackupSignals.lo `test -f 'vmBackupSignals.c' || echo '$(srcdir)/'`vmBackupSignals.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libvmbackup_la-vmBackupSignals.Tpo $(DEPDIR)/libvmbackup_la-vmBackupSignals.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vmBackupSignals.c' object='libvmbackup_la-vmBackupSignals.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvmbackup_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libvmbackup_la-vmBackupSignals.lo `test -f 'vmBackupSignals.c' || echo '$(srcdir)/'`vmBackupSignals.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(plugindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pluginLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pluginLTLIBRARIES .MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-pluginLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-pluginLTLIBRARIES install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-pluginLTLIBRARIES vmBackupSignals.c: $(top_srcdir)/services/plugins/vmbackup/vmBackupSignals.gm glib-genmarshal --body $(top_srcdir)/services/plugins/vmbackup/vmBackupSignals.gm > \ $@ || (rm -f $@ && exit 1) vmBackupSignals.h: $(top_srcdir)/services/plugins/vmbackup/vmBackupSignals.gm glib-genmarshal --header $(top_srcdir)/services/plugins/vmbackup/vmBackupSignals.gm > \ $@ || (rm -f $@ && exit 1) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/services/plugins/timeSync/0000755765153500003110000000000012220061625020533 5ustar dtormtsopen-vm-tools-9.4.0-1280544/services/plugins/timeSync/slewAdjtime.c0000644765153500003110000000551012220061556023153 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file slewAdjtime.c * * Implementation of slewing using Posix adjtime system call. */ #include "timeSync.h" #include "timeSyncPosix.h" #include #include #include #include #include #include #include #include "vm_assert.h" /* ****************************************************************************** * TimeSync_DisableTimeSlew -- */ /** * * Disable time slewing, canceling any pending slew. * * @return TRUE on success. * ****************************************************************************** */ Bool TimeSync_DisableTimeSlew(void) { struct timeval tx = {0}; int error; error = adjtime(&tx, NULL); if (error == -1) { g_debug("adjtime failed: %s\n", strerror(errno)); return FALSE; } return TRUE; } /* ****************************************************************************** * TimeSync_Slew -- */ /** * * Slew the clock, correcting 'delta' microseconds. timeSyncPeriod is * ignored by this implementation. Report the amount of the previous * correction that has not been applied. * * @param[in] delta Correction to apply in us. * @param[in] timeSyncPeriod Time interval in us. * @param[out] remaining Amount of previous correction not applied. * * @return TRUE on success. * ****************************************************************************** */ Bool TimeSync_Slew(int64 delta, int64 timeSyncPeriod, int64 *remaining) { struct timeval tx; struct timeval oldTx; int error; TimeSyncWriteTimeVal(delta, &tx); error = adjtime(&tx, &oldTx); if (error == -1) { g_debug("adjtime failed: %s\n", strerror(errno)); return FALSE; } g_debug("time slew start.\n"); *remaining = (int64)oldTx.tv_sec * US_PER_SEC + (int64)oldTx.tv_usec; return TRUE; } open-vm-tools-9.4.0-1280544/services/plugins/timeSync/slewLinux.c0000644765153500003110000001146412220061556022702 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file slewLinux.c * * Implementation of slewing using Linux's adjtimex system call to alter * the tick length. */ #include "timeSync.h" #include "timeSyncPosix.h" #include #include #include #include #include #include #include #include "vm_assert.h" /* * The interval between two ticks (in usecs) can only be altered by 10%, * and the default value is 10000. So the values 900000L and 1000000L * divided by USER_HZ, which is 100. */ #ifdef __linux__ # define USER_HZ 100 /* from asm/param.h */ # define TICK_INCR_NOMINAL (1000000L / USER_HZ) /* nominal tick increment */ # define TICK_INCR_MAX (1100000L / USER_HZ) /* maximum tick increment */ # define TICK_INCR_MIN (900000L / USER_HZ) /* minimum tick increment */ #endif /* ****************************************************************************** * TimeSync_DisableTimeSlew -- */ /** * * Disable time slewing, setting the tick frequency to default. If failed to * disable the tick frequency, system time will not reflect the actual time - * it will be behind. * * @return TRUE on success. * ****************************************************************************** */ Bool TimeSync_DisableTimeSlew(void) { struct timex tx; int error; tx.modes = ADJ_TICK; tx.tick = TICK_INCR_NOMINAL; error = adjtimex(&tx); if (error == -1) { g_debug("adjtimex failed: %s\n", strerror(errno)); return FALSE; } g_debug("time slew end\n"); return TRUE; } /* ****************************************************************************** * TimeSync_Slew -- */ /** * * Slew the clock so that the time difference is covered within the * timeSyncPeriod. timeSyncPeriod is the interval of the time sync loop * and we intend to catch up delta us. Report the amount of the previous * correction that has not been applied (this may be negative if more than * timeSyncPeriod elapsed since the last call). * * This changes the tick frequency and hence needs to be reset after the time * sync is achieved. * * All times are in microseconds. * * @param[in] delta Correction to apply. * @param[in] timeSyncPeriod Time interval. * @param[out] remaining Amount of previous correction not applied. * * @return TRUE on success. * ****************************************************************************** */ Bool TimeSync_Slew(int64 delta, int64 timeSyncPeriod, int64 *remaining) { static int64 startTime = 0; static int64 tickLength; static int64 deltaRequested; struct timex tx; int error; int64 now; ASSERT(timeSyncPeriod > 0); if (!TimeSync_GetCurrentTime(&now)) { return FALSE; } if (startTime != 0) { int64 ticksElapsed = (now - startTime) / tickLength; int64 deltaApplied = ticksElapsed * (tickLength - TICK_INCR_NOMINAL); *remaining = deltaRequested - deltaApplied; } /* * Set the tick length so that delta time is corrected in * timeSyncPeriod period. tick is the number of microseconds added per * clock tick. We adjust this so that we get the desired delta + the * timeSyncPeriod in timeSyncPeriod interval. */ tickLength = (timeSyncPeriod + delta) / ((timeSyncPeriod / US_PER_SEC) * USER_HZ); if (tickLength > TICK_INCR_MAX) { tickLength = TICK_INCR_MAX; } else if (tickLength < TICK_INCR_MIN) { tickLength = TICK_INCR_MIN; } tx.tick = tickLength; tx.modes = ADJ_TICK; ASSERT(delta != 0 || tickLength == TICK_INCR_NOMINAL); startTime = now; deltaRequested = delta; error = adjtimex(&tx); if (error == -1) { startTime = 0; g_debug("adjtimex failed: %s\n", strerror(errno)); return FALSE; } g_debug("time slew start: %ld\n", tx.tick); return TRUE; } open-vm-tools-9.4.0-1280544/services/plugins/timeSync/pllLinux.c0000644765153500003110000001347712220061556022525 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file pllLinux.c * * Implementation of the NTP PLL using Linux's adjtimex system call. */ #include "timeSync.h" #include "timeSyncPosix.h" #include #include #include #include #include #include #include #include "vm_assert.h" static void TimeSyncLogPLLState(const char *prefix, struct timex *tx) { g_debug("%s : off %ld freq %ld maxerr %ld esterr %ld status %d " "const %ld precision %ld tolerance %ld tick %ld\n", prefix, tx->offset, tx->freq, tx->maxerror, tx->esterror, tx->status, tx->constant, tx->precision, tx->tolerance, tx->tick); } /* ****************************************************************************** * TimeSync_PLLSupported -- */ /** * * Report whether the platform supports an NTP style Type-II Phase Locked * Loop for correcting the time. * * @return TRUE iff NTP Phase Locked Loop is supported. * ****************************************************************************** */ Bool TimeSync_PLLSupported(void) { return TRUE; } /* ****************************************************************************** * TimeSync_PLLSetFrequency -- */ /** * * Set the frequency of the PLL. * * @param[in] ppmCorrection The parts per million error that should be * corrected. This value is the ppm shifted * left by 16 to match NTP. * * @return TRUE on success. * ****************************************************************************** */ Bool TimeSync_PLLSetFrequency(int64 ppmCorrection) { struct timex tx; int error; tx.modes = ADJ_FREQUENCY; tx.freq = ppmCorrection; error = adjtimex(&tx); if (error == -1) { g_debug("%s: adjtimex failed: %d %s\n", __FUNCTION__, error, strerror(errno)); return FALSE; } TimeSyncLogPLLState(__FUNCTION__, &tx); return TRUE; } /* ****************************************************************************** * TimeSync_PLLUpdate -- */ /** * * Updates the PLL with a new offset. * * @param[in] offset The offset between the host and the guest. * * @return TRUE on success. * ****************************************************************************** */ Bool TimeSync_PLLUpdate(int64 offset) { struct timex tx; int error; if (offset < -500000) { offset = -500000; g_debug("%s: clamped offset at -500000\n", __FUNCTION__); } if (offset > 500000) { offset = 500000; g_debug("%s: clamped offset at 500000\n", __FUNCTION__); } tx.modes = ADJ_OFFSET | ADJ_MAXERROR | ADJ_ESTERROR; tx.offset = offset; tx.esterror = 0; tx.maxerror = 0; error = adjtimex(&tx); if (error == -1) { g_debug("%s: adjtimex set offset failed: %d %s\n", __FUNCTION__, error, strerror(errno)); return FALSE; } TimeSyncLogPLLState(__FUNCTION__, &tx); /* Ensure that the kernel discipline is in the right mode. STA_PLLs * should be set and STA_UNSYNC should not be set. * * The time constant is a bit trickier. In "Computer Network Time * Synchronization" the terms used are "time constant" and "poll * exponent" where time constant = 2 ^ poll exponent. Valid values for * the poll exponent are 4 through 17, corresponding to a range of 16s * to 131072s (36 hours). On linux things are a bit different though: * tx.constant appears to be the poll exponent and when trying to set * the poll exponent, tx.constant should be set to poll exponent - 4. * * We want to set the time constant to as low a value as possible. The * core NTP PLL that the kernel discipline implements is built assuming * that there is a clock filter with a variable delay of up to 8. * Since TimeSyncReadHostAndGuest retries if the error is large, we * don't need to implement the clock filter. Hence we want a time * constant of 60/8 = 7, but settle for the lowest available: 16. This * allows us to react to changes relatively fast. */ if (tx.constant != 4) { tx.modes = ADJ_TIMECONST; tx.constant = 0; error = adjtimex(&tx); if (error == -1) { g_debug("%s: adjtimex set time constant failed: %d %s\n", __FUNCTION__, error, strerror(errno)); return FALSE; } g_debug("Set PLL time constant\n"); TimeSyncLogPLLState(__FUNCTION__, &tx); } if ((tx.status & STA_PLL) != STA_PLL || (tx.status & STA_UNSYNC) != 0) { tx.modes = ADJ_STATUS; tx.status = STA_PLL; error = adjtimex(&tx); if (error == -1) { g_debug("%s: adjtimex set status failed: %d %s\n", __FUNCTION__, error, strerror(errno)); return FALSE; } g_debug("Set PLL status\n"); TimeSyncLogPLLState(__FUNCTION__, &tx); } return TRUE; } open-vm-tools-9.4.0-1280544/services/plugins/timeSync/pllNone.c0000644765153500003110000000475512220061556022324 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file pllNone.c * * Null implementation of the NTP PLL. */ #include "timeSync.h" #include "vm_assert.h" /* ****************************************************************************** * TimeSync_PLLSupported -- */ /** * * Report whether the platform supports an NTP style Type-II Phase Locked * Loop for correcting the time. * * @return TRUE iff NTP Phase Locked Loop is supported. * ****************************************************************************** */ Bool TimeSync_PLLSupported(void) { return FALSE; } /* ****************************************************************************** * TimeSync_PLLSetFrequency -- */ /** * * Set the frequency of the PLL. * * @param[in] ppmCorrection The parts per million error that should be * corrected. This value is the ppm shifted * left by 16 to match NTP. * * @return FALSE * ****************************************************************************** */ Bool TimeSync_PLLSetFrequency(int64 ppmCorrection) { NOT_IMPLEMENTED(); return FALSE; } /* ****************************************************************************** * TimeSync_PLLUpdate -- */ /** * * Updates the PLL with a new offset. * * @param[in] offset The offset between the host and the guest. * * @return FALSE * ****************************************************************************** */ Bool TimeSync_PLLUpdate(int64 offset) { NOT_IMPLEMENTED(); return FALSE; } open-vm-tools-9.4.0-1280544/services/plugins/timeSync/timeSyncPosix.c0000644765153500003110000000605712220061556023530 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file timeSyncPosix.c * * Implementation of time sync functions for POSIX systems. */ #include "timeSync.h" #include "timeSyncPosix.h" #include #include #include #include #include #include #include "vm_assert.h" /* ****************************************************************************** * TimeSync_AddToCurrentTime -- */ /** * * Adjust the current system time by adding the given number of * microseconds. This function disables any time slewing to correctly set * the guest time. * * @param[in] delta Microseconds to add. * * @return TRUE on success. * ****************************************************************************** */ Bool TimeSync_AddToCurrentTime(int64 delta) { struct timeval tv; int64 newTime; int64 now; if (!TimeSync_GetCurrentTime(&now)) { return FALSE; } newTime = now + delta; ASSERT(newTime > 0); /* * timeval.tv_sec is a 32-bit signed integer. So, Linux will treat * newTime as a time before the epoch if newTime is a time 68 years * after the epoch (beacuse of overflow). * * If it is a 64-bit linux, everything should be fine. */ if (sizeof tv.tv_sec < 8 && newTime / US_PER_SEC > MAX_INT32) { g_debug("overflow: delta=%"FMT64"d, now=%"FMT64"d\n", delta, now); return FALSE; } TimeSyncWriteTimeVal(newTime, &tv); if (settimeofday(&tv, NULL) < 0) { return FALSE; } return TRUE; } /* ****************************************************************************** * TimeSync_GetCurrentTime -- */ /** * * Get the system time in seconds & microseconds. * * @param[in] secs Where to store the number of seconds. * @param[in] usecs Where to store the number of microseconds. * * @return TRUE on success. * ****************************************************************************** */ Bool TimeSync_GetCurrentTime(int64 *now) { struct timeval tv; ASSERT(now); if (gettimeofday(&tv, NULL) < 0) { return FALSE; } *now = (int64)tv.tv_sec * US_PER_SEC + (int64)tv.tv_usec; return TRUE; } open-vm-tools-9.4.0-1280544/services/plugins/timeSync/timeSync.h0000644765153500003110000000272112220061556022504 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _TIMESYNC_INT_H_ #define _TIMESYNC_INT_H_ /** * @file timeSync.h * * Functions and definitions related to syncing time. */ #define G_LOG_DOMAIN "timeSync" #include "vm_basic_types.h" #define US_PER_SEC 1000000 Bool TimeSync_GetCurrentTime(int64 *now); Bool TimeSync_AddToCurrentTime(int64 delta); Bool TimeSync_Slew(int64 delta, int64 timeSyncPeriod, int64 *remaining); Bool TimeSync_DisableTimeSlew(void); Bool TimeSync_PLLUpdate(int64 offset); Bool TimeSync_PLLSetFrequency(int64 ppmCorrection); Bool TimeSync_PLLSupported(void); #endif /* _TIMESYNC_INT_H_ */ open-vm-tools-9.4.0-1280544/services/plugins/timeSync/timeSyncPosix.h0000644765153500003110000000374312220061556023534 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _TIMESYNC_POSIX_H_ #define _TIMESYNC_POSIX_H_ /** * @file timeSyncPosix.h * * Posix specific functions and definitions related to syncing time. */ #include "timeSync.h" #include "vm_assert.h" #include /* ****************************************************************************** * TimeSyncWriteTimeVal -- */ /** * * Convert time represented as microseconds, to a timeval. This function * handles positive and negative values for "time." For a timeval to be * valid tv_usec must be between 0 and 999999. See * http://www.gnu.org/s/libc/manual/html_node/Elapsed-Time.html for more * details. * ****************************************************************************** */ static INLINE void TimeSyncWriteTimeVal(int64 time, struct timeval *tv) { int64 sec = time / US_PER_SEC; int64 usec = time - sec * US_PER_SEC; if (usec < 0) { usec += US_PER_SEC; sec--; } ASSERT(0 <= usec && usec < US_PER_SEC && time == sec * US_PER_SEC + usec); tv->tv_sec = sec; tv->tv_usec = usec; } #endif /* _TIMESYNC_INT_H_ */ open-vm-tools-9.4.0-1280544/services/plugins/timeSync/COPYING0000644765153500003110000006347112220061556021604 0ustar dtormts GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! open-vm-tools-9.4.0-1280544/services/plugins/timeSync/Makefile.am0000644765153500003110000000301412220061556022570 0ustar dtormts################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ plugindir = @VMSVC_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libtimeSync.la libtimeSync_la_CPPFLAGS = libtimeSync_la_CPPFLAGS += @PLUGIN_CPPFLAGS@ libtimeSync_la_LDFLAGS = libtimeSync_la_LDFLAGS += @PLUGIN_LDFLAGS@ libtimeSync_la_LIBADD = libtimeSync_la_LIBADD += @VMTOOLS_LIBS@ libtimeSync_la_SOURCES = libtimeSync_la_SOURCES += timeSync.c libtimeSync_la_SOURCES += timeSyncPosix.c if SOLARIS libtimeSync_la_SOURCES += slewAdjtime.c libtimeSync_la_SOURCES += pllNone.c endif if FREEBSD libtimeSync_la_SOURCES += slewAdjtime.c libtimeSync_la_SOURCES += pllNone.c endif if LINUX libtimeSync_la_SOURCES += slewLinux.c libtimeSync_la_SOURCES += pllLinux.c endif open-vm-tools-9.4.0-1280544/services/plugins/timeSync/timeSync.c0000644765153500003110000007161212220061556022504 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file timeSync.c * * Plugin to handle time synchronization between the guest and host. * * There are two types of corrections this plugin makes: one time and periodic. * * Periodic time synchronization is done when tools.timeSync is enabled * (this corresponds with the Synchronize Host and Guest Time checkbox in * the toolbox). When it is active time is corrected once per period * (typically every 60 seconds). * * One time corrections are done: at tools startup, resuming from suspend, * after disk shrink and other times when the guest has not been running * for a while. * * There are two basic methods for correcting the time: stepping and slewing. * * Stepping the time explictly sets the time in the guest to the time on * the host. This a brute force approach that isn't very accurate. Any * delay between deciding what to set the time to and actually setting the * time introduces error into the new time. Additionally setting the time * backwards can confuse some applications. During normal operation this * plugin only steps the time forward and only if the error is greater * than one second. * * Slewing time changes the rate of time advancement allowing errors to be * corrected smoothly (thus it is possible to correct time in the guest * being ahead of time on the host without time in the guest ever going * backwards). An additional advantage is that only a relative change is * made, so delays in effecting a change don't introduce a large error * like they might with stepping the time. One thing to note is that * windows has a notion of slewing being enabled/disabled independant of * whether the slew is set to nominal, so we track three states: disabled, * enabled-nominal, and enabled-active. * * Interacting with other time sync agents: * * When stepping it is relatively easy to co-exist with another time sync * agent. We will only run into issues when we try to step the time at * exactly the same time as the other agent. Since we are relatively * conservative about when to step, this is very unlikely. * * When slewing the time we will conflict much more directly with any * other time sync agent that is trying to slew the time since only one * slew rate can be active at any given time. To play as nicely as * possible we only change the slew when necessary: * * 1. When starting the timesync loop reset the slew to nominal to clean * up any odd state left behind a previous time sync agent. For * example vmware tools could have been running with a slew and then * crashed. Reseting to nominal gives us a reasonable starting point. * An additional bonus is that on Windows turning on slewing (even when * left at nominal) turns off windows' built in time synchronization * according to MSDN. * * 2. When stopping the timesync loop disable slewing. * * 3. When we stop slewing (either because we move to a host that doesn't * support BDOOR_CMD_GETTIMEFULL_WITH_LAG or slew correction was * disabled), reset the slew rate to nominal. * * 4. When stepping the time, reset slewing to nominal if it isn't * already. * * 5. Avoid changing the slew in any other circumstance. This allows a * another agent to slew the time when we are not actively slewing. */ #include "timeSync.h" #include "backdoor.h" #include "backdoor_def.h" #include "conf.h" #include "msg.h" #include "strutil.h" #include "system.h" #include "vmware/guestrpc/timesync.h" #include "vmware/tools/plugin.h" #include "vmware/tools/utils.h" #if !defined(__APPLE__) #include "embed_version.h" #include "vmtoolsd_version.h" VM_EMBED_VERSION(VMTOOLSD_VERSION_STRING); #endif /* Sync the time once a minute. */ #define TIMESYNC_TIME 60 /* Correct PERCENT_CORRECTION percent of the error each period. */ #define TIMESYNC_PERCENT_CORRECTION 50 /* When measuring the difference between time on the host and time in the * guest we try up to TIMESYNC_MAX_SAMPLES times to read a sample * where the two host reads are within TIMESYNC_GOOD_SAMPLE_THRESHOLD * microseconds. */ #define TIMESYNC_MAX_SAMPLES 4 #define TIMESYNC_GOOD_SAMPLE_THRESHOLD 2000 /* Once the error drops below TIMESYNC_PLL_ACTIVATE, activate the PLL. * 500ppm error acumulated over a 60 second interval can produce 30ms of * error. */ #define TIMESYNC_PLL_ACTIVATE (30 * 1000) /* 30ms. */ /* If the error goes above TIMESYNC_PLL_UNSYNC, deactivate the PLL. */ #define TIMESYNC_PLL_UNSYNC (2 * TIMESYNC_PLL_ACTIVATE) /* Period during which the frequency error of guest time is measured. */ #define TIMESYNC_CALIBRATION_DURATION (15 * 60 * US_PER_SEC) /* 15min. */ typedef enum TimeSyncState { TIMESYNC_INITIALIZING, TIMESYNC_STOPPED, TIMESYNC_RUNNING, } TimeSyncState; typedef enum TimeSyncSlewState { TimeSyncUncalibrated, TimeSyncCalibrating, TimeSyncPLL, } TimeSyncSlewState; typedef struct TimeSyncData { gboolean slewActive; gboolean slewCorrection; uint32 slewPercentCorrection; uint32 timeSyncPeriod; /* In seconds. */ TimeSyncState state; TimeSyncSlewState slewState; GSource *timer; } TimeSyncData; static void TimeSyncSetSlewState(TimeSyncData *data, gboolean active); static void TimeSyncResetSlew(TimeSyncData *data); /** * Read the time reported by the Host OS. * * @param[out] host Time on the Host. * @param[out] apparentError Apparent time error = apparent - real. * @param[out] apparentErrorValid Did the platform inform us of apparentError. * @param[out] maxTimeError Maximum amount of error than can go. * uncorrected. * * @return TRUE on success. */ static gboolean TimeSyncReadHost(int64 *host, int64 *apparentError, Bool *apparentErrorValid, int64 *maxTimeError) { Backdoor_proto bp; int64 maxTimeLag; int64 interruptLag; int64 hostSecs; int64 hostUsecs; Bool timeLagCall; /* * We need 3 things from the host, and there exist 3 different versions of * the calls (described further below): * 1) host time * 2) maximum time lag allowed (config option), which is a * threshold that keeps the tools from being over eager about * resetting the time when it is only a little bit off. * 3) interrupt lag (the amount that apparent time lags real time) * * First 2 versions of the call add interrupt lag to the maximum allowed * time lag, where as in the last call it is returned separately. * * Three versions of the call: * * - BDOOR_CMD_GETTIME: suffers from a 136-year overflow problem that * cannot be corrected without breaking backwards compatibility with * older Tools. So, we have the newer BDOOR_CMD_GETTIMEFULL, which is * overflow safe. * * - BDOOR_CMD_GETTIMEFULL: overcomes the problem above. * * - BDOOR_CMD_GETTIMEFULL_WITH_LAG: Both BDOOR_CMD_GETTIMEFULL and * BDOOR_CMD_GETTIME returns max lag limit as interrupt lag + the maximum * allowed time lag. BDOOR_CMD_GETTIMEFULL_WITH_LAG separates these two * values. This is helpful when synchronizing time backwards by slewing * the clock. * * We use BDOOR_CMD_GETTIMEFULL_WITH_LAG first and fall back to * BDOOR_CMD_GETTIMEFULL or BDOOR_CMD_GETTIME. * * Note that BDOOR_CMD_GETTIMEFULL and BDOOR_CMD_GETTIMEFULL_WITH_LAG will * not touch EAX when it succeeds. So we check for errors by comparing EAX to * BDOOR_MAGIC, which was set by the call to Backdoor() prior to touching the * backdoor port. */ bp.in.cx.halfs.low = BDOOR_CMD_GETTIMEFULL_WITH_LAG; Backdoor(&bp); if (bp.out.ax.word == BDOOR_MAGIC) { hostSecs = ((uint64)bp.out.si.word << 32) | bp.out.dx.word; interruptLag = bp.out.di.word; timeLagCall = TRUE; g_debug("Using BDOOR_CMD_GETTIMEFULL_WITH_LAG\n"); } else { g_debug("BDOOR_CMD_GETTIMEFULL_WITH_LAG not supported by current host, " "attempting BDOOR_CMD_GETTIMEFULL\n"); interruptLag = 0; timeLagCall = FALSE; bp.in.cx.halfs.low = BDOOR_CMD_GETTIMEFULL; Backdoor(&bp); if (bp.out.ax.word == BDOOR_MAGIC) { hostSecs = ((uint64)bp.out.si.word << 32) | bp.out.dx.word; } else { g_debug("BDOOR_CMD_GETTIMEFULL not supported by current host, " "attempting BDOOR_CMD_GETTIME\n"); bp.in.cx.halfs.low = BDOOR_CMD_GETTIME; Backdoor(&bp); hostSecs = bp.out.ax.word; } } hostUsecs = bp.out.bx.word; maxTimeLag = bp.out.cx.word; *host = hostSecs * US_PER_SEC + hostUsecs; *apparentError = -interruptLag; *apparentErrorValid = timeLagCall; *maxTimeError = maxTimeLag; if (hostSecs <= 0) { g_warning("Invalid host OS time: %"FMT64"d secs, %"FMT64"d usecs.\n\n", hostSecs, hostUsecs); return FALSE; } return TRUE; } /** * Read the Guest OS time and the Host OS time. * * There are three time domains that are revelant here: * 1. Guest time - the time reported by the guest * 2. Apparent time - the time reported by the virtualization layer * 3. Host time - the time reported by the host operating system. * * This function reports the host time, the guest time and the difference * between apparent time and host time (apparentError). The host and * guest time may be sampled multiple times to ensure an accurate reading. * * @param[out] host Time on the Host. * @param[out] guest Time in the Guest. * @param[out] apparentError Apparent time error = apparent - real. * @param[out] apparentErrorValid Did the platform inform us of apparentError. * @param[out] maxTimeError Maximum amount of error than can go. * uncorrected. * * @return TRUE on success. */ static gboolean TimeSyncReadHostAndGuest(int64 *host, int64 *guest, int64 *apparentError, Bool *apparentErrorValid, int64 *maxTimeError) { int64 host1, host2, hostDiff; int64 tmpGuest, tmpApparentError, tmpMaxTimeError; Bool tmpApparentErrorValid; int64 bestHostDiff = MAX_INT64; int iter = 0; DEBUG_ONLY(static int64 lastHost = 0); *apparentErrorValid = FALSE; *host = *guest = *apparentError = *maxTimeError = 0; if (!TimeSyncReadHost(&host2, &tmpApparentError, &tmpApparentErrorValid, &tmpMaxTimeError)) { return FALSE; } do { iter++; host1 = host2; if (!TimeSync_GetCurrentTime(&tmpGuest)) { g_warning("Unable to retrieve the guest OS time: %s.\n\n", Msg_ErrString()); return FALSE; } if (!TimeSyncReadHost(&host2, &tmpApparentError, &tmpApparentErrorValid, &tmpMaxTimeError)) { return FALSE; } if (host1 < host2) { hostDiff = host2 - host1; } else { hostDiff = 0; } if (hostDiff <= bestHostDiff) { bestHostDiff = hostDiff; *host = host1 + hostDiff / 2; *guest = tmpGuest; *apparentError = tmpApparentError; *apparentErrorValid = tmpApparentErrorValid; *maxTimeError = tmpMaxTimeError; } } while (iter < TIMESYNC_MAX_SAMPLES && bestHostDiff > TIMESYNC_GOOD_SAMPLE_THRESHOLD); ASSERT(*host != 0 && *guest != 0); #ifdef VMX86_DEBUG g_debug("Daemon: Guest vs host error %.6fs; guest vs apparent error %.6fs; " "limit=%.2fs; apparentError %.6fs; iter=%d error=%.6fs; " "%.6f secs since last update\n", (*guest - *host) / 1000000.0, (*guest - *host - *apparentError) / 1000000.0, *maxTimeError / 1000000.0, *apparentError / 1000000.0, iter, bestHostDiff / 1000000.0, (*host - lastHost) / 1000000.0); lastHost = *host; #endif return TRUE; } /** * Set the guest OS time to the host OS time by stepping the time. * * @param[in] data Structure tracking time sync state. * @param[in] adjustment Amount to correct the guest time. */ gboolean TimeSyncStepTime(TimeSyncData *data, int64 adjustment) { Backdoor_proto bp; int64 before; int64 after; if (vmx86_debug) { TimeSync_GetCurrentTime(&before); } /* Stepping invalidates the current slew, reset to nominal. */ TimeSyncSetSlewState(data, FALSE); if (!TimeSync_AddToCurrentTime(adjustment)) { return FALSE; } /* * Tell timetracker to stop trying to catch up, since we have corrected * both the guest OS error and the apparent time error. */ bp.in.cx.halfs.low = BDOOR_CMD_STOPCATCHUP; Backdoor(&bp); if (vmx86_debug) { TimeSync_GetCurrentTime(&after); g_debug("Time changed by %"FMT64"dus from %"FMT64"d.%06"FMT64"d -> " "%"FMT64"d.%06"FMT64"d\n", adjustment, before / US_PER_SEC, before % US_PER_SEC, after / US_PER_SEC, after % US_PER_SEC); } return TRUE; } /** * Slew the guest OS time advancement to correct the time. * * In addition to standard slewing (implemented via TimeSync_Slew), we * also support using an NTP style PLL to slew the time. The PLL can take * a while to end up with an accurate measurement of the frequency error, * so before entering PLL mode we calibrate the frequency error over a * period of TIMESYNC_PLL_ACTIVATE seconds. * * When using standard slewing, only correct slewPercentCorrection of the * error. This is to avoid overcorrection when the error is mis-measured, * or overcorrection caused by the daemon waking up later than it is * supposed to leaving the slew in place for longer than anticpiated. * * @param[in] data Structure tracking time sync state. * @param[in] adjustment Amount to correct the guest time. */ static gboolean TimeSyncSlewTime(TimeSyncData *data, int64 adjustment) { static int64 calibrationStart; static int64 calibrationAdjustment; int64 now; int64 remaining = 0; int64 timeSyncPeriodUS = data->timeSyncPeriod * US_PER_SEC; int64 slewDiff = (adjustment * data->slewPercentCorrection) / 100; if (!TimeSync_GetCurrentTime(&now)) { return FALSE; } if (adjustment > TIMESYNC_PLL_UNSYNC && data->slewState != TimeSyncUncalibrated) { g_debug("Adjustment too large (%"FMT64"d), resetting PLL state.\n", adjustment); data->slewState = TimeSyncUncalibrated; } if (data->slewState == TimeSyncUncalibrated) { g_debug("Slewing time: adjustment %"FMT64"d\n", adjustment); if (!TimeSync_Slew(slewDiff, timeSyncPeriodUS, &remaining)) { data->slewState = TimeSyncUncalibrated; return FALSE; } if (adjustment < TIMESYNC_PLL_ACTIVATE && TimeSync_PLLSupported()) { g_debug("Starting PLL calibration.\n"); calibrationStart = now; /* Starting out the calibration period we are adjustment behind, * but have already requested to correct slewDiff of that. */ calibrationAdjustment = slewDiff - adjustment; data->slewState = TimeSyncCalibrating; } } else if (data->slewState == TimeSyncCalibrating) { if (now > calibrationStart + TIMESYNC_CALIBRATION_DURATION) { int64 ppmErr; /* Reset slewing to nominal and find out remaining slew. */ TimeSync_Slew(0, timeSyncPeriodUS, &remaining); calibrationAdjustment += adjustment; calibrationAdjustment -= remaining; ppmErr = ((1000000 * calibrationAdjustment) << 16) / (now - calibrationStart); if (ppmErr >> 16 < 500 && ppmErr >> 16 > -500) { g_debug("Activating PLL ppmEst=%"FMT64"d (%"FMT64"d)\n", ppmErr >> 16, ppmErr); TimeSync_PLLUpdate(adjustment); TimeSync_PLLSetFrequency(ppmErr); data->slewState = TimeSyncPLL; } else { /* PPM error is too large to try the PLL. */ g_debug("PPM error too large: %"FMT64"d (%"FMT64"d) " "not activating PLL\n", ppmErr >> 16, ppmErr); data->slewState = TimeSyncUncalibrated; } } else { g_debug("Calibrating error: adjustment %"FMT64"d\n", adjustment); if (!TimeSync_Slew(slewDiff, timeSyncPeriodUS, &remaining)) { return FALSE; } calibrationAdjustment += slewDiff; calibrationAdjustment -= remaining; } } else { ASSERT(data->slewState == TimeSyncPLL); g_debug("Updating PLL: adjustment %"FMT64"d\n", adjustment); if (!TimeSync_PLLUpdate(adjustment)) { TimeSyncResetSlew(data); } } return TRUE; } /** * Reset the slew to nominal. * * @param[in] data Structure tracking time sync state. */ static void TimeSyncResetSlew(TimeSyncData *data) { int64 remaining; int64 timeSyncPeriodUS = data->timeSyncPeriod * US_PER_SEC; data->slewState = TimeSyncUncalibrated; TimeSync_Slew(0, timeSyncPeriodUS, &remaining); if (TimeSync_PLLSupported()) { TimeSync_PLLUpdate(0); TimeSync_PLLSetFrequency(0); } } /** * Update whether slewing is used for time correction. * * @param[in] data Structure tracking time sync state. * @param[in] active Is slewing active. */ static void TimeSyncSetSlewState(TimeSyncData *data, gboolean active) { if (active != data->slewActive) { g_debug(active ? "Starting slew.\n" : "Stopping slew.\n"); if (!active) { TimeSyncResetSlew(data); } data->slewActive = active; } } /** * Set the guest OS time to the host OS time. * * @param[in] slewCorrection Is clock slewing enabled? * @param[in] syncOnce Is this function called in a loop? * @param[in] allowBackwardSync Can we sync time backwards when doing syncOnce? * @param[in] _data Time sync data. * * @return TRUE on success. */ static gboolean TimeSyncDoSync(Bool slewCorrection, Bool syncOnce, Bool allowBackwardSync, void *_data) { int64 guest, host; int64 gosError, apparentError, maxTimeError; Bool apparentErrorValid; TimeSyncData *data = _data; g_debug("Synchronizing time: " "syncOnce %d, slewCorrection %d, allowBackwardSync %d.\n", syncOnce, slewCorrection, allowBackwardSync); if (!TimeSyncReadHostAndGuest(&host, &guest, &apparentError, &apparentErrorValid, &maxTimeError)) { return FALSE; } gosError = guest - host - apparentError; if (syncOnce) { /* * Non-loop behavior: * * Perform a step correction if: * 1) The guest OS error is behind by more than maxTimeError. * 2) The guest OS is ahead of the host OS. */ if (gosError < -maxTimeError || (gosError + apparentError > 0 && allowBackwardSync)) { g_debug("One time synchronization: stepping time.\n"); if (!TimeSyncStepTime(data, -gosError + -apparentError)) { return FALSE; } } else { g_debug("One time synchronization: correction not needed.\n"); } } else { /* * Loop behavior: * * If guest error is more than maxTimeError behind perform a step * correction. Otherwise, if we can distinguish guest error from * apparent time error perform a slew correction . */ TimeSyncSetSlewState(data, apparentErrorValid && slewCorrection); if (gosError < -maxTimeError) { g_debug("Periodic synchronization: stepping time.\n"); if (!TimeSyncStepTime(data, -gosError + -apparentError)) { return FALSE; } } else if (slewCorrection && apparentErrorValid) { g_debug("Periodic synchronization: slewing time.\n"); if (!TimeSyncSlewTime(data, -gosError)) { return FALSE; } } } return TRUE; } /** * Run the "time synchronization" loop. * * @param[in] _data Time sync data. * * @return always TRUE. */ static gboolean ToolsDaemonTimeSyncLoop(gpointer _data) { TimeSyncData *data = _data; ASSERT(data != NULL); if (!TimeSyncDoSync(data->slewCorrection, FALSE, FALSE, data)) { g_warning("Unable to synchronize time.\n"); } return TRUE; } /** * Start the "time synchronization" loop. * * @param[in] ctx The application context. * @param[in] data Time sync data. * * @return TRUE on success. */ static Bool TimeSyncStartLoop(ToolsAppCtx *ctx, TimeSyncData *data) { ASSERT(data != NULL); ASSERT(data->state != TIMESYNC_RUNNING); ASSERT(data->timer == NULL); g_debug("Starting time sync loop.\n"); /* * Turn slew on and set it to nominal. */ TimeSyncResetSlew(data); g_debug("New sync period is %d sec.\n", data->timeSyncPeriod); if (!TimeSyncDoSync(data->slewCorrection, FALSE, FALSE, data)) { g_warning("Unable to synchronize time when starting time loop.\n"); } data->timer = g_timeout_source_new(data->timeSyncPeriod * 1000); VMTOOLSAPP_ATTACH_SOURCE(ctx, data->timer, ToolsDaemonTimeSyncLoop, data, NULL); data->state = TIMESYNC_RUNNING; return TRUE; } /** * Stop the "time synchronization" loop. * * @param[in] ctx The application context. * @param[in] data Time sync data. */ static void TimeSyncStopLoop(ToolsAppCtx *ctx, TimeSyncData *data) { ASSERT(data != NULL); ASSERT(data->state == TIMESYNC_RUNNING); ASSERT(data->timer != NULL); g_debug("Stopping time sync loop.\n"); TimeSyncSetSlewState(data, FALSE); TimeSync_DisableTimeSlew(); g_source_destroy(data->timer); g_source_unref(data->timer); data->timer = NULL; data->state = TIMESYNC_STOPPED; } /** * Sync the guest's time with the host's. * * @param[in] data RPC request data. * * @return TRUE on success. */ static gboolean TimeSyncTcloHandler(RpcInData *data) { Bool backwardSync = !strcmp(data->args, "1"); TimeSyncData *syncData = data->clientData; if (!TimeSyncDoSync(syncData->slewCorrection, TRUE, backwardSync, syncData)) { return RPCIN_SETRETVALS(data, "Unable to sync time", FALSE); } else { return RPCIN_SETRETVALS(data, "", TRUE); } } /** * Parses boolean option string. * * @param[in] string Option string to be parsed. * @param[out] gboolean Value of the option. * * @return TRUE on success. */ static gboolean ParseBoolOption(const gchar *string, gboolean *value) { if (strcmp(string, "1") == 0) { *value = TRUE; } else if (strcmp(string, "0") == 0) { *value = FALSE; } else { return FALSE; } return TRUE; } /** * Handles a "Set_Option" callback. Processes the time sync related options. * * @param[in] src The source object. * @param[in] ctx The app context. * @param[in] option Option being set. * @param[in] value Option value. * @param[in] plugin Plugin registration data. * * @return TRUE on success. */ static gboolean TimeSyncSetOption(gpointer src, ToolsAppCtx *ctx, const gchar *option, const gchar *value, ToolsPluginData *plugin) { static gboolean syncBeforeLoop; TimeSyncData *data = plugin->_private; if (strcmp(option, TOOLSOPTION_SYNCTIME) == 0) { gboolean start; if (!ParseBoolOption(value, &start)) { return FALSE; } if (start && data->state != TIMESYNC_RUNNING) { /* * Try the one-shot time sync if time sync transitions from * 'off' to 'on' and TOOLSOPTION_SYNCTIME_ENABLE is turned on. * Note that during startup we receive TOOLSOPTION_SYNCTIME * before receiving TOOLSOPTION_SYNCTIME_ENABLE and so the * one-shot sync will not be done here. Nor should it because * the startup synchronization behavior is controlled by * TOOLSOPTION_SYNCTIME_STARTUP which is handled separately. */ if (data->state == TIMESYNC_STOPPED && syncBeforeLoop) { TimeSyncDoSync(data->slewCorrection, TRUE, TRUE, data); } if (!TimeSyncStartLoop(ctx, data)) { g_warning("Unable to change time sync period.\n"); return FALSE; } } else if (!start) { if (data->state == TIMESYNC_RUNNING) { TimeSyncStopLoop(ctx, data); } else { data->state = TIMESYNC_STOPPED; } } } else if (strcmp(option, TOOLSOPTION_SYNCTIME_SLEWCORRECTION) == 0) { data->slewCorrection = strcmp(value, "0"); g_debug("Daemon: Setting slewCorrection, %d.\n", data->slewCorrection); } else if (strcmp(option, TOOLSOPTION_SYNCTIME_PERCENTCORRECTION) == 0) { int32 percent; g_debug("Daemon: Setting slewPercentCorrection to %s.\n", value); if (!StrUtil_StrToInt(&percent, value)) { return FALSE; } if (percent <= 0 || percent > 100) { data->slewPercentCorrection = TIMESYNC_PERCENT_CORRECTION; } else { data->slewPercentCorrection = percent; } } else if (strcmp(option, TOOLSOPTION_SYNCTIME_PERIOD) == 0) { uint32 period; if (!StrUtil_StrToUint(&period, value)) { return FALSE; } if (period <= 0) period = TIMESYNC_TIME; /* * If the sync loop is running and the time sync period has changed, * restart the loop with the new period value. If the sync loop is * not running, just remember the new sync period value. */ if (period != data->timeSyncPeriod) { data->timeSyncPeriod = period; if (data->state == TIMESYNC_RUNNING) { TimeSyncStopLoop(ctx, data); if (!TimeSyncStartLoop(ctx, data)) { g_warning("Unable to change time sync period.\n"); return FALSE; } } } } else if (strcmp(option, TOOLSOPTION_SYNCTIME_STARTUP) == 0) { static gboolean doneAlready = FALSE; gboolean doSync; if (!ParseBoolOption(value, &doSync)) { return FALSE; } if (doSync && !doneAlready && !TimeSyncDoSync(data->slewCorrection, TRUE, TRUE, data)) { g_warning("Unable to sync time during startup.\n"); return FALSE; } doneAlready = TRUE; } else if (strcmp(option, TOOLSOPTION_SYNCTIME_ENABLE) == 0) { if (!ParseBoolOption(value, &syncBeforeLoop)) { return FALSE; } } else { return FALSE; } return TRUE; } /** * Handles a shutdown callback; cleans up internal plugin state. * * @param[in] src The source object. * @param[in] ctx The app context. * @param[in] plugin Plugin registration data. */ static void TimeSyncShutdown(gpointer src, ToolsAppCtx *ctx, ToolsPluginData *plugin) { TimeSyncData *data = plugin->_private; if (data->state == TIMESYNC_RUNNING) { TimeSyncStopLoop(ctx, data); } g_free(data); } /** * Plugin entry point. Initializes internal state and returns the registration * data. * * @param[in] ctx The app context. * * @return The registration data. */ TOOLS_MODULE_EXPORT ToolsPluginData * ToolsOnLoad(ToolsAppCtx *ctx) { static ToolsPluginData regData = { "timeSync", NULL, NULL }; TimeSyncData *data = g_malloc(sizeof (TimeSyncData)); RpcChannelCallback rpcs[] = { { TIMESYNC_SYNCHRONIZE, TimeSyncTcloHandler, data, NULL, NULL, 0 } }; ToolsPluginSignalCb sigs[] = { { TOOLS_CORE_SIG_SET_OPTION, TimeSyncSetOption, ®Data }, { TOOLS_CORE_SIG_SHUTDOWN, TimeSyncShutdown, ®Data } }; ToolsAppReg regs[] = { { TOOLS_APP_GUESTRPC, VMTools_WrapArray(rpcs, sizeof *rpcs, ARRAYSIZE(rpcs)) }, { TOOLS_APP_SIGNALS, VMTools_WrapArray(sigs, sizeof *sigs, ARRAYSIZE(sigs)) } }; data->slewActive = FALSE; data->slewCorrection = FALSE; data->slewPercentCorrection = TIMESYNC_PERCENT_CORRECTION; data->state = TIMESYNC_INITIALIZING; data->slewState = TimeSyncUncalibrated; data->timeSyncPeriod = TIMESYNC_TIME; data->timer = NULL; regData.regs = VMTools_WrapArray(regs, sizeof *regs, ARRAYSIZE(regs)); regData._private = data; return ®Data; } open-vm-tools-9.4.0-1280544/services/plugins/timeSync/Makefile.in0000644765153500003110000006771212220061625022615 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @SOLARIS_TRUE@am__append_1 = slewAdjtime.c pllNone.c @FREEBSD_TRUE@am__append_2 = slewAdjtime.c pllNone.c @LINUX_TRUE@am__append_3 = slewLinux.c pllLinux.c subdir = services/plugins/timeSync DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(plugin_LTLIBRARIES) libtimeSync_la_DEPENDENCIES = am__libtimeSync_la_SOURCES_DIST = timeSync.c timeSyncPosix.c \ slewAdjtime.c pllNone.c slewLinux.c pllLinux.c @SOLARIS_TRUE@am__objects_1 = libtimeSync_la-slewAdjtime.lo \ @SOLARIS_TRUE@ libtimeSync_la-pllNone.lo @FREEBSD_TRUE@am__objects_2 = libtimeSync_la-slewAdjtime.lo \ @FREEBSD_TRUE@ libtimeSync_la-pllNone.lo @LINUX_TRUE@am__objects_3 = libtimeSync_la-slewLinux.lo \ @LINUX_TRUE@ libtimeSync_la-pllLinux.lo am_libtimeSync_la_OBJECTS = libtimeSync_la-timeSync.lo \ libtimeSync_la-timeSyncPosix.lo $(am__objects_1) \ $(am__objects_2) $(am__objects_3) libtimeSync_la_OBJECTS = $(am_libtimeSync_la_OBJECTS) libtimeSync_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libtimeSync_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libtimeSync_la_SOURCES) DIST_SOURCES = $(am__libtimeSync_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ plugindir = @VMSVC_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libtimeSync.la libtimeSync_la_CPPFLAGS = @PLUGIN_CPPFLAGS@ libtimeSync_la_LDFLAGS = @PLUGIN_LDFLAGS@ libtimeSync_la_LIBADD = @VMTOOLS_LIBS@ libtimeSync_la_SOURCES = timeSync.c timeSyncPosix.c $(am__append_1) \ $(am__append_2) $(am__append_3) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu services/plugins/timeSync/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu services/plugins/timeSync/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ } uninstall-pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ done clean-pluginLTLIBRARIES: -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) @list='$(plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libtimeSync.la: $(libtimeSync_la_OBJECTS) $(libtimeSync_la_DEPENDENCIES) $(EXTRA_libtimeSync_la_DEPENDENCIES) $(libtimeSync_la_LINK) -rpath $(plugindir) $(libtimeSync_la_OBJECTS) $(libtimeSync_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtimeSync_la-pllLinux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtimeSync_la-pllNone.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtimeSync_la-slewAdjtime.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtimeSync_la-slewLinux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtimeSync_la-timeSync.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtimeSync_la-timeSyncPosix.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libtimeSync_la-timeSync.lo: timeSync.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtimeSync_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtimeSync_la-timeSync.lo -MD -MP -MF $(DEPDIR)/libtimeSync_la-timeSync.Tpo -c -o libtimeSync_la-timeSync.lo `test -f 'timeSync.c' || echo '$(srcdir)/'`timeSync.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtimeSync_la-timeSync.Tpo $(DEPDIR)/libtimeSync_la-timeSync.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='timeSync.c' object='libtimeSync_la-timeSync.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtimeSync_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtimeSync_la-timeSync.lo `test -f 'timeSync.c' || echo '$(srcdir)/'`timeSync.c libtimeSync_la-timeSyncPosix.lo: timeSyncPosix.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtimeSync_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtimeSync_la-timeSyncPosix.lo -MD -MP -MF $(DEPDIR)/libtimeSync_la-timeSyncPosix.Tpo -c -o libtimeSync_la-timeSyncPosix.lo `test -f 'timeSyncPosix.c' || echo '$(srcdir)/'`timeSyncPosix.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtimeSync_la-timeSyncPosix.Tpo $(DEPDIR)/libtimeSync_la-timeSyncPosix.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='timeSyncPosix.c' object='libtimeSync_la-timeSyncPosix.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtimeSync_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtimeSync_la-timeSyncPosix.lo `test -f 'timeSyncPosix.c' || echo '$(srcdir)/'`timeSyncPosix.c libtimeSync_la-slewAdjtime.lo: slewAdjtime.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtimeSync_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtimeSync_la-slewAdjtime.lo -MD -MP -MF $(DEPDIR)/libtimeSync_la-slewAdjtime.Tpo -c -o libtimeSync_la-slewAdjtime.lo `test -f 'slewAdjtime.c' || echo '$(srcdir)/'`slewAdjtime.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtimeSync_la-slewAdjtime.Tpo $(DEPDIR)/libtimeSync_la-slewAdjtime.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='slewAdjtime.c' object='libtimeSync_la-slewAdjtime.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtimeSync_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtimeSync_la-slewAdjtime.lo `test -f 'slewAdjtime.c' || echo '$(srcdir)/'`slewAdjtime.c libtimeSync_la-pllNone.lo: pllNone.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtimeSync_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtimeSync_la-pllNone.lo -MD -MP -MF $(DEPDIR)/libtimeSync_la-pllNone.Tpo -c -o libtimeSync_la-pllNone.lo `test -f 'pllNone.c' || echo '$(srcdir)/'`pllNone.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtimeSync_la-pllNone.Tpo $(DEPDIR)/libtimeSync_la-pllNone.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pllNone.c' object='libtimeSync_la-pllNone.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtimeSync_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtimeSync_la-pllNone.lo `test -f 'pllNone.c' || echo '$(srcdir)/'`pllNone.c libtimeSync_la-slewLinux.lo: slewLinux.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtimeSync_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtimeSync_la-slewLinux.lo -MD -MP -MF $(DEPDIR)/libtimeSync_la-slewLinux.Tpo -c -o libtimeSync_la-slewLinux.lo `test -f 'slewLinux.c' || echo '$(srcdir)/'`slewLinux.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtimeSync_la-slewLinux.Tpo $(DEPDIR)/libtimeSync_la-slewLinux.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='slewLinux.c' object='libtimeSync_la-slewLinux.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtimeSync_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtimeSync_la-slewLinux.lo `test -f 'slewLinux.c' || echo '$(srcdir)/'`slewLinux.c libtimeSync_la-pllLinux.lo: pllLinux.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtimeSync_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtimeSync_la-pllLinux.lo -MD -MP -MF $(DEPDIR)/libtimeSync_la-pllLinux.Tpo -c -o libtimeSync_la-pllLinux.lo `test -f 'pllLinux.c' || echo '$(srcdir)/'`pllLinux.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtimeSync_la-pllLinux.Tpo $(DEPDIR)/libtimeSync_la-pllLinux.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pllLinux.c' object='libtimeSync_la-pllLinux.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtimeSync_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtimeSync_la-pllLinux.lo `test -f 'pllLinux.c' || echo '$(srcdir)/'`pllLinux.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(plugindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pluginLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pluginLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-pluginLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-pluginLTLIBRARIES install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-pluginLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/services/plugins/desktopEvents/0000755765153500003110000000000012220061624021575 5ustar dtormtsopen-vm-tools-9.4.0-1280544/services/plugins/desktopEvents/xioError.c0000644765153500003110000001200012220061556023547 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file xioError.c * * Handles responding to X11 I/O errors. */ /* Include first. Sets G_LOG_DOMAIN. */ #include "desktopEventsInt.h" #include #include #include #include #include #include #include "vmware/tools/desktopevents.h" static int gParentPid; static ToolsAppCtx *gCtx; static XIOErrorHandler gOrigHandler; /* ****************************************************************************** * DEXIOErrorHandler -- */ /** * * Handler for all X I/O errors. Xlib documentation says we should not * return when handling I/O errors. * * @param[in] dpy Unused. * * @return 1 (but doesn't really return). * ****************************************************************************** */ static int DEXIOErrorHandler(Display *dpy) { pid_t my_pid = getpid(); /* * ProcMgr_ExecAsync() needs to fork off a child to handle watching the * process being run. When it dies, it will come through here, so we don't * want to let it shut down the RPC channel. */ if (my_pid == gParentPid) { g_debug("%s", __func__); /* * Inform clients capable of/interested in quick'n'dirty cleanup upon an * X I/O error. */ g_signal_emit_by_name(gCtx->serviceObj, TOOLS_CORE_SIG_XIOERROR, gCtx); /* * XXX: the really correct thing to do here would be to properly stop all * plugins so that capabilities are unset and all other "clean shutdown" * tasks are performed. Unfortunately two things currently prevent that: * * . we can't rely on g_main_loop_quit() because we can't return from this * function (well, we can, but Xlib will exit() before vmtoolsd is able * to clean up things), so the main loop will never regain control off * the app. * * . we can't access the internal vmtoolsd functions that cleanly shuts * down plugins. * * So, right now, let's stick with just stopping the RPC channel so that * the host is notified the application is gone. This may cause temporary * issues with clients that only look at capabilities and not at the * status of vmusr. */ if (gCtx->rpc != NULL) { RpcChannel_Stop(gCtx->rpc); } exit(EXIT_FAILURE); } else { /* * _exit is used here so that any atexit() registered routines don't * interfere with any resources shared with the parent. */ g_debug("%s hit from forked() child", __func__); _exit(EXIT_FAILURE); } return 1; } /* ****************************************************************************** * XIOError_Init -- */ /** * * Sets up an X11 I/O error callback that stops the daemon. * * @param[in] ctx Application context. * @param[in] pdata Registration data. * * @return TRUE. * ****************************************************************************** */ gboolean XIOError_Init(ToolsAppCtx *ctx, ToolsPluginData *pdata) { gCtx = ctx; gParentPid = getpid(); gOrigHandler = XSetIOErrorHandler(DEXIOErrorHandler); g_signal_new(TOOLS_CORE_SIG_XIOERROR, G_OBJECT_TYPE(ctx->serviceObj), 0, // GSignalFlags 0, // class offset NULL, // accumulator NULL, // accu_data g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); return TRUE; } /* ****************************************************************************** * XIOError_Shutdown -- */ /** * * Shutdown function, restores the original X I/O error handler. * * @param[in] ctx Application context. * @param[in] pdata Plugin data (unused). * ****************************************************************************** */ void XIOError_Shutdown(ToolsAppCtx *ctx, ToolsPluginData *pdata) { XSetIOErrorHandler(gOrigHandler); gCtx = NULL; gOrigHandler = NULL; } open-vm-tools-9.4.0-1280544/services/plugins/desktopEvents/reload.c0000644765153500003110000000674412220061556023226 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file reload.c * * Code to respond to SIGUSR2 and restart the vmtoolsd instance. */ #include "desktopEventsInt.h" #include #include #include static GSource *gReloadSrc; /* ****************************************************************************** * ReloadSelf -- */ /** * * Signal handler for SIGUSR2. Stops the RPC channel and reloads the vmusr * instance. * * @param[in] info Unused. * @param[in] data The application context. * * @return FALSE. * ****************************************************************************** */ static gboolean ReloadSelf(const siginfo_t *info, gpointer data) { ToolsAppCtx *ctx = data; if (ctx->rpc != NULL) { RpcChannel_Stop(ctx->rpc); } Reload_Do(); return FALSE; } /* ****************************************************************************** * Reload_Do -- */ /** * * Re-launch vmware-user by attempting to execute VMUSER_TITLE ('vmware-user'), * relying on the user's search path. * * On success, vmware-user is relaunched in our stead. On failure, we exit with * EXIT_FAILURE. * ****************************************************************************** */ void Reload_Do(void) { g_debug("Reloading the vmusr instance."); execlp(VMUSER_TITLE, VMUSER_TITLE, NULL); _exit(EXIT_FAILURE); } /* ****************************************************************************** * Reload_Init -- */ /** * * Registers a signal handler for SIGUSR2 that reloads the container. * * @param[in] ctx Application context. * @param[in] pdata Registration data. * * @return TRUE. * ****************************************************************************** */ gboolean Reload_Init(ToolsAppCtx *ctx, ToolsPluginData *pdata) { gReloadSrc = VMTools_NewSignalSource(SIGUSR2); VMTOOLSAPP_ATTACH_SOURCE(ctx, gReloadSrc, ReloadSelf, ctx, NULL); return TRUE; } /* ****************************************************************************** * Reload_Shutdown -- */ /** * * Unregisters the SIGUSR2 signal handler. * * @param[in] ctx Application context. * @param[in] pdata Plugin data (unused). * ****************************************************************************** */ void Reload_Shutdown(ToolsAppCtx *ctx, ToolsPluginData *pdata) { g_source_destroy(gReloadSrc); g_source_unref(gReloadSrc); gReloadSrc = NULL; } open-vm-tools-9.4.0-1280544/services/plugins/desktopEvents/sessionMgrSignals.gm0000644765153500003110000000206612220061556025604 0ustar dtormts########################################################## # Copyright (C) 2011 VMware, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public # License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # ########################################################## ## # @file sessionMgrSignals.gm # # Defines the custom GClosure marshal functions for the desktopEvents::sessionMgr # signals. # # @see desktopEvents.h # # XSM SaveYourself signal. VOID:POINTER,INT,BOOLEAN,INT,BOOLEAN open-vm-tools-9.4.0-1280544/services/plugins/desktopEvents/Makefile.am0000644765153500003110000000444312220061556023642 0ustar dtormts################################################################################ ### Copyright 2010 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ plugindir = @VMUSR_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libdesktopEvents.la libdesktopEvents_la_CPPFLAGS = libdesktopEvents_la_CPPFLAGS += @GTK_CPPFLAGS@ libdesktopEvents_la_CPPFLAGS += @PLUGIN_CPPFLAGS@ libdesktopEvents_la_LDFLAGS = libdesktopEvents_la_LDFLAGS += @PLUGIN_LDFLAGS@ libdesktopEvents_la_LIBADD = libdesktopEvents_la_LIBADD += @COMMON_XLIBS@ libdesktopEvents_la_LIBADD += @GTK_LIBS@ libdesktopEvents_la_LIBADD += @VMTOOLS_LIBS@ libdesktopEvents_la_SOURCES = libdesktopEvents_la_SOURCES += desktopEvents.c libdesktopEvents_la_SOURCES += reload.c libdesktopEvents_la_SOURCES += x11Lock.c libdesktopEvents_la_SOURCES += xioError.c if HAVE_XSM libdesktopEvents_la_LIBADD += @XSM_LIBS@ libdesktopEvents_la_SOURCES += sessionMgr.c libdesktopEvents_la_SOURCES += sessionMgrSignals.c BUILT_SOURCES = BUILT_SOURCES += sessionMgrSignals.c BUILT_SOURCES += sessionMgrSignals.h CLEANFILES = CLEANFILES += sessionMgrSignals.c CLEANFILES += sessionMgrSignals.h EXTRA_DIST = EXTRA_DIST += sessionMgrSignals.gm sessionMgrSignals.c: $(top_srcdir)/services/plugins/desktopEvents/sessionMgrSignals.gm glib-genmarshal --body $(top_srcdir)/services/plugins/desktopEvents/sessionMgrSignals.gm > \ $@ || (rm -f $@ && exit 1) sessionMgrSignals.h: $(top_srcdir)/services/plugins/desktopEvents/sessionMgrSignals.gm glib-genmarshal --header $(top_srcdir)/services/plugins/desktopEvents/sessionMgrSignals.gm > \ $@ || (rm -f $@ && exit 1) endif open-vm-tools-9.4.0-1280544/services/plugins/desktopEvents/desktopEventsInt.h0000644765153500003110000000332712220061556025270 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _DESKTOPEVENTSINT_H_ #define _DESKTOPEVENTSINT_H_ /** * @file destopEventsInt.h * * Internal plugin definitions. */ #define VMW_TEXT_DOMAIN "desktopEvents" #define G_LOG_DOMAIN VMW_TEXT_DOMAIN #include "vmware/tools/plugin.h" typedef struct DesktopEventFuncs { gboolean (*initFn)(ToolsAppCtx *, ToolsPluginData *); void (*shutdownFn)(ToolsAppCtx *ctx, ToolsPluginData *); gboolean initialized; } DesktopEventFuncs; /* * This plugin's private data field is a GHashTable*. Each sub-feature may use * that table to keep its own private state. The following key is reserved and * points to the hosting application's ToolsAppCtx. */ #define DE_PRIVATE_CTX "ctx" /* * This platform-specific file defines the list of features available * for the current platform being built. */ #include "deFeatures.h" #endif /* _DESKTOPEVENTSINT_H_ */ open-vm-tools-9.4.0-1280544/services/plugins/desktopEvents/sessionMgr.c0000644765153500003110000004661012220061556024105 0ustar dtormts/********************************************************* * Copyright (C) 2011 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file sessionMgr.c * * Support for X session management using the, well, X Session Management * Library (libSM) with a little help from the Inter-Client Exchange Library * (libICE). This allows vmusr to receive X session lifecycle events and clean * up appropriately upon session termination. For now, cleanup upon shutdown * is the only activity we're interested in. * * A custom event source is used to bind libICE connections with GLib's main * loop and dispatch messages. As this is the first (and hopefully only) * libICE client, all ICE interaction is handled here (as opposed to in a * provider application). * * This should work with any session manager implementing XSMP, covering all * of our supported desktop environments. * * This plugin also maps the XSM callbacks to GLib signals. See desktopevents.h * for details. * * @todo Scrutinize libICE error handling. I/O errors should be handled here, * but errors handled by libICE's default may exit(). */ /* Include first. Sets G_LOG_DOMAIN. */ #include "desktopEventsInt.h" #include "vmware.h" #include "vmware/tools/desktopevents.h" #include "sessionMgrSignals.h" #include #include #include #include #include #include #include #include /* * Identifier used for SessionMgr private data in DesktopEvents private hash * table. */ #define DE_FEATURE_KEY "sessionMgr" static void InitSignals(ToolsAppCtx* ctx); static void InitSMProperties(SmcConn smcCnx); /* * libICE integration declarations. */ typedef struct { GSource *iceSource; IceConn iceCnx; } ICEWatchCtx; static gboolean ICEDispatch(GIOChannel *chn, GIOCondition cond, gpointer cbData); static void ICEIOErrorHandler(IceConn iceCnx); static void ICEWatch(IceConn iceCnx, IcePointer clientData, Bool opening, IcePointer *watchData); /* * libSM callbacks. */ static void SMDieCb(SmcConn smcCnx, SmPointer cbData); static void SMSaveYourselfCb(SmcConn smcCnx, SmPointer cbData, int saveType, Bool shutdown, int interactStyle, Bool fast); static void SMSaveCompleteCb(SmcConn smcCnx, SmPointer cbData); static void SMShutdownCancelledCb(SmcConn smcCnx, SmPointer cbData); /* ****************************************************************************** * SessionMgr_Init -- */ /** * * Register custom ICE connection source and sign up with the session manager. * * @param[in] ctx Application context. * @param[in] pdata Plugin data. * * @retval TRUE Always "succeeds". Session management is optional. * ****************************************************************************** */ gboolean SessionMgr_Init(ToolsAppCtx *ctx, ToolsPluginData *pdata) { SmcCallbacks smCallbacks; unsigned long cbMask = SmcSaveYourselfProcMask | SmcDieProcMask | SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask; SmcConn smcCnx; char errorBuf[128]; char *clientID = NULL; IceSetIOErrorHandler(ICEIOErrorHandler); IceAddConnectionWatch(ICEWatch, pdata); memset(&smCallbacks, 0, sizeof smCallbacks); smCallbacks.save_yourself.callback = &SMSaveYourselfCb; smCallbacks.save_yourself.client_data = pdata; smCallbacks.save_complete.callback = &SMSaveCompleteCb; smCallbacks.save_complete.client_data = pdata; smCallbacks.shutdown_cancelled.callback = &SMShutdownCancelledCb; smCallbacks.shutdown_cancelled.client_data = pdata; smCallbacks.die.callback = &SMDieCb; smCallbacks.die.client_data = pdata; smcCnx = SmcOpenConnection(NULL, NULL, SmProtoMajor, SmProtoMinor, cbMask, &smCallbacks, NULL, &clientID, sizeof errorBuf, errorBuf); if (smcCnx != NULL) { InitSignals(ctx); InitSMProperties(smcCnx); g_hash_table_insert(pdata->_private, DE_FEATURE_KEY, smcCnx); g_debug("Registered with session manager as %s\n", clientID); free(clientID); } else { g_message("Failed to register with session manager.\n"); g_message("SmcOpenConnection: %s\n", errorBuf); IceRemoveConnectionWatch(ICEWatch, pdata); } return TRUE; } /* ****************************************************************************** * SessionMgr_Shutdown -- */ /** * * Shuts down XSM and ICE interfaces and frees other resources. * * @param[in] ctx Application context. * @param[in] pdata Plugin data. * ****************************************************************************** */ void SessionMgr_Shutdown(ToolsAppCtx *ctx, ToolsPluginData *pdata) { GHashTable *desktopData = pdata->_private; SmcConn smcCnx = g_hash_table_lookup(desktopData, DE_FEATURE_KEY); if (smcCnx != NULL) { SmcCloseConnection(smcCnx, 0, NULL); IceRemoveConnectionWatch(ICEWatch, pdata); g_hash_table_remove(desktopData, DE_FEATURE_KEY); } } /* ****************************************************************************** * InitSignals -- */ /** * * Creates new signals for XSM events. * * @param[in] ctx ToolsAppCtx*: Application context. * ****************************************************************************** */ static void InitSignals(ToolsAppCtx *ctx) { /* SmcCallbacks::save_yourself */ g_signal_new(TOOLS_CORE_SIG_XSM_SAVE_YOURSELF, G_OBJECT_TYPE(ctx->serviceObj), 0, // GSignalFlags 0, // class offset NULL, // accumulator NULL, // accu_data g_cclosure_user_marshal_VOID__POINTER_INT_BOOLEAN_INT_BOOLEAN, G_TYPE_NONE, 5, G_TYPE_POINTER, G_TYPE_INT, G_TYPE_BOOLEAN, G_TYPE_INT, G_TYPE_BOOLEAN); /* SmcCallbacks::die */ g_signal_new(TOOLS_CORE_SIG_XSM_DIE, G_OBJECT_TYPE(ctx->serviceObj), 0, // GSignalFlags 0, // class offset NULL, // accumulator NULL, // accu_data g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); /* SmcCallbacks::save_complete */ g_signal_new(TOOLS_CORE_SIG_XSM_SAVE_COMPLETE, G_OBJECT_TYPE(ctx->serviceObj), 0, // GSignalFlags 0, // class offset NULL, // accumulator NULL, // accu_data g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); /* SmcCallbacks::shutdown_cancelled */ g_signal_new(TOOLS_CORE_SIG_XSM_SHUTDOWN_CANCELLED, G_OBJECT_TYPE(ctx->serviceObj), 0, // GSignalFlags 0, // class offset NULL, // accumulator NULL, // accu_data g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); } /* ****************************************************************************** * InitSMProperties -- */ /** * * Tell the session manager a little bit about ourself. * * The most important property to us is SmRestartStyleHint, where we hint to * the session manager that it shouldn't attempt to restore the vmusr container * as part of a session. (Instead, that job is handled by our XDG autostart * entry.) * * The other properties are set only because SMlib docs claim they're * mandatory. Dummy values are used where possible. * * @param[in] smcCnx SM client connection. * ****************************************************************************** */ static void InitSMProperties(SmcConn smcCnx) { enum { PROP_ID_CLONE_CMD, PROP_ID_PROGRAM, PROP_ID_RESTART_CMD, PROP_ID_RESTART_STYLE, PROP_ID_USER_ID, }; static uint8 restartHint = SmRestartNever; static SmPropValue values[] = { { sizeof "/bin/false" - 1, "/bin/false" }, { sizeof "vmware-user" - 1, "vmware-user" }, { sizeof "/bin/false" - 1, "/bin/false" }, { sizeof restartHint, &restartHint }, { 0, NULL }, }; static SmProp properties[] = { { SmCloneCommand, SmLISTofARRAY8, 1, &values[PROP_ID_CLONE_CMD] }, { SmProgram, SmARRAY8, 1, &values[PROP_ID_PROGRAM] }, { SmRestartCommand, SmLISTofARRAY8, 1, &values[PROP_ID_RESTART_CMD] }, { SmRestartStyleHint, SmCARD8, 1, &values[PROP_ID_RESTART_STYLE] }, { SmUserID, SmARRAY8, 1, &values[PROP_ID_USER_ID] }, }; static SmProp *propp[] = { &properties[0], &properties[1], &properties[2], &properties[3], &properties[4] }; struct passwd *pw = getpwuid(getuid()); values[PROP_ID_USER_ID].length = strlen(pw->pw_name); values[PROP_ID_USER_ID].value = pw->pw_name; SmcSetProperties(smcCnx, ARRAYSIZE(propp), (SmProp**)propp); } /* ****************************************************************************** * BEGIN libICE stuff. */ /* * A note on source reference counting: * * There are two entities that maintain references on ICEWatchCtx's GSource. * - GLib's GMainContext, and * - libICE's IceConn (via ICEWatch's watchData). * * A source's initial reference created in ICEWatch may be considered as * transferred to libICE until ICEWatch is again called upon connection close. * The second reference comes from attaching the source to the GLib main loop. */ /* ****************************************************************************** * ICEIOErrorHandler -- */ /** * * Handler for libICE I/O errors. * * Does nothing but replaces libICE's default handler which would've caused us * to exit. * * @param[in] iceCnx Opaque ICE connection descriptor. * ****************************************************************************** */ static void ICEIOErrorHandler(IceConn iceCnx) { g_message("%s: %s\n", __func__, strerror(errno)); } /* ****************************************************************************** * ICEDispatch -- */ /** * * GSource dispatch routine. Calls IceProcessMessages on the ICE connection. * * @param[in] chn GIOChannel event source * @param[in] cond condition satisfied (ignored) * @param[in] cbData (ICEWatchCtx*) Channel context. * * @retval TRUE Underlying iceCnx is still valid, so do not kill this source. * @retval FALSE Underlying iceCnx was destroyed, so remove this source. * ****************************************************************************** */ static gboolean ICEDispatch(GIOChannel *chn, GIOCondition cond, gpointer cbData) { IceProcessMessagesStatus status; ICEWatchCtx *watchCtx = cbData; ASSERT(watchCtx); /* * We ignore the error conditions here and let IceProcessMessages return * an IceProcessMessagesIOError, resulting in a single, shared error code * path. */ status = IceProcessMessages(watchCtx->iceCnx, NULL, NULL); switch (status) { case IceProcessMessagesSuccess: return TRUE; case IceProcessMessagesIOError: IceCloseConnection(watchCtx->iceCnx); // Let ICEWatch kill the source. return TRUE; case IceProcessMessagesConnectionClosed: /* * iceCnx was invalidated, so we won't see another call to ICEWatch, * so we'll return FALSE and let GLib destroy the source for us. */ watchCtx->iceCnx = NULL; g_source_unref(watchCtx->iceSource); return FALSE; } NOT_REACHED(); } /* ****************************************************************************** * ICEWatch -- */ /** * * libICE connection watching callback. * * Creates or removes GLib event sources upon ICE connection creation/ * destruction. * * From ICElib.xml: * "If opening is True the client should set the *watch_data pointer to * any data it may need to save until the connection is closed and the * watch procedure is invoked again with opening set to False." * * @param[in] iceCnx Opaque ICE connection descriptor. * @parma[in] cbData (ToolsPluginData*) plugin data * @param[in] opening True if creating a connection, False if closing. * @param[in] watchData See above. New source will be stored here. * ****************************************************************************** */ static void ICEWatch(IceConn iceCnx, IcePointer cbData, Bool opening, IcePointer *watchData) { ToolsPluginData *pdata = cbData; ToolsAppCtx *ctx; ctx = g_hash_table_lookup(pdata->_private, DE_PRIVATE_CTX); ASSERT(ctx); if (opening) { GIOChannel *iceChannel; GSource *iceSource; ICEWatchCtx *watchCtx; GError *error = NULL; iceChannel = g_io_channel_unix_new(IceConnectionNumber(iceCnx)); if (g_io_channel_set_encoding(iceChannel, NULL, &error) != G_IO_STATUS_NORMAL) { g_warning("%s: g_io_channel_set_encoding: %s\n", __func__, error->message); g_clear_error(&error); g_io_channel_unref(iceChannel); return; } g_io_channel_set_buffered(iceChannel, FALSE); iceSource = g_io_create_watch(iceChannel, G_IO_IN|G_IO_HUP|G_IO_ERR); g_io_channel_unref(iceChannel); // Ownership transferred to iceSource. watchCtx = g_new(ICEWatchCtx, 1); watchCtx->iceSource = iceSource; watchCtx->iceCnx = iceCnx; *watchData = watchCtx; VMTOOLSAPP_ATTACH_SOURCE(ctx, iceSource, &ICEDispatch, watchCtx, NULL); } else { ICEWatchCtx *watchCtx = *watchData; if (watchCtx) { watchCtx->iceCnx = NULL; if (watchCtx->iceSource) { g_source_destroy(watchCtx->iceSource); g_source_unref(watchCtx->iceSource); } g_free(watchCtx); *watchData = NULL; } } } /* * END libICE stuff. ****************************************************************************** */ /* ****************************************************************************** * BEGIN libSM stuff. */ /* ****************************************************************************** * SMDieCb -- */ /** * * Callback for a XSM "Die" event. * * Instructs the main loop to quit. We "acknowledge" the callback by closing * the connection in our shutdown handler. * * @param[in] smcCnx Opaque XSM connection object. * @param[in] cbData (ToolsPluginData*) Plugin data. * ****************************************************************************** */ static void SMDieCb(SmcConn smcCnx, SmPointer cbData) { ToolsPluginData *pdata = cbData; ToolsAppCtx *ctx; ASSERT(pdata); ctx = g_hash_table_lookup(pdata->_private, DE_PRIVATE_CTX); ASSERT(ctx); g_message("Session manager says our time is up. Exiting.\n"); g_signal_emit_by_name(ctx->serviceObj, TOOLS_CORE_SIG_XSM_DIE, ctx); g_main_loop_quit(ctx->mainLoop); } /* ****************************************************************************** * SMSaveYourselfCb -- */ /** * * Callback for XSM "SaveYourself" event. * * This event is sent to all XSM clients either to checkpoint a session * or in advance of a (cancellable) session shutdown event. If we needed * time to persist state, now would be the time to do it. Since we don't, * however, this is nearly a no-op -- we only acknowledge the manager. * * @param[in] smcCnx Opaque XSM connection object. * @param[in] cbData (ToolsPluginData*) Plugin data. * @param[in] saveType Refer to SMlib.xml. * @param[in] shutdown Checkpoint or shutdown? * @param[in] interactStyle May interact with user? * @param[in] fast Shutdown as quickly as possible. * * @todo Consider whether it'd make sense to unregister capabilities and pause * other plugins if shutdown == True until either we receive a 'die' or * 'shutdown cancelled' event. * ****************************************************************************** */ static void SMSaveYourselfCb(SmcConn smcCnx, SmPointer cbData, int saveType, Bool shutdown, int interactStyle, Bool fast) { ToolsPluginData *pdata = cbData; ToolsAppCtx *ctx; ASSERT(pdata); ctx = g_hash_table_lookup(pdata->_private, DE_PRIVATE_CTX); ASSERT(ctx); g_signal_emit_by_name(ctx->serviceObj, TOOLS_CORE_SIG_XSM_SAVE_YOURSELF, ctx, saveType, shutdown, interactStyle, fast); SmcSaveYourselfDone(smcCnx, True); } /* ****************************************************************************** * SMSaveCompleteCb -- */ /** * * Callback for XSM "SaveComplete" event. * * State has been checkpointed. Application may resume normal operations. * Total no-op. * * @param[in] smcCnx Opaque XSM connection object. * @param[in] cbData (ToolsPluginData*) Plugin data. * ****************************************************************************** */ static void SMSaveCompleteCb(SmcConn smcCnx, SmPointer cbData) { ToolsPluginData *pdata = cbData; ToolsAppCtx *ctx; ASSERT(pdata); ctx = g_hash_table_lookup(pdata->_private, DE_PRIVATE_CTX); ASSERT(ctx); g_signal_emit_by_name(ctx->serviceObj, TOOLS_CORE_SIG_XSM_SAVE_COMPLETE, ctx); } /* ****************************************************************************** * SMShutdownCancelledCb -- */ /** * * Callback for XSM "ShutdownCancelled" event. * * User cancelled shutdown. May resume normal operations. Again, total no-op. * * @param[in] smcCnx Opaque XSM connection object. * @param[in] cbData (ToolsPluginData*) Plugin data. * ****************************************************************************** */ static void SMShutdownCancelledCb(SmcConn smcCnx, SmPointer cbData) { ToolsPluginData *pdata = cbData; ToolsAppCtx *ctx; ASSERT(pdata); ctx = g_hash_table_lookup(pdata->_private, DE_PRIVATE_CTX); ASSERT(ctx); g_signal_emit_by_name(ctx->serviceObj, TOOLS_CORE_SIG_XSM_SHUTDOWN_CANCELLED, ctx); } /* * END libSM stuff. ****************************************************************************** */ open-vm-tools-9.4.0-1280544/services/plugins/desktopEvents/x11Lock.c0000644765153500003110000003033312220061556023171 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file x11lock.c * * Sets up an X11 lock atom and check it to avoid multiple running instances * of vmusr. */ #include "desktopEventsInt.h" #include "vmware.h" #include #include #include #include #include #define LOCK_ATOM_NAME "vmware-user-lock" /* ****************************************************************************** * InitGroupLeader -- */ /** * * This routine sets a few properties related to our main window created * by {gdk,gtk}_init. Specifically this routine sets the window title, * sets the override_redirect X11 property, and reparents it to the root * window, * * In addition, this routine will return Xlib handles for the following * objects: * - Main or group leader window * - Display's root window * * As a result of this function: * - groupLeader will have a title of VMUSER_TITLE. * - groupLeader, if not already directly parented by the root, will be. * * - dpy will point to our default display (ex: $DISPLAY). * - groupLeader will point to the window created by gtk_init(). * - rootWindow will point to the root window on $DISPLAY. * * @param[out] groupLeader Group leader window. * @param[out] rootWindow Root window. * * @return TRUE on success, FALSE on failure. * ****************************************************************************** */ static gboolean InitGroupLeader(Window *groupLeader, Window *rootWindow) { Window myGroupLeader; Window myRootWindow; XSetWindowAttributes attr; GdkDisplay *gdkDisplay; GdkWindow *gdkLeader; attr.override_redirect = True; ASSERT(groupLeader); ASSERT(rootWindow); gdkDisplay = gdk_display_get_default(); gdkLeader = gdk_display_get_default_group(gdkDisplay); myGroupLeader = GDK_WINDOW_XWINDOW(gdkLeader); myRootWindow = GDK_ROOT_WINDOW(); ASSERT(myGroupLeader); ASSERT(myRootWindow); /* XXX: With g_set_prgname() being called, this can probably go away. */ XStoreName(GDK_DISPLAY(), myGroupLeader, VMUSER_TITLE); /* * Sanity check: Set the override redirect property on our group leader * window (not default), then re-parent it to the root window (default). * This makes sure that (a) a window manager can't re-parent our window, * and (b) that we remain a top-level window. */ XChangeWindowAttributes(GDK_DISPLAY(), myGroupLeader, CWOverrideRedirect, &attr); XReparentWindow(GDK_DISPLAY(), myGroupLeader, myRootWindow, 10, 10); XSync(GDK_DISPLAY(), FALSE); *groupLeader = myGroupLeader; *rootWindow = myRootWindow; return TRUE; } /* ****************************************************************************** * QueryX11Lock -- */ /** * * This is just a wrapper around XGetWindowProperty which queries the * window described by for the property described by lockAtom. * * @param[in] dpy X11 display to query * @param[in] w Window to query * @param[in] lockAtom Atom used for locking * * @return TRUE if property defined by parameters exists; FALSE otherwise. * ****************************************************************************** */ static gboolean QueryX11Lock(Display *dpy, Window w, Atom lockAtom) { Atom ptype; // returned property type int pfmt; // returned property format unsigned long np; // returned # of properties unsigned long remaining; // amount of data remaining in property unsigned char *data = NULL; if (XGetWindowProperty(dpy, w, lockAtom, 0, 1, False, lockAtom, &ptype, &pfmt, &np, &remaining, &data) != Success) { g_warning("%s: Unable to query window %lx for property %s\n", __func__, w, LOCK_ATOM_NAME); return FALSE; } /* * Xlib is wacky. If the following test is true, then our property * didn't exist for the window in question. As a result, `data' is * unset, so don't worry about the lack of XFree(data) here. */ if (ptype == None) { return FALSE; } /* * We care only about the existence of the property, not its value. */ XFree(data); return TRUE; } /* ****************************************************************************** * AcquireDisplayLock -- */ /** * * This function "locks" the display against being "claimed" by another * instance of vmware-user. It will succeed if we're the first/only * instance of vmware-user, and fail otherwise. * * NB: This routine must be called -after- gtk_init(). * * Vmware-user enjoys per-display exclusivity using the following algorithm: * * 1. Grab X server. (I.e., get exclusive access.) * 2. Search for top-level X windows meeting the following criteria: * a. named "vmware-user" * b. has the property "vmware-user-lock" set. * 3a. If any such windows described above found, then another vmware-user * process is attached to this display, so we consider the display * locked. * 3b. Else we're the only one. Set the "vmware-user-lock" property on * our top-level window. * 4. Ungrab the X server. * * The first time this routine is ever called during the lifetime of an X * session, a new X11 Atom, "vmware-user-lock" is created for the lifetime * of the X server. * * The "vmware-user-lock" property may be set on this process's group leader * window. * * @return TRUE if "lock" acquired (i.e., we're the first/only vmware-user * process); otherwise FALSE. * ****************************************************************************** */ static gboolean AcquireDisplayLock(void) { Display *defaultDisplay; // Current default X11 display. Window rootWindow; // Root window of defaultDisplay; used as root node // passed to XQueryTree(). Window groupLeader; // Our instance's window group leader. This is // implicitly created by gtk_init(). Window *children = NULL; // Array of windows returned by XQueryTree(). unsigned int nchildren; // Length of children. Window dummy1, dummy2; // Throwaway window IDs for XQueryTree(). Atom lockAtom; // Refers to the "vmware-user-lock" X11 Atom. unsigned int index; Bool alreadyLocked = FALSE; // Set to TRUE if we discover lock is held. Bool retval = FALSE; defaultDisplay = GDK_DISPLAY(); /* * Reset some of our main window's settings & fetch Xlib handles for * the GDK group leader and root windows. */ if (InitGroupLeader(&groupLeader, &rootWindow) == FALSE) { g_warning("%s: unable to initialize main window.\n", __func__); return FALSE; } /* * Look up the lock atom, creating it if it doesn't already exist. */ lockAtom = XInternAtom(defaultDisplay, LOCK_ATOM_NAME, False); if (lockAtom == None) { g_warning("%s: unable to create X11 atom: " LOCK_ATOM_NAME "\n", __func__); return FALSE; } /* * Okay, so at this point the following is done: * * 1. Our top-level / group leader window is a child of the display's * root window. * 2. The window manager can't get its hands on said window. * 3. We have a handle on the X11 atom which will be used to identify * the X11 property used as our lock. */ g_debug("%s: Grabbing X server.\n", __func__); /* * Neither of these can fail, or at least not in the sense that they'd * return an error. Instead we'd likely see an X11 I/O error, tearing * the connection down. * * XSync simply blocks until the XGrabServer request is acknowledged * by the server. It makes sure that we don't continue issuing requests, * such as XQueryTree, until the server grants our "grab". */ XGrabServer(defaultDisplay); XSync(defaultDisplay, False); /* * WARNING: At this point, we have grabbed the X server. Consider the * UI to be completely frozen. Under -no- circumstances should we return * without ungrabbing the server first. */ if (XQueryTree(defaultDisplay, rootWindow, &dummy1, &dummy2, &children, &nchildren) == 0) { g_warning("%s: XQueryTree failed\n", __func__); goto out; } /* * Iterate over array of top-level windows. Search for those named * vmware-user and with the property "vmware-user-lock" set. * * If any such windows are found, then another process has already * claimed this X session. */ for (index = 0; (index < nchildren) && !alreadyLocked; index++) { char *name = NULL; /* Skip unless window is named vmware-user. */ if ((XFetchName(defaultDisplay, children[index], &name) == 0) || (name == NULL) || strcmp(name, VMUSER_TITLE)) { XFree(name); continue; } /* * Query the window for the "vmware-user-lock" property. */ alreadyLocked = QueryX11Lock(defaultDisplay, children[index], lockAtom); XFree(name); } /* * Yay. Lock isn't held, so go ahead and acquire it. */ if (!alreadyLocked) { unsigned char dummy[] = "1"; g_debug("%s: Setting property " LOCK_ATOM_NAME "\n", __func__); /* * NB: Current Xlib always returns one. This may generate a -fatal- IO * error, though. */ XChangeProperty(defaultDisplay, groupLeader, lockAtom, lockAtom, 8, PropModeReplace, dummy, sizeof dummy); retval = TRUE; } out: XUngrabServer(defaultDisplay); XSync(defaultDisplay, False); XFree(children); return retval; } /* ****************************************************************************** * X11Lock_Init -- */ /** * * Initializes GTK, and sets up a lock atom to make sure only one vmusr * instance is running. * * On error, this function will request that the application's main loop stop * running. * * @param[in] ctx Application context. * @param[in] pdata Registration data. * * @return TRUE on success, FALSE if another vmusr instance owns the display or * not running in the right container (vmusr). * ****************************************************************************** */ gboolean X11Lock_Init(ToolsAppCtx *ctx, ToolsPluginData *pdata) { int argc = 0; char *argv[] = { NULL, NULL }; if (strcmp(ctx->name, VMTOOLS_USER_SERVICE) != 0) { VMTOOLSAPP_ERROR(ctx, EXIT_FAILURE); return FALSE; } /* * We depend on the window title when performing (primitive) vmware-user * session detection, and unfortunately for us, GTK has a nasty habit of * retitling toplevel windows. That said, we can control GTK's default * title by setting Glib's application or program name. * * XXX Consider using g_set_application_name("VMware User Agent") or * similar. */ g_set_prgname(VMUSER_TITLE); argv[0] = VMUSER_TITLE; /* XXX: is calling gtk_init() multiple times safe? */ gtk_init(&argc, (char ***) &argv); if (!AcquireDisplayLock()) { g_warning("Another instance of vmware-user already running. Exiting.\n"); VMTOOLSAPP_ERROR(ctx, EXIT_FAILURE); return FALSE; } return TRUE; } open-vm-tools-9.4.0-1280544/services/plugins/desktopEvents/deFeatures.h0000644765153500003110000000407412220061556024046 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _DEFEATURES_H_ #define _DEFEATURES_H_ /** * @file deFeatures.h * * X11-specific featurs of the plugin. Don't include this file directly - * include desktopEventsInt.h instead. */ #define VMUSER_TITLE "vmware-user" void Reload_Do(void); gboolean Reload_Init(ToolsAppCtx *ctx, ToolsPluginData *pdata); void Reload_Shutdown(ToolsAppCtx *ctx, ToolsPluginData *pdata); #ifndef NO_XSM gboolean SessionMgr_Init(ToolsAppCtx *ctx, ToolsPluginData *pdata); void SessionMgr_Shutdown(ToolsAppCtx *ctx, ToolsPluginData *pdata); #endif gboolean X11Lock_Init(ToolsAppCtx *ctx, ToolsPluginData *pdata); gboolean XIOError_Init(ToolsAppCtx *ctx, ToolsPluginData *pdata); void XIOError_Shutdown(ToolsAppCtx *ctx, ToolsPluginData *pdata); #if defined(DE_MAIN) static DesktopEventFuncs gFeatures[] = { { X11Lock_Init, NULL, FALSE }, { Reload_Init, Reload_Shutdown, FALSE }, #ifndef NO_XSM { SessionMgr_Init, SessionMgr_Shutdown, FALSE }, #endif { XIOError_Init, XIOError_Shutdown, FALSE }, }; #endif #endif /* _DEFEATURES_H_ */ open-vm-tools-9.4.0-1280544/services/plugins/desktopEvents/Makefile.in0000644765153500003110000007244512220061624023656 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2010 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @HAVE_XSM_TRUE@am__append_1 = @XSM_LIBS@ @HAVE_XSM_TRUE@am__append_2 = sessionMgr.c sessionMgrSignals.c subdir = services/plugins/desktopEvents DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(plugin_LTLIBRARIES) am__DEPENDENCIES_1 = libdesktopEvents_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am__libdesktopEvents_la_SOURCES_DIST = desktopEvents.c reload.c \ x11Lock.c xioError.c sessionMgr.c sessionMgrSignals.c @HAVE_XSM_TRUE@am__objects_1 = libdesktopEvents_la-sessionMgr.lo \ @HAVE_XSM_TRUE@ libdesktopEvents_la-sessionMgrSignals.lo am_libdesktopEvents_la_OBJECTS = libdesktopEvents_la-desktopEvents.lo \ libdesktopEvents_la-reload.lo libdesktopEvents_la-x11Lock.lo \ libdesktopEvents_la-xioError.lo $(am__objects_1) libdesktopEvents_la_OBJECTS = $(am_libdesktopEvents_la_OBJECTS) libdesktopEvents_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libdesktopEvents_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libdesktopEvents_la_SOURCES) DIST_SOURCES = $(am__libdesktopEvents_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ plugindir = @VMUSR_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libdesktopEvents.la libdesktopEvents_la_CPPFLAGS = @GTK_CPPFLAGS@ @PLUGIN_CPPFLAGS@ libdesktopEvents_la_LDFLAGS = @PLUGIN_LDFLAGS@ libdesktopEvents_la_LIBADD = @COMMON_XLIBS@ @GTK_LIBS@ @VMTOOLS_LIBS@ \ $(am__append_1) libdesktopEvents_la_SOURCES = desktopEvents.c reload.c x11Lock.c \ xioError.c $(am__append_2) @HAVE_XSM_TRUE@BUILT_SOURCES = sessionMgrSignals.c sessionMgrSignals.h @HAVE_XSM_TRUE@CLEANFILES = sessionMgrSignals.c sessionMgrSignals.h @HAVE_XSM_TRUE@EXTRA_DIST = sessionMgrSignals.gm all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu services/plugins/desktopEvents/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu services/plugins/desktopEvents/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ } uninstall-pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ done clean-pluginLTLIBRARIES: -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) @list='$(plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libdesktopEvents.la: $(libdesktopEvents_la_OBJECTS) $(libdesktopEvents_la_DEPENDENCIES) $(EXTRA_libdesktopEvents_la_DEPENDENCIES) $(libdesktopEvents_la_LINK) -rpath $(plugindir) $(libdesktopEvents_la_OBJECTS) $(libdesktopEvents_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdesktopEvents_la-desktopEvents.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdesktopEvents_la-reload.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdesktopEvents_la-sessionMgr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdesktopEvents_la-sessionMgrSignals.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdesktopEvents_la-x11Lock.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdesktopEvents_la-xioError.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libdesktopEvents_la-desktopEvents.lo: desktopEvents.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdesktopEvents_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdesktopEvents_la-desktopEvents.lo -MD -MP -MF $(DEPDIR)/libdesktopEvents_la-desktopEvents.Tpo -c -o libdesktopEvents_la-desktopEvents.lo `test -f 'desktopEvents.c' || echo '$(srcdir)/'`desktopEvents.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libdesktopEvents_la-desktopEvents.Tpo $(DEPDIR)/libdesktopEvents_la-desktopEvents.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='desktopEvents.c' object='libdesktopEvents_la-desktopEvents.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdesktopEvents_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdesktopEvents_la-desktopEvents.lo `test -f 'desktopEvents.c' || echo '$(srcdir)/'`desktopEvents.c libdesktopEvents_la-reload.lo: reload.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdesktopEvents_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdesktopEvents_la-reload.lo -MD -MP -MF $(DEPDIR)/libdesktopEvents_la-reload.Tpo -c -o libdesktopEvents_la-reload.lo `test -f 'reload.c' || echo '$(srcdir)/'`reload.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libdesktopEvents_la-reload.Tpo $(DEPDIR)/libdesktopEvents_la-reload.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='reload.c' object='libdesktopEvents_la-reload.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdesktopEvents_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdesktopEvents_la-reload.lo `test -f 'reload.c' || echo '$(srcdir)/'`reload.c libdesktopEvents_la-x11Lock.lo: x11Lock.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdesktopEvents_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdesktopEvents_la-x11Lock.lo -MD -MP -MF $(DEPDIR)/libdesktopEvents_la-x11Lock.Tpo -c -o libdesktopEvents_la-x11Lock.lo `test -f 'x11Lock.c' || echo '$(srcdir)/'`x11Lock.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libdesktopEvents_la-x11Lock.Tpo $(DEPDIR)/libdesktopEvents_la-x11Lock.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='x11Lock.c' object='libdesktopEvents_la-x11Lock.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdesktopEvents_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdesktopEvents_la-x11Lock.lo `test -f 'x11Lock.c' || echo '$(srcdir)/'`x11Lock.c libdesktopEvents_la-xioError.lo: xioError.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdesktopEvents_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdesktopEvents_la-xioError.lo -MD -MP -MF $(DEPDIR)/libdesktopEvents_la-xioError.Tpo -c -o libdesktopEvents_la-xioError.lo `test -f 'xioError.c' || echo '$(srcdir)/'`xioError.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libdesktopEvents_la-xioError.Tpo $(DEPDIR)/libdesktopEvents_la-xioError.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xioError.c' object='libdesktopEvents_la-xioError.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdesktopEvents_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdesktopEvents_la-xioError.lo `test -f 'xioError.c' || echo '$(srcdir)/'`xioError.c libdesktopEvents_la-sessionMgr.lo: sessionMgr.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdesktopEvents_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdesktopEvents_la-sessionMgr.lo -MD -MP -MF $(DEPDIR)/libdesktopEvents_la-sessionMgr.Tpo -c -o libdesktopEvents_la-sessionMgr.lo `test -f 'sessionMgr.c' || echo '$(srcdir)/'`sessionMgr.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libdesktopEvents_la-sessionMgr.Tpo $(DEPDIR)/libdesktopEvents_la-sessionMgr.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sessionMgr.c' object='libdesktopEvents_la-sessionMgr.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdesktopEvents_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdesktopEvents_la-sessionMgr.lo `test -f 'sessionMgr.c' || echo '$(srcdir)/'`sessionMgr.c libdesktopEvents_la-sessionMgrSignals.lo: sessionMgrSignals.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdesktopEvents_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdesktopEvents_la-sessionMgrSignals.lo -MD -MP -MF $(DEPDIR)/libdesktopEvents_la-sessionMgrSignals.Tpo -c -o libdesktopEvents_la-sessionMgrSignals.lo `test -f 'sessionMgrSignals.c' || echo '$(srcdir)/'`sessionMgrSignals.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libdesktopEvents_la-sessionMgrSignals.Tpo $(DEPDIR)/libdesktopEvents_la-sessionMgrSignals.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sessionMgrSignals.c' object='libdesktopEvents_la-sessionMgrSignals.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdesktopEvents_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdesktopEvents_la-sessionMgrSignals.lo `test -f 'sessionMgrSignals.c' || echo '$(srcdir)/'`sessionMgrSignals.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(plugindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pluginLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pluginLTLIBRARIES .MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-pluginLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-pluginLTLIBRARIES install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-pluginLTLIBRARIES @HAVE_XSM_TRUE@sessionMgrSignals.c: $(top_srcdir)/services/plugins/desktopEvents/sessionMgrSignals.gm @HAVE_XSM_TRUE@ glib-genmarshal --body $(top_srcdir)/services/plugins/desktopEvents/sessionMgrSignals.gm > \ @HAVE_XSM_TRUE@ $@ || (rm -f $@ && exit 1) @HAVE_XSM_TRUE@sessionMgrSignals.h: $(top_srcdir)/services/plugins/desktopEvents/sessionMgrSignals.gm @HAVE_XSM_TRUE@ glib-genmarshal --header $(top_srcdir)/services/plugins/desktopEvents/sessionMgrSignals.gm > \ @HAVE_XSM_TRUE@ $@ || (rm -f $@ && exit 1) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/services/plugins/desktopEvents/desktopEvents.c0000644765153500003110000001047712220061556024614 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file desktopEvents.c * * Entry point for the desktop events plugin. Initializes all the individual * features of the plugin. */ /* * DE_MAIN enables the definition of the list of features of this plugin * (gFeatures) defined in the platform-specific "deFeatures.h" files. */ #define DE_MAIN #include "vmware.h" #include "desktopEventsInt.h" /* ****************************************************************************** * DesktopEventsShutdown -- */ /** * * Description of DesktopEventsShutdown. * * Calls the shutdown function of the available features. * * @param[in] obj Unused. * @param[in] ctx The application context. * @param[in] plugin Plugin data. * * @return TRUE. * ****************************************************************************** */ static gboolean DesktopEventsShutdown(gpointer serviceObj, ToolsAppCtx *ctx, ToolsPluginData *plugin) { size_t i; for (i = 0; i < ARRAYSIZE(gFeatures); i++) { DesktopEventFuncs *f = &gFeatures[i]; if (f->initialized && f->shutdownFn != NULL) { f->shutdownFn(ctx, plugin); } } if (plugin->_private) { g_hash_table_remove(plugin->_private, DE_PRIVATE_CTX); g_hash_table_unref(plugin->_private); plugin->_private = NULL; } return TRUE; } /* ****************************************************************************** * ToolsOnLoad -- */ /** * * Returns the registration data for the plugin. * * @param[in] ctx The application context. * * @return The registration data. * ****************************************************************************** */ TOOLS_MODULE_EXPORT ToolsPluginData * ToolsOnLoad(ToolsAppCtx *ctx) { static ToolsPluginData regData = { "desktopEvents", NULL, NULL, NULL }; size_t i; #if defined(_WIN32) /* * If we aren't running in a VM (e.g., running in bootcamp natively on * a Mac), then return NULL to disable the plugin. */ if (!ctx->isVMware) { return NULL; } g_return_val_if_fail(gPluginHandle != NULL, NULL); #endif regData.regs = g_array_new(FALSE, TRUE, sizeof (ToolsAppReg)); regData._private = g_hash_table_new(g_str_hash, g_str_equal); g_hash_table_insert(regData._private, DE_PRIVATE_CTX, ctx); for (i = 0; i < ARRAYSIZE(gFeatures); i++) { DesktopEventFuncs *f = &gFeatures[i]; if (!f->initFn(ctx, ®Data)) { break; } f->initialized = TRUE; } /* * Register the shutdown callback and return if all features were * initialized successfully. */ if (i == ARRAYSIZE(gFeatures)) { ToolsPluginSignalCb sigs[] = { { TOOLS_CORE_SIG_SHUTDOWN, DesktopEventsShutdown, ®Data } }; ToolsAppReg regs[] = { { TOOLS_APP_SIGNALS, VMTools_WrapArray(sigs, sizeof *sigs, ARRAYSIZE(sigs)) }, }; g_array_append_vals(regData.regs, regs, ARRAYSIZE(regs)); return ®Data; } /* Failed to initialize something, clean up and unload. */ DesktopEventsShutdown(NULL, ctx, ®Data); /* Cleanup regData to make sure memory is freed. */ for (i = 0; i < regData.regs->len; i++) { ToolsAppReg *reg = &g_array_index(regData.regs, ToolsAppReg, i); if (reg->data != NULL) { g_array_free(reg->data, TRUE); } } g_array_free(regData.regs, TRUE); return NULL; } open-vm-tools-9.4.0-1280544/services/plugins/resolutionSet/0000755765153500003110000000000012220061625021617 5ustar dtormtsopen-vm-tools-9.4.0-1280544/services/plugins/resolutionSet/resolutionX11.c0000644765153500003110000004330112220061556024464 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * @file resolutionX11.c * * X11 backend for resolutionSet plugin. */ #include #include #include #include "resolutionInt.h" #include "resolutionRandR12.h" #include #ifndef NO_MULTIMON #include #endif #include #include #include "vmware.h" #include "debug.h" #include "fileIO.h" #include "libvmwarectrl.h" #include "str.h" #include "strutil.h" #include "util.h" #define VMWAREDRV_PATH_64 "/usr/X11R6/lib64/modules/drivers/vmware_drv.o" #define VMWAREDRV_PATH "/usr/X11R6/lib/modules/drivers/vmware_drv.o" #define VERSION_STRING "VMware Guest X Server" /** * Describes the state of the X11 back-end of lib/resolution. */ typedef struct { Display *display; // X11 connection / display context Window rootWindow; // points to display's root window Bool canUseVMwareCtrl; // TRUE if VMwareCtrl extension available Bool canUseVMwareCtrlTopologySet; // TRUE if VMwareCtrl extension supports topology set Bool canUseRandR12; // TRUE if RandR extension >= 1.2 available } ResolutionInfoX11Type; /* * Global variables */ ResolutionInfoX11Type resolutionInfoX11; /* * Local function prototypes */ static Bool ResolutionCanSet(void); static Bool TopologyCanSet(void); static Bool SelectResolution(uint32 width, uint32 height); /* * Global function definitions */ /** * X11 back-end initializer. Records caller's X11 display, then determines * which capabilities are available. * * @param[in] handle User's X11 display * @return TRUE on success, FALSE on failure. */ Bool ResolutionBackendInit(InitHandle handle) { ResolutionInfoX11Type *resInfoX = &resolutionInfoX11; ResolutionInfoType *resInfo = &resolutionInfo; int dummy1; int dummy2; memset(resInfoX, 0, sizeof *resInfoX); resInfoX->display = handle; if (resInfoX->display == NULL) { g_warning("%s: Called with invalid X display!\n", __func__); return FALSE; } resInfoX->display = handle; resInfoX->rootWindow = DefaultRootWindow(resInfoX->display); resInfoX->canUseVMwareCtrl = VMwareCtrl_QueryVersion(resInfoX->display, &dummy1, &dummy2); resInfoX->canUseVMwareCtrlTopologySet = FALSE; resInfoX->canUseRandR12 = FALSE; resInfo->canSetResolution = ResolutionCanSet(); resInfo->canSetTopology = TopologyCanSet(); return TRUE; } /** * Stub implementation of ResolutionBackendCleanup for the X11 back-end. */ void ResolutionBackendCleanup(void) { return; } /** * Given a width and height, define a custom resolution (if VMwareCtrl is * available), then issue a change resolution request via XRandR. * * This is called as a result of the Resolution_Set request from the vmx. * * @param[in] width requested width * @param[in] height requested height * @return TRUE if we are able to set to the exact size requested, FALSE otherwise. */ Bool ResolutionSetResolution(uint32 width, uint32 height) { ResolutionInfoX11Type *resInfoX = &resolutionInfoX11; Bool ret; ASSERT(resolutionInfo.canSetResolution); XGrabServer(resInfoX->display); if (resInfoX->canUseVMwareCtrl) { /* * If so, use the VMWARE_CTRL extension to provide a custom resolution * which we'll find as an exact match from XRRConfigSizes() (unless * the resolution is too large). * * As such, we don't care if this succeeds or fails, we'll make a best * effort attempt to change resolution anyway. * * On vmwgfx, this is routed through the X server down to the * kernel modesetting system to provide a preferred mode with * correcte width and height. */ VMwareCtrl_SetRes(resInfoX->display, DefaultScreen(resInfoX->display), width, height); } /* * Use legacy RandR (vmwlegacy) or RandR12 (vmwgfx) to select the * desired mode. */ ret = SelectResolution(width, height); XUngrabServer(resInfoX->display); XFlush(resInfoX->display); return ret; } /** * Employs the Xinerama extension to declare a new display topology. * * @note Solaris 10 uses a different Xinerama standard than expected here. As a * result, topology set is not supported and this function is excluded from * Solaris builds. With Solaris 10 shipping X.org, perhaps we should revisit * this decision. * * @param[in] ndisplays number of elements in topology * @param[in] topology array of display geometries * @return TRUE if operation succeeded, FALSE otherwise. */ Bool ResolutionSetTopology(unsigned int ndisplays, DisplayTopologyInfo *topology) { #ifdef NO_MULTIMON return FALSE; #else ResolutionInfoX11Type *resInfoX = &resolutionInfoX11; Bool success = FALSE; unsigned int i; xXineramaScreenInfo *displays = NULL; short maxX = 0; short maxY = 0; int minX = 0x7FFF; int minY = 0x7FFF; ASSERT(resolutionInfo.canSetTopology); /* * Allocate xXineramaScreenInfo array & translate from DisplayTopologyInfo. * Iterate over displays looking for minimum, maximum dimensions. * Warn if min isn't at (0,0). * Transform to (0,0). * Call out to VMwareCtrl_SetTopology. * Set new jumbotron resolution. */ displays = malloc(sizeof *displays * ndisplays); if (!displays) { goto out; } for (i = 0; i < ndisplays; i++) { displays[i].x_org = topology[i].x; displays[i].y_org = topology[i].y; displays[i].width = topology[i].width; displays[i].height = topology[i].height; maxX = MAX(maxX, displays[i].x_org + displays[i].width); maxY = MAX(maxY, displays[i].y_org + displays[i].height); minX = MIN(minX, displays[i].x_org); minY = MIN(minY, displays[i].y_org); } if (minX != 0 || minY != 0) { g_warning("The bounding box of the display topology does not have an " "origin of (0,0)\n"); } /* * Transform the topology so that the bounding box has an origin of (0,0). Since the * host is already supposed to pass a normalized topology, this should not have any * effect. */ for (i = 0; i < ndisplays; i++) { displays[i].x_org -= minX; displays[i].y_org -= minY; } /* * Grab server to avoid potential races between setting GUI topology * and setting FB topology. */ XGrabServer(resInfoX->display); /* * First, call vmwarectrl to update the connection info * and resolution capabilities of connected monitors, * according to the host GUI layout on vmwgfx. On vmwlegacy this * sets the driver's exported Xinerama topology. * * For vmwgfx, this might be replaced with a direct kernel driver call * in upcoming versions. */ if (resInfoX->canUseVMwareCtrlTopologySet) { if (!VMwareCtrl_SetTopology(resInfoX->display, DefaultScreen(resInfoX->display), displays, ndisplays)) { g_debug("Failed to set topology in the driver.\n"); goto out; } } if (resInfoX->canUseRandR12) { /* * For vmwgfx, use RandR12 to set the FB layout to a 1:1 mapping * of the host GUI layout. */ success = RandR12_SetTopology(resInfoX->display, DefaultScreen(resInfoX->display), resInfoX->rootWindow, ndisplays, displays, maxX - minX, maxY - minY); } else if (resInfoX->canUseVMwareCtrlTopologySet) { /* * For vmwlegacy, use legacy RandR to set the backing framebuffer * size. We don't do this unless we were able to set a new * topology using vmwarectrl. */ if (!SelectResolution(maxX - minX, maxY - minY)) { g_debug("Failed to set new resolution.\n"); goto out; } success = TRUE; } out: XUngrabServer(resInfoX->display); XFlush(resInfoX->display); free(displays); return success; #endif } /* * Local function definitions */ /** * Does VMware SVGA driver support resolution changing? We check by * testing RandR version and the availability of VMWCTRL extension. It * also check the output names for RandR 1.2 and above which is used for * the vmwgfx driver. Finally it searches the driver binary for a known * version string. * * resInfoX->canUseRandR12 will be set if RandR12 is usable. * * @return TRUE if the driver version is high enough, FALSE otherwise. */ static Bool ResolutionCanSet(void) { ResolutionInfoX11Type *resInfoX = &resolutionInfoX11; FileIODescriptor fd; FileIOResult res; int64 filePos = 0; Bool keepSearching = TRUE; Bool found = FALSE; char buf[sizeof VERSION_STRING + 10]; // size of VERSION_STRING plus some extra for the version number const char versionString[] = VERSION_STRING; size_t bytesRead; int32 major, minor, level; unsigned int tokPos; /* See if the randr X module is loaded */ if (!XRRQueryVersion(resInfoX->display, &major, &minor) ) { return FALSE; } #ifndef NO_MULTIMON /* * See if RandR >= 1.2 can be used: The extension version is high enough and * all output names match the expected format. */ if (major > 1 || (major == 1 && minor >= 2)) { XRRScreenResources* xrrRes; XRROutputInfo* xrrOutput; unsigned int num; int i; xrrRes = XRRGetScreenResources(resInfoX->display, resInfoX->rootWindow); if (xrrRes) { for (i = 0; i < xrrRes->noutput; i++) { xrrOutput = XRRGetOutputInfo(resInfoX->display, xrrRes, xrrRes->outputs[i]); if (!xrrOutput) { break; } if (sscanf(xrrOutput->name, RR12_OUTPUT_FORMAT, &num) != 1 || num < 1) { XRRFreeOutputInfo(xrrOutput); break; } XRRFreeOutputInfo(xrrOutput); } if (i == xrrRes->noutput) { resInfoX->canUseRandR12 = TRUE; } else { g_debug("RandR >= 1.2 not usable\n"); } XRRFreeScreenResources(xrrRes); } if (resInfoX->canUseRandR12) { return TRUE; } } #endif // ifndef NO_MULTIMON /* * See if the VMWARE_CTRL extension is supported. */ if (resInfoX->canUseVMwareCtrl) { return TRUE; } /* * XXX: This check does not work with XOrg 6.9/7.0 for two reasons: Both * versions now use .so for the driver extension and 7.0 moves the drivers * to a completely different directory. As long as we ship a driver for * 6.9/7.0, we can instead just use the VMWARE_CTRL check. */ buf[sizeof buf - 1] = '\0'; FileIO_Invalidate(&fd); res = FileIO_Open(&fd, VMWAREDRV_PATH_64, FILEIO_ACCESS_READ, FILEIO_OPEN); if (res != FILEIO_SUCCESS) { res = FileIO_Open(&fd, VMWAREDRV_PATH, FILEIO_ACCESS_READ, FILEIO_OPEN); } if (res == FILEIO_SUCCESS) { /* * One of the opens succeeded, so start searching thru the file. */ while (keepSearching) { res = FileIO_Read(&fd, buf, sizeof buf - 1, &bytesRead); if (res != FILEIO_SUCCESS || bytesRead < sizeof buf -1 ) { keepSearching = FALSE; } else { if (Str_Strncmp(versionString, buf, sizeof versionString - 1) == 0) { keepSearching = FALSE; found = TRUE; } } filePos = FileIO_Seek(&fd, filePos+1, FILEIO_SEEK_BEGIN); if (filePos == -1) { keepSearching = FALSE; } } FileIO_Close(&fd); if (found) { /* * We NUL-terminated buf earlier, but Coverity really wants it to * be NUL-terminated after the call to FileIO_Read (because * FileIO_Read doesn't NUL-terminate). So we'll do it again. */ buf[sizeof buf - 1] = '\0'; /* * Try and parse the major, minor and level versions */ tokPos = sizeof versionString - 1; if (!StrUtil_GetNextIntToken(&major, &tokPos, buf, ".- ")) { return FALSE; } if (!StrUtil_GetNextIntToken(&minor, &tokPos, buf, ".- ")) { return FALSE; } if (!StrUtil_GetNextIntToken(&level, &tokPos, buf, ".- ")) { return FALSE; } return ((major > 10) || (major == 10 && minor >= 11)); } } return FALSE; } /** * Tests whether or not we can change display topology. * * resInfoX->canUseVMwareCtrlTopologySet will be set to TRUE if we should * use the old driver path when setting topology. * * @return TRUE if we're able to reset topology, otherwise FALSE. * @note resInfoX->canUseVMwareCtrlTopologySet will be set to TRUE on success. */ static Bool TopologyCanSet(void) { ResolutionInfoX11Type *resInfoX = &resolutionInfoX11; /** * Note: For some strange reason, an early call to XineramaQueryVersion in * in this function stops vmtoolsd from deadlocking and freezing the X * display. Might be a call to XGrabServer() in and X library init * function that is called when we've already grabbed the server.... */ #ifdef NO_MULTIMON resInfoX->canUseVMwareCtrlTopologySet = FALSE; return FALSE; #else int major; int minor; if (resInfoX->canUseVMwareCtrl && XineramaQueryVersion(resInfoX->display, &major, &minor)) { /* * We need both a new enough VMWARE_CTRL and Xinerama for this to work. */ resInfoX->canUseVMwareCtrlTopologySet = (major > 0) || (major == 0 && minor >= 2); } else { resInfoX->canUseVMwareCtrlTopologySet = FALSE; } return resInfoX->canUseVMwareCtrlTopologySet || (resInfoX->canUseRandR12 && resInfoX->canUseVMwareCtrl); #endif } /** * Given a width and height, find the biggest resolution that will "fit". * This is called as a result of the resolution set request from the vmx. * * @param[in] width * @param[in] height * * @return TRUE if we are able to set to the exact size requested, FALSE otherwise. */ Bool SelectResolution(uint32 width, uint32 height) { ResolutionInfoX11Type *resInfoX = &resolutionInfoX11; XRRScreenConfiguration* xrrConfig; XRRScreenSize *xrrSizes; Rotation xrrCurRotation; uint32 xrrNumSizes; uint32 i; uint32 bestFitIndex = 0; uint64 bestFitSize = 0; uint64 potentialSize; Bool perfectMatch; #ifndef NO_MULTIMON if (resInfoX->canUseRandR12) { xXineramaScreenInfo display; display.x_org = 0; display.y_org = 0; display.width = width; display.height = height; return RandR12_SetTopology(resInfoX->display, DefaultScreen(resInfoX->display), resInfoX->rootWindow, 1, &display, width, height); } #endif xrrConfig = XRRGetScreenInfo(resInfoX->display, resInfoX->rootWindow); xrrSizes = XRRConfigSizes(xrrConfig, &xrrNumSizes); bestFitIndex = XRRConfigCurrentConfiguration(xrrConfig, &xrrCurRotation); /* * Iterate thru the list finding the best fit that is still <= in both width * and height. */ for (i = 0; i < xrrNumSizes; i++) { potentialSize = xrrSizes[i].width * xrrSizes[i].height; if (xrrSizes[i].width <= width && xrrSizes[i].height <= height && potentialSize > bestFitSize ) { bestFitSize = potentialSize; bestFitIndex = i; } } if (bestFitSize > 0) { Status rc; g_debug("Setting guest resolution to: %dx%d (requested: %d, %d)\n", xrrSizes[bestFitIndex].width, xrrSizes[bestFitIndex].height, width, height); rc = XRRSetScreenConfig(resInfoX->display, xrrConfig, resInfoX->rootWindow, bestFitIndex, xrrCurRotation, GDK_CURRENT_TIME); g_debug("XRRSetScreenConfig returned %d (result: %dx%d)\n", rc, xrrSizes[bestFitIndex].width, xrrSizes[bestFitIndex].height); } else { g_debug("Can't find a suitable guest resolution, ignoring request for %dx%d\n", width, height); } perfectMatch = xrrSizes[bestFitIndex].width == width && xrrSizes[bestFitIndex].height == height; XRRFreeScreenConfigInfo(xrrConfig); return perfectMatch; } /** * Obtain a "handle", which for X11, is a display pointer. * * @note We will have to move this out of the resolution plugin soon, I am * just landing this here now for convenience as I port resolution set over * to the new service architecture. * * @return X server display */ InitHandle ResolutionToolkitInit(void) { int argc = 1; char *argv[] = {"", NULL}; GtkWidget *wnd; Display *display; gtk_init(&argc, (char ***) &argv); wnd = gtk_invisible_new(); display = GDK_WINDOW_XDISPLAY(wnd->window); return (InitHandle) display; } open-vm-tools-9.4.0-1280544/services/plugins/resolutionSet/libvmwarectrl.h0000644765153500003110000000375712220061556024664 0ustar dtormts/* * Copyright 2006 by VMware, Inc. * * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. * * Except as contained in this notice, the name of the copyright holder(s) * and author(s) shall not be used in advertising or otherwise to promote * the sale, use or other dealings in this Software without prior written * authorization from the copyright holder(s) and author(s). */ /* * libvmwarectrl.c -- * * The VMWARE_CTRL client library. */ #ifndef _LIB_VMWARE_CTRL_H_ #define _LIB_VMWARE_CTRL_H_ #include #include #ifndef NO_MULTIMON #include #endif Bool VMwareCtrl_QueryExtension(Display *dpy, int *event_basep, int *error_basep); Bool VMwareCtrl_QueryVersion(Display *dpy, int *majorVersion, int *minorVersion); Bool VMwareCtrl_SetRes(Display *dpy, int screen, int x, int y); #ifndef NO_MULTIMON Bool VMwareCtrl_SetTopology(Display *dpy, int screen, xXineramaScreenInfo[], int number); #endif #endif /* _LIB_VMWARE_CTRL_H_ */ open-vm-tools-9.4.0-1280544/services/plugins/resolutionSet/resolutionSet.c0000644765153500003110000003777212220061556024665 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file resolution.c -- * * Set of functions to handle guest screen resizing for vmware-{user,guestd}. */ #include #include #include #include "vmware.h" #include "debug.h" #include "rpcout.h" #include "str.h" #include "strutil.h" #include "resolutionInt.h" #include "xdrutil.h" #include "vmware/guestrpc/tclodefs.h" #include "vmware/tools/plugin.h" #include "vmware/tools/utils.h" #include "embed_version.h" #include "vmtoolsd_version.h" VM_EMBED_VERSION(VMTOOLSD_VERSION_STRING); /* * The maximum number of capabilities we can set. * * See ResolutionSetCapabilities(). */ #define RESOLUTION_SET_CAPABILITIES_MAX 5 /* * Internal global variables */ /** * The name of the RPC channel we're using, e.g. TOOLS_DAEMON_NAME. Used by * ResolutionSet_SetServerCapability() to determine which capability to set. */ static const char *rpcChannelName = NULL; /** * Describes current state of the library. */ ResolutionInfoType resolutionInfo; /* * Global function definitions */ /** * * Initialize the guest resolution library. * * @param[in] handle Back-end specific handle, if needed. E.g., in the X11 case, this refers to the X11 display handle. * @return TRUE on success, FALSE on failure */ static Bool ResolutionInit(InitHandle handle) { // Shorter-named convenience alias. I expect this to be optimized out. ResolutionInfoType *resInfo = &resolutionInfo; ASSERT(resInfo->initialized == FALSE); if (!ResolutionBackendInit(handle)) { return FALSE; } resInfo->initialized = TRUE; return TRUE; } /** * * Shutdown the plugin, free resources, etc. * Resolution_* calls will fail until user next calls ResolutionInit(). */ static void ResolutionCleanup(void) { ResolutionInfoType *resInfo = &resolutionInfo; if (!resInfo->initialized) { return; } ResolutionBackendCleanup(); } /** * * Handler for TCLO 'Resolution_Set'. * * Routine unmarshals RPC arguments and passes over to back-end ResolutionSet(). * * @param[in] data RPC data * @return TRUE if we can reply, FALSE otherwise. */ static gboolean ResolutionResolutionSetCB(RpcInData *data) { uint32 width = 0 ; uint32 height = 0; unsigned int index = 0; gboolean retval = FALSE; ResolutionInfoType *resInfo = &resolutionInfo; if (!resInfo->initialized) { g_debug("%s: FAIL! Request for resolution set but plugin is not initialized\n", __FUNCTION__); return RPCIN_SETRETVALS(data, "Invalid guest state: resolution set not initialized", FALSE); } /* parse the width and height */ if (!StrUtil_GetNextUintToken(&width, &index, data->args, " ")) { goto invalid_arguments; } if (!StrUtil_GetNextUintToken(&height, &index, data->args, "")) { goto invalid_arguments; } retval = ResolutionSetResolution(width, height); invalid_arguments: return RPCIN_SETRETVALS(data, retval ? "" : "Invalid arguments", retval); } #if defined(RESOLUTION_WIN32) /** * * Handler for TCLO 'ChangeHost3DAvailabilityHint'. * * Routine unmarshals RPC arguments and passes over to back-end for handling. * * @param[in] data RPC data * @return TRUE if we can reply, FALSE otherwise. */ static gboolean ResolutionChangeHost3DAvailabilityHintCB(RpcInData *data) { unsigned int set; gboolean success = FALSE; unsigned int index = 0; g_debug("%s: enter\n", __FUNCTION__); if (!StrUtil_GetNextUintToken(&set, &index, data->args, " ")) { g_debug("%s: invalid arguments\n", __FUNCTION__); return RPCIN_SETRETVALS(data, "Invalid arguments. Expected \"set\"", FALSE); } success = ResolutionChangeHost3DAvailabilityHint(set?TRUE:FALSE); RPCIN_SETRETVALS(data, success ? "" : "ResolutionChangeHost3DAvailabilityHint failed", success); g_debug("%s: leave\n", __FUNCTION__); return success; } /** * * Handler for TCLO 'DisplayTopologyModes_Set'. * * Routine unmarshals RPC arguments and passes over to back-end * ModesTopologySet(). * * @note the following can be added as a unit test: * * RpcInData testdata; * testdata.args = "10 0 1, 1111 111, 2222 222, 3333 333, 4444 444, 5555 555, 6666 666, 7777 777, 8888 888, 9999 999, 0000 000"; * ResolutionDisplayTopologyModesSetCB(&testdata); * * @param[in] data RPC data * @return TRUE if we can reply, FALSE otherwise. */ static gboolean ResolutionDisplayTopologyModesSetCB(RpcInData *data) { DisplayTopologyInfo *displays = NULL; unsigned int count; unsigned int i; unsigned int cmd; unsigned int screen; gboolean success = FALSE; const char *p; g_debug("%s: enter\n", __FUNCTION__); /* * The argument string will look something like: * [ , ] * count. * * e.g. * 3 0 1, 640 480 , 800 600 , 1024 768 */ if (sscanf(data->args, "%u %u %u", &count, &screen, &cmd) != 3) { g_debug("%s: invalid arguments\n", __FUNCTION__); return RPCIN_SETRETVALS(data, "Invalid arguments. Expected \"count\", \"screen\", and \"cmd\"", FALSE); } displays = malloc(sizeof *displays * count); if (!displays) { g_debug("%s: alloc failed\n", __FUNCTION__); RPCIN_SETRETVALS(data, "Failed to alloc buffer for display modes", FALSE); goto out; } for (p = data->args, i = 0; i < count; i++) { p = strchr(p, ','); if (!p) { g_debug("%s: expected comma separated display modes list\n", __FUNCTION__); RPCIN_SETRETVALS(data, "Expected comma separated display modes list", FALSE); goto out; } p++; /* Skip past the , */ if (sscanf(p, " %d %d ", &displays[i].width, &displays[i].height) != 2) { g_debug("%s: expected w, h in display modes entry\n", __FUNCTION__); RPCIN_SETRETVALS(data, "Expected w, h in display modes entry", FALSE); goto out; } } success = ResolutionSetTopologyModes(screen, cmd, count, displays); RPCIN_SETRETVALS(data, success ? "" : "ResolutionSetTopologyModes failed", success); out: free(displays); g_debug("%s: leave\n", __FUNCTION__); return success; } #endif /** * * Handler for TCLO 'DisplayTopology_Set'. * * Routine unmarshals RPC arguments and passes over to back-end TopologySet(). * * @param[in] data RPC data * @return TRUE if we can reply, FALSE otherwise. */ static gboolean ResolutionDisplayTopologySetCB(RpcInData *data) { DisplayTopologyInfo *displays = NULL; unsigned int count, i; gboolean success = FALSE; const char *p; ResolutionInfoType *resInfo = &resolutionInfo; if (!resInfo->initialized) { g_debug("%s: FAIL! Request for topology set but plugin is not initialized\n", __FUNCTION__); RPCIN_SETRETVALS(data, "Invalid guest state: topology set not initialized", FALSE); goto out; } /* * The argument string will look something like: * [ , ] * count. * * e.g. * 3 , 0 0 640 480 , 640 0 800 600 , 0 480 640 480 */ if (sscanf(data->args, "%u", &count) != 1) { return RPCIN_SETRETVALS(data, "Invalid arguments. Expected \"count\"", FALSE); } displays = malloc(sizeof *displays * count); if (!displays) { RPCIN_SETRETVALS(data, "Failed to alloc buffer for display info", FALSE); goto out; } for (p = data->args, i = 0; i < count; i++) { p = strchr(p, ','); if (!p) { RPCIN_SETRETVALS(data, "Expected comma separated display list", FALSE); goto out; } p++; /* Skip past the , */ if (sscanf(p, " %d %d %d %d ", &displays[i].x, &displays[i].y, &displays[i].width, &displays[i].height) != 4) { RPCIN_SETRETVALS(data, "Expected x, y, w, h in display entry", FALSE); goto out; } } success = ResolutionSetTopology(count, displays); RPCIN_SETRETVALS(data, success ? "" : "ResolutionSetTopology failed", success); out: free(displays); return success; } /** * Cleanup internal data on shutdown. * * @param[in] src The source object. * @param[in] ctx Unused. * @param[in] data Unused. */ static void ResolutionSetShutdown(gpointer src, ToolsAppCtx *ctx, gpointer data) { ResolutionCleanup(); } /** * Sends the tools.capability.resolution_server RPC to the VMX. * * @param[in] chan The RPC channel. * @param[in] value The value to send for the capability bit. */ static void ResolutionSetServerCapability(RpcChannel *chan, unsigned int value) { gchar *msg; if (!rpcChannelName) { g_debug("Channel name is null, RPC not sent.\n"); return; } msg = g_strdup_printf("tools.capability.resolution_server %s %d", rpcChannelName, value); if (!RpcChannel_Send(chan, msg, strlen(msg), NULL, NULL)) { g_warning("%s: Unable to set tools.capability.resolution_server\n", __FUNCTION__); } g_free(msg); } /** * Returns the list of the plugin's capabilities. * * * @param[in] src The source object. * @param[in] ctx The app context. * @param[in] set Whether setting or unsetting the capability. * @param[in] data Unused. * * @return A list of capabilities. */ static GArray * ResolutionSetCapabilities(gpointer src, ToolsAppCtx *ctx, gboolean set, gpointer data) { /* The array of capabilities to return to the tools service. */ ToolsAppCapability capabilityArray[RESOLUTION_SET_CAPABILITIES_MAX]; /* The next unused entry in the capabilities array. */ unsigned int capabilityCount = 0; ResolutionInfoType *resInfo = &resolutionInfo; g_debug("%s: enter\n", __FUNCTION__); if (!resInfo->initialized) { return FALSE; } /* * XXX: We must register display_topology_set before resolution_set to avoid * a race condition in the host. See bug 472343. */ /* * If we can set the guest topology, add the display_topology_set and * display_global_offset capabilities to our array. */ if (resInfo->canSetTopology) { /* * XXX: We use a value of '2' here because, for historical reasons, the * Workstation/Fusion UI will treat a value of 1 for this capability * as unsupported. See bug 149541. */ capabilityArray[capabilityCount].type = TOOLS_CAP_OLD; capabilityArray[capabilityCount].name = "display_topology_set"; capabilityArray[capabilityCount].index = 0; capabilityArray[capabilityCount].value = set ? 2 : 0; capabilityCount++; capabilityArray[capabilityCount].type = TOOLS_CAP_OLD; capabilityArray[capabilityCount].name = "display_global_offset"; capabilityArray[capabilityCount].index = 0; capabilityArray[capabilityCount].value = set ? 1 : 0; capabilityCount++; } /* * If we can set the guest resolution, add the resolution_set capability to * our array. */ if (resInfo->canSetResolution) { capabilityArray[capabilityCount].type = TOOLS_CAP_OLD; capabilityArray[capabilityCount].name = "resolution_set"; capabilityArray[capabilityCount].index = 0; capabilityArray[capabilityCount].value = set ? 1 : 0; capabilityCount++; /* * Send the resolution_server RPC to the VMX. * * XXX: We need to send this ourselves, instead of including it in the * capability array, because the resolution_server RPC includes the * name of the RPC channel that the VMX should use when sending * resolution set RPCs as an argument. */ if (ctx && ctx->rpc && ctx->isVMware) { ResolutionSetServerCapability(ctx->rpc, set ? 1 : 0); } } #if defined(RESOLUTION_WIN32) /* * XXX: I believe we can always handle these RPCs from the service, even on * Vista, so we always set the capabilities here, regardless of the * value of resInfo->canSetTopology. */ g_debug("%s: setting DPY_TOPO_MODES_SET_IDX to %u\n", __FUNCTION__, set ? 1 : 0); capabilityArray[capabilityCount].type = TOOLS_CAP_NEW; capabilityArray[capabilityCount].name = NULL; capabilityArray[capabilityCount].index = CAP_SET_TOPO_MODES; capabilityArray[capabilityCount].value = set ? 1 : 0; capabilityCount++; capabilityArray[capabilityCount].type = TOOLS_CAP_NEW; capabilityArray[capabilityCount].name = NULL; capabilityArray[capabilityCount].index = CAP_CHANGE_HOST_3D_AVAILABILITY_HINT; capabilityArray[capabilityCount].value = set ? 1 : 0; capabilityCount++; #endif ASSERT(capabilityCount <= RESOLUTION_SET_CAPABILITIES_MAX); return VMTools_WrapArray(capabilityArray, sizeof *capabilityArray, capabilityCount); } /** * Plugin entry point. Initializes internal plugin state. * * @param[in] ctx The app context. * * @return The registration data. */ TOOLS_MODULE_EXPORT ToolsPluginData * ToolsOnLoad(ToolsAppCtx *ctx) { RpcChannelCallback rpcs[] = { { "Resolution_Set", &ResolutionResolutionSetCB }, { "DisplayTopology_Set", &ResolutionDisplayTopologySetCB }, #if defined(RESOLUTION_WIN32) { "DisplayTopologyModes_Set", &ResolutionDisplayTopologyModesSetCB }, { "ChangeHost3DAvailabilityHint", &ResolutionChangeHost3DAvailabilityHintCB }, #endif }; InitHandle handle; static ToolsPluginData regData = { "resolutionSet", NULL, NULL }; ToolsPluginSignalCb sigs[] = { { TOOLS_CORE_SIG_CAPABILITIES, ResolutionSetCapabilities, ®Data }, { TOOLS_CORE_SIG_SHUTDOWN, ResolutionSetShutdown, ®Data } }; ToolsAppReg regs[] = { { TOOLS_APP_GUESTRPC, NULL }, { TOOLS_APP_SIGNALS, VMTools_WrapArray(sigs, sizeof *sigs, ARRAYSIZE(sigs)) } }; ResolutionInfoType *resInfo = &resolutionInfo; /* * If we aren't running in a VM (e.g., running in bootcamp natively on * a Mac), then just return NULL. */ if (!ctx->isVMware) { return NULL; } /* * Save the RPC channel name from the ToolsAppCtx so that we can use it later * in calls to ResolutionSetServerCapability(). */ if (strcmp(ctx->name, VMTOOLS_GUEST_SERVICE) == 0) { rpcChannelName = TOOLS_DAEMON_NAME; } else if (strcmp(ctx->name, VMTOOLS_USER_SERVICE) == 0) { rpcChannelName = TOOLS_DND_NAME; } else { NOT_REACHED(); } resInfo->initialized = FALSE; /* * XXX move to some shared lib or plugin */ handle = ResolutionToolkitInit(); ResolutionInit(handle); regs[0].data = VMTools_WrapArray(rpcs, sizeof *rpcs, ARRAYSIZE(rpcs)); regData.regs = VMTools_WrapArray(regs, sizeof *regs, ARRAYSIZE(regs)); return ®Data; } open-vm-tools-9.4.0-1280544/services/plugins/resolutionSet/resolutionRandR12.c0000644765153500003110000007705512220061556025301 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * resolutionRandR12.c -- * * Set of functions to handle RandR12 guest screen resizing and topology change * for vmusr * */ /* * * The RandR12 API lacks good documentation. To avoid poor bug fixes, please * refer to the Xrandr.h header file and perhaps * * http://www.x.org/wiki/Development/Documentation/HowVideoCardsWork * * And become familiar with the following concepts: * * * Output An output is a physical monitor connector on the machine, and * the associated physical device. For the vmwgfx driver, * it's a logical entry point to which a VMware display may be * attached. * * * Mode A mode describes a resolution and associated timing information. * The timing information is never used for the vmwgfx display driver * itself, but may be used by the X server to purge modes whose * timing limits lie outside of its specification. The * X server keeps a global list of modes, and each output carries * a list of a subset of these modes that are suitable for that * output. * * * Crtc In a physical machine, a crtc is the device that scans out * data from a given portion of display memory and feeds it to * one or more outputs. The crtc and its outputs need to agree about * timing and they are therefore programmed with the same mode. * In the vmwgfx driver, there is one and only one output per * logical crtc and the crtc and its output may be viewed as a * single entity. * * * Fb Or framebuffer is the display storage area from which the * crtcs scan out. It needs to be at least the size of the union * of all crtc scanout areas, but may be larger. */ #ifndef NO_MULTIMON #include "resolutionInt.h" #include #include #include #include #include #include #include #include "resolutionRandR12.h" #include "str.h" #include "strutil.h" #include "util.h" #define RR12_MODE_FORMAT "vmw-autofit-%ux%u" #define RR12_MODE_MAXLEN (sizeof RR12_MODE_FORMAT + 2 * (10 - 2) + 1) #define RR12_DEFAULT_DPI (96.0) #define MILLIS_PER_INCH (25.4) /* * Local data */ /* * The output structure. * Contains detailed information about each output and its connectivity. */ typedef struct RandR12Output { XRROutputInfo *output; // Pointer to detailed info RROutput id; // XID of the output int crtc; // crtc entry in the RandR12Info array RRMode mode; // XID of current mode } RandR12Output; /* * The RandR12Info context. Contains info about the current topology state * and enough information to revert to the previous state. */ typedef struct RandR12Info { unsigned int nCrtc; // Number of crtcs in the crtcs array unsigned int nOutput; // Number of outputs in the outputs array unsigned int nNewModes; // Number of new modes in the newModes array XRRCrtcInfo **crtcs; RandR12Output *outputs; XRRModeInfo **newModes; // Newly created autofit modes XRRScreenResources *xrrRes; // Screen resuources obtained from the server unsigned int xdpi; // Current dpi in x direction unsigned int ydpi; // Current dpi in y direction unsigned int origWidth; // Used for reverting on failure unsigned int origHeight; // Used for reverting on failure int event_base; // For the RandR extension int error_base; } RandR12Info; /* * Optionally dump RandR12 log messages to a local logfile rather than to the * gtk logfile. */ /* #define _LOCAL_LOG_ "/tmp/randr12.log" */ #ifdef _LOCAL_LOG_ static FILE *_ofile; #define LOG_START _ofile = fopen(_LOCAL_LOG_, "a") #define g_debug(...) do { \ fprintf(_ofile, "Debug: " __VA_ARGS__); \ fflush(_ofile); } while (0) #define g_warning(...) do { \ fprintf(_ofile, "Warning: " __VA_ARGS__); \ fflush(_ofile); } while (0) #define LOG_STOP fclose(_ofile) #else #define LOG_START #include #define LOG_STOP #endif /* * Local functions */ static void RandR12FreeInfo(RandR12Info *info); static RandR12Info *RandR12GetInfo(Display *display, Window rootWin); static Bool RandR12CrtcDisable(Display *display, unsigned int ndisplays, RandR12Info *info, unsigned int width, unsigned int height); static unsigned int RandR12Dpi(unsigned int pixels, unsigned int mm); static void RandR12CurrentSize(Display *display, int screen, XRRScreenSize *cSize); static Bool RandR12SetSizeVerify(Display *display, Window rootWin, int screen, RandR12Info *info, int width, int height); static Bool RandR12OutputHasMode(XRROutputInfo *output, XRRModeInfo *modeInfo); static XRRModeInfo *RandR12MatchMode(Display *display, Window rootWin, RandR12Output *rrOutput, RandR12Info *info, int width, int height); static Bool RandR12SetupOutput(Display *display, Window rootWin, RandR12Info *info, RandR12Output *rrOutput, int x, int y, int width, int height); static void RandR12DeleteModes(Display *display, RandR12Info *info); /* *----------------------------------------------------------------------------- * * RandR12FreeInfo -- * * Free all allocations associated with a RandR12Info context * * Results: * The RandR12Info context is freed, and the pointer may no * longer be dereferenced. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void RandR12FreeInfo(RandR12Info *info) // IN/OUT the RandR12Info context { unsigned int i; if (!info) { return; } if (!info->xrrRes) { goto out_freeinfo; } for (i = 0; i < info->nNewModes; ++i) { XRRFreeModeInfo(info->newModes[i]); } for (i = 0; i < info->nCrtc; ++i) { if (info->crtcs[i]) { XRRFreeCrtcInfo(info->crtcs[i]); } } for (i = 0; i < info->nOutput; ++i) { if (info->outputs[i].output) { XRRFreeOutputInfo(info->outputs[i].output); } } free(info->newModes); free(info->outputs); free(info->crtcs); XRRFreeScreenResources(info->xrrRes); out_freeinfo: free(info); } /* *----------------------------------------------------------------------------- * * RandR12GetInfo -- * * Allocate and initialize a RandR12Info context. * Get the current X server configuration and info about outputs and * crtcs. When done with the context, it should be freed using * RandR12FreeInfo. * * Results: * A pointer to a RandR12Info context on success. NULL on failure. * * Side effects: * The info structure is setup for subsequent use of other functions. * Space is allocated as needed and outputs are ordered in the * info->outputs array with LVDS0 first and LVDS8 last. * *----------------------------------------------------------------------------- */ static RandR12Info * RandR12GetInfo(Display *display, // IN: Pointer to our display connection Window rootWin) // IN: ID of the root window { unsigned int i, j, num, numVMWCrtc; XRROutputInfo *output; RandR12Output *rrOutput; XRRCrtcInfo *crtc; XRRScreenResources *xrrRes; unsigned int nVMWOutput = 0; RandR12Info *info = Util_SafeCalloc(1, sizeof *info); /* * XRRQueryExtension is only used to get info->event_base, */ if (!XRRQueryExtension(display, &info->event_base, &info->error_base)) { g_warning("%s: XRRQueryExtension failed.\n", __func__); goto out_err; } info->xrrRes = xrrRes = XRRGetScreenResources(display, rootWin); if (!xrrRes) { goto out_err; } info->nCrtc = xrrRes->ncrtc; info->nOutput = xrrRes->noutput; info->crtcs = Util_SafeCalloc(info->nCrtc, sizeof *info->crtcs); info->outputs = Util_SafeCalloc(info->nOutput, sizeof *info->outputs); info->newModes = Util_SafeCalloc(info->nOutput, sizeof *info->newModes); for (i = 0; i < info->nOutput; ++i) { output = XRRGetOutputInfo(display, xrrRes, xrrRes->outputs[i]); if (!output) { goto out_err; } if (sscanf(output->name, RR12_OUTPUT_FORMAT, &num) != 1) { XRRFreeOutputInfo(output); continue; } if (num > info->nOutput) { XRRFreeOutputInfo(output); goto out_err; } info->outputs[num - 1].output = output; info->outputs[num - 1].id = xrrRes->outputs[i]; info->outputs[num - 1].crtc = -1; if (num > nVMWOutput) { nVMWOutput = num; } } /* * Sanity checks. This should never really happen with current drivers. */ if (nVMWOutput != info->nOutput) { g_warning("%s: Not all outputs were VMW outputs.\n", __func__); goto out_err; } for (i = 0; i < nVMWOutput; ++i) { if (!info->outputs[i].output) { g_warning("%s: Missing output. %d\n", __func__, i); goto out_err; } } numVMWCrtc = 0; for (i = 0; i < info->nCrtc; ++i) { crtc = XRRGetCrtcInfo(display, xrrRes, xrrRes->crtcs[i]); if (!crtc) { goto out_err; } info->crtcs[i] = crtc; for (j = 0; j < nVMWOutput; ++j) { rrOutput = &info->outputs[j]; if (crtc->npossible > 0 && crtc->possible[0] == rrOutput->id && rrOutput->crtc == -1) { rrOutput->crtc = i; rrOutput->mode = crtc->mode; numVMWCrtc++; break; } } } /* * Sanity check. This should never really happen with our drivers. */ if (numVMWCrtc != nVMWOutput) { g_warning("%s: Crtc / Output number mismatch.\n", __func__); goto out_err; } return info; out_err: RandR12FreeInfo(info); return NULL; } /* *----------------------------------------------------------------------------- * * RandR12CrtcDisable -- * * Disable crtcs and associated outputs before an fb size change. * The function disables crtcs and associated outputs * 1) whose scanout area is too big for the new fb size. * 2) that are going to be disabled with the new topology. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * The RandR12info context is modified. * The current mode of disabled outputs is set to "None". * *----------------------------------------------------------------------------- */ static Bool RandR12CrtcDisable(Display *display, // IN: Pointer to display // connection unsigned int ndisplays, // IN: Number of VMware display in // the new topology RandR12Info *info, // IN/OUT: The RandR12Info context unsigned int width, // IN: Width of new topology unsigned int height) // IN: Height of new topology { XRRScreenResources *xrrRes = info->xrrRes; XRRCrtcInfo *crtc; unsigned int i; for (i = 0; i < info->nCrtc; ++i) { crtc = info->crtcs[i]; if (crtc->mode != None && (crtc->x + crtc->width > width || crtc->y + crtc->height > height)) { if (XRRSetCrtcConfig(display, xrrRes, xrrRes->crtcs[i], CurrentTime, 0, 0, None, RR_Rotate_0, NULL, 0) != Success) { return FALSE; } } } for (i = ndisplays; i < info->nOutput; ++i) { crtc = info->crtcs[info->outputs[i].crtc]; if (crtc->mode != None && XRRSetCrtcConfig(display, xrrRes, xrrRes->crtcs[i], CurrentTime, 0, 0, None, RR_Rotate_0, NULL, 0) != Success) { return FALSE; } info->outputs[i].mode = None; } return TRUE; } /* *----------------------------------------------------------------------------- * * RandR12Dpi -- * * Given a number of pixels and a width in mm, compute the DPI value. * If input or output looks suspicious (zero), revert to a default * DPI value. * * Results: * Returns the DPI value. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static unsigned int RandR12Dpi(unsigned int pixels, // IN: Dimension in pixels unsigned int mm) // IN: Dimension in mm { unsigned int dpi = 0; if (mm > 0) { dpi = (unsigned int)((double)pixels * MILLIS_PER_INCH / (double)mm + 0.5); } return (dpi > 0) ? dpi : RR12_DEFAULT_DPI; } /* *----------------------------------------------------------------------------- * * RandR12CurrentSize -- * * Return the current dimensions of the fb, as cached in the display * structure. * * Results: * cSize is filled with the dimensions in pixels and mm. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void RandR12CurrentSize(Display *display, // IN: Pointer to the display // connection int screen, // IN: The X screen XRRScreenSize *cSize) // OUT: The fb size { memset(cSize, 0, sizeof *cSize); cSize->width = DisplayWidth(display, screen); cSize->mwidth = DisplayWidthMM(display, screen); cSize->height = DisplayHeight(display, screen); cSize->mheight = DisplayHeightMM(display, screen); } /* *----------------------------------------------------------------------------- * * RandR12GetDpi -- * * Save the width, height and dpi of the current fb setup. * This is used when reverting on failure and the dpi is used * to calculate the new fb dimesions in mm. * * Results: * The info structure is populated with the computed values. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void RandR12GetDpi(Display *display, // IN: Pointer to the display connection int screen, // IN: The X server screen RandR12Info *info) // OUT: The RandR12Info context { XRRScreenSize cSize; RandR12CurrentSize(display, screen, &cSize); info->origWidth = cSize.width; info->origHeight = cSize.height; info->xdpi = RandR12Dpi(cSize.width, cSize.mwidth); info->ydpi = RandR12Dpi(cSize.height, cSize.mheight); g_debug("%s: DPI is %u %u\n", __func__, info->xdpi, info->ydpi); } /* *----------------------------------------------------------------------------- * * RandR12SetSizeVerify -- * * Set a new fb size, verify that the change went through and update * the display structure. * * Results: * Returns TRUE if function succeeds, FALSE otherwise. Upon failure, * the function will make an attempt to restore the previous dimensions. * The display structure is updated to hold the new dimensions. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool RandR12SetSizeVerify(Display *display, // IN/OUT: Pointer to the display // connection Window rootWin, // IN: ID of root window int screen, // IN: ID of X screen RandR12Info *info, // IN: The RandR12Info context int width, // IN: New width int height) // IN: New height { XRRScreenSize cSize; XEvent configEvent; unsigned int xmm; unsigned int ymm; Bool event = FALSE; xmm = (int)(MILLIS_PER_INCH * width / ((double)info->xdpi) + 0.5); ymm = (int)(MILLIS_PER_INCH * height / ((double)info->ydpi) + 0.5); g_debug("%s: Setting screenSize to %d %d %d %d\n", __func__, width, height, xmm, ymm); XRRSelectInput(display, rootWin, RRScreenChangeNotifyMask); XRRSetScreenSize(display, rootWin, width, height, xmm, ymm); /* * We need to sync and parse these events to update our display * structure with the new size. Nobody else does this for us. */ XSync(display, FALSE); while (XCheckTypedEvent(display, RRScreenChangeNotify + info->event_base, &configEvent)) { (void)XRRUpdateConfiguration(&configEvent); event = TRUE; } XRRSelectInput(display, rootWin, 0); if (!event) { g_warning("%s: Received no size change events.\n", __func__); } RandR12CurrentSize(display, screen, &cSize); if (cSize.width == width && cSize.height == height) { return TRUE; } /* * On failure, try to revert to the original size in preparation for * also reverting the Crtcs. */ if (cSize.width != info->origWidth || cSize.height != info->origHeight) { xmm = (int)(MILLIS_PER_INCH * info->origWidth / ((double)info->xdpi) + 0.5); ymm = (int)(MILLIS_PER_INCH * info->origHeight / ((double)info->ydpi) + 0.5); XRRSelectInput(display, rootWin, RRScreenChangeNotifyMask); XRRSetScreenSize(display, rootWin, info->origWidth, info->origHeight, xmm, ymm); XSync(display, FALSE); while (XCheckTypedEvent(display, RRScreenChangeNotify + info->event_base, &configEvent)) { (void)XRRUpdateConfiguration(&configEvent); } XRRSelectInput(display, rootWin, 0); } return FALSE; } /* *----------------------------------------------------------------------------- * * RandR12OutputHasMode -- * * Determine whether a mode is registered with an output. * * Results: * TRUE if the mode is registered, FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool RandR12OutputHasMode(XRROutputInfo *output, // IN: Output XRRModeInfo *modeInfo) // IN: Mode. { unsigned int i; for (i = 0; i < output->nmode; ++i) { if (output->modes[i] == modeInfo->id) { return TRUE; } } return FALSE; } /* *----------------------------------------------------------------------------- * * RandR12MatchMode -- * * Lookup an already exising mode, or register a new mode for the * given size and the given output. * * Results: * Returns a pointer to the mode's XRRModeInfo structure on success. * NULL on failure. * * Side effects: * If a new mode is created, it is registered with the RandR12Info * structure for cached lookup, and with the X server. * *----------------------------------------------------------------------------- */ static XRRModeInfo * RandR12MatchMode(Display *display, // IN: Pointer to display connection Window rootWin, // IN: ID of root window RandR12Output *rrOutput, // IN: The output RandR12Info *info, // IN/OUT: RandR12Info context int width, // IN: Width of sought mode int height) // IN: Height of sought mode. { XRROutputInfo *output = rrOutput->output; XRRScreenResources *xrrRes = info->xrrRes; XRRModeInfo *modeInfo = NULL; char name[RR12_MODE_MAXLEN]; int i; RRMode newMode; g_debug("%s: Trying to find a mode for resolution %dx%d.\n", __func__, width, height); for (i = 0; i < xrrRes->nmode; ++i) { modeInfo = &xrrRes->modes[i]; if (modeInfo->width == width && modeInfo->height == height) { unsigned int w, h; /* * An autofit mode will work with any output */ if (sscanf(modeInfo->name, RR12_MODE_FORMAT, &w, &h) == 2) { return modeInfo; } /* * Otherwise, make sure the mode is registered with the given output, * to avoid issues with timing incompatibilities. */ if (RandR12OutputHasMode(output, modeInfo)) { g_debug("%s: Found an existing mode. Mode name is %s\n", __func__, modeInfo->name); return modeInfo; } } } /* * Check for recent autofit modes. If the mode is not in the * output's modelist, then add it. */ for (i = 0; i < info->nNewModes; ++i) { modeInfo = info->newModes[i]; if (modeInfo->width == width && modeInfo->height == height) { if (!RandR12OutputHasMode(output, modeInfo)) { XRRAddOutputMode(display, rrOutput->id, modeInfo->id); } g_debug("%s: Found a recent autofit mode. Mode name is %s\n", __func__, modeInfo->name); return modeInfo; } } /* * Create a new mode. */ snprintf(name, sizeof name, RR12_MODE_FORMAT, width, height); modeInfo = XRRAllocModeInfo(name, strlen(name)); modeInfo->width = width; modeInfo->height = height; newMode = XRRCreateMode(display, rootWin, modeInfo); if (newMode == None) { XRRFreeModeInfo(modeInfo); return NULL; } modeInfo->id = newMode; info->newModes[info->nNewModes++] = modeInfo; XRRAddOutputMode(display, rrOutput->id, modeInfo->id); g_debug("%s: Set up a new mode. Mode name is %s\n", __func__, modeInfo->name); return modeInfo; } /* *----------------------------------------------------------------------------- * * RandR12SetupOutput -- * * Set up an output and it's associated CRTC to scanout and show a * specified region of the frame-buffer. * * Results: * Returns TRUE on success. FALSE on failure. * May add new modes to the RandR12Info context. * Sets up rrOutput->mode to point to the new mode. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool RandR12SetupOutput(Display *display, // IN: The display connection Window rootWin, // IN: ID of root window RandR12Info *info, // IN/OUT: RandR12Info context RandR12Output *rrOutput, // IN/OUT: Identifies the output int x, // IN: X coordinate of upper // left corner of scanout area int y, // IN: Corresponding Y coordinate int width, // IN: Width of scanout area int height) // IN: Height of scanout area { RRCrtc crtcID = info->xrrRes->crtcs[rrOutput->crtc]; XRRModeInfo *mode; Status ret; mode = RandR12MatchMode(display, rootWin, rrOutput, info, width, height); g_debug("%s: Setting up RandR Crtc %d. %dx%d@%d,%d: \"%s\"\n", __func__, (int)crtcID, width, height, x, y, (mode) ? mode->name : "NULL"); if (!mode) { return FALSE; } ret = XRRSetCrtcConfig(display, info->xrrRes, crtcID, CurrentTime, x, y, mode->id, RR_Rotate_0, &rrOutput->id, 1); if (ret == Success) { rrOutput->mode = mode->id; return TRUE; } return FALSE; } /* *----------------------------------------------------------------------------- * * RandR12DeleteModes -- * * Delete unused autofit modes from outputs not using them and * unregister those modes from the X server if no utput is using * them. * * Results: * Nothing immediately visible to the caller. * * Side effects: * Invalidates the RandR12Info context for subsequent mode lookups. * The RandR12Info context should be destroyed after this operation. * *----------------------------------------------------------------------------- */ static void RandR12DeleteModes(Display *display, // IN: The display connection RandR12Info *info) // IN: RandR12Info context { XRRScreenResources *xrrRes = info->xrrRes; XRRModeInfo *modeInfo; RandR12Output *rrOutput; unsigned int i, j; unsigned int w, h; Bool used; /* * Loop over the global X server mode list skipping modes that are not * our autofit modes. */ for (i = 0; i < xrrRes->nmode; ++i) { modeInfo = &xrrRes->modes[i]; if (sscanf(modeInfo->name, RR12_MODE_FORMAT, &w, &h) != 2) { continue; } used = FALSE; /* * Loop over all outputs and see if the outfit mode is used by any * output. In that case mark it as used, * otherwise check if the mode is in the output's mode list. * In that case remove it from the output mode list. */ for (j = 0; j < info->nOutput; ++j) { rrOutput = &info->outputs[j]; if (rrOutput->mode != modeInfo->id) { if (RandR12OutputHasMode(rrOutput->output, modeInfo)) { g_debug("%s: Deleting mode %s.\n", __func__, modeInfo->name); XRRDeleteOutputMode(display, rrOutput->id, modeInfo->id); } } else { used = TRUE; } } /* * If the mode wasn't used by any output, remove it from the X server's * global modelist. */ if (!used) { g_debug("%s: Destroying mode %s.\n", __func__, modeInfo->name); XRRDestroyMode(display, modeInfo->id); } } } /* *----------------------------------------------------------------------------- * * RandR12Revert -- * * Attempt to revert crtcs and outputs to the previous topology. * Delete unused autofit modes. * * Results: * Nothing immediately visible to the caller. * The RandR12Info context pointer may be replaced with a * pointer to a new context. In that case the old context * will have been freed. * * Side effects: * The RandR12Info context will be invalidated for subsequent * mode lookups and should be destroyed after this operation. * *----------------------------------------------------------------------------- */ static void RandR12Revert(Display *display, // IN: The display connection Window rootWin, // IN: ID of the root window RandR12Info **pInfo) // IN/OUT: RandR12Info context pointer { unsigned int i; RandR12Info *info = *pInfo; XRRScreenResources *xrrRes = info->xrrRes; RandR12Output *rrOutput; XRRCrtcInfo *crtc; RRCrtc crtcID; g_debug("%s: Reverting to original setup.\n", __func__); for (i = 0; i < info->nOutput; ++i) { rrOutput = &info->outputs[i]; crtc = info->crtcs[rrOutput->crtc]; crtcID = xrrRes->crtcs[rrOutput->crtc]; if (XRRSetCrtcConfig(display, info->xrrRes, crtcID, CurrentTime, crtc->x, crtc->y, crtc->mode, crtc->rotation, crtc->outputs, crtc->noutput) != Success) { g_warning("%s: Reverting crtc id %d failed.\n", __func__, (int)crtcID); } else { rrOutput->mode = crtc->mode; } } *pInfo = RandR12GetInfo(display, rootWin); if (*pInfo) { RandR12FreeInfo(info); info = *pInfo; RandR12DeleteModes(display, info); } else { *pInfo = info; g_warning("%s: Deleting unused modes after revert failed.\n", __func__); } } /* *----------------------------------------------------------------------------- * * RandR12_SetTopology -- * * Employs the RandR 1.2 extension to set a new display topology. * This is for the new vmwgfx X driver, which uses RandR 1.2 to * program multiple outputs. * Delete unused autofit modes. * * Results: * Returns TRUE on success, FALSE on failure. * The Display structure will be updated with the new fb dimensions. * On failure, the function will have made an attempt to restore the * old dimensions and topology. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool RandR12_SetTopology(Display *dpy, // IN/OUT: The display connection int screen, // IN: The X screen Window rootWin, // IN: ID of root window unsigned int ndisplays, // IN: Number of VMware displays // in the topology. xXineramaScreenInfo *displays, // IN: Array describing the // topology unsigned int width, // IN: Topology width unsigned int height) // IN: Topology height { int minWidth, minHeight, maxWidth, maxHeight; RandR12Info *info; Bool retVal = FALSE; unsigned int i; static unsigned long sequence = 0; LOG_START; g_debug("%s: New request. Sequence is %lu\n", __func__, sequence++); if (!XRRGetScreenSizeRange(dpy, rootWin, &minWidth, &minHeight, &maxWidth, &maxHeight) || width < minWidth || height < minHeight || width > maxWidth || height > maxHeight) { g_warning("%s: Invalid size request.\n", __func__); LOG_STOP; return FALSE; } info = RandR12GetInfo(dpy, rootWin); if (!info) { g_warning("%s: Setup info struct failed.\n", __func__); goto out_ungrab; } RandR12GetDpi(dpy, screen, info); if (!RandR12CrtcDisable(dpy, ndisplays, info, width, height)) { g_warning("%s: Failed disabling unused crtcs.\n", __func__); RandR12Revert(dpy, rootWin, &info); goto out_ungrab; } if (!RandR12SetSizeVerify(dpy, rootWin, screen, info, width, height)) { g_warning("%s: Failed setting new framebuffer size.\n", __func__); RandR12Revert(dpy, rootWin, &info); goto out_ungrab; } g_debug("%s: Setting up %d VMware displays.\n", __func__, ndisplays); for (i = 0; i < ndisplays; ++i) { xXineramaScreenInfo *vmwin = &displays[i]; if (i >= info->nOutput) break; if (!RandR12SetupOutput(dpy, rootWin, info, &info->outputs[i], vmwin->x_org, vmwin->y_org, vmwin->width, vmwin->height)) { /* * If this fails, something is seriously wrong, so * we don't try to revert at this point. */ g_warning("%s: Setup VMware display %d failed, " "but we're not reverting the operation.\n", __func__, i); } } retVal = TRUE; out_ungrab: g_debug("%s: Deleting unused autofit modes.\n", __func__); RandR12DeleteModes(dpy, info); XSync(dpy, FALSE); RandR12FreeInfo(info); LOG_STOP; return retVal; } #endif // ifndef NO_MULTIMON open-vm-tools-9.4.0-1280544/services/plugins/resolutionSet/COPYING0000644765153500003110000006347112220061556022670 0ustar dtormts GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! open-vm-tools-9.4.0-1280544/services/plugins/resolutionSet/Makefile.am0000644765153500003110000000310612220061556023656 0ustar dtormts################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ plugindir = @VMUSR_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libresolutionSet.la libresolutionSet_la_CPPFLAGS = libresolutionSet_la_CPPFLAGS += @GTK_CPPFLAGS@ libresolutionSet_la_CPPFLAGS += @PLUGIN_CPPFLAGS@ libresolutionSet_la_CPPFLAGS += -DRESOLUTION_X11 libresolutionSet_la_LDFLAGS = libresolutionSet_la_LDFLAGS += @PLUGIN_LDFLAGS@ libresolutionSet_la_LIBADD = libresolutionSet_la_LIBADD += @COMMON_XLIBS@ libresolutionSet_la_LIBADD += @GTK_LIBS@ libresolutionSet_la_LIBADD += @VMTOOLS_LIBS@ libresolutionSet_la_SOURCES = libresolutionSet_la_SOURCES += libvmwarectrl.c libresolutionSet_la_SOURCES += resolutionSet.c libresolutionSet_la_SOURCES += resolutionX11.c libresolutionSet_la_SOURCES += resolutionRandR12.c open-vm-tools-9.4.0-1280544/services/plugins/resolutionSet/resolutionRandR12.h0000644765153500003110000000307212220061556025272 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * resolutionRandR12.h -- * * This header file exports the minimalistic RandR12 utilities * interface. */ #ifndef _RESOLUTIONRANDR12_H_ #define _RESOLUTIONRANDR12_H_ #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #ifndef NO_MULTIMON #include #include #include #include #define RR12_OUTPUT_FORMAT "Virtual%u" /* * Global functions */ extern Bool RandR12_SetTopology(Display *dpy, int screen, Window rootWin, unsigned int ndisplays, xXineramaScreenInfo *displays, unsigned int width, unsigned int height); #endif // ifndef NO_MULTIMON #endif // ifndef _RESOLUTIONRANDR12_H_ open-vm-tools-9.4.0-1280544/services/plugins/resolutionSet/vmwarectrlproto.h0000644765153500003110000000706412220061556025254 0ustar dtormts/* * Copyright 2006 by VMware, Inc. * * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. * * Except as contained in this notice, the name of the copyright holder(s) * and author(s) shall not be used in advertising or otherwise to promote * the sale, use or other dealings in this Software without prior written * authorization from the copyright holder(s) and author(s). */ /* * vmwarectrlproto.h -- * * The description of the VMWARE_CTRL protocol extension that * allows X clients to communicate with the driver. */ #ifndef _VMWARE_CTRL_PROTO_H_ #define _VMWARE_CTRL_PROTO_H_ #include #include "vmwarectrl.h" /* * Requests and Replies */ /* Version 0.1 definitions. */ typedef struct { CARD8 reqType; /* always X_VMwareCtrlReqCode */ CARD8 VMwareCtrlReqType; /* always X_VMwareCtrlQueryVersion */ CARD16 length B16; CARD32 majorVersion B32; CARD32 minorVersion B32; } xVMwareCtrlQueryVersionReq; #define sz_xVMwareCtrlQueryVersionReq 12 typedef struct { BYTE type; /* X_Reply */ BYTE pad1; CARD16 sequenceNumber B16; CARD32 length B32; CARD32 majorVersion B32; CARD32 minorVersion B32; CARD32 pad2 B32; CARD32 pad3 B32; CARD32 pad4 B32; CARD32 pad5 B32; } xVMwareCtrlQueryVersionReply; #define sz_xVMwareCtrlQueryVersionReply 32 typedef struct { CARD8 reqType; /* always X_VMwareCtrlReqCode */ CARD8 VMwareCtrlReqType; /* always X_VMwareCtrlSetRes */ CARD16 length B16; CARD32 screen B32; CARD32 x B32; CARD32 y B32; } xVMwareCtrlSetResReq; #define sz_xVMwareCtrlSetResReq 16 typedef struct { BYTE type; /* X_Reply */ BYTE pad1; CARD16 sequenceNumber B16; CARD32 length B32; CARD32 screen B32; CARD32 x B32; CARD32 y B32; CARD32 pad2 B32; CARD32 pad3 B32; CARD32 pad4 B32; } xVMwareCtrlSetResReply; #define sz_xVMwareCtrlSetResReply 32 /* Version 0.2 definitions. */ typedef struct { CARD8 reqType; /* always X_VMwareCtrlReqCode */ CARD8 VMwareCtrlReqType; /* always X_VMwareCtrlSetTopology */ CARD16 length B16; CARD32 screen B32; CARD32 number B32; CARD32 pad1 B32; } xVMwareCtrlSetTopologyReq; #define sz_xVMwareCtrlSetTopologyReq 16 typedef struct { BYTE type; /* X_Reply */ BYTE pad1; CARD16 sequenceNumber B16; CARD32 length B32; CARD32 screen B32; CARD32 pad2 B32; CARD32 pad3 B32; CARD32 pad4 B32; CARD32 pad5 B32; CARD32 pad6 B32; } xVMwareCtrlSetTopologyReply; #define sz_xVMwareCtrlSetTopologyReply 32 #endif /* _VMWARE_CTRL_PROTO_H_ */ open-vm-tools-9.4.0-1280544/services/plugins/resolutionSet/vmwarectrl.h0000644765153500003110000000351412220061556024164 0ustar dtormts/* * Copyright 2006 by VMware, Inc. * * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. * * Except as contained in this notice, the name of the copyright holder(s) * and author(s) shall not be used in advertising or otherwise to promote * the sale, use or other dealings in this Software without prior written * authorization from the copyright holder(s) and author(s). */ /* * vmwarectrl.h -- * * The definitions used by the VMWARE_CTRL protocol extension that * allows X clients to communicate with the driver. */ #ifndef _VMWARE_CTRL_H_ #define _VMWARE_CTRL_H_ #define VMWARE_CTRL_PROTOCOL_NAME "VMWARE_CTRL" #define VMWARE_CTRL_MAJOR_VERSION 0 #define VMWARE_CTRL_MINOR_VERSION 2 #define X_VMwareCtrlQueryVersion 0 #define X_VMwareCtrlSetRes 1 #define X_VMwareCtrlSetTopology 2 #endif /* _VMWARE_CTRL_H_ */ open-vm-tools-9.4.0-1280544/services/plugins/resolutionSet/libvmwarectrl.c0000644765153500003110000001646612220061556024660 0ustar dtormts/* * Copyright 2006 by VMware, Inc. * * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. * * Except as contained in this notice, the name of the copyright holder(s) * and author(s) shall not be used in advertising or otherwise to promote * the sale, use or other dealings in this Software without prior written * authorization from the copyright holder(s) and author(s). */ /* * libvmwarectrl.c -- * * The VMWARE_CTRL client library. */ #define NEED_EVENTS #define NEED_REPLIES #include #include "libvmwarectrl.h" #include "vmwarectrlproto.h" #include #include /* * Static data and functions. */ static XExtensionInfo _vmwarectrl_info_data; static XExtensionInfo *vmwarectrl_info = &_vmwarectrl_info_data; static char *vmwarectrl_extension_name = VMWARE_CTRL_PROTOCOL_NAME; #define VMwareCtrlCheckExtension(dpy, i, val) \ XextCheckExtension(dpy, i, vmwarectrl_extension_name, val) static int close_display(Display *dpy, XExtCodes *codes); static /* const */ XExtensionHooks vmwarectrl_extension_hooks = { NULL, /* create_gc */ NULL, /* copy_gc */ NULL, /* flush_gc */ NULL, /* free_gc */ NULL, /* create_font */ NULL, /* free_font */ close_display, /* close_display */ NULL, /* wire_to_event */ NULL, /* event_to_wire */ NULL, /* error */ NULL, /* error_string */ }; static XEXT_GENERATE_CLOSE_DISPLAY (close_display, vmwarectrl_info) static XEXT_GENERATE_FIND_DISPLAY (find_display, vmwarectrl_info, vmwarectrl_extension_name, &vmwarectrl_extension_hooks, 0, NULL) /* *---------------------------------------------------------------------------- * * VMwareCtrl_QueryExtension -- * * Standard QueryExtension implementation. Not very interesting for * VMWARE_CTRL as it doesn't define any events or errors. * * Results: * True if information is successfully retrieved. False otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool VMwareCtrl_QueryExtension(Display *dpy, // IN: int *event_basep, // OUT: int *error_basep) // OUT: { XExtDisplayInfo *info = find_display(dpy); if (XextHasExtension(info)) { *event_basep = info->codes->first_event; *error_basep = info->codes->first_error; return True; } else { return False; } } /* *---------------------------------------------------------------------------- * * VMwareCtrl_QueryVersion -- * * Send the QueryVersion command to the driver and return the results. * * Results: * True if information is successfully retrieved. False otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool VMwareCtrl_QueryVersion(Display *dpy, // IN: int *majorVersion, // OUT: int *minorVersion) // OUT: { xVMwareCtrlQueryVersionReply rep; xVMwareCtrlQueryVersionReq *req; XExtDisplayInfo *info = find_display(dpy); Bool ret = False; VMwareCtrlCheckExtension(dpy, info, False); LockDisplay(dpy); GetReq(VMwareCtrlQueryVersion, req); req->reqType = info->codes->major_opcode; req->VMwareCtrlReqType = X_VMwareCtrlQueryVersion; if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { goto exit; } *majorVersion = rep.majorVersion; *minorVersion = rep.minorVersion; ret = True; exit: UnlockDisplay(dpy); SyncHandle(); return ret; } /* *---------------------------------------------------------------------------- * * VMwareCtrl_SetRes -- * * Send the SetRes command to the driver. * * Results: * True if the resolution was set. False otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool VMwareCtrl_SetRes(Display *dpy, // IN: int screen, // IN: int x, // IN: int y) // IN: { xVMwareCtrlSetResReply rep; xVMwareCtrlSetResReq *req; XExtDisplayInfo *info = find_display(dpy); Bool ret = False; VMwareCtrlCheckExtension(dpy, info, False); LockDisplay(dpy); GetReq(VMwareCtrlSetRes, req); req->reqType = info->codes->major_opcode; req->VMwareCtrlReqType = X_VMwareCtrlSetRes; req->screen = screen; req->x = x; req->y = y; if (!_XReply(dpy, (xReply *)&rep, (SIZEOF(xVMwareCtrlSetResReply) - SIZEOF(xReply)) >> 2, xFalse)) { goto exit; } ret = True; exit: UnlockDisplay(dpy); SyncHandle(); return ret; } /* *---------------------------------------------------------------------------- * * VMwareCtrl_SetTopology -- * * Send the SetTopology command to the driver. * * Solaris 10 uses a different Xinerama standard than expected here. As a * result, topology set is not supported and this function is excluded from * Solaris builds. * * Results: * True if the resolution and xinerama topology were set. False otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #ifndef NO_MULTIMON Bool VMwareCtrl_SetTopology(Display *dpy, // IN: int screen, // IN: xXineramaScreenInfo extents[], // IN: int number) // IN: { xVMwareCtrlSetTopologyReply rep; xVMwareCtrlSetTopologyReq *req; XExtDisplayInfo *info = find_display(dpy); Bool ret = False; long len; VMwareCtrlCheckExtension(dpy, info, False); LockDisplay(dpy); GetReq(VMwareCtrlSetTopology, req); req->reqType = info->codes->major_opcode; req->VMwareCtrlReqType = X_VMwareCtrlSetTopology; req->screen = screen; req->number = number; len = ((long) number) << 1; SetReqLen(req, len, len); len <<= 2; _XSend(dpy, (char *)extents, len); if (!_XReply(dpy, (xReply *)&rep, (SIZEOF(xVMwareCtrlSetTopologyReply) - SIZEOF(xReply)) >> 2, xFalse)) { goto exit; } ret = True; exit: UnlockDisplay(dpy); SyncHandle(); return ret; } #endif open-vm-tools-9.4.0-1280544/services/plugins/resolutionSet/resolutionInt.h0000644765153500003110000000570612220061556024661 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file resolutionInt.h -- * * Internal header file for lib/resolution. */ #ifndef _LIB_RESOLUTIONINT_H_ #define _LIB_RESOLUTIONINT_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_DISTRIBUTE #include "includeCheck.h" #include "vmware.h" #if defined(_WIN32) # include "resolutionWinCommon.h" #endif #if defined(RESOLUTION_X11) # include typedef Display * InitHandle; #elif defined(__APPLE__) || defined(RESOLUTION_WIN32) typedef void * InitHandle; #else # error Unknown display backend #endif /* * Describes internal state of the resolution library. I.e., tracks whether * a capability is supported, enabled, etc. */ typedef struct { Bool initialized; // TRUE if successfully initialized. Bool canSetResolution; // TRUE if back-end supports Resolution_Set. Bool canSetTopology; // TRUE if back-end supports DisplayTopology_Set. } ResolutionInfoType; #if !defined(_WIN32) /* * Describes the size and offset of a display. An array of these * structures describes the entire topology of the guest desktop. * * XXX: For Win32, this is already defined in resolutionWinCommon.h. */ typedef struct { int x; int y; int width; int height; } DisplayTopologyInfo; #endif /* * Global variables */ extern ResolutionInfoType resolutionInfo; /* * Global functions */ /* Functions defined by back-end. */ Bool ResolutionBackendInit(InitHandle handle); InitHandle ResolutionToolkitInit(void); void ResolutionBackendCleanup(void); Bool ResolutionSetResolution(uint32 width, uint32 height); #if defined(RESOLUTION_WIN32) Bool ResolutionChangeHost3DAvailabilityHint(Bool enable); void ResolutionSetSessionChange(DWORD code, DWORD sessionID); #endif Bool ResolutionSetTopology(unsigned int ndisplays, DisplayTopologyInfo displays[]); Bool ResolutionSetTopologyModes(unsigned int screen, unsigned int cmd, unsigned int ndisplays, DisplayTopologyInfo displays[]); #if defined(G_LOG_DOMAIN) #error Please include this file before glib.h #endif #define G_LOG_DOMAIN "resolutionSet" #endif // ifndef _LIB_RESOLUTIONINT_H_ open-vm-tools-9.4.0-1280544/services/plugins/resolutionSet/Makefile.in0000644765153500003110000006361412220061625023676 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = services/plugins/resolutionSet DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(plugin_LTLIBRARIES) libresolutionSet_la_DEPENDENCIES = am_libresolutionSet_la_OBJECTS = libresolutionSet_la-libvmwarectrl.lo \ libresolutionSet_la-resolutionSet.lo \ libresolutionSet_la-resolutionX11.lo \ libresolutionSet_la-resolutionRandR12.lo libresolutionSet_la_OBJECTS = $(am_libresolutionSet_la_OBJECTS) libresolutionSet_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libresolutionSet_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libresolutionSet_la_SOURCES) DIST_SOURCES = $(libresolutionSet_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ plugindir = @VMUSR_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libresolutionSet.la libresolutionSet_la_CPPFLAGS = @GTK_CPPFLAGS@ @PLUGIN_CPPFLAGS@ \ -DRESOLUTION_X11 libresolutionSet_la_LDFLAGS = @PLUGIN_LDFLAGS@ libresolutionSet_la_LIBADD = @COMMON_XLIBS@ @GTK_LIBS@ @VMTOOLS_LIBS@ libresolutionSet_la_SOURCES = libvmwarectrl.c resolutionSet.c \ resolutionX11.c resolutionRandR12.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu services/plugins/resolutionSet/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu services/plugins/resolutionSet/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ } uninstall-pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ done clean-pluginLTLIBRARIES: -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) @list='$(plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libresolutionSet.la: $(libresolutionSet_la_OBJECTS) $(libresolutionSet_la_DEPENDENCIES) $(EXTRA_libresolutionSet_la_DEPENDENCIES) $(libresolutionSet_la_LINK) -rpath $(plugindir) $(libresolutionSet_la_OBJECTS) $(libresolutionSet_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libresolutionSet_la-libvmwarectrl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libresolutionSet_la-resolutionRandR12.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libresolutionSet_la-resolutionSet.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libresolutionSet_la-resolutionX11.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libresolutionSet_la-libvmwarectrl.lo: libvmwarectrl.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libresolutionSet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libresolutionSet_la-libvmwarectrl.lo -MD -MP -MF $(DEPDIR)/libresolutionSet_la-libvmwarectrl.Tpo -c -o libresolutionSet_la-libvmwarectrl.lo `test -f 'libvmwarectrl.c' || echo '$(srcdir)/'`libvmwarectrl.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libresolutionSet_la-libvmwarectrl.Tpo $(DEPDIR)/libresolutionSet_la-libvmwarectrl.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libvmwarectrl.c' object='libresolutionSet_la-libvmwarectrl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libresolutionSet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libresolutionSet_la-libvmwarectrl.lo `test -f 'libvmwarectrl.c' || echo '$(srcdir)/'`libvmwarectrl.c libresolutionSet_la-resolutionSet.lo: resolutionSet.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libresolutionSet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libresolutionSet_la-resolutionSet.lo -MD -MP -MF $(DEPDIR)/libresolutionSet_la-resolutionSet.Tpo -c -o libresolutionSet_la-resolutionSet.lo `test -f 'resolutionSet.c' || echo '$(srcdir)/'`resolutionSet.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libresolutionSet_la-resolutionSet.Tpo $(DEPDIR)/libresolutionSet_la-resolutionSet.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='resolutionSet.c' object='libresolutionSet_la-resolutionSet.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libresolutionSet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libresolutionSet_la-resolutionSet.lo `test -f 'resolutionSet.c' || echo '$(srcdir)/'`resolutionSet.c libresolutionSet_la-resolutionX11.lo: resolutionX11.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libresolutionSet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libresolutionSet_la-resolutionX11.lo -MD -MP -MF $(DEPDIR)/libresolutionSet_la-resolutionX11.Tpo -c -o libresolutionSet_la-resolutionX11.lo `test -f 'resolutionX11.c' || echo '$(srcdir)/'`resolutionX11.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libresolutionSet_la-resolutionX11.Tpo $(DEPDIR)/libresolutionSet_la-resolutionX11.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='resolutionX11.c' object='libresolutionSet_la-resolutionX11.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libresolutionSet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libresolutionSet_la-resolutionX11.lo `test -f 'resolutionX11.c' || echo '$(srcdir)/'`resolutionX11.c libresolutionSet_la-resolutionRandR12.lo: resolutionRandR12.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libresolutionSet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libresolutionSet_la-resolutionRandR12.lo -MD -MP -MF $(DEPDIR)/libresolutionSet_la-resolutionRandR12.Tpo -c -o libresolutionSet_la-resolutionRandR12.lo `test -f 'resolutionRandR12.c' || echo '$(srcdir)/'`resolutionRandR12.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libresolutionSet_la-resolutionRandR12.Tpo $(DEPDIR)/libresolutionSet_la-resolutionRandR12.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='resolutionRandR12.c' object='libresolutionSet_la-resolutionRandR12.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libresolutionSet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libresolutionSet_la-resolutionRandR12.lo `test -f 'resolutionRandR12.c' || echo '$(srcdir)/'`resolutionRandR12.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(plugindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pluginLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pluginLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-pluginLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-pluginLTLIBRARIES install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-pluginLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/services/plugins/hgfsServer/0000755765153500003110000000000012220061625021056 5ustar dtormtsopen-vm-tools-9.4.0-1280544/services/plugins/hgfsServer/hgfsPlugin.c0000644765153500003110000001260312220061556023335 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file hgfsPlugin.c * * Functionality to utilize the hgfs server in bora/lib as a tools plugin. */ #include #define G_LOG_DOMAIN "hgfsd" #include "hgfs.h" #include "hgfsServerManager.h" #include "vm_assert.h" #include "vmware/guestrpc/tclodefs.h" #include "vmware/tools/log.h" #include "vmware/tools/plugin.h" #include "vmware/tools/utils.h" #if !defined(__APPLE__) #include "embed_version.h" #include "vmtoolsd_version.h" VM_EMBED_VERSION(VMTOOLSD_VERSION_STRING); #endif /** * Clean up internal state on shutdown. * * @param[in] src The source object. * @param[in] ctx Unused. * @param[in] plugin Plugin registration data. */ static void HgfsServerShutdown(gpointer src, ToolsAppCtx *ctx, ToolsPluginData *plugin) { HgfsServerMgrData *mgrData = plugin->_private; HgfsServerManager_Unregister(mgrData); g_free(mgrData); } /** * Handles hgfs requests. * * @param[in] data RPC request data. * * @return TRUE on success, FALSE on error. */ static gboolean HgfsServerRpcDispatch(RpcInData *data) { HgfsServerMgrData *mgrData; size_t replySize; static char reply[HGFS_LARGE_PACKET_MAX]; ASSERT(data->clientData != NULL); mgrData = data->clientData; if (data->argsSize == 0) { return RPCIN_SETRETVALS(data, "1 argument required", FALSE); } replySize = sizeof reply; HgfsServerManager_ProcessPacket(mgrData, data->args + 1, data->argsSize - 1, reply, &replySize); data->result = reply; data->resultLen = replySize; return TRUE; } /** * Sends the HGFS capability to the VMX. * * @param[in] src The source object. * @param[in] ctx The app context. * @param[in] set Whether setting or unsetting the capability. * @param[in] data Unused. * * @return NULL. The function sends the capability directly. */ static GArray * HgfsServerCapReg(gpointer src, ToolsAppCtx *ctx, gboolean set, ToolsPluginData *plugin) { gchar *msg; const char *appName = NULL; if (strcmp(ctx->name, VMTOOLS_GUEST_SERVICE) == 0) { appName = TOOLS_DAEMON_NAME; } else if (strcmp(ctx->name, VMTOOLS_USER_SERVICE) == 0) { appName = TOOLS_DND_NAME; } else { NOT_REACHED(); } msg = g_strdup_printf("tools.capability.hgfs_server %s %d", appName, set ? 1 : 0); /* * Prior to WS55, the VMX did not know about the "hgfs_server" * capability. This doesn't mean that the HGFS server wasn't needed, it's * just that the capability was introduced in CS 225439 so that the VMX * could decide which HGFS server to communicate with. * * Long story short, we shouldn't care if this function fails. */ if (ctx->rpc && !RpcChannel_Send(ctx->rpc, msg, strlen(msg) + 1, NULL, NULL)) { g_warning("Setting HGFS server capability failed!\n"); } g_free(msg); return NULL; } /** * Returns the registration data for the HGFS server. * * @param[in] ctx The application context. * * @return The registration data. */ TOOLS_MODULE_EXPORT ToolsPluginData * ToolsOnLoad(ToolsAppCtx *ctx) { static ToolsPluginData regData = { "hgfsServer", NULL, NULL }; HgfsServerMgrData *mgrData; if (strcmp(ctx->name, VMTOOLS_GUEST_SERVICE) != 0 && strcmp(ctx->name, VMTOOLS_USER_SERVICE) != 0) { g_info("Unknown container '%s', not loading HGFS plugin.", ctx->name); return NULL; } mgrData = g_malloc0(sizeof *mgrData); HgfsServerManager_DataInit(mgrData, ctx->name, NULL, // rpc channel unused NULL); // no rpc callback if (!HgfsServerManager_Register(mgrData)) { g_warning("HgfsServer_InitState() failed, aborting HGFS server init.\n"); g_free(mgrData); return NULL; } { RpcChannelCallback rpcs[] = { { HGFS_SYNC_REQREP_CMD, HgfsServerRpcDispatch, mgrData, NULL, NULL, 0 } }; ToolsPluginSignalCb sigs[] = { { TOOLS_CORE_SIG_CAPABILITIES, HgfsServerCapReg, ®Data }, { TOOLS_CORE_SIG_SHUTDOWN, HgfsServerShutdown, ®Data } }; ToolsAppReg regs[] = { { TOOLS_APP_GUESTRPC, VMTools_WrapArray(rpcs, sizeof *rpcs, ARRAYSIZE(rpcs)) }, { TOOLS_APP_SIGNALS, VMTools_WrapArray(sigs, sizeof *sigs, ARRAYSIZE(sigs)) } }; regData.regs = VMTools_WrapArray(regs, sizeof *regs, ARRAYSIZE(regs)); } regData._private = mgrData; return ®Data; } open-vm-tools-9.4.0-1280544/services/plugins/hgfsServer/COPYING0000644765153500003110000006347112220061556022127 0ustar dtormts GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! open-vm-tools-9.4.0-1280544/services/plugins/hgfsServer/Makefile.am0000644765153500003110000000241112220061556023113 0ustar dtormts################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ plugindir = @COMMON_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libhgfsServer.la libhgfsServer_la_CPPFLAGS = libhgfsServer_la_CPPFLAGS += @PLUGIN_CPPFLAGS@ libhgfsServer_la_LDFLAGS = libhgfsServer_la_LDFLAGS += @PLUGIN_LDFLAGS@ libhgfsServer_la_LIBADD = libhgfsServer_la_LIBADD += @VMTOOLS_LIBS@ libhgfsServer_la_LIBADD += @HGFS_LIBS@ libhgfsServer_la_SOURCES = libhgfsServer_la_SOURCES += hgfsPlugin.c open-vm-tools-9.4.0-1280544/services/plugins/hgfsServer/Makefile.in0000644765153500003110000005354112220061625023133 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = services/plugins/hgfsServer DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(plugin_LTLIBRARIES) libhgfsServer_la_DEPENDENCIES = am_libhgfsServer_la_OBJECTS = libhgfsServer_la-hgfsPlugin.lo libhgfsServer_la_OBJECTS = $(am_libhgfsServer_la_OBJECTS) libhgfsServer_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libhgfsServer_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libhgfsServer_la_SOURCES) DIST_SOURCES = $(libhgfsServer_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ plugindir = @COMMON_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libhgfsServer.la libhgfsServer_la_CPPFLAGS = @PLUGIN_CPPFLAGS@ libhgfsServer_la_LDFLAGS = @PLUGIN_LDFLAGS@ libhgfsServer_la_LIBADD = @VMTOOLS_LIBS@ @HGFS_LIBS@ libhgfsServer_la_SOURCES = hgfsPlugin.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu services/plugins/hgfsServer/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu services/plugins/hgfsServer/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ } uninstall-pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ done clean-pluginLTLIBRARIES: -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) @list='$(plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhgfsServer.la: $(libhgfsServer_la_OBJECTS) $(libhgfsServer_la_DEPENDENCIES) $(EXTRA_libhgfsServer_la_DEPENDENCIES) $(libhgfsServer_la_LINK) -rpath $(plugindir) $(libhgfsServer_la_OBJECTS) $(libhgfsServer_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhgfsServer_la-hgfsPlugin.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libhgfsServer_la-hgfsPlugin.lo: hgfsPlugin.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhgfsServer_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhgfsServer_la-hgfsPlugin.lo -MD -MP -MF $(DEPDIR)/libhgfsServer_la-hgfsPlugin.Tpo -c -o libhgfsServer_la-hgfsPlugin.lo `test -f 'hgfsPlugin.c' || echo '$(srcdir)/'`hgfsPlugin.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libhgfsServer_la-hgfsPlugin.Tpo $(DEPDIR)/libhgfsServer_la-hgfsPlugin.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hgfsPlugin.c' object='libhgfsServer_la-hgfsPlugin.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhgfsServer_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhgfsServer_la-hgfsPlugin.lo `test -f 'hgfsPlugin.c' || echo '$(srcdir)/'`hgfsPlugin.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(plugindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pluginLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pluginLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-pluginLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-pluginLTLIBRARIES install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-pluginLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/services/plugins/Makefile.am0000644765153500003110000000315212220061556021000 0ustar dtormts################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ SUBDIRS = if HAVE_X11 SUBDIRS += desktopEvents endif if HAVE_GTKMM SUBDIRS += dndcp endif SUBDIRS += guestInfo SUBDIRS += hgfsServer SUBDIRS += powerOps if HAVE_X11 SUBDIRS += resolutionSet endif SUBDIRS += timeSync SUBDIRS += vix SUBDIRS += vmbackup # # plugin_LTLIBRARIES causes both .la and .so files to be installed to the # plugin directories. Clean up the .la files and keep just the shared # libraries around. Sometimes, even though we're passing "-shared" to # libtool, .a files are also generated, so clean up those too. # install-exec-local: rm -f $(DESTDIR)$(VMSVC_PLUGIN_INSTALLDIR)/*.a rm -f $(DESTDIR)$(VMSVC_PLUGIN_INSTALLDIR)/*.la rm -f $(DESTDIR)$(VMUSR_PLUGIN_INSTALLDIR)/*.a rm -f $(DESTDIR)$(VMUSR_PLUGIN_INSTALLDIR)/*.la open-vm-tools-9.4.0-1280544/services/plugins/guestInfo/0000755765153500003110000000000012220061624020702 5ustar dtormtsopen-vm-tools-9.4.0-1280544/services/plugins/guestInfo/guestInfoServer.c0000644765153500003110000011720612220061556024213 0ustar dtormts/********************************************************* * Copyright (C) 1998-2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * guestInfoServer.c -- * * This is the implementation of the common code in the guest tools * to send out guest information to the host. The guest info server * runs in the context of the tools daemon's event loop and periodically * gathers all guest information and sends updates to the host if required. * This file implements the platform independent framework for this. */ #include #include #include #include #include #ifndef WIN32 # include #endif #include "vmware.h" #include "buildNumber.h" #include "conf.h" #include "debug.h" #include "dynxdr.h" #include "hostinfo.h" #include "guestInfoInt.h" #include "guest_msg_def.h" // For GUESTMSG_MAX_IN_SIZE #include "netutil.h" #include "rpcvmx.h" #include "procMgr.h" #include "str.h" #include "strutil.h" #include "system.h" #include "util.h" #include "xdrutil.h" #include "vmsupport.h" #include "vmware/guestrpc/tclodefs.h" #include "vmware/tools/log.h" #include "vmware/tools/plugin.h" #include "vmware/tools/utils.h" #include "vmware/tools/vmbackup.h" #if !defined(__APPLE__) #include "embed_version.h" #include "vmtoolsd_version.h" VM_EMBED_VERSION(VMTOOLSD_VERSION_STRING); #endif /** * Default poll interval is 30s (in milliseconds). */ #define GUESTINFO_TIME_INTERVAL_MSEC 30000 #define GUESTINFO_DEFAULT_DELIMITER ' ' /* * Stores information about all guest information sent to the vmx. */ typedef struct _GuestInfoCache { /* Stores values of all key-value pairs. */ char *value[INFO_MAX]; NicInfoV3 *nicInfo; GuestDiskInfo *diskInfo; } GuestInfoCache; /** * Defines the current poll interval (in milliseconds). * * This value is controlled by the guestinfo.poll-interval config file option. */ int guestInfoPollInterval = 0; /** * Gather loop timeout source. */ static GSource *gatherTimeoutSource = NULL; /* Local cache of the guest information that was last sent to vmx. */ static GuestInfoCache gInfoCache; /* * A boolean flag that specifies whether the state of the VM was * changed since the last time guest info was sent to the VMX. * Tools daemon sets it to TRUE after the VM was resumed. */ static Bool vmResumed; /* * Local functions */ static Bool GuestInfoUpdateVmdb(ToolsAppCtx *ctx, GuestInfoType infoType, void *info); static Bool SetGuestInfo(ToolsAppCtx *ctx, GuestInfoType key, const char *value); static void SendUptime(ToolsAppCtx *ctx); static Bool DiskInfoChanged(const GuestDiskInfo *diskInfo); static void GuestInfoClearCache(void); static GuestNicList *NicInfoV3ToV2(const NicInfoV3 *infoV3); static void TweakGatherLoop(ToolsAppCtx *ctx, gboolean enable); /* ****************************************************************************** * GuestInfoVMSupport -- */ /** * * Launches the vm-support process. Data returned asynchronously via RPCI. * * @param[in] data RPC request data. * * @return TRUE if able to launch script, FALSE if script failed. * ****************************************************************************** */ static gboolean GuestInfoVMSupport(RpcInData *data) { #if defined(_WIN32) char vmSupportCmd[] = "vm-support.vbs"; char *vmSupportPath = NULL; gchar *vmSupport = NULL; SECURITY_ATTRIBUTES saProcess = {0}, saThread = {0}; ProcMgr_AsyncProc *vmSupportProc = NULL; ProcMgr_ProcArgs vmSupportProcArgs = {0}; /* * Construct the commandline to be passed during execution * This will be the path of our vm-support.vbs */ vmSupportPath = GuestApp_GetInstallPath(); if (vmSupportPath == NULL) { return RPCIN_SETRETVALS(data, "GuestApp_GetInstallPath failed", FALSE); } /* Put together absolute vm-support filename. */ vmSupport = g_strdup_printf("cscript \"%s%s%s\" -u", vmSupportPath, DIRSEPS, vmSupportCmd); vm_free(vmSupportPath); saProcess.nLength = sizeof saProcess; saProcess.bInheritHandle = TRUE; saThread.nLength = sizeof saThread; vmSupportProcArgs.lpProcessAttributes = &saProcess; vmSupportProcArgs.lpThreadAttributes = &saThread; vmSupportProcArgs.dwCreationFlags = CREATE_NO_WINDOW; g_debug("Starting vm-support script - %s\n", vmSupport); vmSupportProc = ProcMgr_ExecAsync(vmSupport, &vmSupportProcArgs); g_free(vmSupport); if (vmSupportProc == NULL) { g_warning("Error starting vm-support script\n"); return RPCIN_SETRETVALS(data, "Error starting vm-support script", FALSE); } ProcMgr_Free(vmSupportProc); return RPCIN_SETRETVALS(data, "", TRUE); #else gchar *vmSupportCmdArgv[] = {"vm-support", "-u", NULL}; g_debug("Starting vm-support script - %s\n", vmSupportCmdArgv[0]); if (!g_spawn_async(NULL, vmSupportCmdArgv, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, NULL, NULL, NULL, NULL)) { g_warning("Error starting vm-support script\n"); return RPCIN_SETRETVALS(data, "Error starting vm-support script", FALSE); } return RPCIN_SETRETVALS(data, "", TRUE); #endif } /* ****************************************************************************** * GuestInfoGather -- */ /** * * Collects all the desired guest information and updates the VMX. * * @param[in] data The application context. * * @return TRUE to indicate that the timer should be rescheduled. * ****************************************************************************** */ static gboolean GuestInfoGather(gpointer data) { char name[256]; // Size is derived from the SUS2 specification // "Host names are limited to 255 bytes" char *osString = NULL; gboolean disableQueryDiskInfo; NicInfoV3 *nicInfo = NULL; GuestDiskInfo *diskInfo = NULL; #if defined(_WIN32) || defined(linux) GuestMemInfo vmStats = {0}; gboolean perfmonEnabled; #endif ToolsAppCtx *ctx = data; g_debug("Entered guest info gather.\n"); /* Send tools version. */ if (!GuestInfoUpdateVmdb(ctx, INFO_BUILD_NUMBER, BUILD_NUMBER)) { /* * An older vmx talking to new tools wont be able to handle * this message. Continue, if thats the case. */ g_warning("Failed to update VMDB with tools version.\n"); } /* Gather all the relevant guest information. */ osString = Hostinfo_GetOSName(); if (osString == NULL) { g_warning("Failed to get OS info.\n"); } else { if (!GuestInfoUpdateVmdb(ctx, INFO_OS_NAME_FULL, osString)) { g_warning("Failed to update VMDB\n"); } } free(osString); osString = Hostinfo_GetOSGuestString(); if (osString == NULL) { g_warning("Failed to get OS info.\n"); } else { if (!GuestInfoUpdateVmdb(ctx, INFO_OS_NAME, osString)) { g_warning("Failed to update VMDB\n"); } } free(osString); disableQueryDiskInfo = g_key_file_get_boolean(ctx->config, CONFGROUPNAME_GUESTINFO, CONFNAME_GUESTINFO_DISABLEQUERYDISKINFO, NULL); if (!disableQueryDiskInfo) { if ((diskInfo = GuestInfo_GetDiskInfo()) == NULL) { g_warning("Failed to get disk info.\n"); } else { if (GuestInfoUpdateVmdb(ctx, INFO_DISK_FREE_SPACE, diskInfo)) { GuestInfo_FreeDiskInfo(gInfoCache.diskInfo); gInfoCache.diskInfo = diskInfo; } else { g_warning("Failed to update VMDB\n."); GuestInfo_FreeDiskInfo(diskInfo); } } } if (!System_GetNodeName(sizeof name, name)) { g_warning("Failed to get netbios name.\n"); } else if (!GuestInfoUpdateVmdb(ctx, INFO_DNS_NAME, name)) { g_warning("Failed to update VMDB.\n"); } /* Get NIC information. */ if (!GuestInfo_GetNicInfo(&nicInfo)) { g_warning("Failed to get nic info.\n"); /* * Return an empty nic info. */ nicInfo = Util_SafeCalloc(1, sizeof (struct NicInfoV3)); } if (GuestInfo_IsEqual_NicInfoV3(nicInfo, gInfoCache.nicInfo)) { g_debug("Nic info not changed.\n"); GuestInfo_FreeNicInfo(nicInfo); } else if (GuestInfoUpdateVmdb(ctx, INFO_IPADDRESS, nicInfo)) { /* * Since the update succeeded, free the old cached object, and assign * ours to the cache. */ GuestInfo_FreeNicInfo(gInfoCache.nicInfo); gInfoCache.nicInfo = nicInfo; } else { g_warning("Failed to update VMDB.\n"); GuestInfo_FreeNicInfo(nicInfo); } /* Send the uptime to VMX so that it can detect soft resets. */ SendUptime(ctx); #if defined(_WIN32) || defined(linux) /* Send the vmstats to the VMX. */ perfmonEnabled = !g_key_file_get_boolean(ctx->config, CONFGROUPNAME_GUESTINFO, CONFNAME_GUESTINFO_DISABLEPERFMON, NULL); if (perfmonEnabled) { if (!GuestInfo_PerfMon(&vmStats)) { g_warning("Failed to get vmstats.\n"); } else { vmStats.version = 1; if (!GuestInfoUpdateVmdb(ctx, INFO_MEMORY, &vmStats)) { g_warning("Failed to send vmstats.\n"); } } } #endif return TRUE; } /* ****************************************************************************** * GuestInfoConvertNicInfoToNicInfoV1 -- */ /** * * Converts V3 XDR NicInfo to hand-packed GuestNicInfoV1. * * @note Any NICs above MAX_NICS or IPs above MAX_IPS will be truncated. * * @param[in] info V3 input data. * @param[out] infoV1 V1 output data. * * @retval TRUE Conversion succeeded. * @retval FALSE Conversion failed. * ****************************************************************************** */ void GuestInfoConvertNicInfoToNicInfoV1(NicInfoV3 *info, GuestNicInfoV1 *infoV1) { uint32 maxNics; u_int i; ASSERT(info); ASSERT(infoV1); maxNics = MIN(info->nics.nics_len, MAX_NICS); infoV1->numNicEntries = maxNics; if (maxNics < info->nics.nics_len) { g_debug("Truncating NIC list for backwards compatibility.\n"); } XDRUTIL_FOREACH(i, info, nics) { u_int j; uint32 maxIPs; GuestNicV3 *nic = XDRUTIL_GETITEM(info, nics, i); Str_Strcpy(infoV1->nicList[i].macAddress, nic->macAddress, sizeof infoV1->nicList[i].macAddress); maxIPs = MIN(nic->ips.ips_len, MAX_IPS); infoV1->nicList[i].numIPs = 0; XDRUTIL_FOREACH(j, nic, ips) { IpAddressEntry *ip = XDRUTIL_GETITEM(nic, ips, j); TypedIpAddress *typedIp = &ip->ipAddressAddr; if (typedIp->ipAddressAddrType != IAT_IPV4) { continue; } if (NetUtil_InetNToP(AF_INET, typedIp->ipAddressAddr.InetAddress_val, infoV1->nicList[i].ipAddress[j], sizeof infoV1->nicList[i].ipAddress[j])) { infoV1->nicList[i].numIPs++; if (infoV1->nicList[i].numIPs == maxIPs) { break; } } } if (infoV1->nicList[i].numIPs != nic->ips.ips_len) { g_debug("Some IP addresses were ignored for compatibility.\n"); } if (i == maxNics) { break; } } } /* ****************************************************************************** * GuestInfoUpdateVmdb -- */ /** * * Push singular GuestInfo snippets to the VMX. * * @note Data are cached, so updates are sent only if they have changed. * * @param[in] ctx Application context. * @param[in] infoType Guest information type. * @param[in] info Type-specific information. * * @retval TRUE Update sent successfully. * @retval FALSE Had trouble with serialization or transmission. * ****************************************************************************** */ Bool GuestInfoUpdateVmdb(ToolsAppCtx *ctx, // IN: Application context GuestInfoType infoType, // IN: guest information type void *info) // IN: type specific information { ASSERT(info); g_debug("Entered update vmdb: %d.\n", infoType); if (vmResumed) { vmResumed = FALSE; GuestInfoClearCache(); } switch (infoType) { case INFO_DNS_NAME: case INFO_BUILD_NUMBER: case INFO_OS_NAME: case INFO_OS_NAME_FULL: case INFO_UPTIME: /* * This is one of our key value pairs. Update it if it has changed. * Above fall-through is intentional. */ if (gInfoCache.value[infoType] != NULL && strcmp(gInfoCache.value[infoType], (char *)info) == 0) { /* The value has not changed */ g_debug("Value unchanged for infotype %d.\n", infoType); break; } if (!SetGuestInfo(ctx, infoType, (char *)info)) { g_warning("Failed to update key/value pair for type %d.\n", infoType); return FALSE; } /* Update the value in the cache as well. */ free(gInfoCache.value[infoType]); gInfoCache.value[infoType] = Util_SafeStrdup((char *) info); break; case INFO_IPADDRESS: { static NicInfoVersion supportedVersion = NIC_INFO_V3; NicInfoV3 *nicInfoV3 = (NicInfoV3 *)info; char *reply = NULL; size_t replyLen; Bool status; nicinfo_fsm: switch (supportedVersion) { case NIC_INFO_V3: case NIC_INFO_V2: { /* * 13 = max size of string representation of an int + 3 spaces. * XXX Ditch the magic numbers. */ char request[sizeof GUEST_INFO_COMMAND + 13]; GuestNicProto message = {0}; GuestNicList *nicList = NULL; NicInfoVersion fallbackVersion; XDR xdrs; if (DynXdr_Create(&xdrs) == NULL) { return FALSE; } /* Add the RPC preamble: message name, and type. */ Str_Sprintf(request, sizeof request, "%s %d ", GUEST_INFO_COMMAND, INFO_IPADDRESS_V2); /* * Fill in message according to the version we'll attempt. Also * note which version we'll fall back to should the VMX reject * our update. */ if (supportedVersion == NIC_INFO_V3) { message.ver = NIC_INFO_V3; message.GuestNicProto_u.nicInfoV3 = nicInfoV3; fallbackVersion = NIC_INFO_V2; } else { nicList = NicInfoV3ToV2(nicInfoV3); message.ver = NIC_INFO_V2; message.GuestNicProto_u.nicsV2 = nicList; fallbackVersion = NIC_INFO_V1; } /* Write preamble and serialized nic info to XDR stream. */ if (!DynXdr_AppendRaw(&xdrs, request, strlen(request)) || !xdr_GuestNicProto(&xdrs, &message)) { g_warning("Error serializing nic info v%d data.", message.ver); DynXdr_Destroy(&xdrs, TRUE); return FALSE; } status = RpcChannel_Send(ctx->rpc, DynXdr_Get(&xdrs), xdr_getpos(&xdrs), &reply, &replyLen); DynXdr_Destroy(&xdrs, TRUE); /* * Do not free/destroy contents of `message`. The v3 nicInfo * passed to us belongs to our caller. Instead, we'll only * destroy our local V2 converted data. */ if (nicList) { VMX_XDR_FREE(xdr_GuestNicList, nicList); free(nicList); nicList = NULL; } if (!status) { g_warning("NicInfo update failed: version %u, reply \"%s\".\n", supportedVersion, reply); supportedVersion = fallbackVersion; vm_free(reply); reply = NULL; goto nicinfo_fsm; } } break; case NIC_INFO_V1: { /* * Could be that we are talking to the old protocol that * GuestNicInfo is still fixed size. Another try to send the * fixed sized Nic info. */ char request[sizeof (GuestNicInfoV1) + sizeof GUEST_INFO_COMMAND + 2 + /* 2 bytes are for digits of infotype. */ 3 * sizeof (char)]; /* 3 spaces */ GuestNicInfoV1 nicInfo; Str_Sprintf(request, sizeof request, "%s %d ", GUEST_INFO_COMMAND, INFO_IPADDRESS); GuestInfoConvertNicInfoToNicInfoV1(nicInfoV3, &nicInfo); memcpy(request + strlen(request), &nicInfo, sizeof(GuestNicInfoV1)); g_debug("Sending nic info message.\n"); /* Send all the information in the message. */ status = RpcChannel_Send(ctx->rpc, request, sizeof request, &reply, &replyLen); g_debug("Just sent fixed sized nic info message.\n"); if (!status) { g_debug("Failed to update fixed sized nic information\n"); vm_free(reply); return FALSE; } } break; default: NOT_REACHED(); } g_debug("Updated new NIC information\n"); vm_free(reply); reply = NULL; } break; case INFO_MEMORY: { char request[sizeof(GuestMemInfo) + sizeof GUEST_INFO_COMMAND + 2 + /* 2 bytes are for digits of infotype. */ 3 * sizeof (char)]; /* 3 spaces */ Bool status; g_debug("Sending GuestMemInfo message.\n"); Str_Sprintf(request, sizeof request, "%s %d ", GUEST_INFO_COMMAND, INFO_MEMORY); memcpy(request + strlen(request), info, sizeof(GuestMemInfo)); /* Send all the information in the message. */ status = RpcChannel_Send(ctx->rpc, request, sizeof(request), NULL, NULL); if (!status) { g_warning("Error sending GuestMemInfo.\n"); return FALSE; } g_debug("GuestMemInfo sent successfully.\n"); break; } case INFO_DISK_FREE_SPACE: { /* * 2 accounts for the digits of infotype and 3 for the three * spaces. */ unsigned int requestSize = sizeof GUEST_INFO_COMMAND + 2 + 3 * sizeof (char); uint8 partitionCount; size_t offset; char *request; char *reply; size_t replyLen; Bool status; GuestDiskInfo *pdi = info; if (!DiskInfoChanged(pdi)) { g_debug("Disk info not changed.\n"); break; } ASSERT((pdi->numEntries && pdi->partitionList) || (!pdi->numEntries && !pdi->partitionList)); requestSize += sizeof pdi->numEntries + sizeof *pdi->partitionList * pdi->numEntries; request = Util_SafeCalloc(requestSize, sizeof *request); Str_Sprintf(request, requestSize, "%s %d ", GUEST_INFO_COMMAND, INFO_DISK_FREE_SPACE); /* partitionCount is a uint8 and cannot be larger than UCHAR_MAX. */ if (pdi->numEntries > UCHAR_MAX) { g_warning("Too many partitions.\n"); vm_free(request); return FALSE; } partitionCount = pdi->numEntries; offset = strlen(request); /* * Construct the disk information message to send to the host. This * contains a single byte indicating the number partitions followed by * the PartitionEntry structure for each one. * * Note that the use of a uint8 to specify the partitionCount is the * result of a bug (see bug 117224) but should not cause a problem * since UCHAR_MAX is 255. Also note that PartitionEntry is packed so * it's safe to send it from 64-bit Tools to a 32-bit VMX, etc. */ memcpy(request + offset, &partitionCount, sizeof partitionCount); /* * Conditioned because memcpy(dst, NULL, 0) -may- lead to undefined * behavior. */ if (pdi->partitionList) { memcpy(request + offset + sizeof partitionCount, pdi->partitionList, sizeof *pdi->partitionList * pdi->numEntries); } g_debug("sizeof request is %d\n", requestSize); status = RpcChannel_Send(ctx->rpc, request, requestSize, &reply, &replyLen); if (status) { status = (*reply == '\0'); } vm_free(request); vm_free(reply); if (!status) { g_warning("Failed to update disk information.\n"); return FALSE; } g_debug("Updated disk info information\n"); break; } default: g_error("Invalid info type: %d\n", infoType); break; } g_debug("Returning after updating guest information\n"); return TRUE; } /* ****************************************************************************** * SendUptime -- */ /** * * Send the guest uptime through the backdoor. * * @param[in] ctx The application context. * ****************************************************************************** */ static void SendUptime(ToolsAppCtx *ctx) { gchar *uptime = g_strdup_printf("%"FMT64"u", System_Uptime()); g_debug("Setting guest uptime to '%s'\n", uptime); GuestInfoUpdateVmdb(ctx, INFO_UPTIME, uptime); g_free(uptime); } /* ****************************************************************************** * SetGuestInfo -- */ /** * * Sends a simple key-value update request to the VMX. * * @param[in] ctx Application context. * @param[in] key VMDB key to set * @param[in] value GuestInfo data * * @retval TRUE RPCI succeeded. * @retval FALSE RPCI failed. * ****************************************************************************** */ Bool SetGuestInfo(ToolsAppCtx *ctx, GuestInfoType key, const char *value) { Bool status; char *reply; gchar *msg; size_t replyLen; ASSERT(key); ASSERT(value); /* * XXX Consider retiring this runtime "delimiter" business and just * insert raw spaces into the format string. */ msg = g_strdup_printf("%s %c%d%c%s", GUEST_INFO_COMMAND, GUESTINFO_DEFAULT_DELIMITER, key, GUESTINFO_DEFAULT_DELIMITER, value); status = RpcChannel_Send(ctx->rpc, msg, strlen(msg) + 1, &reply, &replyLen); g_free(msg); if (!status) { g_warning("Error sending rpc message: %s\n", reply ? reply : "NULL"); vm_free(reply); return FALSE; } /* The reply indicates whether the key,value pair was updated in VMDB. */ status = (*reply == '\0'); vm_free(reply); return status; } /* ****************************************************************************** * GuestInfoFindMacAddress -- */ /** * * Locates a NIC with the given MAC address in the NIC list. * * @param[in] nicInfo NicInfoV3 container. * @param[in] macAddress Requested MAC address. * * @return Valid pointer if NIC found, else NULL. * ****************************************************************************** */ GuestNicV3 * GuestInfoFindMacAddress(NicInfoV3 *nicInfo, // IN/OUT const char *macAddress) // IN { u_int i; for (i = 0; i < nicInfo->nics.nics_len; i++) { GuestNicV3 *nic = &nicInfo->nics.nics_val[i]; if (strncmp(nic->macAddress, macAddress, NICINFO_MAC_LEN) == 0) { return nic; } } return NULL; } /* ****************************************************************************** * DiskInfoChanged -- */ /** * * Checks whether disk info information just obtained is different from the * information last sent to the VMX. * * @param[in] diskInfo New disk info. * * @retval TRUE Data has changed. * @retval FALSE Data has not changed. * ****************************************************************************** */ static Bool DiskInfoChanged(const GuestDiskInfo *diskInfo) { int index; char *name; int i; int matchedPartition; PGuestDiskInfo cachedDiskInfo; cachedDiskInfo = gInfoCache.diskInfo; if (cachedDiskInfo == diskInfo) { return FALSE; /* Implies that either cachedDiskInfo or diskInfo != NULL. */ } else if (!cachedDiskInfo || !diskInfo) { return TRUE; } if (cachedDiskInfo->numEntries != diskInfo->numEntries) { g_debug("Number of disks has changed\n"); return TRUE; } /* Have any disks been modified? */ for (index = 0; index < cachedDiskInfo->numEntries; index++) { name = cachedDiskInfo->partitionList[index].name; /* Find the corresponding partition in the new partition info. */ for (i = 0; i < diskInfo->numEntries; i++) { if (!strncmp(diskInfo->partitionList[i].name, name, PARTITION_NAME_SIZE)) { break; } } matchedPartition = i; if (matchedPartition == diskInfo->numEntries) { /* This partition has been deleted. */ g_debug("Partition %s deleted\n", name); return TRUE; } else { /* Compare the free space. */ if (diskInfo->partitionList[matchedPartition].freeBytes != cachedDiskInfo->partitionList[index].freeBytes) { g_debug("Free space changed\n"); return TRUE; } if (diskInfo->partitionList[matchedPartition].totalBytes != cachedDiskInfo->partitionList[index].totalBytes) { g_debug("Total space changed\n"); return TRUE; } } } return FALSE; } /* ****************************************************************************** * GuestInfoClearCache -- */ /** * * Clears the cached guest info data. * ****************************************************************************** */ static void GuestInfoClearCache(void) { int i; for (i = 0; i < INFO_MAX; i++) { free(gInfoCache.value[i]); gInfoCache.value[i] = NULL; } GuestInfo_FreeDiskInfo(gInfoCache.diskInfo); gInfoCache.diskInfo = NULL; GuestInfo_FreeNicInfo(gInfoCache.nicInfo); gInfoCache.nicInfo = NULL; } /* *********************************************************************** * NicInfoV3ToV2 -- */ /** * * @brief Converts the NicInfoV3 NIC list to a GuestNicList. * * @note This function performs @e shallow copies of things such as * IP address array, making it depend on the source NicInfoV3. * In other words, do @e not free NicInfoV3 before freeing the * returned pointer. * * @param[in] infoV3 Source NicInfoV3 container. * * @return Pointer to a GuestNicList. Caller should free it using * plain ol' @c free. * *********************************************************************** */ static GuestNicList * NicInfoV3ToV2(const NicInfoV3 *infoV3) { GuestNicList *nicList; unsigned int i, j; nicList = Util_SafeCalloc(sizeof *nicList, 1); (void)XDRUTIL_ARRAYAPPEND(nicList, nics, infoV3->nics.nics_len); XDRUTIL_FOREACH(i, infoV3, nics) { GuestNicV3 *nic = XDRUTIL_GETITEM(infoV3, nics, i); GuestNic *oldNic = XDRUTIL_GETITEM(nicList, nics, i); Str_Strcpy(oldNic->macAddress, nic->macAddress, sizeof oldNic->macAddress); (void)XDRUTIL_ARRAYAPPEND(oldNic, ips, nic->ips.ips_len); XDRUTIL_FOREACH(j, nic, ips) { IpAddressEntry *ipEntry = XDRUTIL_GETITEM(nic, ips, j); TypedIpAddress *ip = &ipEntry->ipAddressAddr; VmIpAddress *oldIp = XDRUTIL_GETITEM(oldNic, ips, j); /* XXX */ oldIp->addressFamily = (ip->ipAddressAddrType == IAT_IPV4) ? NICINFO_ADDR_IPV4 : NICINFO_ADDR_IPV6; NetUtil_InetNToP(ip->ipAddressAddrType == IAT_IPV4 ? AF_INET : AF_INET6, ip->ipAddressAddr.InetAddress_val, oldIp->ipAddress, sizeof oldIp->ipAddress); Str_Sprintf(oldIp->subnetMask, sizeof oldIp->subnetMask, "%u", ipEntry->ipAddressPrefixLength); } } return nicList; } /* ****************************************************************************** * TweakGatherLoop -- */ /** * * @brief Start, stop, reconfigure the GuestInfoGather poll loop. * * This function is responsible for creating, manipulating, and resetting the * GuestInfoGather loop timeout source. * * @param[in] ctx The app context. * @param[in] enable Whether to enable the gather loop. * * @sa CONFNAME_GUESTINFO_POLLINTERVAL * ****************************************************************************** */ static void TweakGatherLoop(ToolsAppCtx *ctx, gboolean enable) { GError *gError = NULL; gint pollInterval = 0; if (enable) { pollInterval = GUESTINFO_TIME_INTERVAL_MSEC; /* * Check the config registry for a custom poll interval, converting from * seconds to milliseconds. */ if (g_key_file_has_key(ctx->config, CONFGROUPNAME_GUESTINFO, CONFNAME_GUESTINFO_POLLINTERVAL, NULL)) { pollInterval = g_key_file_get_integer(ctx->config, CONFGROUPNAME_GUESTINFO, CONFNAME_GUESTINFO_POLLINTERVAL, &gError); pollInterval *= 1000; if (pollInterval < 0 || gError) { g_warning("Invalid %s.%s value. Using default.\n", CONFGROUPNAME_GUESTINFO, CONFNAME_GUESTINFO_POLLINTERVAL); pollInterval = GUESTINFO_TIME_INTERVAL_MSEC; } } } /* * If the interval hasn't changed, let's not interfere with the existing * timeout source. */ if (guestInfoPollInterval == pollInterval) { ASSERT(pollInterval || gatherTimeoutSource == NULL); return; } /* * All checks have passed. Destroy the existing timeout source, if it * exists, then create and attach a new one. */ if (gatherTimeoutSource != NULL) { g_source_destroy(gatherTimeoutSource); gatherTimeoutSource = NULL; } guestInfoPollInterval = pollInterval; if (guestInfoPollInterval) { g_info("New poll interval is %us.\n", guestInfoPollInterval / 1000); gatherTimeoutSource = g_timeout_source_new(guestInfoPollInterval); VMTOOLSAPP_ATTACH_SOURCE(ctx, gatherTimeoutSource, GuestInfoGather, ctx, NULL); g_source_unref(gatherTimeoutSource); } else { g_info("Poll loop disabled.\n"); } g_clear_error(&gError); } /* ****************************************************************************** * BEGIN Tools Core Services goodies. */ /* ****************************************************************************** * GuestInfoServerConfReload -- */ /** * * @brief Reconfigures the poll loop interval upon config file reload. * * @param[in] src The source object. * @param[in] ctx The application context. * @param[in] data Unused. * ****************************************************************************** */ static void GuestInfoServerConfReload(gpointer src, ToolsAppCtx *ctx, gpointer data) { TweakGatherLoop(ctx, TRUE); } /* ****************************************************************************** * GuestInfoServerIOFreeze -- */ /** * * IO freeze signal handler. Disables info gathering while I/O is frozen. * See bug 529653. * * @param[in] src The source object. * @param[in] ctx The application context. * @param[in] freeze Whether I/O is being frozen. * @param[in] data Unused. * ****************************************************************************** */ static void GuestInfoServerIOFreeze(gpointer src, ToolsAppCtx *ctx, gboolean freeze, gpointer data) { TweakGatherLoop(ctx, !freeze); } /* ****************************************************************************** * GuestInfoServerShutdown -- */ /** * * Cleanup internal data on shutdown. * * @param[in] src The source object. * @param[in] ctx Unused. * @param[in] data Unused. * ****************************************************************************** */ static void GuestInfoServerShutdown(gpointer src, ToolsAppCtx *ctx, gpointer data) { GuestInfoClearCache(); if (gatherTimeoutSource != NULL) { g_source_destroy(gatherTimeoutSource); gatherTimeoutSource = NULL; } #ifdef _WIN32 NetUtil_FreeIpHlpApiDll(); #endif } /* ****************************************************************************** * GuestInfoServerReset -- */ /** * * Reset callback - sets the internal flag that says we should purge all * caches. * * @param[in] src The source object. * @param[in] ctx Unused. * @param[in] data Unused. * ****************************************************************************** */ static void GuestInfoServerReset(gpointer src, ToolsAppCtx *ctx, gpointer data) { vmResumed = TRUE; } /* ****************************************************************************** * GuestInfoServerSendCaps -- */ /** * * Send capabilities callback. If setting capabilities, sends VM's uptime. * * This is weird. There's sort of an old Tools <-> VMX understanding that * vmsvc should report the guest's uptime in response to a "what're your * capabilities?" RPC. * * @param[in] src The source object. * @param[in] ctx The application context. * @param[in] set TRUE if setting capabilities, FALSE if unsetting them. * @param[in] data Client data. * * @retval NULL This function returns no capabilities. * ****************************************************************************** */ static GArray * GuestInfoServerSendCaps(gpointer src, ToolsAppCtx *ctx, gboolean set, gpointer data) { if (set) { SendUptime(ctx); } return NULL; } /* ****************************************************************************** * GuestInfoServerSetOption -- */ /** * * Responds to a "broadcastIP" Set_Option command, by sending the primary IP * back to the VMX. * * @param[in] src The source object. * @param[in] ctx The application context. * @param[in] option Option name. * @param[in] value Option value. * @param[in] data Unused. * ****************************************************************************** */ static gboolean GuestInfoServerSetOption(gpointer src, ToolsAppCtx *ctx, const gchar *option, const gchar *value, gpointer data) { char *ip; Bool ret = FALSE; gchar *msg; if (strcmp(option, TOOLSOPTION_BROADCASTIP) != 0) { goto exit; } if (strcmp(value, "0") == 0) { ret = TRUE; goto exit; } if (strcmp(value, "1") != 0) { goto exit; } ip = NetUtil_GetPrimaryIP(); if (ip == NULL) { /* * If there is any error, then return a blank string. */ ip = Util_SafeStrdup(""); } msg = g_strdup_printf("info-set guestinfo.ip %s", ip); ret = RpcChannel_Send(ctx->rpc, msg, strlen(msg) + 1, NULL, NULL); vm_free(ip); g_free(msg); exit: return (gboolean) ret; } /* ****************************************************************************** * ToolsOnLoad -- */ /** * * Plugin entry point. Initializes internal plugin state. * * @param[in] ctx The app context. * * @return The registration data. * ****************************************************************************** */ TOOLS_MODULE_EXPORT ToolsPluginData * ToolsOnLoad(ToolsAppCtx *ctx) { static ToolsPluginData regData = { "guestInfo", NULL, NULL }; /* * This plugin is useless without an RpcChannel. If we don't have one, * just bail. */ if (ctx->rpc != NULL) { RpcChannelCallback rpcs[] = { { RPC_VMSUPPORT_START, GuestInfoVMSupport, ®Data, NULL, NULL, 0 } }; ToolsPluginSignalCb sigs[] = { { TOOLS_CORE_SIG_CAPABILITIES, GuestInfoServerSendCaps, NULL }, { TOOLS_CORE_SIG_CONF_RELOAD, GuestInfoServerConfReload, NULL }, { TOOLS_CORE_SIG_IO_FREEZE, GuestInfoServerIOFreeze, NULL }, { TOOLS_CORE_SIG_RESET, GuestInfoServerReset, NULL }, { TOOLS_CORE_SIG_SET_OPTION, GuestInfoServerSetOption, NULL }, { TOOLS_CORE_SIG_SHUTDOWN, GuestInfoServerShutdown, NULL } }; ToolsAppReg regs[] = { { TOOLS_APP_GUESTRPC, VMTools_WrapArray(rpcs, sizeof *rpcs, ARRAYSIZE(rpcs)) }, { TOOLS_APP_SIGNALS, VMTools_WrapArray(sigs, sizeof *sigs, ARRAYSIZE(sigs)) } }; #ifdef _WIN32 if (NetUtil_LoadIpHlpApiDll() != ERROR_SUCCESS) { g_warning("Failed to load iphlpapi.dll. Cannot report networking details.\n"); return NULL; } #endif regData.regs = VMTools_WrapArray(regs, sizeof *regs, ARRAYSIZE(regs)); memset(&gInfoCache, 0, sizeof gInfoCache); vmResumed = FALSE; /* * Set up the GuestInfoGather loop. */ TweakGatherLoop(ctx, TRUE); return ®Data; } return NULL; } /* * END Tools Core Services goodies. ****************************************************************************** */ open-vm-tools-9.4.0-1280544/services/plugins/guestInfo/guestInfoLib.h0000644765153500003110000000544012220061556023454 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _GUESTINFOLIB_H_ #define _GUESTINFOLIB_H_ /** * @file guestInfoLib.h * * Declarations of functions implemented in the guestInfo library. */ #include "vm_basic_types.h" #include "guestInfo.h" Bool GuestInfo_GetFqdn(int outBufLen, char fqdn[]); Bool GuestInfo_GetNicInfo(NicInfoV3 **nicInfo); void GuestInfo_FreeNicInfo(NicInfoV3 *nicInfo); GuestDiskInfo * GuestInfo_GetDiskInfo(void); void GuestInfo_FreeDiskInfo(GuestDiskInfo *di); Bool GuestInfo_GetOSName(unsigned int outBufFullLen, unsigned int outBufLen, char *osNameFull, char *osName); /* * Comparison routines -- handy for caching, unit testing. */ Bool GuestInfo_IsEqual_DhcpConfigInfo(const DhcpConfigInfo *a, const DhcpConfigInfo *b); Bool GuestInfo_IsEqual_DnsConfigInfo(const DnsConfigInfo *a, const DnsConfigInfo *b); Bool GuestInfo_IsEqual_DnsHostname(const DnsHostname *a, const DnsHostname *b); Bool GuestInfo_IsEqual_InetCidrRouteEntry(const InetCidrRouteEntry *a, const InetCidrRouteEntry *b, const NicInfoV3 *aInfo, const NicInfoV3 *bInfo); Bool GuestInfo_IsEqual_IpAddressEntry(const IpAddressEntry *a, const IpAddressEntry *b); Bool GuestInfo_IsEqual_NicInfoV3(const NicInfoV3 *a, const NicInfoV3 *b); Bool GuestInfo_IsEqual_TypedIpAddress(const TypedIpAddress *a, const TypedIpAddress *b); Bool GuestInfo_IsEqual_WinsConfigInfo(const WinsConfigInfo *a, const WinsConfigInfo *b); /* * Misc utilities. */ GuestNicV3 * GuestInfo_Util_FindNicByMac(const NicInfoV3 *nicInfo, const char *macAddress); #endif /* _GUESTINFOLIB_H_ */ open-vm-tools-9.4.0-1280544/services/plugins/guestInfo/guestInfoInt.h0000644765153500003110000000230212220061556023472 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _GUESTINFOINT_H_ #define _GUESTINFOINT_H_ /** * @file guestInfoInt.h * * Declares internal functions of the guestInfo plugin. */ #define G_LOG_DOMAIN "guestinfo" #include #include "guestInfoLib.h" extern int guestInfoPollInterval; Bool GuestInfo_PerfMon(struct GuestMemInfo *vmStats); #endif /* _GUESTINFOINT_H_ */ open-vm-tools-9.4.0-1280544/services/plugins/guestInfo/getlib/0000755765153500003110000000000012220061624022150 5ustar dtormtsopen-vm-tools-9.4.0-1280544/services/plugins/guestInfo/getlib/util.c0000644765153500003110000000354212220061556023301 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file util.c * * Random GuestInfo type utilities. */ #include #include "vmware.h" #include "guestInfoLib.h" #include "xdrutil.h" /* ****************************************************************************** * GuestInfo_Util_FindNicByMac -- */ /** * * Searches a NIC list for the NIC identified by a MAC address. * * @param[in] nicInfo NIC container. * @param[in] mac MAC address. * * @retval GuestNicV3* if found. * @retval NULL if not found. * ****************************************************************************** */ GuestNicV3 * GuestInfo_Util_FindNicByMac(const NicInfoV3 *nicInfo, const char *macAddress) { u_int i; ASSERT(nicInfo); ASSERT(macAddress); XDRUTIL_FOREACH(i, nicInfo, nics) { GuestNicV3 *nic; nic = XDRUTIL_GETITEM(nicInfo, nics, i); if (strcasecmp(nic->macAddress, macAddress) == 0) { return nic; } } return NULL; } open-vm-tools-9.4.0-1280544/services/plugins/guestInfo/getlib/guestInfo.c0000644765153500003110000003536312220061556024275 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file guestInfo.c * * Library backing parts of the vm.GuestInfo VIM APIs. */ #include #include #if defined _WIN32 # include #endif #include "vm_assert.h" #include "debug.h" #include "getlibInt.h" #include "str.h" #include "util.h" #include "xdrutil.h" #include "netutil.h" #include "wiper.h" /** * Helper to initialize an opaque struct member. * * @todo Move to xdrutil.h? Sticking point is dependency on Util_SafeMalloc. */ #define XDRUTIL_SAFESETOPAQUE(ptr, type, src, size) \ do { \ (ptr)->type##_len = (size); \ (ptr)->type##_val = Util_SafeMalloc((size)); \ memcpy((ptr)->type##_val, (src), (size)); \ } while (0) /* * Global functions. */ /* ****************************************************************************** * GuestInfo_GetFqdn -- */ /** * * @brief Returns the guest's hostname (aka fully qualified domain name, FQDN). * * @param[in] outBufLen Size of outBuf. * @param[out] outBuf Output buffer. * * @retval TRUE Success. Hostname written to @a outBuf. * @retval FALSE Failure. * ****************************************************************************** */ Bool GuestInfo_GetFqdn(int outBufLen, char fqdn[]) { return GuestInfoGetFqdn(outBufLen, fqdn); } /* ****************************************************************************** * GuestInfo_GetNicInfo -- */ /** * * @brief Returns guest networking configuration (and some runtime state). * * @param[out] nicInfo Will point to a newly allocated NicInfo. * * @note * Caller is responsible for freeing @a nicInfo with GuestInfo_FreeNicInfo. * * @retval TRUE Success. @a nicInfo now points to a populated NicInfoV3. * @retval FALSE Failure. * ****************************************************************************** */ Bool GuestInfo_GetNicInfo(NicInfoV3 **nicInfo) { Bool retval = FALSE; *nicInfo = Util_SafeCalloc(1, sizeof (struct NicInfoV3)); retval = GuestInfoGetNicInfo(*nicInfo); if (!retval) { GuestInfo_FreeNicInfo(*nicInfo); *nicInfo = NULL; } return retval; } /* ****************************************************************************** * GuestInfo_FreeNicInfo -- */ /** * * @brief Frees a NicInfoV3 structure and all memory it points to. * * @param[in] nicInfo Pointer to NicInfoV3 container. * * @sa GuestInfo_GetNicInfo * ****************************************************************************** */ void GuestInfo_FreeNicInfo(NicInfoV3 *nicInfo) { if (nicInfo != NULL) { VMX_XDR_FREE(xdr_NicInfoV3, nicInfo); free(nicInfo); } } /* ****************************************************************************** * GuestInfo_FreeDiskInfo -- */ /** * * @brief Frees memory allocated by GuestInfoGetDiskInfo. * * @param[in] di DiskInfo container. * ****************************************************************************** */ void GuestInfo_FreeDiskInfo(GuestDiskInfo *di) { if (di) { free(di->partitionList); free(di); } } /* * Private library functions. */ /* ****************************************************************************** * GuestInfoGetDiskInfoWiper -- */ /** * * Uses wiper library to enumerate fixed volumes and lookup utilization data. * * @return Pointer to a GuestDiskInfo structure on success or NULL on failure. * Caller should free returned pointer with GuestInfoFreeDiskInfo. * ****************************************************************************** */ GuestDiskInfo * GuestInfoGetDiskInfoWiper(void) { WiperPartition_List pl; DblLnkLst_Links *curr; unsigned int partCount = 0; uint64 freeBytes = 0; uint64 totalBytes = 0; unsigned int partNameSize = 0; Bool success = FALSE; GuestDiskInfo *di; /* Get partition list. */ if (!WiperPartition_Open(&pl)) { g_debug("GetDiskInfo: ERROR: could not get partition list\n"); return FALSE; } di = Util_SafeCalloc(1, sizeof *di); partNameSize = sizeof (di->partitionList)[0].name; DblLnkLst_ForEach(curr, &pl.link) { WiperPartition *part = DblLnkLst_Container(curr, WiperPartition, link); if (part->type != PARTITION_UNSUPPORTED) { PPartitionEntry newPartitionList; PPartitionEntry partEntry; unsigned char *error; error = WiperSinglePartition_GetSpace(part, &freeBytes, &totalBytes); if (strlen(error)) { g_debug("GetDiskInfo: ERROR: could not get space for partition %s: %s\n", part->mountPoint, error); goto out; } if (strlen(part->mountPoint) + 1 > partNameSize) { g_debug("GetDiskInfo: ERROR: Partition name buffer too small\n"); goto out; } newPartitionList = Util_SafeRealloc(di->partitionList, (partCount + 1) * sizeof *di->partitionList); partEntry = &newPartitionList[partCount++]; Str_Strcpy(partEntry->name, part->mountPoint, partNameSize); partEntry->freeBytes = freeBytes; partEntry->totalBytes = totalBytes; di->partitionList = newPartitionList; } } di->numEntries = partCount; success = TRUE; out: if (!success) { GuestInfo_FreeDiskInfo(di); di = NULL; } WiperPartition_Close(&pl); return di; } /* ****************************************************************************** * GuestInfoAddNicEntry -- */ /** * * @brief GuestNicV3 constructor. * * @param[in,out] nicInfo List of NICs. * @param[in] macAddress MAC address of new NIC. * @param[in] dnsInfo Per-NIC DNS config state. * @param[in] winsInfo Per-NIC WINS config state. * * @note The returned GuestNic will take ownership of @a dnsInfo and * @a winsInfo The caller must not free it directly. * * @return Pointer to the new NIC, or NULL if NIC limit was reached. * ****************************************************************************** */ GuestNicV3 * GuestInfoAddNicEntry(NicInfoV3 *nicInfo, const char macAddress[NICINFO_MAC_LEN], DnsConfigInfo *dnsInfo, WinsConfigInfo *winsInfo) { GuestNicV3 *newNic; /* Check to see if we're going above our limit. See bug 605821. */ if (nicInfo->nics.nics_len == NICINFO_MAX_NICS) { g_message("%s: NIC limit (%d) reached, skipping overflow.", __FUNCTION__, NICINFO_MAX_NICS); return NULL; } newNic = XDRUTIL_ARRAYAPPEND(nicInfo, nics, 1); ASSERT_MEM_ALLOC(newNic); newNic->macAddress = Util_SafeStrdup(macAddress); newNic->dnsConfigInfo = dnsInfo; newNic->winsConfigInfo = winsInfo; return newNic; } /* ****************************************************************************** * GuestInfoAddIpAddress -- */ /** * * @brief Add an IP address entry into the GuestNic. * * @param[in,out] nic The NIC information. * @param[in] sockAddr The new IP address. * @param[in] pfxLen Prefix length (use 0 if unknown). * @param[in] origin Address's origin. (Optional.) * @param[in] status Address's status. (Optional.) * * @return Newly allocated IP address struct, NULL on failure. * ****************************************************************************** */ IpAddressEntry * GuestInfoAddIpAddress(GuestNicV3 *nic, const struct sockaddr *sockAddr, InetAddressPrefixLength pfxLen, const IpAddressOrigin *origin, const IpAddressStatus *status) { IpAddressEntry *ip; ASSERT(sockAddr); /* Check to see if we're going above our limit. See bug 605821. */ if (nic->ips.ips_len == NICINFO_MAX_IPS) { g_message("%s: IP address limit (%d) reached, skipping overflow.", __FUNCTION__, NICINFO_MAX_IPS); return NULL; } ip = XDRUTIL_ARRAYAPPEND(nic, ips, 1); ASSERT_MEM_ALLOC(ip); ASSERT_ON_COMPILE(sizeof *origin == sizeof *ip->ipAddressOrigin); ASSERT_ON_COMPILE(sizeof *status == sizeof *ip->ipAddressStatus); switch (sockAddr->sa_family) { case AF_INET: { static const IpAddressStatus defaultStatus = IAS_PREFERRED; GuestInfoSockaddrToTypedIpAddress(sockAddr, &ip->ipAddressAddr); ip->ipAddressPrefixLength = pfxLen; ip->ipAddressOrigin = origin ? Util_DupeThis(origin, sizeof *origin) : NULL; ip->ipAddressStatus = status ? Util_DupeThis(status, sizeof *status) : Util_DupeThis(&defaultStatus, sizeof defaultStatus); } break; case AF_INET6: { static const IpAddressStatus defaultStatus = IAS_UNKNOWN; GuestInfoSockaddrToTypedIpAddress(sockAddr, &ip->ipAddressAddr); ip->ipAddressPrefixLength = pfxLen; ip->ipAddressOrigin = origin ? Util_DupeThis(origin, sizeof *origin) : NULL; ip->ipAddressStatus = status ? Util_DupeThis(status, sizeof *status) : Util_DupeThis(&defaultStatus, sizeof defaultStatus); } break; default: NOT_REACHED(); } return ip; } /* ****************************************************************************** * GuestInfoSockaddrToTypedIpAddress -- */ /** * * @brief Converts a struct sockaddr to a @c TypedIpAddress. * * @param[in] sa Source @c sockaddr. * @param[out] typedIp Destination @c TypedIpAddress. * * @warning Caller is responsible for making sure source is AF_INET or * AF_INET6. * ****************************************************************************** */ void GuestInfoSockaddrToTypedIpAddress(const struct sockaddr *sa, TypedIpAddress *typedIp) { struct sockaddr_in *sin = (struct sockaddr_in *)sa; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; switch (sa->sa_family) { case AF_INET: typedIp->ipAddressAddrType = IAT_IPV4; XDRUTIL_SAFESETOPAQUE(&typedIp->ipAddressAddr, InetAddress, &sin->sin_addr.s_addr, sizeof sin->sin_addr.s_addr); break; case AF_INET6: typedIp->ipAddressAddrType = IAT_IPV6; XDRUTIL_SAFESETOPAQUE(&typedIp->ipAddressAddr, InetAddress, &sin6->sin6_addr.s6_addr, sizeof sin6->sin6_addr.s6_addr); /* * Some TCP stacks (hello Apple and FreeBSD!) deviate from the RFC and * embed the scope id in link-local IPv6 addresses. This breaks things * since the address with the scope id does not work on the wire. For * example: * * fe80:4::20c:29ff:fece:3dcf * * Is an invalid IPv6 address because the "4" violates the RFC. But that's * what SIOCGIFCONF returns on these platforms. * * Detect link-local addresses here and make sure they comply with the * RFC. Just for reference, link local addresses start with '1111111010' * and have 54 zero bits after that: * * http://tools.ietf.org/html/rfc4291#section-2.5.6 */ { uint64 ip6_ll_test = 0x80FE; uint64 ip6_ll_mask = 0xC0FF; uint64 *ip6 = (uint64 *) typedIp->ipAddressAddr.InetAddress_val; if ((*ip6 & ip6_ll_mask) == ip6_ll_test) { *ip6 &= ip6_ll_mask; } } break; default: NOT_REACHED(); } } #if defined linux || defined _WIN32 /* ****************************************************************************** * GuestInfoGetNicInfoIfIndex -- */ /** * * @brief Given a local interface's index, find its corresponding location in the * NicInfoV3 @c nics vector. * * @param[in] nicInfo NIC container. * @param[in] ifIndex Device to search for. * @param[out] nicifIndex Array offset, if found. * * @retval TRUE Device found. * @retval FALSE Device not found. * ****************************************************************************** */ Bool GuestInfoGetNicInfoIfIndex(NicInfoV3 *nicInfo, int ifIndex, int *nicIfIndex) { char hwAddrString[NICINFO_MAC_LEN]; unsigned char hwAddr[16]; IanaIfType ifType; Bool ret = FALSE; u_int i; ASSERT(nicInfo); ASSERT(nicIfIndex); if (NetUtil_GetHardwareAddress(ifIndex, hwAddr, sizeof hwAddr, &ifType) != 6 || ifType != IANA_IFTYPE_ETHERNETCSMACD) { return FALSE; } Str_Sprintf(hwAddrString, sizeof hwAddrString, "%02x:%02x:%02x:%02x:%02x:%02x", hwAddr[0], hwAddr[1], hwAddr[2], hwAddr[3], hwAddr[4], hwAddr[5]); XDRUTIL_FOREACH(i, nicInfo, nics) { GuestNicV3 *nic = XDRUTIL_GETITEM(nicInfo, nics, i); if (!strcasecmp(nic->macAddress, hwAddrString)) { *nicIfIndex = i; ret = TRUE; break; } } return ret; } #endif // if defined linux || defined _WIN32 /* * XXX */ /** * Return a copy of arbitrary memory. * * @param[in] source Source address. * @param[in] sourceSize Number of bytes to allocate, copy. * * @return Pointer to newly allocated memory. * * @todo Determine if I'm duplicating functionality. * @todo Move this to bora/lib/util or whatever. */ void * Util_DupeThis(const void *source, size_t sourceSize) { void *dest; ASSERT(source); dest = Util_SafeMalloc(sourceSize); memcpy(dest, source, sourceSize); return dest; } open-vm-tools-9.4.0-1280544/services/plugins/guestInfo/getlib/getlibInt.h0000644765153500003110000000472312220061556024254 0ustar dtormts/********************************************************* * Copyright (C) 2001 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * getlibInt.h -- * * Functions used to communicate guest information to the host. * */ #ifndef GETLIB_INT_H #define GETLIB_INT_H #include "guestInfoInt.h" #if defined __FreeBSD__ || defined __sun__ || defined __APPLE__ # include // struct sockaddr #endif Bool GuestInfoGetFqdn(int outBufLen, char fqdn[]); GuestDiskInfo *GuestInfoGetDiskInfoWiper(void); Bool GuestInfoGetNicInfo(NicInfoV3 *nicInfo); GuestNicV3 *GuestInfoAddNicEntry(NicInfoV3 *nicInfo, // IN/OUT const char macAddress[NICINFO_MAC_LEN], // IN DnsConfigInfo *dnsInfo, // IN WinsConfigInfo *winsInfo); // IN IpAddressEntry *GuestInfoAddIpAddress(GuestNicV3 *nic, // IN/OUT const struct sockaddr *sockAddr, // IN InetAddressPrefixLength pfxLen, // IN const IpAddressOrigin *origin, // IN const IpAddressStatus *status); // IN #if defined linux || defined _WIN32 Bool GuestInfoGetNicInfoIfIndex(NicInfoV3 *nicInfo, // IN int ifIndex, // IN int *nicIfIndex); // OUT #endif // if defined linux || defined _WIN32 void GuestInfoSockaddrToTypedIpAddress(const struct sockaddr *sa, // IN TypedIpAddress *typedIp); // OUT /* XXX */ void * Util_DupeThis(const void *source, size_t sourceSize); #endif open-vm-tools-9.4.0-1280544/services/plugins/guestInfo/getlib/compareNicInfo.c0000644765153500003110000003260212220061556025217 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file compareNicInfo.c * * Comparison routines for NicInfo types. Handy for caching, unit testing. * * @todo Each byte of a MAC address is assumed to be represented by two * characters. So, as far as these routines are concerned, 0:1:2:3:4:5 * != 00:01:02:03:04:05. Is this a problem? */ #include #include "vmware.h" #include "xdrutil.h" #include "guestInfoLib.h" /** * Common comparison prefix routine. */ #define RETURN_EARLY_CMP_PTRS(a, b) do { \ if (!(a) && !(b)) { \ return TRUE; \ } else if ((!(a) && (b)) || ((a) && !(b))) { \ return FALSE; \ } \ } while (0) /* ****************************************************************************** * GuestInfo_IsEqual_DhcpConfigInfo -- */ /** * * Compares a pair of DhcpConfigInfos. * * @param[in] a DhcpConfigInfo number 1. May be NULL. * @param[in] b DhcpConfigInfo number 2. May be NULL. * * @retval TRUE DhcpConfigInfos are equivalent. * @retval FALSE DhcpConfigInfos differ. * ****************************************************************************** */ Bool GuestInfo_IsEqual_DhcpConfigInfo(const DhcpConfigInfo *a, const DhcpConfigInfo *b) { RETURN_EARLY_CMP_PTRS(a, b); return a->enabled == b->enabled && strcmp(a->dhcpSettings, b->dhcpSettings) == 0; } /* ****************************************************************************** * GuestInfo_IsEqual_DnsConfigInfo -- */ /** * * Compares a pair of DnsConfigInfos. * * @param[in] a DnsConfigInfo number 1. May be NULL. * @param[in] b DnsConfigInfo number 2. May be NULL. * * @retval TRUE DnsConfigInfos are equivalent. * @retval FALSE DnsConfigInfos differ. * ****************************************************************************** */ Bool GuestInfo_IsEqual_DnsConfigInfo(const DnsConfigInfo *a, const DnsConfigInfo *b) { u_int ai; u_int bi; RETURN_EARLY_CMP_PTRS(a, b); if (!GuestInfo_IsEqual_DnsHostname(a->hostName, b->hostName) || !GuestInfo_IsEqual_DnsHostname(a->domainName, b->domainName) || a->serverList.serverList_len != b->serverList.serverList_len || a->searchSuffixes.searchSuffixes_len != b->searchSuffixes.searchSuffixes_len) { return FALSE; } /* * Since the lists' lengths match, search in b for each item in a. We'll * assume that we don't have any duplicates in a s.t. unique(a) is a proper * subset of b. * * Bail if we can't find an entry. */ XDRUTIL_FOREACH(ai, a, serverList) { TypedIpAddress *aServer = XDRUTIL_GETITEM(a, serverList, ai); XDRUTIL_FOREACH(bi, b, serverList) { TypedIpAddress *bServer = XDRUTIL_GETITEM(b, serverList, bi); if (GuestInfo_IsEqual_TypedIpAddress(aServer, bServer)) { break; } } if (bi == b->serverList.serverList_len) { /* Exhausted b's list, didn't find aServer. */ return FALSE; } } XDRUTIL_FOREACH(ai, a, searchSuffixes) { DnsHostname *aSuffix = XDRUTIL_GETITEM(a, searchSuffixes, ai); XDRUTIL_FOREACH(bi, b, searchSuffixes) { DnsHostname *bSuffix = XDRUTIL_GETITEM(b, searchSuffixes, bi); if (GuestInfo_IsEqual_DnsHostname(aSuffix, bSuffix)) { break; } } if (bi == b->searchSuffixes.searchSuffixes_len) { /* Exhausted b's list, didn't find aSuffix. */ return FALSE; } } return TRUE; } /* ****************************************************************************** * GuestInfo_IsEqual_DnsHostname -- */ /** * * Compares a pair of DnsHostnames. * * @param[in] a DnsHostname number 1. May be NULL. * @param[in] b DnsHostname number 2. May be NULL. * * @retval TRUE DnsHostnames are equivalent. * @retval FALSE DnsHostnames differ. * ****************************************************************************** */ Bool GuestInfo_IsEqual_DnsHostname(const DnsHostname *a, const DnsHostname *b) { RETURN_EARLY_CMP_PTRS(a, b); return strcasecmp(*a, *b) == 0 ? TRUE : FALSE; } /* ****************************************************************************** * GuestInfo_IsEqual_GuestNicV3 -- */ /** * * Compares two GuestNicV3s. * * @param[in] a GuestNicV3 number 1. May be NULL. * @param[in] b GuestNicV3 number 2. May be NULL. * * @retval TRUE GuestNicV3s are equivalent. * @retval FALSE GuestNicV3s differ. * ****************************************************************************** */ Bool GuestInfo_IsEqual_GuestNicV3(const GuestNicV3 *a, const GuestNicV3 *b) { u_int ai; u_int bi; RETURN_EARLY_CMP_PTRS(a, b); /* Not optional fields. */ ASSERT(a->macAddress); ASSERT(b->macAddress); if (strcasecmp(a->macAddress, b->macAddress) != 0) { return FALSE; } /* * Compare the IP lists. */ if (a->ips.ips_len != b->ips.ips_len) { return FALSE; } XDRUTIL_FOREACH(ai, a, ips) { IpAddressEntry *aEntry = XDRUTIL_GETITEM(a, ips, ai); XDRUTIL_FOREACH(bi, b, ips) { IpAddressEntry *bEntry = XDRUTIL_GETITEM(b, ips, bi); if (GuestInfo_IsEqual_IpAddressEntry(aEntry, bEntry)) { break; } } if (bi == b->ips.ips_len) { /* Exhausted b's list, didn't find aEntry. */ return FALSE; } } return GuestInfo_IsEqual_DnsConfigInfo(a->dnsConfigInfo, b->dnsConfigInfo) && GuestInfo_IsEqual_WinsConfigInfo(a->winsConfigInfo, b->winsConfigInfo) && GuestInfo_IsEqual_DhcpConfigInfo(a->dhcpConfigInfov4, b->dhcpConfigInfov4) && GuestInfo_IsEqual_DhcpConfigInfo(a->dhcpConfigInfov6, b->dhcpConfigInfov6); } /* ****************************************************************************** * GuestInfo_IsEqual_InetCidrRouteEntry -- */ /** * * Compares two InetCidrRouteEntrys. * * @param[in] a InetCidrRouteEntry number 1. May be NULL. * @param[in] b InetCidrRouteEntry number 2. May be NULL. * @param[in] aInfo a's NicInfo container. If a != NULL, may NOT be NULL. * @param[in] bInfo b's NicInfo container. If b != NULL, may NOT be NULL. * * @retval TRUE InetCidrRouteEntrys are equivalent. * @retval FALSE InetCidrRouteEntrys differ. * ****************************************************************************** */ Bool GuestInfo_IsEqual_InetCidrRouteEntry(const InetCidrRouteEntry *a, const InetCidrRouteEntry *b, const NicInfoV3 *aInfo, const NicInfoV3 *bInfo) { RETURN_EARLY_CMP_PTRS(a, b); ASSERT(aInfo); ASSERT(bInfo); return GuestInfo_IsEqual_TypedIpAddress(&a->inetCidrRouteDest, &b->inetCidrRouteDest) && a->inetCidrRoutePfxLen == b->inetCidrRoutePfxLen && GuestInfo_IsEqual_TypedIpAddress(a->inetCidrRouteNextHop, b->inetCidrRouteNextHop) && strcasecmp(aInfo->nics.nics_val[a->inetCidrRouteIfIndex].macAddress, bInfo->nics.nics_val[b->inetCidrRouteIfIndex].macAddress) == 0 && a->inetCidrRouteType == b->inetCidrRouteType && a->inetCidrRouteMetric == b->inetCidrRouteMetric; } /* ****************************************************************************** * GuestInfo_IsEqual_IpAddressEntry -- */ /** * * Compares two IpAddressEntrys. * * @param[in] a IpAddressEntry number 1. May be NULL. * @param[in] b IpAddressEntry number 2. May be NULL. * * @retval TRUE IpAddressEntrys are equivalent. * @retval FALSE IpAddressEntrys differ. * ****************************************************************************** */ Bool GuestInfo_IsEqual_IpAddressEntry(const IpAddressEntry *a, const IpAddressEntry *b) { RETURN_EARLY_CMP_PTRS(a, b); return GuestInfo_IsEqual_TypedIpAddress(&a->ipAddressAddr, &b->ipAddressAddr) && a->ipAddressPrefixLength == b->ipAddressPrefixLength && ((a->ipAddressOrigin == NULL && b->ipAddressOrigin == NULL) || (a->ipAddressOrigin != NULL && b->ipAddressOrigin != NULL && *a->ipAddressOrigin == *b->ipAddressOrigin)) && ((a->ipAddressStatus == NULL && b->ipAddressStatus == NULL) || (a->ipAddressStatus != NULL && b->ipAddressStatus != NULL && *a->ipAddressStatus == *b->ipAddressStatus)); } /* ****************************************************************************** * GuestInfo_IsEqual_NicInfoV3 -- */ /** * * Compares two NicInfoV3s. * * @param[in] a NicInfoV3 number 1. May be NULL. * @param[in] b NicInfoV3 number 2. May be NULL. * * @retval TRUE NicInfoV3s are equivalent. * @retval FALSE NicInfoV3s differ. * ****************************************************************************** */ Bool GuestInfo_IsEqual_NicInfoV3(const NicInfoV3 *a, const NicInfoV3 *b) { u_int ai; u_int bi; RETURN_EARLY_CMP_PTRS(a, b); /* * Compare the NIC lists. */ if (a->nics.nics_len != b->nics.nics_len) { return FALSE; } XDRUTIL_FOREACH(ai, a, nics) { GuestNicV3 *eachNic = XDRUTIL_GETITEM(a, nics, ai); GuestNicV3 *cmpNic = GuestInfo_Util_FindNicByMac(b, eachNic->macAddress); if (cmpNic == NULL || !GuestInfo_IsEqual_GuestNicV3(eachNic, cmpNic)) { return FALSE; } } /* * Compare routes. */ if (a->routes.routes_len != b->routes.routes_len) { return FALSE; } XDRUTIL_FOREACH(ai, a, routes) { InetCidrRouteEntry *aRoute = XDRUTIL_GETITEM(a, routes, ai); XDRUTIL_FOREACH(bi, b, routes) { InetCidrRouteEntry *bRoute = XDRUTIL_GETITEM(b, routes, bi); if (GuestInfo_IsEqual_InetCidrRouteEntry(aRoute, bRoute, a, b)) { break; } } if (bi == b->routes.routes_len) { /* Exhausted b's list, didn't find aRoute. */ return FALSE; } } /* * Compare the stack settings: * . DnsConfigInfo * . WinsConfigInfo * . DhcpConfigInfov4 * . DhcpConfigInfov6 */ return GuestInfo_IsEqual_DnsConfigInfo(a->dnsConfigInfo, b->dnsConfigInfo) && GuestInfo_IsEqual_WinsConfigInfo(a->winsConfigInfo, b->winsConfigInfo) && GuestInfo_IsEqual_DhcpConfigInfo(a->dhcpConfigInfov4, b->dhcpConfigInfov4) && GuestInfo_IsEqual_DhcpConfigInfo(a->dhcpConfigInfov6, b->dhcpConfigInfov6); } /* ****************************************************************************** * GuestInfo_IsEqual_TypedIpAddress -- */ /** * * Compares two TypedIpAddresses. * * @param[in] a TypedIpAddress number 1. May be NULL. * @param[in] b TypedIpAddress number 2. May be NULL. * * @retval TRUE TypedIpAddresses are equivalent. * @retval FALSE TypedIpAddresses differ. * ****************************************************************************** */ Bool GuestInfo_IsEqual_TypedIpAddress(const TypedIpAddress *a, const TypedIpAddress *b) { RETURN_EARLY_CMP_PTRS(a, b); if (a->ipAddressAddrType != b->ipAddressAddrType || memcmp(a->ipAddressAddr.InetAddress_val, b->ipAddressAddr.InetAddress_val, a->ipAddressAddr.InetAddress_len)) { return FALSE; } return TRUE; } /* ****************************************************************************** * GuestInfo_IsEqual_WinsConfigInfo -- */ /** * * Compares a pair of WinsConfigInfos. * * @param[in] a WinsConfigInfo number 1. May be NULL. * @param[in] b WinsConfigInfo number 2. May be NULL. * * @retval TRUE WinsConfigInfos are equivalent. * @retval FALSE WinsConfigInfos differ. * ****************************************************************************** */ Bool GuestInfo_IsEqual_WinsConfigInfo(const WinsConfigInfo *a, const WinsConfigInfo *b) { RETURN_EARLY_CMP_PTRS(a, b); return GuestInfo_IsEqual_TypedIpAddress(&a->primary, &b->primary) && GuestInfo_IsEqual_TypedIpAddress(&a->secondary, &b->secondary); } open-vm-tools-9.4.0-1280544/services/plugins/guestInfo/getlib/guestInfoPosix.c0000644765153500003110000005211612220061556025313 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file guestInfoPosix.c * * Contains POSIX-specific bits of GuestInfo collector library. */ #include #include #include #include #ifdef sun # include #endif #include #include #include #include #include #if defined(__FreeBSD__) || defined(__APPLE__) # include #endif #ifndef NO_DNET # ifdef DNET_IS_DUMBNET # include # else # include # endif #endif #include #include #include #ifdef __linux__ # include #endif /* * resolver(3) and IPv6: * * The ISC BIND resolver included various IPv6 implementations over time, but * unfortunately the ISC hadn't bumped __RES accordingly. (__RES is -supposed- * to behave as a version datestamp for the resolver interface.) Similarly * the GNU C Library forked resolv.h and made modifications of their own, also * without changing __RES. * * glibc 2.1.92 included a patch which provides IPv6 name server support by * embedding in6_addr pointers in _res._u._ext. Since I only care about major * and minor numbers, though, I'm going to condition this impl. on glibc 2.2. * * ISC, OTOH, provided accessing IPv6 servers via a res_getservers API. * TTBOMK, this went public with BIND 8.3.0. Unfortunately __RES wasn't * bumped for this release, so instead I'm going to assume that appearance with * that release of a new macro, RES_F_DNS0ERR, implies this API is available. * (For internal builds, we'll know instantly when a build breaks. The down- * side is that this could cause some trouble for Open VM Tools users. ,_,) * * resolv.h version IPv6 API __RES * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * glibc 2.2+ _ext 19991006 * BIND 8.3.0 getservers 19991006 * BIND 8.3.4+ getservers 20030124(+?) * * To distinguish between the variants where __RES == 19991006, I'll * discriminate on the existence of new macros included with the appropriate * version. */ #if defined __GLIBC__ # if __GLIBC_PREREQ(2,2) # define RESOLVER_IPV6_EXT # endif // __GLIBC_PREREQ(2,2) #elif (__RES > 19991006 || (__RES == 19991006 && defined RES_F_EDNS0ERR)) # define RESOLVER_IPV6_GETSERVERS #endif // if defined __GLIBC__ #include "util.h" #include "sys/utsname.h" #include "sys/ioctl.h" #include "vmware.h" #include "hostinfo.h" #include "getlibInt.h" #include "debug.h" #include "str.h" #include "guest_os.h" #include "guestApp.h" #include "guestInfo.h" #include "xdrutil.h" #ifdef USE_SLASH_PROC # include "slashProc.h" #endif #include "netutil.h" #include "file.h" /* * Local functions */ #ifndef NO_DNET static void RecordNetworkAddress(GuestNicV3 *nic, const struct addr *addr); static int ReadInterfaceDetails(const struct intf_entry *entry, void *arg); static Bool RecordResolverInfo(NicInfoV3 *nicInfo); static void RecordResolverNS(DnsConfigInfo *dnsConfigInfo); static Bool RecordRoutingInfo(NicInfoV3 *nicInfo); #endif /* ****************************************************************************** * GuestInfoGetFqdn -- */ /** * * @copydoc GuestInfo_GetFqdn * ****************************************************************************** */ Bool GuestInfoGetFqdn(int outBufLen, // IN: length of output buffer char fqdn[]) // OUT: fully qualified domain name { ASSERT(fqdn); if (gethostname(fqdn, outBufLen) < 0) { g_debug("Error, gethostname failed\n"); return FALSE; } return TRUE; } /* ****************************************************************************** * GuestInfoGetNicInfo -- */ /** * * @copydoc GuestInfo_GetNicInfo * ****************************************************************************** */ Bool GuestInfoGetNicInfo(NicInfoV3 *nicInfo) // OUT { #ifndef NO_DNET intf_t *intf; /* Get a handle to read the network interface configuration details. */ if ((intf = intf_open()) == NULL) { g_debug("Error, failed NULL result from intf_open()\n"); return FALSE; } if (intf_loop(intf, ReadInterfaceDetails, nicInfo) < 0) { intf_close(intf); g_debug("Error, negative result from intf_loop\n"); return FALSE; } intf_close(intf); if (!RecordResolverInfo(nicInfo)) { return FALSE; } if (!RecordRoutingInfo(nicInfo)) { return FALSE; } return TRUE; #else return FALSE; #endif } /* ****************************************************************************** * GuestInfo_GetDiskInfo -- */ /** * * Uses wiper library to enumerate fixed volumes and lookup utilization data. * * @return Pointer to a GuestDiskInfo structure on success or NULL on failure. * Caller should free returned pointer with GuestInfoFreeDiskInfo. * ****************************************************************************** */ GuestDiskInfo * GuestInfo_GetDiskInfo(void) { return GuestInfoGetDiskInfoWiper(); } /* * Local functions */ #ifndef NO_DNET /* ****************************************************************************** * RecordNetworkAddress -- */ /** * * @brief Massages a dnet(3)-style interface address (IPv4 or IPv6) and stores * it as part of a GuestNicV3 structure. * * @param[in] nic Operand NIC. * @param[in] addr dnet(3) address. * ****************************************************************************** */ static void RecordNetworkAddress(GuestNicV3 *nic, // IN: operand NIC const struct addr *addr) // IN: dnet(3) address to process { struct sockaddr_storage ss; struct sockaddr *sa = (struct sockaddr *)&ss; memset(&ss, 0, sizeof ss); addr_ntos(addr, sa); GuestInfoAddIpAddress(nic, sa, addr->addr_bits, NULL, NULL); } /* ****************************************************************************** * ReadInterfaceDetails -- */ /** * * @brief Callback function called by libdnet when iterating over all the NICs * on the host. * * @param[in] entry Current interface entry. * @param[in] arg Pointer to NicInfoV3 container. * * @note New GuestNicV3 structures are added to the NicInfoV3 structure. * * @retval 0 Success. * @retval -1 Failure. * ****************************************************************************** */ static int ReadInterfaceDetails(const struct intf_entry *entry, // IN: current interface entry void *arg) // IN: Pointer to the GuestNicList { int i; NicInfoV3 *nicInfo = arg; ASSERT(entry); ASSERT(arg); if (entry->intf_type == INTF_TYPE_ETH && entry->intf_link_addr.addr_type == ADDR_TYPE_ETH) { GuestNicV3 *nic = NULL; char macAddress[NICINFO_MAC_LEN]; /* * There is a race where the guest info plugin might be iterating over the * interfaces while the OS is modifying them (i.e. by bringing them up * after a resume). If we see an ethernet interface with an invalid MAC, * then ignore it for now. Subsequent iterations of the gather loop will * pick up any changes. */ if (entry->intf_link_addr.addr_type == ADDR_TYPE_ETH) { Str_Sprintf(macAddress, sizeof macAddress, "%s", addr_ntoa(&entry->intf_link_addr)); nic = GuestInfoAddNicEntry(nicInfo, macAddress, NULL, NULL); if (NULL == nic) { /* * We reached maximum number of NICs we can report to the host. */ return 0; } /* Record the "primary" address. */ if (entry->intf_addr.addr_type == ADDR_TYPE_IP || entry->intf_addr.addr_type == ADDR_TYPE_IP6) { RecordNetworkAddress(nic, &entry->intf_addr); } /* Walk the list of alias's and add those that are IPV4 or IPV6 */ for (i = 0; i < entry->intf_alias_num; i++) { const struct addr *alias = &entry->intf_alias_addrs[i]; if (alias->addr_type == ADDR_TYPE_IP || alias->addr_type == ADDR_TYPE_IP6) { RecordNetworkAddress(nic, alias); } } } } return 0; } /* ****************************************************************************** * RecordResolverInfo -- */ /** * * @brief Query resolver(3), mapping settings to DnsConfigInfo. * * @param[out] nicInfo NicInfoV3 container. * * @retval TRUE Values collected, attached to @a nicInfo. * @retval FALSE Something went wrong. @a nicInfo is unharmed. * ****************************************************************************** */ static Bool RecordResolverInfo(NicInfoV3 *nicInfo) // OUT { DnsConfigInfo *dnsConfigInfo = NULL; char namebuf[DNSINFO_MAX_ADDRLEN + 1]; char **s; if (res_init() == -1) { return FALSE; } dnsConfigInfo = Util_SafeCalloc(1, sizeof *dnsConfigInfo); /* * Copy in the host name. */ if (!GuestInfoGetFqdn(sizeof namebuf, namebuf)) { goto fail; } dnsConfigInfo->hostName = Util_SafeCalloc(1, sizeof *dnsConfigInfo->hostName); *dnsConfigInfo->hostName = Util_SafeStrdup(namebuf); /* * Repeat with the domain name. */ dnsConfigInfo->domainName = Util_SafeCalloc(1, sizeof *dnsConfigInfo->domainName); *dnsConfigInfo->domainName = Util_SafeStrdup(_res.defdname); /* * Name servers. */ RecordResolverNS(dnsConfigInfo); /* * Search suffixes. */ for (s = _res.dnsrch; *s; s++) { DnsHostname *suffix; /* Check to see if we're going above our limit. See bug 605821. */ if (dnsConfigInfo->searchSuffixes.searchSuffixes_len == DNSINFO_MAX_SUFFIXES) { g_message("%s: dns search suffix limit (%d) reached, skipping overflow.", __FUNCTION__, DNSINFO_MAX_SUFFIXES); break; } suffix = XDRUTIL_ARRAYAPPEND(dnsConfigInfo, searchSuffixes, 1); ASSERT_MEM_ALLOC(suffix); *suffix = Util_SafeStrdup(*s); } /* * "Commit" dnsConfigInfo to nicInfo. */ nicInfo->dnsConfigInfo = dnsConfigInfo; return TRUE; fail: VMX_XDR_FREE(xdr_DnsConfigInfo, dnsConfigInfo); free(dnsConfigInfo); return FALSE; } /* ****************************************************************************** * RecordResolverNS -- */ /** * * @brief Copies name servers used by resolver(3) to @a dnsConfigInfo. * * @param[out] dnsConfigInfo Destination DnsConfigInfo container. * ****************************************************************************** */ static void RecordResolverNS(DnsConfigInfo *dnsConfigInfo) // IN { int i; #if defined RESOLVER_IPV6_GETSERVERS { union res_sockaddr_union *ns; ns = Util_SafeCalloc(_res.nscount, sizeof *ns); if (res_getservers(&_res, ns, _res.nscount) != _res.nscount) { g_warning("%s: res_getservers failed.\n", __func__); return; } for (i = 0; i < _res.nscount; i++) { struct sockaddr *sa = (struct sockaddr *)&ns[i]; if (sa->sa_family == AF_INET || sa->sa_family == AF_INET6) { TypedIpAddress *ip; /* Check to see if we're going above our limit. See bug 605821. */ if (dnsConfigInfo->serverList.serverList_len == DNSINFO_MAX_SERVERS) { g_message("%s: dns server limit (%d) reached, skipping overflow.", __FUNCTION__, DNSINFO_MAX_SERVERS); break; } ip = XDRUTIL_ARRAYAPPEND(dnsConfigInfo, serverList, 1); ASSERT_MEM_ALLOC(ip); GuestInfoSockaddrToTypedIpAddress(sa, ip); } } } #else // if defined RESOLVER_IPV6_GETSERVERS { /* * Name servers (IPv4). */ for (i = 0; i < MAXNS; i++) { struct sockaddr_in *sin = &_res.nsaddr_list[i]; if (sin->sin_family == AF_INET) { TypedIpAddress *ip; /* Check to see if we're going above our limit. See bug 605821. */ if (dnsConfigInfo->serverList.serverList_len == DNSINFO_MAX_SERVERS) { g_message("%s: dns server limit (%d) reached, skipping overflow.", __FUNCTION__, DNSINFO_MAX_SERVERS); break; } ip = XDRUTIL_ARRAYAPPEND(dnsConfigInfo, serverList, 1); ASSERT_MEM_ALLOC(ip); GuestInfoSockaddrToTypedIpAddress((struct sockaddr *)sin, ip); } } # if defined RESOLVER_IPV6_EXT /* * Name servers (IPv6). */ for (i = 0; i < MAXNS; i++) { struct sockaddr_in6 *sin6 = _res._u._ext.nsaddrs[i]; if (sin6) { TypedIpAddress *ip; /* Check to see if we're going above our limit. See bug 605821. */ if (dnsConfigInfo->serverList.serverList_len == DNSINFO_MAX_SERVERS) { g_message("%s: dns server limit (%d) reached, skipping overflow.", __FUNCTION__, DNSINFO_MAX_SERVERS); break; } ip = XDRUTIL_ARRAYAPPEND(dnsConfigInfo, serverList, 1); ASSERT_MEM_ALLOC(ip); GuestInfoSockaddrToTypedIpAddress((struct sockaddr *)sin6, ip); } } # endif // if defined RESOLVER_IPV6_EXT } #endif // if !defined RESOLVER_IPV6_GETSERVERS } #ifdef USE_SLASH_PROC /* ****************************************************************************** * RecordRoutingInfoIPv4 -- */ /** * * @brief Query the IPv4 routing subsystem and pack up contents * (struct rtentry) into InetCidrRouteEntries. * * @param[out] nicInfo NicInfoV3 container. * * @note Do not call this routine without first populating @a nicInfo 's NIC * list. * * @retval TRUE Values collected, attached to @a nicInfo. * @retval FALSE Something went wrong. @a nicInfo is unharmed. * ****************************************************************************** */ static Bool RecordRoutingInfoIPv4(NicInfoV3 *nicInfo) { GPtrArray *routes = NULL; guint i; Bool ret = FALSE; if ((routes = SlashProcNet_GetRoute()) == NULL) { return FALSE; } for (i = 0; i < routes->len; i++) { struct rtentry *rtentry; struct sockaddr_in *sin_dst; struct sockaddr_in *sin_gateway; struct sockaddr_in *sin_genmask; InetCidrRouteEntry *icre; uint32_t ifIndex; /* Check to see if we're going above our limit. See bug 605821. */ if (nicInfo->routes.routes_len == NICINFO_MAX_ROUTES) { g_message("%s: route limit (%d) reached, skipping overflow.", __FUNCTION__, NICINFO_MAX_ROUTES); break; } rtentry = g_ptr_array_index(routes, i); if ((rtentry->rt_flags & RTF_UP) == 0 || !GuestInfoGetNicInfoIfIndex(nicInfo, if_nametoindex(rtentry->rt_dev), &ifIndex)) { continue; } icre = XDRUTIL_ARRAYAPPEND(nicInfo, routes, 1); ASSERT_MEM_ALLOC(icre); sin_dst = (struct sockaddr_in *)&rtentry->rt_dst; sin_gateway = (struct sockaddr_in *)&rtentry->rt_gateway; sin_genmask = (struct sockaddr_in *)&rtentry->rt_genmask; GuestInfoSockaddrToTypedIpAddress((struct sockaddr *)sin_dst, &icre->inetCidrRouteDest); addr_stob((struct sockaddr *)sin_genmask, (uint16_t *)&icre->inetCidrRoutePfxLen); /* * Gateways are optional (ex: one can bind a route to an interface w/o * specifying a next hop address). */ if (rtentry->rt_flags & RTF_GATEWAY) { TypedIpAddress *ip = Util_SafeCalloc(1, sizeof *ip); GuestInfoSockaddrToTypedIpAddress((struct sockaddr *)sin_gateway, ip); icre->inetCidrRouteNextHop = ip; } /* * Interface, metric. */ icre->inetCidrRouteIfIndex = ifIndex; icre->inetCidrRouteMetric = rtentry->rt_metric; } ret = TRUE; SlashProcNet_FreeRoute(routes); return ret; } /* ****************************************************************************** * RecordRoutingInfoIPv6 -- */ /** * * @brief Query the IPv6 routing subsystem and pack up contents * (struct in6_rtmsg) into InetCidrRouteEntries. * * @param[out] nicInfo NicInfoV3 container. * * @note Do not call this routine without first populating @a nicInfo 's NIC * list. * * @retval TRUE Values collected, attached to @a nicInfo. * @retval FALSE Something went wrong. @a nicInfo is unharmed. * ****************************************************************************** */ static Bool RecordRoutingInfoIPv6(NicInfoV3 *nicInfo) { GPtrArray *routes = NULL; guint i; Bool ret = FALSE; if ((routes = SlashProcNet_GetRoute6()) == NULL) { return FALSE; } for (i = 0; i < routes->len; i++) { struct sockaddr_storage ss; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss; struct in6_rtmsg *in6_rtmsg; InetCidrRouteEntry *icre; uint32_t ifIndex = -1; /* Check to see if we're going above our limit. See bug 605821. */ if (nicInfo->routes.routes_len == NICINFO_MAX_ROUTES) { g_message("%s: route limit (%d) reached, skipping overflow.", __FUNCTION__, NICINFO_MAX_ROUTES); break; } in6_rtmsg = g_ptr_array_index(routes, i); if ((in6_rtmsg->rtmsg_flags & RTF_UP) == 0 || !GuestInfoGetNicInfoIfIndex(nicInfo, in6_rtmsg->rtmsg_ifindex, &ifIndex)) { continue; } icre = XDRUTIL_ARRAYAPPEND(nicInfo, routes, 1); ASSERT_MEM_ALLOC(icre); /* * Destination. */ sin6->sin6_family = AF_INET6; sin6->sin6_addr = in6_rtmsg->rtmsg_dst; GuestInfoSockaddrToTypedIpAddress((struct sockaddr *)sin6, &icre->inetCidrRouteDest); icre->inetCidrRoutePfxLen = in6_rtmsg->rtmsg_dst_len; /* * Next hop. */ if (in6_rtmsg->rtmsg_flags & RTF_GATEWAY) { TypedIpAddress *ip = Util_SafeCalloc(1, sizeof *ip); sin6->sin6_addr = in6_rtmsg->rtmsg_gateway; GuestInfoSockaddrToTypedIpAddress((struct sockaddr *)sin6, ip); icre->inetCidrRouteNextHop = ip; } /* * Interface, metric. */ icre->inetCidrRouteIfIndex = ifIndex; icre->inetCidrRouteMetric = in6_rtmsg->rtmsg_metric; } ret = TRUE; SlashProcNet_FreeRoute6(routes); return ret; } /* ****************************************************************************** * RecordRoutingInfo -- */ /** * * @brief Query the routing subsystem and pack up contents into * InetCidrRouteEntries when either of IPv4 or IPV6 is configured. * * @param[out] nicInfo NicInfoV3 container. * * @note Do not call this routine without first populating @a nicInfo 's NIC * list. * * @retval TRUE Values collected(either IPv4 or IPv6 or both), * attached to @a nicInfo. * @retval FALSE Something went wrong(neither IPv4 nor IPv6 configured). * ****************************************************************************** */ static Bool RecordRoutingInfo(NicInfoV3 *nicInfo) { Bool retIPv4 = TRUE; Bool retIPv6 = TRUE; if (File_Exists("/proc/net/route") && !RecordRoutingInfoIPv4(nicInfo)) { g_warning("%s: Unable to collect IPv4 routing table.\n", __func__); retIPv4 = FALSE; } if (File_Exists("/proc/net/ipv6_route") && !RecordRoutingInfoIPv6(nicInfo)) { g_warning("%s: Unable to collect IPv6 routing table.\n", __func__); retIPv6 = FALSE; } return (retIPv4 || retIPv6); } #else // ifdef USE_SLASH_PROC static Bool RecordRoutingInfo(NicInfoV3 *nicInfo) { return TRUE; } #endif // else #endif // ifndef NO_DNET open-vm-tools-9.4.0-1280544/services/plugins/guestInfo/getlib/Makefile.am0000644765153500003110000000235112220061556024211 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libGuestInfo.la libGuestInfo_la_SOURCES = libGuestInfo_la_SOURCES += compareNicInfo.c libGuestInfo_la_SOURCES += guestInfo.c libGuestInfo_la_SOURCES += guestInfoPosix.c libGuestInfo_la_SOURCES += util.c libGuestInfo_la_CPPFLAGS = libGuestInfo_la_CPPFLAGS += @GLIB2_CPPFLAGS@ libGuestInfo_la_CPPFLAGS += -I$(srcdir)/.. AM_CFLAGS = $(DNET_CPPFLAGS) open-vm-tools-9.4.0-1280544/services/plugins/guestInfo/getlib/Makefile.in0000644765153500003110000005515312220061624024226 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = services/plugins/guestInfo/getlib DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libGuestInfo_la_LIBADD = am_libGuestInfo_la_OBJECTS = libGuestInfo_la-compareNicInfo.lo \ libGuestInfo_la-guestInfo.lo libGuestInfo_la-guestInfoPosix.lo \ libGuestInfo_la-util.lo libGuestInfo_la_OBJECTS = $(am_libGuestInfo_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libGuestInfo_la_SOURCES) DIST_SOURCES = $(libGuestInfo_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libGuestInfo.la libGuestInfo_la_SOURCES = compareNicInfo.c guestInfo.c \ guestInfoPosix.c util.c libGuestInfo_la_CPPFLAGS = @GLIB2_CPPFLAGS@ -I$(srcdir)/.. AM_CFLAGS = $(DNET_CPPFLAGS) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu services/plugins/guestInfo/getlib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu services/plugins/guestInfo/getlib/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libGuestInfo.la: $(libGuestInfo_la_OBJECTS) $(libGuestInfo_la_DEPENDENCIES) $(EXTRA_libGuestInfo_la_DEPENDENCIES) $(LINK) $(libGuestInfo_la_OBJECTS) $(libGuestInfo_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGuestInfo_la-compareNicInfo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGuestInfo_la-guestInfo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGuestInfo_la-guestInfoPosix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGuestInfo_la-util.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libGuestInfo_la-compareNicInfo.lo: compareNicInfo.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libGuestInfo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libGuestInfo_la-compareNicInfo.lo -MD -MP -MF $(DEPDIR)/libGuestInfo_la-compareNicInfo.Tpo -c -o libGuestInfo_la-compareNicInfo.lo `test -f 'compareNicInfo.c' || echo '$(srcdir)/'`compareNicInfo.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libGuestInfo_la-compareNicInfo.Tpo $(DEPDIR)/libGuestInfo_la-compareNicInfo.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='compareNicInfo.c' object='libGuestInfo_la-compareNicInfo.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libGuestInfo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libGuestInfo_la-compareNicInfo.lo `test -f 'compareNicInfo.c' || echo '$(srcdir)/'`compareNicInfo.c libGuestInfo_la-guestInfo.lo: guestInfo.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libGuestInfo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libGuestInfo_la-guestInfo.lo -MD -MP -MF $(DEPDIR)/libGuestInfo_la-guestInfo.Tpo -c -o libGuestInfo_la-guestInfo.lo `test -f 'guestInfo.c' || echo '$(srcdir)/'`guestInfo.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libGuestInfo_la-guestInfo.Tpo $(DEPDIR)/libGuestInfo_la-guestInfo.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='guestInfo.c' object='libGuestInfo_la-guestInfo.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libGuestInfo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libGuestInfo_la-guestInfo.lo `test -f 'guestInfo.c' || echo '$(srcdir)/'`guestInfo.c libGuestInfo_la-guestInfoPosix.lo: guestInfoPosix.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libGuestInfo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libGuestInfo_la-guestInfoPosix.lo -MD -MP -MF $(DEPDIR)/libGuestInfo_la-guestInfoPosix.Tpo -c -o libGuestInfo_la-guestInfoPosix.lo `test -f 'guestInfoPosix.c' || echo '$(srcdir)/'`guestInfoPosix.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libGuestInfo_la-guestInfoPosix.Tpo $(DEPDIR)/libGuestInfo_la-guestInfoPosix.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='guestInfoPosix.c' object='libGuestInfo_la-guestInfoPosix.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libGuestInfo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libGuestInfo_la-guestInfoPosix.lo `test -f 'guestInfoPosix.c' || echo '$(srcdir)/'`guestInfoPosix.c libGuestInfo_la-util.lo: util.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libGuestInfo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libGuestInfo_la-util.lo -MD -MP -MF $(DEPDIR)/libGuestInfo_la-util.Tpo -c -o libGuestInfo_la-util.lo `test -f 'util.c' || echo '$(srcdir)/'`util.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libGuestInfo_la-util.Tpo $(DEPDIR)/libGuestInfo_la-util.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='util.c' object='libGuestInfo_la-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libGuestInfo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libGuestInfo_la-util.lo `test -f 'util.c' || echo '$(srcdir)/'`util.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/services/plugins/guestInfo/perfMonLinux.c0000644765153500003110000001241212220061556023500 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * This file gathers the virtual memory stats from Linux guest to be * passed on to the vmx. */ #include #include #include #include #include #include #include "vmware.h" #include "guestInfo.h" #include "strutil.h" #include "debug.h" #ifndef NO_PROCPS #include "vm_procps.h" static void GuestInfoMonitorGetStat(GuestMemInfo *vmStats); static Bool GuestInfoMonitorReadMeminfo(GuestMemInfo *vmStats); #endif #define LINUX_MEMINFO_FLAGS (MEMINFO_MEMTOTAL | MEMINFO_MEMFREE | MEMINFO_MEMBUFF |\ MEMINFO_MEMCACHE | MEMINFO_MEMACTIVE | MEMINFO_MEMINACTIVE |\ MEMINFO_SWAPINRATE | MEMINFO_SWAPOUTRATE |\ MEMINFO_IOINRATE | MEMINFO_IOOUTRATE) /* *---------------------------------------------------------------------- * * GuestInfo_PerfMon -- * * Gather performance stats. * * Results: * Gathered stats. Returns FALSE on failure. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool GuestInfo_PerfMon(GuestMemInfo *vmStats) // OUT: filled vmstats { #ifndef NO_PROCPS ASSERT(vmStats); vmStats->flags = 0; GuestInfoMonitorGetStat(vmStats); if (GuestInfoMonitorReadMeminfo(vmStats)) { vmStats->flags |= LINUX_MEMINFO_FLAGS; return TRUE; } #endif return FALSE; } #ifndef NO_PROCPS /* *---------------------------------------------------------------------- * * GuestInfoMonitorGetStat -- * * Calls getstat() to gather memory stats. * * Results: * Gathered stats in vmStats. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void GuestInfoMonitorGetStat(GuestMemInfo *vmStats) // OUT: filled vmstats { uint32 hz = Hertz; uint32 dummy; jiff cpuUse[2]; jiff cpuNic[2]; jiff cpuSys[2]; jiff cpuIdl[2]; jiff cpuIow[2]; jiff cpuXxx[2]; jiff cpuYyy[2]; jiff cpuZzz[2]; jiff cpuTotal; jiff cpuHalf; unsigned long pageIn[2]; unsigned long pageOut[2]; unsigned long swapIn[2]; unsigned long swapOut[2]; unsigned int dummy2[2]; unsigned long kb_per_page = sysconf(_SC_PAGESIZE) / 1024ul; meminfo(); getstat(cpuUse, cpuNic, cpuSys, cpuIdl, cpuIow, cpuXxx, cpuYyy, cpuZzz, pageIn, pageOut, swapIn, swapOut, dummy2, dummy2, &dummy, &dummy, &dummy, &dummy); cpuTotal = *cpuUse + *cpuNic + *cpuSys + *cpuXxx + *cpuYyy + *cpuIdl + *cpuIow + *cpuZzz; cpuHalf = cpuTotal / 2UL; vmStats->memFree = kb_main_free; vmStats->memBuff = kb_main_buffers; vmStats->memCache = kb_main_cached, vmStats->memInactive = kb_inactive; vmStats->memActive = kb_active; vmStats->swapInRate = (uint64)((*swapIn * kb_per_page * hz + cpuHalf) / cpuTotal); vmStats->swapOutRate = (uint64)((*swapOut * kb_per_page * hz + cpuHalf) / cpuTotal); vmStats->ioInRate = (uint64)((*pageIn * kb_per_page * hz + cpuHalf) / cpuTotal); vmStats->ioOutRate = (uint64)((*pageOut * kb_per_page * hz + cpuHalf) / cpuTotal); } /* *---------------------------------------------------------------------- * * GuestInfoMonitorReadMeminfo -- * * Reads /proc/meminfo to gather phsycial memory and huge page stats. * * Results: * Read /proc/meminfo for total physical memory and huge pages info. * Returns FALSE on failure. * * Side effects: * None. * *---------------------------------------------------------------------- */ static Bool GuestInfoMonitorReadMeminfo(GuestMemInfo *vmStats) // OUT: filled vmstats { char buf[512]; uint64 value; FILE *fp; /* Get the total memory, and huge page info from /proc/meminfo. */ fp = fopen("/proc/meminfo", "r"); if (!fp) { Log("GuestInfoMonitorReadMeminfo: Error opening /proc/meminfo.\n"); return FALSE; } while(!feof(fp)) { if (fscanf(fp, "%s %"FMT64"u", buf, &value) != 2) { continue; } if (StrUtil_StartsWith(buf, "MemTotal")) { vmStats->memTotal = value; } if (StrUtil_StartsWith(buf, "HugePages_Total")) { vmStats->hugePagesTotal = value; vmStats->flags |= MEMINFO_HUGEPAGESTOTAL; } if (StrUtil_StartsWith(buf, "HugePages_Free")) { vmStats->hugePagesFree = value; vmStats->flags |= MEMINFO_HUGEPAGESFREE; } } fclose(fp); return TRUE; } #endif open-vm-tools-9.4.0-1280544/services/plugins/guestInfo/COPYING0000644765153500003110000006347112220061556021754 0ustar dtormts GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! open-vm-tools-9.4.0-1280544/services/plugins/guestInfo/Makefile.am0000644765153500003110000000273612220061556022752 0ustar dtormts################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ SUBDIRS = SUBDIRS += getlib plugindir = @VMSVC_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libguestInfo.la libguestInfo_la_CPPFLAGS = libguestInfo_la_CPPFLAGS += @PLUGIN_CPPFLAGS@ libguestInfo_la_LDFLAGS = libguestInfo_la_LDFLAGS += @PLUGIN_LDFLAGS@ libguestInfo_la_LIBADD = libguestInfo_la_LIBADD += @VMTOOLS_LIBS@ libguestInfo_la_LIBADD += @PROCPS_LIBS@ libguestInfo_la_LIBADD += @XDR_LIBS@ libguestInfo_la_LIBADD += getlib/libGuestInfo.la if HAVE_DNET libguestInfo_la_LIBADD += @DNET_LIBS@ endif libguestInfo_la_SOURCES = libguestInfo_la_SOURCES += guestInfoServer.c libguestInfo_la_SOURCES += perfMonLinux.c open-vm-tools-9.4.0-1280544/services/plugins/guestInfo/Makefile.in0000644765153500003110000007012112220061624022750 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @HAVE_DNET_TRUE@am__append_1 = @DNET_LIBS@ subdir = services/plugins/guestInfo DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(plugin_LTLIBRARIES) am__DEPENDENCIES_1 = libguestInfo_la_DEPENDENCIES = getlib/libGuestInfo.la \ $(am__DEPENDENCIES_1) am_libguestInfo_la_OBJECTS = libguestInfo_la-guestInfoServer.lo \ libguestInfo_la-perfMonLinux.lo libguestInfo_la_OBJECTS = $(am_libguestInfo_la_OBJECTS) libguestInfo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libguestInfo_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libguestInfo_la_SOURCES) DIST_SOURCES = $(libguestInfo_la_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = getlib plugindir = @VMSVC_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libguestInfo.la libguestInfo_la_CPPFLAGS = @PLUGIN_CPPFLAGS@ libguestInfo_la_LDFLAGS = @PLUGIN_LDFLAGS@ libguestInfo_la_LIBADD = @VMTOOLS_LIBS@ @PROCPS_LIBS@ @XDR_LIBS@ \ getlib/libGuestInfo.la $(am__append_1) libguestInfo_la_SOURCES = guestInfoServer.c perfMonLinux.c all: all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu services/plugins/guestInfo/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu services/plugins/guestInfo/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ } uninstall-pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ done clean-pluginLTLIBRARIES: -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) @list='$(plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libguestInfo.la: $(libguestInfo_la_OBJECTS) $(libguestInfo_la_DEPENDENCIES) $(EXTRA_libguestInfo_la_DEPENDENCIES) $(libguestInfo_la_LINK) -rpath $(plugindir) $(libguestInfo_la_OBJECTS) $(libguestInfo_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libguestInfo_la-guestInfoServer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libguestInfo_la-perfMonLinux.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libguestInfo_la-guestInfoServer.lo: guestInfoServer.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libguestInfo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libguestInfo_la-guestInfoServer.lo -MD -MP -MF $(DEPDIR)/libguestInfo_la-guestInfoServer.Tpo -c -o libguestInfo_la-guestInfoServer.lo `test -f 'guestInfoServer.c' || echo '$(srcdir)/'`guestInfoServer.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libguestInfo_la-guestInfoServer.Tpo $(DEPDIR)/libguestInfo_la-guestInfoServer.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='guestInfoServer.c' object='libguestInfo_la-guestInfoServer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libguestInfo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libguestInfo_la-guestInfoServer.lo `test -f 'guestInfoServer.c' || echo '$(srcdir)/'`guestInfoServer.c libguestInfo_la-perfMonLinux.lo: perfMonLinux.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libguestInfo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libguestInfo_la-perfMonLinux.lo -MD -MP -MF $(DEPDIR)/libguestInfo_la-perfMonLinux.Tpo -c -o libguestInfo_la-perfMonLinux.lo `test -f 'perfMonLinux.c' || echo '$(srcdir)/'`perfMonLinux.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libguestInfo_la-perfMonLinux.Tpo $(DEPDIR)/libguestInfo_la-perfMonLinux.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='perfMonLinux.c' object='libguestInfo_la-perfMonLinux.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libguestInfo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libguestInfo_la-perfMonLinux.lo `test -f 'perfMonLinux.c' || echo '$(srcdir)/'`perfMonLinux.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done cscopelist-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) cscopelist); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(LTLIBRARIES) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(plugindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-pluginLTLIBRARIES install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-pluginLTLIBRARIES .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) \ cscopelist-recursive ctags-recursive install-am install-strip \ tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ clean-pluginLTLIBRARIES cscopelist cscopelist-recursive ctags \ ctags-recursive distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-pluginLTLIBRARIES install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am uninstall-pluginLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/services/plugins/dndcp/0000755765153500003110000000000012220061624020027 5ustar dtormtsopen-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndFileList.hh0000644765153500003110000000512412220061556022557 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * dndFileList.hh * * Translates filelists to different formats. */ #ifndef DND_FILELIST_HH #define DND_FILELIST_HH #include #include extern "C" { #include "vm_basic_types.h" #include "dndClipboard.h" #include "dynbuf.h" } class DnDFileList { public: DnDFileList(); ~DnDFileList() {}; void SetFileSize(uint64 fsize); uint64 GetFileSize() const; void AddFile(const std::string fullPath, const std::string relPath); void AddFileUri(const std::string uriPath); void AddFiles(const std::vector fullPathList, const std::vector relPathList); void AddFileAttributes(const CPFileAttributes& attributes); /* Copy paste/dndV2 V2 rpc */ void SetRelPathsStr(const std::string inpath); /* DnDFileTransfer & V2 RPC */ std::string GetRelPathsStr() const; std::string GetFullPathsStr(bool local) const; std::string GetUriPathsStr() const; /* UI Local clipboard */ std::vector GetRelPaths() const; std::vector GetFileAttributes() const; /* CPClipboard */ bool ToCPClipboard(DynBuf *out, bool local) const; bool ToUriClipboard(DynBuf *out) const; bool AttributesToCPClipboard(DynBuf *out) const; bool FromCPClipboard(const void *buf, size_t len); bool AttributesFromCPClipboard(const void *buf, size_t len); void Clear(); private: std::vector mRelPaths; std::vector mFullPaths; std::vector mUriPaths; std::vector mAttributeList; std::string mFullPathsBinary; uint64 mFileSize; }; #endif // DND_FILELIST_HH open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dragDetWndX11.h0000644765153500003110000000356112220061556022526 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file dragDetWnd.h * * Header for the DragDetWnd class. */ #ifndef DRAG_DET_WND_H #define DRAG_DET_WND_H #include #if !defined(DETWNDTEST) extern "C" { #include "dnd.h" } #endif class DnDUI; class DragDetWnd : public Gtk::Invisible { public: DragDetWnd(); virtual ~DragDetWnd(); void Show(); void Hide(); void Raise(); void Lower(); int GetScreenWidth(); int GetScreenHeight(); void SetGeometry(const int x, const int y, const int width, const int height); void GetGeometry(int &x, int &y, int &width, int &height); void SetIsVisible(const bool isVisible) {m_isVisible = isVisible;}; bool GetIsVisible() {return m_isVisible;}; #if defined(DETWNDEBUG) void DebugSetAttributes(); #endif private: void Flush(); bool m_isVisible; }; #if defined(DETWNDTEST) class DragDetWndTest : public Gtk::Window { public: void CreateTestUI(); private: virtual void RunUnitTests(); Gtk::Button m_button; }; #endif #endif // DRAG_DET_WND_H open-vm-tools-9.4.0-1280544/services/plugins/dndcp/copyPasteDnDX11.h0000644765153500003110000000402012220061556023027 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file copyPasteDnDX11.h * * This class provides the concrete UI implementation for the DnD and * copy paste abstraction, for the X11 platform. */ #ifndef __COPYPASTEDNDX11_H__ #define __COPYPASTEDNDX11_H__ extern "C" { #include "dnd.h" /* for DnDBlockControl */ } #include "copyPasteUIX11.h" #include "dndUIX11.h" #include #include "vm_basic_types.h" #include "copyPasteDnDImpl.h" extern "C" { void CopyPasteDnDWrapper_SetUnityMode(Bool mode); } class CopyPasteDnDX11 : public CopyPasteDnDImpl { public: CopyPasteDnDX11(); ~CopyPasteDnDX11(); virtual gboolean Init(ToolsAppCtx *ctx); virtual void PointerInit(); virtual gboolean RegisterCP(); virtual void UnregisterCP(); virtual gboolean RegisterDnD(); virtual void UnregisterDnD(); virtual void DnDVersionChanged(int version); virtual void CopyPasteVersionChanged(int version); virtual uint32 GetCaps(); void SetUnityMode(Bool mode) {m_dndUI->SetUnityMode(mode);}; void SetDnDAllowed(bool allowed); void SetCopyPasteAllowed(bool allowed); private: Gtk::Main *m_main; CopyPasteUIX11 *m_copyPasteUI; DnDUIX11 *m_dndUI; }; #endif // __COPYPASTEDNDX11_H__ open-vm-tools-9.4.0-1280544/services/plugins/dndcp/copyPasteDnDX11.cpp0000644765153500003110000002511212220061556023367 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file copyPasteDnDX11.cpp * * Implementation class for DnD and copy paste on X11 platform. */ #define G_LOG_DOMAIN "dndcp" #include "copyPasteDnDWrapper.h" #include "copyPasteDnDX11.h" #include "dndPluginIntX11.h" Window gXRoot; Display *gXDisplay; GtkWidget *gUserMainWidget; extern "C" { #include "copyPasteCompat.h" #include "vmware/tools/plugin.h" void CopyPaste_Register(GtkWidget *mainWnd, ToolsAppCtx *ctx); void CopyPaste_Unregister(GtkWidget *mainWnd); } #include "pointer.h" /** * * BlockingService - a singleton class responsible for initializing and * cleaning up blocking state (vmblock). */ class BlockService { public: static BlockService *GetInstance(); void Init(ToolsAppCtx *); DnDBlockControl *GetBlockCtrl() { return &m_blockCtrl; } private: BlockService(); ~BlockService(); void Shutdown(); static gboolean ShutdownSignalHandler(const siginfo_t *, gpointer); GSource *m_shutdownSrc; DnDBlockControl m_blockCtrl; bool m_initialized; static BlockService *m_instance; }; BlockService *BlockService::m_instance = 0; /** * * Constructor. */ BlockService::BlockService() : m_shutdownSrc(0), m_initialized(false) { memset(&m_blockCtrl, 0, sizeof m_blockCtrl); m_blockCtrl.fd = -1; } /** * * Get an instance of BlockService, which is an application singleton. * * @return a pointer to the singleton BlockService object, or NULL if * for some reason it could not be allocated. */ BlockService * BlockService::GetInstance() { g_debug("%s: enter\n", __FUNCTION__); if (!m_instance) { m_instance = new BlockService(); } ASSERT(m_instance); return m_instance; } /** * * Initialize blocking subsystem so that GTK+ DnD operations won't * time out. Also install SIGUSR1 handler so we can disconnect from * blcoing subsystem upon request. * * @param[in] ctx tools app context. */ void BlockService::Init(ToolsAppCtx *ctx) { g_debug("%s: enter\n", __FUNCTION__); if (!m_initialized && ctx) { m_blockCtrl.fd = ctx->blockFD; m_blockCtrl.fd >= 0 ? DnD_CompleteBlockInitialization(m_blockCtrl.fd, &m_blockCtrl) : DnD_InitializeBlocking(&m_blockCtrl); m_shutdownSrc = VMTools_NewSignalSource(SIGUSR1); VMTOOLSAPP_ATTACH_SOURCE(ctx, m_shutdownSrc, ShutdownSignalHandler, ctx, NULL); m_initialized = true; } } /** * * Signal handler called when we receive SIGUSR1 which is a hint for us * to disconnect from blocking subsystem so that it can be upgraded. * * @param[in] siginfo unused. * @param[in] data unused. * * @return always TRUE. */ gboolean BlockService::ShutdownSignalHandler(const siginfo_t *siginfo, gpointer data) { g_debug("%s: enter\n", __FUNCTION__); GetInstance()->Shutdown(); return FALSE; } /** * * Shut down blocking susbsystem so that we can perform upgrade. */ void BlockService::Shutdown() { g_debug("%s: enter\n", __FUNCTION__); if (m_initialized) { g_source_destroy(m_shutdownSrc); g_source_unref(m_shutdownSrc); m_shutdownSrc = 0; if (DnD_BlockIsReady(&m_blockCtrl)) { DnD_UninitializeBlocking(&m_blockCtrl); } m_initialized = false; } } /** * * Constructor. */ CopyPasteDnDX11::CopyPasteDnDX11() : m_copyPasteUI(NULL), m_dndUI(NULL) { } /** * * Initialize Win32 platform DnD/CP. Initialize Gtk+, and create detection * windows. * * @param[in] ctx tools app context. */ gboolean CopyPasteDnDX11::Init(ToolsAppCtx *ctx) { g_debug("%s: enter\n", __FUNCTION__); CopyPasteDnDWrapper *wrapper = CopyPasteDnDWrapper::GetInstance(); ASSERT(ctx); int argc = 1; char *argv[] = {"", NULL}; m_main = new Gtk::Main(&argc, (char ***) &argv, false); if (wrapper) { BlockService::GetInstance()->Init(ctx); } gUserMainWidget = gtk_invisible_new(); gXDisplay = GDK_WINDOW_XDISPLAY(gUserMainWidget->window); gXRoot = RootWindow(gXDisplay, DefaultScreen(gXDisplay)); /* * Register legacy (backdoor) version of copy paste. */ CopyPaste_SetVersion(1); CopyPaste_Register(gUserMainWidget, ctx); return TRUE; } /** * * Destructor. */ CopyPasteDnDX11::~CopyPasteDnDX11() { if (m_copyPasteUI) { delete m_copyPasteUI; } if (m_dndUI) { delete m_dndUI; } if (m_main) { delete m_main; } /* * Legacy CP. */ CopyPaste_Unregister(gUserMainWidget); if (gUserMainWidget) { gtk_widget_destroy(gUserMainWidget); } } /** * * Register copy and paste capabilities with the VMX. * * @return TRUE on success, FALSE on failure */ gboolean CopyPasteDnDX11::RegisterCP() { g_debug("%s: enter\n", __FUNCTION__); CopyPasteDnDWrapper *wrapper = CopyPasteDnDWrapper::GetInstance(); if (wrapper->IsCPRegistered()) { return TRUE; } if (!wrapper->IsCPEnabled()) { return FALSE; } m_copyPasteUI = new CopyPasteUIX11(); if (m_copyPasteUI) { if (m_copyPasteUI->Init()) { BlockService *bs = BlockService::GetInstance(); m_copyPasteUI->SetBlockControl(bs->GetBlockCtrl()); wrapper->SetCPIsRegistered(TRUE); int version = wrapper->GetCPVersion(); g_debug("%s: version is %d\n", __FUNCTION__, version); if (version >= 3) { CopyPasteVersionChanged(version); m_copyPasteUI->SetCopyPasteAllowed(TRUE); } /* * Set legacy copy/paste version. */ CopyPaste_SetVersion(version); } else { delete m_copyPasteUI; m_copyPasteUI = NULL; } } return wrapper->IsCPRegistered(); } /** * * Register DnD capabilities with the VMX. * * @return TRUE on success, FALSE on failure */ gboolean CopyPasteDnDX11::RegisterDnD() { g_debug("%s: enter\n", __FUNCTION__); CopyPasteDnDWrapper *wrapper = CopyPasteDnDWrapper::GetInstance(); if (!wrapper->IsDnDEnabled()) { return FALSE; } if (!wrapper->IsDnDRegistered()) { m_dndUI = new DnDUIX11(wrapper->GetToolsAppCtx()); if (m_dndUI) { BlockService *bs = BlockService::GetInstance(); m_dndUI->SetBlockControl(bs->GetBlockCtrl()); if (m_dndUI->Init()) { wrapper->SetDnDIsRegistered(TRUE); m_dndUI->SetDnDAllowed(TRUE); int version = wrapper->GetDnDVersion(); g_debug("%s: dnd version is %d\n", __FUNCTION__, version); if (version >= 3) { DnDVersionChanged(version); } } else { delete m_dndUI; m_dndUI = NULL; } } } g_debug("%s: dnd is registered? %d\n", __FUNCTION__, (int) wrapper->IsDnDRegistered()); return wrapper->IsDnDRegistered(); } /** * * Unregister copy paste capabilities and do general cleanup. */ void CopyPasteDnDX11::UnregisterCP() { g_debug("%s: enter\n", __FUNCTION__); CopyPasteDnDWrapper *wrapper = CopyPasteDnDWrapper::GetInstance(); if (wrapper->IsCPRegistered()) { if (m_copyPasteUI) { delete m_copyPasteUI; m_copyPasteUI = NULL; } wrapper->SetCPIsRegistered(FALSE); wrapper->SetCPVersion(-1); } } /** * * Unregister DnD capabilities and do general cleanup. */ void CopyPasteDnDX11::UnregisterDnD() { g_debug("%s: enter\n", __FUNCTION__); CopyPasteDnDWrapper *wrapper = CopyPasteDnDWrapper::GetInstance(); if (wrapper->IsDnDRegistered()) { if (m_dndUI) { delete m_dndUI; m_dndUI = NULL; } wrapper->SetDnDIsRegistered(false); wrapper->SetDnDVersion(-1); return; } } /** * * Communicate dnd allowed to platform implementation. * * @param[allowed] if TRUE, dnd allowed. */ void CopyPasteDnDX11::SetDnDAllowed(bool allowed) { ASSERT(m_dndUI); g_debug("%s: enter\n", __FUNCTION__); m_dndUI->SetDnDAllowed(allowed); } /** * * Communicate copypaste allowed to platform implementation. * * @param[allowed] if TRUE, copy paste allowed. */ void CopyPasteDnDX11::SetCopyPasteAllowed(bool allowed) { ASSERT(m_copyPasteUI); g_debug("%s: enter\n", __FUNCTION__); m_copyPasteUI->SetCopyPasteAllowed(allowed); } /** * Communicate copy paste version change to the platform implementation. * * @param[in] version the new version */ void CopyPasteDnDX11::CopyPasteVersionChanged(int version) { g_debug("%s: enter\n", __FUNCTION__); CopyPasteDnDWrapper *wrapper = CopyPasteDnDWrapper::GetInstance(); ToolsAppCtx *ctx = wrapper->GetToolsAppCtx(); g_debug("%s: calling VmxCopyPasteVersionChanged (version %d)\n", __FUNCTION__, version); if (ctx) { m_copyPasteUI->VmxCopyPasteVersionChanged(ctx->rpc, version); } } /** * Communicate DnD version change by calling the platform implementation. * * @param[in] version the new version. */ void CopyPasteDnDX11::DnDVersionChanged(int version) { g_debug("%s: enter\n", __FUNCTION__); CopyPasteDnDWrapper *wrapper = CopyPasteDnDWrapper::GetInstance(); ToolsAppCtx *ctx = wrapper->GetToolsAppCtx(); g_debug("%s: calling VmxDnDVersionChanged (version %d)\n", __FUNCTION__, version); ASSERT(ctx); ASSERT(m_dndUI); m_dndUI->VmxDnDVersionChanged(ctx->rpc, version); } /** * * Initialize pointer code. */ void CopyPasteDnDX11::PointerInit() { g_debug("%s: enter\n", __FUNCTION__); CopyPasteDnDWrapper *wrapper = CopyPasteDnDWrapper::GetInstance(); ASSERT(wrapper); ToolsAppCtx *ctx = wrapper->GetToolsAppCtx(); ASSERT(ctx); Pointer_Init(ctx); } /** * Return platform DnD/CP caps. * * @return 32-bit caps vector. */ uint32 CopyPasteDnDX11::GetCaps() { return DND_CP_CAP_VALID | DND_CP_CAP_DND | DND_CP_CAP_CP | DND_CP_CAP_FORMATS_ALL | DND_CP_CAP_ACTIVE_CP | DND_CP_CAP_BIG_BUFFER; } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/pointer.h0000644765153500003110000000176112220061556021671 0ustar dtormts/********************************************************* * Copyright (C) 1999 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * pointer.h -- * * Commands for pointer control. */ #include "vmware/tools/plugin.h" void Pointer_Init(ToolsAppCtx *ctx); open-vm-tools-9.4.0-1280544/services/plugins/dndcp/copyPasteCompat.h0000644765153500003110000000303712220061556023322 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * copyPasteCompat.h -- * * copyPaste header file. * */ #if !defined _COPYPASTE_COMPAT_H #define _COPYPASTE_COMPAT_H #include "vmware.h" /* Functions to be compatible with old text copy/paste directly based on backdoor cmd. */ Bool CopyPaste_RequestSelection(void); Bool CopyPaste_GetBackdoorSelections(void); Bool CopyPaste_IsRpcCPSupported(void); void CopyPaste_Init(void); void CopyPaste_SetVersion(int version); int32 CopyPaste_GetHostSelectionLen(void); void CopyPaste_GetHostSelection(unsigned int size, // IN char *data); // OUT void CopyPaste_SetSelLength(uint32 length); // IN void CopyPaste_SetNextPiece(uint32 data); // IN #endif open-vm-tools-9.4.0-1280544/services/plugins/dndcp/copyPasteCompatX11.c0000644765153500003110000006444312220061556023617 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * copyPasteCompatX11.c -- * * Set of functions in guest side for copy/paste (both file and text). * Currently there are 2 versions copy/paste. Version 1 only supports * text copy/paste, and based on backdoor cmd. Version 2 supports both * text and file copy/paste, and based on guestRPC. * * G->H Text Copy/Paste (version 1) * -------------------- * When Ungrab, CopyPaste_RequestSelection got called, which try to get * selection text and send to backdoor. * * H->G Text Copy/Paste (version 1) * -------------------- * When grab, CopyPaste_GetBackdoorSelections got called, which first * get host selection text, then claim as selection owner. If some app * asks for selection, CopyPasteSelectionGetCB will reply with host * selection text. */ #include "dndPluginIntX11.h" #include #include #include #include #include #include "vm_assert.h" #include "copyPasteCompat.h" #include "str.h" #include "strutil.h" #include "dnd.h" #include "util.h" #include "cpName.h" #include "cpNameUtil.h" #include "vmblock.h" #include "file.h" #include "codeset.h" #include "escape.h" #include "hostinfo.h" #include "wiper.h" #include "vmware/guestrpc/tclodefs.h" #include "vmware/tools/plugin.h" /* * Gtk 1.2 doesn't know about the CLIPBOARD selection, but that doesn't matter, we * just create the atom we need directly in main(). */ #ifndef GDK_SELECTION_CLIPBOARD GdkAtom GDK_SELECTION_CLIPBOARD; #endif #ifndef GDK_SELECTION_TYPE_TIMESTAMP GdkAtom GDK_SELECTION_TYPE_TIMESTAMP; #endif #ifndef GDK_SELECTION_TYPE_UTF8_STRING GdkAtom GDK_SELECTION_TYPE_UTF8_STRING; #endif /* * Currently there are 2 versions copy/paste. * Key points in copy/paste version 1: * 1. Only text copy/paste * 2. copy/paste is based on backdoor directly * * Key points in copy/paste version 2: * 1. Support both file/text copy/paste * 2. Both file/text copy/paste are based on guestRPC */ static int32 gVmxCopyPasteVersion = 1; /* * Getting a selection is an asyncronous event, so we have to keep track of both * selections globablly in order to decide which one to use. */ static Bool gWaitingOnGuestSelection = FALSE; static char gGuestSelPrimaryBuf[MAX_SELECTION_BUFFER_LENGTH]; static char gGuestSelClipboardBuf[MAX_SELECTION_BUFFER_LENGTH]; static uint64 gGuestSelPrimaryTime = 0; static uint64 gGuestSelClipboardTime = 0; static char gHostClipboardBuf[MAX_SELECTION_BUFFER_LENGTH + 1]; static Bool gIsOwner; static ToolsAppCtx *gCtx = NULL; /* * Forward Declarations */ static gboolean IsCtxMainLoopActive(void); static INLINE void CopyPasteStateInit(void); static void CopyPasteSelectionReceivedCB(GtkWidget *widget, GtkSelectionData *selection_data, gpointer data); static void CopyPasteSelectionGetCB(GtkWidget *widget, GtkSelectionData *selection_data, guint info, guint time_stamp, gpointer data); static gint CopyPasteSelectionClearCB(GtkWidget *widget, GdkEventSelection *event, gpointer data); static void CopyPasteSetBackdoorSelections(void); /* This struct is only used by CopyPasteSelectionRemoveTarget. */ struct SelectionTargetList { GdkAtom selection; GtkTargetList *list; }; /* *----------------------------------------------------------------------------- * * CopyPasteSelectionRemoveTarget -- * * To remove a target from a selection target list. The reason to develop * this function is that in gtk there is only gtk_selection_add_target to * add supported target to selection list, but no function to remove one. * * Results: * None. * * Side effects: * If no more target, the selection list will be removed too. * *----------------------------------------------------------------------------- */ void CopyPasteSelectionRemoveTarget(GtkWidget *widget, GdkAtom selection, GdkAtom target) { const char *selection_handler_key = "gtk-selection-handlers"; struct SelectionTargetList *targetList; GList *tempList; GList *selectionLists; /* Get selection list. */ selectionLists = gtk_object_get_data(GTK_OBJECT (widget), selection_handler_key); tempList = selectionLists; while (tempList) { /* Enumerate the list to find the selection. */ targetList = tempList->data; if (targetList->selection == selection) { /* Remove target. */ gtk_target_list_remove(targetList->list, target); /* If no more target, remove selection from list. */ if (!targetList->list->list) { /* Free target list. */ gtk_target_list_unref(targetList->list); g_free(targetList); /* Remove and free selection node. */ selectionLists = g_list_remove_link(selectionLists, tempList); g_list_free_1(tempList); } break; } tempList = tempList->next; } /* Put new selection list back. */ gtk_object_set_data (GTK_OBJECT (widget), selection_handler_key, selectionLists); } /* *----------------------------------------------------------------------------- * * CopyPaste_RequestSelection -- * * Request the guest's text clipboard (asynchronously), we'll give it to * the host when the request completes. For version 1 guest->host text * copy/paste. * * Results: * TRUE on success, FALSE otherwise. * * Side effects: * The owner of the clipboard will get a request from our application. * *----------------------------------------------------------------------------- */ Bool CopyPaste_RequestSelection(void) { if (gVmxCopyPasteVersion > 1) { return FALSE; } /* * Ask for both the PRIMARY and CLIPBOARD selections. */ gGuestSelPrimaryBuf[0] = '\0'; gGuestSelClipboardBuf[0] = '\0'; /* Only send out request if we are not the owner. */ if (!gIsOwner) { /* Try to get timestamp for primary and clipboard. */ gWaitingOnGuestSelection = TRUE; gtk_selection_convert(gUserMainWidget, GDK_SELECTION_PRIMARY, GDK_SELECTION_TYPE_TIMESTAMP, GDK_CURRENT_TIME); while (IsCtxMainLoopActive() && gWaitingOnGuestSelection) { gtk_main_iteration(); } gWaitingOnGuestSelection = TRUE; gtk_selection_convert(gUserMainWidget, GDK_SELECTION_CLIPBOARD, GDK_SELECTION_TYPE_TIMESTAMP, GDK_CURRENT_TIME); while (IsCtxMainLoopActive() && gWaitingOnGuestSelection) { gtk_main_iteration(); } /* Try to get utf8 text from primary and clipboard. */ gWaitingOnGuestSelection = TRUE; gtk_selection_convert(gUserMainWidget, GDK_SELECTION_PRIMARY, GDK_SELECTION_TYPE_UTF8_STRING, GDK_CURRENT_TIME); while (IsCtxMainLoopActive() && gWaitingOnGuestSelection) { gtk_main_iteration(); } gWaitingOnGuestSelection = TRUE; gtk_selection_convert(gUserMainWidget, GDK_SELECTION_CLIPBOARD, GDK_SELECTION_TYPE_UTF8_STRING, GDK_CURRENT_TIME); while (IsCtxMainLoopActive() && gWaitingOnGuestSelection) { gtk_main_iteration(); } if (gGuestSelPrimaryBuf[0] == '\0' && gGuestSelClipboardBuf[0] == '\0') { /* * If we cannot get utf8 text, try to get localized text from primary * and clipboard. */ gWaitingOnGuestSelection = TRUE; gtk_selection_convert(gUserMainWidget, GDK_SELECTION_PRIMARY, GDK_SELECTION_TYPE_STRING, GDK_CURRENT_TIME); while (IsCtxMainLoopActive() && gWaitingOnGuestSelection) { gtk_main_iteration(); } gWaitingOnGuestSelection = TRUE; gtk_selection_convert(gUserMainWidget, GDK_SELECTION_CLIPBOARD, GDK_SELECTION_TYPE_STRING, GDK_CURRENT_TIME); while (IsCtxMainLoopActive() && gWaitingOnGuestSelection) { gtk_main_iteration(); } } } /* Send text to host. */ g_debug("CopyPaste_RequestSelection: Prim is [%s], Clip is [%s]\n", gGuestSelPrimaryBuf, gGuestSelClipboardBuf); CopyPasteSetBackdoorSelections(); return TRUE; } /** * Check to see if we are running in tools main loop. * * @return TRUE if we are, FALSE if we are not running in main loop. */ static gboolean IsCtxMainLoopActive(void) { ASSERT(gCtx); return g_main_loop_is_running(gCtx->mainLoop); } /* *----------------------------------------------------------------------------- * * CopyPasteSelectionReceivedCB -- * * Callback for the gtk signal "selection_received". * Called because we previously requested a copy/paste selection and * finally got results of that asynchronous operation. After some basic * sanity checks, send the result (in selection_data) thru the backdoor * (version 1) or guestRPC (version 2) so the vmx can copy it to host * clipboard. * * We made several requests for selections, the string (actual data) and * file list for each of PRIMARY and CLIPBOARD selections. So this funtion * will get called several times, once for each request. * * For guest->host copy/paste (both text and file). * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void CopyPasteSelectionReceivedCB(GtkWidget *widget, // IN: unused GtkSelectionData *selection_data, // IN: requested data gpointer data) // IN: unused { char *target; char *utf8Str = NULL; size_t len; size_t aligned_len; if ((widget == NULL) || (selection_data == NULL)) { g_debug("CopyPasteSelectionReceivedCB: Error, widget or selection_data is invalid\n"); goto exit; } if (selection_data->length < 0) { g_debug("CopyPasteSelectionReceivedCB: Error, length less than 0\n"); goto exit; } /* Try to get clipboard or selection timestamp. */ if (selection_data->target == GDK_SELECTION_TYPE_TIMESTAMP) { if (selection_data->selection == GDK_SELECTION_PRIMARY) { if (selection_data->length == 4) { gGuestSelPrimaryTime = *(uint32 *)selection_data->data; g_debug("CopyPasteSelectionReceivedCB: Got pri time [%"FMT64"u]\n", gGuestSelPrimaryTime); } else if (selection_data->length == 8) { gGuestSelPrimaryTime = *(uint64 *)selection_data->data; g_debug("CopyPasteSelectionReceivedCB: Got pri time [%"FMT64"u]\n", gGuestSelPrimaryTime); } else { g_debug("CopyPasteSelectionReceivedCB: Unknown pri time. Size %d\n", selection_data->length); } } if (selection_data->selection == GDK_SELECTION_CLIPBOARD) { if (selection_data->length == 4) { gGuestSelClipboardTime = *(uint32 *)selection_data->data; g_debug("CopyPasteSelectionReceivedCB: Got clip time [%"FMT64"u]\n", gGuestSelClipboardTime); } else if (selection_data->length == 8) { gGuestSelClipboardTime = *(uint64 *)selection_data->data; g_debug("CopyPasteSelectionReceivedCB: Got clip time [%"FMT64"u]\n", gGuestSelClipboardTime); } else { g_debug("CopyPasteSelectionReceivedCB: Unknown clip time. Size %d\n", selection_data->length); } } goto exit; } if (selection_data->selection == GDK_SELECTION_PRIMARY) { target = gGuestSelPrimaryBuf; } else if (selection_data->selection == GDK_SELECTION_CLIPBOARD) { target = gGuestSelClipboardBuf; } else { goto exit; } utf8Str = selection_data->data; len = strlen(selection_data->data); if (selection_data->target != GDK_SELECTION_TYPE_STRING && selection_data->target != GDK_SELECTION_TYPE_UTF8_STRING) { /* It is a file list. */ if (len >= MAX_SELECTION_BUFFER_LENGTH - 1) { Warning("CopyPasteSelectionReceivedCB file list too long\n"); } else { memcpy(target, selection_data->data, len + 1); } goto exit; } /* * If target is GDK_SELECTION_TYPE_STRING, assume encoding is local code * set. Convert to utf8 before send to vmx. */ if (selection_data->target == GDK_SELECTION_TYPE_STRING && !CodeSet_CurrentToUtf8(selection_data->data, selection_data->length, &utf8Str, &len)) { g_debug("CopyPasteSelectionReceivedCB: Couldn't convert to utf8 code set\n"); gWaitingOnGuestSelection = FALSE; return; } /* * String in backdoor communication is 4 bytes by 4 bytes, so the len * should be aligned to 4; */ aligned_len = (len + 4) & ~3; if (aligned_len >= MAX_SELECTION_BUFFER_LENGTH) { /* With alignment, len is still possible to be less than max. */ if (len < (MAX_SELECTION_BUFFER_LENGTH - 1)) { memcpy(target, utf8Str, len + 1); } else { memcpy(target, utf8Str, MAX_SELECTION_BUFFER_LENGTH - 1); target[MAX_SELECTION_BUFFER_LENGTH - 1] ='\0'; } } else { memcpy(target, utf8Str, len + 1); } exit: if (selection_data->target == GDK_SELECTION_TYPE_STRING) { free(utf8Str); } gWaitingOnGuestSelection = FALSE; } /* *----------------------------------------------------------------------------- * * CopyPasteSelectionGetCB -- * * Callback for the gtk signal "selection_get". * This is called when some other app requests the copy/paste selection, * probably because we declare oursleves the selection owner on mouse * grab. In text copy/paste case, we simply respond with contents of * gHostClipboardBuf, which should have been set on mouse grab. In file * copy/paste case, send file transfer request to host vmx, then return * file list with right format according to different request. * For host->guest copy/paste (both text and file). * * Results: * None * * Side effects: * An X message is sent to the requesting app containing the data, it * will likely act on it in some way. In FCP case, may first start a * host->guest file transfer. Add block if blocking driver is available, * otherwise wait till file copy done. * *----------------------------------------------------------------------------- */ void CopyPasteSelectionGetCB(GtkWidget *widget, // IN: unused GtkSelectionData *selection_data, // IN: requested type // OUT:the data to be sent guint info, // IN: unused guint time_stamp, // IN: unsued gpointer data) // IN: unused { if ((widget == NULL) || (selection_data == NULL)) { g_debug("CopyPasteSelectionGetCB: Error, widget or selection_data is invalid\n"); return; } /* If it is text copy paste, return gHostClipboardBuf. */ if (GDK_SELECTION_TYPE_STRING == selection_data->target || GDK_SELECTION_TYPE_UTF8_STRING == selection_data->target) { char *outBuf = gHostClipboardBuf; size_t len = strlen(gHostClipboardBuf); /* * If target is GDK_SELECTION_TYPE_STRING, assume encoding is local code * set. Convert from utf8 to local one. */ if (GDK_SELECTION_TYPE_STRING == selection_data->target && !CodeSet_Utf8ToCurrent(gHostClipboardBuf, strlen(gHostClipboardBuf), &outBuf, &len)) { g_debug("CopyPasteSelectionGetCB: can not convert to current codeset\n"); return; } gtk_selection_data_set(selection_data, selection_data->target, 8, outBuf, len); g_debug("CopyPasteSelectionGetCB: Set text [%s]\n", outBuf); if (GDK_SELECTION_TYPE_STRING == selection_data->target) { free(outBuf); } return; } } /* *----------------------------------------------------------------------------- * * CopyPasteSelectionClearCB -- * * Callback for the gtk signal "selection_clear". * * Results: * Always TRUE. * * Side effects: * None * *----------------------------------------------------------------------------- */ static gint CopyPasteSelectionClearCB(GtkWidget *widget, // IN: unused GdkEventSelection *event, // IN: unused gpointer data) // IN: unused { g_debug("CopyPasteSelectionClearCB got clear signal\n"); gIsOwner = FALSE; return TRUE; } /* *----------------------------------------------------------------------------- * * CopyPasteSetBackdoorSelections -- * * Set the clipboard one of two ways, the old way or the new way. * The old way uses CopyPaste_SetSelLength and there's only one selection. * Set backdoor selection with either primary selection or clipboard. * The primary selection is the first priority, then clipboard. * If both unavailable, set backdoor selection length to be 0. * This will be used by older VMXs or VMXs on Windows hosts (which * has only one clipboard). Doing this gives us backwards * compatibility. * * The new way uses new sets both PRIMARY and CLIPBOARD. Newer Linux * VMXs will use these rather than the above method and have the two * selections set separately. * * XXX: The "new way" doesn't exist yet, the vmx has no support for it. * * Results: * None. * * Side effects: * The VMX probably changes some string buffers. * *----------------------------------------------------------------------------- */ void CopyPasteSetBackdoorSelections(void) { uint32 const *p; size_t len; size_t aligned_len; size_t primaryLen; size_t clipboardLen; unsigned int i; primaryLen = strlen(gGuestSelPrimaryBuf); clipboardLen = strlen(gGuestSelClipboardBuf); if (primaryLen && clipboardLen) { /* Pick latest one if both are available. */ p = gGuestSelPrimaryTime >= gGuestSelClipboardTime ? (uint32 const *)gGuestSelPrimaryBuf : (uint32 const *)gGuestSelClipboardBuf; } else if (primaryLen) { /* * Send primary selection to backdoor if it exists. */ p = (uint32 const *)gGuestSelPrimaryBuf; } else if (clipboardLen) { /* * Otherwise send clipboard to backdoor if it exists. */ p = (uint32 const *)gGuestSelClipboardBuf; } else { /* * Neither selection is set */ p = NULL; } if (p == NULL) { CopyPaste_SetSelLength(0); g_debug("CopyPasteSetBackdoorSelections Set empty text.\n"); } else { len = strlen((char *)p); g_debug("CopyPasteSetBackdoorSelections Set text [%s].\n", (char *)p); aligned_len = (len + 4) & ~3; /* Here long string should already be truncated. */ ASSERT(aligned_len <= MAX_SELECTION_BUFFER_LENGTH); CopyPaste_SetSelLength(len); for (i = 0; i < len; i += 4, p++) { CopyPaste_SetNextPiece(*p); } } } /* *----------------------------------------------------------------------------- * * CopyPaste_GetBackdoorSelections -- * * Get the clipboard "the old way". * The old way uses CopyPaste_GetHostSelectionLen and there's only one * selection. We don't have to do anything for the "new way", since the * host will just push PRIMARY and/or CLIPBOARD when they are available * on the host. * * XXX: the "new way" isn't availble yet because the vmx doesn't * implement separate clipboards. Even when it does this * function will still exist for backward compatibility * * Results: * TRUE if selection length>=0, FALSE otherwise. * * Side effects: * This application becomes the selection owner for PRIMARY and/or CLIPBOARD selections. * *----------------------------------------------------------------------------- */ Bool CopyPaste_GetBackdoorSelections(void) { int selLength; if (gVmxCopyPasteVersion > 1) { return TRUE; } selLength = CopyPaste_GetHostSelectionLen(); if (selLength < 0 || selLength > MAX_SELECTION_BUFFER_LENGTH) { return FALSE; } else if (selLength > 0) { CopyPaste_GetHostSelection(selLength, gHostClipboardBuf); gHostClipboardBuf[selLength] = 0; g_debug("CopyPaste_GetBackdoorSelections Get text [%s].\n", gHostClipboardBuf); gtk_selection_owner_set(gUserMainWidget, GDK_SELECTION_CLIPBOARD, GDK_CURRENT_TIME); gtk_selection_owner_set(gUserMainWidget, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME); gIsOwner = TRUE; } return TRUE; } /* *----------------------------------------------------------------------------- * * CopyPaste_Register -- * * Setup callbacks, initialize. * * Results: * Always TRUE. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CopyPaste_Register(GtkWidget* mainWnd, // IN ToolsAppCtx *ctx) // IN { g_debug("%s: enter\n", __FUNCTION__); ASSERT(mainWnd); ASSERT(ctx); gCtx = ctx; /* Text copy/paste initialization for all versions. */ #ifndef GDK_SELECTION_CLIPBOARD GDK_SELECTION_CLIPBOARD = gdk_atom_intern("CLIPBOARD", FALSE); #endif #ifndef GDK_SELECTION_TYPE_TIMESTAMP GDK_SELECTION_TYPE_TIMESTAMP = gdk_atom_intern("TIMESTAMP", FALSE); #endif #ifndef GDK_SELECTION_TYPE_UTF8_STRING GDK_SELECTION_TYPE_UTF8_STRING = gdk_atom_intern("UTF8_STRING", FALSE); #endif /* * String is always in supported list. FCP atoms will dynamically be * added and removed. */ gtk_selection_add_target(mainWnd, GDK_SELECTION_PRIMARY, GDK_SELECTION_TYPE_STRING, 0); gtk_selection_add_target(mainWnd, GDK_SELECTION_CLIPBOARD, GDK_SELECTION_TYPE_STRING, 0); gtk_selection_add_target(mainWnd, GDK_SELECTION_PRIMARY, GDK_SELECTION_TYPE_UTF8_STRING, 0); gtk_selection_add_target(mainWnd, GDK_SELECTION_CLIPBOARD, GDK_SELECTION_TYPE_UTF8_STRING, 0); gtk_signal_connect(GTK_OBJECT(mainWnd), "selection_received", GTK_SIGNAL_FUNC(CopyPasteSelectionReceivedCB), mainWnd); gtk_signal_connect(GTK_OBJECT(mainWnd), "selection_get", GTK_SIGNAL_FUNC(CopyPasteSelectionGetCB), mainWnd); gtk_signal_connect(GTK_OBJECT(mainWnd), "selection_clear_event", GTK_SIGNAL_FUNC(CopyPasteSelectionClearCB), mainWnd); CopyPasteStateInit(); return TRUE; } /* *----------------------------------------------------------------------------- * * CopyPaste_Unregister -- * * Cleanup copy/paste related things. * * Results: * None. * * Side effects: * copy/paste is stopped, the rpc channel to the vmx is closed. * *----------------------------------------------------------------------------- */ void CopyPaste_Unregister(GtkWidget* mainWnd) { g_debug("%s: enter\n", __FUNCTION__); gtk_signal_disconnect_by_func(GTK_OBJECT(mainWnd), GTK_SIGNAL_FUNC(CopyPasteSelectionReceivedCB), mainWnd); gtk_signal_disconnect_by_func(GTK_OBJECT(mainWnd), GTK_SIGNAL_FUNC(CopyPasteSelectionGetCB), mainWnd); gtk_signal_disconnect_by_func(GTK_OBJECT(mainWnd), GTK_SIGNAL_FUNC(CopyPasteSelectionClearCB), mainWnd); } /* *---------------------------------------------------------------------------- * * CopyPaste_IsRpcCPSupported -- * * Check if RPC copy/paste is supported by vmx or not. * * Results: * FALSE always. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool CopyPaste_IsRpcCPSupported(void) { return gVmxCopyPasteVersion > 1; } /* *---------------------------------------------------------------------------- * * CopyPasteStateInit -- * * Initalialize CopyPaste State. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void CopyPasteStateInit(void) { g_debug("%s: enter\n", __FUNCTION__); gHostClipboardBuf[0] = '\0'; gGuestSelPrimaryBuf[0] = '\0'; gGuestSelClipboardBuf[0] = '\0'; gIsOwner = FALSE; } /** * Set the copy paste version. * * @param[in] version version to set. */ void CopyPaste_SetVersion(int version) { g_debug("%s: enter version %d\n", __FUNCTION__, version); gVmxCopyPasteVersion = version; } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndUIX11.cpp0000644765153500003110000020135712220061556022044 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file dndUIX11.cpp -- * * This class implements stubs for the methods that allow DnD between * host and guest. */ #define G_LOG_DOMAIN "dndcp" #include "dndUIX11.h" #include "guestDnDCPMgr.hh" extern "C" { #include "vmblock.h" #include "file.h" #include "copyPasteCompat.h" #include "dnd.h" #include "dndMsg.h" #include "dndClipboard.h" #include "cpName.h" #include "cpNameUtil.h" #include "hostinfo.h" #include "rpcout.h" #include #include #include /* for XTest*() */ #include "vmware/guestrpc/tclodefs.h" } /* IsXExtensionPointer may be not defined with old Xorg. */ #ifndef IsXExtensionPointer #define IsXExtensionPointer 4 #endif #include "copyPasteDnDWrapper.h" /** * * Constructor. */ DnDUIX11::DnDUIX11(ToolsAppCtx *ctx) : m_ctx(ctx), m_DnD(NULL), m_detWnd(NULL), m_blockCtrl(NULL), m_HGGetFileStatus(DND_FILE_TRANSFER_NOT_STARTED), m_blockAdded(false), m_GHDnDInProgress(false), m_GHDnDDataReceived(false), m_unityMode(false), m_inHGDrag(false), m_effect(DROP_NONE), m_mousePosX(0), m_mousePosY(0), m_dc(NULL), m_numPendingRequest(0), m_destDropTime(0), mTotalFileSize(0) { g_debug("%s: enter\n", __FUNCTION__); } /** * * Destructor. */ DnDUIX11::~DnDUIX11() { g_debug("%s: enter\n", __FUNCTION__); if (m_detWnd) { delete m_detWnd; } CPClipboard_Destroy(&m_clipboard); /* Any files from last unfinished file transfer should be deleted. */ if (DND_FILE_TRANSFER_IN_PROGRESS == m_HGGetFileStatus && !m_HGStagingDir.empty()) { uint64 totalSize = File_GetSizeEx(m_HGStagingDir.c_str()); if (mTotalFileSize != totalSize) { g_debug("%s: deleting %s, expecting %"FMT64"d, finished %"FMT64"d\n", __FUNCTION__, m_HGStagingDir.c_str(), mTotalFileSize, totalSize); DnD_DeleteStagingFiles(m_HGStagingDir.c_str(), FALSE); } else { g_debug("%s: file size match %s\n", __FUNCTION__, m_HGStagingDir.c_str()); } } CommonResetCB(); } /** * * Initialize DnDUIX11 object. */ bool DnDUIX11::Init() { g_debug("%s: enter\n", __FUNCTION__); bool ret = true; CPClipboard_Init(&m_clipboard); GuestDnDCPMgr *p = GuestDnDCPMgr::GetInstance(); ASSERT(p); m_DnD = p->GetDnDMgr(); ASSERT(m_DnD); m_detWnd = new DragDetWnd(); if (!m_detWnd) { g_debug("%s: unable to allocate DragDetWnd object\n", __FUNCTION__); goto fail; } #if defined(DETWNDDEBUG) /* * This code can only be called when DragDetWnd is derived from * Gtk::Window. The normal case is that DragDetWnd is an instance of * Gtk::Invisible, which doesn't implement the methods that SetAttributes * relies upon. */ m_detWnd->SetAttributes(); #endif SetTargetsAndCallbacks(); /* Set common layer callbacks. */ m_DnD->srcDragBeginChanged.connect( sigc::mem_fun(this, &DnDUIX11::CommonDragStartCB)); m_DnD->srcDropChanged.connect( sigc::mem_fun(this, &DnDUIX11::CommonSourceDropCB)); m_DnD->srcCancelChanged.connect( sigc::mem_fun(this, &DnDUIX11::CommonSourceCancelCB)); m_DnD->getFilesDoneChanged.connect( sigc::mem_fun(this, &DnDUIX11::CommonSourceFileCopyDoneCB)); m_DnD->destCancelChanged.connect( sigc::mem_fun(this, &DnDUIX11::CommonDestCancelCB)); m_DnD->privDropChanged.connect( sigc::mem_fun(this, &DnDUIX11::CommonDestPrivateDropCB)); m_DnD->updateDetWndChanged.connect( sigc::mem_fun(this, &DnDUIX11::CommonUpdateDetWndCB)); m_DnD->moveMouseChanged.connect( sigc::mem_fun(this, &DnDUIX11::CommonUpdateMouseCB)); m_DnD->updateUnityDetWndChanged.connect( sigc::mem_fun(this, &DnDUIX11::CommonUpdateUnityDetWndCB)); m_DnD->destMoveDetWndToMousePosChanged.connect( sigc::mem_fun(this, &DnDUIX11::CommonMoveDetWndToMousePos)); /* Set Gtk+ callbacks for source. */ m_detWnd->signal_drag_begin().connect( sigc::mem_fun(this, &DnDUIX11::GtkSourceDragBeginCB)); m_detWnd->signal_drag_data_get().connect( sigc::mem_fun(this, &DnDUIX11::GtkSourceDragDataGetCB)); m_detWnd->signal_drag_end().connect( sigc::mem_fun(this, &DnDUIX11::GtkSourceDragEndCB)); m_detWnd->signal_enter_notify_event().connect( sigc::mem_fun(this, &DnDUIX11::GtkEnterEventCB)); m_detWnd->signal_leave_notify_event().connect( sigc::mem_fun(this, &DnDUIX11::GtkLeaveEventCB)); m_detWnd->signal_map_event().connect( sigc::mem_fun(this, &DnDUIX11::GtkMapEventCB)); m_detWnd->signal_unmap_event().connect( sigc::mem_fun(this, &DnDUIX11::GtkUnmapEventCB)); m_detWnd->signal_realize().connect( sigc::mem_fun(this, &DnDUIX11::GtkRealizeEventCB)); m_detWnd->signal_unrealize().connect( sigc::mem_fun(this, &DnDUIX11::GtkUnrealizeEventCB)); m_detWnd->signal_motion_notify_event().connect( sigc::mem_fun(this, &DnDUIX11::GtkMotionNotifyEventCB)); m_detWnd->signal_configure_event().connect( sigc::mem_fun(this, &DnDUIX11::GtkConfigureEventCB)); m_detWnd->signal_button_press_event().connect( sigc::mem_fun(this, &DnDUIX11::GtkButtonPressEventCB)); m_detWnd->signal_button_release_event().connect( sigc::mem_fun(this, &DnDUIX11::GtkButtonReleaseEventCB)); CommonUpdateDetWndCB(false, 0, 0); CommonUpdateUnityDetWndCB(false, 0, false); goto out; fail: ret = false; if (m_DnD) { delete m_DnD; m_DnD = NULL; } if (m_detWnd) { delete m_detWnd; m_detWnd = NULL; } out: return ret; } /** * * Setup targets we support, claim ourselves as a drag destination, and * register callbacks for Gtk+ drag and drop callbacks the platform will * send to us. */ void DnDUIX11::SetTargetsAndCallbacks() { g_debug("%s: enter\n", __FUNCTION__); /* Construct supported target list for HG DnD. */ std::list targets; /* File DnD. */ targets.push_back(Gtk::TargetEntry(DRAG_TARGET_NAME_URI_LIST)); /* RTF text DnD. */ targets.push_back(Gtk::TargetEntry(TARGET_NAME_APPLICATION_RTF)); targets.push_back(Gtk::TargetEntry(TARGET_NAME_TEXT_RICHTEXT)); /* Plain text DnD. */ targets.push_back(Gtk::TargetEntry(TARGET_NAME_UTF8_STRING)); targets.push_back(Gtk::TargetEntry(TARGET_NAME_STRING)); targets.push_back(Gtk::TargetEntry(TARGET_NAME_TEXT_PLAIN)); targets.push_back(Gtk::TargetEntry(TARGET_NAME_COMPOUND_TEXT)); /* * We don't want Gtk handling any signals for us, we want to * do it ourselves based on the results from the guest. * * Second argument in drag_dest_set defines the automatic behaviour options * of the destination widget. We used to not define it (0) and in some * distributions (like Ubuntu 6.10) DragMotion only get called once, * and not send updated mouse position to guest, and also got cancel * signal when user drop the file (bug 175754). With flag DEST_DEFAULT_MOTION * the bug is fixed. Almost all other example codes use DEST_DEFAULT_ALL * but in our case, we will call drag_get_data during DragMotion, and * will cause X dead with DEST_DEFAULT_ALL. The reason is unclear. */ m_detWnd->drag_dest_set(targets, Gtk::DEST_DEFAULT_MOTION, Gdk::ACTION_COPY | Gdk::ACTION_MOVE); m_detWnd->signal_drag_leave().connect(sigc::mem_fun(this, &DnDUIX11::GtkDestDragLeaveCB)); m_detWnd->signal_drag_motion().connect(sigc::mem_fun(this, &DnDUIX11::GtkDestDragMotionCB)); m_detWnd->signal_drag_drop().connect(sigc::mem_fun(this, &DnDUIX11::GtkDestDragDropCB)); m_detWnd->signal_drag_data_received().connect(sigc::mem_fun(this, &DnDUIX11::GtkDestDragDataReceivedCB)); } /* Begin of callbacks issued by common layer code */ /** * * Reset Callback to reset dnd ui state. */ void DnDUIX11::CommonResetCB(void) { g_debug("%s: entering\n", __FUNCTION__); m_GHDnDDataReceived = false; m_HGGetFileStatus = DND_FILE_TRANSFER_NOT_STARTED; m_GHDnDInProgress = false; m_effect = DROP_NONE; m_inHGDrag = false; m_dc = NULL; RemoveBlock(); } /* Source functions for HG DnD. */ /** * * Called when host successfully detected a pending HG drag. * * param[in] clip cross-platform clipboard * param[in] stagingDir associated staging directory */ void DnDUIX11::CommonDragStartCB(const CPClipboard *clip, std::string stagingDir) { Glib::RefPtr targets; Gdk::DragAction actions; GdkEventMotion event; CPClipboard_Clear(&m_clipboard); CPClipboard_Copy(&m_clipboard, clip); g_debug("%s: enter\n", __FUNCTION__); /* * Before the DnD, we should make sure that the mouse is released * otherwise it may be another DnD, not ours. Send a release, then * a press here to cover this case. */ SendFakeXEvents(false, true, false, false, false, 0, 0); SendFakeXEvents(true, true, true, false, true, 0, 0); /* * Construct the target and action list, as well as a fake motion notify * event that's consistent with one that would typically start a drag. */ targets = Gtk::TargetList::create(std::list()); if (CPClipboard_ItemExists(&m_clipboard, CPFORMAT_FILELIST)) { m_HGStagingDir = stagingDir; if (!m_HGStagingDir.empty()) { targets->add(Glib::ustring(DRAG_TARGET_NAME_URI_LIST)); /* Add private data to tag dnd as originating from this vm. */ char *pid; g_debug("%s: adding re-entrant drop target, pid %d\n", __FUNCTION__, (int)getpid()); pid = Str_Asprintf(NULL, "guest-dnd-target %d", static_cast(getpid())); if (pid) { targets->add(Glib::ustring(pid)); free(pid); } } } if (CPClipboard_ItemExists(&m_clipboard, CPFORMAT_FILECONTENTS)) { if (WriteFileContentsToStagingDir()) { targets->add(Glib::ustring(DRAG_TARGET_NAME_URI_LIST)); } } if (CPClipboard_ItemExists(&m_clipboard, CPFORMAT_TEXT)) { targets->add(Glib::ustring(TARGET_NAME_STRING)); targets->add(Glib::ustring(TARGET_NAME_TEXT_PLAIN)); targets->add(Glib::ustring(TARGET_NAME_UTF8_STRING)); targets->add(Glib::ustring(TARGET_NAME_COMPOUND_TEXT)); } if (CPClipboard_ItemExists(&m_clipboard, CPFORMAT_RTF)) { targets->add(Glib::ustring(TARGET_NAME_APPLICATION_RTF)); targets->add(Glib::ustring(TARGET_NAME_TEXT_RICHTEXT)); } actions = Gdk::ACTION_COPY | Gdk::ACTION_MOVE; /* TODO set the x/y coords to the actual drag initialization point. */ event.type = GDK_MOTION_NOTIFY; event.window = m_detWnd->get_window()->gobj(); event.send_event = false; event.time = GDK_CURRENT_TIME; event.x = 10; event.y = 10; event.axes = NULL; event.state = GDK_BUTTON1_MASK; event.is_hint = 0; event.device = gdk_device_get_core_pointer(); event.x_root = 0; event.y_root = 5; /* Tell Gtk that a drag should be started from this widget. */ m_detWnd->drag_begin(targets, actions, 1, (GdkEvent *)&event); m_blockAdded = false; m_HGGetFileStatus = DND_FILE_TRANSFER_NOT_STARTED; SourceDragStartDone(); /* Initialize host hide feedback to DROP_NONE. */ m_effect = DROP_NONE; SourceUpdateFeedback(m_effect); } /** * * Cancel current HG DnD. */ void DnDUIX11::CommonSourceCancelCB(void) { g_debug("%s: entering\n", __FUNCTION__); /* * Force the window to show, position the mouse over it, and release. * Seems like moving the window to 0, 0 eliminates frequently observed * flybacks when we cancel as user moves mouse in and out of destination * window in a H->G DnD. */ CommonUpdateDetWndCB(true, 0, 0); SendFakeXEvents(true, true, false, true, true, 0, 0); CommonUpdateDetWndCB(false, 0, 0); m_inHGDrag = false; m_HGGetFileStatus = DND_FILE_TRANSFER_NOT_STARTED; m_effect = DROP_NONE; RemoveBlock(); } /** * * Handle common layer private drop CB. * * @param[in] x position to release the mouse button (ignored). * @param[in] y position to release the mouse button (ignored). * * @note We ignore the coordinates, because we just need to release the mouse * in its current position. */ void DnDUIX11::CommonDestPrivateDropCB(int32 x, int32 y) { g_debug("%s: entering\n", __FUNCTION__); /* Unity manager in host side may already send the drop into guest. */ if (m_GHDnDInProgress) { /* * Release the mouse button. */ SendFakeXEvents(false, true, false, false, false, 0, 0); } CommonResetCB(); } /** * * Cancel current DnD (G->H only). */ void DnDUIX11::CommonDestCancelCB(void) { g_debug("%s: entering\n", __FUNCTION__); /* Unity manager in host side may already send the drop into guest. */ if (m_GHDnDInProgress) { CommonUpdateDetWndCB(true, 0, 0); /* * Show the window, move it to the mouse position, and release the * mouse button. */ SendFakeXEvents(true, true, false, true, false, 0, 0); } m_destDropTime = GetTimeInMillis(); CommonResetCB(); } /** * * Got drop from host side. Release the mouse button in the detection window */ void DnDUIX11::CommonSourceDropCB(void) { g_debug("%s: enter\n", __FUNCTION__); CommonUpdateDetWndCB(true, 0, 0); /* * Move the mouse to the saved coordinates, and release the mouse button. */ SendFakeXEvents(false, true, false, false, true, m_mousePosX, m_mousePosY); CommonUpdateDetWndCB(false, 0, 0); } /** * * Callback when file transfer is done, which finishes the file * copying from host to guest staging directory. * * @param[in] success if true, transfer was successful */ void DnDUIX11::CommonSourceFileCopyDoneCB(bool success) { g_debug("%s: %s\n", __FUNCTION__, success ? "success" : "failed"); /* * If hg drag is not done yet, only remove block. GtkSourceDragEndCB will * call CommonResetCB(). Otherwise destination may miss the data because * we are already reset. */ m_HGGetFileStatus = DND_FILE_TRANSFER_FINISHED; if (!m_inHGDrag) { CommonResetCB(); } else { RemoveBlock(); } } /** * * Shows/hides drag detection windows based on the mask. * * @param[in] bShow if true, show the window, else hide it. * @param[in] x x-coordinate to which the detection window needs to be moved * @param[in] y y-coordinate to which the detection window needs to be moved */ void DnDUIX11::CommonUpdateDetWndCB(bool bShow, int32 x, int32 y) { g_debug("%s: enter 0x%lx show %d x %d y %d\n", __FUNCTION__, (unsigned long) m_detWnd->get_window()->gobj(), bShow, x, y); /* If the window is being shown, move it to the right place. */ if (bShow) { x = MAX(x - DRAG_DET_WINDOW_WIDTH / 2, 0); y = MAX(y - DRAG_DET_WINDOW_WIDTH / 2, 0); m_detWnd->Show(); m_detWnd->Raise(); m_detWnd->SetGeometry(x, y, DRAG_DET_WINDOW_WIDTH * 2, DRAG_DET_WINDOW_WIDTH * 2); g_debug("%s: show at (%d, %d, %d, %d)\n", __FUNCTION__, x, y, DRAG_DET_WINDOW_WIDTH * 2, DRAG_DET_WINDOW_WIDTH * 2); /* * Wiggle the mouse here. Especially for G->H DnD, this improves * reliability of making the drag escape the guest window immensly. * Stolen from the legacy V2 DnD code. */ SendFakeMouseMove(x + 2, y + 2); m_detWnd->SetIsVisible(true); } else { g_debug("%s: hide\n", __FUNCTION__); m_detWnd->Hide(); m_detWnd->SetIsVisible(false); } } /** * * Shows/hides full-screen Unity drag detection window. * * @param[in] bShow if true, show the window, else hide it. * @param[in] unityWndId active front window * @param[in] bottom if true, adjust the z-order to be bottom most. */ void DnDUIX11::CommonUpdateUnityDetWndCB(bool bShow, uint32 unityWndId, bool bottom) { g_debug("%s: enter 0x%lx unityID 0x%x\n", __FUNCTION__, (unsigned long) m_detWnd->get_window()->gobj(), unityWndId); if (bShow && ((unityWndId > 0) || bottom)) { int width = m_detWnd->GetScreenWidth(); int height = m_detWnd->GetScreenHeight(); m_detWnd->SetGeometry(0, 0, width, height); m_detWnd->Show(); if (bottom) { m_detWnd->Lower(); } g_debug("%s: show, (0, 0, %d, %d)\n", __FUNCTION__, width, height); } else { if (m_detWnd->GetIsVisible() == true) { if (m_unityMode) { /* * Show and move detection window to current mouse position * and resize. */ SendFakeXEvents(true, false, true, true, false, 0, 0); } } else { m_detWnd->Hide(); g_debug("%s: hide\n", __FUNCTION__); } } } /** * * Move detection windows to current cursor position. */ void DnDUIX11::CommonMoveDetWndToMousePos(void) { SendFakeXEvents(true, false, true, true, false, 0, 0); } /** * * Handle request from common layer to update mouse position. * * @param[in] x x coordinate of pointer * @param[in] y y coordinate of pointer */ void DnDUIX11::CommonUpdateMouseCB(int32 x, int32 y) { // Position the pointer, and record its position. SendFakeXEvents(false, false, false, false, true, x, y); m_mousePosX = x; m_mousePosY = y; if (m_dc && !m_GHDnDInProgress) { // If we are the context of a DnD, send DnD feedback to the source. DND_DROPEFFECT effect; effect = ToDropEffect((Gdk::DragAction)(m_dc->action)); if (effect != m_effect) { m_effect = effect; g_debug("%s: Updating feedback\n", __FUNCTION__); SourceUpdateFeedback(m_effect); } } } /* Beginning of Gtk+ Callbacks */ /* * Source callbacks from Gtk+. Most are seen only when we are acting as a * drag source. */ /** * * "drag_motion" signal handler for GTK. We should respond by setting drag * status. Note that there is no drag enter signal. We need to figure out * if a new drag is happening on our own. Also, we don't respond with a * "allowed" drag status right away, we start a new drag operation over VMDB * (which tries to notify the host of the new operation). Once the host has * responded), we respond with a proper drag status. * * @param[in] dc associated drag context * @param[in] x x coordinate of the drag motion * @param[in] y y coordinate of the drag motion * @param[in] time time of the drag motion * * @return returning false means we won't get notified of future motion. So, * we only return false if we don't recognize the types being offered. We * return true otherwise, even if we don't accept the drag right now for some * other reason. * * @note you may see this callback during DnD when detection window is acting * as a source. In that case it will be ignored. In a future refactoring, * we will try and avoid this. */ bool DnDUIX11::GtkDestDragMotionCB(const Glib::RefPtr &dc, int x, int y, guint timeValue) { /* * If this is a Host to Guest drag, we are done here, so return. */ unsigned long curTime = GetTimeInMillis(); g_debug("%s: enter dc %p, m_dc %p\n", __FUNCTION__, dc ? dc->gobj() : NULL, m_dc ? m_dc : NULL); if (curTime - m_destDropTime <= 1000) { g_debug("%s: ignored %ld %ld %ld\n", __FUNCTION__, curTime, m_destDropTime, curTime - m_destDropTime); return true; } g_debug("%s: not ignored %ld %ld %ld\n", __FUNCTION__, curTime, m_destDropTime, curTime - m_destDropTime); if (m_inHGDrag || (m_HGGetFileStatus != DND_FILE_TRANSFER_NOT_STARTED)) { g_debug("%s: ignored not in hg drag or not getting hg data\n", __FUNCTION__); return true; } Gdk::DragAction srcActions; Gdk::DragAction suggestedAction; Gdk::DragAction dndAction = (Gdk::DragAction)0; Glib::ustring target = m_detWnd->drag_dest_find_target(dc); if (!m_DnD->IsDnDAllowed()) { g_debug("%s: No dnd allowed!\n", __FUNCTION__); dc->drag_status(dndAction, timeValue); return true; } /* Check if dnd began from this vm. */ /* * TODO: Once we upgrade to shipping gtkmm 2.12, we can go back to * Gdk::DragContext::get_targets, but API/ABI broke between 2.10 and * 2.12, so we work around it like this for now. */ Glib::ListHandle targets( dc->gobj()->targets, Glib::OWNERSHIP_NONE); std::list as = targets; std::list::iterator result; char *pid; pid = Str_Asprintf(NULL, "guest-dnd-target %d", static_cast(getpid())); if (pid) { result = std::find(as.begin(), as.end(), std::string(pid)); free(pid); } else { result = as.end(); } if (result != as.end()) { g_debug("%s: found re-entrant drop target, pid %s\n", __FUNCTION__, pid ); return true; } m_dc = dc->gobj(); if (target != "") { /* * We give preference to the suggested action from the source, and prefer * copy over move. */ suggestedAction = dc->get_suggested_action(); srcActions = dc->get_actions(); if (suggestedAction == Gdk::ACTION_COPY || suggestedAction == Gdk::ACTION_MOVE) { dndAction = suggestedAction; } else if (srcActions & Gdk::ACTION_COPY) { dndAction= Gdk::ACTION_COPY; } else if (srcActions & Gdk::ACTION_MOVE) { dndAction = Gdk::ACTION_MOVE; } else { dndAction = (Gdk::DragAction)0; } } else { dndAction = (Gdk::DragAction)0; } if (dndAction != (Gdk::DragAction)0) { dc->drag_status(dndAction, timeValue); if (!m_GHDnDInProgress) { g_debug("%s: new drag, need to get data for host\n", __FUNCTION__); /* * This is a new drag operation. We need to start a drag thru the * backdoor, and to the host. Before we can tell the host, we have to * retrieve the drop data. */ m_GHDnDInProgress = true; /* only begin drag enter after we get the data */ /* Need to grab all of the data. */ if (!RequestData(dc, timeValue)) { g_debug("%s: RequestData failed.\n", __FUNCTION__); return false; } } else { g_debug("%s: Multiple drag motions before gh data has been received.\n", __FUNCTION__); } } else { g_debug("%s: Invalid drag\n", __FUNCTION__); return false; } return true; } /** * * "drag_leave" signal handler for GTK. Log the reception of this signal, * but otherwise unhandled in our implementation. * * @param[in] dc drag context * @param[in] time time of the drag */ void DnDUIX11::GtkDestDragLeaveCB(const Glib::RefPtr &dc, guint time) { g_debug("%s: enter dc %p, m_dc %p\n", __FUNCTION__, dc ? dc->gobj() : NULL, m_dc ? m_dc : NULL); /* * If we reach here after reset DnD, or we are getting a late * DnD drag leave signal (we have started another DnD), then * finish the old DnD. Otherwise, Gtk will not reset and a new * DnD will not start until Gtk+ times out (which appears to * be 5 minutes). * See http://bugzilla.eng.vmware.com/show_bug.cgi?id=528320 */ if (!m_dc || dc->gobj() != m_dc) { g_debug("%s: calling drag_finish\n", __FUNCTION__); dc->drag_finish(true, false, time); } } /* * Gtk+ callbacks that are seen when we are a drag source. */ /** * * "drag_begin" signal handler for GTK. * * @param[in] context drag context */ void DnDUIX11::GtkSourceDragBeginCB(const Glib::RefPtr& context) { g_debug("%s: enter dc %p, m_dc %p\n", __FUNCTION__, context ? context->gobj() : NULL, m_dc ? m_dc : NULL); m_dc = context->gobj(); } /** * * "drag_data_get" handler for GTK. We don't send drop until we are done. * * @param[in] dc drag state * @param[in] selection_data buffer for data * @param[in] info unused * @param[in] time timestamp * * @note if the drop has occurred, the files are copied from the guest. * *----------------------------------------------------------------------------- */ void DnDUIX11::GtkSourceDragDataGetCB(const Glib::RefPtr &dc, Gtk::SelectionData& selection_data, guint info, guint time) { size_t index = 0; std::string str; std::string uriList; std::string stagingDirName; void *buf; size_t sz; utf::utf8string hgData; DnDFileList fList; std::string pre; std::string post; const utf::string target = selection_data.get_target().c_str(); selection_data.set(target.c_str(), ""); g_debug("%s: enter dc %p, m_dc %p with target %s\n", __FUNCTION__, dc ? dc->gobj() : NULL, m_dc ? m_dc : NULL, target.c_str()); if (!m_inHGDrag) { g_debug("%s: not in drag, return\n", __FUNCTION__); return; } if (target == DRAG_TARGET_NAME_URI_LIST && CPClipboard_GetItem(&m_clipboard, CPFORMAT_FILELIST, &buf, &sz)) { /* Provide path within vmblock file system instead of actual path. */ stagingDirName = GetLastDirName(m_HGStagingDir); if (stagingDirName.length() == 0) { g_debug("%s: Cannot get staging directory name, stagingDir: %s\n", __FUNCTION__, m_HGStagingDir.c_str()); return; } if (!fList.FromCPClipboard(buf, sz)) { g_debug("%s: Can't get data from clipboard\n", __FUNCTION__); return; } mTotalFileSize = fList.GetFileSize(); /* Provide URIs for each path in the guest's file list. */ if (FCP_TARGET_INFO_GNOME_COPIED_FILES == info) { pre = FCP_GNOME_LIST_PRE; post = FCP_GNOME_LIST_POST; } else if (FCP_TARGET_INFO_URI_LIST == info) { pre = DND_URI_LIST_PRE_KDE; post = DND_URI_LIST_POST; } else { g_debug("%s: Unknown request target: %s\n", __FUNCTION__, selection_data.get_target().c_str()); return; } /* Provide path within vmblock file system instead of actual path. */ hgData = fList.GetRelPathsStr(); /* Provide URIs for each path in the guest's file list. */ while ((str = GetNextPath(hgData, index).c_str()).length() != 0) { uriList += pre; if (DnD_BlockIsReady(m_blockCtrl)) { uriList += m_blockCtrl->blockRoot; uriList += DIRSEPS + stagingDirName + DIRSEPS + str + post; } else { uriList += DIRSEPS + m_HGStagingDir + DIRSEPS + str + post; } } /* * This seems to be the best place to do the blocking. If we do * it in the source drop callback from the DnD layer, we often * find ourselves adding the block too late; the user will (in * GNOME, in the dest) be told that it could not find the file, * and if you click retry, it is there, meaning the block was * added too late). * * We find ourselves in this callback twice for each H->G DnD. * We *must* always set the selection data, when called, or else * the DnD for that context will fail, but we *must not* add the * block twice or else things get confused. So we add a check to * see if we are in the right state (no block yet added, and we * are in a HG drag still, both must be true) when adding the block. * Doing both of these addresses bug * http://bugzilla.eng.vmware.com/show_bug.cgi?id=391661. */ if (!m_blockAdded && m_inHGDrag && (m_HGGetFileStatus == DND_FILE_TRANSFER_NOT_STARTED)) { m_HGGetFileStatus = DND_FILE_TRANSFER_IN_PROGRESS; AddBlock(); } else { g_debug("%s: not calling AddBlock\n", __FUNCTION__); } selection_data.set(DRAG_TARGET_NAME_URI_LIST, uriList.c_str()); g_debug("%s: providing uriList [%s]\n", __FUNCTION__, uriList.c_str()); return; } if (target == DRAG_TARGET_NAME_URI_LIST && CPClipboard_ItemExists(&m_clipboard, CPFORMAT_FILECONTENTS)) { g_debug("%s: Providing uriList [%s] for file contents DnD\n", __FUNCTION__, m_HGFileContentsUriList.c_str()); selection_data.set(DRAG_TARGET_NAME_URI_LIST, m_HGFileContentsUriList.c_str()); return; } if ((target == TARGET_NAME_STRING || target == TARGET_NAME_TEXT_PLAIN || target == TARGET_NAME_UTF8_STRING || target == TARGET_NAME_COMPOUND_TEXT) && CPClipboard_GetItem(&m_clipboard, CPFORMAT_TEXT, &buf, &sz)) { g_debug("%s: providing plain text, size %"FMTSZ"u\n", __FUNCTION__, sz); selection_data.set(target.c_str(), (const char *)buf); return; } if ((target == TARGET_NAME_APPLICATION_RTF || target == TARGET_NAME_TEXT_RICHTEXT) && CPClipboard_GetItem(&m_clipboard, CPFORMAT_RTF, &buf, &sz)) { g_debug("%s: providing rtf text, size %"FMTSZ"u\n", __FUNCTION__, sz); selection_data.set(target.c_str(), (const char *)buf); return; } /* Can not get any valid data, cancel this HG DnD. */ g_debug("%s: no valid data for HG DnD\n", __FUNCTION__); CommonResetCB(); } /** * * "drag_end" handler for GTK. Received by drag source. * * @param[in] dc drag state */ void DnDUIX11::GtkSourceDragEndCB(const Glib::RefPtr &dc) { g_debug("%s: entering dc %p, m_dc %p\n", __FUNCTION__, dc ? dc->gobj() : NULL, m_dc ? m_dc : NULL); /* * We may see a drag end for the previous DnD, but after a new * DnD has started. If so, ignore it. */ if (m_dc && dc && (m_dc != dc->gobj())) { g_debug("%s: got old dc (new DnD started), ignoring\n", __FUNCTION__); return; } /* * If we are a file DnD and file transfer is not done yet, don't call * CommonResetCB() here, since we will do so in the fileCopyDoneChanged * callback. */ if (DND_FILE_TRANSFER_IN_PROGRESS != m_HGGetFileStatus) { CommonResetCB(); } m_inHGDrag = false; } /* Gtk+ callbacks seen when we are a drag destination. */ /** * * "drag_data_received" signal handler for GTK. We requested the drag * data earlier from some drag source on the guest; this is the response. * * This is for G->H DnD. * * @param[in] dc drag context * @param[in] x where the drop happened * @param[in] y where the drop happened * @param[in] sd the received data * @param[in] info the info that has been registered with the target in the * target list. * @param[in] time the timestamp at which the data was received. */ void DnDUIX11::GtkDestDragDataReceivedCB(const Glib::RefPtr &dc, int x, int y, const Gtk::SelectionData& sd, guint info, guint time) { g_debug("%s: enter dc %p, m_dc %p\n", __FUNCTION__, dc ? dc->gobj() : NULL, m_dc ? m_dc : NULL); /* The GH DnD may already finish before we got response. */ if (!m_GHDnDInProgress) { g_debug("%s: not valid\n", __FUNCTION__); return; } /* * Try to get data provided from the source. If we cannot get any data, * there is no need to inform the guest of anything. If there is no data, * reset, so that the next drag_motion callback that we see will be allowed * to request data again. */ if (SetCPClipboardFromGtk(sd) == false) { g_debug("%s: Failed to set CP clipboard.\n", __FUNCTION__); CommonResetCB(); return; } m_numPendingRequest--; if (m_numPendingRequest > 0) { return; } if (CPClipboard_IsEmpty(&m_clipboard)) { g_debug("%s: Failed getting item.\n", __FUNCTION__); CommonResetCB(); return; } /* * There are two points in the DnD process at which this is called, and both * are in response to us calling drag_data_get(). The first occurs on the * first "drag_motion" received and is used to start a drag; at that point * we need to provide the file list to the guest so we request the data from * the target. The second occurs when the "drag_drop" signal is received * and we confirm this data with the target before starting the drop. * * Note that we prevent against sending multiple "dragStart"s or "drop"s for * each DnD. */ if (!m_GHDnDDataReceived) { g_debug("%s: Drag entering.\n", __FUNCTION__); m_GHDnDDataReceived = true; TargetDragEnter(); } else { g_debug("%s: not !m_GHDnDDataReceived\n", __FUNCTION__); } } /** * * "drag_drop" signal handler for GTK. Send the drop to the host (by * way of the backdoor), then tell the host to get the files. * * @param[in] dc drag context * @param[in] x x location of the drop * @param[in] y y location of the drop * @param[in] time timestamp for the drop * * @return true on success, false otherwise. */ bool DnDUIX11::GtkDestDragDropCB(const Glib::RefPtr &dc, int x, int y, guint time) { g_debug("%s: enter dc %p, m_dc %p x %d y %d\n", __FUNCTION__, (dc ? dc->gobj() : NULL), (m_dc ? m_dc : NULL), x, y); Glib::ustring target; target = m_detWnd->drag_dest_find_target(dc); g_debug("%s: calling drag_finish\n", __FUNCTION__); dc->drag_finish(true, false, time); if (target == "") { g_debug("%s: No valid data on clipboard.\n", __FUNCTION__); return false; } if (CPClipboard_IsEmpty(&m_clipboard)) { g_debug("%s: No valid data on m_clipboard.\n", __FUNCTION__); return false; } return true; } /* General utility functions */ /** * * Try to construct cross-platform clipboard data from selection data * provided to us by Gtk+. * * @param[in] sd Gtk selection data to convert to CP clipboard data * * @return false on failure, true on success */ bool DnDUIX11::SetCPClipboardFromGtk(const Gtk::SelectionData& sd) // IN { char *newPath; char *newRelPath; size_t newPathLen; size_t index = 0; DnDFileList fileList; DynBuf buf; uint64 totalSize = 0; int64 size; const utf::string target = sd.get_target().c_str(); /* Try to get file list. */ if (m_DnD->CheckCapability(DND_CP_CAP_FILE_DND) && target == DRAG_TARGET_NAME_URI_LIST) { /* * Turn the uri list into two \0 delimited lists. One for full paths and * one for just the last path component. */ utf::string source = sd.get_data_as_string().c_str(); g_debug("%s: Got file list: [%s]\n", __FUNCTION__, source.c_str()); if (sd.get_data_as_string().length() == 0) { g_debug("%s: empty file list!\n", __FUNCTION__); return false; } /* * In gnome, before file list there may be a extra line indicating it * is a copy or cut. */ if (source.length() >= 5 && source.compare(0, 5, "copy\n") == 0) { source = source.erase(0, 5); } if (source.length() >= 4 && source.compare(0, 4, "cut\n") == 0) { source = source.erase(0, 4); } while (source.length() > 0 && (source[0] == '\n' || source[0] == '\r' || source[0] == ' ')) { source = source.erase(0, 1); } while ((newPath = DnD_UriListGetNextFile(source.c_str(), &index, &newPathLen)) != NULL) { #if defined(linux) if (DnD_UriIsNonFileSchemes(newPath)) { /* Try to get local file path for non file uri. */ GFile *file = g_file_new_for_uri(newPath); free(newPath); if (!file) { g_debug("%s: g_file_new_for_uri failed\n", __FUNCTION__); return false; } newPath = g_file_get_path(file); g_object_unref(file); if (!newPath) { g_debug("%s: g_file_get_path failed\n", __FUNCTION__); return false; } } #endif /* * Parse relative path. */ newRelPath = Str_Strrchr(newPath, DIRSEPC) + 1; // Point to char after '/' /* Keep track of how big the dnd files are. */ if ((size = File_GetSizeEx(newPath)) >= 0) { totalSize += size; } else { g_debug("%s: unable to get file size for %s\n", __FUNCTION__, newPath); } g_debug("%s: Adding newPath '%s' newRelPath '%s'\n", __FUNCTION__, newPath, newRelPath); fileList.AddFile(newPath, newRelPath); free(newPath); } DynBuf_Init(&buf); fileList.SetFileSize(totalSize); if (fileList.ToCPClipboard(&buf, false)) { CPClipboard_SetItem(&m_clipboard, CPFORMAT_FILELIST, DynBuf_Get(&buf), DynBuf_GetSize(&buf)); } DynBuf_Destroy(&buf); return true; } /* Try to get plain text. */ if (m_DnD->CheckCapability(DND_CP_CAP_PLAIN_TEXT_DND) && ( target == TARGET_NAME_STRING || target == TARGET_NAME_TEXT_PLAIN || target == TARGET_NAME_UTF8_STRING || target == TARGET_NAME_COMPOUND_TEXT)) { std::string source = sd.get_data_as_string(); if (source.size() > 0 && source.size() < DNDMSG_MAX_ARGSZ && CPClipboard_SetItem(&m_clipboard, CPFORMAT_TEXT, source.c_str(), source.size() + 1)) { g_debug("%s: Got text, size %"FMTSZ"u\n", __FUNCTION__, source.size()); } else { g_debug("%s: Failed to get text\n", __FUNCTION__); return false; } return true; } /* Try to get RTF string. */ if (m_DnD->CheckCapability(DND_CP_CAP_RTF_DND) && ( target == TARGET_NAME_APPLICATION_RTF || target == TARGET_NAME_TEXT_RICHTEXT)) { std::string source = sd.get_data_as_string(); if (source.size() > 0 && source.size() < DNDMSG_MAX_ARGSZ && CPClipboard_SetItem(&m_clipboard, CPFORMAT_RTF, source.c_str(), source.size() + 1)) { g_debug("%s: Got RTF, size %"FMTSZ"u\n", __FUNCTION__, source.size()); return true; } else { g_debug("%s: Failed to get text\n", __FUNCTION__ ); return false; } } return true; } /** * * Ask for clipboard data from drag source. * * @param[in] dc Associated drag context * @param[in] time Time of the request * * @return true if there is any data request, false otherwise. */ bool DnDUIX11::RequestData(const Glib::RefPtr &dc, guint time) { Glib::RefPtr targets; targets = Gtk::TargetList::create(std::list()); CPClipboard_Clear(&m_clipboard); m_numPendingRequest = 0; /* * First check file list. If file list is available, all other formats will * be ignored. */ targets->add(Glib::ustring(DRAG_TARGET_NAME_URI_LIST)); Glib::ustring target = m_detWnd->drag_dest_find_target(dc, targets); targets->remove(Glib::ustring(DRAG_TARGET_NAME_URI_LIST)); if (target != "") { m_detWnd->drag_get_data(dc, target, time); m_numPendingRequest++; return true; } /* Then check plain text. */ targets->add(Glib::ustring(TARGET_NAME_UTF8_STRING)); targets->add(Glib::ustring(TARGET_NAME_STRING)); targets->add(Glib::ustring(TARGET_NAME_TEXT_PLAIN)); targets->add(Glib::ustring(TARGET_NAME_COMPOUND_TEXT)); target = m_detWnd->drag_dest_find_target(dc, targets); targets->remove(Glib::ustring(TARGET_NAME_STRING)); targets->remove(Glib::ustring(TARGET_NAME_TEXT_PLAIN)); targets->remove(Glib::ustring(TARGET_NAME_UTF8_STRING)); targets->remove(Glib::ustring(TARGET_NAME_COMPOUND_TEXT)); if (target != "") { m_detWnd->drag_get_data(dc, target, time); m_numPendingRequest++; } /* Then check RTF. */ targets->add(Glib::ustring(TARGET_NAME_APPLICATION_RTF)); targets->add(Glib::ustring(TARGET_NAME_TEXT_RICHTEXT)); target = m_detWnd->drag_dest_find_target(dc, targets); targets->remove(Glib::ustring(TARGET_NAME_APPLICATION_RTF)); targets->remove(Glib::ustring(TARGET_NAME_TEXT_RICHTEXT)); if (target != "") { m_detWnd->drag_get_data(dc, target, time); m_numPendingRequest++; } return (m_numPendingRequest > 0); } /** * * Try to get last directory name from a full path name. * * @param[in] str pathname to process * * @return last dir name in the full path name if sucess, empty str otherwise */ std::string DnDUIX11::GetLastDirName(const std::string &str) { std::string ret; size_t start; size_t end; end = str.size() - 1; if (end >= 0 && DIRSEPC == str[end]) { end--; } if (end <= 0 || str[0] != DIRSEPC) { return ""; } start = end; while (str[start] != DIRSEPC) { start--; } return str.substr(start + 1, end - start); } /** * * Provide a substring containing the next path from the provided * NUL-delimited string starting at the provided index. * * @param[in] str NUL-delimited path list * @param[in] index current index into string * * @return a string with the next path or "" if there are no more paths. */ utf::utf8string DnDUIX11::GetNextPath(utf::utf8string& str, size_t& index) { utf::utf8string ret; size_t start; if (index >= str.length()) { return ""; } for (start = index; str[index] != '\0' && index < str.length(); index++) { /* * Escape reserved characters according to RFC 1630. We'd use * Escape_Do() if this wasn't a utf::string, but let's use the same table * replacement approach. */ static char const Dec2Hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', }; unsigned char ubyte = str[index]; if (ubyte == '#' || /* Fragment identifier delimiter */ ubyte == '?' || /* Query string delimiter */ ubyte == '*' || /* "Special significance within specific schemes" */ ubyte == '!' || /* "Special significance within specific schemes" */ ubyte == '%' || /* Escape character */ ubyte >= 0x80) { /* UTF-8 encoding bytes */ str.replace(index, 1, "%"); str.insert(index + 1, 1, Dec2Hex[ubyte >> 4]); str.insert(index + 2, 1, Dec2Hex[ubyte & 0xF]); index += 2; } } ret = str.substr(start, index - start); g_debug("%s: nextpath: %s", __FUNCTION__, ret.c_str()); index++; return ret; } /** * * Issue a fake mouse move event to the detection window. Code stolen from * DnD V2 Linux guest implementation, where it was originally defined as a * macro. * * @param[in] x x-coordinate of location to move mouse to. * @param[in] y y-coordinate of location to move mouse to. * * @return true on success, false on failure. */ bool DnDUIX11::SendFakeMouseMove(const int x, const int y) { return SendFakeXEvents(false, false, false, false, true, x, y); } /** * * Fake X mouse events and window movement for the provided Gtk widget. * * This function will optionally show the widget, move the provided widget * to either the provided location or the current mouse position if no * coordinates are provided, and cause a button press or release event. * * @param[in] showWidget whether to show Gtk widget * @param[in] buttonEvent whether to send a button event * @param[in] buttonPress whether to press or release mouse * @param[in] moveWindow: whether to move our window too * @param[in] coordsProvided whether coordinates provided * @param[in] xCoord x coordinate * @param[in] yCoord y coordinate * * @note todo this code should be implemented using GDK APIs. * @note todo this code should be moved into the detection window class * * @return true on success, false on failure. */ bool DnDUIX11::SendFakeXEvents(const bool showWidget, const bool buttonEvent, const bool buttonPress, const bool moveWindow, const bool coordsProvided, const int xCoord, const int yCoord) { GtkWidget *widget; Window rootWnd; bool ret = false; Display *dndXDisplay; Window dndXWindow; Window rootReturn; int x; int y; Window childReturn; int rootXReturn; int rootYReturn; int winXReturn; int winYReturn; unsigned int maskReturn; x = xCoord; y = yCoord; widget = GetDetWndAsWidget(); if (!widget) { g_debug("%s: unable to get widget\n", __FUNCTION__); return false; } dndXDisplay = GDK_WINDOW_XDISPLAY(widget->window); dndXWindow = GDK_WINDOW_XWINDOW(widget->window); rootWnd = RootWindow(dndXDisplay, DefaultScreen(dndXDisplay)); /* * Turn on X synchronization in order to ensure that our X events occur in * the order called. In particular, we want the window movement to occur * before the mouse movement so that the events we are coercing do in fact * happen. */ XSynchronize(dndXDisplay, True); if (showWidget) { g_debug("%s: showing Gtk widget\n", __FUNCTION__); gtk_widget_show(widget); gdk_window_show(widget->window); } /* Get the current location of the mouse if coordinates weren't provided. */ if (!coordsProvided) { if (!XQueryPointer(dndXDisplay, rootWnd, &rootReturn, &childReturn, &rootXReturn, &rootYReturn, &winXReturn, &winYReturn, &maskReturn)) { Warning("%s: XQueryPointer() returned False.\n", __FUNCTION__); goto exit; } g_debug("%s: current mouse is at (%d, %d)\n", __FUNCTION__, rootXReturn, rootYReturn); /* * Position away from the edge of the window. */ int width = m_detWnd->GetScreenWidth(); int height = m_detWnd->GetScreenHeight(); bool change = false; x = rootXReturn; y = rootYReturn; /* * first do left and top edges. */ if (x <= 5) { x = 6; change = true; } if (y <= 5) { y = 6; change = true; } /* * next, move result away from right and bottom edges. */ if (x > width - 5) { x = width - 6; change = true; } if (y > height - 5) { y = height - 6; change = true; } if (change) { g_debug("%s: adjusting mouse position. root %d, %d, adjusted %d, %d\n", __FUNCTION__, rootXReturn, rootYReturn, x, y); } } if (moveWindow) { /* * Make sure the window is at this point and at the top (raised). The * window is resized to be a bit larger than we would like to increase * the likelihood that mouse events are attributed to our window -- this * is okay since the window is invisible and hidden on cancels and DnD * finish. */ XMoveResizeWindow(dndXDisplay, dndXWindow, x - 5 , y - 5, 25, 25); XRaiseWindow(dndXDisplay, dndXWindow); g_debug("%s: move wnd to (%d, %d, %d, %d)\n", __FUNCTION__, x - 5, y - 5 , x + 25, y + 25); } /* * Generate mouse movements over the window. The second one makes ungrabs * happen more reliably on KDE, but isn't necessary on GNOME. */ XTestFakeMotionEvent(dndXDisplay, -1, x, y, CurrentTime); XTestFakeMotionEvent(dndXDisplay, -1, x + 1, y + 1, CurrentTime); g_debug("%s: move mouse to (%d, %d) and (%d, %d)\n", __FUNCTION__, x, y, x + 1, y + 1); if (buttonEvent) { g_debug("%s: faking left mouse button %s\n", __FUNCTION__, buttonPress ? "press" : "release"); XTestFakeButtonEvent(dndXDisplay, 1, buttonPress, CurrentTime); XSync(dndXDisplay, False); if (!buttonPress) { /* * The button release simulation may be failed with some distributions * like Ubuntu 10.4 and RHEL 6 for guest->host DnD. So first query * mouse button status. If some button is still down, we will try * mouse device level event simulation. For details please refer * to bug 552807. */ if (!XQueryPointer(dndXDisplay, rootWnd, &rootReturn, &childReturn, &rootXReturn, &rootYReturn, &winXReturn, &winYReturn, &maskReturn)) { Warning("%s: XQueryPointer returned False.\n", __FUNCTION__); goto exit; } if ((maskReturn & Button1Mask) || (maskReturn & Button2Mask) || (maskReturn & Button3Mask) || (maskReturn & Button4Mask) || (maskReturn & Button5Mask)) { Debug("%s: XTestFakeButtonEvent was not working for button " "release, trying XTestFakeDeviceButtonEvent now.\n", __FUNCTION__); ret = TryXTestFakeDeviceButtonEvent(); } else { g_debug("%s: XTestFakeButtonEvent was working for button release.\n", __FUNCTION__); ret = true; } } else { ret = true; } } exit: XSynchronize(dndXDisplay, False); return ret; } /** * Fake X mouse events in device level. * * XXX The function will only be called if XTestFakeButtonEvent does not work * for mouse button release. Later on we may only call this one for mouse * button simulation if this is more reliable. * * @return true on success, false on failure. */ bool DnDUIX11::TryXTestFakeDeviceButtonEvent(void) { XDeviceInfo *list = NULL; XDeviceInfo *list2 = NULL; XDevice *tdev = NULL; XDevice *buttonDevice = NULL; int numDevices = 0; int i = 0; int j = 0; XInputClassInfo *ip = NULL; GtkWidget *widget; Display *dndXDisplay; widget = GetDetWndAsWidget(); if (!widget) { g_debug("%s: unable to get widget\n", __FUNCTION__); return false; } dndXDisplay = GDK_WINDOW_XDISPLAY(widget->window); /* First get list of all input device. */ if (!(list = XListInputDevices (dndXDisplay, &numDevices))) { g_debug("%s: XListInputDevices failed\n", __FUNCTION__); return false; } else { g_debug("%s: XListInputDevices got %d devices\n", __FUNCTION__, numDevices); } list2 = list; for (i = 0; i < numDevices; i++, list++) { /* We only care about mouse device. */ if (list->use != IsXExtensionPointer) { continue; } tdev = XOpenDevice(dndXDisplay, list->id); if (!tdev) { g_debug("%s: XOpenDevice failed\n", __FUNCTION__); continue; } for (ip = tdev->classes, j = 0; j < tdev->num_classes; j++, ip++) { if (ip->input_class == ButtonClass) { buttonDevice = tdev; break; } } if (buttonDevice) { g_debug("%s: calling XTestFakeDeviceButtonEvent for %s\n", __FUNCTION__, list->name); XTestFakeDeviceButtonEvent(dndXDisplay, buttonDevice, 1, False, NULL, 0, CurrentTime); buttonDevice = NULL; } XCloseDevice(dndXDisplay, tdev); } XFreeDeviceList(list2); return true; } /** * * Get the GtkWidget pointer for a DragDetWnd object. The X11 Unity * implementation requires access to the drag detection window as * a GtkWindow pointer, which it uses to show and hide the detection * window. This function is also called by the code that issues fake * X events to the detection window. * * @return a pointer to the GtkWidget for the detection window, or NULL * on failure. */ GtkWidget * DnDUIX11::GetDetWndAsWidget() { GtkInvisible *window; GtkWidget *widget = NULL; if (!m_detWnd) { return NULL; } window = m_detWnd->gobj(); if (window) { widget = GTK_WIDGET(window); } return widget; } /** * * Add a block for the current H->G file transfer. Must be paired with a * call to RemoveBlock() on finish or cancellation. */ void DnDUIX11::AddBlock() { g_debug("%s: enter\n", __FUNCTION__); if (m_blockAdded) { g_debug("%s: block already added\n", __FUNCTION__); return; } g_debug("%s: DnDBlockIsReady %d fd %d\n", __FUNCTION__, DnD_BlockIsReady(m_blockCtrl), m_blockCtrl->fd); if (DnD_BlockIsReady(m_blockCtrl) && m_blockCtrl->AddBlock(m_blockCtrl->fd, m_HGStagingDir.c_str())) { m_blockAdded = true; g_debug("%s: add block for %s.\n", __FUNCTION__, m_HGStagingDir.c_str()); } else { m_blockAdded = false; g_debug("%s: unable to add block dir %s.\n", __FUNCTION__, m_HGStagingDir.c_str()); } } /** * * Remove block for the current H->G file transfer. Must be paired with a * call to AddBlock(), but it will only attempt to remove block if one is * currently in effect. */ void DnDUIX11::RemoveBlock() { g_debug("%s: enter\n", __FUNCTION__); if (m_blockAdded && (DND_FILE_TRANSFER_IN_PROGRESS != m_HGGetFileStatus)) { g_debug("%s: removing block for %s\n", __FUNCTION__, m_HGStagingDir.c_str()); /* We need to make sure block subsystem has not been shut off. */ if (DnD_BlockIsReady(m_blockCtrl)) { m_blockCtrl->RemoveBlock(m_blockCtrl->fd, m_HGStagingDir.c_str()); } m_blockAdded = false; } else { g_debug("%s: not removing block m_blockAdded %d m_HGGetFileStatus %d\n", __FUNCTION__, m_blockAdded, m_HGGetFileStatus); } } /** * * Convert a Gdk::DragAction value to its corresponding DND_DROPEFFECT. * * @param[in] the Gdk::DragAction value to return. * * @return the corresponding DND_DROPEFFECT, with DROP_UNKNOWN returned * if no mapping is supported. * * @note DROP_NONE is not mapped in this function. */ DND_DROPEFFECT DnDUIX11::ToDropEffect(Gdk::DragAction action) { DND_DROPEFFECT effect; switch(action) { case Gdk::ACTION_COPY: case Gdk::ACTION_DEFAULT: effect = DROP_COPY; break; case Gdk::ACTION_MOVE: effect = DROP_MOVE; break; case Gdk::ACTION_LINK: effect = DROP_LINK; break; case Gdk::ACTION_PRIVATE: case Gdk::ACTION_ASK: default: effect = DROP_UNKNOWN; break; } return effect; } /** * * Try to extract file contents from m_clipboard. Write all files to a * temporary staging directory. Construct uri list. * * @return true if success, false otherwise. */ bool DnDUIX11::WriteFileContentsToStagingDir(void) { void *buf = NULL; size_t sz = 0; XDR xdrs; CPFileContents fileContents; CPFileContentsList *contentsList = NULL; size_t nFiles = 0; CPFileItem *fileItem = NULL; Unicode tempDir = NULL; size_t i = 0; bool ret = false; if (!CPClipboard_GetItem(&m_clipboard, CPFORMAT_FILECONTENTS, &buf, &sz)) { return false; } /* Extract file contents from buf. */ xdrmem_create(&xdrs, (char *)buf, sz, XDR_DECODE); memset(&fileContents, 0, sizeof fileContents); if (!xdr_CPFileContents(&xdrs, &fileContents)) { g_debug("%s: xdr_CPFileContents failed.\n", __FUNCTION__); xdr_destroy(&xdrs); return false; } xdr_destroy(&xdrs); contentsList = fileContents.CPFileContents_u.fileContentsV1; if (!contentsList) { g_debug("%s: invalid contentsList.\n", __FUNCTION__); goto exit; } nFiles = contentsList->fileItem.fileItem_len; if (0 == nFiles) { g_debug("%s: invalid nFiles.\n", __FUNCTION__); goto exit; } fileItem = contentsList->fileItem.fileItem_val; if (!fileItem) { g_debug("%s: invalid fileItem.\n", __FUNCTION__); goto exit; } /* * Write files into a temporary staging directory. These files will be moved * to final destination, or deleted on next reboot. */ tempDir = DnD_CreateStagingDirectory(); if (!tempDir) { g_debug("%s: DnD_CreateStagingDirectory failed.\n", __FUNCTION__); goto exit; } m_HGFileContentsUriList = ""; for (i = 0; i < nFiles; i++) { utf::string fileName; utf::string filePathName; VmTimeType createTime = -1; VmTimeType accessTime = -1; VmTimeType writeTime = -1; VmTimeType attrChangeTime = -1; if (!fileItem[i].cpName.cpName_val || 0 == fileItem[i].cpName.cpName_len) { g_debug("%s: invalid fileItem[%"FMTSZ"u].cpName.\n", __FUNCTION__, i); goto exit; } /* * '\0' is used as directory separator in cross-platform name. Now turn * '\0' in data into DIRSEPC. * * Note that we don't convert the final '\0' into DIRSEPC so the string * is NUL terminated. */ CPNameUtil_CharReplace(fileItem[i].cpName.cpName_val, fileItem[i].cpName.cpName_len - 1, '\0', DIRSEPC); fileName = fileItem[i].cpName.cpName_val; filePathName = tempDir; filePathName += DIRSEPS + fileName; if (fileItem[i].validFlags & CP_FILE_VALID_TYPE && CP_FILE_TYPE_DIRECTORY == fileItem[i].type) { if (!File_CreateDirectory(filePathName.c_str())) { goto exit; } g_debug("%s: created directory [%s].\n", __FUNCTION__, filePathName.c_str()); } else if (fileItem[i].validFlags & CP_FILE_VALID_TYPE && CP_FILE_TYPE_REGULAR == fileItem[i].type) { FileIODescriptor file; FileIOResult fileErr; FileIO_Invalidate(&file); fileErr = FileIO_Open(&file, filePathName.c_str(), FILEIO_ACCESS_WRITE, FILEIO_OPEN_CREATE_EMPTY); if (!FileIO_IsSuccess(fileErr)) { goto exit; } fileErr = FileIO_Write(&file, fileItem[i].content.content_val, fileItem[i].content.content_len, NULL); FileIO_Close(&file); g_debug("%s: created file [%s].\n", __FUNCTION__, filePathName.c_str()); } else { /* * Right now only Windows can provide CPFORMAT_FILECONTENTS data. * Symlink file is not expected. Continue with next file if the * type is not valid. */ continue; } /* Update file time attributes. */ createTime = fileItem->validFlags & CP_FILE_VALID_CREATE_TIME ? fileItem->createTime: -1; accessTime = fileItem->validFlags & CP_FILE_VALID_ACCESS_TIME ? fileItem->accessTime: -1; writeTime = fileItem->validFlags & CP_FILE_VALID_WRITE_TIME ? fileItem->writeTime: -1; attrChangeTime = fileItem->validFlags & CP_FILE_VALID_CHANGE_TIME ? fileItem->attrChangeTime: -1; if (!File_SetTimes(filePathName.c_str(), createTime, accessTime, writeTime, attrChangeTime)) { /* Not a critical error, only log it. */ g_debug("%s: File_SetTimes failed with file [%s].\n", __FUNCTION__, filePathName.c_str()); } /* Update file permission attributes. */ if (fileItem->validFlags & CP_FILE_VALID_PERMS) { if (Posix_Chmod(filePathName.c_str(), fileItem->permissions) < 0) { /* Not a critical error, only log it. */ g_debug("%s: Posix_Chmod failed with file [%s].\n", __FUNCTION__, filePathName.c_str()); } } /* * If there is no DIRSEPC inside the fileName, this file/directory is a * top level one. We only put top level name into uri list. */ if (fileName.find(DIRSEPS, 0) == utf::string::npos) { m_HGFileContentsUriList += "file://" + filePathName + "\r\n"; } } g_debug("%s: created uri list [%s].\n", __FUNCTION__, m_HGFileContentsUriList.c_str()); ret = true; exit: xdr_free((xdrproc_t) xdr_CPFileContents, (char *)&fileContents); if (tempDir && !ret) { DnD_DeleteStagingFiles(tempDir, false); } free(tempDir); return ret; } /** * Tell host that we are done with HG DnD initialization. */ void DnDUIX11::SourceDragStartDone(void) { g_debug("%s: enter\n", __FUNCTION__); m_inHGDrag = true; m_DnD->SrcUIDragBeginDone(); } /** * Set block control member. * * @param[in] block control as setup by vmware-user. */ void DnDUIX11::SetBlockControl(DnDBlockControl *blockCtrl) { m_blockCtrl = blockCtrl; } /** * Got feedback from our DropSource, send it over to host. Called by * drag motion callback. * * @param[in] effect feedback to send to the UI-independent DnD layer. */ void DnDUIX11::SourceUpdateFeedback(DND_DROPEFFECT effect) { g_debug("%s: entering\n", __FUNCTION__); m_DnD->SrcUIUpdateFeedback(effect); } /** * This is triggered when user drags valid data from guest to host. Try to * get clip data and notify host to start GH DnD. */ void DnDUIX11::TargetDragEnter(void) { g_debug("%s: entering\n", __FUNCTION__); /* Check if there is valid data with current detection window. */ if (!CPClipboard_IsEmpty(&m_clipboard)) { g_debug("%s: got valid data from detWnd.\n", __FUNCTION__); m_DnD->DestUIDragEnter(&m_clipboard); } /* * Show the window, and position it under the current mouse position. * This is particularly important for KDE 3.5 guests. */ SendFakeXEvents(true, false, true, true, false, 0, 0); } /** * Get Unix time in milliseconds. See man 2 gettimeofday for details. * * @return unix time in milliseconds. */ unsigned long DnDUIX11::GetTimeInMillis(void) { VmTimeType atime; Hostinfo_GetTimeOfDay(&atime); return((unsigned long)(atime / 1000)); } /** * Update version information in m_DnD. * * @param[ignored] chan RpcChannel pointer * @param[in] version the version negotiated with host. */ void DnDUIX11::VmxDnDVersionChanged(RpcChannel *chan, uint32 version) { ASSERT(m_DnD); m_DnD->VmxDnDVersionChanged(version); } /** * Track enter events on detection window. * * @param[ignored] event event data (ignored) * * @return always true. */ bool DnDUIX11::GtkEnterEventCB(GdkEventCrossing *ignored) { g_debug("%s: enter\n", __FUNCTION__); return true; } /** * Track enter events on detection window. * * @param[ignored] event event data (ignored) * * @return always true. */ bool DnDUIX11::GtkLeaveEventCB(GdkEventCrossing *ignored) { g_debug("%s: enter\n", __FUNCTION__); return true; } /** * Track enter events on detection window. * * @param[ignored] event event data (ignored) * * @return always true. */ bool DnDUIX11::GtkMapEventCB(GdkEventAny *event) { g_debug("%s: enter\n", __FUNCTION__); return true; } /** * Track enter events on detection window. * * @param[ignored] event event data (ignored) * * @return always true. */ bool DnDUIX11::GtkUnmapEventCB(GdkEventAny *event) { g_debug("%s: enter\n", __FUNCTION__); return true; } /** * Track realize events on detection window. */ void DnDUIX11::GtkRealizeEventCB() { g_debug("%s: enter\n", __FUNCTION__); } /** * Track unrealize events on detection window. */ void DnDUIX11::GtkUnrealizeEventCB() { g_debug("%s: enter\n", __FUNCTION__); } /** * Track motion notify events on detection window. * * @param[in] event event data * * @return always true. */ bool DnDUIX11::GtkMotionNotifyEventCB(GdkEventMotion *event) { g_debug("%s: enter x %f y %f state 0x%x\n", __FUNCTION__, event->x, event->y, event->state); return true; } /** * Track configure events on detection window. * * @param[in] event event data * * @return always true. */ bool DnDUIX11::GtkConfigureEventCB(GdkEventConfigure *event) { g_debug("%s: enter x %d y %d width %d height %d\n", __FUNCTION__, event->x, event->y, event->width, event->height); return true; } /** * Track button press events on detection window. * * @param[ignored] event event data (ignored) * * @return always true. */ bool DnDUIX11::GtkButtonPressEventCB(GdkEventButton *event) { g_debug("%s: enter\n", __FUNCTION__); return true; } /** * Track button release events on detection window. * * @param[ignored] event event data (ignored) * * @return always true. */ bool DnDUIX11::GtkButtonReleaseEventCB(GdkEventButton *event) { g_debug("%s: enter\n", __FUNCTION__); return true; } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/stringxx/0000755765153500003110000000000012220061556021721 5ustar dtormtsopen-vm-tools-9.4.0-1280544/services/plugins/dndcp/stringxx/string.cc0000644765153500003110000013153212220061556023543 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * string.cc -- * * A string wrapper for bora/lib/unicode. This class is intended to provide * more c++ features such as operator overloading, automatic string conversion * between different types of string classes. */ #include #include #include "string.hh" #include "unicode.h" #include "util.h" namespace utf { /* * Initialize static scope variables, * * Note that with the way this is done, it's important not to delay load glib * libraries. See bug 397373 for more details. If you're getting crazy values * for utf::string::npos, check your linker flags. */ const string::size_type string::npos = Glib::ustring::npos; /* *----------------------------------------------------------------------------- * * utf::string::string -- * * Constructor. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ string::string() : mUstr(), mUtf16Cache(NULL), mUtf16Length(npos) { } /* *----------------------------------------------------------------------------- * * utf::string::string -- * * Constructor. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ string::string(ConstUnicode s) // IN : mUstr(), mUtf16Cache(NULL), mUtf16Length(npos) { ASSERT(s); mUstr = Unicode_GetUTF8(s); ASSERT(Validate(mUstr)); } #ifdef _WIN32 /* *----------------------------------------------------------------------------- * * utf::string::string -- * * Constructor from a ubstr_t object. Copies the UTF-16 representation of * the ubstr_t. * * Results: * None. * * Side effects: * Makes a copy of the ubstr_t data and frees that data when the * utf::string is destroyed. * * Note: * WIN32 only call * *----------------------------------------------------------------------------- */ string::string(const ubstr_t &s) // IN : mUstr(), mUtf16Cache(NULL), mUtf16Length(npos) { // If the input is empty, then there's nothing to do. if (s.length() == 0) { return; } mUstr = static_cast(s); ASSERT(Validate(mUstr)); } /* *----------------------------------------------------------------------------- * * utf::string::string -- * * Constructor from a _bstr_t object. Copies the UTF-16 representation of * the _bstr_t. Needed for dealing with _com_error::Description(). * * Results: * None. * * Side effects: * Makes a copy of the _bstr_t data and frees that data when * the utf::string is destroyed. * * Note: * WIN32 only call * *----------------------------------------------------------------------------- */ string::string(const _bstr_t &s) // IN : mUstr(), mUtf16Cache(NULL), mUtf16Length(npos) { // If the input is empty, then there's nothing to do. if (s.length() == 0) { return; } Unicode utf8 = Unicode_AllocWithUTF16(static_cast(s)); try { mUstr = utf8; Unicode_Free(utf8); } catch (...) { Unicode_Free(utf8); throw; } ASSERT(Validate(mUstr)); } #endif /* *----------------------------------------------------------------------------- * * utf::string::string -- * * Constructor. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ string::string(const utf16string &s) // IN : mUstr(), mUtf16Cache(NULL), mUtf16Length(npos) { // If the input is empty, then there's nothing to do. if (s.empty()) { return; } string copy(s.c_str()); swap(copy); } /* *----------------------------------------------------------------------------- * * utf::string::string -- * * Constructor. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ string::string(const utf16_t *s) // IN : mUstr(), mUtf16Cache(NULL), mUtf16Length(npos) { ASSERT(s != NULL); /* * Since we already have a UTF-16 representation of the string, copy it * now. */ mUtf16Cache = Unicode_UTF16Strdup(s); Unicode utf8 = Unicode_AllocWithUTF16(s); try { mUstr = utf8; Unicode_Free(utf8); } catch (...) { Unicode_Free(utf8); throw; } ASSERT(Validate(mUstr)); } /* *----------------------------------------------------------------------------- * * utf::string::string -- * * Constructor. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ string::string(const char *s, // IN StringEncoding encoding) // IN : mUstr(), mUtf16Cache(NULL), mUtf16Length(npos) { ASSERT(s != NULL); Unicode utf8 = Unicode_Alloc(s, encoding); try { mUstr = utf8; Unicode_Free(utf8); } catch (...) { Unicode_Free(utf8); throw; } ASSERT(Validate(mUstr)); } /* *----------------------------------------------------------------------------- * * utf::string::string -- * * Constructor. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ string::string(const Glib::ustring& s) // IN : mUstr(s), mUtf16Cache(NULL), mUtf16Length(npos) { ASSERT(Validate(s)); } /* *----------------------------------------------------------------------------- * * utf::string::string -- * * Copy constructor. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ string::string(const string& s) // IN : mUstr(s.mUstr), mUtf16Cache(NULL), mUtf16Length(npos) { } /* *----------------------------------------------------------------------------- * * utf::string::~string -- * * Destructor. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ string::~string() { InvalidateCache(); } /* *----------------------------------------------------------------------------- * * utf::string::operator Glib::ustring -- * * Implicit conversion to Glib::ustring operator * * Results: * The internal Glib::ustring object. * * Side effects: * None. * *----------------------------------------------------------------------------- */ string::operator const Glib::ustring& () const { return ustr(); } #ifdef _WIN32 /* *----------------------------------------------------------------------------- * * utf::string::operator ubstr_t -- * * Implicit conversion to ubstr_t * * Results: * The current ubstr_t string. NUL-terminated. * * Side effects: * None * * Note: * This function is only defined in _WIN32 * *----------------------------------------------------------------------------- */ string::operator const ubstr_t() const { return ubstr_t(GetUtf16Cache()); } #endif /* *----------------------------------------------------------------------------- * * utf::string::operator= -- * * Assignment operator. * * Results: * A reference to this string. * * Side effects: * None * *----------------------------------------------------------------------------- */ string& string::operator=(string copy) // IN { swap(copy); return *this; } /* *----------------------------------------------------------------------------- * * utf::string::operator+= -- * * Append operator of the utf::string class. * * Results: * A reference to this string. * * Side effects: * None * *----------------------------------------------------------------------------- */ string& string::operator+=(const string &s) // IN { return append(s); } string& string::operator+=(value_type uc) // IN { push_back(uc); return *this; } /* *----------------------------------------------------------------------------- * * utf::string::swap -- * * Swaps the contents with a given utf::string. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ void string::swap(string &s) // IN/OUT { mUstr.swap(s.mUstr); std::swap(mUtf16Cache, s.mUtf16Cache); std::swap(mUtf16Length, s.mUtf16Length); } /* *----------------------------------------------------------------------------- * * utf::string::resize -- * * Change the size of this utf::string. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ void string::resize(size_type n, // IN value_type c) // IN/OPT { InvalidateCache(); mUstr.resize(n, c); } /* *----------------------------------------------------------------------------- * * utf::string::c_str -- * * Get the UTF-8 representation of this string. * * Results: * The current string with UTF-8 encoding. NUL-terminated. * * Side effects: * None * *----------------------------------------------------------------------------- */ const char * string::c_str() const { return mUstr.c_str(); } /* *----------------------------------------------------------------------------- * * utf::string::w_str -- * * Get the UTF-16 representation of this string. * * Results: * The current string with UTF-16 (host-endian) encoding. NUL-terminated. * * Side effects: * None * *----------------------------------------------------------------------------- */ const utf16_t * string::w_str() const { return GetUtf16Cache(); } /* *----------------------------------------------------------------------------- * * utf::string::ustr -- * * Get the Glib::ustring backing of this string. * * Results: * The internal Glib::ustring object. * * Side effects: * None * *----------------------------------------------------------------------------- */ const Glib::ustring& string::ustr() const { return mUstr; } /* *----------------------------------------------------------------------------- * * utf::string::empty -- * * Test if this is an empty string. * * Results: * true if it's an empty string, otherwise false. * * Side effects: * None * *----------------------------------------------------------------------------- */ bool string::empty() const { return mUstr.empty(); } /* *----------------------------------------------------------------------------- * * utf::string::size -- * * Results: * Returns the length of this string, in characters (code points), * excluding NUL. * * Side effects: * None * *----------------------------------------------------------------------------- */ string::size_type string::size() const { return mUstr.size(); } /* *----------------------------------------------------------------------------- * * utf::string::w_size -- * * Results: * Returns the length of this string, in UTF-16 code units, * excluding NUL. * * Side effects: * None * *----------------------------------------------------------------------------- */ string::size_type string::w_size() const { if (mUtf16Length == npos) { mUtf16Length = Unicode_UTF16Strlen(GetUtf16Cache()); } return mUtf16Length; } /* *----------------------------------------------------------------------------- * * utf::string::length -- * * Results: * Returns the length of this string, in characters (code points), * excluding NUL. (Same as size().) * * Side effects: * None * *----------------------------------------------------------------------------- */ string::size_type string::length() const { return size(); } /* *----------------------------------------------------------------------------- * * utf::string::bytes -- * * Results: * Returns the number of bytes used by the UTF-8 representation of this * string, excluding NUL. * * Side effects: * None * *----------------------------------------------------------------------------- */ string::size_type string::bytes() const { return mUstr.bytes(); } /* *----------------------------------------------------------------------------- * * utf::string::foldCase -- * * Returns the case-folded string of this string. * * Results: * The newly created string. * * Side effects: * None * *----------------------------------------------------------------------------- */ string string::foldCase() const { return string(mUstr.casefold()); } /* *----------------------------------------------------------------------------- * * utf::string::trim -- * * Returns the whitespace-trimmed version of this string. * * Results: * The newly created string. * * Side effects: * None * *----------------------------------------------------------------------------- */ string string::trim() const { Unicode trim = Unicode_Trim(c_str()); string result(trim); Unicode_Free(trim); return result; } /* *----------------------------------------------------------------------------- * * utf::string::trimLeft -- * * Get the left-trimmed version of this string. * * Results: * The newly created string. * * Side effects: * None * *----------------------------------------------------------------------------- */ string string::trimLeft() const { Unicode trim = Unicode_TrimLeft(c_str()); string result(trim); Unicode_Free(trim); return result; } /* *----------------------------------------------------------------------------- * * utf::string::trimRight -- * * Get the right-trimmed version of this string. * * Results: * The newly created string. * * Side effects: * None * *----------------------------------------------------------------------------- */ string string::trimRight() const { Unicode trim = Unicode_TrimRight(c_str()); string result(trim); Unicode_Free(trim); return result; } /* *----------------------------------------------------------------------------- * * utf::string::normalize -- * * Creates a new string by normalizing the input string. * * Results: * The newly created string. * * Side effects: * None * *----------------------------------------------------------------------------- */ string string::normalize(NormalizeMode mode) // IN const { return mUstr.normalize((Glib::NormalizeMode)mode); } /* *----------------------------------------------------------------------------- * * utf::string::toLower -- * * Creates a new string by lower-casing the input string using * the rules of the specified locale. * * Results: * The newly created string. * * Side effects: * None * *----------------------------------------------------------------------------- */ string string::toLower(const char *locale) // IN const { #ifdef USE_ICU Unicode lower = Unicode_ToLower(c_str(), locale); string results(lower); Unicode_Free(lower); #else string results(mUstr.lowercase()); #endif return results; } /* *----------------------------------------------------------------------------- * * utf::string::toUpper -- * * Creates a new string by upper-casing the input string using * the rules of the specified locale. * * Results: * The newly created string. * * Side effects: * None * *----------------------------------------------------------------------------- */ string string::toUpper(const char *locale) // IN const { #ifdef USE_ICU Unicode upper = Unicode_ToUpper(c_str(), locale); string results(upper); Unicode_Free(upper); #else string results(mUstr.uppercase()); #endif return results; } #ifdef USE_ICU /* *----------------------------------------------------------------------------- * * utf::string::toTitle -- * * Creates a new string by title-casing the input string using * the rules of the specified locale. * * Results: * The newly created string. * * Side effects: * None * *----------------------------------------------------------------------------- */ string string::toTitle(const char *locale) // IN const { Unicode title = Unicode_ToTitle(c_str(), locale); string results(title); Unicode_Free(title); return results; } #endif /* *----------------------------------------------------------------------------- * * utf::string::append -- * * Appends the argument string to this utf::string. * * Results: * A reference to this object. * * Side effects: * None * *----------------------------------------------------------------------------- */ string& string::append(const string &s) // IN { InvalidateCache(); mUstr.append(s.mUstr); return *this; } string& string::append(const string &s, // IN size_type i, // IN size_type n) // IN { InvalidateCache(); mUstr.append(s.mUstr, i, n); return *this; } string& string::append(const char *s, // IN size_type n) // IN { InvalidateCache(); mUstr.append(s, n); return *this; } /* *----------------------------------------------------------------------------- * * utf::string::push_back -- * * Appends the character at the end of this string. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void string::push_back(value_type uc) // IN { InvalidateCache(); mUstr.push_back(uc); } /* *----------------------------------------------------------------------------- * * utf::string::assign -- * * Assigns the passed in string to this string. * * Callers should prefer using operator= instead of assign(). * * Results: * A reference to this object * * Side effects: * None * *----------------------------------------------------------------------------- */ string& string::assign(const string &s) // IN { return operator=(s); } /* *----------------------------------------------------------------------------- * * utf::string::insert -- * * Inserts the argument string to this string at index i, return this * string. * * These are passthrough calls to the Glib::insert calls. * * Results: * A reference to this object * * Side effects: * None * *----------------------------------------------------------------------------- */ string& string::insert(size_type i, // IN const string& s) // IN { InvalidateCache(); mUstr.insert(i, s.mUstr); return *this; } string& string::insert(size_type i, // IN size_type n, // IN value_type uc) { InvalidateCache(); mUstr.insert(i, n, uc); return *this; } string& string::insert(iterator p, // IN value_type uc) // IN { InvalidateCache(); mUstr.insert(p, uc); return *this; } /* *----------------------------------------------------------------------------- * * utf::string::clear -- * * Clears this string. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void string::clear() { InvalidateCache(); mUstr.clear(); } /* *----------------------------------------------------------------------------- * * utf::string::erase -- * * Erase the contents of this string in the specified index range. * * Results: * A reference to this object * * Side effects: * None * *----------------------------------------------------------------------------- */ string& string::erase(size_type i, // IN size_type n) // IN { InvalidateCache(); mUstr.erase(i, n); return *this; } /* *----------------------------------------------------------------------------- * * utf::string::erase -- * * Erase the contents of this string with given iterator. * * Results: * The current iterator. * * Side effects: * None * *----------------------------------------------------------------------------- */ string::iterator string::erase(iterator p) // IN { InvalidateCache(); return mUstr.erase(p); } string::iterator string::erase(iterator pbegin, // IN iterator pend) // IN { InvalidateCache(); return mUstr.erase(pbegin, pend); } /* *----------------------------------------------------------------------------- * * utf::string::replace -- * * Replace the string contents specified by the range, with the passed in * string. * * Results: * A reference to this object. * * Side effects: * None * *----------------------------------------------------------------------------- */ string& string::replace(size_type i, // IN size_type n, // IN const string& s) // IN { InvalidateCache(); mUstr.replace(i, n, s.mUstr); return *this; } /* *----------------------------------------------------------------------------- * * utf::string::replace -- * * Mutates this string by replacing all occurrences of one string with * another. * * Results: * A reference to this object. * * Side effects: * None * *----------------------------------------------------------------------------- */ string& string::replace(const string& from, // IN const string& to) // IN { size_type end; size_type start = 0; size_type fromSize = from.length(); string result; while ((end = find(from, start)) != string::npos) { result += substr(start, end - start); result += to; start = end + fromSize; } if (start < length()) { result += substr(start); } swap(result); return *this; } /* *----------------------------------------------------------------------------- * * utf::string::replace_copy -- * * Results: * Returns a new string with all occurrences of one string replaced by * another. * * Side effects: * None * *----------------------------------------------------------------------------- */ string string::replace_copy(const string& from, // IN const string& to) // IN const { return string(*this).replace(from, to); } /* *----------------------------------------------------------------------------- * * utf::string::compare -- * * A 3-way (output -1, 0, or 1) string comparison. Compares each Unicode * code point of this string to the argument string. * * Results: * -1 if *this < s, 0 if *this == s, 1 if *this > s. * * Side effects: * None * *----------------------------------------------------------------------------- */ int string::compare(const string &s, // IN bool ignoreCase) // IN/OPT: false by default const { return ignoreCase ? Unicode_CompareIgnoreCase(c_str(), s.c_str()) : Unicode_Compare(c_str(), s.c_str()); } int string::compare(size_type i, // IN size_type n, // IN const string &s) // IN const { return mUstr.compare(i, n, s.mUstr); } /* *----------------------------------------------------------------------------- * * utf::string::compareLength -- * * A 3-way (output -1, 0, or 1) string comparison with given length. * Compares only the first len characters (in code units) of the strings. * * Results: * -1 if *this < s, 0 if *this == s, 1 if *this > s. * * Side effects: * None * *----------------------------------------------------------------------------- */ int string::compareLength(const string &s, // IN size_type len, // IN: length in code-point bool ignoreCase) // IN/OPT: false by default const { return substr(0, len).compare(s.substr(0, len), ignoreCase); } /* *----------------------------------------------------------------------------- * * utf::string::compareRange -- * * A 3-way (output -1, 0, or 1) string comparison with given length. * Compares the substrings from this string [thisStart ~ thisStart + thisLength-1] * with the input string str [strStart ~ strStart + strLength - 1]. * * Results: * -1 if *this < s, 0 if *this == s, 1 if *this > s. * * Side effects: * None * *----------------------------------------------------------------------------- */ int string::compareRange(size_type thisStart, // IN: index in code-point size_type thisLength, // IN: length in code-point const string &str, // IN size_type strStart, // IN: index in code-point size_type strLength, // IN: length in code-point bool ignoreCase) // IN/OPT: false by default const { return substr(thisStart, thisLength).compare(str.substr(strStart, strLength), ignoreCase); } /* *----------------------------------------------------------------------------- * * utf::string::find -- * * Searches for the first occurrence of the input string inside this string. * * Results: * If s is found, then, it returns the first starting index of the input string. * Otherwise, returns npos. * * Side effects: * None * *----------------------------------------------------------------------------- */ string::size_type string::find(const string &s, // IN size_type pos) // IN/OPT const { return mUstr.find(s.mUstr, pos); } string::size_type string::find(value_type uc, // IN size_type pos) // IN/OPT const { return mUstr.find(uc, pos); } /* *----------------------------------------------------------------------------- * * utf::string::rfind -- * * Searches for the last occurrence of the input string inside this string. * * Results: * If s is found, then, it returns the last starting index of the input string. * Otherwise, returns npos. * * Side effects: * None * *----------------------------------------------------------------------------- */ string::size_type string::rfind(const string &s, // IN size_type pos) // IN/OPT const { return mUstr.rfind(s.mUstr, pos); } string::size_type string::rfind(value_type uc, // IN size_type pos) // IN/OPT const { return mUstr.rfind(uc, pos); } /* *----------------------------------------------------------------------------- * * utf::string::find_first_of -- * * Find the first occurrence of 's' in this string. 'i' determines where in * the current string we start searching for 's' * * Results: * If s is found, then, it returns the index where s occurs in this * string. * Otherwise, returns npos. * * Side effects: * None * *----------------------------------------------------------------------------- */ string::size_type string::find_first_of(const string &s, // IN size_type i) // IN/OPT const { return mUstr.find_first_of(s.mUstr, i); } string::size_type string::find_first_of(value_type uc, // IN size_type i) // IN/OPT const { return mUstr.find_first_of(uc, i); } /* *----------------------------------------------------------------------------- * * utf::string::find_first_not_of -- * * Find the first occurrence of a string NOT in 's' in this string. 'i' * determines where in this string we start searching to NOT 's'. * * Results: * Returns the index of the first sequence in this string that is not 's' * Otherwise, returns npos. * * Side effects: * None * *----------------------------------------------------------------------------- */ string::size_type string::find_first_not_of(const string &s, // IN size_type i) // IN/OPT const { return mUstr.find_first_not_of(s.mUstr, i); } string::size_type string::find_first_not_of(value_type uc, // IN size_type i) // IN/OPT const { return mUstr.find_first_not_of(uc, i); } /* *----------------------------------------------------------------------------- * * utf::string::find_last_of -- * * Does a reverse search in this string for 's'. 'i' determines where we * start the search for in this string. * * Results: * If s is found, then, it returns the index where s occurs in this * string. * Otherwise, returns npos. * * Side effects: * None * *----------------------------------------------------------------------------- */ string::size_type string::find_last_of(const string &s, // IN size_type i) // IN/OPT const { return mUstr.find_last_of(s.mUstr, i); } string::size_type string::find_last_of(value_type uc, // IN size_type i) // IN/OPT const { return mUstr.find_last_of(uc, i); } /* *----------------------------------------------------------------------------- * * utf::string::find_last_not_of -- * * Searches for the last character within the current string that does * not match any characters in 's'. 'i' determines where we start the * search for in this string. (moving backwards). * * Results: * If NOT 's' is found, then, it returns the index where s does not occurs * in this string. * Otherwise, returns npos. * * Side effects: * None * *----------------------------------------------------------------------------- */ string::size_type string::find_last_not_of(const string &s, // IN size_type i) // IN/OPT const { return mUstr.find_last_not_of(s.mUstr, i); } string::size_type string::find_last_not_of(value_type uc, // IN size_type i) // IN/OPT const { return mUstr.find_last_not_of(uc, i); } /* *----------------------------------------------------------------------------- * * utf::string::substr -- * * Create a substring of this string with given range. * * Results: * The newly created string. * * Side effects: * None * *----------------------------------------------------------------------------- */ string string::substr(size_type start, // IN size_type len) // IN const { return string(mUstr.substr(start, len)); } /* *----------------------------------------------------------------------------- * * utf::string::operator[] -- * * Get the UTF-32 character at given index in this string. * * Results: * UTF-32 character (gunichar). * * Side effects: * None * *----------------------------------------------------------------------------- */ string::value_type string::operator[](size_type i) // IN const { return mUstr[i]; } /* *----------------------------------------------------------------------------- * * utf::string::startsWith -- * * Tests if the current string starts with 's' * * Results: * true if current string starts with 's', false otherwise * * Side effects: * None * *----------------------------------------------------------------------------- */ bool string::startsWith(const string &s, // IN bool ignoreCase) // IN/OPT: false by default const { return UnicodeStartsWith(c_str(), s.c_str(), ignoreCase); } /* *----------------------------------------------------------------------------- * * utf::string::endsWith -- * * Tests if the current string ends with 's' * * Results: * true if current string ends with 's', false otherwise * * Side effects: * None * *----------------------------------------------------------------------------- */ bool string::endsWith(const string &s, // IN bool ignoreCase) // IN/OPT: false by default const { return UnicodeEndsWith(c_str(), s.c_str(), ignoreCase); } /* *----------------------------------------------------------------------------- * * utf::string::split -- * * Return a vector of utf::strings. The vector contains the elements of * the string split by the passed in separator. Empty tokens are not * skipped. If maxStrings is zero, any number of strings will be returned, * otherwise parsing stops after maxStrings - 1 matches of the separator. * In that case, the last string returned includes the rest of the * original string. * * "1,2,3".split(",") -> ["1", "2", "3"] * "1,,".split(",") -> ["1", "", ""] * "1".split(",") -> ["1"] * "1,2,3".split(",", 2) -> ["1", "2,3"] * * XXX If this is to be used for things like command line parsing, support * for quoted strings needs to be added. * * Results: * A vector of utf::strings * * Side effects: * None * *----------------------------------------------------------------------------- */ std::vector string::split(const string &sep, // IN size_t maxStrings) // IN/OPT const { std::vector splitStrings; size_type sIndex = 0; size_type sepLen = sep.length(); size_t count = 0; ASSERT(sepLen > 0); while (true) { size_type index = find(sep, sIndex); count++; if (count == maxStrings || index == npos) { splitStrings.push_back(substr(sIndex)); break; } splitStrings.push_back(substr(sIndex, index - sIndex)); sIndex = index + sepLen; } return splitStrings; } /* *----------------------------------------------------------------------------- * * utf::string::GetUtf16Cache -- * * Return the UTF-16 representation of the current string, this value is * cached, in the object. If the cache is not valid (NULL), then create * the cache value * * Results: * A UTF-16 representation of the current string * * Side effects: * Allocates a UTF16 string * *----------------------------------------------------------------------------- */ const utf16_t * string::GetUtf16Cache() const { if (mUtf16Cache == NULL) { mUtf16Cache = Unicode_GetAllocUTF16(c_str()); } return mUtf16Cache; } /* *----------------------------------------------------------------------------- * * utf::string::InvalidateCache -- * * Frees the cache in this string. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void string::InvalidateCache() { free(mUtf16Cache); mUtf16Cache = NULL; mUtf16Length = npos; } /* *----------------------------------------------------------------------------- * * utf::string::operator+ -- * * Create a new string by appending the input string to this string. * * NOTE: This is not the same as append. append() will modify the * current object, while this will return a new object. * * Results: * The newly created string. * * Side effects: * None * *----------------------------------------------------------------------------- */ string string::operator+(const string &rhs) // IN const { return mUstr + rhs.mUstr; } string string::operator+(value_type uc) // IN const { return mUstr + uc; } /* *----------------------------------------------------------------------------- * * utf::string::operator== -- * * Equality operator for string objects * * Results: * true or false (true if equal) * * Side effects: * None * *----------------------------------------------------------------------------- */ bool string::operator==(const string &rhs) // IN const { return compare(rhs) == 0; } /* *----------------------------------------------------------------------------- * * utf::string::operator!= -- * * Inequality operator for string objects * * Results: * true or false (true if not equal) * * Side effects: * None * *----------------------------------------------------------------------------- */ bool string::operator!=(const string &rhs) // IN const { return compare(rhs) != 0; } /* *----------------------------------------------------------------------------- * * utf::string::operator< -- * * Less than operator for string objects * * Results: * true or false (true if lhs is < rhs) * * Side effects: * None * *----------------------------------------------------------------------------- */ bool string::operator<(const string &rhs) // IN const { return compare(rhs) < 0; } /* *----------------------------------------------------------------------------- * * utf::string::operator> -- * * Greater than operator for string objects * * Results: * true or false (true if lhs is > rhs) * * Side effects: * None * *----------------------------------------------------------------------------- */ bool string::operator>(const string &rhs) // IN const { return compare(rhs) > 0; } /* *----------------------------------------------------------------------------- * * utf::string::operator<= -- * * Less than or equal than operator for string objects * * Results: * true or false (true if lhs is <= rhs) * * Side effects: * None * *----------------------------------------------------------------------------- */ bool string::operator<=(const string &rhs) // IN const { return compare(rhs) <= 0; } /* *----------------------------------------------------------------------------- * * utf::string::operator>= -- * * Greater than or equal than operator for string objects * * Results: * true or false (true if lhs is >= rhs) * * Side effects: * None * *----------------------------------------------------------------------------- */ bool string::operator>=(const string &rhs) // IN const { return compare(rhs) >= 0; } /* *----------------------------------------------------------------------------- * * utf::string::begin -- * * Returns an iterator to the start of the string. * * Results: * iterator * * Side effects: * None * *----------------------------------------------------------------------------- */ string::iterator string::begin() { return mUstr.begin(); } string::const_iterator string::begin() const { return mUstr.begin(); } /* *----------------------------------------------------------------------------- * * utf::string::end -- * * Returns an iterator to the end of the string. * * Results: * iterator * * Side effects: * None * *----------------------------------------------------------------------------- */ string::iterator string::end() { return mUstr.end(); } string::const_iterator string::end() const { return mUstr.end(); } /* *----------------------------------------------------------------------------- * * utf::Validate -- * * Validates the string. * * Results: * true if the string contains is valid UTF-8, false otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ bool Validate(const Glib::ustring& s) // IN { bool isValid = s.validate(); if (!isValid) { char *escaped = Unicode_EscapeBuffer(s.c_str(), -1, STRING_ENCODING_UTF8); Warning("Invalid UTF-8 string: \"%s\"\n", escaped); free(escaped); } return isValid; } /* *----------------------------------------------------------------------------- * * utf::CreateWithLength -- * * A wrapper function for Unicode_AllocWithLength() that returns a utf::string. * * Results: * A utf::string created with given parameters. * * Side effects: * None * *----------------------------------------------------------------------------- */ string CreateWithLength(const void *buffer, // IN ssize_t lengthInBytes, // IN: NUL not included StringEncoding encoding) // IN { if (!Unicode_IsBufferValid(buffer, lengthInBytes, encoding)) { throw ConversionError(); } Unicode utf8 = Unicode_AllocWithLength(buffer, lengthInBytes, encoding); try { string result(utf8); Unicode_Free(utf8); return result; } catch (...) { Unicode_Free(utf8); throw; } } /* *---------------------------------------------------------------------- * * utf::CreateWithBOMBuffer -- * * Convert a text buffer with BOM (byte-order mark) to utf::string. * If BOM not present, assume it's UTF-8. * * Results: * A utf::string containing the text buffer. * * Side Effect: * None. * *---------------------------------------------------------------------- */ string CreateWithBOMBuffer(const void *buffer, // IN ssize_t lengthInBytes) // IN: NUL not included { struct BOMMap { uint8 bom[4]; // BOM with max size. ssize_t len; // Length of BOM. StringEncoding encoding; // Encoding if a BOM is present. }; static const BOMMap mapBOM[] = { {{0}, 0, STRING_ENCODING_UTF8 }, // Default encoding. {{0xEF, 0xBB, 0xBF}, 3, STRING_ENCODING_UTF8 }, {{0xFE, 0xFF}, 2, STRING_ENCODING_UTF16_BE }, {{0xFF, 0xFE}, 2, STRING_ENCODING_UTF16_LE }, {{0x00, 0x00, 0xFE, 0xFF}, 4, STRING_ENCODING_UTF32_BE }, {{0xFF, 0xFE, 0x00, 0x00}, 4, STRING_ENCODING_UTF32_LE } }; ASSERT(lengthInBytes >= 0); unsigned int index = 0; // Default encoding, no need to check. for (unsigned int i = 1; i < ARRAYSIZE(mapBOM); i++) { if ( lengthInBytes >= mapBOM[i].len && memcmp(mapBOM[i].bom, buffer, mapBOM[i].len) == 0) { index = i; break; } } return CreateWithLength(reinterpret_cast(buffer) + mapBOM[index].len, lengthInBytes - mapBOM[index].len, mapBOM[index].encoding); } /* *----------------------------------------------------------------------------- * * utf::IntToStr -- * * Converts an integer to a utf::string. * * Results: * A utf::string created with the given integer. * * Side effects: * None * *----------------------------------------------------------------------------- */ string IntToStr(int64 val) // IN { std::ostringstream ostream; ostream << val; return ostream.str().c_str(); } /* *----------------------------------------------------------------------------- * * utf::CopyArray -- * * Copies an array to a vector. * Guaranteed to not shrink the vector. * * Results: * A vector containing a shallow copy of the array. * * Side effects: * None * *----------------------------------------------------------------------------- */ template static void CopyArray(const T *p, // IN: size_t n, // IN: The number of array elements to copy. std::vector& buf) // OUT: { if (n > buf.size()) { buf.resize(n); } if (!buf.empty()) { ASSERT(p != NULL); memcpy(&buf[0], p, n * sizeof buf[0]); } } /* *----------------------------------------------------------------------------- * * utf::CreateWritableBuffer -- * * Copies a utf::string to a writable buffer. * Guaranteed to never shrink the size of the destination buffer. * * Results: * A std::vector containing the NUL-terminated string data. * The size of the resulting vector may exceed the length of the * NUL-terminated string. * * Side effects: * None * *----------------------------------------------------------------------------- */ void CreateWritableBuffer(const string& s, // IN: std::vector& buf) // OUT: A copy of the string, as UTF-8. { CopyArray(s.c_str(), s.bytes() + 1, buf); } void CreateWritableBuffer(const string& s, // IN: std::vector& buf) // OUT: A copy of the string, as UTF-16. { CopyArray(s.w_str(), s.w_size() + 1, buf); } } // namespace utf open-vm-tools-9.4.0-1280544/services/plugins/dndcp/stringxx/ubstr_t.hh0000644765153500003110000004552312220061556023735 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * ubstr_t.hh -- * * A string wrapper for _bstr_t. _bstr_t assumes all char* strings use * the local MBCS encoding, but we want to require that char* strings be * interpreted as UTF-8. */ #ifndef _WIN32 #error This file should be built on Windows only. #endif #pragma once #include #include #include extern "C" { #include "unicode.h" #include "util.h" } #ifdef I_LOVE_BSTR_T_CLASSIC typedef _bstr_t ubstr_t; typedef _variant_t uvariant_t; #else class ubstr_t { public: ubstr_t(); ubstr_t(const char *s); ubstr_t(const wchar_t *s); ubstr_t(const _variant_t& var); explicit ubstr_t(const _bstr_t& bstr); ubstr_t(BSTR bstr, bool copy); ubstr_t(const ubstr_t& s); ubstr_t& operator=(ubstr_t copy); ubstr_t& operator=(const char *s); ubstr_t& operator=(const wchar_t *s); ubstr_t& operator=(const _variant_t& var); // Wrappers around standard _bstr_t methods. void Assign(BSTR s); BSTR copy(bool copy = true) const; void Attach(BSTR s); BSTR Detach(); BSTR *GetAddress(); BSTR& GetBSTR(); unsigned int length() const; ubstr_t& operator+=(const ubstr_t& s); ubstr_t operator+(const ubstr_t& s) const; ubstr_t operator+(const char *s) const; ubstr_t operator+(const wchar_t *s) const; bool operator!() const; bool operator==(const ubstr_t& s) const; bool operator!=(const ubstr_t& s) const; bool operator<(const ubstr_t& s) const; bool operator>(const ubstr_t& s) const; bool operator<=(const ubstr_t& s) const; bool operator>=(const ubstr_t& s) const; operator const wchar_t*() const; operator wchar_t*() const; // XXX: Get rid of this. operator const char*() const; #ifndef I_HATE_NON_CONST_BSTR_T_CASTS operator char*() const; // XXX: Get rid of this. #endif /* * _variant_t is implicitly constructible from a _bstr_t. Since we can't * add a constructor to _variant_t, instead provide an implicit conversion * from ubstr_t to _variant_t. */ operator _variant_t() const; void swap(ubstr_t& s); private: class UTF8Data { public: // Takes ownership of the input string. UTF8Data(char *utf8String = NULL) // IN/OUT: May be NULL : mUTF8String(utf8String), mRefCount(1) { } // For Glib::RefPtr. void reference() { ++mRefCount; } // For Glib::RefPtr. void unreference() { --mRefCount; if (mRefCount == 0) { delete this; } } // Takes ownership of the input string. void Set(char *utf8String) // IN/OUT: May be NULL. { free(mUTF8String); mUTF8String = utf8String; } char *Get() { return mUTF8String; } private: // Only destructible via unreference(). ~UTF8Data() { free(mUTF8String); } char *mUTF8String; unsigned int mRefCount; private: // Intentionally unimplemented. UTF8Data(const UTF8Data&); UTF8Data& operator=(const UTF8Data&); }; char *GetUTF8Cache() const; void InvalidateCache(); /* * Anything that mutates mBstr (all non-const methods) must call * InvalidateCache(). */ _bstr_t mBstr; // mUTF8 is allocated and initialized lazily. mutable Glib::RefPtr mUTF8; }; /* * _variant_t does string conversions too, so we also need to wrap that. * Since _variant_t doesn't keep a cached version of the locally-encoded * MBCS string and since we don't use _variant_t nearly as much as _bstr_t, * substitutability isn't as much of a concern, so we can use inheritance. */ class uvariant_t : public _variant_t { public: /* * Wrappers around standard _variant_t constructors. Unfortunately we * have to wrap all the constructors since they aren't inherited. */ uvariant_t() : _variant_t() { } uvariant_t(const VARIANT& var) : _variant_t(var) { } uvariant_t(const VARIANT *var) : _variant_t(var) { } uvariant_t(const _variant_t& var) : _variant_t(var) { } uvariant_t(VARIANT& var, bool copy) : _variant_t(var, copy) { } uvariant_t(short i, VARTYPE vt = VT_I2) : _variant_t(i, vt) { } uvariant_t(long i, VARTYPE vt = VT_I4) : _variant_t(i, vt) { } uvariant_t(float f) : _variant_t(f) { } uvariant_t(double d, VARTYPE vt = VT_R8) : _variant_t(d, vt) { } uvariant_t(const CY& cy) : _variant_t(cy) { } uvariant_t(const _bstr_t& s) : _variant_t(s) { } uvariant_t(const wchar_t *s) : _variant_t(s) { } uvariant_t(IDispatch *dispatch, bool addRef = true) : _variant_t(dispatch, addRef) { } uvariant_t(bool b) : _variant_t(b) { } uvariant_t(IUnknown *unknown, bool addRef = true) : _variant_t(unknown, addRef) { } uvariant_t(const DECIMAL& dec) : _variant_t(dec) { } uvariant_t(BYTE i) : _variant_t(i) { } uvariant_t(char c) : _variant_t(c) { } uvariant_t(unsigned short i) : _variant_t(i) { } uvariant_t(unsigned long i) : _variant_t(i) { } uvariant_t(int i) : _variant_t(i) { } uvariant_t(unsigned int i) : _variant_t(i) { } #if _WIN32_WINNT >= 0x0501 uvariant_t(__int64 i) : _variant_t(i) { } uvariant_t(unsigned __int64 i) : _variant_t(i) { } #endif // Override the _variant_t constructor that assumes locally-encoded strings. uvariant_t(const char *s) : _variant_t(ubstr_t(s)) { } // Provide conversion from our ubstr_t wrapper. uvariant_t(const ubstr_t& s) : _variant_t(s) { } }; /* *----------------------------------------------------------------------------- * * ubstr_t::ubstr_t -- * * ubstr_t constructors. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ inline ubstr_t::ubstr_t() : mBstr(), mUTF8() { } inline ubstr_t::ubstr_t(const char *s) // IN: A UTF-8-encoded string. : mBstr(), mUTF8() { if (s != NULL) { // Since we already have the UTF-8 version of the string, cache it now. mUTF8 = Glib::RefPtr(new UTF8Data(Util_SafeStrdup(s))); utf16_t *utf16Str = Unicode_GetAllocUTF16(s); try { mBstr = utf16Str; free(utf16Str); } catch (...) { free(utf16Str); throw; } } } inline ubstr_t::ubstr_t(const wchar_t *s) // IN : mBstr(s), mUTF8() { } inline ubstr_t::ubstr_t(const _variant_t& var) // IN : mBstr(var), mUTF8() { } inline ubstr_t::ubstr_t(const _bstr_t& bstr) // IN : mBstr(bstr), mUTF8() { } inline ubstr_t::ubstr_t(BSTR bstr, // IN bool copy) // IN : mBstr(bstr, copy), mUTF8() { } inline ubstr_t::ubstr_t(const ubstr_t& s) // IN : mBstr(s.mBstr), mUTF8(s.mUTF8) { if (static_cast(mBstr) != NULL && !mUTF8) { mUTF8 = s.mUTF8 = Glib::RefPtr(new UTF8Data()); } } /* *----------------------------------------------------------------------------- * * ubstr_t::operator= -- * * ubstr_t assignment operators. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ inline ubstr_t& ubstr_t::operator=(ubstr_t copy) // IN { swap(copy); return *this; } inline ubstr_t& ubstr_t::operator=(const char *s) // IN: A UTF-8-encoded string. { return operator=(ubstr_t(s)); } inline ubstr_t& ubstr_t::operator=(const wchar_t *s) // IN { return operator=(ubstr_t(s)); } inline ubstr_t& ubstr_t::operator=(const _variant_t& var) // IN { return operator=(ubstr_t(var)); } /* *----------------------------------------------------------------------------- * * ubstr_t::Assign -- * * Wrapper around _bstr_t::Assign. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ inline void ubstr_t::Assign(BSTR s) // IN { InvalidateCache(); mBstr.Assign(s); } /* *----------------------------------------------------------------------------- * * ubstr_t::copy -- * * Wrapper around _bstr_t::copy. * * Results: * A copy of the underlying BSTR. * * Side effects: * None. * *----------------------------------------------------------------------------- */ inline BSTR ubstr_t::copy(bool copy) // IN/OPT const { return mBstr.copy(copy); } /* *----------------------------------------------------------------------------- * * ubstr_t::Attach -- * * Wrapper around _bstr_t::Attach. * * Results: * None. * * Side effects: * Invalidates the UTF-8 cache. * *----------------------------------------------------------------------------- */ inline void ubstr_t::Attach(BSTR s) // IN { InvalidateCache(); mBstr.Attach(s); } /* *----------------------------------------------------------------------------- * * ubstr_t::Detach -- * * Wrapper around _bstr_t::Detach. * * Results: * The underlying BSTR, which is no longer managed. * * Side effects: * Invalidates the UTF-8 cache. * *----------------------------------------------------------------------------- */ inline BSTR ubstr_t::Detach() { InvalidateCache(); return mBstr.Detach(); } /* *----------------------------------------------------------------------------- * * ubstr_t::GetAddress -- * * Wrapper around _bstr_t::GetAddress. * * Results: * A pointer to the underlying BSTR. * * Side effects: * Invalidates the UTF-8 cache. * *----------------------------------------------------------------------------- */ inline BSTR * ubstr_t::GetAddress() { /* * We don't know if the underlying BSTR will be modified via the returned * pointer. We can only assume it will. */ InvalidateCache(); return mBstr.GetAddress(); } /* *----------------------------------------------------------------------------- * * ubstr_t::GetBSTR -- * * Wrapper around _bstr_t::GetBSTR. * * Results: * A reference to the underlying BSTR. * * Side effects: * Invalidates the UTF-8 cache. * *----------------------------------------------------------------------------- */ inline BSTR& ubstr_t::GetBSTR() { /* * We don't know if the underlying BSTR will be modified via the returned * reference. We can only assume it will. */ InvalidateCache(); return mBstr.GetBSTR(); } /* *----------------------------------------------------------------------------- * * ubstr_t::length -- * * Wrapper around _bstr_t::length. * * Results: * The length of the string, in TCHARs. * * Side effects: * None. * *----------------------------------------------------------------------------- */ inline unsigned int ubstr_t::length() const { return mBstr.length(); } /* *----------------------------------------------------------------------------- * * ubstr_t::operator+= -- * * Mutating concatenation operator. * * Results: * A reference to this ubstr_t object. * * Side effects: * Invalidates the UTF-8 cache. * *----------------------------------------------------------------------------- */ inline ubstr_t& ubstr_t::operator+=(const ubstr_t& s) // IN { InvalidateCache(); mBstr += s.mBstr; return *this; } /* *----------------------------------------------------------------------------- * * ubstr_t::operator+ -- * * Concatenation operators. * * Results: * A copy of the concatenated string. * * Side effects: * None. * *----------------------------------------------------------------------------- */ inline ubstr_t ubstr_t::operator+(const ubstr_t& s) // IN const { ubstr_t copy(*this); copy += s; return copy; } inline ubstr_t ubstr_t::operator+(const char *s) // IN const { return operator+(ubstr_t(s)); } inline ubstr_t ubstr_t::operator+(const wchar_t *s) // IN const { return operator+(ubstr_t(s)); } /* *----------------------------------------------------------------------------- * * ubstr_t::operator! -- * * Wrapper around _bstr_t::operator!. * * Results: * true if the underlying _bstr_t is NULL, false otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ inline bool ubstr_t::operator!() const { return !mBstr; } /* *----------------------------------------------------------------------------- * * ubstr_t::operator== -- * ubstr_t::operator!= -- * ubstr_t::operator< -- * ubstr_t::operator> -- * ubstr_t::operator<= -- * ubstr_t::operator>= -- * * Wrappers around _bstr_t's comparison operators. * * Results: * true if the comparisons are hold, false otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ inline bool ubstr_t::operator==(const ubstr_t& s) // IN const { return mBstr == s.mBstr; } inline bool ubstr_t::operator!=(const ubstr_t& s) // IN const { return mBstr != s.mBstr; } inline bool ubstr_t::operator<(const ubstr_t& s) // IN const { return mBstr < s.mBstr; } inline bool ubstr_t::operator>(const ubstr_t& s) // IN const { return mBstr > s.mBstr; } inline bool ubstr_t::operator<=(const ubstr_t& s) // IN const { return mBstr <= s.mBstr; } inline bool ubstr_t::operator>=(const ubstr_t& s) // IN const { return mBstr >= s.mBstr; } /* *----------------------------------------------------------------------------- * * ubstr_t::operator const wchar_t* -- * ubstr_t::operator wchar_t* -- * * Wrappers around _bstr_t's cast operators. * * Results: * A pointer to the underlying UTF-16 string. * * Side effects: * None. * *----------------------------------------------------------------------------- */ inline ubstr_t::operator const wchar_t*() const { return static_cast(mBstr); } inline ubstr_t::operator wchar_t*() const { return static_cast(mBstr); } /* *----------------------------------------------------------------------------- * * ubstr_t::operator const char_t* -- * ubstr_t::operator char_t* -- * * Cast operators to UTF-8 strings. * * Results: * A pointer to a UTF-8 string. * * Side effects: * Might initializes the UTF-8 cache. * *----------------------------------------------------------------------------- */ inline ubstr_t::operator const char*() const { return GetUTF8Cache(); } #ifndef I_HATE_NON_CONST_BSTR_T_CASTS inline ubstr_t::operator char*() const { return GetUTF8Cache(); } #endif /* *----------------------------------------------------------------------------- * * ubstr_t::operator _variant_t -- * * Cast operator to _variant_t. * * Results: * A _variant_t equivalent to this ubstr_t object. * * Side effects: * None. * *----------------------------------------------------------------------------- */ inline ubstr_t::operator _variant_t() const { return static_cast(mBstr); } /* *----------------------------------------------------------------------------- * * ubstr_t::swap -- * * Swaps this ubstr_t object with another. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ inline void ubstr_t::swap(ubstr_t& s) // IN/OUT { std::swap(mBstr, s.mBstr); mUTF8.swap(s.mUTF8); } /* *----------------------------------------------------------------------------- * * ubstr_t::GetUTF8Cache -- * * Retrieves the UTF-8 cache, initializing it if necessary. * * Results: * The cached UTF-8 string. * * Side effects: * None. * *----------------------------------------------------------------------------- */ inline char * ubstr_t::GetUTF8Cache() const { if (static_cast(mBstr) == NULL) { // Nothing to do. return NULL; } char *utf8Str = NULL; try { if (!mUTF8) { mUTF8 = Glib::RefPtr(new UTF8Data()); } if (mUTF8->Get() == NULL) { utf8Str = Unicode_AllocWithUTF16(static_cast(mBstr)); mUTF8->Set(utf8Str); } } catch (...) { free(utf8Str); throw; } return mUTF8->Get(); } /* *----------------------------------------------------------------------------- * * ubstr_t::InvalidateCache -- * * Clears the UTF-8 cache. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ inline void ubstr_t::InvalidateCache() { mUTF8.clear(); } /* *----------------------------------------------------------------------------- * * operator+ -- * * Non-member concatenation operators. * * Results: * A copy of the concatenated string. * * Side effects: * None. * *----------------------------------------------------------------------------- */ inline ubstr_t operator+(const char *s1, // IN: A UTF-8-encoded sting. const ubstr_t& s2) // IN { return ubstr_t(s1) + s2; } inline ubstr_t operator+(const wchar_t *s1, // IN const ubstr_t& s2) // IN { return ubstr_t(s1) + s2; } /* * These are not part of the _bstr_t interface but are provided to catch * misuse. They are intentionally unimplemented to avoid a maintenance * burden, and they intentionally return nothing so that accidental usage * normally results in compile-time errors instead of link-time ones. */ void operator==(const char *s1, const ubstr_t& s2); void operator!=(const char *s1, const ubstr_t& s2); void operator<(const char *s1, const ubstr_t& s2); void operator>(const char *s1, const ubstr_t& s2); void operator<=(const char *s1, const ubstr_t& s2); void operator>=(const char *s1, const ubstr_t& s2); void operator==(const WCHAR *s1, const ubstr_t& s2); void operator!=(const WCHAR *s1, const ubstr_t& s2); void operator<(const WCHAR *s1, const ubstr_t& s2); void operator>(const WCHAR *s1, const ubstr_t& s2); void operator<=(const WCHAR *s1, const ubstr_t& s2); void operator>=(const WCHAR *s1, const ubstr_t& s2); #endif // I_LOVE_BSTR_T_CLASSIC open-vm-tools-9.4.0-1280544/services/plugins/dndcp/stringxx/string.hh0000644765153500003110000002261512220061556023556 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * string.hh -- * * A string wrapper for bora/lib/unicode. This class is intended to provide * more c++ features such as operator overloading, automatic string conversion * between different types of string classes. * * This class uses glib::ustring as the underlying storage for its data, * we chose this object because of its internal support for unicode. * */ #ifndef UTF_STRING_HH #define UTF_STRING_HH #include #include #include #ifdef _WIN32 #pragma pack(push, 8) #endif // _WIN32 #include #ifdef _WIN32 #pragma pack(pop) #endif // _WIN32 #ifdef _WIN32 #include "ubstr_t.hh" #endif #include "libExport.hh" extern "C" { #include "unicodeTypes.h" } #ifdef _WIN32 /* * Disabling Windows warning 4251 * This is a warning msg about requiring Glib::ustring to be DLL * exportable. */ #pragma warning(push) #pragma warning(disable:4251) #endif namespace utf { /* utf8string should be replaced with an opaque type. It is temporarily used * to replace the std::string in our codebase. */ typedef std::string utf8string; typedef std::basic_string utf16string; class VMSTRING_EXPORT string { public: // type definitions typedef Glib::ustring::size_type size_type; typedef Glib::ustring::value_type value_type; typedef Glib::ustring::iterator iterator; typedef Glib::ustring::const_iterator const_iterator; // constant definitions static const size_type npos; // Normalize mode map to Glib::NormalizeMode typedef enum { NORMALIZE_DEFAULT = Glib::NORMALIZE_DEFAULT, NORMALIZE_NFD = Glib::NORMALIZE_NFD, NORMALIZE_DEFAULT_COMPOSE = Glib::NORMALIZE_DEFAULT_COMPOSE, NORMALIZE_NFC = Glib::NORMALIZE_NFC, NORMALIZE_ALL = Glib::NORMALIZE_ALL, NORMALIZE_NFKD = Glib::NORMALIZE_NFKD, NORMALIZE_ALL_COMPOSE = Glib::NORMALIZE_ALL_COMPOSE, NORMALIZE_NFKC = Glib::NORMALIZE_NFKC } NormalizeMode; string(); string(ConstUnicode s); #ifdef _WIN32 string(const ubstr_t &s); explicit string(const _bstr_t &s); #endif string(const utf16string &s); string(const utf16_t *s); string(const char *s, StringEncoding encoding); string(const Glib::ustring &s); string(const string &s); ~string(); // Implicit conversions operator const Glib::ustring& () const; #ifdef _WIN32 operator const ubstr_t() const; #endif // Conversions to other i18n types (utf8, utf16, unicode) const char *c_str() const; const utf16_t *w_str() const; const Glib::ustring& ustr() const; // Mapping functions to Glib::ustring void swap(string &s); void resize(size_type n, value_type c = '\0'); bool empty() const; size_type size() const; size_type w_size() const; size_type length() const; size_type bytes() const; string foldCase() const; string trim() const; string trimLeft() const; string trimRight() const; string normalize(NormalizeMode mode = NORMALIZE_DEFAULT_COMPOSE) const; string toLower(const char *locale) const; string toUpper(const char *locale) const; #ifdef USE_ICU string toTitle(const char *locale) const; #endif // String-level member methods. string& append(const string &s); string& append(const string &s, size_type i, size_type n); string& append(const char *s, size_type n); string& assign(const string &s); void push_back(value_type uc); void clear(); string& insert(size_type i, const string& s); string& insert(size_type i, size_type n, value_type uc); string& insert(iterator p, value_type uc); string& erase(size_type i, size_type n = npos); iterator erase(iterator p); iterator erase(iterator pbegin, iterator pend); string& replace(size_type i, size_type n, const string& s); string& replace(const string& from, const string& to); string replace_copy(const string& from, const string& to) const; int compare(const string &s, bool ignoreCase = false) const; int compare(size_type i, size_type n, const string &s) const; int compareLength(const string &s, size_type len, bool ignoreCase = false) const; int compareRange(size_type thisStart, size_type thisLength, const string &str, size_type strStart, size_type strLength, bool ignoreCase = false) const; size_type find(const string &s, size_type pos = 0) const; size_type rfind(const string &s, size_type pos = npos) const; size_type find_first_of(const string &s, size_type i = 0) const; size_type find_first_not_of(const string &s, size_type i = 0) const; size_type find_last_of(const string &s, size_type i = npos) const; size_type find_last_not_of(const string &s, size_type i = npos) const; string substr(size_type start = 0, size_type len = npos) const; // Character-level member methods. value_type operator[](size_type i) const; size_type find(value_type uc, size_type pos = 0) const; size_type rfind(value_type uc, size_type pos = npos) const; size_type find_first_of(value_type uc, size_type i = 0) const; size_type find_first_not_of(value_type uc, size_type i = 0) const; size_type find_last_of(value_type uc, size_type i = npos) const; size_type find_last_not_of(value_type uc, size_type i = npos) const; // Sequence accessor. iterator begin(); iterator end(); const_iterator begin() const; const_iterator end() const; // Operator overloads string& operator=(string copy); string& operator+=(const string &s); string& operator+=(value_type uc); // Some helper functions that are nice to have bool startsWith(const string &s, bool ignoreCase = false) const; bool endsWith(const string &s, bool ignoreCase = false) const; std::vector split(const string &sep, size_t maxStrings = 0) const; // Overloaded operators string operator+(const string &rhs) const; string operator+(value_type uc) const; bool operator==(const string &rhs) const; bool operator!=(const string &rhs) const; bool operator<(const string &rhs) const; bool operator>(const string &rhs) const; bool operator<=(const string &rhs) const; bool operator>=(const string &rhs) const; private: // Cache operations void InvalidateCache(); // Cache accessors const utf16_t *GetUtf16Cache() const; // utf::string is internally backed by Glib::ustring. Glib::ustring mUstr; // Cached representations. mutable utf16_t *mUtf16Cache; mutable size_type mUtf16Length; /* * All added members need to be initialized in all constructors and need * to be handled in swap(). */ }; // Helper operators string inline operator+(ConstUnicode lhs, const string &rhs) { return string(lhs) + rhs; } string inline operator+(const string& lhs, ConstUnicode rhs) { return lhs + string(rhs); } bool inline operator==(ConstUnicode lhs, const string &rhs) { return string(lhs) == rhs; } bool inline operator!=(ConstUnicode lhs, const string &rhs) { return string(lhs) != rhs; } bool inline operator<(ConstUnicode lhs, const string &rhs) { return string(lhs) < rhs; } bool inline operator>(ConstUnicode lhs, const string &rhs) { return string(lhs) > rhs; } bool inline operator<=(ConstUnicode lhs, const string &rhs) { return string(lhs) <= rhs; } bool inline operator>=(ConstUnicode lhs, const string &rhs) { return string(lhs) >= rhs; } // This lets a utf::string appear on the right side of a stream insertion operator. inline std::ostream& operator<<(std::ostream& strm, const string& s) { strm << s.c_str(); return strm; } inline std::wostream& operator<<(std::wostream& strm, const string& s) { strm << s.w_str(); return strm; } // ConversionError class for exception class ConversionError {}; // Helper functions bool VMSTRING_EXPORT Validate(const Glib::ustring& s); string VMSTRING_EXPORT CreateWithLength(const void *buffer, ssize_t lengthInBytes, StringEncoding encoding); string VMSTRING_EXPORT CreateWithBOMBuffer(const void *buffer, ssize_t lengthInBytes); string VMSTRING_EXPORT IntToStr(int64 val); void VMSTRING_EXPORT CreateWritableBuffer(const string& s, std::vector& buf); void VMSTRING_EXPORT CreateWritableBuffer(const string& s, std::vector& buf); } // namespace utf // Template specializations for utf::string. namespace std { template<> inline void swap(utf::string& s1, // IN/OUT utf::string& s2) // IN/OUT { s1.swap(s2); } } // namespace std #ifdef _WIN32 #pragma warning(pop) #endif #endif open-vm-tools-9.4.0-1280544/services/plugins/dndcp/copyPasteDnDImpl.h0000644765153500003110000000346212220061556023370 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file copyPasteDnDImpl.h * * Interface for concrete classes that implement the DnD, Copy paste plugin * abstraction. Implementing DnD/CP for a new guest platform involves creating * a class that inherits CopyPasteDnDImpl. */ #ifndef __COPYPASTEDNDIMPL_H__ #define __COPYPASTEDNDIMPL_H__ extern "C" { #include "vmware.h" #include "vmware/tools/plugin.h" } class CopyPasteDnDImpl { public: virtual ~CopyPasteDnDImpl() {}; virtual gboolean Init(ToolsAppCtx *ctx) = 0; virtual void PointerInit() = 0; virtual gboolean RegisterCP() = 0; virtual void UnregisterCP() = 0; virtual gboolean RegisterDnD() = 0; virtual void UnregisterDnD() = 0; virtual void CopyPasteVersionChanged(const int version) = 0; virtual void DnDVersionChanged(const int version) = 0; virtual void SetCopyPasteAllowed(bool allowed) = 0; virtual void SetDnDAllowed(bool allowed) = 0; virtual uint32 GetCaps() = 0; }; #endif // __COPYPASTEDNDIMPL_H__ open-vm-tools-9.4.0-1280544/services/plugins/dndcp/copyPasteCompat.c0000644765153500003110000000763012220061556023320 0ustar dtormts/********************************************************* * Copyright (C) 2011 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * copyPasteCompat.c -- * * Legacy copy/paste functions. */ #include "backdoor.h" #include "backdoor_def.h" #include "copyPasteCompat.h" /* *----------------------------------------------------------------------------- * * CopyPaste_GetHostSelectionLen -- * * Retrieve the length of the clipboard (if any) to receive from the * VMX. * * Results: * Length >= 0 if a clipboard must be retrieved from the host. * < 0 on error (VMWARE_DONT_EXCHANGE_SELECTIONS or * VMWARE_SELECTION_NOT_READY currently) * * Side effects: * None * *----------------------------------------------------------------------------- */ int32 CopyPaste_GetHostSelectionLen(void) { Backdoor_proto bp; bp.in.cx.halfs.low = BDOOR_CMD_GETSELLENGTH; Backdoor(&bp); return bp.out.ax.word; } /* *----------------------------------------------------------------------------- * * CopyPasteGetNextPiece -- * * Retrieve the next 4 bytes of the host clipboard. * * Results: * The next 4 bytes of the host clipboard. * * Side effects: * None * *----------------------------------------------------------------------------- */ static uint32 CopyPasteGetNextPiece(void) { Backdoor_proto bp; bp.in.cx.halfs.low = BDOOR_CMD_GETNEXTPIECE; Backdoor(&bp); return bp.out.ax.word; } /* *----------------------------------------------------------------------------- * * CopyPaste_GetHostSelection -- * * Retrieve the host clipboard. 'data' must be a buffer whose size is at * least (('size' + 4 - 1) / 4) * 4 bytes. * * Results: * The host clipboard in 'data'. * * Side effects: * None * *----------------------------------------------------------------------------- */ void CopyPaste_GetHostSelection(unsigned int size, // IN char *data) // OUT { uint32 *current; uint32 const *end; current = (uint32 *)data; end = current + (size + sizeof *current - 1) / sizeof *current; for (; current < end; current++) { *current = CopyPasteGetNextPiece(); } } /* *----------------------------------------------------------------------------- * * CopyPaste_SetSelLength -- * * Tell the VMX about the length of the clipboard we are about to send * to it. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void CopyPaste_SetSelLength(uint32 length) // IN { Backdoor_proto bp; bp.in.cx.halfs.low = BDOOR_CMD_SETSELLENGTH; bp.in.size = length; Backdoor(&bp); } /* *----------------------------------------------------------------------------- * * CopyPaste_SetNextPiece -- * * Send the next 4 bytes of the guest clipboard. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void CopyPaste_SetNextPiece(uint32 data) // IN { Backdoor_proto bp; bp.in.cx.halfs.low = BDOOR_CMD_SETNEXTPIECE; bp.in.size = data; Backdoor(&bp); } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/0000755765153500003110000000000012220061556020600 5ustar dtormtsopen-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/dndCPTransport.h0000644765153500003110000000433412220061556023662 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * dndCPTransport.h -- * * DnDCPTransport provides a data transportation interface for both dnd and copyPaste. */ #ifndef DND_CP_TRANSPORT_H #define DND_CP_TRANSPORT_H #ifndef LIB_EXPORT #define LIB_EXPORT #endif extern "C" { #include "vm_basic_types.h" } /* Some definitions for addressId. */ #define MAX_NUM_OF_CONNECTIONS 50 #define BROADCAST_CONNECTION_ID 10000 #define DEFAULT_CONNECTION_ID 10001 #define INVALID_CONNECTION_ID 99999 typedef enum TransportInterfaceType { TRANSPORT_HOST_CONTROLLER_DND = 0, TRANSPORT_HOST_CONTROLLER_CP, TRANSPORT_HOST_CONTROLLER_FT, TRANSPORT_GUEST_CONTROLLER_DND, TRANSPORT_GUEST_CONTROLLER_CP, TRANSPORT_GUEST_CONTROLLER_FT, TRANSPORT_INTERFACE_MAX, } TransportInterfaceType; class RpcBase; #if defined(SWIG) class DnDCPTransport #else class LIB_EXPORT DnDCPTransport #endif { public: virtual ~DnDCPTransport() {}; virtual void StartLoop() {}; virtual void EndLoop() {}; virtual void IterateLoop() {}; virtual bool RegisterRpc(RpcBase *rpc, TransportInterfaceType type) = 0; virtual bool UnregisterRpc(TransportInterfaceType type) = 0; virtual bool SendPacket(uint32 destId, TransportInterfaceType type, const uint8 *msg, size_t length) = 0; }; #endif // DND_CP_TRANSPORT_H open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/fileTransferRpc.hh0000644765153500003110000000335412220061556024217 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @fileTransferRpc.hh -- * * File transfer roc object for DnD/CopyPaste. */ #ifndef FILE_TRANSFER_RPC_HH #define FILE_TRANSFER_RPC_HH #include #include "dndCPLibExport.hh" #include "rpcBase.h" extern "C" { #include "vm_basic_types.h" } class LIB_EXPORT FileTransferRpc : public RpcBase { public: virtual ~FileTransferRpc(void) {}; sigc::signal HgfsPacketReceived; sigc::signal HgfsReplyReceived; virtual void Init(void) = 0; virtual bool SendHgfsPacket(uint32 sessionId, const uint8 *packet, uint32 packetSize) = 0; virtual bool SendHgfsReply(uint32 sessionId, const uint8 *packet, uint32 packetSize) = 0; }; #endif // FILE_TRANSFER_RPC_HH open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/dndClipboard.c0000644765153500003110000004303612220061556023337 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * dndClipboard.c * * Implements dndClipboard.h */ #include #include #include "vm_assert.h" #include "dndClipboard.h" #include "dndInt.h" #include "dndCPMsgV4.h" #include "unicode.h" #define CPFormatToIndex(x) ((unsigned int)(x) - 1) /* *---------------------------------------------------------------------------- * * CPClipItemInit -- * * CPClipboardItem constructor. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static INLINE void CPClipItemInit(CPClipItem *item) // IN/OUT: the clipboard item { ASSERT(item); item->buf = NULL; item->size = 0; item->exists = FALSE; } /* *---------------------------------------------------------------------------- * * CPClipItemDestroy -- * * CPCilpboardItem destructor. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static INLINE void CPClipItemDestroy(CPClipItem *item) // IN/OUT: the clipboard item { ASSERT(item); free(item->buf); item->buf = NULL; item->size = 0; item->exists = FALSE; } /* *---------------------------------------------------------------------------- * * CPClipItemCopy -- * * Copy clipboard item from src to dest. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool CPClipItemCopy(CPClipItem *dest, // IN: dest clipboard item const CPClipItem *src) // IN: source clipboard item { ASSERT(dest); ASSERT(src); if (src->buf) { void *tmp = dest->buf; dest->buf = realloc(dest->buf, src->size + 1); if (!dest->buf) { dest->buf = tmp; return FALSE; } ((uint8 *)dest->buf)[src->size] = 0; memcpy(dest->buf, src->buf, src->size); } dest->size = src->size; dest->exists = src->exists; return TRUE; } /* *---------------------------------------------------------------------------- * * CPClipboard_Init -- * * Constructor for CPClipboard. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void CPClipboard_Init(CPClipboard *clip) // IN/OUT: the clipboard { unsigned int i; ASSERT(clip); clip->changed = TRUE; for (i = CPFORMAT_MIN; i < CPFORMAT_MAX; ++i) { CPClipItemInit(&clip->items[CPFormatToIndex(i)]); } } /* *---------------------------------------------------------------------------- * * CPClipboard_Destroy -- * * Destroys a clipboard. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void CPClipboard_Destroy(CPClipboard *clip) // IN/OUT: the clipboard { unsigned int i; ASSERT(clip); for (i = CPFORMAT_MIN; i < CPFORMAT_MAX; ++i) { CPClipItemDestroy(&clip->items[CPFormatToIndex(i)]); } } /* *---------------------------------------------------------------------------- * * CPClipboard_Clear -- * * Clears the items in CPClipboard. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void CPClipboard_Clear(CPClipboard *clip) // IN/OUT: the clipboard { unsigned int i; ASSERT(clip); clip->changed = TRUE; for (i = CPFORMAT_MIN; i < CPFORMAT_MAX; ++i) { CPClipboard_ClearItem(clip, i); } } /* *---------------------------------------------------------------------------- * * CPClipboard_SetItem -- * * Makes a copy of the item adds it to the clipboard. If something * already exists for the format it is overwritten. To set a promised * type, pass in NULL for buffer and 0 for the size. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool CPClipboard_SetItem(CPClipboard *clip, // IN/OUT: the clipboard const DND_CPFORMAT fmt, // IN: the item format const void *clipitem, // IN: the item const size_t size) // IN: the item size { CPClipItem *item; uint8 *newBuf = NULL; /* * Image, rtf and text may be put into a clipboard at same time, and total * size may be more than limit. Image data will be first dropped, then * rtf data. */ DND_CPFORMAT filterList[] = {CPFORMAT_IMG_PNG, CPFORMAT_RTF, CPFORMAT_TEXT}; int filterIndex = 0; ASSERT(clip); if (!(CPFORMAT_UNKNOWN < fmt && fmt < CPFORMAT_MAX)) { return FALSE; } if (!CPClipboard_ClearItem(clip, fmt)) { return FALSE; } if (size >= CPCLIPITEM_MAX_SIZE_V3) { return FALSE; } item = &clip->items[CPFormatToIndex(fmt)]; if (clipitem) { /* It has to be valid utf8 for plain text format. */ if (CPFORMAT_TEXT == fmt) { char *str = (char *)clipitem; if (!Unicode_IsBufferValid(str, size, STRING_ENCODING_UTF8)) { return FALSE; } } newBuf = malloc(size + 1); if (!newBuf) { return FALSE; } memcpy(newBuf, clipitem, size); newBuf[size] = 0; } item->buf = newBuf; item->size = size; item->exists = TRUE; /* Drop some data if total size is more than limit. */ while (CPClipboard_GetTotalSize(clip) >= CPCLIPITEM_MAX_SIZE_V3 && filterIndex < ARRAYSIZE(filterList)) { if (!CPClipboard_ClearItem(clip, filterList[filterIndex])) { return FALSE; } filterIndex++; } return TRUE; } /* *---------------------------------------------------------------------------- * * CPClipboard_ClearItem -- * * Clears the item in the clipboard. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool CPClipboard_ClearItem(CPClipboard *clip, // IN: the clipboard DND_CPFORMAT fmt) // IN: item to be cleared { CPClipItem *item; ASSERT(clip); if (!(CPFORMAT_UNKNOWN < fmt && fmt < CPFORMAT_MAX)) { return FALSE; } item = &clip->items[CPFormatToIndex(fmt)]; free(item->buf); item->buf = NULL; item->size = 0; item->exists = FALSE; return TRUE; } /* *---------------------------------------------------------------------------- * * CPClipboard_GetItem -- * * Get the clipboard item of format fmt from the clipboard. The clipboard * maintains ownership of the data. If the item is promised, the buffer * will contain NULL and the size will be 0. * * Results: * TRUE if item exists, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool CPClipboard_GetItem(const CPClipboard *clip, // IN: the clipboard DND_CPFORMAT fmt, // IN: the format void **buf, // OUT size_t *size) // OUT { ASSERT(clip); ASSERT(size); ASSERT(buf); if(!(CPFORMAT_UNKNOWN < fmt && fmt < CPFORMAT_MAX)) { return FALSE; } if (clip->items[CPFormatToIndex(fmt)].exists) { *buf = clip->items[CPFormatToIndex(fmt)].buf; *size = clip->items[CPFormatToIndex(fmt)].size; ASSERT(*buf); ASSERT((*size > 0) && (*size < CPCLIPITEM_MAX_SIZE_V3)); return TRUE; } else { ASSERT(!clip->items[CPFormatToIndex(fmt)].size); return FALSE; } } /* *---------------------------------------------------------------------------- * * CPClipboard_ItemExists -- * * Check if the clipboard item of format fmt exists or not. * * Results: * TRUE if item exists, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool CPClipboard_ItemExists(const CPClipboard *clip, // IN: the clipboard DND_CPFORMAT fmt) // IN: the format { ASSERT(clip); if(!(CPFORMAT_UNKNOWN < fmt && fmt < CPFORMAT_MAX)) { return FALSE; } return (clip->items[CPFormatToIndex(fmt)].exists && clip->items[CPFormatToIndex(fmt)].size > 0); } /* *---------------------------------------------------------------------------- * * CPClipboard_IsEmpty -- * * Check if the clipboard item of format fmt exists or not. * * Results: * TRUE if item exists, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool CPClipboard_IsEmpty(const CPClipboard *clip) // IN: the clipboard { unsigned int i; ASSERT(clip); for (i = CPFORMAT_MIN; i < CPFORMAT_MAX; ++i) { if (clip->items[CPFormatToIndex(i)].exists && clip->items[CPFormatToIndex(i)].size > 0) { return FALSE; } } return TRUE; } /* *---------------------------------------------------------------------------- * * CPClipboard_GetTotalSize -- * * Get total buffer size of the clipboard. * * Results: * Total buffer size of the clipboard. * * Side effects: * None. * *---------------------------------------------------------------------------- */ size_t CPClipboard_GetTotalSize(const CPClipboard *clip) // IN: the clipboard { unsigned int i = 0; size_t totalSize = 0; ASSERT(clip); for (i = CPFORMAT_MIN; i < CPFORMAT_MAX; ++i) { if (clip->items[CPFormatToIndex(i)].exists && clip->items[CPFormatToIndex(i)].size > 0) { totalSize += clip->items[CPFormatToIndex(i)].size; } } return totalSize; } /* *---------------------------------------------------------------------------- * * CPClipboard_SetChanged -- * * Set clip->changed. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void CPClipboard_SetChanged(CPClipboard *clip, // IN/OUT: the clipboard Bool changed) // IN { clip->changed = changed; } /* *---------------------------------------------------------------------------- * * CPClipboard_Changed -- * * Return clip->changed. * * Results: * Return clip->changed. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool CPClipboard_Changed(const CPClipboard *clip) // IN: the clipboard { return clip->changed; } /* *---------------------------------------------------------------------------- * * CPClipboard_Copy -- * * Copies the clipboard contents from src to dest. Assumes that dest has * been initialized and contains no data. * * Results: * TRUE on success, FALSE on failure. On failure the caller should * destroy the object to ensure memory is cleaned up. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool CPClipboard_Copy(CPClipboard *dest, // IN: the desination clipboard const CPClipboard *src) // IN: the source clipboard { unsigned int i; ASSERT(dest); ASSERT(src); for (i = CPFORMAT_MIN; i < CPFORMAT_MAX; ++i) { if (!CPClipItemCopy(&dest->items[CPFormatToIndex(i)], &src->items[CPFormatToIndex(i)])) { return FALSE; } } dest->changed = src->changed; return TRUE; } /* *---------------------------------------------------------------------------- * * CPClipboard_Serialize -- * * Serialize the contents of the CPClipboard out to the provided dynbuf. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool CPClipboard_Serialize(const CPClipboard *clip, // IN DynBuf *buf) // OUT: the output buffer { DND_CPFORMAT fmt; uint32 maxFmt = CPFORMAT_MAX; ASSERT(clip); ASSERT(buf); /* First append number of formats in clip. */ if (!DynBuf_Append(buf, &maxFmt, sizeof maxFmt)) { return FALSE; } /* Append format data one by one. */ for (fmt = CPFORMAT_MIN; fmt < CPFORMAT_MAX; ++fmt) { CPClipItem *item = (CPClipItem *)&(clip->items[CPFormatToIndex(fmt)]); if (!DynBuf_Append(buf, &item->exists, sizeof item->exists) || !DynBuf_Append(buf, &item->size, sizeof item->size)) { return FALSE; } if (item->exists && (item->size > 0) && !DynBuf_Append(buf, item->buf, item->size)) { return FALSE; } } if (!DynBuf_Append(buf, &clip->changed, sizeof clip->changed)) { return FALSE; } return TRUE; } /* *---------------------------------------------------------------------------- * * CPClipboard_Unserialize -- * * Unserialize the arguments of the CPClipboard provided by the buffer. * On failure the clip will be destroyed. * * Results: * TRUE if success, FALSE otherwise * * Side effects: * The clip passed in should be empty, otherwise will cause memory leakage. * On success, arguments found in buf are unserialized into clip. * *---------------------------------------------------------------------------- */ Bool CPClipboard_Unserialize(CPClipboard *clip, // OUT: the clipboard const void *buf, // IN: input buffer size_t len) // IN: buffer length { DND_CPFORMAT fmt; BufRead r; uint32 maxFmt; ASSERT(clip); ASSERT(buf); CPClipboard_Init(clip); r.pos = buf; r.unreadLen = len; /* First get number of formats in the buf. */ if (!DnDReadBuffer(&r, &maxFmt, sizeof maxFmt)) { goto error; } /* This version only supports number of formats up to CPFORMAT_MAX. */ maxFmt = MIN(CPFORMAT_MAX, maxFmt); for (fmt = CPFORMAT_MIN; fmt < maxFmt; ++fmt) { Bool exists; uint32 size; if (!DnDReadBuffer(&r, &exists, sizeof exists) || !DnDReadBuffer(&r, &size, sizeof size)) { goto error; } if (exists && size) { if (size > r.unreadLen) { goto error; } if (!CPClipboard_SetItem(clip, fmt, r.pos, size)) { goto error; } if (!DnDSlideBuffer(&r, size)) { goto error; } } } /* It is possible that clip->changed is missing in some beta products. */ if (r.unreadLen == sizeof clip->changed && !DnDReadBuffer(&r, &clip->changed, sizeof clip->changed)) { goto error; } return TRUE; error: CPClipboard_Destroy(clip); return FALSE; } /* *---------------------------------------------------------------------------- * * CPClipboard_Strip -- * * Remove clipboard items based on the passed in capabilities mask. * Introduced in DnDV4. * * XXX This function assumes that the bits in mask are such that if the * check is being made for copy paste, that the corresponding bit for * DnD is set to zero. Otherwise, the format cleared by copy paste will * not be removed. Similar for the other case. A way to make this clearer * would be to pass a flag to this function that tells it which bits * to check, with no dependencies on the other bits being in proper * state. * * Results: * TRUE if clipboard is empty as a result, else FALSE. * *---------------------------------------------------------------------------- */ Bool CPClipboard_Strip(CPClipboard *clip, // IN/OUT: the clipboard uint32 mask) // IN: if TRUE, DnD. { if (!(mask & DND_CP_CAP_PLAIN_TEXT_DND) && !(mask & DND_CP_CAP_PLAIN_TEXT_CP)) { CPClipboard_ClearItem(clip, CPFORMAT_TEXT); } if (!(mask & DND_CP_CAP_RTF_DND) && !(mask & DND_CP_CAP_RTF_CP)) { CPClipboard_ClearItem(clip, CPFORMAT_RTF); } if (!(mask & DND_CP_CAP_IMAGE_DND) && !(mask & DND_CP_CAP_IMAGE_CP)) { CPClipboard_ClearItem(clip, CPFORMAT_IMG_PNG); } if (!(mask & DND_CP_CAP_FILE_DND) && !(mask & DND_CP_CAP_FILE_CP)) { CPClipboard_ClearItem(clip, CPFORMAT_FILELIST); CPClipboard_ClearItem(clip, CPFORMAT_FILELIST_URI); } if (!(mask & DND_CP_CAP_FILE_CONTENT_DND) && !(mask & DND_CP_CAP_FILE_CONTENT_CP)) { CPClipboard_ClearItem(clip, CPFORMAT_FILECONTENTS); } return CPClipboard_IsEmpty(clip); } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/copyPasteRpc.hh0000644765153500003110000000513012220061556023534 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @copyPasteRpc.hh -- * * Rpc layer object for CopyPaste. */ #ifndef COPY_PASTE_RPC_HH #define COPY_PASTE_RPC_HH #include #include "dndCPLibExport.hh" #include "rpcBase.h" extern "C" { #include "dnd.h" } class LIB_EXPORT CopyPasteRpc : public RpcBase { public: virtual ~CopyPasteRpc(void) {}; /* sigc signals for CopyPaste source callback. */ sigc::signal srcRecvClipChanged; sigc::signal requestFilesChanged; sigc::signal getFilesDoneChanged; /* sigc signal for CopyPaste destination callback. */ sigc::signal destRequestClipChanged; /* sigc signal for ping reply callback. */ sigc::signal pingReplyChanged; /* sigc signal for rpc command reply received. */ sigc::signal cmdReplyChanged; virtual void Init(void) = 0; virtual void SendPing(uint32 caps) = 0; /* CopyPaste Rpc functions. */ virtual bool SrcRequestClip(uint32 sessionId, bool isActive) = 0; virtual bool DestSendClip(uint32 sessionId, bool isActive, const CPClipboard* clip) = 0; virtual bool RequestFiles(uint32 sessionId, const uint8 *stagingDirCP, uint32 sz) = 0; virtual bool SendFilesDone(uint32 sessionId, bool success, const uint8 *stagingDirCP, uint32 sz) = 0; virtual bool GetFilesDone(uint32 sessionId, bool success) = 0; }; #endif // COPY_PASTE_RPC_HH open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/copyPasteRpcV4.hh0000644765153500003110000000517112220061556023753 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @copyPasteRpcV4.hh -- * * Rpc layer object for CopyPaste version 4. */ #ifndef COPY_PASTE_RPC_V4_HH #define COPY_PASTE_RPC_V4_HH #include #include "copyPasteRpc.hh" #include "dndCPTransport.h" #include "rpcV4Util.hpp" extern "C" { #include "dnd.h" #include "dndMsg.h" #include "dndCPMsgV4.h" } class LIB_EXPORT CopyPasteRpcV4 : public CopyPasteRpc, public sigc::trackable { public: CopyPasteRpcV4(DnDCPTransport *transport); virtual void Init(void); virtual void SendPing(uint32 caps); /* CopyPaste Rpc functions. */ virtual bool SrcRequestClip(uint32 sessionId, bool isActive); virtual bool DestSendClip(uint32 sessionId, bool isActive, const CPClipboard* clip); virtual bool RequestFiles(uint32 sessionId, const uint8 *stagingDirCP, uint32 sz); virtual bool SendFilesDone(uint32 sessionId, bool success, const uint8 *stagingDirCP, uint32 sz); virtual bool GetFilesDone(uint32 sessionId, bool success); virtual void HandleMsg(RpcParams *params, const uint8 *binary, uint32 binarySize); virtual bool SendPacket(uint32 destId, const uint8 *packet, size_t length); virtual void OnRecvPacket(uint32 srcId, const uint8 *packet, size_t packetSize); private: DnDCPTransport *mTransport; TransportInterfaceType mTransportInterface; RpcV4Util mUtil; }; #endif // COPY_PASTE_RPC_V4_HH open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/dndCPMsgV4.c0000644765153500003110000002446712220061556022632 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @dndCPMsgV4.c -- * * Helper functions for DnDCPMsgV4. */ #include "vm_assert.h" #include "dnd.h" #include "dndClipboard.h" #include "dndCPMsgV4.h" #include "util.h" /** * Check if received packet is valid or not. * * @param[in] packet * @param[in] packetSize * * @return TRUE if the packet is valid, FALSE otherwise. */ static Bool DnDCPMsgV4IsPacketValid(const uint8 *packet, size_t packetSize) { DnDCPMsgHdrV4 *msgHdr = NULL; ASSERT(packet); if (packetSize < DND_CP_MSG_HEADERSIZE_V4) { return FALSE; } msgHdr = (DnDCPMsgHdrV4 *)packet; /* Payload size is not valid. */ if (msgHdr->payloadSize > DND_CP_PACKET_MAX_PAYLOAD_SIZE_V4) { return FALSE; } /* Binary size is not valid. */ if (msgHdr->binarySize > DND_CP_MSG_MAX_BINARY_SIZE_V4) { return FALSE; } /* Payload size is more than binary size. */ if (msgHdr->payloadOffset + msgHdr->payloadSize > msgHdr->binarySize) { return FALSE; } return TRUE; } /** * Initialize the DnDCPMsgV4. * * @param[in/out] msg DnDCPMsgV4 to be initialized. */ void DnDCPMsgV4_Init(DnDCPMsgV4 *msg) { ASSERT(msg); memset(msg, 0, sizeof(DnDCPMsgV4)); } /** * Destroy the DnDCPMsgV4. * * @param[in/out] msg DnDCPMsgV4 to be destroyed. */ void DnDCPMsgV4_Destroy(DnDCPMsgV4 *msg) { if (msg) { free(msg->binary); DnDCPMsgV4_Init(msg); } } /** * Check the packet type. * * @param[in] packet * @param[in] packetSize * * @return DnDCPMsgPacketType */ DnDCPMsgPacketType DnDCPMsgV4_GetPacketType(const uint8 *packet, size_t packetSize) { DnDCPMsgHdrV4 *msgHdr = NULL; ASSERT(packet); if (!DnDCPMsgV4IsPacketValid(packet, packetSize)) { return DND_CP_MSG_PACKET_TYPE_INVALID; } msgHdr = (DnDCPMsgHdrV4 *)packet; if (msgHdr->binarySize <= DND_CP_PACKET_MAX_PAYLOAD_SIZE_V4) { return DND_CP_MSG_PACKET_TYPE_SINGLE; } if (0 == msgHdr->payloadOffset) { return DND_CP_MSG_PACKET_TYPE_MULTIPLE_NEW; } if (msgHdr->payloadOffset + msgHdr->payloadSize == msgHdr->binarySize) { return DND_CP_MSG_PACKET_TYPE_MULTIPLE_END; } return DND_CP_MSG_PACKET_TYPE_MULTIPLE_CONTINUE; } /** * Serialize the msg to packet. * * @param[in/out] msg DnDCPMsgV4 to be serialized from. * @param[out] packet DnDCPMsgV4 to be serialized to. * @param[out] packetSize serialized packet size. * * @return TRUE if succeed, FALSE otherwise. */ Bool DnDCPMsgV4_Serialize(DnDCPMsgV4 *msg, uint8 **packet, size_t *packetSize) { size_t payloadSize = 0; ASSERT(msg); ASSERT(packet); ASSERT(packetSize); ASSERT(msg->hdr.binarySize >= msg->hdr.payloadOffset); if (msg->hdr.binarySize <= DND_CP_PACKET_MAX_PAYLOAD_SIZE_V4) { /* * One single packet is enough for the message. For short message, the * payloadOffset should always be 0. */ ASSERT(msg->hdr.payloadOffset == 0); payloadSize = msg->hdr.binarySize; } else { /* For big message, payloadOffset means binary size we already sent out. */ if (msg->hdr.binarySize - msg->hdr.payloadOffset > DND_CP_PACKET_MAX_PAYLOAD_SIZE_V4) { payloadSize = DND_CP_PACKET_MAX_PAYLOAD_SIZE_V4; } else { payloadSize = msg->hdr.binarySize - msg->hdr.payloadOffset; } } *packetSize = DND_CP_MSG_HEADERSIZE_V4 + payloadSize; *packet = Util_SafeMalloc(*packetSize); memcpy(*packet, msg, DND_CP_MSG_HEADERSIZE_V4); if (payloadSize > 0) { memcpy(*packet + DND_CP_MSG_HEADERSIZE_V4, msg->binary + msg->hdr.payloadOffset, payloadSize); } ((DnDCPMsgHdrV4 *)(*packet))->payloadSize = payloadSize; /* Next DnDCPMsgV4_Serialize will use this payloadOffset to get unsent binary. */ msg->hdr.payloadOffset += payloadSize; return TRUE; } /** * Unserialize the packet to DnDCPMsgV4 for short messsage. * * @param[in/out] msg DnDCPMsgV4 to be unserialized to. * @param[in] packet DnDCPMsgV4 to be unserialized from. * @param[in] packetSize * * @return TRUE if succeed, FALSE otherwise. */ Bool DnDCPMsgV4_UnserializeSingle(DnDCPMsgV4 *msg, const uint8 *packet, size_t packetSize) { DnDCPMsgHdrV4 *msgHdr = NULL; ASSERT(msg); ASSERT(packet); if (!DnDCPMsgV4IsPacketValid(packet, packetSize)) { return FALSE; } msgHdr = (DnDCPMsgHdrV4 *)packet; /* Offset should be 0 for short message. */ if (msgHdr->payloadOffset != 0) { return FALSE; } memcpy(msg, msgHdr, DND_CP_MSG_HEADERSIZE_V4); if (msg->hdr.binarySize != 0) { msg->binary = Util_SafeMalloc(msg->hdr.binarySize); memcpy(msg->binary, packet + DND_CP_MSG_HEADERSIZE_V4, msg->hdr.payloadSize); msg->hdr.payloadOffset = msg->hdr.payloadSize; } return TRUE; } /** * Unserialize the packet to DnDCPMsgV4 for big messsage. * * @param[in/out] msg DnDCPMsgV4 to be unserialized to. * @param[in] packet DnDCPMsgV4 to be unserialized from. * @param[in] packetSize * * @return TRUE if succeed, FALSE otherwise. */ Bool DnDCPMsgV4_UnserializeMultiple(DnDCPMsgV4 *msg, const uint8 *packet, size_t packetSize) { DnDCPMsgHdrV4 *msgHdr = NULL; ASSERT(msg); ASSERT(packet); if (!DnDCPMsgV4IsPacketValid(packet, packetSize)) { return FALSE; } msgHdr = (DnDCPMsgHdrV4 *)packet; /* * For each session, there is at most 1 big message. If the received * sessionId is different with buffered one, the received packet is for * another another new message. Destroy old buffered message. */ if (msg->binary && msg->hdr.sessionId != msgHdr->sessionId) { DnDCPMsgV4_Destroy(msg); } /* Offset should be 0 for new message. */ if (NULL == msg->binary && msgHdr->payloadOffset != 0) { return FALSE; } /* For existing buffered message, the payload offset should match. */ if (msg->binary && msg->hdr.sessionId == msgHdr->sessionId && msg->hdr.payloadOffset != msgHdr->payloadOffset) { return FALSE; } if (NULL == msg->binary) { memcpy(msg, msgHdr, DND_CP_MSG_HEADERSIZE_V4); msg->binary = Util_SafeMalloc(msg->hdr.binarySize); } /* msg->hdr.payloadOffset is used as received binary size. */ memcpy(msg->binary + msg->hdr.payloadOffset, packet + DND_CP_MSG_HEADERSIZE_V4, msgHdr->payloadSize); msg->hdr.payloadOffset += msgHdr->payloadSize; return TRUE; } /** * Map a command to a string. * * @param[in] cmd the DnD V4 command * * @return a valid command string if the command is valid, "invalid command" * otherwise. */ const char * DnDCPMsgV4_LookupCmd(uint32 cmd) { static const struct { uint32 cmd; const char *cmdStr; } cmdStringTable[] = { { DNDCP_CMD_PING, "DNDCP_CMD_PING" }, { DNDCP_CMD_PING_REPLY, "DNDCP_CMD_PING_REPLY" }, { DNDCP_CMD_REQUEST_NEXT, "DNDCP_CMD_REQUEST_NEXT" }, { DNDCP_CMP_REPLY, "DNDCP_CMP_REPLY" }, { DNDCP_CMD_TEST_BIG_BINARY, "DNDCP_CMD_TEST_BIG_BINARY" }, { DNDCP_CMD_TEST_BIG_BINARY_REPLY, "DNDCP_CMD_TEST_BIG_BINARY_REPLY" }, { DND_CMD_DEST_DRAG_ENTER, "DND_CMD_DEST_DRAG_ENTER" }, { DND_CMD_DEST_DRAG_ENTER_REPLY, "DND_CMD_DEST_DRAG_ENTER_REPLY" }, { DND_CMD_DEST_SEND_CLIPBOARD, "DND_CMD_DEST_SEND_CLIPBOARD" }, { DND_CMD_DEST_DRAG_LEAVE, "DND_CMD_DEST_DRAG_LEAVE" }, { DND_CMD_DEST_DROP, "DND_CMD_DEST_DROP" }, { DND_CMD_SRC_DRAG_BEGIN, "DND_CMD_SRC_DRAG_BEGIN" }, { DND_CMD_SRC_DRAG_BEGIN_DONE, "DND_CMD_SRC_DRAG_BEGIN_DONE" }, { DND_CMD_SRC_DROP, "DND_CMD_SRC_DROP" }, { DND_CMD_SRC_DROP_DONE, "DND_CMD_SRC_DROP_DONE" }, { DND_CMD_SRC_CANCEL, "DND_CMD_SRC_CANCEL" }, { DND_CMD_PRIV_DRAG_ENTER, "DND_CMD_PRIV_DRAG_ENTER" }, { DND_CMD_PRIV_DRAG_LEAVE, "DND_CMD_PRIV_DRAG_LEAVE" }, { DND_CMD_PRIV_DROP, "DND_CMD_PRIV_DROP" }, { DND_CMD_MOVE_MOUSE, "DND_CMD_MOVE_MOUSE" }, { DND_CMD_UPDATE_FEEDBACK, "DND_CMD_UPDATE_FEEDBACK" }, { DND_CMD_REQUEST_FILES, "DND_CMD_REQUEST_FILES" }, { DND_CMD_GET_FILES_DONE, "DND_CMD_GET_FILES_DONE" }, { DND_CMD_SEND_FILES_DONE, "DND_CMD_SEND_FILES_DONE" }, { DND_CMD_QUERY_EXITING, "DND_CMD_QUERY_EXITING" }, { DND_CMD_DRAG_NOT_PENDING, "DND_CMD_DRAG_NOT_PENDING" }, { DND_CMD_UPDATE_UNITY_DET_WND, "DND_CMD_UPDATE_UNITY_DET_WND" }, { CP_CMD_REQUEST_CLIPBOARD, "CP_CMD_REQUEST_CLIPBOARD" }, { CP_CMD_REQUEST_FILES, "CP_CMD_REQUEST_FILES" }, { CP_CMD_RECV_CLIPBOARD, "CP_CMD_RECV_CLIPBOARD" }, { CP_CMD_SEND_CLIPBOARD, "CP_CMD_SEND_CLIPBOARD" }, { CP_CMD_GET_FILES_DONE, "CP_CMD_GET_FILES_DONE" }, { CP_CMD_SEND_FILES_DONE, "CP_CMD_SEND_FILES_DONE" }, { FT_CMD_HGFS_REQUEST, "FT_CMD_HGFS_REQUEST" }, { FT_CMD_HGFS_REPLY, "FT_CMD_HGFS_REPLY" }, { FT_CMD_UPDATE_PROGRESS, "FT_CMD_UPDATE_PROGRESS" }, { FT_CMD_PROGRESS_REPLY, "FT_CMD_PROGRESS_REPLY" }, }; size_t i; for (i = 0; i < ARRAYSIZE(cmdStringTable); i++) { if (cmdStringTable[i].cmd == cmd) { return cmdStringTable[i].cmdStr; } } return "invalid command"; } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/dndClipboard.h0000644765153500003110000001035312220061556023340 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * dndClipboard.h * * This file maintains an interface for the clipboard object. The object * may contain several representations of the same object. For * example, we could have a plain text filename as well as the file's * contents on the clipboard at the same time. * * The purpose of this structure is to store cross platform clipboard * data for further processing. The UI is responsible for converting local * clipboard data to a crossplatform format and inserting it into the * cross platform clipboard. */ #ifndef _DND_CLIPBOARD_H_ #define _DND_CLIPBOARD_H_ #include "vm_basic_types.h" #include "dnd.h" #include "dynbuf.h" /* * Make sure each clipboard item is at most 64kb - 100 b. This limitation is * copied from the current text copy paste limit. */ #define CPCLIPITEM_MAX_SIZE_V1 ((1 << 16) - 100) #define CPCLIPITEM_MAX_SIZE_V2 ((1 << 16) - 100) #define CPCLIPITEM_MAX_SIZE_V3 (DNDMSG_MAX_ARGSZ - 100) /* Cross platform formats */ typedef #include "vmware_pack_begin.h" struct CPFileList { uint64 fileSize; uint32 relPathsLen; uint32 fulPathsLen; uint8 filelists[1]; } #include "vmware_pack_end.h" CPFileList; #define CPFILELIST_HEADER_SIZE (1* sizeof(uint64) + 2 * sizeof(uint32)) typedef #include "vmware_pack_begin.h" struct UriFileList { uint64 fileSize; uint32 uriPathsLen; uint8 filelists[1]; } #include "vmware_pack_end.h" UriFileList; #define URI_FILELIST_HEADER_SIZE (1* sizeof(uint64) + 1 * sizeof(uint32)) typedef #include "vmware_pack_begin.h" struct CPFileAttributes { // File, Directory, or link. See HgfsFileType. uint64 fileType; // Read, write, execute permissions. See File_GetFilePermissions(). uint64 filePermissions; } #include "vmware_pack_end.h" CPFileAttributes; typedef #include "vmware_pack_begin.h" struct CPAttributeList { uint32 attributesLen; CPFileAttributes attributeList[1]; } #include "vmware_pack_end.h" CPAttributeList; #define URI_ATTRIBUTES_LIST_HEADER_SIZE (1* sizeof(uint32)) /* Types which can be stored on the clipboard. */ /* * XXX * This is currently in dnd.h, but should be moved over to dndClipboard.h * Ling's vmx code reorg should handle this. */ /* typedef enum { CPFORMAT_UNKNOWN = 0 CPFORMAT_TEXT, CPFORMAT_FILELIST, CPFORMAT_MAX, } DND_CPFORMAT; */ #define CPFORMAT_MIN CPFORMAT_TEXT /* CPClipboard */ void CPClipboard_Init(CPClipboard *clip); void CPClipboard_Destroy(CPClipboard *clip); void CPClipboard_Clear(CPClipboard *clip); Bool CPClipboard_SetItem(CPClipboard *clip, const DND_CPFORMAT fmt, const void *buf, const size_t size); void CPClipboard_SetChanged(CPClipboard *clip, Bool changed); Bool CPClipboard_Changed(const CPClipboard *clip); Bool CPClipboard_ClearItem(CPClipboard *clip, DND_CPFORMAT fmt); Bool CPClipboard_GetItem(const CPClipboard *clip, DND_CPFORMAT fmt, void **buf, size_t *size); Bool CPClipboard_ItemExists(const CPClipboard *clip, DND_CPFORMAT fmt); Bool CPClipboard_IsEmpty(const CPClipboard *clip); #if !defined(SWIG) size_t CPClipboard_GetTotalSize(const CPClipboard *clip); #endif Bool CPClipboard_Copy(CPClipboard *dest, const CPClipboard *src); Bool CPClipboard_Serialize(const CPClipboard *clip, DynBuf *buf); Bool CPClipboard_Unserialize(CPClipboard *clip, const void *buf, size_t len); Bool CPClipboard_Strip(CPClipboard *clip, uint32 caps); #endif // _DND_CLIPBOARD_H_ open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/dndCPMsgV4.h0000644765153500003110000002054012220061556022623 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @dndCPMsgV4.h -- * * DnDCPMsgV4 represents version 4 rpc message/packet for DnD/Copy/Paste. * DnD/CP message/packet is used to pass command between 2 spots (between host * and controller, or between controller and guest). The message/packet is * cross-platform. In sender side, RPC layer should construct dnd/cp message, * serialize it to packet, and transport layer will send the packet to another * side. In receiver side, transport layer will dispatch the packet to right * RPC, and the RPC should unpack the packet into message and send up to common * state machine layer. */ #ifndef DND_CP_MSG_V4_H #define DND_CP_MSG_V4_H #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #include "vm_basic_types.h" /* * These commands will be used as cross-platform DnD/CopyPaste communication. * All common commands start from 0. DnD commands start from 1000. CopyPaste * commands start from 2000. FileTransfer commands start from 3000. */ /* Commands for all channels. */ typedef enum { DNDCP_CMD_INVALID = 0, /* * These 2 commands are used right after any communication channel is * established to exchange some initial information such as version, * capability. */ DNDCP_CMD_PING, DNDCP_CMD_PING_REPLY, /* This command is used for big binary transfer. */ DNDCP_CMD_REQUEST_NEXT, /* * This command is used for general reply for any command. The reply is * optional. Most commands do not need it. */ DNDCP_CMP_REPLY, /* These 2 commands are used for testing big binary transport. */ DNDCP_CMD_TEST_BIG_BINARY, DNDCP_CMD_TEST_BIG_BINARY_REPLY, } DnDCPCmdV4; /* DnD Commands. */ typedef enum { /* For DnD destination. */ DND_CMD_DEST_DRAG_ENTER = 1000, DND_CMD_DEST_DRAG_ENTER_REPLY, DND_CMD_DEST_SEND_CLIPBOARD, DND_CMD_DEST_DRAG_LEAVE, DND_CMD_DEST_DROP, /* For DnD source. */ DND_CMD_SRC_DRAG_BEGIN, DND_CMD_SRC_DRAG_BEGIN_DONE, DND_CMD_SRC_DROP, DND_CMD_SRC_DROP_DONE, DND_CMD_SRC_CANCEL, /* For private DnD. */ DND_CMD_PRIV_DRAG_ENTER, DND_CMD_PRIV_DRAG_LEAVE, DND_CMD_PRIV_DROP, /* For some common DnD operation. */ DND_CMD_MOVE_MOUSE, DND_CMD_UPDATE_FEEDBACK, DND_CMD_REQUEST_FILES, DND_CMD_GET_FILES_DONE, DND_CMD_SEND_FILES_DONE, DND_CMD_QUERY_EXITING, DND_CMD_DRAG_NOT_PENDING, DND_CMD_UPDATE_UNITY_DET_WND, DND_CMD_DEST_CANCEL } DnDCmdV4; /* Copy/Paste commands. */ typedef enum { CP_CMD_REQUEST_CLIPBOARD = 2000, CP_CMD_REQUEST_FILES, CP_CMD_RECV_CLIPBOARD, CP_CMD_SEND_CLIPBOARD, CP_CMD_GET_FILES_DONE, CP_CMD_SEND_FILES_DONE, } CopyPasteCmdV4; /* File transfer commands. */ typedef enum { FT_CMD_HGFS_REQUEST = 3000, FT_CMD_HGFS_REPLY, FT_CMD_UPDATE_PROGRESS, FT_CMD_PROGRESS_REPLY } FileTransferCmdV4; /* Message types. */ typedef enum DnDCPMsgType { DND_CP_MSG_TYPE_INVALID = 0, DND_CP_MSG_TYPE_DND, DND_CP_MSG_TYPE_CP, DND_CP_MSG_TYPE_FT } DnDCPMsgType; /* Message source. */ typedef enum DnDCPMsgSrc { DND_CP_MSG_SRC_INVALID = 0, DND_CP_MSG_SRC_HOST, DND_CP_MSG_SRC_CONTROLLER, DND_CP_MSG_SRC_GUEST } DnDCPMsgSrc; /* Command reply status. */ typedef enum DnDCPMsgStatus { DND_CP_MSG_STATUS_SUCCESS, DND_CP_MSG_STATUS_ERROR, DND_CP_MSG_STATUS_CANCEL, DND_CP_MSG_STATUS_BUSY, DND_CP_MSG_STATUS_ACCEPTED, DND_CP_MSG_STATUS_INVALID_PACKET, DND_CP_MSG_STATUS_INVALID_SESSION_ID, DND_CP_MSG_STATUS_INVALID_FORMAT, } DnDCPMsgStatus; /* Packet types. */ typedef enum DnDCPMsgPacketType { DND_CP_MSG_PACKET_TYPE_SINGLE, DND_CP_MSG_PACKET_TYPE_MULTIPLE_NEW, DND_CP_MSG_PACKET_TYPE_MULTIPLE_CONTINUE, DND_CP_MSG_PACKET_TYPE_MULTIPLE_END, DND_CP_MSG_PACKET_TYPE_INVALID } DnDCPMsgPacketType; /* * Definitions for DnD/CP capabilities. DND_CP_CAP_VALID is used to specify if * the capability itself is valid or not. */ #define DND_CP_CAP_VALID (1 << 0) #define DND_CP_CAP_DND (1 << 1) #define DND_CP_CAP_CP (1 << 2) #define DND_CP_CAP_PLAIN_TEXT_DND (1 << 3) #define DND_CP_CAP_PLAIN_TEXT_CP (1 << 4) #define DND_CP_CAP_RTF_DND (1 << 5) #define DND_CP_CAP_RTF_CP (1 << 6) #define DND_CP_CAP_IMAGE_DND (1 << 7) #define DND_CP_CAP_IMAGE_CP (1 << 8) #define DND_CP_CAP_FILE_DND (1 << 9) #define DND_CP_CAP_FILE_CP (1 << 10) #define DND_CP_CAP_FILE_CONTENT_DND (1 << 11) #define DND_CP_CAP_FILE_CONTENT_CP (1 << 12) #define DND_CP_CAP_ACTIVE_CP (1 << 13) #define DND_CP_CAP_GUEST_PROGRESS (1 << 14) #define DND_CP_CAP_BIG_BUFFER (1 << 15) #define DND_CP_CAP_FORMATS_CP (DND_CP_CAP_PLAIN_TEXT_CP | \ DND_CP_CAP_RTF_CP | \ DND_CP_CAP_IMAGE_CP | \ DND_CP_CAP_FILE_CP | \ DND_CP_CAP_FILE_CONTENT_CP) #define DND_CP_CAP_FORMATS_DND (DND_CP_CAP_PLAIN_TEXT_DND | \ DND_CP_CAP_RTF_DND | \ DND_CP_CAP_IMAGE_DND | \ DND_CP_CAP_FILE_DND | \ DND_CP_CAP_FILE_CONTENT_DND) #define DND_CP_CAP_FORMATS_ALL (DND_CP_CAP_FORMATS_CP | \ DND_CP_CAP_FORMATS_DND) /* * Header definition for DnD version 4 packet. Any DnD version 4 packet has 2 * parts: fixed header and payload. payload is optional. */ typedef #include "vmware_pack_begin.h" struct DnDCPMsgHdrV4 { uint32 cmd; /* DnD/CP message command. */ uint32 type; /* DnD/CP message type. */ uint32 src; /* Message sender. */ uint32 sessionId; /* DnD/CP session ID. */ uint32 status; /* Status for last operation. */ uint32 param1; /* Optional parameter. Optional. */ uint32 param2; /* Optional parameter. Optional. */ uint32 param3; /* Optional parameter. Optional. */ uint32 param4; /* Optional parameter. Optional. */ uint32 param5; /* Optional parameter. Optional. */ uint32 param6; /* Optional parameter. Optional. */ uint32 binarySize; /* Binary size. */ uint32 payloadOffset; /* Payload offset. */ uint32 payloadSize; /* Payload size. */ } #include "vmware_pack_end.h" DnDCPMsgHdrV4; /* Some important definitions for DnDCPMsgV4. */ #define DND_CP_MSG_HEADERSIZE_V4 (sizeof (DnDCPMsgHdrV4)) #define DND_CP_PACKET_MAX_PAYLOAD_SIZE_V4 (DND_MAX_TRANSPORT_PACKET_SIZE - \ DND_CP_MSG_HEADERSIZE_V4) #define DND_CP_MSG_MAX_BINARY_SIZE_V4 (1 << 22) /* DnD version 4 message. */ typedef struct DnDCPMsgV4 { DnDCPMsgHdrV4 hdr; uint32 addrId; uint8 *binary; } DnDCPMsgV4; #if !defined(SWIG) void DnDCPMsgV4_Init(DnDCPMsgV4 *msg); void DnDCPMsgV4_Destroy(DnDCPMsgV4 *msg); DnDCPMsgPacketType DnDCPMsgV4_GetPacketType(const uint8 *packet, size_t packetSize); Bool DnDCPMsgV4_Serialize(DnDCPMsgV4 *msg, uint8 **packet, size_t *packetSize); Bool DnDCPMsgV4_UnserializeSingle(DnDCPMsgV4 *msg, const uint8 *packet, size_t packetSize); Bool DnDCPMsgV4_UnserializeMultiple(DnDCPMsgV4 *msg, const uint8 *packet, size_t packetSize); const char *DnDCPMsgV4_LookupCmd(uint32 cmd); #endif #endif // DND_CP_MSG_V4_H open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/dnd.h0000644765153500003110000002413512220061556021523 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * dnd.h -- * * Drag and Drop library * */ #ifndef _DND_H_ #define _DND_H_ #define INCLUDE_ALLOW_USERLEVEL #ifdef _WIN32 # include # include #endif #include "includeCheck.h" #include "vm_basic_types.h" #include "unicodeTypes.h" #include "dynarray.h" /* Error value returned when data contains illegal characters */ #define DND_ILLEGAL_CHARACTERS "data contains illegal characters" /* * Use the same maximum path length as Hgfs. * XXX: Move HGFS_PATH_MAX to some header file which is more public * and use it here. */ #define DND_MAX_PATH 6144 #define DNDMSG_HEADERSIZE_V3 ((3 * sizeof (uint32)) + (1 * sizeof (uint8))) /* Hard limits we never want to exceed */ /* The maximum size of a serializied DnDMsg. Close to 4M. */ #define DNDMSG_MAX_ARGSZ ((1 << 22) - DNDMSG_HEADERSIZE_V3) /* The maximum number of arguments we can hold */ #define DNDMSG_MAX_ARGS 64 /* Linux only defines. Should be in separate dndLinux.h */ /* Strings used for formatting various types of data */ #define DND_URI_LIST_PRE "file://" #define DND_URI_LIST_PRE_KDE "file:" #define DND_URI_NON_FILE_SCHEMES {"ssh", "sftp", "smb", "dav", "davs", "ftp", NULL} #define DND_URI_LIST_POST "\r\n" #define DND_TEXT_PLAIN_PRE "" #define DND_TEXT_PLAIN_POST "" #define DND_STRING_PRE "" #define DND_STRING_POST "" #define FCP_GNOME_LIST_PRE "file://" #define FCP_GNOME_LIST_POST "\n" /* FCP target used in gnome. */ #define FCP_TARGET_NAME_GNOME_COPIED_FILES "x-special/gnome-copied-files" #define FCP_TARGET_INFO_GNOME_COPIED_FILES 0 /* FCP target used in KDE. */ #define FCP_TARGET_NAME_URI_LIST "text/uri-list" #define FCP_TARGET_INFO_URI_LIST 1 /* Number of FCP targets. */ #define NR_FCP_TARGETS 2 #define VMWARE_TARGET "vmware-target" #define FCP_COPY_DELAY 1000000 // 1 second #define TARGET_NAME_TIMESTAMP "TIMESTAMP" #define TARGET_NAME_STRING "STRING" #define TARGET_NAME_TEXT_PLAIN "text/plain" #define TARGET_NAME_UTF8_STRING "UTF8_STRING" #define TARGET_NAME_COMPOUND_TEXT "COMPOUND_TEXT" #define TARGET_NAME_APPLICATION_RTF "application/rtf" #define TARGET_NAME_TEXT_RICHTEXT "text/richtext" #define DRAG_TARGET_NAME_URI_LIST "text/uri-list" #define DRAG_LEAVE_TIMEOUT 500 /* Guest detection window width and height. */ #define DRAG_DET_WINDOW_WIDTH 15 /* Clipboard image size limit. */ #define CLIPBOARD_IMAGE_MAX_WIDTH 4000 #define CLIPBOARD_IMAGE_MAX_HEIGHT 4000 typedef enum { CPFORMAT_UNKNOWN = 0, CPFORMAT_TEXT, /* NUL terminated UTF-8. */ CPFORMAT_FILELIST, CPFORMAT_RTF, CPFORMAT_FILELIST_URI, CPFORMAT_FILECONTENTS, CPFORMAT_IMG_PNG, CPFORMAT_FILEATTRIBUTES, CPFORMAT_MAX, } DND_CPFORMAT; enum DND_DROPEFFECT { DROP_UNKNOWN = 1<<31, DROP_NONE = 0, DROP_COPY = 1<<0, DROP_MOVE = 1<<1, DROP_LINK = 1<<2, }; /* Clipboard item. */ typedef struct CPClipItem { void *buf; uint32 size; Bool exists; } CPClipItem; /* * Cross platform clipboard. The native UI will convert host clipboard content * into cross platform clipboards. */ typedef struct { Bool changed; CPClipItem items[CPFORMAT_MAX - 1]; } CPClipboard; #if !defined(SWIG) typedef enum { DND_FILE_TRANSFER_NOT_STARTED = 0, DND_FILE_TRANSFER_IN_PROGRESS, DND_FILE_TRANSFER_FINISHED, } DND_FILE_TRANSFER_STATUS; /* * Comment out the following for SWIG. We don't currently need to use any of * these data structures or call any of these functions from test scripts, and * we would have to link in extra libraries if so. Only DnD V3 transport layer * will call these functions. At some later time, may want to refactor this * file to separate CPClipboard definitions from all these transport-related * stuff (it is just the CPClipboard code that test scripts need). */ /* Definitions for transport layer big buffer support (>= V3). */ typedef enum { DND_TRANSPORT_PACKET_TYPE_UNKNOWN = 0, DND_TRANSPORT_PACKET_TYPE_SINGLE, DND_TRANSPORT_PACKET_TYPE_REQUEST, DND_TRANSPORT_PACKET_TYPE_PAYLOAD, } DND_TRANSPORT_PACKET_TYPE; typedef #include "vmware_pack_begin.h" struct DnDTransportPacketHeader { uint32 type; uint32 seqNum; uint32 totalSize; uint32 payloadSize; uint32 offset; uint8 payload[1]; } #include "vmware_pack_end.h" DnDTransportPacketHeader; typedef struct DnDTransportBuffer { size_t seqNum; uint8 *buffer; size_t totalSize; size_t offset; VmTimeType lastUpdateTime; } DnDTransportBuffer; #define DND_TRANSPORT_PACKET_HEADER_SIZE (5 * sizeof(uint32)) /* Close to 64k (maximum guestRpc message size). Leave some space for guestRpc header. */ #define DND_MAX_TRANSPORT_PACKET_SIZE ((1 << 16) - 100) #define DND_MAX_TRANSPORT_PACKET_PAYLOAD_SIZE (DND_MAX_TRANSPORT_PACKET_SIZE - \ DND_TRANSPORT_PACKET_HEADER_SIZE) #define DND_MAX_TRANSPORT_LATENCY_TIME 3 * 1000000 /* 3 seconds. */ /* * Structure to access methods of currently used blocking mechanism. */ typedef struct DnDBlockControl { int fd; const char *blockRoot; Bool (*AddBlock)(int blockFd, const char *blockPath); Bool (*RemoveBlock)(int blockFd, const char *blockedPath); } DnDBlockControl; #ifdef _WIN32 /* * Windows-specific functions */ Unicode DnD_GetClipboardFormatName(UINT cf); HGLOBAL DnD_CopyStringToGlobal(ConstUnicode str); HGLOBAL DnD_CopyDWORDToGlobal(DWORD *pDWORD); HGLOBAL DnD_CreateHDrop(ConstUnicode path, ConstUnicode fileList); HGLOBAL DnD_CreateHDropForGuest(ConstUnicode path, ConstUnicode fileList); size_t DnD_CPStringToLocalString(ConstUnicode bufIn, utf16_t **bufOut); size_t DnD_LocalStringToCPString(utf16_t *bufIn, char **bufOut); Bool DnD_SetCPClipboardFromLocalText(CPClipboard *clip, utf16_t *bufIn); Bool DnD_SetCPClipboardFromLocalRtf(CPClipboard *clip, char *bufIn); Bool DnD_SetCPClipboardFromBMPInfo(CPClipboard *clip, const LPBITMAPINFOHEADER bmi, DND_CPFORMAT fmt); Bool DnD_SetCPClipboardFromHBITMAP(CPClipboard *clip, HBITMAP hBitmap, DND_CPFORMAT fmt); Bool DnD_PNGToLocalFormat(const unsigned char *pngData, unsigned int pngDataLen, int pngReadFlags, DynBuf *bmpData, HBITMAP *hBitmap); Bool DnD_FakeMouseEvent(DWORD flag); Bool DnD_FakeMouseState(DWORD key, Bool isDown); Bool DnD_FakeEscapeKey(void); Bool DnD_DeleteLocalDirectory(ConstUnicode localDir); Bool DnD_SetClipboard(UINT format, char *buffer, int len); Bool DnD_GetFileList(HDROP hDrop, char **remoteFiles, int *remoteLength, char **localFiles, int *localLength, uint64 *totalSize); #else /* * Posix-specific functions */ char *DnD_UriListGetNextFile(char const *uriList, size_t *index, size_t *length); Bool DnD_UriIsNonFileSchemes(char const *uri); #endif /* * Shared functions */ ConstUnicode DnD_GetFileRoot(void); char *DnD_CreateStagingDirectory(void); Bool DnD_DeleteStagingFiles(ConstUnicode stagingDir, Bool onReboot); Bool DnD_PrependFileRoot(ConstUnicode fileRoot, char **src, size_t *srcSize); int DnD_LegacyConvertToCPName(const char *nameIn, size_t bufOutSize, char *bufOut); Bool DnD_CPNameListToDynBufArray(char *fileList, size_t listSize, DynBufArray *dynBufArray); Unicode DnD_GetLastDirName(const char *str); /* vmblock support functions. */ Bool DnD_InitializeBlocking(DnDBlockControl *blkCtrl); Bool DnD_UninitializeBlocking(DnDBlockControl *blkCtrl); Bool DnD_CompleteBlockInitialization(int fd, DnDBlockControl *blkCtrl); static INLINE Bool DnD_BlockIsReady(DnDBlockControl *blkCtrl) // IN: blocking control structure { if (blkCtrl->fd >= 0) { ASSERT(blkCtrl->AddBlock && blkCtrl->RemoveBlock); return TRUE; } return FALSE; } /* Transport layer big buffer support functions. */ void DnD_TransportBufInit(DnDTransportBuffer *buf, uint8 *msg, size_t msgSize, uint32 seqNum); void DnD_TransportBufReset(DnDTransportBuffer *buf); size_t DnD_TransportBufGetPacket(DnDTransportBuffer *buf, DnDTransportPacketHeader **packet); Bool DnD_TransportBufAppendPacket(DnDTransportBuffer *buf, DnDTransportPacketHeader *packet, size_t packetSize); size_t DnD_TransportMsgToPacket(uint8 *msg, size_t msgSize, uint32 seqNum, DnDTransportPacketHeader **packet); size_t DnD_TransportReqPacket(DnDTransportBuffer *buf, DnDTransportPacketHeader **packet); #endif // !SWIG #endif // _DND_H_ open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/dndFileContentsUtil.h0000644765153500003110000000513712220061556024700 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * dndFileContentsUtil.h * * Helper functions for format conversion for file contents. */ #ifndef _DND_FILE_CONTENTS_UTIL_H_ #define _DND_FILE_CONTENTS_UTIL_H_ #include "guestrpc/cpFileContents.h" #define CP_FILE_VALID_NONE 0 #define CP_FILE_VALID_TYPE (1 << 0) #define CP_FILE_VALID_SIZE (1 << 1) #define CP_FILE_VALID_CREATE_TIME (1 << 2) #define CP_FILE_VALID_ACCESS_TIME (1 << 3) #define CP_FILE_VALID_WRITE_TIME (1 << 4) #define CP_FILE_VALID_CHANGE_TIME (1 << 5) #define CP_FILE_VALID_PERMS (1 << 6) #define CP_FILE_VALID_ATTR (1 << 7) #define CP_FILE_VALID_NAME (1 << 8) #define CP_FILE_VALID_CONTENT (1 << 9) #define CP_FILE_ATTR_NONE 0 #define CP_FILE_ATTR_HIDDEN (1 << 0) #define CP_FILE_ATTR_SYSTEM (1 << 1) #define CP_FILE_ATTR_ARCHIVE (1 << 2) #define CP_FILE_ATTR_HIDDEN_FORCED (1 << 3) #define CP_FILE_ATTR_READONLY (1 << 4) #define CP_FILE_TYPE_REGULAR 1 #define CP_FILE_TYPE_DIRECTORY 2 #define CP_FILE_TYPE_SYMLINK 3 #ifdef _WIN32 #include Bool DnD_FileDescAToCPFileContents(FILEDESCRIPTORA *fileDescA, CPFileItem* cpItem); Bool DnD_FileDescWToCPFileContents(FILEDESCRIPTORW *fileDescW, CPFileItem* cpItem); Bool DnD_CPFileContentsToFileDescA(CPFileItem* cpItem, FILEDESCRIPTORA *fileDescA, Bool processName); Bool DnD_CPFileContentsToFileDescW(CPFileItem* cpItem, FILEDESCRIPTORW *fileDescW); #endif // _WIN32 #endif // _DND_FILE_CONTENTS_UTIL_H_ open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/dndMsg.h0000644765153500003110000000776012220061556022177 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * dndMsg.h -- * * DnDMsg represents an rpc message which is sent across the * wire. Any args that it holds will be written out exactly as stored. */ #ifndef _DNDMSG_H_ #define _DNDMSG_H_ #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #include "vm_basic_types.h" #include "dynbuf.h" #include "dynarray.h" #include "dnd.h" /* Various return types serialization/unserialization functions can return. */ typedef enum { DNDMSG_SUCCESS = 0, DNDMSG_ERR, DNDMSG_NOMEM, DNDMSG_INPUT_TOO_SMALL, /* Input buffer needs to be bigger. */ DNDMSG_INPUT_ERR, /* Serialize/unserialized failed sanity checks. */ } DnDMsgErr; /* * DnD Commands. */ typedef enum { DND_INVALID = 0, /* * We need to send mouse packets for old protocols because old guest tools * manipulate the mouse directly, but in DnD Version 3+, the host controls the * mouse pointer via foundry. */ /* DnD Ver 1/2 Commands */ DND_HG_SEND_MOUSE_PACKET, /* DnD version 3 commands */ // GHDnD (h->g) DND_GH_QUERY_PENDING_DRAG, DND_GH_CANCEL, DND_GH_COPY_DONE, // GHDnD (g->h) DND_GH_DRAG_ENTER, DND_GH_NOT_PENDING, // HGDnD (h->g) DND_HG_DRAG_ENTER, DND_HG_DRAG_START, DND_HG_CANCEL, DND_HG_DROP, DND_HG_FILE_COPY_DONE, // HGDnD (g->h) DND_HG_DRAG_ENTER_DONE, DND_HG_DRAG_READY, DND_HG_UPDATE_FEEDBACK, DND_HG_DROP_DONE, DND_HG_START_FILE_COPY, // Add future commands here. DND_GH_UPDATE_UNITY_DET_WND, // New command after DnD version 3.1 DND_UPDATE_HOST_VERSION, DND_UPDATE_GUEST_VERSION, DND_UPDATE_MOUSE, DND_GH_PRIVATE_DROP, DND_GH_TRANSPORT_TEST, DND_MOVE_DET_WND_TO_MOUSE_POS, DND_GH_SET_CLIPBOARD, DND_GH_GET_NEXT_NAME, DND_HG_SET_GUEST_FILE_ROOT, DND_MAX, } DnDCommand; /* * Copy/Paste commands. */ typedef enum { CP_INVALID = 0, /* DnD version 3 commands. */ // GHCopyPaste (h->g) CP_GH_GET_CLIPBOARD, // GHCopyPaste (g->h) CP_GH_GET_CLIPBOARD_DONE, // FORMAT DATA(property list?) // HGCopyPaste (h->g) CP_HG_SET_CLIPBOARD, CP_HG_FILE_COPY_DONE, // HGCopyPaste(g->h) CP_HG_START_FILE_COPY, // Add future commands here. CP_GH_TRANSPORT_TEST, CP_MAX, } CopyPasteCommand; /* * Opaque data structure. * Members are listed in order of unserialization. */ typedef struct DnDMsg { /* Header */ uint8 ver; // Must be first across all versions. uint32 cmd; uint32 nargs; /* The expected size of the buffer needed to unserialize the arguments. */ uint32 expectedArgsSz; /* Body */ DynBufArray args; } DnDMsg; #define DnDMsg_Success(x) ((x) == DNDMSG_SUCCESS) void DnDMsg_Init(DnDMsg *msg); void DnDMsg_Destroy(DnDMsg *msg); /* Header information. */ uint32 DnDMsg_GetCmd(DnDMsg *msg); void DnDMsg_SetCmd(DnDMsg *msg, uint32 cmd); uint32 DnDMsg_NumArgs(DnDMsg *msg); DynBuf *DnDMsg_GetArg(DnDMsg *msg, uint32 arg); Bool DnDMsg_AppendArg(DnDMsg *msg, void *buf, size_t len); Bool DnDMsg_Serialize(DnDMsg *msg, DynBuf *buf); DnDMsgErr DnDMsg_UnserializeHeader(DnDMsg *msg, void *buf, size_t len); DnDMsgErr DnDMsg_UnserializeArgs(DnDMsg *msg, void *buf, size_t len); #endif /* _DNDMSG_H_ */ open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/dndLinux.c0000644765153500003110000005400112220061556022531 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * dndLinux.c -- * * Some common dnd functions for UNIX guests and hosts. */ #include #include #include #include #include #include "vmware.h" #include "dndInt.h" #include "dnd.h" #include "posix.h" #include "file.h" #include "strutil.h" #include "vm_assert.h" #include "util.h" #include "escape.h" #include "su.h" #if defined(linux) || defined(sun) || defined(__FreeBSD__) #include "vmblock_user.h" #include "mntinfo.h" #endif #define LOGLEVEL_MODULE dnd #include "loglevel_user.h" #include "unicodeOperations.h" #define DND_ROOTDIR_PERMS (S_IRWXU | S_IRWXG | S_IRWXO) #define DND_STAGINGDIR_PERMS (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) #ifdef sun #define ACCESSPERMS (S_IRWXU | S_IRWXG | S_IRWXO) #endif #ifdef __ANDROID__ /* * Android doesn't support setmntent(), endmntent() or MOUNTED. */ #define NO_SETMNTENT #define NO_ENDMNTENT #define ACCESSPERMS (S_IRWXU | S_IRWXG | S_IRWXO) #endif /* *----------------------------------------------------------------------------- * * DnD_GetFileRoot -- * * Gets the root path of the staging directory for DnD file transfers. * * Results: * The path to the staging directory. * * Side effects: * None * *----------------------------------------------------------------------------- */ ConstUnicode DnD_GetFileRoot(void) { return "/tmp/VMwareDnD/"; } /* *----------------------------------------------------------------------------- * * DnD_PrependFileRoot -- * * Given a buffer of '\0' delimited filenames, this prepends the file root * to each one and uses '\0' delimiting for the output buffer. The buffer * pointed to by *src will be freed and *src will point to a new buffer * containing the results. *srcSize is set to the size of the new buffer, * not including the NUL-terminator. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * *src will be freed, and a new buffer will be allocated. This buffer must * be freed by the caller. * *----------------------------------------------------------------------------- */ Bool DnD_PrependFileRoot(const char *fileRoot, // IN : file root to append char **src, // IN/OUT: NUL-delimited list of paths size_t *srcSize) // IN/OUT: size of list { ASSERT(fileRoot); ASSERT(src); ASSERT(*src); ASSERT(srcSize); return DnDPrependFileRoot(fileRoot, '\0', src, srcSize); } /* *---------------------------------------------------------------------------- * * DnDUriListGetFile -- * * Retrieves the filename and length from the file scheme (file://) entry at * the specified index in a text/uri-list string. * * Results: * The address of the beginning of the next filename on success, NULL if * there are no more entries or on error. index is updated with the * location of the next entry in the list, and length is updated with the * size of the filename starting at the returned value. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static char * DnDUriListGetFile(char const *uriList, // IN : text/uri-list string size_t *index, // IN/OUT: current index size_t *length) // OUT : length of returned string { char const *nameStart; char const *nameEnd; char const *curr; ASSERT(uriList); ASSERT(index); ASSERT(length); /* The common case on the last entry */ if (uriList[*index] == '\0') { return NULL; } /* * Ensure the URI list is formatted properly. This is ugly, but we have to * special case for KDE (which doesn't follow the standard). * * XXX Note that this assumes we only support dropping files, based on the * definition of the macro that is used. */ nameStart = &uriList[*index]; if (strncmp(nameStart, DND_URI_LIST_PRE, sizeof DND_URI_LIST_PRE - 1) == 0) { nameStart += sizeof DND_URI_LIST_PRE - 1; } else if (strncmp(nameStart, DND_URI_LIST_PRE_KDE, sizeof DND_URI_LIST_PRE_KDE - 1) == 0) { nameStart += sizeof DND_URI_LIST_PRE_KDE - 1; #if defined(linux) } else if (DnD_UriIsNonFileSchemes(nameStart)) { /* Do nothing. */ #endif } else { Warning("%s: the URI list did not begin with %s or %s\n", __func__, DND_URI_LIST_PRE, DND_URI_LIST_PRE_KDE); return NULL; } nameEnd = NULL; /* Walk the filename looking for the end */ curr = nameStart; while (*curr != '\0' && *curr != '\r' && *curr != '\n') { curr++; } nameEnd = curr - 1; /* Bump curr based on trailing newline characters found */ while (*curr == '\r' || *curr == '\n') { curr++; } *index = curr - uriList; *length = nameEnd - nameStart + 1; return (char *)nameStart; } /* *---------------------------------------------------------------------------- * * DnD_UriListGetNextFile -- * * Retrieves and unescapes the next file from the provided test/uri-list * mime type string. The index provided is used to iteratively retrieve * successive files from the list. * * Results: * An allocated, unescaped, NUL-terminated string containing the filename * within the uri-list after the specified index. index is updated to point * to the next entry of the uri-list, and length (if provided) is set to the * length of the allocated string (not including the NUL terminator). * NULL if there are no more entries in the list, or on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ char * DnD_UriListGetNextFile(char const *uriList, // IN : text/uri-list string size_t *index, // IN/OUT: current index size_t *length) // OUT : length of returned string { char const *file; size_t nextIndex; size_t fileLength = 0; char *unescapedName; size_t unescapedLength; ASSERT(uriList); ASSERT(index); nextIndex = *index; /* Get pointer to and length of next filename */ file = DnDUriListGetFile(uriList, &nextIndex, &fileLength); if (!file) { return NULL; } /* * Retrieve an allocated, unescaped name. This undoes the ' ' -> "%20" * escaping as required by RFC 1630 for entries in a uri-list. */ unescapedName = Escape_Undo('%', file, fileLength, &unescapedLength); if (!unescapedName) { Warning("%s: error unescaping filename\n", __func__); return NULL; } *index = nextIndex; if (length) { *length = unescapedLength; } return unescapedName; } /* *---------------------------------------------------------------------------- * * DnD_UriIsNonFileSchemes -- * * Check if the uri contains supported non-file scheme. * * Results: * TRUE if the uri contains supported non-file scheme. FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool DnD_UriIsNonFileSchemes(const char *uri) { const char *schemes[] = DND_URI_NON_FILE_SCHEMES; int i = 0; while (schemes[i] != NULL) { if (strncmp(uri, schemes[i], strlen(schemes[i])) == 0) { return TRUE; } i++; } return FALSE; } /* We need to make this suck less. */ #if defined(linux) || defined(sun) || defined(__FreeBSD__) /* *---------------------------------------------------------------------------- * * DnD_AddBlockLegacy -- * * Adds a block to blockPath. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * Processes trying to access this path will block until DnD_RemoveBlock * is called. * *---------------------------------------------------------------------------- */ Bool DnD_AddBlockLegacy(int blockFd, // IN const char *blockPath) // IN { ASSERT(blockFd >= 0); if (VMBLOCK_CONTROL(blockFd, VMBLOCK_ADD_FILEBLOCK, blockPath) != 0) { LOG(1, ("%s: Cannot add block on %s (%s)\n", __func__, blockPath, strerror(errno))); return FALSE; } return TRUE; } /* *---------------------------------------------------------------------------- * * DnD_RemoveBlockLegacy -- * * Removes block on blockedPath. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * Processes blocked on accessing this path will continue. * *---------------------------------------------------------------------------- */ Bool DnD_RemoveBlockLegacy(int blockFd, // IN const char *blockedPath) // IN { if (blockFd >= 0) { if (VMBLOCK_CONTROL(blockFd, VMBLOCK_DEL_FILEBLOCK, blockedPath) != 0) { Log("%s: Cannot delete block on %s (%s)\n", __func__, blockedPath, strerror(errno)); return FALSE; } } else { LOG(4, ("%s: Could not remove block on %s: " "fd to vmblock no longer exists.\n", __func__, blockedPath)); } return TRUE; } /* *---------------------------------------------------------------------------- * * DnD_CheckBlockLegacy -- * * Verifies that given file descriptor is truly a control file of * kernel-based vmblock implementation. Just a stub, for now at * least since we don't have a good way to check. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static Bool DnD_CheckBlockLegacy(int blockFd) // IN { return TRUE; } /* *---------------------------------------------------------------------------- * * DnD_AddBlockFuse -- * * Adds a block to blockPath. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * Processes trying to access this path will block until DnD_RemoveBlock * is called. * *---------------------------------------------------------------------------- */ Bool DnD_AddBlockFuse(int blockFd, // IN const char *blockPath) // IN { ASSERT(blockFd >= 0); if (VMBLOCK_CONTROL_FUSE(blockFd, VMBLOCK_FUSE_ADD_FILEBLOCK, blockPath) != 0) { LOG(1, ("%s: Cannot add block on %s (%s)\n", __func__, blockPath, strerror(errno))); return FALSE; } return TRUE; } /* *---------------------------------------------------------------------------- * * DnD_RemoveBlockFuse -- * * Removes block on blockedPath. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * Processes blocked on accessing this path will continue. * *---------------------------------------------------------------------------- */ Bool DnD_RemoveBlockFuse(int blockFd, // IN const char *blockedPath) // IN { if (blockFd >= 0) { if (VMBLOCK_CONTROL_FUSE(blockFd, VMBLOCK_FUSE_DEL_FILEBLOCK, blockedPath) != 0) { Log("%s: Cannot delete block on %s (%s)\n", __func__, blockedPath, strerror(errno)); return FALSE; } } else { LOG(4, ("%s: Could not remove block on %s: " "fd to vmblock no longer exists.\n", __func__, blockedPath)); } return TRUE; } /* *---------------------------------------------------------------------------- * * DnD_CheckBlockFuse -- * * Verifies that given file descriptor is truly a control file of * FUSE-based vmblock implementation. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static Bool DnD_CheckBlockFuse(int blockFd) // IN { char buf[sizeof(VMBLOCK_FUSE_READ_RESPONSE)]; ssize_t size; size = read(blockFd, buf, sizeof(VMBLOCK_FUSE_READ_RESPONSE)); if (size < 0) { LOG(4, ("%s: read failed, error %s.\n", __func__, strerror(errno))); return FALSE; } if (size != sizeof(VMBLOCK_FUSE_READ_RESPONSE)) { /* * Refer to bug 817761 of casting size to size_t. */ LOG(4, ("%s: Response too short (%"FMTSZ"u vs. %"FMTSZ"u).\n", __func__, (size_t)size, sizeof(VMBLOCK_FUSE_READ_RESPONSE))); return FALSE; } if (memcmp(buf, VMBLOCK_FUSE_READ_RESPONSE, sizeof(VMBLOCK_FUSE_READ_RESPONSE))) { LOG(4, ("%s: Invalid response %.*s", __func__, (int)sizeof(VMBLOCK_FUSE_READ_RESPONSE) - 1, buf)); return FALSE; } return TRUE; } /* *---------------------------------------------------------------------------- * * DnD_TryInitVmblock -- * * Initializes file blocking needed to prevent access to file before * transfer has finished. * * Results: * Block descriptor on success, -1 on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int DnD_TryInitVmblock(const char *vmbFsName, // IN const char *vmbMntPoint, // IN const char *vmbDevice, // IN mode_t vmbDeviceMode, // IN Bool (*verifyBlock)(int fd)) // IN { #if defined NO_SETMNTENT || defined NO_ENDMNTENT NOT_IMPLEMENTED(); errno = ENOSYS; return -1; #else Bool found = FALSE; int blockFd = -1; char *realMntPoint; MNTHANDLE fp; DECLARE_MNTINFO(mnt); ASSERT(vmbFsName); ASSERT(vmbMntPoint); ASSERT(vmbDevice); /* Resolve desired mount point in case it is symlinked somewhere */ realMntPoint = Posix_RealPath(vmbMntPoint); if (!realMntPoint) { /* * If resolve failed for some reason try to fall back to * original mount point specification. */ realMntPoint = Util_SafeStrdup(vmbMntPoint); } /* Make sure the vmblock file system is mounted. */ fp = OPEN_MNTFILE("r"); if (fp == NULL) { LOG(1, ("%s: could not open mount file\n", __func__)); goto out; } while (GETNEXT_MNTINFO(fp, mnt)) { /* * In the future we can publish the mount point in VMDB so that the UI * can use it rather than enforcing the VMBLOCK_MOUNT_POINT check here. */ if (strcmp(MNTINFO_FSTYPE(mnt), vmbFsName) == 0 && strcmp(MNTINFO_MNTPT(mnt), realMntPoint) == 0) { found = TRUE; break; } } (void) CLOSE_MNTFILE(fp); if (found) { /* Open device node for communication with vmblock. */ blockFd = Posix_Open(vmbDevice, vmbDeviceMode); if (blockFd < 0) { LOG(1, ("%s: Can not open blocker device (%s)\n", __func__, strerror(errno))); } else { LOG(4, ("%s: Opened blocker device at %s\n", __func__, VMBLOCK_DEVICE)); if (verifyBlock && !verifyBlock(blockFd)) { LOG(4, ("%s: Blocker device at %s did not pass checks, closing.\n", __func__, VMBLOCK_DEVICE)); close(blockFd); blockFd = -1; } } } out: free(realMntPoint); return blockFd; #endif } /* *---------------------------------------------------------------------------- * * DnD_InitializeBlocking -- * * Initializes file blocking needed to prevent access to file before * transfer has finished. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool DnD_InitializeBlocking(DnDBlockControl *blkCtrl) // OUT { uid_t uid; int blockFd; /* Root access is needed for opening the vmblock device. */ uid = Id_BeginSuperUser(); /* Fitrst try FUSE and see if it is available. */ blockFd = DnD_TryInitVmblock(VMBLOCK_FUSE_FS_NAME, VMBLOCK_FUSE_MOUNT_POINT, VMBLOCK_FUSE_DEVICE, VMBLOCK_FUSE_DEVICE_MODE, DnD_CheckBlockFuse); if (blockFd != -1) { blkCtrl->fd = blockFd; /* Setup FUSE methods. */ blkCtrl->blockRoot = VMBLOCK_FUSE_FS_ROOT; blkCtrl->AddBlock = DnD_AddBlockFuse; blkCtrl->RemoveBlock = DnD_RemoveBlockFuse; goto out; } /* Now try OS-specific VMBlock driver. */ blockFd = DnD_TryInitVmblock(VMBLOCK_FS_NAME, VMBLOCK_MOUNT_POINT, VMBLOCK_DEVICE, VMBLOCK_DEVICE_MODE, NULL); if (blockFd != -1) { blkCtrl->fd = blockFd; /* Setup legacy in-kernel methods. */ blkCtrl->blockRoot = VMBLOCK_FS_ROOT; blkCtrl->AddBlock = DnD_AddBlockLegacy; blkCtrl->RemoveBlock = DnD_RemoveBlockLegacy; goto out; } LOG(4, ("%s: could not find vmblock mounted\n", __func__)); out: Id_EndSuperUser(uid); return blockFd != -1; } /* *---------------------------------------------------------------------------- * * DnD_UninitializeBlocking -- * * Uninitialize file blocking. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * All existing blocks will be removed. * *---------------------------------------------------------------------------- */ Bool DnD_UninitializeBlocking(DnDBlockControl *blkCtrl) // IN { Bool ret = TRUE; if (blkCtrl->fd >= 0) { if (close(blkCtrl->fd) < 0) { Log("%s: Can not close blocker device (%s)\n", __func__, strerror(errno)); ret = FALSE; } else { blkCtrl->fd = -1; } } return ret; } /* * DnD_CompleteBlockInitialization -- * * Complete block initialization in case when we were handed * blocking file descriptor (presumably opened for us by a * suid application). * * Results: * TRUE on success, FALSE on failure (invalid type). * * Side effects: * Adjusts blkCtrl to match blocking device type (legacy or fuse). * */ Bool DnD_CompleteBlockInitialization(int fd, // IN DnDBlockControl *blkCtrl) // OUT { blkCtrl->fd = fd; if (DnD_CheckBlockFuse(fd)) { /* Setup FUSE methods. */ blkCtrl->blockRoot = VMBLOCK_FUSE_FS_ROOT; blkCtrl->AddBlock = DnD_AddBlockFuse; blkCtrl->RemoveBlock = DnD_RemoveBlockFuse; } else if (DnD_CheckBlockLegacy(fd)) { /* Setup legacy methods. */ blkCtrl->blockRoot = VMBLOCK_FS_ROOT; blkCtrl->AddBlock = DnD_AddBlockLegacy; blkCtrl->RemoveBlock = DnD_RemoveBlockLegacy; } else { Log("%s: Can't determine block type.\n", __func__); return FALSE; } return TRUE; } #endif /* linux || sun || FreeBSD */ /* *---------------------------------------------------------------------------- * * DnDRootDirUsable -- * * Determines whether the provided directory is usable as the root for * staging directories. * * Results: * TRUE if the root directory is usable, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool DnDRootDirUsable(ConstUnicode pathName) // IN: { struct stat buf; if (Posix_Stat(pathName, &buf) < 0) { return FALSE; } return S_ISDIR(buf.st_mode) && (buf.st_mode & S_ISVTX) == S_ISVTX && (buf.st_mode & ACCESSPERMS) == DND_ROOTDIR_PERMS; } /* *---------------------------------------------------------------------------- * * DnDSetPermissionsOnRootDir -- * * Sets the correct permissions for the root staging directory. We set the * root directory to 1777 so that all users can create their own staging * directories within it and that other users cannot delete that directory. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool DnDSetPermissionsOnRootDir(ConstUnicode pathName) // IN: { return Posix_Chmod(pathName, S_ISVTX | DND_ROOTDIR_PERMS) == 0; } /* *---------------------------------------------------------------------------- * * DnDStagingDirectoryUsable -- * * Determines whether a staging directory is usable for the current * process. A directory is only usable by the current process if it is * owned by the effective uid of the current process. * * Results: * TRUE if the directory is usable, FALSE if it is not. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool DnDStagingDirectoryUsable(ConstUnicode pathName) // IN: { struct stat buf; if (Posix_Stat(pathName, &buf) < 0) { return FALSE; } return buf.st_uid == Id_GetEUid(); } /* *---------------------------------------------------------------------------- * * DnDSetPermissionsOnStagingDir -- * * Sets the correct permissions for staging directories. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool DnDSetPermissionsOnStagingDir(ConstUnicode pathName) // IN: { return Posix_Chmod(pathName, DND_STAGINGDIR_PERMS) == 0; } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/dndRpc.hh0000644765153500003110000001045012220061556022333 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @dndRpc.hh -- * * Rpc layer object for DnD. */ #ifndef DND_RPC_HH #define DND_RPC_HH #include #include "dndCPLibExport.hh" #include "rpcBase.h" extern "C" { #include "dnd.h" } class LIB_EXPORT DnDRpc : public RpcBase { public: virtual ~DnDRpc(void) {}; /* sigc signals for DnD source callback. */ sigc::signal srcDragBeginChanged; sigc::signal srcCancelChanged; sigc::signal srcDropChanged; /* sigc signals for DnD destination callback. */ sigc::signal destDragEnterReplyChanged; sigc::signal destPrivDragEnterChanged; sigc::signal destPrivDragLeaveChanged; sigc::signal destPrivDropChanged; sigc::signal destDropChanged; sigc::signal destCancelChanged; sigc::signal moveMouseChanged; sigc::signal updateFeedbackChanged; sigc::signal queryExitingChanged; sigc::signal dragNotPendingChanged; sigc::signal updateUnityDetWndChanged; sigc::signal requestFileChanged; sigc::signal getFilesDoneChanged; /* sigc signal for responding to ping reply */ sigc::signal pingReplyChanged; /* sigc signal for rpc cmd reply received. */ sigc::signal cmdReplyChanged; /* DnD source. */ virtual bool SrcDragBeginDone(uint32 sessionId) = 0; virtual bool SrcDrop(uint32 sessionId, int32 x, int32 y) = 0; virtual bool SrcDropDone(uint32 sessionId, const uint8 *stagingDirCP, uint32 sz) = 0; virtual bool SrcPrivDragEnter(uint32 sessionId) = 0; virtual bool SrcPrivDragLeave(uint32 sessionId, int32 x, int32 y) = 0; virtual bool SrcPrivDrop(uint32 sessionId, int32 x, int32 y) = 0; virtual bool SrcCancel(uint32 sessionId) = 0; /* DnD destination. */ virtual bool DestDragEnter(uint32 sessionId, const CPClipboard *clip) = 0; virtual bool DestSendClip(uint32 sessionId, const CPClipboard *clip) = 0; virtual bool DestDragLeave(uint32 sessionId, int32 x, int32 y) = 0; virtual bool DestDrop(uint32 sessionId, int32 x, int32 y) = 0; virtual bool DestCancel(uint32 sessionId) = 0; /* Common. */ virtual void Init(void) = 0; virtual void SendPing(uint32 caps) = 0; virtual bool UpdateFeedback(uint32 sessionId, DND_DROPEFFECT feedback) = 0; virtual bool MoveMouse(uint32 sessionId, int32 x, int32 y) = 0; virtual bool QueryExiting(uint32 sessionId, int32 x, int32 y) = 0; virtual bool DragNotPending(uint32 sessionId) = 0; virtual bool UpdateUnityDetWnd(uint32 sessionId, bool show, uint32 unityWndId) = 0; virtual bool RequestFiles(uint32 sessionId) = 0; virtual bool SendFilesDone(uint32 sessionId, bool success, const uint8 *stagingDirCP, uint32 sz) = 0; virtual bool GetFilesDone(uint32 sessionId, bool success) = 0; }; #endif // DND_RPC_HH open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/dndMsg.c0000644765153500003110000003026712220061556022170 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * dndMsg.c -- * * DnDMsg represents an rpc message which is sent across the * wire. Any args that it holds will be written out exactly as stored. * * To protect itself there are many checks to ensure the data which is * serialized and unserialized is sane. Defines and asserts are used to * ensure the message stays under these limits when serializing out and * checks are enforced to ensure that the data to be unserialized remains * under these limits. */ #include #include #include "vm_assert.h" #include "dndMsg.h" #include "dndInt.h" #define LOGLEVEL_MODULE dnd #include "loglevel_user.h" /* *---------------------------------------------------------------------------- * * DnDMsg_Init -- * * DnDMsg constructor. * * Results: * None. * * Side effects: * None * *---------------------------------------------------------------------------- */ void DnDMsg_Init(DnDMsg *msg) // IN/OUT: the message { ASSERT(msg); msg->ver = 3; msg->cmd = 0; msg->nargs = 0; DynBufArray_Init(&msg->args, 0); msg->expectedArgsSz = 0; } /* *---------------------------------------------------------------------------- * * DnDMsg_Destroy -- * * Destroys a message by clearing any of the data that is contained in it. * * Results: * None * * Side effects: * Frees the arguments' memory. * *---------------------------------------------------------------------------- */ void DnDMsg_Destroy(DnDMsg *msg) // IN/OUT: the message { uint32 i; uint32 count; ASSERT(msg); count = DynArray_Count(&msg->args); msg->ver = 0; msg->cmd = 0; msg->nargs = 0; msg->expectedArgsSz = 0; for (i = 0; i < count; ++i) { DynBuf *b = DynArray_AddressOf(&msg->args, i); DynBuf_Destroy(b); } DynArray_SetCount(&msg->args, 0); DynBufArray_Destroy(&msg->args); } /* *---------------------------------------------------------------------------- * * DnDMsg_Cmd -- * * Gets the dnd/copy paste command from the header. * * Results: * An uint32 representing the command. * * Side effects: * None. * *---------------------------------------------------------------------------- */ uint32 DnDMsg_GetCmd(DnDMsg *msg) // IN/OUT: the message { ASSERT(msg); return msg->cmd; } /* *---------------------------------------------------------------------------- * * DnDMsg_SetCmd -- * * Sets the command for the message. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void DnDMsg_SetCmd(DnDMsg *msg, // IN/OUT: the message uint32 cmd) // IN: the command { ASSERT(msg); ASSERT((DND_INVALID < cmd && cmd < DND_MAX) || (CP_INVALID < cmd && cmd < CP_MAX)); msg->cmd = cmd; } /* *---------------------------------------------------------------------------- * * DnDMsg_NumArgs -- * * Determines the number of arguments currently in the DnDMsg. * * Results: * The number of arguments. * * Side effects: * None. * *---------------------------------------------------------------------------- */ uint32 DnDMsg_NumArgs(DnDMsg *msg) // IN/OUT: the message { ASSERT(msg); return DynBufArray_Count(&msg->args); } /* *---------------------------------------------------------------------------- * * DnDMsg_GetArg -- * * Gets an argument stored in DnDMsg. * * Results: * Null if the argument is out of bounds, otherwise a pointer to a dynbuf * containing the argument. * This dynbuf is still * managed by the DnDMsg and should NOT be destroyed. * * Side effects: * None. * *---------------------------------------------------------------------------- */ DynBuf * DnDMsg_GetArg(DnDMsg *msg, // IN/OUT: the message uint32 idx) // IN: the argument to return { ASSERT(msg); ASSERT(0 <= idx && idx < DynBufArray_Count(&msg->args)); return DynArray_AddressOf(&msg->args, idx); } /* *---------------------------------------------------------------------------- * * DnDMsg_AppendArg -- * * Adds the data to the end of the argument list in the message. It will * create a copy of the data to be mananged by DnDMsg until the message is * destroyed. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * Increases the internal arg size counter. * *---------------------------------------------------------------------------- */ Bool DnDMsg_AppendArg(DnDMsg *msg, // IN/OUT: the message void *buf, // IN: the input buffer size_t len) // IN: the length of the input buffer { DynBuf clonebuf; ASSERT(msg); ASSERT(buf); if (DynBufArray_Count(&msg->args) >= DNDMSG_MAX_ARGS) { return FALSE; } DynBuf_Init(&clonebuf); if (!DynBuf_Append(&clonebuf, buf, len)) { goto err; } /* The dynbufarray now owns the clonebuf data. */ if (!DynBufArray_Push(&msg->args, clonebuf)) { goto err; } return TRUE; err: DynBuf_Destroy(&clonebuf); return FALSE; } /* *---------------------------------------------------------------------------- * * DnDMsg_Serialize -- * * Serialize the contents of the DnDMsg out to the provided dynbuf. It * will ASSERT if any invariants are broken. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool DnDMsg_Serialize(DnDMsg *msg, // IN/OUT: the message DynBuf* buf) // OUT: the output buffer { DynBuf *curArg; uint32 nargs; uint32 i; uint32 serializeArgsSz = 0; ASSERT(msg); ASSERT(buf); ASSERT((DND_INVALID < msg->cmd && msg->cmd < DND_MAX) || (CP_INVALID < msg->cmd && msg->cmd < CP_MAX)); nargs = DynBufArray_Count(&msg->args); for (i = 0; i < nargs; ++i) { DynBuf *b = DynArray_AddressOf(&msg->args, i); serializeArgsSz += sizeof(uint32) + DynBuf_GetSize(b); } if (DynBuf_Append(buf, &msg->ver, sizeof msg->ver) && DynBuf_Append(buf, &msg->cmd, sizeof msg->cmd) && DynBuf_Append(buf, &nargs, sizeof nargs) && DynBuf_Append(buf, &serializeArgsSz, sizeof serializeArgsSz)) { int i; uint32 curArgsSz; for (i = 0; i < nargs; i++) { curArg = DynBufArray_AddressOf(&msg->args, i); curArgsSz = DynBuf_GetSize(curArg); if (!DynBuf_Append(buf, &curArgsSz, sizeof curArgsSz) || !DynBuf_Append(buf, DynBuf_Get(curArg), curArgsSz)) { return FALSE; } } } else { return FALSE; } return TRUE; } /* *---------------------------------------------------------------------------- * * DnDMsg_UnserializeHeader -- * * Read the header from the buffer into a DnDMsg. Any contents in the * DnDMsg will be destroyed. This allows you to retrieve header * information. These functions are specified in the dndMsg.h. Most * notably, you can retrieve the size of the arguments so that you can * pass a properly sized buffer to DnDMsg_UnserializeArgs. * * This is the one of the two places that nargs is set. The other is * implicitly set by DnDMsg_AppendArg with the push and only ever * realized through the DnDMsg_Serialize function. expectedArgsSz, * curArgSz follows the same idea. * * Results: * DNDMSG_SUCCESS on success. * DNDMSG_INPUT_TOO_SMALL when provided buffer is too small. * DNDMSG_INPUT_ERR when the provided buffer is inconsistant. * DNDMSG_NOMEM when we run out of memory. * DNDMSG_ERR on any other error. * * Side effects: * On success the msg's header will be filled. On failure the msg will be * destroyed. * *---------------------------------------------------------------------------- */ DnDMsgErr DnDMsg_UnserializeHeader(DnDMsg *msg, // IN/OUT: the message void *buf, // IN: the input buffer size_t len) // IN: the buffer length { BufRead r; ASSERT(msg); ASSERT(buf); r.pos = buf; r.unreadLen = len; if (len < DNDMSG_HEADERSIZE_V3) { return DNDMSG_INPUT_TOO_SMALL; } /* Read buffer into msg. */ if (DnDReadBuffer(&r, &msg->ver, sizeof msg->ver) && DnDReadBuffer(&r, &msg->cmd, sizeof msg->cmd) && DnDReadBuffer(&r, &msg->nargs, sizeof msg->nargs) && DnDReadBuffer(&r, &msg->expectedArgsSz, sizeof msg->expectedArgsSz)) { /* Sanity checks. */ if (msg->expectedArgsSz < DNDMSG_MAX_ARGSZ && (msg->cmd < DND_MAX || msg->cmd < CP_MAX) && 0 < msg->cmd && msg->ver >= 3 && msg->nargs < DNDMSG_MAX_ARGS) { return DNDMSG_SUCCESS; } else { return DNDMSG_INPUT_ERR; } } else { return DNDMSG_INPUT_TOO_SMALL; } } /* *---------------------------------------------------------------------------- * * DnDMsg_UnserializeArgs -- * * Unserialize the arguments of the message provided by the buffer. * Each argument is a uint32 of the size followed by the buffer. On * failure the message will revert to the state which was passed into the * function. * * Results: * DNDMSG_SUCCESS on success. * DNDMSG_INPUT_TOO_SMALL when provided buffer is too small. * DNDMSG_INPUT_ERR when the provided buffer is inconsistant. * DNDMSG_NOMEM when we run out of memory. * DNDMSG_ERR on any other error. * * Side effects: * On success, arguments found in buf are unserialized into msg. * *---------------------------------------------------------------------------- */ DnDMsgErr DnDMsg_UnserializeArgs(DnDMsg *msg, // IN/OUT: the message void *buf, // IN: input buffer size_t len) // IN: buffer length { uint32 i; uint32 count; BufRead r; uint32 readArgsSz = 0; void *data = NULL; DnDMsgErr ret = DNDMSG_SUCCESS; ASSERT(msg); ASSERT(DynBufArray_Count(&msg->args) == 0); ASSERT(buf); r.pos = buf; r.unreadLen = len; if (len < msg->expectedArgsSz) { return DNDMSG_INPUT_TOO_SMALL; } for (i = 0; i < msg->nargs; ++i) { uint32 argSz; if (!DnDReadBuffer(&r, &argSz, sizeof argSz)) { ret = DNDMSG_INPUT_TOO_SMALL; goto err; } if (argSz > DNDMSG_MAX_ARGSZ || readArgsSz + sizeof (uint32) + argSz > msg->expectedArgsSz) { ret = DNDMSG_INPUT_ERR; goto err; } data = malloc(argSz); if (!data) { ret = DNDMSG_NOMEM; goto err; } if (!DnDReadBuffer(&r, data, argSz)) { ret = DNDMSG_ERR; goto err; } if (!DnDMsg_AppendArg(msg, data, argSz)) { ret = DNDMSG_NOMEM; goto err; } readArgsSz += argSz + sizeof (uint32); free(data); } ASSERT(ret == DNDMSG_SUCCESS); return ret; err: if (data) { free(data); } count = DynBufArray_Count(&msg->args); for (i = 0; i < count; ++i) { DynBuf *b = DynArray_AddressOf(&msg->args, i); DynBuf_Destroy(b); } /* * DnDMsg_AppendArg relies on DynBufArray_Push, hence the count needs to be * reset. */ DynBufArray_SetCount(&msg->args, 0); return ret; } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/fileTransferRpcV4.hh0000644765153500003110000000423512220061556024430 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @fileTransferRpcV4.hh -- * * File transfer rpc version 4 object for DnD/CopyPaste. */ #ifndef FILE_TRANSFER_RPC_V4_HH #define FILE_TRANSFER_RPC_V4_HH #include "fileTransferRpc.hh" #include "dndCPTransport.h" #include "rpcV4Util.hpp" extern "C" { #include "dndCPMsgV4.h" } class LIB_EXPORT FileTransferRpcV4 : public FileTransferRpc, public sigc::trackable { public: FileTransferRpcV4(DnDCPTransport *transport); virtual void Init(void); virtual bool SendHgfsPacket(uint32 sessionId, const uint8 *packet, uint32 packetSize); virtual bool SendHgfsReply(uint32 sessionId, const uint8 *packet, uint32 packetSize); virtual void HandleMsg(RpcParams *params, const uint8 *binary, uint32 binarySize); virtual bool SendPacket(uint32 destId, const uint8 *packet, size_t length); virtual void OnRecvPacket(uint32 srcId, const uint8 *packet, size_t packetSize); private: DnDCPTransport *mTransport; TransportInterfaceType mTransportInterface; RpcV4Util mUtil; }; #endif // FILE_TRANSFER_RPC_V4_HH open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/rpcBase.h0000644765153500003110000000555612220061556022343 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * rpcBase.h -- * * Rpc layer object for DnD/CP. */ #ifndef RPC_BASE_H #define RPC_BASE_H #ifndef LIB_EXPORT #define LIB_EXPORT #endif extern "C" { #include "vm_basic_types.h" } typedef struct RpcParams { uint32 addrId; /* Destination address id. */ uint32 cmd; /* DnD/CP message command. */ uint32 sessionId; /* DnD/CP session ID. */ uint32 status; /* Status for last operation. */ union { struct { uint32 major; uint32 minor; uint32 capability; } version; struct { uint32 x; uint32 y; } mouseInfo; struct { uint32 cmd; } replyToCmd; struct { uint32 cmd; uint32 binarySize; uint32 payloadOffset; } requestNextCmd; struct { uint32 feedback; } feedback; struct { uint32 major; uint32 minor; uint32 capability; uint32 x; uint32 y; } queryExiting; struct { uint32 major; uint32 minor; uint32 capability; uint32 show; uint32 unityWndId; } updateUnityDetWnd; struct { uint32 major; uint32 minor; uint32 capability; uint32 isActive; } cpInfo; struct { uint32 param1; uint32 param2; uint32 param3; uint32 param4; uint32 param5; uint32 param6; } genericParams; } optional; } RpcParams; class LIB_EXPORT RpcBase { public: virtual ~RpcBase(void) {}; virtual void OnRecvPacket(uint32 srcId, const uint8 *packet, size_t packetSize) = 0; virtual bool SendPacket(uint32 destId, const uint8 *packet, size_t length) = 0; virtual void HandleMsg(RpcParams *params, const uint8 *binary, uint32 binarySize) = 0; }; #endif // RPC_BASE_H open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/dndCommon.c0000644765153500003110000006500012220061556022663 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * dndCommon.c -- * * Implementation of bora/lib/public/dnd.h functions that are common to * Linux and Windows platforms */ #include #include #include #include "vmware.h" #include "dndInt.h" #include "dnd.h" #include "file.h" #include "str.h" #include "random.h" #include "util.h" #include "cpNameUtil.h" #include "hgfsEscape.h" #include "hgfsServerPolicy.h" #include "hgfsVirtualDir.h" #include "unicodeOperations.h" #include "hostinfo.h" #define LOGLEVEL_MODULE dnd #include "loglevel_user.h" #define WIN_DIRSEPC '\\' #define WIN_DIRSEPS "\\" static ConstUnicode DnDCreateRootStagingDirectory(void); /* *----------------------------------------------------------------------------- * * DnD_CreateStagingDirectory -- * * Generate a unique staging directory name, create the directory, and * return the name. The caller is responsible for freeing the returned * string. * * Our staging directory structure is comprised of a "root" staging * directory that itself contains multiple staging directories that are * intended to be used on a per-DnD and per-user basis. That is, each DnD * by a particular user will have its own staging directory within the root. * Sometimes these directories are emptied after the DnD (either because it * was cancelled or the destination application told us to), and we resuse * any empty directories that we can. This function will return a directory * to be reused if possible and fall back on creating a new one if * necessary. * * Results: * A string containing the newly created name, or NULL on failure. * * Side effects: * A directory is created * *----------------------------------------------------------------------------- */ Unicode DnD_CreateStagingDirectory(void) { ConstUnicode root; Unicode *stagingDirList; int numStagingDirs; int i; Unicode ret = NULL; Bool found = FALSE; /* * Make sure the root staging directory is created with the correct * permissions. */ root = DnDCreateRootStagingDirectory(); if (!root) { return NULL; } /* Look for an existing, empty staging directory */ numStagingDirs = File_ListDirectory(root, &stagingDirList); if (numStagingDirs < 0) { goto exit; } for (i = 0; i < numStagingDirs; i++) { if (!found) { Unicode stagingDir; stagingDir = Unicode_Append(root, stagingDirList[i]); if (File_IsEmptyDirectory(stagingDir) && DnDStagingDirectoryUsable(stagingDir)) { ret = Unicode_Append(stagingDir, DIRSEPS); /* * We can use this directory. Make sure to continue to loop * so we don't leak the remaining stagindDirList[i]s. */ found = TRUE; } Unicode_Free(stagingDir); } } Unicode_FreeList(stagingDirList, numStagingDirs); /* Only create a directory if we didn't find one above. */ if (!found) { rqContext *context; context = Random_QuickSeed((unsigned)time(NULL)); for (i = 0; i < 10; i++) { Unicode temp; /* Each staging directory is given a random name. */ Unicode_Free(ret); temp = Unicode_Format("%08x%c", Random_Quick(context), DIRSEPC); ASSERT_MEM_ALLOC(temp); ret = Unicode_Append(root, temp); Unicode_Free(temp); if (File_CreateDirectory(ret) && DnDSetPermissionsOnStagingDir(ret)) { found = TRUE; break; } } free(context); } exit: if (!found && ret != NULL) { Unicode_Free(ret); ret = NULL; } return ret; } /* *----------------------------------------------------------------------------- * * DnD_DeleteStagingFiles -- * * Attempts to delete all files in the staging directory. This does not * delete the directory itself. * * Results: * TRUE if all files were deleted. FALSE if there was an error. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool DnD_DeleteStagingFiles(ConstUnicode stagingDir, // IN: Bool onReboot) // IN: { Bool ret = TRUE; ASSERT(stagingDir); if (!File_Exists(stagingDir)) { /* The stagingDir is already gone. */ return TRUE; } if (!File_IsDirectory(stagingDir)) { return FALSE; } if (onReboot) { if (File_UnlinkDelayed(stagingDir)) { ret = FALSE; } } else { int i; int numFiles; Unicode base; Unicode *fileList = NULL; /* get list of files in current directory */ numFiles = File_ListDirectory(stagingDir, &fileList); if (numFiles == -1) { return FALSE; } /* delete everything in the directory */ base = Unicode_Append(stagingDir, DIRSEPS); for (i = 0; i < numFiles; i++) { Unicode curPath; curPath = Unicode_Append(base, fileList[i]); if (File_IsDirectory(curPath)) { if (!File_DeleteDirectoryTree(curPath)) { ret = FALSE; } } else { if (File_Unlink(curPath) == -1) { ret = FALSE; } } Unicode_Free(curPath); } Unicode_Free(base); } return ret; } /* *---------------------------------------------------------------------------- * * DnDCreateRootStagingDirectory -- * * Checks if the root staging directory exists with the correct permissions, * or creates it if necessary. * * Results: * The path of the root directory on success, NULL on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static ConstUnicode DnDCreateRootStagingDirectory(void) { ConstUnicode root; /* * DnD_GetFileRoot() gives us a pointer to a static string, so there's no * need to free anything. */ root = DnD_GetFileRoot(); if (!root) { return NULL; } if (File_Exists(root)) { if (!DnDRootDirUsable(root) && !DnDSetPermissionsOnRootDir(root)) { /* * The directory already exists and its permissions are wrong and * cannot be set, so there's not much we can do. */ return NULL; } } else { if (!File_CreateDirectory(root) || !DnDSetPermissionsOnRootDir(root)) { /* We couldn't create the directory or set the permissions. */ return NULL; } } return root; } /* *---------------------------------------------------------------------------- * * DnDPrependFileRoot -- * * Given a buffer of '\0' delimited filenames, this prepends the file root * to each one and uses delimiter for delimiting the output buffer. The * buffer pointed to by *src will be freed and *src will point to a new * buffer containing the results. *srcSize is set to the size of the new * buffer, not including the NUL-terminator. * * The logic here and in the called functions appears to be UTF8-safe. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * *src will be freed, and a new buffer will be allocated. This buffer must * be freed by the caller. * *---------------------------------------------------------------------------- */ Bool DnDPrependFileRoot(ConstUnicode fileRoot, // IN : file root to append char delimiter, // IN : delimiter for output buffer char **src, // IN/OUT: NUL-delimited list of paths size_t *srcSize) // IN/OUT: size of list { char *newData = NULL; size_t newDataLen = 0; Bool firstPass = TRUE; const char *begin; const char *end; const char *next; size_t rootLen; int len; ASSERT(fileRoot); ASSERT(src); ASSERT(*src); ASSERT(srcSize); rootLen = strlen(fileRoot); /* * To prevent CPName_GetComponent() errors, we set begin to the first * Non-NUL character in *src, and end to the last NUL character in *src. We * assume that the components are delimited with single NUL characters; if * that is not true, CPName_GetComponent() will fail. */ for (begin = *src; *begin == '\0'; begin++) ; end = CPNameUtil_Strrchr(*src, *srcSize, '\0'); /* Get the length of this component, and a pointer to the next */ while ((len = CPName_GetComponent(begin, end, &next)) != 0) { size_t origNewDataLen = newDataLen; int escapedLen; if (len < 0) { Log("%s: error getting next component\n", __FUNCTION__); if (!firstPass) { free(newData); } return FALSE; } /* * Append this component to our list: allocate one more for NUL on first * pass and delimiter on all other passes. */ escapedLen = HgfsEscape_GetSize(begin, len); if (escapedLen < 0) { Log("%s: error calculating buffer size\n", __FUNCTION__); return FALSE; } else if (0 == escapedLen) { newDataLen += rootLen + len + 1; newData = (char *)Util_SafeRealloc(newData, newDataLen); if (!firstPass) { ASSERT(origNewDataLen > 0); newData[origNewDataLen - 1] = delimiter; } memcpy(newData + origNewDataLen, fileRoot, rootLen); memcpy(newData + origNewDataLen + rootLen, begin, len); } else { newDataLen += rootLen + 1; newData = (char *)Util_SafeRealloc(newData, newDataLen); if (!firstPass) { ASSERT(origNewDataLen > 0); newData[origNewDataLen - 1] = delimiter; } memcpy(newData + origNewDataLen, fileRoot, rootLen); HgfsEscape_Do(begin, len, escapedLen, newData + origNewDataLen + rootLen); } newData[newDataLen - 1] = '\0'; firstPass = FALSE; begin = next; } free(*src); *src = newData; /* Not including NUL terminator */ *srcSize = newDataLen - 1; return TRUE; } /* *---------------------------------------------------------------------------- * * DnD_LegacyConvertToCPName -- * * Converts paths received from older tools that do not send data in CPName * format across the backdoor. Older tools send paths in Windows format so * this implementation must always convert from Windows path to CPName path, * regardless of the platform we are running on. * * The logic here and in the called functions appears to be UTF8-safe. * * Results: * On success, returns the number of bytes used in the cross-platform name, * NOT including the final terminating NUL character. On failure, returns * a negative error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int DnD_LegacyConvertToCPName(const char *nameIn, // IN: Buffer to convert size_t bufOutSize, // IN: Size of output buffer char *bufOut) // OUT: Output buffer { const char partialName[] = HGFS_SERVER_POLICY_ROOT_SHARE_NAME; const size_t partialNameLen = HGFS_STR_LEN(HGFS_SERVER_POLICY_ROOT_SHARE_NAME); const char *partialNameSuffix = ""; size_t partialNameSuffixLen; char *fullName; size_t fullNameSize; size_t nameSize; int result; ASSERT(nameIn); ASSERT(bufOut); /* * Create the full name. Note that Str_Asprintf should not be * used here as it uses FormatMessages which interprets 'data', a UTF-8 * string, as a string in the current locale giving wrong results. */ /* * Is this file path a UNC path? */ if (nameIn[0] == WIN_DIRSEPC && nameIn[1] == WIN_DIRSEPC) { partialNameSuffix = WIN_DIRSEPS HGFS_UNC_DIR_NAME WIN_DIRSEPS; partialNameSuffixLen = HGFS_STR_LEN(WIN_DIRSEPS) + HGFS_STR_LEN(HGFS_UNC_DIR_NAME) + HGFS_STR_LEN(WIN_DIRSEPS); } else { partialNameSuffix = WIN_DIRSEPS HGFS_DRIVE_DIR_NAME WIN_DIRSEPS; partialNameSuffixLen = HGFS_STR_LEN(WIN_DIRSEPS) + HGFS_STR_LEN(HGFS_DRIVE_DIR_NAME) + HGFS_STR_LEN(WIN_DIRSEPS); } /* Skip any path separators at the beginning of the input string */ while (*nameIn == WIN_DIRSEPC) { nameIn++; } nameSize = strlen(nameIn); fullNameSize = partialNameLen + partialNameSuffixLen + nameSize; fullName = (char *)Util_SafeMalloc(fullNameSize + 1); memcpy(fullName, partialName, partialNameLen); memcpy(fullName + partialNameLen, partialNameSuffix, partialNameSuffixLen); memcpy(fullName + partialNameLen + partialNameSuffixLen, nameIn, nameSize); fullName[fullNameSize] = '\0'; LOG(4, ("%s: generated name is \"%s\"\n", __FUNCTION__, fullName)); /* * CPName_ConvertTo implementation is performed here without calling any * CPName_ functions. This is safer since those functions might change, but * the legacy behavior we are special casing here will not. */ { char const *winNameIn = fullName; char const *origOut = bufOut; char const *endOut = bufOut + bufOutSize; char const pathSep = WIN_DIRSEPC; char *ignores = ":"; /* Skip any path separators at the beginning of the input string */ while (*winNameIn == pathSep) { winNameIn++; } /* * Copy the string to the output buf, converting all path separators into * '\0' and ignoring the specified characters. */ for (; *winNameIn != '\0' && bufOut < endOut; winNameIn++) { if (ignores) { char *currIgnore = ignores; Bool ignore = FALSE; while (*currIgnore != '\0') { if (*winNameIn == *currIgnore) { ignore = TRUE; break; } currIgnore++; } if (!ignore) { *bufOut = (*winNameIn == pathSep) ? '\0' : *winNameIn; bufOut++; } } else { *bufOut = (*winNameIn == pathSep) ? '\0' : *winNameIn; bufOut++; } } /* * NUL terminate. XXX This should go away. * * When we get rid of NUL termination here, this test should * also change to "if (*winNameIn != '\0')". */ if (bufOut == endOut) { result = -1; goto out; } *bufOut = '\0'; /* Path name size should not require more than 4 bytes. */ ASSERT((bufOut - origOut) <= 0xFFFFFFFF); /* If there were any trailing path separators, dont count them [krishnan] */ result = (int)(bufOut - origOut); while ((result >= 1) && (origOut[result - 1] == 0)) { result--; } /* * Make exception and call CPName_Print() here, since it's only for * logging */ LOG(4, ("%s: CPName is \"%s\"\n", __FUNCTION__, CPName_Print(origOut, result))); } out: free(fullName); return result; } /* *----------------------------------------------------------------------------- * * DnD_CPNameListToDynBufArray -- * * Export CPName file list from binary buffer to DynBufArray. * * Results: * TRUE if success, FALSE otherwise. * * Side effects: * Memory may allocated for DynBufArray if success. * *----------------------------------------------------------------------------- */ Bool DnD_CPNameListToDynBufArray(char *fileList, // IN: CPName format size_t listSize, // IN DynBufArray *dynBufArray) // OUT { DynBuf buf; BufRead r; int32 pathLen; size_t count; size_t i; ASSERT(fileList); r.pos = fileList; r.unreadLen = listSize; DynBufArray_Init(dynBufArray, 0); while (r.unreadLen > 0) { DynBuf_Init(&buf); if (!DnDReadBuffer(&r, &pathLen, sizeof pathLen) || (pathLen > r.unreadLen) || !DynBuf_Append(&buf, r.pos, pathLen)) { goto error; } if (!DnDSlideBuffer(&r, pathLen)) { goto error; } if (!DynBufArray_Push(dynBufArray, buf)) { goto error; } } return TRUE; error: DynBuf_Destroy(&buf); count = DynBufArray_Count(dynBufArray); for (i = 0; i < count; i++) { DynBuf *b = DynArray_AddressOf(dynBufArray, i); DynBuf_Destroy(b); } DynBufArray_SetCount(dynBufArray, 0); DynBufArray_Destroy(dynBufArray); return FALSE; } /* *----------------------------------------------------------------------------- * * DnD_GetLastDirName -- * * Try to get last directory name from a full path name. * * Results: * The allocated Unicode string, or NULL on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Unicode DnD_GetLastDirName(ConstUnicode str) // IN { size_t end = strlen(str); size_t start; size_t res = 0; if (end != 0 && DIRSEPC == str[end - 1]) { end--; } if (end == 0) { return 0; } start = end; while (start && DIRSEPC != str[start - 1]) { start--; } /* There should be at lease 1 DIRSEPC before end. */ if (start == 0) { return 0; } res = end - start; return Unicode_AllocWithLength(str + start, res, STRING_ENCODING_UTF8); } /* Transport layer big buffer support functions. */ /* *----------------------------------------------------------------------------- * * DnD_TransportBufInit -- * * Initialize transport layer buffer with DnD message. * * Results: * None. * * Side effects: * Buffer memory is allocated. * *----------------------------------------------------------------------------- */ void DnD_TransportBufInit(DnDTransportBuffer *buf, // OUT uint8 *msg, // IN size_t msgSize, // IN uint32 seqNum) // IN { ASSERT(buf); ASSERT(msgSize <= DNDMSG_MAX_ARGSZ); free(buf->buffer); buf->buffer = Util_SafeMalloc(msgSize); memcpy(buf->buffer, msg, msgSize); buf->seqNum = seqNum; buf->totalSize = msgSize; buf->offset = 0; } /* *----------------------------------------------------------------------------- * * DnD_TransportBufReset -- * * Reset transport layer buffer. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void DnD_TransportBufReset(DnDTransportBuffer *buf) // IN/OUT { ASSERT(buf); free(buf->buffer); buf->buffer = NULL; buf->seqNum = 0; buf->totalSize = 0; buf->offset = 0; buf->lastUpdateTime = 0; } /* *----------------------------------------------------------------------------- * * DnD_TransportBufGetPacket -- * * Get a transport layer packet from transport layer buffer. * * Results: * Transport layer packet size, or 0 if failed. * * Side effects: * Memory may be allocated for packet. * *----------------------------------------------------------------------------- */ size_t DnD_TransportBufGetPacket(DnDTransportBuffer *buf, // IN/OUT DnDTransportPacketHeader **packet) // OUT { size_t payloadSize; ASSERT(buf); if (buf->totalSize < buf->offset) { return 0; } if ((buf->totalSize - buf->offset) > DND_MAX_TRANSPORT_PACKET_PAYLOAD_SIZE) { payloadSize = DND_MAX_TRANSPORT_PACKET_PAYLOAD_SIZE; } else { payloadSize = buf->totalSize - buf->offset; } *packet = (DnDTransportPacketHeader *)Util_SafeMalloc( payloadSize + DND_TRANSPORT_PACKET_HEADER_SIZE); (*packet)->type = DND_TRANSPORT_PACKET_TYPE_PAYLOAD; (*packet)->seqNum = buf->seqNum; (*packet)->totalSize = buf->totalSize; (*packet)->payloadSize = payloadSize; (*packet)->offset = buf->offset; memcpy((*packet)->payload, buf->buffer + buf->offset, payloadSize); buf->offset += payloadSize; /* This time is used for timeout purpose. */ buf->lastUpdateTime = Hostinfo_SystemTimerUS(); return payloadSize + DND_TRANSPORT_PACKET_HEADER_SIZE; } /* *----------------------------------------------------------------------------- * * DnD_TransportBufAppendPacket -- * * Put a received packet into transport layer buffer. * * Results: * TRUE if success, FALSE otherwise. * * Side effects: * Memory may be allocated for transport layer buffer. * *----------------------------------------------------------------------------- */ Bool DnD_TransportBufAppendPacket(DnDTransportBuffer *buf, // IN/OUT DnDTransportPacketHeader *packet, // IN size_t packetSize) // IN { ASSERT(buf); ASSERT(packetSize == (packet->payloadSize + DND_TRANSPORT_PACKET_HEADER_SIZE) && packetSize <= DND_MAX_TRANSPORT_PACKET_SIZE && (packet->payloadSize + packet->offset) <= packet->totalSize && packet->totalSize <= DNDMSG_MAX_ARGSZ); if (packetSize != (packet->payloadSize + DND_TRANSPORT_PACKET_HEADER_SIZE) || packetSize > DND_MAX_TRANSPORT_PACKET_SIZE || (packet->payloadSize + packet->offset) > packet->totalSize || packet->totalSize > DNDMSG_MAX_ARGSZ) { goto error; } /* * If seqNum does not match, it means either this is the first packet, or there * is a timeout in another side. Reset the buffer in all cases. */ if (buf->seqNum != packet->seqNum) { DnD_TransportBufReset(buf); } if (!buf->buffer) { ASSERT(!packet->offset); if (packet->offset) { goto error; } buf->buffer = Util_SafeMalloc(packet->totalSize); buf->totalSize = packet->totalSize; buf->seqNum = packet->seqNum; buf->offset = 0; } if (buf->offset != packet->offset) { goto error; } memcpy(buf->buffer + buf->offset, packet->payload, packet->payloadSize); buf->offset += packet->payloadSize; return TRUE; error: DnD_TransportBufReset(buf); return FALSE; } /* *----------------------------------------------------------------------------- * * DnD_TransportMsgToPacket -- * * Get a packet from small size message. * * Results: * Transport layer packet size, or 0 if failed. * * Side effects: * Memory may be allocated for packet. * *----------------------------------------------------------------------------- */ size_t DnD_TransportMsgToPacket(uint8 *msg, // IN size_t msgSize, // IN uint32 seqNum, // IN DnDTransportPacketHeader **packet) // OUT { size_t packetSize; ASSERT(msgSize > 0 && msgSize <= DND_MAX_TRANSPORT_PACKET_PAYLOAD_SIZE); ASSERT(msg); ASSERT(packet); if (msgSize <=0 || msgSize > DND_MAX_TRANSPORT_PACKET_PAYLOAD_SIZE || !msg || !packet) { return 0; } packetSize = msgSize + DND_TRANSPORT_PACKET_HEADER_SIZE; *packet = (DnDTransportPacketHeader *)Util_SafeMalloc(packetSize); (*packet)->type = DND_TRANSPORT_PACKET_TYPE_SINGLE; (*packet)->seqNum = seqNum; (*packet)->totalSize = msgSize; (*packet)->payloadSize = msgSize; (*packet)->offset = 0; memcpy((*packet)->payload, msg, msgSize); return packetSize; } /* *----------------------------------------------------------------------------- * * DnD_TransportReqPacket -- * * Generate a request packet with empty payload. After got a payload, receive * side should send a DND_TRANSPORT_PACKET_TYPE_REQUEST packet to ask for * next payload packet. * * Results: * Transport layer packet size. * * Side effects: * Memory is allocated for packet. * *----------------------------------------------------------------------------- */ size_t DnD_TransportReqPacket(DnDTransportBuffer *buf, // IN DnDTransportPacketHeader **packet) // OUT { *packet = (DnDTransportPacketHeader *)Util_SafeMalloc( DND_TRANSPORT_PACKET_HEADER_SIZE); (*packet)->type = DND_TRANSPORT_PACKET_TYPE_REQUEST; (*packet)->seqNum = buf->seqNum; (*packet)->totalSize = buf->totalSize; (*packet)->payloadSize = 0; (*packet)->offset = buf->offset; return DND_TRANSPORT_PACKET_HEADER_SIZE; } /* *---------------------------------------------------------------------------- * * DnDReadBuffer -- * * Copies len bytes of data from b to out. Subsequent calls to this * function will copy data from the last unread point. * * Results: * TRUE when data is successfully copies to out, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool DnDReadBuffer(BufRead *b, // IN/OUT: buffer to read from void *out, // OUT: the output buffer size_t len) // IN: the amount to read { ASSERT(b); ASSERT(out); if (len > b->unreadLen) { return FALSE; } memcpy(out, b->pos, len); if (!DnDSlideBuffer(b, len)) { return FALSE; } return TRUE; } /* *---------------------------------------------------------------------------- * * DnDSlideBuffer -- * * Ignore len bytes of data in b. Subsequent calls to DnDReadBuffer will * copy data from the last point. * * Results: * TRUE when pos is successfully changed, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool DnDSlideBuffer(BufRead *b, // IN/OUT: buffer to read from size_t len) // IN: the amount to read { ASSERT(b); if (len > b->unreadLen) { return FALSE; } b->pos += len; b->unreadLen -= len; return TRUE; } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/dndInt.h0000644765153500003110000000344112220061556022173 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * dndInt.h -- * * Private functions for the Drag and Drop library. */ #ifndef __DND_INT_H__ #define __DND_INT_H__ #include "vm_basic_types.h" #include "unicodeTypes.h" typedef struct { const uint8 *pos; size_t unreadLen; } BufRead; Bool DnDDataContainsIllegalCharacters(const char *data, const size_t dataSize, const char *illegalChars); Bool DnDPrependFileRoot(ConstUnicode fileRoot, char delimiter, char **src, size_t *srcSize); Bool DnDRootDirUsable(ConstUnicode pathName); Bool DnDSetPermissionsOnRootDir(ConstUnicode pathName); Bool DnDStagingDirectoryUsable(ConstUnicode pathName); Bool DnDSetPermissionsOnStagingDir(ConstUnicode pathName); Bool DnDReadBuffer(BufRead *b, void *out, size_t len); Bool DnDSlideBuffer(BufRead *b, size_t len); #endif /* __DND_INT_H__ */ open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/dndCPLibExport.hh0000644765153500003110000000223712220061556023746 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @dndCPLibExport.hh -- * * LibExport definition. */ #ifndef DND_CP_LIB_EXPORT_HH #define DND_CP_LIB_EXPORT_HH #if defined VMX86_TOOLS || COMPILE_WITHOUT_CUI # ifdef LIB_EXPORT # undef LIB_EXPORT # endif #define LIB_EXPORT #else #include "libExport.hh" #endif #endif // DND_CP_LIB_EXPORT_HH open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/rpcV3Util.hpp0000644765153500003110000000247412220061556023153 0ustar dtormts/* ************************************************************************** * Copyright (C) 2010 VMware, Inc. All Rights Reserved -- VMware Confidential * **************************************************************************/ /** * @rpcV3Util.hpp -- * * Rpc layer object for DnD version 4. */ #ifndef RPC_V3_UTIL_HPP #define RPC_V3_UTIL_HPP #ifndef LIB_EXPORT #define LIB_EXPORT #endif #include "rpcBase.h" extern "C" { #include "dnd.h" } struct DnDMsg; class LIB_EXPORT RpcV3Util { public: RpcV3Util(void); virtual ~RpcV3Util(void); void Init(RpcBase *rpc); void OnRecvPacket(uint32 srcId, const uint8 *packet, size_t packetSize); bool SendMsg(uint32 cmd); bool SendMsg(uint32 cmd, const CPClipboard *clip); bool SendMsg(uint32 cmd, int32 x, int32 y); // For cmd with mouse info. bool SendMsg(const DnDMsg *msg); uint32 GetVersionMajor(void) { return mVersionMajor; } uint32 GetVersionMinor(void) { return mVersionMinor; } private: bool SendMsg(const uint8 *binary, uint32 binarySize); RpcBase *mRpc; uint32 mVersionMajor; uint32 mVersionMinor; uint32 mMsgType; uint32 mMsgSrc; DnDTransportBuffer mSendBuf; DnDTransportBuffer mRecvBuf; uint32 mSeqNum; }; #endif // RPC_V3_UTIL_HPP open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dnd/dndRpcV4.hh0000644765153500003110000000750712220061556022556 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @dndRpcV4.hh -- * * Rpc layer object for DnD version 4. */ #ifndef DND_RPC_V4_HH #define DND_RPC_V4_HH #include #include "dndRpc.hh" #include "dndCPTransport.h" #include "rpcV4Util.hpp" extern "C" { #include "dnd.h" #include "dndMsg.h" #include "dndCPMsgV4.h" } class LIB_EXPORT DnDRpcV4 : public DnDRpc, public sigc::trackable { public: DnDRpcV4(DnDCPTransport *transport); virtual void Init(void); virtual void SendPing(uint32 caps); /* DnD source. */ virtual bool SrcDragBeginDone(uint32 sessionId); virtual bool SrcDrop(uint32 sessionId, int32 x, int32 y); virtual bool SrcDropDone(uint32 sessionId, const uint8 *stagingDirCP, uint32 sz); virtual bool SrcPrivDragEnter(uint32 sessionId); virtual bool SrcPrivDragLeave(uint32 sessionId, int32 x, int32 y); virtual bool SrcPrivDrop(uint32 sessionId, int32 x, int32 y); virtual bool SrcCancel(uint32 sessionId); /* DnD destination. */ virtual bool DestDragEnter(uint32 sessionId, const CPClipboard *clip); virtual bool DestSendClip(uint32 sessionId, const CPClipboard *clip); virtual bool DestDragLeave(uint32 sessionId, int32 x, int32 y); virtual bool DestDrop(uint32 sessionId, int32 x, int32 y); virtual bool DestCancel(uint32 sessionId); /* Common. */ virtual bool UpdateFeedback(uint32 sessionId, DND_DROPEFFECT feedback); virtual bool MoveMouse(uint32 sessionId, int32 x, int32 y); virtual bool QueryExiting(uint32 sessionId, int32 x, int32 y); virtual bool DragNotPending(uint32 sessionId); virtual bool UpdateUnityDetWnd(uint32 sessionId, bool bShow, uint32 unityWndId); virtual bool RequestFiles(uint32 sessionId); virtual bool SendFilesDone(uint32 sessionId, bool success, const uint8 *stagingDirCP, uint32 sz); virtual bool GetFilesDone(uint32 sessionId, bool success); virtual void HandleMsg(RpcParams *params, const uint8 *binary, uint32 binarySize); virtual bool SendPacket(uint32 destId, const uint8 *packet, size_t length); virtual void OnRecvPacket(uint32 srcId, const uint8 *packet, size_t packetSize); void AddRpcReceivedListener(DnDRpcListener *obj); void RemoveRpcReceivedListener(DnDRpcListener *obj); void AddRpcSentListener(DnDRpcListener *obj); void RemoveRpcSentListener(DnDRpcListener *obj); private: DnDCPTransport *mTransport; TransportInterfaceType mTransportInterface; RpcV4Util mUtil; }; #endif // DND_RPC_V4_HH open-vm-tools-9.4.0-1280544/services/plugins/dndcp/Makefile.am0000644765153500003110000000667012220061556022100 0ustar dtormts################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ plugindir = @VMUSR_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libdndcp.la CFLAGS += -Wno-unused libdndcp_la_CPPFLAGS = libdndcp_la_CPPFLAGS += @GTK_CPPFLAGS@ libdndcp_la_CPPFLAGS += @GTKMM_CPPFLAGS@ libdndcp_la_CPPFLAGS += @PLUGIN_CPPFLAGS@ libdndcp_la_CPPFLAGS += -I$(top_srcdir)/services/plugins/dndcp/dnd libdndcp_la_CPPFLAGS += -I$(top_srcdir)/services/plugins/dndcp/dndGuest libdndcp_la_CPPFLAGS += -I$(top_srcdir)/services/plugins/dndcp/stringxx libdndcp_la_CPPFLAGS += -I$(top_builddir)/include libdndcp_la_LDFLAGS = libdndcp_la_LDFLAGS += @PLUGIN_LDFLAGS@ libdndcp_la_LIBADD = libdndcp_la_LIBADD += @COMMON_XLIBS@ libdndcp_la_LIBADD += @GTK_LIBS@ libdndcp_la_LIBADD += @GTKMM_LIBS@ libdndcp_la_LIBADD += @VMTOOLS_LIBS@ libdndcp_la_LIBADD += @HGFS_LIBS@ libdndcp_la_SOURCES = libdndcp_la_SOURCES += dnd/dndClipboard.c libdndcp_la_SOURCES += dnd/dndCommon.c libdndcp_la_SOURCES += dnd/dndCPMsgV4.c libdndcp_la_SOURCES += dnd/dndLinux.c libdndcp_la_SOURCES += dnd/dndMsg.c libdndcp_la_SOURCES += dndGuest/copyPasteRpcV3.cc libdndcp_la_SOURCES += dndGuest/dndFileList.cc libdndcp_la_SOURCES += dndGuest/dndRpcV3.cc libdndcp_la_SOURCES += dndGuest/guestCopyPasteDest.cc libdndcp_la_SOURCES += dndGuest/guestCopyPasteMgr.cc libdndcp_la_SOURCES += dndGuest/guestCopyPasteSrc.cc libdndcp_la_SOURCES += dndGuest/guestDnDCPMgr.cc libdndcp_la_SOURCES += dndGuest/guestDnDDest.cc libdndcp_la_SOURCES += dndGuest/guestDnDMgr.cc libdndcp_la_SOURCES += dndGuest/guestDnDSrc.cc libdndcp_la_SOURCES += dndGuest/guestFileTransfer.cc libdndcp_la_SOURCES += dndGuest/copyPasteRpcV4.cc libdndcp_la_SOURCES += dndGuest/dndRpcV4.cc libdndcp_la_SOURCES += dndGuest/fileTransferRpcV4.cc libdndcp_la_SOURCES += dndGuest/rpcV3Util.cpp libdndcp_la_SOURCES += dndGuest/rpcV4Util.cpp libdndcp_la_SOURCES += dndGuest/dndCPTransportGuestRpc.cpp libdndcp_la_SOURCES += stringxx/string.cc libdndcp_la_SOURCES += copyPasteCompat.c libdndcp_la_SOURCES += copyPasteCompatX11.c libdndcp_la_SOURCES += copyPasteDnDWrapper.cpp libdndcp_la_SOURCES += copyPasteDnDX11.cpp libdndcp_la_SOURCES += copyPasteUIX11.cpp libdndcp_la_SOURCES += dndUIX11.cpp libdndcp_la_SOURCES += dndcp.cpp libdndcp_la_SOURCES += dragDetWndX11.cpp libdndcp_la_SOURCES += pointer.cpp BUILT_SOURCES = BUILT_SOURCES += cpFileContents.h BUILT_SOURCES += cpFileContents_xdr.c CLEANFILES = CLEANFILES += $(BUILT_SOURCES) libdndcp_la_SOURCES += cpFileContents_xdr.c cpFileContents.h: cpFileContents.x @RPCGEN_WRAPPER@ services/plugins/dndcp/cpFileContents.x $@ cpFileContents_xdr.c: cpFileContents.x cpFileContents.h @RPCGEN_WRAPPER@ services/plugins/dndcp/cpFileContents.x $@ open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/0000755765153500003110000000000012220061556021610 5ustar dtormtsopen-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/rpcV4Util.hpp0000644765153500003110000000524212220061556024160 0ustar dtormts/* ************************************************************************** * Copyright (C) 2010 VMware, Inc. All Rights Reserved -- VMware Confidential * **************************************************************************/ /** * @rpcV4Util.hpp -- * * Rpc layer object for DnD version 4. */ #ifndef RPC_V4_UTIL_HPP #define RPC_V4_UTIL_HPP #ifndef LIB_EXPORT #define LIB_EXPORT #endif #include "rpcBase.h" #include "dndRpcListener.hpp" #include "dbllnklst.h" extern "C" { #include "dnd.h" #include "dndCPMsgV4.h" } typedef struct DnDRpcReceivedListenerNode { DblLnkLst_Links l; const DnDRpcListener *listener; } DnDRpcReceivedListenerNode; typedef struct DnDRpcSentListenerNode { DblLnkLst_Links l; const DnDRpcListener *listener; } DnDRpcSentListenerNode; class LIB_EXPORT RpcV4Util { public: RpcV4Util(void); virtual ~RpcV4Util(void); void Init(RpcBase *rpc, uint32 msgType, uint32 msgSrc); void OnRecvPacket(uint32 srcId, const uint8 *packet, size_t packetSize); bool SendPingMsg(uint32 destId, uint32 capability); bool SendPingReplyMsg(uint32 destId, uint32 capability); bool SendCmdReplyMsg(uint32 destId, uint32 cmd, uint32 status); bool SendMsg(RpcParams *params, const uint8 *binary, uint32 binarySize); bool SendMsg(RpcParams *params, const CPClipboard *clip); bool SendMsg(RpcParams *params) { return SendMsg(params, NULL, 0); } uint32 GetVersionMajor(void) { return mVersionMajor; } uint32 GetVersionMinor(void) { return mVersionMinor; } bool AddRpcReceivedListener(const DnDRpcListener *obj); bool RemoveRpcReceivedListener(const DnDRpcListener *obj); bool AddRpcSentListener(const DnDRpcListener *obj); bool RemoveRpcSentListener(const DnDRpcListener *obj); private: void FireRpcReceivedCallbacks(uint32 cmd, uint32 src, uint32 session); void FireRpcSentCallbacks(uint32 cmd, uint32 dest, uint32 session); bool SendMsg(DnDCPMsgV4 *msg); bool RequestNextPacket(void); void HandlePacket(uint32 srcId, const uint8 *packet, size_t packetSize); void HandlePacket(uint32 srcId, const uint8 *packet, size_t packetSize, DnDCPMsgPacketType packetType); void HandleMsg(DnDCPMsgV4 *msg); RpcBase *mRpc; uint32 mVersionMajor; uint32 mVersionMinor; DnDCPMsgV4 mBigMsgIn; DnDCPMsgV4 mBigMsgOut; uint32 mMsgType; uint32 mMsgSrc; DblLnkLst_Links mRpcSentListeners; DblLnkLst_Links mRpcReceivedListeners; }; #endif // RPC_V4_UTIL_HPP open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/dndFileList.hh0000644765153500003110000000512412220061556024334 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * dndFileList.hh * * Translates filelists to different formats. */ #ifndef DND_FILELIST_HH #define DND_FILELIST_HH #include #include extern "C" { #include "vm_basic_types.h" #include "dndClipboard.h" #include "dynbuf.h" } class DnDFileList { public: DnDFileList(); ~DnDFileList() {}; void SetFileSize(uint64 fsize); uint64 GetFileSize() const; void AddFile(const std::string fullPath, const std::string relPath); void AddFileUri(const std::string uriPath); void AddFiles(const std::vector fullPathList, const std::vector relPathList); void AddFileAttributes(const CPFileAttributes& attributes); /* Copy paste/dndV2 V2 rpc */ void SetRelPathsStr(const std::string inpath); /* DnDFileTransfer & V2 RPC */ std::string GetRelPathsStr() const; std::string GetFullPathsStr(bool local) const; std::string GetUriPathsStr() const; /* UI Local clipboard */ std::vector GetRelPaths() const; std::vector GetFileAttributes() const; /* CPClipboard */ bool ToCPClipboard(DynBuf *out, bool local) const; bool ToUriClipboard(DynBuf *out) const; bool AttributesToCPClipboard(DynBuf *out) const; bool FromCPClipboard(const void *buf, size_t len); bool AttributesFromCPClipboard(const void *buf, size_t len); void Clear(); private: std::vector mRelPaths; std::vector mFullPaths; std::vector mUriPaths; std::vector mAttributeList; std::string mFullPathsBinary; uint64 mFileSize; }; #endif // DND_FILELIST_HH open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/dndRpcListener.hpp0000644765153500003110000000137512220061556025247 0ustar dtormts/* ************************************************************************** * Copyright (C) 2010 VMware, Inc. All Rights Reserved -- VMware Confidential * **************************************************************************/ /** * @dndRpcListener.hpp -- * * Interface for objects that receive rpc send and received notifications * from the vmx dnd controller. These signals are used for introspection * during unit testing and simulation. */ #ifndef DND_RPC_LISTENER_HPP #define DND_RPC_LISTENER_HPP class DnDRpcListener { public: virtual ~DnDRpcListener() {}; virtual void OnRpcReceived(uint32 cmd, uint32 src, uint32 session) = 0; virtual void OnRpcSent(uint32 cmd, uint32 dest, uint32 session) = 0; }; #endif // DND_RPC_LISTENER_HPP open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/dndRpcV3.cc0000644765153500003110000003652312220061556023553 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @DnDRpcV3.cc -- * * Implementation of the DnDRpcV3 class. */ #if defined (_WIN32) /* * When compile this file for Windows dnd plugin dll, there may be a conflict * between CRT and MFC libraries. From * http://support.microsoft.com/default.aspx?scid=kb;en-us;q148652: The CRT * libraries use weak external linkage for the DllMain function. The MFC * libraries also contain this function. The function requires the MFC * libraries to be linked before the CRT library. The Afx.h include file * forces the correct order of the libraries. */ #include #endif #include "dndRpcV3.hh" extern "C" { #include "debug.h" #include "dndClipboard.h" #include "util.h" #include "dndMsg.h" } /** * Constructor. * * @param[in] transport for sending packets. */ DnDRpcV3::DnDRpcV3(DnDCPTransport *transport) : mTransport(transport), mTransportInterface(TRANSPORT_GUEST_CONTROLLER_DND) { ASSERT(mTransport); mUtil.Init(this); CPClipboard_Init(&mClipboard); } /** * Destructor. */ DnDRpcV3::~DnDRpcV3(void) { CPClipboard_Destroy(&mClipboard); } /** * Init. */ void DnDRpcV3::Init(void) { Debug("%s: entering.\n", __FUNCTION__); ASSERT(mTransport); mTransport->RegisterRpc(this, mTransportInterface); } /** * Send DND_HG_DRAG_ENTER_DONE message. * * @param[in] x mouse position x. * @param[in] y mouse position y. * * @return true on success, false otherwise. */ bool DnDRpcV3::SrcDragEnterDone(int32 x, int32 y) { Debug("%s: entering.\n", __FUNCTION__); return mUtil.SendMsg(DND_HG_DRAG_ENTER_DONE, x, y); } /** * Send DND_HG_DRAG_READY message. * * @param[ignored] sessionId active session id the controller assigned earlier. * * @return true on success, false otherwise. */ bool DnDRpcV3::SrcDragBeginDone(uint32 sessionId) { Debug("%s: entering.\n", __FUNCTION__); return mUtil.SendMsg(DND_HG_DRAG_READY); } /** * Send DND_HG_UPDATE_FEEDBACK message. * * @param[ignored] sessionId active session id the controller assigned earlier. * @param[in] feedback current dnd operation feedback. * * @return true on success, false otherwise. */ bool DnDRpcV3::UpdateFeedback(uint32 sessionId, DND_DROPEFFECT feedback) { DnDMsg msg; bool ret = false; DnDMsg_Init(&msg); DnDMsg_SetCmd(&msg, DND_HG_UPDATE_FEEDBACK); if (!DnDMsg_AppendArg(&msg, &feedback, sizeof feedback)) { Debug("%s: DnDMsg_AppendData failed.\n", __FUNCTION__); goto exit; } ret = mUtil.SendMsg(&msg); exit: DnDMsg_Destroy(&msg); return ret; } /** * Not needed for version 3. * * @param[ignored] sessionId active session id the controller assigned earlier. * * @return always true. */ bool DnDRpcV3::SrcPrivDragEnter(uint32 sessionId) { Debug("%s: entering.\n", __FUNCTION__); return true; } /** * Not needed for version 3. * * @param[ignored] sessionId active session id the controller assigned earlier. * @param[ignored] x mouse position x. * @param[ignored] y mouse position y. * * @return always true. */ bool DnDRpcV3::SrcPrivDragLeave(uint32 sessionId, int32 x, int32 y) { Debug("%s: entering.\n", __FUNCTION__); return true; } /** * Not needed for version 3. * * @param[ignored] sessionId active session id the controller assigned earlier. * @param[ignored] x mouse position x. * @param[ignored] y mouse position y. * * @return always true. */ bool DnDRpcV3::SrcPrivDrop(uint32 sessionId, int32 x, int32 y) { Debug("%s: entering.\n", __FUNCTION__); return true; } /** * Not needed for version 3. * * @param[ignored] sessionId active session id the controller assigned earlier. * @param[ignored] x mouse position x. * @param[ignored] y mouse position y. * * @return always true. */ bool DnDRpcV3::SrcDrop(uint32 sessionId, int32 x, int32 y) { Debug("%s: entering.\n", __FUNCTION__); return true; } /** * Send DND_HG_DROP_DONE message. * * @param[ignored] sessionId active session id the controller assigned earlier. * @param[in] stagingDirCP staging dir name in cross-platform format * @param[in] sz the staging dir name size in bytes * * @return true on success, false otherwise. */ bool DnDRpcV3::SrcDropDone(uint32 sessionId, const uint8 *stagingDirCP, uint32 sz) { DnDMsg msg; bool ret = false; Debug("%s: entering.\n", __FUNCTION__); DnDMsg_Init(&msg); /* Construct msg with both cmd CP_HG_START_FILE_COPY and stagingDirCP. */ DnDMsg_SetCmd(&msg, DND_HG_DROP_DONE); if (!DnDMsg_AppendArg(&msg, (void *)stagingDirCP, sz)) { Debug("%s: DnDMsg_AppendData failed.\n", __FUNCTION__); goto exit; } ret = mUtil.SendMsg(&msg); exit: DnDMsg_Destroy(&msg); return ret; } /** * Send DND_GH_DRAG_ENTER message. * * @param[ignored] sessionId active session id the controller assigned earlier. * @param[in] clip cross-platform clipboard data. * * @return true on success, false otherwise. */ bool DnDRpcV3::DestDragEnter(uint32 sessionId, const CPClipboard *clip) { Debug("%s: entering.\n", __FUNCTION__); return mUtil.SendMsg(DND_GH_DRAG_ENTER, clip); } /** * Not needed for version 3. * * @param[ignored] sessionId active session id the controller assigned earlier. * @param[ignored] clip cross-platform clipboard data. * * @return always true. */ bool DnDRpcV3::DestSendClip(uint32 sessionId, const CPClipboard *clip) { Debug("%s: entering.\n", __FUNCTION__); return true; } /** * Send DND_GH_NOT_PENDING message. * * @param[ignored] sessionId active session id the controller assigned earlier. * * @return true on success, false otherwise. */ bool DnDRpcV3::DragNotPending(uint32 sessionId) { Debug("%s: entering.\n", __FUNCTION__); return mUtil.SendMsg(DND_GH_NOT_PENDING); } /** * Not needed for version 3. * * @param[ignored] sessionId active session id the controller assigned earlier. * @param[ignored] x mouse position x. * @param[ignored] y mouse position y. * * @return always true. */ bool DnDRpcV3::DestDragLeave(uint32 sessionId, int32 x, int32 y) { Debug("%s: entering.\n", __FUNCTION__); return true; } /** * Not needed for version 3. * * @param[ignored] sessionId active session id the controller assigned earlier. * @param[ignored] x mouse position x. * @param[ignored] y mouse position y. * * @return always true. */ bool DnDRpcV3::DestDrop(uint32 sessionId, int32 x, int32 y) { Debug("%s: entering.\n", __FUNCTION__); return true; } /** * Not needed for version 3. * * @param[ignored] sessionId active session id the controller assigned earlier. * @param[ignored] x mouse position x. * @param[ignored] y mouse position y. * * @return always true. */ bool DnDRpcV3::QueryExiting(uint32 sessionId, int32 x, int32 y) { Debug("%s: entering.\n", __FUNCTION__); return true; } /** * Not needed for version 3. * * @param[ignored] sessionId Active session id the controller assigned earlier. * @param[ignored] show Show or hide unity DnD detection window. * @param[ignored] unityWndId The unity windows id. * * @return always true. */ bool DnDRpcV3::UpdateUnityDetWnd(uint32 sessionId, bool show, uint32 unityWndId) { Debug("%s: entering.\n", __FUNCTION__); return true; } /** * Not needed for version 3. * * @param[ignored] sessionId active session id the controller assigned earlier. * @param[ignored] x mouse position x. * @param[ignored] y mouse position y. * * @return always true. */ bool DnDRpcV3::MoveMouse(uint32 sessionId, int32 x, int32 y) { Debug("%s: entering.\n", __FUNCTION__); return true; } /** * Not needed for version 3. * * @param[ignored] sessionId active session id the controller assigned earlier. * * @return always true. */ bool DnDRpcV3::RequestFiles(uint32 sessionId) { Debug("%s: entering.\n", __FUNCTION__); return true; } /** * Not needed for version 3. * * @param[ignored] sessionId active session id the controller assigned earlier. * @param[ignored] success the file transfer operation was successful or not * @param[ignored] stagingDirCP staging dir name in cross-platform format * @param[ignored] sz the staging dir name size in bytes * * @return always true. */ bool DnDRpcV3::SendFilesDone(uint32 sessionId, bool success, const uint8 *stagingDirCP, uint32 sz) { Debug("%s: entering.\n", __FUNCTION__); return true; } /** * Not needed for version 3. * * @param[ignored] sessionId active session id the controller assigned earlier. * @param[ignored] success the file transfer operation was successful or not * * @return always true. */ bool DnDRpcV3::GetFilesDone(uint32 sessionId, bool success) { Debug("%s: entering.\n", __FUNCTION__); return true; } /** * Send a packet. * * @param[in] destId destination address id. * @param[in] packet * @param[in] length packet length * * @return true on success, false otherwise. */ bool DnDRpcV3::SendPacket(uint32 destId, const uint8 *packet, size_t length) { Debug("%s: entering.\n", __FUNCTION__); return mTransport->SendPacket(destId, mTransportInterface, packet, length); } /** * Handle a received version 3 message. * * @param[in] params parameter list for received message. * @param[in] binary attached binary data for received message. * @param[in] binarySize */ void DnDRpcV3::HandleMsg(RpcParams *params, const uint8 *binary, uint32 binarySize) { DnDMsg msg; DnDMsgErr ret; DynBuf *buf = NULL; DnDMsg_Init(&msg); ret = DnDMsg_UnserializeHeader(&msg, (void *)binary, binarySize); if (DNDMSG_SUCCESS != ret) { Debug("%s: DnDMsg_UnserializeHeader failed %d\n", __FUNCTION__, ret); goto exit; } ret = DnDMsg_UnserializeArgs(&msg, (void *)(binary + DNDMSG_HEADERSIZE_V3), binarySize - DNDMSG_HEADERSIZE_V3); if (DNDMSG_SUCCESS != ret) { Debug("%s: DnDMsg_UnserializeArgs failed with %d\n", __FUNCTION__, ret); goto exit; } Debug("%s: Got %d, binary size %d.\n", __FUNCTION__, DnDMsg_GetCmd(&msg), binarySize); /* * Translate command and emit signal. Session Id 1 is used because version * 3 command does not provide session Id. */ switch (DnDMsg_GetCmd(&msg)) { case DND_HG_DRAG_ENTER: { CPClipboard_Clear(&mClipboard); /* Unserialize clipboard data for the command. */ buf = DnDMsg_GetArg(&msg, 0); if (!CPClipboard_Unserialize(&mClipboard, DynBuf_Get(buf), DynBuf_GetSize(buf))) { Debug("%s: CPClipboard_Unserialize failed.\n", __FUNCTION__); break; } SrcDragEnterDone(DRAG_DET_WINDOW_WIDTH / 2, DRAG_DET_WINDOW_WIDTH / 2); break; } case DND_HG_DRAG_START: srcDragBeginChanged.emit(1, &mClipboard); CPClipboard_Clear(&mClipboard); break; case DND_HG_CANCEL: srcCancelChanged.emit(1); break; case DND_HG_DROP: srcDropChanged.emit(1, 0, 0); break; case DND_GH_CANCEL: destCancelChanged.emit(1); break; case DND_GH_PRIVATE_DROP: { int32 x = 0; int32 y = 0; buf = DnDMsg_GetArg(&msg, 0); if (DynBuf_GetSize(buf) == sizeof(int32)) { memcpy(&x, (const char *)DynBuf_Get(buf), sizeof(int32)); } else { break; } buf = DnDMsg_GetArg(&msg, 1); if (DynBuf_GetSize(buf) == sizeof(int32)) { memcpy(&y, (const char *)DynBuf_Get(buf), sizeof(int32)); } else { break; } destPrivDropChanged.emit(1, x, y); break; } case DND_GH_UPDATE_UNITY_DET_WND: { bool show = false; uint32 unityWndId; buf = DnDMsg_GetArg(&msg, 0); if (DynBuf_GetSize(buf) == sizeof(show)) { memcpy(&show, (const char *)DynBuf_Get(buf), sizeof(show)); } else { break; } buf = DnDMsg_GetArg(&msg, 1); if (DynBuf_GetSize(buf) == sizeof(unityWndId)) { memcpy(&unityWndId, (const char *)DynBuf_Get(buf), sizeof(unityWndId)); } else { break; } updateUnityDetWndChanged.emit(1, show, unityWndId); break; } case DND_GH_QUERY_PENDING_DRAG: { int32 x = 0; int32 y = 0; buf = DnDMsg_GetArg(&msg, 0); if (DynBuf_GetSize(buf) == sizeof(int32)) { memcpy(&x, (const char *)DynBuf_Get(buf), sizeof(int32)); } else { break; } buf = DnDMsg_GetArg(&msg, 1); if (DynBuf_GetSize(buf) == sizeof(int32)) { memcpy(&y, (const char *)DynBuf_Get(buf), sizeof(int32)); } else { break; } queryExitingChanged.emit(1, x, y); break; } case DND_UPDATE_MOUSE: { int32 x = 0; int32 y = 0; buf = DnDMsg_GetArg(&msg, 0); if (DynBuf_GetSize(buf) == sizeof(x)) { memcpy(&x, (const char *)DynBuf_Get(buf), sizeof(x)); } else { break; } buf = DnDMsg_GetArg(&msg, 1); if (DynBuf_GetSize(buf) == sizeof(y)) { memcpy(&y, (const char *)DynBuf_Get(buf), sizeof(y)); } else { break; } moveMouseChanged.emit(1, x, y); break; } case DND_HG_FILE_COPY_DONE: { bool success; buf = DnDMsg_GetArg(&msg, 0); if (DynBuf_GetSize(buf) == sizeof(success)) { memcpy(&success, (const char *)DynBuf_Get(buf), sizeof(success)); } else { break; } buf = DnDMsg_GetArg(&msg, 1); getFilesDoneChanged.emit(1, success, (const uint8 *)DynBuf_Get(buf), DynBuf_GetSize(buf)); break; } default: Debug("%s: got unsupported new command %d.\n", __FUNCTION__, DnDMsg_GetCmd(&msg)); } exit: DnDMsg_Destroy(&msg); } /** * Callback from transport layer after received a packet from srcId. * * @param[in] srcId addressId where the packet is from * @param[in] packet * @param[in] packetSize */ void DnDRpcV3::OnRecvPacket(uint32 srcId, const uint8 *packet, size_t packetSize) { Debug("%s: entering.\n", __FUNCTION__); mUtil.OnRecvPacket(srcId, packet, packetSize); } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/dndCPTransportGuestRpc.hpp0000644765153500003110000000502112220061556026701 0ustar dtormts/* ************************************************************************** * Copyright (C) 2010 VMware, Inc. All Rights Reserved -- VMware Confidential * **************************************************************************/ /** * @dndCPTransportGuestRpc.hpp -- * * GuestRpc implementation of the dndCPTransport interface. Both vmx and guest * tools use this class for DnD version 4. */ #ifndef DND_CP_TRANSPORT_GUEST_RPC_HPP #define DND_CP_TRANSPORT_GUEST_RPC_HPP #include "dndCPTransport.h" extern "C" { #include "dnd.h" #ifdef VMX86_TOOLS #include "vmware/tools/guestrpc.h" #else #include "guest_rpc.h" #endif } #define GUEST_RPC_CMD_STR_DND "dnd.transport" #define GUEST_RPC_CMD_STR_CP "copypaste.transport" #define GUEST_RPC_DND_DISABLE "dndDisable" #define GUEST_RPC_CP_DISABLE "copyDisable" class DnDCPTransportGuestRpc; typedef struct GuestRpcCBCtx { DnDCPTransportGuestRpc *transport; TransportInterfaceType type; } GuestRpcCBCtx; class TransportGuestRpcTables { public: TransportGuestRpcTables(void); ~TransportGuestRpcTables(void); RpcBase *GetRpc(TransportInterfaceType type); void SetRpc(TransportInterfaceType type, RpcBase *rpc); #ifndef VMX86_TOOLS GuestRpcCmd GetCmd(TransportInterfaceType type); #endif const char *GetCmdStr(TransportInterfaceType type); const char *GetDisableStr(TransportInterfaceType type); private: RpcBase *mRpcList[TRANSPORT_INTERFACE_MAX]; #ifndef VMX86_TOOLS GuestRpcCmd mCmdTable[TRANSPORT_INTERFACE_MAX]; #endif const char *mCmdStrTable[TRANSPORT_INTERFACE_MAX]; const char *mDisableStrTable[TRANSPORT_INTERFACE_MAX]; }; class DnDCPTransportGuestRpc : public DnDCPTransport { public: #ifdef VMX86_TOOLS DnDCPTransportGuestRpc(RpcChannel *chan); #else DnDCPTransportGuestRpc(void); #endif bool Init(void); virtual bool RegisterRpc(RpcBase *rpc, TransportInterfaceType type); virtual bool UnregisterRpc(TransportInterfaceType type); virtual bool SendPacket(uint32 destId, TransportInterfaceType type, const uint8 *msg, size_t length); void OnRecvPacket(TransportInterfaceType type, const uint8 *packet, size_t packetSize); private: TransportGuestRpcTables mTables; GuestRpcCBCtx mCBCtx[TRANSPORT_INTERFACE_MAX]; #ifdef VMX86_TOOLS RpcChannel *mRpcChannel; RpcChannelCallback mRpcChanCBList[TRANSPORT_INTERFACE_MAX]; #endif }; #endif // DND_CP_TRANSPORT_GUEST_RPC_HPP open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/guestDnDSrc.cc0000644765153500003110000001764112220061556024315 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @guestDnDSrc.cc -- * * Implementation of common layer GuestDnDSrc object for guest. */ #include "guestDnD.hh" extern "C" { #include "dndClipboard.h" #include "util.h" #include "debug.h" #include "file.h" #include "cpNameUtil.h" #include "str.h" } /** * Constructor. * * @param[in] mgr guest DnD manager */ GuestDnDSrc::GuestDnDSrc(GuestDnDMgr *mgr) : mMgr(mgr) { ASSERT(mMgr); mMgr->GetRpc()->srcDropChanged.connect( sigc::mem_fun(this, &GuestDnDSrc::OnRpcDrop)); mMgr->GetRpc()->srcCancelChanged.connect( sigc::mem_fun(this, &GuestDnDSrc::OnRpcCancel)); mMgr->GetRpc()->getFilesDoneChanged.connect( sigc::mem_fun(this, &GuestDnDSrc::OnRpcGetFilesDone)); CPClipboard_Init(&mClipboard); } /** * Destructor. */ GuestDnDSrc::~GuestDnDSrc(void) { ASSERT(mMgr); CPClipboard_Destroy(&mClipboard); /* Reset current session id after finished. */ mMgr->SetSessionId(0); } /** * Rpc got dragBegin with valid data. Ask UI to show the detection window and * start host->guest DnD inside guest. * * @param[in] clip cross-platform clipboard data. */ void GuestDnDSrc::OnRpcDragBegin(const CPClipboard *clip) { ASSERT(mMgr); ASSERT(clip); Debug("%s: state is %d\n", __FUNCTION__, mMgr->GetState()); /* Setup staging directory. */ mStagingDir = SetupDestDir(""); if (mStagingDir.empty()) { Debug("%s: SetupDestDir failed.\n", __FUNCTION__); return; } /* Show detection window in (0, 0). */ mMgr->ShowDetWnd(0, 0); CPClipboard_Clear(&mClipboard); CPClipboard_Copy(&mClipboard, clip); mMgr->SetState(GUEST_DND_SRC_DRAGBEGIN_PENDING); Debug("%s: state changed to DRAGBEGIN_PENDING\n", __FUNCTION__); mMgr->srcDragBeginChanged.emit(&mClipboard, mStagingDir); } /** * Guest UI got dragBeginDone. Send dragBeginDone cmd to controller. */ void GuestDnDSrc::UIDragBeginDone(void) { ASSERT(mMgr); Debug("%s: state is %d\n", __FUNCTION__, mMgr->GetState()); if (mMgr->GetState() != GUEST_DND_SRC_DRAGBEGIN_PENDING) { /* Reset DnD for any wrong state. */ Debug("%s: Bad state: %d\n", __FUNCTION__, mMgr->GetState()); goto error; } if (!mMgr->GetRpc()->SrcDragBeginDone(mMgr->GetSessionId())) { Debug("%s: SrcDragBeginDone failed\n", __FUNCTION__); goto error; } mMgr->SetState(GUEST_DND_SRC_DRAGGING); Debug("%s: state changed to DRAGGING\n", __FUNCTION__); return; error: mMgr->ResetDnD(); } /** * Guest UI got DnD feedback. Send updateFeedback cmd to controller. * * @param[in] feedback */ void GuestDnDSrc::UIUpdateFeedback(DND_DROPEFFECT feedback) { ASSERT(mMgr); Debug("%s: state is %d\n", __FUNCTION__, mMgr->GetState()); /* This operation needs a valid session id from controller. */ if (0 == mMgr->GetSessionId()) { Debug("%s: can not get a valid session id from controller.\n", __FUNCTION__); return; } if (!mMgr->GetRpc()->UpdateFeedback(mMgr->GetSessionId(), feedback)) { Debug("%s: UpdateFeedback failed\n", __FUNCTION__); mMgr->ResetDnD(); } } /** * Got drop cmd from rpc. Ask UI to simulate the drop at (x, y). * * @param[in] sessionId active DnD session id * @param[in] x mouse position x. * @param[in] y mouse position y. */ void GuestDnDSrc::OnRpcDrop(uint32 sessionId, int32 x, int32 y) { char cpName[FILE_MAXPATH]; int32 cpNameSize; ASSERT(mMgr); Debug("%s: state is %d\n", __FUNCTION__, mMgr->GetState()); if (mMgr->GetState() != GUEST_DND_SRC_DRAGGING) { /* Reset DnD for any wrong state. */ Debug("%s: Bad state: %d\n", __FUNCTION__, mMgr->GetState()); goto error; } mMgr->srcDropChanged.emit(); if (CPClipboard_ItemExists(&mClipboard, CPFORMAT_FILELIST)) { /* Convert staging name to CP format. */ cpNameSize = CPNameUtil_ConvertToRoot(mStagingDir.c_str(), sizeof cpName, cpName); if (cpNameSize < 0) { Debug("%s: Error, could not convert to CPName.\n", __FUNCTION__); goto error; } if (!mMgr->GetRpc()->SrcDropDone(sessionId, (const uint8 *)cpName, cpNameSize)) { Debug("%s: SrcDropDone failed\n", __FUNCTION__); goto error; } } else { /* For non-file formats, the DnD is done. Hide detection window. */ mMgr->HideDetWnd(); mMgr->SetState(GUEST_DND_READY); Debug("%s: state changed to READY\n", __FUNCTION__); } return; error: mMgr->ResetDnD(); } /** * Got cancel cmd from rpc. Ask UI to cancel the DnD as source. * * @param[in] sessionId active DnD session id */ void GuestDnDSrc::OnRpcCancel(uint32 sessionId) { ASSERT(mMgr); Debug("%s: state is %d\n", __FUNCTION__, mMgr->GetState()); mMgr->srcCancelChanged.emit(); mMgr->DelayHideDetWnd(); mMgr->SetState(GUEST_DND_READY); Debug("%s: state changed to READY\n", __FUNCTION__); } /** * Got getFileDone cmd from rpc. Reset state machine and hide detection window. * * @param[in] sessionId active DnD session id * @param[in] success if the file transfer is successful or not * @param[in] stagingCP staging dir name in cross-platform format * @param[in] sz the staging dir name size */ void GuestDnDSrc::OnRpcGetFilesDone(uint32 sessionId, bool success, const uint8 *stagingDirCP, uint32 sz) { if (!success && !mStagingDir.empty()) { /* Delete all files if host canceled the file transfer. */ DnD_DeleteStagingFiles(mStagingDir.c_str(), FALSE); mStagingDir.clear(); } /* UI should remove block with this signal. */ mMgr->getFilesDoneChanged.emit(success); mMgr->HideDetWnd(); mMgr->SetState(GUEST_DND_READY); Debug("%s: state changed to READY\n", __FUNCTION__); } /** * Creates a directory for file transfer. If the destination dir is provided, * we will attempt to copy files to that directory. * * @param[in] destDir the preferred destination directory * * @return the destination directory on success, an empty string on failure. */ const std::string & GuestDnDSrc::SetupDestDir(const std::string &destDir) { mStagingDir = ""; if (!destDir.empty() && File_Exists(destDir.c_str())) { mStagingDir = destDir; const char *lastSep = Str_Strrchr(mStagingDir.c_str(), DIRSEPC); if (lastSep && lastSep[1] != '\0') { mStagingDir += DIRSEPS; } return mStagingDir; } else { char *newDir; newDir = DnD_CreateStagingDirectory(); if (newDir != NULL) { mStagingDir = newDir; char *lastSep = Str_Strrchr(newDir, DIRSEPC); if (lastSep && lastSep[1] != '\0') { mStagingDir += DIRSEPS; } free(newDir); Debug("%s: destdir: %s", __FUNCTION__, mStagingDir.c_str()); return mStagingDir; } else { Debug("%s: destdir not created", __FUNCTION__); return mStagingDir; } } } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/guestCopyPasteSrc.cc0000644765153500003110000001306112220061556025547 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @guestCopyPasteSrc.cc -- * * Implementation of common layer GuestCopyPasteSrc object for guest. */ #include "guestCopyPaste.hh" extern "C" { #include "dndClipboard.h" #include "debug.h" #include "file.h" #include "cpNameUtil.h" #include "util.h" #include "str.h" } /** * Constructor. * * @param[in] mgr guest CP manager */ GuestCopyPasteSrc::GuestCopyPasteSrc(GuestCopyPasteMgr *mgr) : mMgr(mgr) { ASSERT(mMgr); mMgr->GetRpc()->getFilesDoneChanged.connect( sigc::mem_fun(this, &GuestCopyPasteSrc::OnRpcGetFilesDone)); CPClipboard_Init(&mClipboard); } /** * Destructor. */ GuestCopyPasteSrc::~GuestCopyPasteSrc(void) { ASSERT(mMgr); CPClipboard_Destroy(&mClipboard); /* Reset current session id after finished. */ mMgr->SetSessionId(0); } /** * Got valid clipboard data from host. Emit srcRecvClipChanged signal if state * machine is right. * * @param[in] isActive active or passive CopyPaste. * @param[in] clip cross-platform clipboard data. */ void GuestCopyPasteSrc::OnRpcRecvClip(bool isActive, const CPClipboard *clip) { ASSERT(mMgr); ASSERT(clip); Debug("%s: state is %d\n", __FUNCTION__, mMgr->GetState()); CPClipboard_Clear(&mClipboard); CPClipboard_Copy(&mClipboard, clip); mMgr->srcRecvClipChanged.emit(clip); } /** * UI is asking for files. Send requestFiles cmd to controller. * * @param[in] dir staging directory in local format. * * @return The staging directory if succeed, otherwise empty string. */ const std::string GuestCopyPasteSrc::UIRequestFiles(const std::string &dir) { std::string destDir; char cpName[FILE_MAXPATH]; int32 cpNameSize; if (mMgr->GetState() != GUEST_CP_READY) { /* Reset DnD for any wrong state. */ Debug("%s: Bad state: %d\n", __FUNCTION__, mMgr->GetState()); goto error; } /* Setup staging directory. */ destDir = SetupDestDir(dir); if (destDir.empty()) { goto error; } /* Convert staging name to CP format. */ cpNameSize = CPNameUtil_ConvertToRoot(destDir.c_str(), sizeof cpName, cpName); if (cpNameSize < 0) { Debug("%s: Error, could not convert to CPName.\n", __FUNCTION__); goto error; } if (!mMgr->GetRpc()->RequestFiles(mMgr->GetSessionId(), (const uint8 *)cpName, cpNameSize)) { goto error; } mStagingDir = destDir; mMgr->SetState(GUEST_CP_HG_FILE_COPYING); Debug("%s: state changed to GUEST_CP_HG_FILE_COPYING\n", __FUNCTION__); return destDir; error: mMgr->ResetCopyPaste(); return ""; } /** * The file transfer is finished. Emit getFilesDoneChanged signal and reset * local state. * * @param[in] sessionId active DnD session id * @param[in] success if the file transfer is successful or not * @param[in] stagingDirCP staging dir name in cross-platform format * @param[in] sz the staging dir name size */ void GuestCopyPasteSrc::OnRpcGetFilesDone(uint32 sessionId, bool success, const uint8 *stagingDirCP, uint32 sz) { if (!success && !mStagingDir.empty()) { /* Delete all files if host canceled the file transfer. */ DnD_DeleteStagingFiles(mStagingDir.c_str(), FALSE); mStagingDir.clear(); } /* UI should remove block with this signal. */ mMgr->getFilesDoneChanged.emit(success); mMgr->SetState(GUEST_CP_READY); Debug("%s: state changed to READY\n", __FUNCTION__); } /** * Creates a directory for file transfer. If the destination dir is provided, * we will attempt to copy files to that directory. * * @param[in] destDir the preferred destination directory * * @return the destination directory on success, an empty string on failure. */ const std::string & GuestCopyPasteSrc::SetupDestDir(const std::string &destDir) { mStagingDir = ""; if (!destDir.empty() && File_Exists(destDir.c_str())) { mStagingDir = destDir; const char *lastSep = Str_Strrchr(mStagingDir.c_str(), DIRSEPC); if (lastSep && lastSep[1] != '\0') { mStagingDir += DIRSEPS; } } else { char *newDir; newDir = DnD_CreateStagingDirectory(); if (newDir != NULL) { mStagingDir = newDir; char *lastSep = Str_Strrchr(newDir, DIRSEPC); if (lastSep && lastSep[1] != '\0') { mStagingDir += DIRSEPS; } free(newDir); Debug("%s: destdir: %s", __FUNCTION__, mStagingDir.c_str()); } else { Debug("%s: destdir not created", __FUNCTION__); } } return mStagingDir; } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/guestCopyPasteMgr.cc0000644765153500003110000001475412220061556025557 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @guestCopyPasteMgr.cc -- * * Implementation of common layer GuestCopyPasteMgr object for guest. */ #include "guestCopyPaste.hh" #include "copyPasteRpcV3.hh" #include "copyPasteRpcV4.hh" #include "guestDnDCPMgr.hh" extern "C" { #include "debug.h" } /** * Constructor. * * @param[in] transport for sending/receiving packets. */ GuestCopyPasteMgr::GuestCopyPasteMgr(DnDCPTransport *transport) : mSrc(NULL), mDest(NULL), mRpc(NULL), mCPState(GUEST_CP_READY), mTransport(transport), mSessionId(0), mCopyPasteAllowed(false), mResolvedCaps(0xffffffff) { ASSERT(transport); } /** * Destructor. */ GuestCopyPasteMgr::~GuestCopyPasteMgr(void) { delete mRpc; mRpc = NULL; } /** * Reset state machine and session id. Delete mSrc and mDest. */ void GuestCopyPasteMgr::ResetCopyPaste(void) { Debug("%s: state %d, session id %d before reset\n", __FUNCTION__, mCPState, mSessionId); if (mSrc) { delete mSrc; mSrc = NULL; } if (mDest) { delete mDest; mDest = NULL; } SetState(GUEST_CP_READY); SetSessionId(0); Debug("%s: change to state %d, session id %d\n", __FUNCTION__, mCPState, mSessionId); } /** * Got valid clipboard data from host. Create mSrc if the state machine * is ready. * * @param[in] sessionId active session id * @param[in] isActive active or passive CopyPaste. * @param[in] clip cross-platform clipboard data. */ void GuestCopyPasteMgr::OnRpcSrcRecvClip(uint32 sessionId, bool isActive, const CPClipboard *clip) { ASSERT(clip); Debug("%s: enter\n", __FUNCTION__); if (!mCopyPasteAllowed) { Debug("%s: CopyPaste is not allowed.\n", __FUNCTION__); return; } if (GUEST_CP_READY != mCPState) { Debug("%s: Bad state: %d, reset\n", __FUNCTION__, mCPState); /* XXX Should reset DnD here. */ return; } if (mSrc) { Debug("%s: mSrc is not NULL\n", __FUNCTION__); delete mSrc; mSrc = NULL; } mSessionId = sessionId; Debug("%s: change sessionId to %d\n", __FUNCTION__, mSessionId); mSrc = new GuestCopyPasteSrc(this); mSrc->OnRpcRecvClip(isActive, clip); } /** * Wrapper for mSrc->UIRequestFiles. * * @param[in] dir staging directory in local format. * * @return The staging directory if succeed, otherwise empty string. */ const std::string GuestCopyPasteMgr::SrcUIRequestFiles(const std::string &dir) { if (mSrc) { return mSrc->UIRequestFiles(dir); } else { Debug("%s: mSrc is NULL\n", __FUNCTION__); return std::string(""); } } /** * Host is asking for clipboard data. Create mDest if the state machine * is ready. * * @param[in] sessionId active session id * @param[in] isActive active or passive CopyPaste. */ void GuestCopyPasteMgr::OnRpcDestRequestClip(uint32 sessionId, bool isActive) { Debug("%s: enter\n", __FUNCTION__); if (!mCopyPasteAllowed) { Debug("%s: CopyPaste is not allowed.\n", __FUNCTION__); return; } if (GUEST_CP_READY != mCPState) { Debug("%s: Bad state: %d, reset\n", __FUNCTION__, mCPState); /* XXX Should reset CP here. */ return; } if (mDest) { Debug("%s: mDest is not NULL\n", __FUNCTION__); delete mDest; mDest = NULL; } mSessionId = sessionId; Debug("%s: change sessionId to %d\n", __FUNCTION__, mSessionId); mDest = new GuestCopyPasteDest(this); mDest->OnRpcRequestClip(isActive); } /** * Wrapper for mDest->UISendClip. * * @param[in] clip cross-platform clipboard data. */ void GuestCopyPasteMgr::DestUISendClip(const CPClipboard *clip) { if (mDest) { mDest->UISendClip(clip); } else { Debug("%s: mDest is NULL\n", __FUNCTION__); } } /** * Handle version change in VMX. * * @param[in] version negotiated CP version. */ void GuestCopyPasteMgr::VmxCopyPasteVersionChanged(uint32 version) { Debug("GuestCopyPasteMgr::%s: enter version %d\n", __FUNCTION__, version); ASSERT(version >= 3); ASSERT(mTransport); if (mRpc) { delete mRpc; } switch(version) { case 4: mRpc = new CopyPasteRpcV4(mTransport); break; case 3: mRpc = new CopyPasteRpcV3(mTransport); break; default: g_debug("%s: unsupported CP version\n", __FUNCTION__); break; } if (mRpc) { Debug("GuestCopyPasteMgr::%s: register ping reply changed %d\n", __FUNCTION__, version); mRpc->pingReplyChanged.connect( sigc::mem_fun(this, &GuestCopyPasteMgr::OnPingReply)); mRpc->srcRecvClipChanged.connect( sigc::mem_fun(this, &GuestCopyPasteMgr::OnRpcSrcRecvClip)); mRpc->destRequestClipChanged.connect( sigc::mem_fun(this, &GuestCopyPasteMgr::OnRpcDestRequestClip)); mRpc->Init(); mRpc->SendPing(GuestDnDCPMgr::GetInstance()->GetCaps() & (DND_CP_CAP_CP | DND_CP_CAP_FORMATS_CP | DND_CP_CAP_VALID)); } ResetCopyPaste(); } /** * Check if a request is allowed based on resolved capabilities. * * @param[in] capsRequest requested capabilities. * * @return TRUE if allowed, FALSE otherwise. */ Bool GuestCopyPasteMgr::CheckCapability(uint32 capsRequest) { Bool allowed = FALSE; if ((mResolvedCaps & capsRequest) == capsRequest) { allowed = TRUE; } return allowed; } /** * Got pingReplyChanged message. Update capabilities. * * @param[in] capability modified capabilities from VMX controller. */ void GuestCopyPasteMgr::OnPingReply(uint32 capabilities) { Debug("%s: copypaste ping reply caps are %x\n", __FUNCTION__, capabilities); mResolvedCaps = capabilities; } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/dndFileList.cc0000644765153500003110000003773412220061556024336 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * dndFileList.cc * * Handles filelists for CPClipboard. * Relative paths are read/write to allow placing data on the clipboard, * but full paths are write only. Full path parsing depends on g->h/h->g * as well as dnd/fcp versions. Given that the host ui never needs to * parse it, full paths are only stored in binary format for consumption * by the vmx. * * Local relative paths are expected to be encoded in Normalized UTF8 in * local format. * * XXX This file is almost identical to bora/apps/lib/cui/dndFileList.cc * but right now we can not find a way to share the file. */ #if defined (_WIN32) /* * When compile this file for Windows dnd plugin dll, there may be a conflict * between CRT and MFC libraries. From * http://support.microsoft.com/default.aspx?scid=kb;en-us;q148652: The CRT * libraries use weak external linkage for the DllMain function. The MFC * libraries also contain this function. The function requires the MFC * libraries to be linked before the CRT library. The Afx.h include file * forces the correct order of the libraries. */ #include #endif #include "dndFileList.hh" extern "C" { #include "dndClipboard.h" #include "vm_assert.h" #include "file.h" #include "cpNameUtil.h" } /* *---------------------------------------------------------------------------- * * DnDFileList -- * * Constructor. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ DnDFileList::DnDFileList() { mFileSize = 0; } /* *---------------------------------------------------------------------------- * * DnDFileList::SetFileSize -- * * Sets the expected size of the files. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void DnDFileList::SetFileSize(uint64 fsize) // IN: The size of the files. { mFileSize = fsize; } /* *---------------------------------------------------------------------------- * * DnDFileList::GetFileSize -- * * Gets the size of the files if known. * * Results: * 0 if the size of the files is not known, otherwise the expected size of * the files. * * Side effects: * None. * *---------------------------------------------------------------------------- */ uint64 DnDFileList::GetFileSize() const { return mFileSize; } /* *---------------------------------------------------------------------------- * * DnDFileList::AddFile -- * * Add the full path and the relative path to the file list. Both strings * should be normalized UTF8. * Will not add file if the file list was created from a clipboard buffer. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void DnDFileList::AddFile(const std::string fullPath, // IN: filename const std::string relPath) // IN: filename { ASSERT(mFullPathsBinary.empty()); if (!mFullPathsBinary.empty()) { return; } mRelPaths.push_back(relPath); mFullPaths.push_back(fullPath); } /* *---------------------------------------------------------------------------- * * DnDFileList::AddFileUri -- * * Add the full uri UTF8 path the file list. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void DnDFileList::AddFileUri(const std::string uriPath) // IN { mUriPaths.push_back(uriPath); } /* *---------------------------------------------------------------------------- * * DnDFileList::AddFiles -- * * Add the full path list and the relative path list. Both lists should be * normalized UTF8. * * Will not add lists if the file list was created from a clipboard buffer. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void DnDFileList::AddFiles(const std::vector fullPathList, // IN: filenames const std::vector relPathList) // IN: filenames { ASSERT(mFullPathsBinary.empty()); if (!mFullPathsBinary.empty()) { return; } mRelPaths = relPathList; mFullPaths = fullPathList; } /* *---------------------------------------------------------------------------- * * DnDFileList::AddFileAttributes -- * * Adds files attributes. * * Will not add attributes if the file list was created from a clipboard * buffer. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void DnDFileList::AddFileAttributes(const CPFileAttributes& attributes) // IN { ASSERT(mFullPathsBinary.empty()); if (!mFullPathsBinary.empty()) { return; } mAttributeList.push_back(attributes); } /* *---------------------------------------------------------------------------- * * DnDFileList::SetRelPathsStr -- * * Set the relative paths based on the serialized input string. Paths are * in normalized utf-8 with local path separators. Exposed for dnd/cp * version 2. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void DnDFileList::SetRelPathsStr(const std::string inpath) // IN: { std::string::size_type mPos = 0; std::string curFile; std::string path; const char* cpath; if (inpath.empty()) { return; } if (inpath[inpath.size()-1] != '\0') { path = inpath + '\0'; } else { path = inpath; } cpath = path.c_str(); mRelPaths.clear(); curFile = cpath; mPos = path.find('\0', mPos); while (mPos != std::string::npos) { mPos++; mRelPaths.push_back(curFile); curFile = cpath + mPos; mPos = path.find('\0', mPos); } } /* *---------------------------------------------------------------------------- * * DnDFileList::GetRelPaths -- * * Gets a vector containing the reletive paths of the files. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ std::vector DnDFileList::GetRelPaths() const { return mRelPaths; } /* *---------------------------------------------------------------------------- * * DnDFileList::GetFileAttributes -- * * Gets a vector containing file attributes. * * Results: * File attributes. * * Side effects: * None. * *---------------------------------------------------------------------------- */ std::vector DnDFileList::GetFileAttributes() const { return mAttributeList; } /* *---------------------------------------------------------------------------- * * DnDFileList::GetFullPathsStr -- * * Gets the serialized version of the full paths. If the file list was * created from a CPClipboard, use the serialized input instead. * * Local paths are serialized inot NUL separated pathes. * CPName paths are converted from local to CPName and serialized into * uint32,cpname pairs. * * Results: * An std::string containing the serialized full paths. Empty string on * error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ std::string DnDFileList::GetFullPathsStr(bool local) // IN: Use local format const { std::string stringList; std::vector::const_iterator i; if (mFullPathsBinary.empty() && !mFullPaths.empty()) { for (i = mFullPaths.begin(); i != mFullPaths.end(); ++i) { if (local) { stringList.append(i->c_str()); stringList.push_back('\0'); } else { char outPath[FILE_MAXPATH + 100]; int32 outPathLen; outPathLen = CPNameUtil_ConvertToRoot(i->c_str(), sizeof outPath, outPath); if (outPathLen < 0) { continue; } stringList.append(reinterpret_cast(&outPathLen), sizeof outPathLen); stringList.append(outPath, outPathLen); } } return stringList; } else if (!mFullPathsBinary.empty() && mFullPaths.empty()) { return mFullPathsBinary; } else { return ""; } } /* *---------------------------------------------------------------------------- * * DnDFileList::GetRelPathsStr -- * * Gets the serialized version of the relative paths. Primarily used for * dnd/cp v2. * * Results: * An std::string contatin the serialized full paths. * * Side effects: * None. * *---------------------------------------------------------------------------- */ std::string DnDFileList::GetRelPathsStr() const { std::string stringList(""); std::vector::const_iterator i; for (i = mRelPaths.begin(); i != mRelPaths.end(); ++i) { stringList.append(i->c_str()); stringList.push_back('\0'); } return stringList; } /* *---------------------------------------------------------------------------- * * DnDFileList::GetUriPathsStr -- * * Gets the serialized version of the uri paths. * * Results: * An std::string contatin the serialized uri paths. * * Side effects: * None. * *---------------------------------------------------------------------------- */ std::string DnDFileList::GetUriPathsStr(void) const { std::string stringList; std::vector::const_iterator i; for (i = mUriPaths.begin(); i != mUriPaths.end(); i++) { stringList.append(i->c_str()); stringList.push_back('\0'); } return stringList; } /* *---------------------------------------------------------------------------- * * DnDFileList::FromCPClipboard -- * * Loads the filelist from a buffer, typically from CPClipboard. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ bool DnDFileList::FromCPClipboard(const void *buf, // IN: Source buffer size_t len) // IN: Buffer length { const CPFileList *flist; std::string relPaths; ASSERT(buf); ASSERT(len); if (!buf || !len) { return false; } flist = reinterpret_cast(buf); relPaths.assign( reinterpret_cast(flist->filelists), flist->relPathsLen); mRelPaths.clear(); mFullPaths.clear(); mFileSize = flist->fileSize; SetRelPathsStr(relPaths); mFullPathsBinary.assign( reinterpret_cast(flist->filelists + flist->relPathsLen), flist->fulPathsLen); return true; } /* *---------------------------------------------------------------------------- * * DnDFileList::AttributesFromCPClipboard -- * * Loads the attribute list from a buffer, typically from CPClipboard. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ bool DnDFileList::AttributesFromCPClipboard(const void *buf, // IN: Source buffer size_t len) // IN: Buffer length { const CPAttributeList *alist; ASSERT(buf); ASSERT(len); if (!buf || !len) { return false; } alist = reinterpret_cast(buf); mAttributeList.resize(alist->attributesLen); for (uint32 i = 0; i < alist->attributesLen; i++) { mAttributeList[i] = alist->attributeList[i]; } return true; } /* *---------------------------------------------------------------------------- * * DnDFileList::ToCPClipboard -- * * Serializes contents for CPClipboard in eithr CPFormat or local format. * * Results: * false on error, true on success. * * Side effects: * None. * *---------------------------------------------------------------------------- */ bool DnDFileList::ToCPClipboard(DynBuf *out, // OUT: Initialized output buffer bool local) // IN: Use local format const { std::string strListRel; std::string strListFul; CPFileList header; strListRel = GetRelPathsStr(); strListFul = GetFullPathsStr(local); if (!out) { return false; } /* Check if the size is too big. */ if (strListRel.size() > MAX_UINT32 || strListFul.size() > MAX_UINT32) { return false; } header.fileSize = mFileSize; header.relPathsLen = strListRel.size(); header.fulPathsLen = strListFul.size(); DynBuf_Append(out, &header, CPFILELIST_HEADER_SIZE); DynBuf_Append(out, strListRel.c_str(), header.relPathsLen); DynBuf_Append(out, strListFul.c_str(), header.fulPathsLen); return true; } /* *---------------------------------------------------------------------------- * * DnDFileList::ToCPClipboard -- * * Serializes uri paths for CPClipboard in URI Format. * * Results: * false on error, true on success. * * Side effects: * None. * *---------------------------------------------------------------------------- */ bool DnDFileList::ToUriClipboard(DynBuf *out) // OUT: Initialized output buffer const { std::string strListUri; UriFileList header; if (!out) { return false; } strListUri = GetUriPathsStr(); /* Check if the size is too big. */ if (strListUri.size() > MAX_UINT32) { return false; } header.fileSize = mFileSize; header.uriPathsLen = strListUri.size(); DynBuf_Append(out, &header, URI_FILELIST_HEADER_SIZE); DynBuf_Append(out, strListUri.c_str(), header.uriPathsLen); return true; } /* *---------------------------------------------------------------------------- * * DnDFileList::AttributesToCPClipboard -- * * Serializes attributes for CPClipboard in Attributes Format. * * Results: * false on error, true on success. * * Side effects: * None. * *---------------------------------------------------------------------------- */ bool DnDFileList::AttributesToCPClipboard(DynBuf *out) // IN const { CPAttributeList header; if (!out) { return false; } header.attributesLen = mAttributeList.size(); DynBuf_Append(out, &header, URI_ATTRIBUTES_LIST_HEADER_SIZE); if (header.attributesLen > 0) { DynBuf_Append(out, &mAttributeList[0], header.attributesLen * sizeof(CPFileAttributes)); } return true; } /* *---------------------------------------------------------------------------- * * DnDFileList::Clear -- * * Clears the contents of the filelist. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void DnDFileList::Clear() { mRelPaths.clear(); mFullPaths.clear(); mUriPaths.clear(); mAttributeList.clear(); mFullPathsBinary.clear(); mFileSize = 0; } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/rpcV3Util.cpp0000644765153500003110000002340012220061556024146 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @rpcV3Util.cpp -- * * Implementation of common utility object for DnD/CP version 3 rpc object. * It is shared by vmx and guest implementation. Some common utilities * including * *packet marshalling/un-marshalling * *big buffer support * are implemented here. */ #include "rpcV3Util.hpp" extern "C" { #ifdef VMX86_TOOLS #include "debug.h" #define LOG(level, msg) (Debug msg) #else #define LOGLEVEL_MODULE dnd #include "loglevel_user.h" #endif #include "dndClipboard.h" #include "util.h" #include "dndMsg.h" #include "hostinfo.h" } /** * Constructor. */ RpcV3Util::RpcV3Util(void) : mVersionMajor(3), mVersionMinor(0), mSeqNum(1) { mSendBuf.buffer = NULL; mRecvBuf.buffer = NULL; DnD_TransportBufReset(&mSendBuf); DnD_TransportBufReset(&mRecvBuf); } /** * Destructor. */ RpcV3Util::~RpcV3Util(void) { free(mSendBuf.buffer); free(mRecvBuf.buffer); } /** * Initialize the RpcV3Util object. All owner should call this first before * calling any other utility function. * * @param[in] rpc the owner of this utility object * @param[in] msgType the type of message (DnD/CP/FT) * @param[in] msgSrc source of the message (host/guest/controller) */ void RpcV3Util::Init(RpcBase *rpc) { ASSERT(rpc); mRpc = rpc; } /** * Serialize command, then send the message. * * @param[in] cmd version 3 command * * @return true on success, false otherwise. */ bool RpcV3Util::SendMsg(uint32 cmd) { DnDMsg msg; bool ret = false; DnDMsg_Init(&msg); DnDMsg_SetCmd(&msg, cmd); ret = SendMsg(&msg); DnDMsg_Destroy(&msg); return ret; } /** * Serialize the clipboard item if there is one, then send the message to * destId. * * @param[in] cmd version 3 command * @param[in] clip the clipboard item. * * @return true on success, false otherwise. */ bool RpcV3Util::SendMsg(uint32 cmd, const CPClipboard *clip) { DnDMsg msg; DynBuf buf; bool ret = false; DnDMsg_Init(&msg); DynBuf_Init(&buf); /* Serialize clip and output into buf. */ if (!CPClipboard_Serialize(clip, &buf)) { LOG(0, ("%s: CPClipboard_Serialize failed.\n", __FUNCTION__)); goto exit; } /* Construct msg with both cmd CP_HG_SET_CLIPBOARD and buf. */ DnDMsg_SetCmd(&msg, cmd); if (!DnDMsg_AppendArg(&msg, DynBuf_Get(&buf), DynBuf_GetSize(&buf))) { LOG(0, ("%s: DnDMsg_AppendData failed.\n", __FUNCTION__)); goto exit; } ret = SendMsg(&msg); exit: DynBuf_Destroy(&buf); DnDMsg_Destroy(&msg); return ret; } /** * Serialize command with mouse position, and send the message. * * @param[in] cmd version 3 command * @param[in] x mouse position x. * @param[in] y mouse position y. * * @return true on success, false otherwise. */ bool RpcV3Util::SendMsg(uint32 cmd, int32 x, int32 y) { bool ret = false; DnDMsg msg; DnDMsg_Init(&msg); DnDMsg_SetCmd(&msg, cmd); if (!DnDMsg_AppendArg(&msg, &x, sizeof x) || !DnDMsg_AppendArg(&msg, &y, sizeof y)) { LOG(0, ("%s: DnDMsg_AppendData failed.\n", __FUNCTION__)); goto exit; } ret = SendMsg(&msg); exit: DnDMsg_Destroy(&msg); return ret; } /** * Serialize and send the message. * * @param[in] msg the message to be serialized and sent. * * @return true on success, false otherwise. */ bool RpcV3Util::SendMsg(const DnDMsg *msg) { DynBuf buf; bool ret = false; DynBuf_Init(&buf); /* Serialize msg and output to buf. */ if (!DnDMsg_Serialize((DnDMsg *)msg, &buf)) { LOG(0, ("%s: DnDMsg_Serialize failed.\n", __FUNCTION__)); goto exit; } ret = SendMsg((uint8 *)DynBuf_Get(&buf), DynBuf_GetSize(&buf)); exit: DynBuf_Destroy(&buf); return ret; } /** * Serialize the message and send it to destId. * * @param[in] binary * @param[in] binarySize * * @return true on success, false otherwise. */ bool RpcV3Util::SendMsg(const uint8 *binary, uint32 binarySize) { DnDTransportPacketHeader *packet = NULL; size_t packetSize; bool ret = FALSE; if (binarySize > DNDMSG_MAX_ARGSZ) { LOG(1, ("%s: message is too big, quit.\n", __FUNCTION__)); return false; } LOG(4, ("%s: got message, size %d.\n", __FUNCTION__, binarySize)); if (binarySize <= DND_MAX_TRANSPORT_PACKET_PAYLOAD_SIZE) { /* * It is a small size message, so it is not needed to buffer it. Just * put message into a packet and send it. */ packetSize = DnD_TransportMsgToPacket((uint8 *)binary, binarySize, mSeqNum, &packet); } else { /* * It is a big size message. First buffer it and send it with multiple * packets. */ if (mSendBuf.buffer) { /* * There is a pending big size message. If there is no update time * more than DND_MAX_TRANSPORT_LATENCY_TIME, remove old message and * send new message. Otherwise ignore this message. */ if ((Hostinfo_SystemTimerUS() - mSendBuf.lastUpdateTime) < DND_MAX_TRANSPORT_LATENCY_TIME) { LOG(1, ("%s: got a big buffer, but there is another pending one, drop it\n", __FUNCTION__)); return false; } } DnD_TransportBufInit(&mSendBuf, (uint8 *)binary, binarySize, mSeqNum); packetSize = DnD_TransportBufGetPacket(&mSendBuf, &packet); } /* Increase sequence number for next message. */ mSeqNum++; if (packetSize) { ret = mRpc->SendPacket(0, (const uint8 *)packet, packetSize); } free(packet); return ret; } /** * Callback from transport layer after received a packet from srcId. * * @param[in] srcId addressId where the packet is from * @param[in] packet * @param[in] packetSize */ void RpcV3Util::OnRecvPacket(uint32 srcId, const uint8 *packet, size_t packetSize) { DnDTransportPacketHeader *packetV3 = (DnDTransportPacketHeader *)packet; ASSERT(packetV3); if (packetSize <= 0 || packetSize != (packetV3->payloadSize + DND_TRANSPORT_PACKET_HEADER_SIZE) || packetSize > DND_MAX_TRANSPORT_PACKET_SIZE) { LOG(0, ("%s: Received invalid data.\n", __FUNCTION__)); return; } switch (packetV3->type) { case DND_TRANSPORT_PACKET_TYPE_SINGLE: if (packetV3->payloadSize != packetV3->totalSize) { LOG(0, ("%s: received invalid packet.\n", __FUNCTION__)); return; } /* This is a single packet. Forward to rpc layer for further processing. */ mRpc->HandleMsg(NULL, packetV3->payload, packetV3->payloadSize); break; case DND_TRANSPORT_PACKET_TYPE_REQUEST: { /* Peer is asking for next packet. */ DnDTransportPacketHeader *replyPacket = NULL; size_t replyPacketSize; if (packetV3->payloadSize || packetV3->seqNum != mSendBuf.seqNum || packetV3->offset != mSendBuf.offset) { LOG(0, ("%s: received packet does not match local buffer.\n", __FUNCTION__)); return; } replyPacketSize = DnD_TransportBufGetPacket(&mSendBuf, &replyPacket); if (!replyPacketSize) { /* * Not needed to reset mSendBuf because DnD_TransportBufGetPacket already * did that. */ LOG(0, ("%s: DnD_TransportBufGetPacket failed.\n", __FUNCTION__)); return; } if (!mRpc->SendPacket(0, (const uint8 *)replyPacket, replyPacketSize) || mSendBuf.offset == mSendBuf.totalSize) { /* Reset mSendBuf if whole buffer is sent or there is any error. */ DnD_TransportBufReset(&mSendBuf); } free(replyPacket); break; } case DND_TRANSPORT_PACKET_TYPE_PAYLOAD: /* Received next packet for big binary buffer. */ if (!DnD_TransportBufAppendPacket(&mRecvBuf, packetV3, packetSize)) { LOG(0, ("%s: DnD_TransportBufAppendPacket failed.\n", __FUNCTION__)); return; } if (mRecvBuf.offset == mRecvBuf.totalSize) { /* * Received all packets for the messge, forward it to rpc layer for * further processing. */ mRpc->HandleMsg(NULL, mRecvBuf.buffer, mRecvBuf.totalSize); DnD_TransportBufReset(&mRecvBuf); } else { /* Send request for next packet. */ DnDTransportPacketHeader *replyPacket = NULL; size_t replyPacketSize; replyPacketSize = DnD_TransportReqPacket(&mRecvBuf, &replyPacket); if (!replyPacketSize) { LOG(0, ("%s: DnD_TransportReqPacket failed.\n", __FUNCTION__)); return; } if (!mRpc->SendPacket(0, (const uint8 *)replyPacket, replyPacketSize)) { DnD_TransportBufReset(&mRecvBuf); } free(replyPacket); } break; default: LOG(0, ("%s: unknown packet.\n", __FUNCTION__)); break; } } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/guestDnDCPMgr.hh0000644765153500003110000000406612220061556024545 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @guestDnDCPMgr.hh -- * * Common layer management object for guest DnD/CP. It is a singleton. */ #ifndef GUEST_DND_CP_HH #define GUEST_DND_CP_HH #include "guestDnD.hh" #include "guestCopyPaste.hh" #include "guestFileTransfer.hh" extern "C" { #include "vmware/tools/guestrpc.h" #include "vmware/tools/plugin.h" } struct DblLnkLst_Links; class GuestDnDCPMgr { public: ~GuestDnDCPMgr(); static GuestDnDCPMgr *GetInstance(); static void Destroy(); GuestDnDMgr *GetDnDMgr(void); GuestCopyPasteMgr *GetCopyPasteMgr(void); DnDCPTransport *GetTransport(void); void StartLoop(); void EndLoop(); void IterateLoop(); void Init(ToolsAppCtx *ctx); void SetCaps(uint32 caps) {mLocalCaps = caps;}; uint32 GetCaps() {return mLocalCaps;}; private: /* We're a singleton, so it is a compile time error to call these. */ GuestDnDCPMgr(void); GuestDnDCPMgr(const GuestDnDCPMgr &mgr); GuestDnDCPMgr& operator=(const GuestDnDCPMgr &mgr); static GuestDnDCPMgr *m_instance; GuestDnDMgr *mDnDMgr; GuestCopyPasteMgr *mCPMgr; GuestFileTransfer *mFileTransfer; DnDCPTransport *mTransport; ToolsAppCtx *mToolsAppCtx; uint32 mLocalCaps; }; #endif // GUEST_DND_CP_HH open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/dndRpcV4.cc0000644765153500003110000005115612220061556023553 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @DnDRpcV4.cc -- * * Implementation of the DnDRpcV4 object. */ #include "dndRpcV4.hh" extern "C" { #if defined VMX86_TOOLS #include "debug.h" #define LOG(level, msg) (Debug msg) #else #define LOGLEVEL_MODULE dnd #include "loglevel_user.h" #endif #include "dndClipboard.h" #include "util.h" } /** * Constructor. * * @param[in] transport for sending packets. */ DnDRpcV4::DnDRpcV4(DnDCPTransport *transport) : mTransport(transport), #ifdef VMX86_TOOLS mTransportInterface(TRANSPORT_GUEST_CONTROLLER_DND) #else mTransportInterface(TRANSPORT_HOST_CONTROLLER_DND) #endif { ASSERT(mTransport); #ifdef VMX86_TOOLS mUtil.Init(this, DND_CP_MSG_SRC_GUEST, DND_CP_MSG_TYPE_DND); #else mUtil.Init(this, DND_CP_MSG_SRC_HOST, DND_CP_MSG_TYPE_DND); #endif } /** * Init. */ void DnDRpcV4::Init() { ASSERT(mTransport); mTransport->RegisterRpc(this, mTransportInterface); } /** * Send Ping message to controller. * * @param[in] caps capabilities value. */ void DnDRpcV4::SendPing(uint32 caps) { mUtil.SendPingMsg(DEFAULT_CONNECTION_ID, caps); } /** * Send cmd DND_CMD_SRC_DRAG_BEGIN_DONE to controller. * * @param[in] sessionId active session id the controller assigned earlier. * * @return true on success, false otherwise. */ bool DnDRpcV4::SrcDragBeginDone(uint32 sessionId) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_SRC_DRAG_BEGIN_DONE; params.sessionId = sessionId; params.optional.version.major = 4; params.optional.version.minor = 0; return mUtil.SendMsg(¶ms); } /** * Send cmd DND_CMD_UPDATE_FEEDBACK to controller. * * @param[in] sessionId active session id the controller assigned earlier. * @param[in] feedback current dnd operation feedback. * * @return true on success, false otherwise. */ bool DnDRpcV4::UpdateFeedback(uint32 sessionId, DND_DROPEFFECT feedback) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_UPDATE_FEEDBACK; params.sessionId = sessionId; params.optional.feedback.feedback = feedback; return mUtil.SendMsg(¶ms); } /** * Send cmd DND_CMD_PRIV_DRAG_ENTER to controller. * * @param[in] sessionId active session id the controller assigned earlier. * * @return true on success, false otherwise. */ bool DnDRpcV4::SrcPrivDragEnter(uint32 sessionId) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_PRIV_DRAG_ENTER; params.sessionId = sessionId; return mUtil.SendMsg(¶ms); } /** * Send cmd DND_CMD_PRIV_DRAG_LEAVE to controller. * * @param[in] sessionId active session id the controller assigned earlier. * @param[in] x mouse position x. * @param[in] y mouse position y. * * @return true on success, false otherwise. */ bool DnDRpcV4::SrcPrivDragLeave(uint32 sessionId, int32 x, int32 y) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_PRIV_DRAG_LEAVE; params.sessionId = sessionId; params.optional.mouseInfo.x = x; params.optional.mouseInfo.y = y; return mUtil.SendMsg(¶ms); } /** * Send cmd DND_CMD_PRIV_DROP to controller. * * @param[in] sessionId active session id the controller assigned earlier. * @param[in] x mouse position x. * @param[in] y mouse position y. * * @return true on success, false otherwise. */ bool DnDRpcV4::SrcPrivDrop(uint32 sessionId, int32 x, int32 y) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_PRIV_DROP; params.sessionId = sessionId; params.optional.mouseInfo.x = x; params.optional.mouseInfo.y = y; return mUtil.SendMsg(¶ms); } /** * Send cmd DND_CMD_SRC_DROP to controller. * * @param[in] sessionId active session id the controller assigned earlier. * @param[in] x mouse position x. * @param[in] y mouse position y. * * @return true on success, false otherwise. */ bool DnDRpcV4::SrcDrop(uint32 sessionId, int32 x, int32 y) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_SRC_DROP; params.sessionId = sessionId; params.optional.mouseInfo.x = x; params.optional.mouseInfo.y = y; return mUtil.SendMsg(¶ms); } /** * Send cmd DND_CMD_SRC_DROP_DONE to controller. * * @param[in] sessionId active session id the controller assigned earlier. * @param[in] stagingDirCP staging dir name in cross-platform format * @param[in] sz the staging dir name size in bytes * * @return true on success, false otherwise. */ bool DnDRpcV4::SrcDropDone(uint32 sessionId, const uint8 *stagingDirCP, uint32 sz) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_SRC_DROP_DONE; params.sessionId = sessionId; return mUtil.SendMsg(¶ms, stagingDirCP, sz); } /** * Send cmd DND_CMD_SRC_CANCEL to controller. * * @param[in] sessionId active session id the controller assigned earlier. * * @return true on success, false otherwise. */ bool DnDRpcV4::SrcCancel(uint32 sessionId) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_SRC_CANCEL; params.sessionId = sessionId; return mUtil.SendMsg(¶ms); } /** * Send cmd DND_CMD_DEST_DRAG_ENTER to controller. * * @param[in] sessionId active session id the controller assigned earlier. * @param[in] clip cross-platform clipboard data. * * @return true on success, false otherwise. */ bool DnDRpcV4::DestDragEnter(uint32 sessionId, const CPClipboard *clip) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_DEST_DRAG_ENTER; params.sessionId = sessionId; params.optional.version.major = mUtil.GetVersionMajor(); params.optional.version.minor = mUtil.GetVersionMinor(); if (clip) { return mUtil.SendMsg(¶ms, clip); } else { return mUtil.SendMsg(¶ms); } } /** * Send cmd DND_CMD_DEST_SEND_CLIPBOARD to controller. * * @param[in] sessionId active session id the controller assigned earlier. * @param[in] clip cross-platform clipboard data. * * @return true on success, false otherwise. */ bool DnDRpcV4::DestSendClip(uint32 sessionId, const CPClipboard *clip) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_DEST_SEND_CLIPBOARD; params.sessionId = sessionId; return mUtil.SendMsg(¶ms, clip); } /** * Send cmd DND_CMD_DRAG_NOT_PENDING to controller. * * @param[in] sessionId active session id the controller assigned earlier. * * @return true on success, false otherwise. */ bool DnDRpcV4::DragNotPending(uint32 sessionId) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_DRAG_NOT_PENDING; params.sessionId = sessionId; return mUtil.SendMsg(¶ms); } /** * Send cmd DND_CMD_DEST_DRAG_LEAVE to controller. * * @param[in] sessionId active session id the controller assigned earlier. * @param[in] x mouse position x. * @param[in] y mouse position y. * * @return true on success, false otherwise. */ bool DnDRpcV4::DestDragLeave(uint32 sessionId, int32 x, int32 y) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_DEST_DRAG_LEAVE; params.sessionId = sessionId; params.optional.mouseInfo.x = x; params.optional.mouseInfo.y = y; return mUtil.SendMsg(¶ms); } /** * Send cmd DND_CMD_DEST_DROP to controller. * * @param[in] sessionId active session id the controller assigned earlier. * @param[in] x mouse position x. * @param[in] y mouse position y. * * @return true on success, false otherwise. */ bool DnDRpcV4::DestDrop(uint32 sessionId, int32 x, int32 y) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_DEST_DROP; params.sessionId = sessionId; params.optional.mouseInfo.x = x; params.optional.mouseInfo.y = y; return mUtil.SendMsg(¶ms); } /** * Send cmd DND_CMD_DEST_CANCEL to controller. * * @param[in] sessionId active session id the controller assigned earlier. * * @return true on success, false otherwise. */ bool DnDRpcV4::DestCancel(uint32 sessionId) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_DEST_CANCEL; params.sessionId = sessionId; return mUtil.SendMsg(¶ms); } /** * Send cmd DND_CMD_QUERY_EXITING to controller. * * @param[in] sessionId active session id the controller assigned earlier. * @param[in] x mouse position x. * @param[in] y mouse position y. * * @return true on success, false otherwise. */ bool DnDRpcV4::QueryExiting(uint32 sessionId, int32 x, int32 y) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_QUERY_EXITING; params.sessionId = sessionId; params.optional.queryExiting.major = mUtil.GetVersionMajor(); params.optional.queryExiting.minor = mUtil.GetVersionMinor(); params.optional.queryExiting.x = x; params.optional.queryExiting.y = y; return mUtil.SendMsg(¶ms); } /** * Send cmd DND_CMD_UPDATE_UNITY_DET_WND to controller. * * @param[in] sessionId Active session id the controller assigned earlier. * @param[in] show Show or hide unity DnD detection window. * @param[in] unityWndId The unity window id. * * @return true on success, false otherwise. */ bool DnDRpcV4::UpdateUnityDetWnd(uint32 sessionId, bool show, uint32 unityWndId) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_UPDATE_UNITY_DET_WND; params.sessionId = sessionId; params.optional.updateUnityDetWnd.major = mUtil.GetVersionMajor(); params.optional.updateUnityDetWnd.minor = mUtil.GetVersionMinor(); params.optional.updateUnityDetWnd.show = show ? 1 : 0; params.optional.updateUnityDetWnd.unityWndId = unityWndId; return mUtil.SendMsg(¶ms); } /** * Send cmd DND_CMD_MOVE_MOUSE to controller. * * @param[in] sessionId active session id the controller assigned earlier. * @param[in] x mouse position x. * @param[in] y mouse position y. * * @return true on success, false otherwise. */ bool DnDRpcV4::MoveMouse(uint32 sessionId, int32 x, int32 y) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_MOVE_MOUSE; params.sessionId = sessionId; params.optional.mouseInfo.x = x; params.optional.mouseInfo.y = y; return mUtil.SendMsg(¶ms); } /** * Send cmd DND_CMD_REQUEST_FILES to controller. * * @param[in] sessionId active session id the controller assigned earlier. * * @return true on success, false otherwise. */ bool DnDRpcV4::RequestFiles(uint32 sessionId) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_REQUEST_FILES; params.sessionId = sessionId; return mUtil.SendMsg(¶ms); } /** * Send cmd DND_CMD_SEND_FILES_DONE to controller. * * @param[in] sessionId active session id the controller assigned earlier. * @param[in] success the file transfer operation was successful or not * @param[in] stagingDirCP staging dir name in cross-platform format * @param[in] sz the staging dir name size in bytes * * @return true on success, false otherwise. */ bool DnDRpcV4::SendFilesDone(uint32 sessionId, bool success, const uint8 *stagingDirCP, uint32 sz) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_SEND_FILES_DONE; params.status = success ? DND_CP_MSG_STATUS_SUCCESS : DND_CP_MSG_STATUS_ERROR; params.sessionId = sessionId; return mUtil.SendMsg(¶ms, stagingDirCP, sz); } /** * Send cmd DND_CMD_GET_FILES_DONE to controller. * * @param[in] sessionId active session id the controller assigned earlier. * @param[in] success the file transfer operation was successful or not * * @return true on success, false otherwise. */ bool DnDRpcV4::GetFilesDone(uint32 sessionId, bool success) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = DND_CMD_GET_FILES_DONE; params.status = success ? DND_CP_MSG_STATUS_SUCCESS : DND_CP_MSG_STATUS_ERROR; params.sessionId = sessionId; return mUtil.SendMsg(¶ms); } /** * Send a packet. * * @param[in] destId destination address id. * @param[in] packet * @param[in] length packet length * * @return true on success, false otherwise. */ bool DnDRpcV4::SendPacket(uint32 destId, const uint8 *packet, size_t length) { return mTransport->SendPacket(destId, mTransportInterface, packet, length); } /** * Handle a received message. * * @param[in] params parameter list for received message. * @param[in] binary attached binary data for received message. * @param[in] binarySize */ void DnDRpcV4::HandleMsg(RpcParams *params, const uint8 *binary, uint32 binarySize) { ASSERT(params); LOG(4, ("%s: Got %s[%d], sessionId %d, srcId %d, binary size %d.\n", __FUNCTION__, DnDCPMsgV4_LookupCmd(params->cmd), params->cmd, params->sessionId, params->addrId, binarySize)); switch (params->cmd) { case DND_CMD_SRC_DRAG_BEGIN: CPClipboard clip; if (!binary || binarySize == 0) { LOG(0, ("%s: invalid clipboard data.\n", __FUNCTION__)); break; } if (!CPClipboard_Unserialize(&clip, (void *)binary, binarySize)) { LOG(0, ("%s: CPClipboard_Unserialize failed.\n", __FUNCTION__)); break; } srcDragBeginChanged.emit(params->sessionId, &clip); CPClipboard_Destroy(&clip); break; case DND_CMD_SRC_CANCEL: srcCancelChanged.emit(params->sessionId); break; case DND_CMD_SRC_DROP: srcDropChanged.emit(params->sessionId, params->optional.mouseInfo.x, params->optional.mouseInfo.y); break; case DND_CMD_DEST_DRAG_ENTER_REPLY: destDragEnterReplyChanged.emit(params->sessionId, params->status); break; case DND_CMD_DEST_DROP: destDropChanged.emit(params->sessionId, params->optional.mouseInfo.x, params->optional.mouseInfo.y); break; case DND_CMD_DEST_CANCEL: destCancelChanged.emit(params->sessionId); break; case DND_CMD_PRIV_DRAG_ENTER: destPrivDragEnterChanged.emit(params->sessionId); break; case DND_CMD_PRIV_DRAG_LEAVE: destPrivDragLeaveChanged.emit(params->sessionId, params->optional.mouseInfo.x, params->optional.mouseInfo.y); break; case DND_CMD_PRIV_DROP: destPrivDropChanged.emit(params->sessionId, params->optional.mouseInfo.x, params->optional.mouseInfo.y); break; case DND_CMD_QUERY_EXITING: queryExitingChanged.emit(params->sessionId, params->optional.queryExiting.x, params->optional.queryExiting.y); break; case DND_CMD_DRAG_NOT_PENDING: dragNotPendingChanged.emit(params->sessionId); break; case DND_CMD_UPDATE_UNITY_DET_WND: updateUnityDetWndChanged.emit(params->sessionId, 1 == params->optional.updateUnityDetWnd.show, params->optional.updateUnityDetWnd.unityWndId); break; case DND_CMD_MOVE_MOUSE: moveMouseChanged.emit(params->sessionId, params->optional.mouseInfo.x, params->optional.mouseInfo.y); break; case DND_CMD_UPDATE_FEEDBACK: updateFeedbackChanged.emit(params->sessionId, params->optional.feedback.feedback); break; case DND_CMD_REQUEST_FILES: requestFileChanged.emit(params->sessionId, binary, binarySize); break; case DND_CMD_GET_FILES_DONE: getFilesDoneChanged.emit(params->sessionId, DND_CP_MSG_STATUS_SUCCESS == params->status, binary, binarySize); break; case DNDCP_CMD_PING_REPLY: pingReplyChanged.emit(params->optional.version.capability); break; case DNDCP_CMD_TEST_BIG_BINARY: { if (binarySize != DND_CP_MSG_MAX_BINARY_SIZE_V4) { LOG(0, ("%s: msg size is not right, should be %u.\n", __FUNCTION__, DND_CP_MSG_MAX_BINARY_SIZE_V4)); } uint32 *testBinary = (uint32 *)binary; for (uint32 i = 0; i < DND_CP_MSG_MAX_BINARY_SIZE_V4 / sizeof *testBinary; i++) { if (testBinary[i] != i) { LOG(0, ("%s: msg wrong in position %u. Expect %u, but got %u.\n", __FUNCTION__, i, i, testBinary[i])); return; } } LOG(4, ("%s: successfully got big binary, sending back.\n", __FUNCTION__)); RpcParams outParams; memset(&outParams, 0, sizeof outParams); outParams.addrId = params->addrId; outParams.cmd = DNDCP_CMD_TEST_BIG_BINARY_REPLY; mUtil.SendMsg(&outParams, binary, DND_CP_MSG_MAX_BINARY_SIZE_V4); break; } case DNDCP_CMP_REPLY: LOG(0, ("%s: Got cmp reply command %d.\n", __FUNCTION__, params->cmd)); cmdReplyChanged.emit(params->cmd, params->status); break; default: LOG(0, ("%s: Got unknown command %d.\n", __FUNCTION__, params->cmd)); break; } } /** * Callback from transport layer after received a packet from srcId. * * @param[in] srcId addressId where the packet is from * @param[in] packet * @param[in] packetSize */ void DnDRpcV4::OnRecvPacket(uint32 srcId, const uint8 *packet, size_t packetSize) { mUtil.OnRecvPacket(srcId, packet, packetSize); } /** * Register a listener that will fire when RPCs are received. * * @param[in] obj an instance of a class that derives DnDRpcListener. */ void DnDRpcV4::AddRpcReceivedListener(DnDRpcListener *obj) { mUtil.AddRpcReceivedListener(obj); } /** * Remove a listener that will fire when RPCs are received. * * @param[in] obj an instance of a class that derives DnDRpcListener. */ void DnDRpcV4::RemoveRpcReceivedListener(DnDRpcListener *obj) { mUtil.RemoveRpcReceivedListener(obj); } /** * Add a listener that will fire when RPCs are sent. * * @param[in] obj an instance of a class that derives DnDRpcListener. */ void DnDRpcV4::AddRpcSentListener(DnDRpcListener *obj) { mUtil.AddRpcSentListener(obj); } /** * Remove a listener that will fire when RPCs are sent. * * @param[in] obj an instance of a class that derives DnDRpcListener. */ void DnDRpcV4::RemoveRpcSentListener(DnDRpcListener *obj) { mUtil.RemoveRpcSentListener(obj); } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/dndCPTransportGuestRpc.cpp0000644765153500003110000002541012220061556026700 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @dndCPTransportGuestRpc.cpp -- * * GuestRpc implementation of the dndCPTransport interface. * * XXX Move this to a common lib or source location. */ #include "dndCPTransportGuestRpc.hpp" #include "rpcBase.h" extern "C" { #include "str.h" #include "hostinfo.h" #include "dndMsg.h" #include "util.h" #ifdef VMX86_TOOLS #include "debug.h" #include "rpcout.h" #include "rpcin.h" #define LOG(level, msg) (Debug msg) #else #include "dndCPInt.h" #include "guest_rpc.h" #include "tclodefs.h" #define LOGLEVEL_MODULE dnd #include "loglevel_user.h" #endif } #ifdef VMX86_TOOLS /** * Received a message from guestRpc. Forward the message to transport class. * * @param[out] result reply string. * @param[out] resultLen reply string length in byte. * @param[in] name guestRpc cmd name. * @param[in] args argument list. * @param[in] argsSize argument list size in byte. * @param[in] clientData callback client data. * * @return TRUE if success, FALSE otherwise. */ static gboolean RecvMsgCB(RpcInData *data) // IN/OUT { LOG(4, ("%s: receiving\n", __FUNCTION__)); const uint8 *packet = (const uint8 *)(data->args + 1); size_t packetSize = data->argsSize - 1; /* '- 1' is to ignore empty space between command and args. */ if ((data->argsSize - 1) <= 0) { Debug("%s: invalid argsSize\n", __FUNCTION__); return RPCIN_SETRETVALS(data, "invalid arg size", FALSE); } GuestRpcCBCtx *ctx = (GuestRpcCBCtx *)data->clientData; #else /** * Received a message from guestRpc. Forward the message to transport class. * * @param[in] clientData callback client data. * @param[ignored] channelId * @param[in] args argument list. * @param[in] argsSize argument list size in byte. * @param[out] result reply string. * @param[out] resultSize reply string length in byte. * * @return TRUE if success, FALSE otherwise. */ static Bool RecvMsgCB(void *clientData, uint16 channelId, const unsigned char *args, uint32 argsSize, unsigned char **result, uint32 *resultSize) { const uint8 *packet = args; size_t packetSize = argsSize; GuestRpcCBCtx *ctx = (GuestRpcCBCtx *)clientData; #endif ASSERT(ctx); ASSERT(ctx->transport); ctx->transport->OnRecvPacket(ctx->type, packet, packetSize); #ifdef VMX86_TOOLS return RPCIN_SETRETVALS(data, "", TRUE); #else return GuestRpc_SetRetVals(result, resultSize, (char *)"", TRUE); #endif } /** * Constructor. */ TransportGuestRpcTables::TransportGuestRpcTables(void) { for (int i = 0; i < TRANSPORT_INTERFACE_MAX; i++) { mRpcList[i] = NULL; mCmdStrTable[i] = NULL; mDisableStrTable[i] = NULL; #ifdef VMX86_TOOLS } #else mCmdTable[i] = GUESTRPC_CMD_MAX; } mCmdTable[TRANSPORT_GUEST_CONTROLLER_DND] = GUESTRPC_CMD_DND_TRANSPORT; mCmdTable[TRANSPORT_GUEST_CONTROLLER_CP] = GUESTRPC_CMD_COPYPASTE_TRANSPORT; #endif mCmdStrTable[TRANSPORT_GUEST_CONTROLLER_DND] = (char *)GUEST_RPC_CMD_STR_DND; mCmdStrTable[TRANSPORT_GUEST_CONTROLLER_CP] = (char *)GUEST_RPC_CMD_STR_CP; mDisableStrTable[TRANSPORT_GUEST_CONTROLLER_DND] = (char *)GUEST_RPC_DND_DISABLE; mDisableStrTable[TRANSPORT_GUEST_CONTROLLER_CP] = (char *)GUEST_RPC_CP_DISABLE; } /** * Destructor. */ TransportGuestRpcTables::~TransportGuestRpcTables(void) { } /** * Get an rpc object by interface type. * * @param[in] type transport interface type * * @return a registered rpc, or NULL if the rpc for the type is not registered. */ RpcBase * TransportGuestRpcTables::GetRpc(TransportInterfaceType type) { ASSERT(type == TRANSPORT_GUEST_CONTROLLER_DND || type == TRANSPORT_GUEST_CONTROLLER_CP || type == TRANSPORT_GUEST_CONTROLLER_FT); return mRpcList[type]; } /** * Add a rpc into rpc table. * * @param[in] type transport interface type * @param[in] rpc rpc which is added into the table. */ void TransportGuestRpcTables::SetRpc(TransportInterfaceType type, RpcBase *rpc) { ASSERT(type == TRANSPORT_GUEST_CONTROLLER_DND || type == TRANSPORT_GUEST_CONTROLLER_CP || type == TRANSPORT_GUEST_CONTROLLER_FT); mRpcList[type] = rpc; } #ifndef VMX86_TOOLS /** * Get a guestRpc cmd by interface type. * * @param[in] type transport interface type * * @return a guestRpc cmd. */ GuestRpcCmd TransportGuestRpcTables::GetCmd(TransportInterfaceType type) { ASSERT(type == TRANSPORT_GUEST_CONTROLLER_DND || type == TRANSPORT_GUEST_CONTROLLER_CP || type == TRANSPORT_GUEST_CONTROLLER_FT); return mCmdTable[type]; } #endif /** * Get a guestRpc cmd string by interface type. * * @param[in] type transport interface type * * @return a guestRpc cmd string. */ const char * TransportGuestRpcTables::GetCmdStr(TransportInterfaceType type) { ASSERT(type == TRANSPORT_GUEST_CONTROLLER_DND || type == TRANSPORT_GUEST_CONTROLLER_CP || type == TRANSPORT_GUEST_CONTROLLER_FT); return mCmdStrTable[type]; } /** * Get a guestRpc cmd disable string by interface type. * * @param[in] type transport interface type * * @return a guestRpc cmd disable string. */ const char * TransportGuestRpcTables::GetDisableStr(TransportInterfaceType type) { ASSERT(type == TRANSPORT_GUEST_CONTROLLER_DND || type == TRANSPORT_GUEST_CONTROLLER_CP || type == TRANSPORT_GUEST_CONTROLLER_FT); return mDisableStrTable[type]; } /** * Constructor. * * @param[in] rpcIn */ #ifdef VMX86_TOOLS DnDCPTransportGuestRpc::DnDCPTransportGuestRpc(RpcChannel *chan) : mRpcChannel(chan) #else DnDCPTransportGuestRpc::DnDCPTransportGuestRpc(void) #endif { for (int i = 0; i < TRANSPORT_INTERFACE_MAX; i++) { mCBCtx[i].transport = this; mCBCtx[i].type = (TransportInterfaceType)i; } } /** * Register a rpc callback to an interface. * * @param[in] rpc rpc which is listening to the message. * @param[in] type the interface type rpc is listening to. * * @return true on success, false otherwise. */ bool DnDCPTransportGuestRpc::RegisterRpc(RpcBase *rpc, TransportInterfaceType type) { if (mTables.GetRpc(type)) { LOG(0, ("%s: the type %d is already registered\n", __FUNCTION__, type)); UnregisterRpc(type); } const char *cmdStr = (const char *)mTables.GetCmdStr(type); const char *disableStr = mTables.GetDisableStr(type); if (!cmdStr || !disableStr) { LOG(0, ("%s: can not find valid cmd for %d, cmdStr %s disableStr %s\n", __FUNCTION__, type, (cmdStr ? cmdStr : "NULL"), (disableStr ? disableStr : "NULL"))); return false; } ASSERT(mCBCtx); ASSERT(type == TRANSPORT_GUEST_CONTROLLER_DND || type == TRANSPORT_GUEST_CONTROLLER_CP || type == TRANSPORT_GUEST_CONTROLLER_FT); LOG(4, ("%s: for %s\n", __FUNCTION__, cmdStr)); #ifdef VMX86_TOOLS ASSERT(mRpcChannel); mRpcChanCBList[type].name = cmdStr; mRpcChanCBList[type].callback = RecvMsgCB; mRpcChanCBList[type].clientData = &mCBCtx[type]; mRpcChanCBList[type].xdrIn = NULL; mRpcChanCBList[type].xdrOut = NULL; mRpcChanCBList[type].xdrInSize = 0; RpcChannel_RegisterCallback(mRpcChannel, &mRpcChanCBList[type]); #else GuestRpc_RegisterCommand(mTables.GetCmd(type), disableStr, (const unsigned char *)cmdStr, RecvMsgCB, &mCBCtx[type]); #endif mTables.SetRpc(type, rpc); return true; } /** * Unregister a rpc callback. * * @param[in] type the interface type rpc is listening to. * * @return true on success, false otherwise. */ bool DnDCPTransportGuestRpc::UnregisterRpc(TransportInterfaceType type) { if (!mTables.GetRpc(type)) { LOG(0, ("%s: the type %d is not registered\n", __FUNCTION__, type)); return false; } #ifdef VMX86_TOOLS ASSERT(mRpcChannel); RpcChannel_UnregisterCallback(mRpcChannel, &mRpcChanCBList[type]); #else GuestRpc_UnregisterCommand(mTables.GetCmd(type)); #endif mTables.SetRpc(type, NULL); return true; } /** * Wrap the buffer into an rpc and send it to the peer. * * @param[ignored] destId destination address id * @param[in] type transport interface type * @param[in] data Payload buffer * @param[in] dataSize Payload buffer size * * @return true on success, false otherwise. */ bool DnDCPTransportGuestRpc::SendPacket(uint32 destId, TransportInterfaceType type, const uint8 *msg, size_t length) { char *rpc = NULL; size_t rpcSize = 0; size_t nrWritten = 0; const char *cmd = mTables.GetCmdStr(type); bool ret = true; if (!cmd) { LOG(0, ("%s: can not find valid cmd for %d\n", __FUNCTION__, type)); return false; } rpcSize = strlen(cmd) + 1 + length; rpc = (char *)Util_SafeMalloc(rpcSize); nrWritten = Str_Sprintf(rpc, rpcSize, "%s ", cmd); if (length > 0) { ASSERT(nrWritten + length <= rpcSize); memcpy(rpc + nrWritten, msg, length); } #ifdef VMX86_TOOLS ret = (TRUE == RpcChannel_Send(mRpcChannel, rpc, rpcSize, NULL, NULL)); if (!ret) { LOG(0, ("%s: failed to send msg to host\n", __FUNCTION__)); } free(rpc); #else GuestRpc_SendWithTimeOut((const unsigned char *)TOOLS_DND_NAME, (const unsigned char *)rpc, rpcSize, GuestRpc_GenericCompletionRoutine, rpc, DND_TIMEOUT); #endif return ret; } /** * Callback after receiving a guestRpc message. * * @param[in] type transport interface type * @param[in] packet Payload buffer * @param[in] packetSize Payload buffer size */ void DnDCPTransportGuestRpc::OnRecvPacket(TransportInterfaceType type, const uint8 *packet, size_t packetSize) { RpcBase *rpc = mTables.GetRpc(type); if (!rpc) { LOG(0, ("%s: can not find valid rpc for %d\n", __FUNCTION__, type)); return; } rpc->OnRecvPacket(DEFAULT_CONNECTION_ID, packet, packetSize); } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/guestDnDDest.cc0000644765153500003110000001441112220061556024455 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @guestDnDDest.cc -- * * Implementation of common layer GuestDnDDest object for guest. */ #include "guestDnD.hh" extern "C" { #include "dndClipboard.h" #include "debug.h" } /** * Constructor. * * @param[in] mgr guest DnD manager */ GuestDnDDest::GuestDnDDest(GuestDnDMgr *mgr) : mMgr(mgr) { ASSERT(mMgr); mMgr->GetRpc()->destPrivDragEnterChanged.connect( sigc::mem_fun(this, &GuestDnDDest::OnRpcPrivDragEnter)); mMgr->GetRpc()->destPrivDragLeaveChanged.connect( sigc::mem_fun(this, &GuestDnDDest::OnRpcPrivDragLeave)); mMgr->GetRpc()->destPrivDropChanged.connect( sigc::mem_fun(this, &GuestDnDDest::OnRpcPrivDrop)); mMgr->GetRpc()->destDropChanged.connect( sigc::mem_fun(this, &GuestDnDDest::OnRpcDrop)); mMgr->GetRpc()->destCancelChanged.connect( sigc::mem_fun(this, &GuestDnDDest::OnRpcCancel)); CPClipboard_Init(&mClipboard); } /** * Destructor. */ GuestDnDDest::~GuestDnDDest(void) { CPClipboard_Destroy(&mClipboard); } /** * Guest UI got dragEnter with valid data. Send dragEnter cmd to controller. * * @param[in] clip cross-platform clipboard data. */ void GuestDnDDest::UIDragEnter(const CPClipboard *clip) { if (!mMgr->IsDragEnterAllowed()) { Debug("%s: not allowed.\n", __FUNCTION__); return; } Debug("%s: entering.\n", __FUNCTION__); if (GUEST_DND_DEST_DRAGGING == mMgr->GetState() || GUEST_DND_PRIV_DRAGGING == mMgr->GetState()) { /* * In GH DnD case, if DnD already happened, user may drag back into guest * VM and drag into the detection window again, and trigger the * DragEnter. In this case, ignore the DragEnter. */ Debug("%s: already in state %d for GH DnD, ignoring.\n", __FUNCTION__, mMgr->GetState()); return; } if (GUEST_DND_SRC_DRAGGING == mMgr->GetState()) { /* * In HG DnD case, if DnD already happened, user may also drag into the * detection window again. The DragEnter should also be ignored. */ Debug("%s: already in SRC_DRAGGING state, ignoring\n", __FUNCTION__); return; } /* * In Unity mode, there is no QueryPendingDrag signal, so may get called * with state READY. */ if (mMgr->GetState() != GUEST_DND_QUERY_EXITING && mMgr->GetState() != GUEST_DND_READY) { Debug("%s: Bad state: %d, reset\n", __FUNCTION__, mMgr->GetState()); goto error; } CPClipboard_Clear(&mClipboard); CPClipboard_Copy(&mClipboard, clip); if (!mMgr->GetRpc()->DestDragEnter(mMgr->GetSessionId(), clip)) { Debug("%s: DestDragEnter failed\n", __FUNCTION__); goto error; } mMgr->SetState(GUEST_DND_DEST_DRAGGING); Debug("%s: state changed to DEST_DRAGGING\n", __FUNCTION__); return; error: mMgr->ResetDnD(); } /** * User drags back to guest during GH DnD. Change state machine to * PRIV_DRAGGING state. * * @param[in] sessionId active session id the controller assigned. */ void GuestDnDDest::OnRpcPrivDragEnter(uint32 sessionId) { Debug("%s: entering.\n", __FUNCTION__); if (GUEST_DND_DEST_DRAGGING != mMgr->GetState()) { Debug("%s: Bad state: %d, reset\n", __FUNCTION__, mMgr->GetState()); goto error; } mMgr->SetState(GUEST_DND_PRIV_DRAGGING); Debug("%s: state changed to PRIV_DRAGGING\n", __FUNCTION__); return; error: mMgr->ResetDnD(); } /** * User drags away from guest during GH DnD. Change state machine to * SRC_DRAGGING state. * * @param[in] sessionId active session id the controller assigned. * @param[in] x mouse position x. * @param[in] y mouse position y. */ void GuestDnDDest::OnRpcPrivDragLeave(uint32 sessionId, int32 x, int32 y) { Debug("%s: entering.\n", __FUNCTION__); if (GUEST_DND_PRIV_DRAGGING != mMgr->GetState()) { Debug("%s: Bad state: %d, reset\n", __FUNCTION__, mMgr->GetState()); goto error; } mMgr->SetState(GUEST_DND_DEST_DRAGGING); mMgr->destMoveDetWndToMousePosChanged.emit(); Debug("%s: state changed to DEST_DRAGGING\n", __FUNCTION__); return; error: mMgr->ResetDnD(); } /** * User drops inside guest during GH DnD. Simulate the mouse drop, hide * detection window, and reset state machine. * * @param[in] sessionId active session id the controller assigned. * @param[in] x mouse position x. * @param[in] y mouse position y. */ void GuestDnDDest::OnRpcPrivDrop(uint32 sessionId, int32 x, int32 y) { mMgr->privDropChanged.emit(x, y); mMgr->HideDetWnd(); mMgr->SetState(GUEST_DND_READY); Debug("%s: state changed to GUEST_DND_READY, session id changed to 0\n", __FUNCTION__); } /** * User drops outside of guest during GH DnD. Simply cancel the local DnD. * * @param[in] sessionId active session id the controller assigned. * @param[in] x mouse position x. * @param[in] y mouse position y. */ void GuestDnDDest::OnRpcDrop(uint32 sessionId, int32 x, int32 y) { OnRpcCancel(sessionId); } /** * Cancel current GH DnD. * * @param[in] sessionId active session id the controller assigned. */ void GuestDnDDest::OnRpcCancel(uint32 sessionId) { mMgr->DelayHideDetWnd(); mMgr->RemoveUngrabTimeout(); mMgr->destCancelChanged.emit(); mMgr->SetState(GUEST_DND_READY); Debug("%s: state changed to GUEST_DND_READY, session id changed to 0\n", __FUNCTION__); } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/guestCopyPaste.hh0000644765153500003110000001007612220061556025114 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @guestCopyPaste.hh -- * * CopyPaste common layer classes for guest. */ #ifndef GUEST_COPY_PASTE_HH #define GUEST_COPY_PASTE_HH #include #include #include "copyPasteRpc.hh" #include "guestFileTransfer.hh" extern "C" { #include "dnd.h" } enum GUEST_CP_STATE { GUEST_CP_INVALID = 0, GUEST_CP_READY, GUEST_CP_HG_FILE_COPYING, }; class GuestCopyPasteSrc; class GuestCopyPasteDest; class GuestCopyPasteMgr : public sigc::trackable { public: GuestCopyPasteMgr(DnDCPTransport *transport); ~GuestCopyPasteMgr(void); sigc::signal srcRecvClipChanged; sigc::signal destRequestClipChanged; sigc::signal getFilesDoneChanged; GUEST_CP_STATE GetState(void) { return mCPState; } void SetState(GUEST_CP_STATE state) { mCPState = state; } CopyPasteRpc *GetRpc(void) { return mRpc; } GuestCopyPasteSrc *GetCopyPasteSrc(void) { return mSrc; } GuestCopyPasteDest *GetCopyPasteDest(void) { return mDest; } void ResetCopyPaste(void); uint32 GetSessionId(void) { return mSessionId; } void SetSessionId(uint32 id) { mSessionId = id; } void DestUISendClip(const CPClipboard *clip); const std::string SrcUIRequestFiles(const std::string &dir = ""); bool IsCopyPasteAllowed (void) { return mCopyPasteAllowed; } void SetCopyPasteAllowed(bool isCopyPasteAllowed) { mCopyPasteAllowed = isCopyPasteAllowed; } void VmxCopyPasteVersionChanged(uint32 version); Bool CheckCapability(uint32 capsRequest); private: void OnRpcSrcRecvClip(uint32 sessionId, bool isActive, const CPClipboard *clip); void OnRpcDestRequestClip(uint32 sessionId, bool isActive); void OnPingReply(uint32 capabilities); GuestCopyPasteSrc *mSrc; GuestCopyPasteDest *mDest; CopyPasteRpc *mRpc; GUEST_CP_STATE mCPState; DnDCPTransport *mTransport; uint32 mSessionId; bool mCopyPasteAllowed; uint32 mResolvedCaps; // caps as returned in ping reply, or default. }; class GuestCopyPasteSrc : public sigc::trackable { public: GuestCopyPasteSrc(GuestCopyPasteMgr *mgr); ~GuestCopyPasteSrc(void); /* Common CopyPaste layer API exposed to UI for CopyPaste source. */ const std::string UIRequestFiles(const std::string &dir = ""); void OnRpcRecvClip(bool isActive, const CPClipboard *clip); private: /* Callbacks from rpc for CopyPaste source. */ void OnRpcGetFilesDone(uint32 sessionId, bool success, const uint8 *stagingDirCP, uint32 sz); const std::string &SetupDestDir(const std::string &destDir); GuestCopyPasteMgr *mMgr; CPClipboard mClipboard; bool mIsActive; std::string mStagingDir; }; class GuestCopyPasteDest : public sigc::trackable { public: GuestCopyPasteDest(GuestCopyPasteMgr *mgr); /* Common CopyPaste layer API exposed to UI for CopyPaste destination. */ void UISendClip(const CPClipboard *clip); /* Callbacks from rpc for CopyPaste destination. */ void OnRpcRequestClip(bool isActive); private: GuestCopyPasteMgr *mMgr; bool mIsActive; }; #endif // GUEST_COPY_PASTE_HH open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/copyPasteRpcV4.cc0000644765153500003110000002100312220061556024741 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @copyPasteRpcV4.cc -- * * Rpc layer object for CopyPaste version 4. */ #include "copyPasteRpcV4.hh" extern "C" { #if defined VMX86_TOOLS #include "debug.h" #define LOG(level, msg) (Debug msg) #else #define LOGLEVEL_MODULE dnd #include "loglevel_user.h" #endif #include "dndClipboard.h" #include "util.h" } /** * Constructor. * * @param[in] transport for sending packets. */ CopyPasteRpcV4::CopyPasteRpcV4(DnDCPTransport *transport) : mTransport(transport), #ifdef VMX86_TOOLS mTransportInterface(TRANSPORT_GUEST_CONTROLLER_CP) #else mTransportInterface(TRANSPORT_HOST_CONTROLLER_CP) #endif { ASSERT(mTransport); #ifdef VMX86_TOOLS mUtil.Init(this, DND_CP_MSG_SRC_GUEST, DND_CP_MSG_TYPE_CP); #else mUtil.Init(this, DND_CP_MSG_SRC_HOST, DND_CP_MSG_TYPE_CP); #endif } /** * Init. */ void CopyPasteRpcV4::Init() { ASSERT(mTransport); mTransport->RegisterRpc(this, mTransportInterface); } /** * Send Ping message to controller. * * @param[in] caps capabilities value. */ void CopyPasteRpcV4::SendPing(uint32 caps) { mUtil.SendPingMsg(DEFAULT_CONNECTION_ID, caps); } /** * Send cmd CP_CMD_REQUEST_CLIPBOARD to controller. * * @param[in] sessionId active session id the controller assigned earlier. * @param[in] isActive active or passive CopyPaste * * @return true on success, false otherwise. */ bool CopyPasteRpcV4::SrcRequestClip(uint32 sessionId, bool isActive) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = CP_CMD_REQUEST_CLIPBOARD; params.sessionId = sessionId; params.optional.cpInfo.major = mUtil.GetVersionMajor(); params.optional.cpInfo.minor = mUtil.GetVersionMinor(); params.optional.cpInfo.isActive = isActive; return mUtil.SendMsg(¶ms); } /** * Send cmd CP_CMD_SEND_CLIPBOARD to controller. * * @param[in] sessionId active session id the controller assigned earlier. * @param[in] isActive active or passive CopyPaste * @param[in] clip cross-platform clipboard data. * * @return true on success, false otherwise. */ bool CopyPasteRpcV4::DestSendClip(uint32 sessionId, bool isActive, const CPClipboard* clip) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = CP_CMD_SEND_CLIPBOARD; params.sessionId = sessionId; params.optional.cpInfo.major = mUtil.GetVersionMajor(); params.optional.cpInfo.minor = mUtil.GetVersionMinor(); params.optional.cpInfo.isActive = isActive; return mUtil.SendMsg(¶ms, clip); } /** * Send cmd CP_CMD_REQUEST_FILE to controller. * * @param[in] sessionId active session id the controller assigned earlier. * @param[in] stagingDirCP staging dir name in cross-platform format * @param[in] sz the staging dir name size in bytes * * @return true on success, false otherwise. */ bool CopyPasteRpcV4::RequestFiles(uint32 sessionId, const uint8 *stagingDirCP, uint32 sz) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = CP_CMD_REQUEST_FILES; params.sessionId = sessionId; return mUtil.SendMsg(¶ms, stagingDirCP, sz); } /** * Send cmd CP_CMD_SEND_FILES_DONE to controller. * * @param[in] sessionId active session id the controller assigned earlier. * @param[in] success the file transfer operation was successful or not * @param[in] stagingDirCP staging dir name in cross-platform format * @param[in] sz the staging dir name size in bytes * * @return true on success, false otherwise. */ bool CopyPasteRpcV4::SendFilesDone(uint32 sessionId, bool success, const uint8 *stagingDirCP, uint32 sz) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = CP_CMD_SEND_FILES_DONE; params.status = success ? DND_CP_MSG_STATUS_SUCCESS : DND_CP_MSG_STATUS_ERROR; params.sessionId = sessionId; return mUtil.SendMsg(¶ms, stagingDirCP, sz); } /** * Send cmd CP_CMD_GET_FILES_DONE to controller. * * @param[in] sessionId active session id the controller assigned earlier. * @param[in] success the file transfer operation was successful or not * * @return true on success, false otherwise. */ bool CopyPasteRpcV4::GetFilesDone(uint32 sessionId, bool success) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = CP_CMD_GET_FILES_DONE; params.status = success ? DND_CP_MSG_STATUS_SUCCESS : DND_CP_MSG_STATUS_ERROR; params.sessionId = sessionId; return mUtil.SendMsg(¶ms); } /** * Send a packet. * * @param[in] destId destination address id. * @param[in] packet * @param[in] length packet length in bytes * * @return true on success, false otherwise. */ bool CopyPasteRpcV4::SendPacket(uint32 destId, const uint8 *packet, size_t length) { ASSERT(mTransport); return mTransport->SendPacket(destId, mTransportInterface, packet, length); } /** * Handle a received message. * * @param[in] params parameter list for received message. * @param[in] binary attached binary data for received message. * @param[in] binarySize in bytes */ void CopyPasteRpcV4::HandleMsg(RpcParams *params, const uint8 *binary, uint32 binarySize) { ASSERT(params); LOG(4, ("%s: Got %s[%d], sessionId %d, srcId %d, binary size %d.\n", __FUNCTION__, DnDCPMsgV4_LookupCmd(params->cmd), params->cmd, params->sessionId, params->addrId, binarySize)); switch (params->cmd) { case CP_CMD_RECV_CLIPBOARD: CPClipboard clip; if (!binary || binarySize == 0) { LOG(0, ("%s: invalid clipboard data.\n", __FUNCTION__)); break; } if (!CPClipboard_Unserialize(&clip, (void *)binary, binarySize)) { LOG(0, ("%s: CPClipboard_Unserialize failed.\n", __FUNCTION__)); break; } srcRecvClipChanged.emit(params->sessionId, 1 == params->optional.cpInfo.isActive, &clip); CPClipboard_Destroy(&clip); break; case CP_CMD_REQUEST_CLIPBOARD: destRequestClipChanged.emit(params->sessionId, 1 == params->optional.cpInfo.isActive); break; case CP_CMD_REQUEST_FILES: requestFilesChanged.emit(params->sessionId, binary, binarySize); break; case CP_CMD_GET_FILES_DONE: getFilesDoneChanged.emit(params->sessionId, DND_CP_MSG_STATUS_SUCCESS == params->status, binary, binarySize); break; case DNDCP_CMD_PING_REPLY: pingReplyChanged.emit(params->optional.version.capability); break; case DNDCP_CMP_REPLY: LOG(0, ("%s: Got cmp reply command %d.\n", __FUNCTION__, params->cmd)); cmdReplyChanged.emit(params->cmd, params->status); break; default: LOG(0, ("%s: Got unknown command %d.\n", __FUNCTION__, params->cmd)); break; } } /** * Callback from transport layer after received a packet from srcId. * * @param[in] srcId addressId where the packet is from * @param[in] packet * @param[in] packetSize */ void CopyPasteRpcV4::OnRecvPacket(uint32 srcId, const uint8 *packet, size_t packetSize) { mUtil.OnRecvPacket(srcId, packet, packetSize); } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/guestFileTransfer.cc0000644765153500003110000000531412220061556025556 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @guestFileTransfer.cc -- * * Implementation of common layer file transfer object for guest. */ #include "guestFileTransfer.hh" #include "fileTransferRpcV4.hh" extern "C" { #include "debug.h" #include "hgfsServer.h" } /** * Create transport object and register callback. * * @param[in] transport pointer to a transport object. */ GuestFileTransfer::GuestFileTransfer(DnDCPTransport *transport) { ASSERT(transport); mRpc = new FileTransferRpcV4(transport); mRpc->Init(); mRpc->HgfsPacketReceived.connect( sigc::mem_fun(this, &GuestFileTransfer::OnRpcRecvHgfsPacket)); HgfsServerManager_DataInit(&mHgfsServerMgrData, "DnDGuestHgfsMgr", NULL, NULL); HgfsServerManager_Register(&mHgfsServerMgrData); } /** * Destructor. */ GuestFileTransfer::~GuestFileTransfer(void) { delete mRpc; mRpc = NULL; HgfsServerManager_Unregister(&mHgfsServerMgrData); } /** * Callback after received message. * * @param[in] sessionId dnd session id. * @param[in] packet hgfs packet from the peer. * @param[in] packetSize hgfs pack size. */ void GuestFileTransfer::OnRpcRecvHgfsPacket(uint32 sessionId, const uint8 *packet, size_t packetSize) { char replyPacket[HGFS_LARGE_PACKET_MAX]; size_t replyPacketSize; ASSERT(packet); ASSERT(mRpc); /* Call hgfs server to process the request, and send reply back to peer. */ HgfsServerManager_ProcessPacket(&mHgfsServerMgrData, (const char *)packet, packetSize, replyPacket, &replyPacketSize); mRpc->SendHgfsReply(sessionId, (const uint8 *)replyPacket, replyPacketSize); } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/guestDnDCPMgr.cc0000644765153500003110000000762512220061556024537 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @GuestDnDCPMgr.cc -- * * Implementation of common layer GuestDnDCPMgr object. */ #include "guestDnDCPMgr.hh" #include "dndCPTransportGuestRpc.hpp" extern "C" { #include "debug.h" #include "guestApp.h" } GuestDnDCPMgr *GuestDnDCPMgr::m_instance = NULL; /** * * Constructor. */ GuestDnDCPMgr::GuestDnDCPMgr() : mDnDMgr(NULL), mCPMgr(NULL), mFileTransfer(NULL), mTransport(NULL), mToolsAppCtx(NULL), mLocalCaps(0xffffffff) { } /** * Destructor. */ GuestDnDCPMgr::~GuestDnDCPMgr(void) { g_debug("%s: enter\n", __FUNCTION__); delete mDnDMgr; mDnDMgr = NULL; delete mFileTransfer; mFileTransfer = NULL; delete mTransport; mTransport = NULL; } /** * Get an instance of GuestDnDCPMgr, which is an application singleton. * * @return a pointer to the singleton GuestDnDCPMgr object, or NULL if * for some reason it could not be allocated. */ GuestDnDCPMgr * GuestDnDCPMgr::GetInstance(void) { if (!m_instance) { m_instance = new GuestDnDCPMgr; } return m_instance; } /** * Destroy the GuestDnDCPMgr singleton. */ void GuestDnDCPMgr::Destroy(void) { if (m_instance) { delete m_instance; m_instance = NULL; } } /** * Initialize the GuestDnDCPMgr object. All owner should call this first before * calling any other function. * * @param[in] ctx ToolsAppCtx */ void GuestDnDCPMgr::Init(ToolsAppCtx *ctx) { mToolsAppCtx = ctx; ASSERT(mToolsAppCtx); if (mFileTransfer) { delete mFileTransfer; } mFileTransfer = new GuestFileTransfer(GetTransport()); } /** * Get the GuestDnDCPMgr object. * * @return a pointer to the GuestDnDCPMgr instance. */ GuestDnDMgr * GuestDnDCPMgr::GetDnDMgr(void) { if (!mDnDMgr) { /* mEventQueue must be set before this call. */ mDnDMgr = new GuestDnDMgr(GetTransport(), mToolsAppCtx); } return mDnDMgr; } /** * Get the GuestCopyPasteMgr object. * * @return a pointer to the GuestCopyPasteMgr instance. */ GuestCopyPasteMgr * GuestDnDCPMgr::GetCopyPasteMgr(void) { if (!mCPMgr) { mCPMgr = new GuestCopyPasteMgr(GetTransport()); } return mCPMgr; } /** * Get the DnDCPTransport object. * * XXX Implementation here is temporary and should be replaced with rpcChannel. * * @return a pointer to the manager's DnDCPTransport instance. */ DnDCPTransport * GuestDnDCPMgr::GetTransport(void) { if (!mTransport) { ASSERT(mToolsAppCtx); mTransport = new DnDCPTransportGuestRpc(mToolsAppCtx->rpc); } return mTransport; } /** * API for starting the transport main loop from python. */ void GuestDnDCPMgr::StartLoop() { (void) GetTransport(); if (mTransport) { mTransport->StartLoop(); } } /** * API for iterating the transport main loop from python. */ void GuestDnDCPMgr::IterateLoop() { (void) GetTransport(); if (mTransport) { mTransport->IterateLoop(); } } /** * API for ending the transport main loop from python. */ void GuestDnDCPMgr::EndLoop() { (void) GetTransport(); if (mTransport) { mTransport->EndLoop(); } } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/rpcV4Util.cpp0000644765153500003110000004072212220061556024155 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @rpcV4Util.cpp -- * * Implementation of common utility object for DnD/CP version 4 rpc object. * It is shared by host, guest and UI implementation. Some common utilities * including * *packet marshalling/un-marshalling * *common rpc (ping, pingReply, etc) * *big buffer support * are implemented here. */ #include "rpcV4Util.hpp" extern "C" { #ifdef VMX86_TOOLS #include "debug.h" #define LOG(level, msg) (Debug msg) #else #define LOGLEVEL_MODULE dnd #include "loglevel_user.h" #endif #include "dndClipboard.h" #include "util.h" } /** * Constructor. */ RpcV4Util::RpcV4Util(void) : mVersionMajor(4), mVersionMinor(0) { DnDCPMsgV4_Init(&mBigMsgIn); DnDCPMsgV4_Init(&mBigMsgOut); DblLnkLst_Init(&mRpcSentListeners); DblLnkLst_Init(&mRpcReceivedListeners); } /** * Destructor. */ RpcV4Util::~RpcV4Util(void) { DnDCPMsgV4_Destroy(&mBigMsgIn); DnDCPMsgV4_Destroy(&mBigMsgOut); while (DblLnkLst_IsLinked(&mRpcSentListeners)) { DnDRpcSentListenerNode *node = DblLnkLst_Container(mRpcSentListeners.next, DnDRpcSentListenerNode, l); ASSERT(node); DblLnkLst_Unlink1(&node->l); free(node); } while (DblLnkLst_IsLinked(&mRpcReceivedListeners)) { DnDRpcReceivedListenerNode *node = DblLnkLst_Container(mRpcReceivedListeners.next, DnDRpcReceivedListenerNode, l); ASSERT(node); DblLnkLst_Unlink1(&node->l); free(node); } } /** * Initialize the RpcV4Util object. All owner should call this first before * calling any other utility function. * * @param[in] rpc the owner of this utility object * @param[in] msgType the type of message (DnD/CP/FT) * @param[in] msgSrc source of the message (host/guest/controller) */ void RpcV4Util::Init(RpcBase *rpc, uint32 msgType, uint32 msgSrc) { ASSERT(rpc); mRpc = rpc; mMsgType = msgType; mMsgSrc = msgSrc; } /** * Serialize the clipboard item if there is one, then send the message to * destId. * * @param[in] params parameter list for the message * @param[in] clip the clipboard item. * * @return true on success, false otherwise. */ bool RpcV4Util::SendMsg(RpcParams *params, const CPClipboard *clip) { DynBuf buf; bool ret = false; ASSERT(params); if (!clip) { return SendMsg(params); } DynBuf_Init(&buf); if (!CPClipboard_Serialize(clip, &buf)) { LOG(0, ("%s: CPClipboard_Serialize failed.\n", __FUNCTION__)); goto exit; } ret = SendMsg(params, (const uint8 *)DynBuf_Get(&buf), (uint32)DynBuf_GetSize(&buf)); exit: DynBuf_Destroy(&buf); return ret; } /** * Serialize the message and send it to destId. * * @param[in] params parameter list for the message * @param[in] binary * @param[in] binarySize * * @return true on success, false otherwise. */ bool RpcV4Util::SendMsg(RpcParams *params, const uint8 *binary, uint32 binarySize) { bool ret = false; DnDCPMsgV4 *msgOut = NULL; DnDCPMsgV4 shortMsg; ASSERT(params); DnDCPMsgV4_Init(&shortMsg); if (binarySize > DND_CP_PACKET_MAX_PAYLOAD_SIZE_V4) { /* * For big message, all information should be cached in mBigMsgOut * because multiple packets and sends are needed. */ DnDCPMsgV4_Destroy(&mBigMsgOut); msgOut = &mBigMsgOut; } else { /* For short message, the temporary shortMsg is enough. */ msgOut = &shortMsg; } msgOut->addrId = params->addrId; msgOut->hdr.cmd = params->cmd; msgOut->hdr.type = mMsgType; msgOut->hdr.src = mMsgSrc; msgOut->hdr.sessionId = params->sessionId; msgOut->hdr.status = params->status; msgOut->hdr.param1 = params->optional.genericParams.param1; msgOut->hdr.param2 = params->optional.genericParams.param2; msgOut->hdr.param3 = params->optional.genericParams.param3; msgOut->hdr.param4 = params->optional.genericParams.param4; msgOut->hdr.param5 = params->optional.genericParams.param5; msgOut->hdr.param6 = params->optional.genericParams.param6; msgOut->hdr.binarySize = binarySize; msgOut->hdr.payloadOffset = 0; msgOut->hdr.payloadSize = 0; msgOut->binary = NULL; if (binarySize > 0) { msgOut->binary = (uint8 *)(Util_SafeMalloc(binarySize)); memcpy(msgOut->binary, binary,binarySize); } ret = SendMsg(msgOut); /* The mBigMsgOut is destroyed when the message sending was failed. */ if (!ret && msgOut == &mBigMsgOut) { DnDCPMsgV4_Destroy(&mBigMsgOut); } DnDCPMsgV4_Destroy(&shortMsg); return ret; } /** * Construct a DNDCP_CMD_PING message and send it to destId. * * @param[in] destId destination address id * @param[in] capability * * @return true on success, false otherwise. */ bool RpcV4Util::SendPingMsg(uint32 destId, uint32 capability) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = destId; params.cmd = DNDCP_CMD_PING; params.optional.version.major = mVersionMajor; params.optional.version.minor = mVersionMinor; params.optional.version.capability = capability; return SendMsg(¶ms); } /** * Construct a DNDCP_CMD_PING_REPLY message and send it to destId. * * @param[in] destId destination address id * @param[in] capability * * @return true on success, false otherwise. */ bool RpcV4Util::SendPingReplyMsg(uint32 destId, uint32 capability) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = destId; params.cmd = DNDCP_CMD_PING_REPLY; params.optional.version.major = mVersionMajor; params.optional.version.minor = mVersionMinor; params.optional.version.capability = capability; return SendMsg(¶ms); } /** * Construct a DNDCP_CMP_REPLY message and send it to destId. * * @param[in] destId destination address id * @param[in] cmd the command to be replied * @param[in] status * * @return true on success, false otherwise. */ bool RpcV4Util::SendCmdReplyMsg(uint32 destId, uint32 cmd, uint32 status) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = destId; params.cmd = DNDCP_CMP_REPLY; params.status = status; params.optional.replyToCmd.cmd = cmd; return SendMsg(¶ms); } /** * Construct a DNDCP_CMD_REQUEST_NEXT message and send it to mBigMsgIn.addrId. * This is used for big message receiving. After received a packet, receiver * side should send this message to ask for next piece of binary. * * @return true on success, false otherwise. */ bool RpcV4Util::RequestNextPacket(void) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = mBigMsgIn.addrId; params.cmd = DNDCP_CMD_REQUEST_NEXT; params.sessionId = mBigMsgIn.hdr.sessionId; params.optional.requestNextCmd.cmd = mBigMsgIn.hdr.cmd; params.optional.requestNextCmd.cmd = mBigMsgIn.hdr.binarySize; params.optional.requestNextCmd.cmd = mBigMsgIn.hdr.payloadOffset; return SendMsg(¶ms); } /** * Serialize a message and send it to msg->addrId. * * @param[in] msg the message to be serialized * * @return true on success, false otherwise. */ bool RpcV4Util::SendMsg(DnDCPMsgV4 *msg) { uint8 *packet = NULL; size_t packetSize = 0; bool ret = false; if (!DnDCPMsgV4_Serialize(msg, &packet, &packetSize)) { LOG(1, ("%s: DnDCPMsgV4_Serialize failed. \n", __FUNCTION__)); return false; } ret = mRpc->SendPacket(msg->addrId, packet, packetSize); if (ret == true) { FireRpcSentCallbacks(msg->hdr.cmd, msg->addrId, msg->hdr.sessionId); } free(packet); return ret; } /** * Callback from transport layer after received a packet from srcId. * * @param[in] srcId addressId where the packet is from * @param[in] packet * @param[in] packetSize */ void RpcV4Util::OnRecvPacket(uint32 srcId, const uint8 *packet, size_t packetSize) { DnDCPMsgPacketType packetType = DnDCPMsgV4_GetPacketType(packet, packetSize); switch (packetType) { case DND_CP_MSG_PACKET_TYPE_SINGLE: HandlePacket(srcId, packet, packetSize); break; case DND_CP_MSG_PACKET_TYPE_MULTIPLE_NEW: case DND_CP_MSG_PACKET_TYPE_MULTIPLE_CONTINUE: case DND_CP_MSG_PACKET_TYPE_MULTIPLE_END: HandlePacket(srcId, packet, packetSize, packetType); break; default: LOG(1, ("%s: invalid packet. \n", __FUNCTION__)); SendCmdReplyMsg(srcId, DNDCP_CMD_INVALID, DND_CP_MSG_STATUS_INVALID_PACKET); break; } } /** * Handle a packet for short message. * * @param[in] srcId addressId where the packet is from * @param[in] packet * @param[in] packetSize */ void RpcV4Util::HandlePacket(uint32 srcId, const uint8 *packet, size_t packetSize) { DnDCPMsgV4 msgIn; DnDCPMsgV4_Init(&msgIn); if (!DnDCPMsgV4_UnserializeSingle(&msgIn, packet, packetSize)) { LOG(1, ("%s: invalid packet. \n", __FUNCTION__)); SendCmdReplyMsg(srcId, DNDCP_CMD_INVALID, DND_CP_MSG_STATUS_INVALID_PACKET); return; } msgIn.addrId = srcId; HandleMsg(&msgIn); DnDCPMsgV4_Destroy(&msgIn); } /** * Handle a packet for long message. * * @param[in] srcId addressId where the packet is from * @param[in] packet * @param[in] packetSize * @param[in] packetType */ void RpcV4Util::HandlePacket(uint32 srcId, const uint8 *packet, size_t packetSize, DnDCPMsgPacketType packetType) { if (!DnDCPMsgV4_UnserializeMultiple(&mBigMsgIn, packet, packetSize)) { LOG(1, ("%s: invalid packet. \n", __FUNCTION__)); SendCmdReplyMsg(srcId, DNDCP_CMD_INVALID, DND_CP_MSG_STATUS_INVALID_PACKET); goto cleanup; } mBigMsgIn.addrId = srcId; /* * If there are multiple packets for the message, sends DNDCP_REQUEST_NEXT * back to sender to ask for next packet. */ if (DND_CP_MSG_PACKET_TYPE_MULTIPLE_END != packetType) { if (!RequestNextPacket()) { LOG(1, ("%s: RequestNextPacket failed.\n", __FUNCTION__)); goto cleanup; } /* * Do not destroy mBigMsgIn here because more packets are expected for * this message. */ return; } HandleMsg(&mBigMsgIn); cleanup: DnDCPMsgV4_Destroy(&mBigMsgIn); } /** * Handle a received message. * * @param[in] msgIn received message. */ void RpcV4Util::HandleMsg(DnDCPMsgV4 *msgIn) { RpcParams params; ASSERT(msgIn); if (DNDCP_CMD_REQUEST_NEXT == msgIn->hdr.cmd) { /* * This is for big buffer support. The receiver is asking for next piece * of data. For details about big buffer support, please refer to * https://wiki.eng.vmware.com/DnDVersion4Message#Binary_Buffer */ bool ret = SendMsg(&mBigMsgOut); if (!ret) { LOG(1, ("%s: SendMsg failed. \n", __FUNCTION__)); } /* * mBigMsgOut will be destroyed if SendMsg failed or whole message has * been sent. */ if (!ret || mBigMsgOut.hdr.payloadOffset == mBigMsgOut.hdr.binarySize) { DnDCPMsgV4_Destroy(&mBigMsgOut); } return; } params.addrId = msgIn->addrId; params.cmd = msgIn->hdr.cmd; params.sessionId = msgIn->hdr.sessionId; params.status = msgIn->hdr.status; params.optional.genericParams.param1 = msgIn->hdr.param1; params.optional.genericParams.param2 = msgIn->hdr.param2; params.optional.genericParams.param3 = msgIn->hdr.param3; params.optional.genericParams.param4 = msgIn->hdr.param4; params.optional.genericParams.param5 = msgIn->hdr.param5; params.optional.genericParams.param6 = msgIn->hdr.param6; mRpc->HandleMsg(¶ms, msgIn->binary, msgIn->hdr.binarySize); FireRpcReceivedCallbacks(msgIn->hdr.cmd, msgIn->addrId, msgIn->hdr.sessionId); } /** * Add an rpc received listener to the list. * * @param[in] listener class instance that implements DnDRpcListener * * @note generally, needs to be matched with a call to * RemoveRpcReceivedListener, but if not, cleanup happens in destructor. */ bool RpcV4Util::AddRpcReceivedListener(const DnDRpcListener *listener) { ASSERT(listener); DnDRpcReceivedListenerNode *node = (DnDRpcReceivedListenerNode *) Util_SafeMalloc(sizeof(DnDRpcReceivedListenerNode)); DblLnkLst_Init(&node->l); node->listener = listener; DblLnkLst_LinkLast(&mRpcReceivedListeners, &node->l); return true; } /** * Remove an rpc received listener from the list. * * @param[in] listener class instance that implements DnDRpcReceivedListener * * @note only the first instance of the listener will be removed. */ bool RpcV4Util::RemoveRpcReceivedListener(const DnDRpcListener *listener) { ASSERT(listener); DblLnkLst_Links *curr; DblLnkLst_ForEach(curr, &mRpcReceivedListeners) { DnDRpcReceivedListenerNode *p = DblLnkLst_Container(curr, DnDRpcReceivedListenerNode, l); if (p && p->listener == listener) { DblLnkLst_Unlink1(&p->l); free(p); return true; } } return false; } /** * Fire all registered rpc received callbacks. * * @param[in] cmd rpc command * @param[in] src src ID * @param[in] session session ID */ void RpcV4Util::FireRpcReceivedCallbacks(uint32 cmd, uint32 src, uint32 session) { DblLnkLst_Links *curr = NULL; DnDRpcReceivedListenerNode *p = NULL; DnDRpcListener *listener = NULL; DblLnkLst_ForEach(curr, &mRpcReceivedListeners) { p = DblLnkLst_Container(curr, DnDRpcReceivedListenerNode, l); if (p) { listener = const_cast(p->listener); listener->OnRpcReceived(cmd, src, session); } } } /** * Add an rpc sent listener to the list. * * @param[in] listener class instance that implements DnDRpcListener * * @note generally, needs to be matched with a call to * RemoveRpcSentListener, but if not, cleanup happens in destructor. */ bool RpcV4Util::AddRpcSentListener(const DnDRpcListener *listener) { ASSERT(listener); DnDRpcSentListenerNode *node = (DnDRpcSentListenerNode *) Util_SafeMalloc(sizeof *node); DblLnkLst_Init(&node->l); node->listener = listener; DblLnkLst_LinkLast(&mRpcSentListeners, &node->l); return true; } /** * Remove an rpc sent listener from the list. * * @param[in] listener class instance that implements DnDRpcSentListener * * @note only the first instance of the listener will be removed. */ bool RpcV4Util::RemoveRpcSentListener(const DnDRpcListener *listener) { ASSERT(listener); DblLnkLst_Links *curr; DblLnkLst_ForEach(curr, &mRpcSentListeners) { DnDRpcSentListenerNode *p = DblLnkLst_Container(curr, DnDRpcSentListenerNode, l); if (p && p->listener == listener) { DblLnkLst_Unlink1(&p->l); free(p); return true; } } return false; } /** * Fire all registered rpc sent callbacks. * * @param[in] cmd rpc command * @param[in] dest destination ID * @param[in] session session ID */ void RpcV4Util::FireRpcSentCallbacks(uint32 cmd, uint32 dest, uint32 session) { DblLnkLst_Links *curr = NULL; DblLnkLst_ForEach(curr, &mRpcSentListeners) { DnDRpcSentListenerNode *p = DblLnkLst_Container(curr, DnDRpcSentListenerNode, l); if (p && p->listener) { const_cast(p->listener)->OnRpcSent(cmd, dest, session); } } } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/dndRpcV3.hh0000644765153500003110000000741312220061556023561 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file dndRpcV3.hh -- * * Rpc layer object for DnD version 3. */ #ifndef DND_RPC_V3_HH #define DND_RPC_V3_HH #include #include "dndRpc.hh" #include "dndCPTransport.h" #include "rpcV3Util.hpp" extern "C" { #include "dnd.h" #include "dndMsg.h" #include "vmware/tools/guestrpc.h" } class LIB_EXPORT DnDRpcV3 : public DnDRpc, public sigc::trackable { public: DnDRpcV3(DnDCPTransport *transport); virtual ~DnDRpcV3(void); virtual void Init(void); virtual void SendPing(uint32 caps) {}; /* DnD source. */ virtual bool SrcDragBeginDone(uint32 sessionId); virtual bool SrcDrop(uint32 sessionId, int32 x, int32 y); virtual bool SrcDropDone(uint32 sessionId, const uint8 *stagingDirCP, uint32 sz); virtual bool SrcPrivDragEnter(uint32 sessionId); virtual bool SrcPrivDragLeave(uint32 sessionId, int32 x, int32 y); virtual bool SrcPrivDrop(uint32 sessionId, int32 x, int32 y); virtual bool SrcCancel(uint32 sessionId) { return true; }; /* DnD destination. */ virtual bool DestDragEnter(uint32 sessionId, const CPClipboard *clip); virtual bool DestSendClip(uint32 sessionId, const CPClipboard *clip); virtual bool DestDragLeave(uint32 sessionId, int32 x, int32 y); virtual bool DestDrop(uint32 sessionId, int32 x, int32 y); virtual bool DestCancel(uint32 sessionId) { return true; }; /* Common. */ virtual bool UpdateFeedback(uint32 sessionId, DND_DROPEFFECT feedback); virtual bool MoveMouse(uint32 sessionId, int32 x, int32 y); virtual bool QueryExiting(uint32 sessionId, int32 x, int32 y); virtual bool DragNotPending(uint32 sessionId); virtual bool UpdateUnityDetWnd(uint32 sessionId, bool show, uint32 unityWndId); virtual bool RequestFiles(uint32 sessionId); virtual bool SendFilesDone(uint32 sessionId, bool success, const uint8 *stagingDirCP, uint32 sz); virtual bool GetFilesDone(uint32 sessionId, bool success); virtual void HandleMsg(RpcParams *params, const uint8 *binary, uint32 binarySize); virtual bool SendPacket(uint32 destId, const uint8 *packet, size_t length); virtual void OnRecvPacket(uint32 srcId, const uint8 *packet, size_t packetSize); private: bool SrcDragEnterDone(int32 x, int32 y); DnDCPTransport *mTransport; TransportInterfaceType mTransportInterface; CPClipboard mClipboard; RpcV3Util mUtil; }; #endif // DND_RPC_V3_HH open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/guestFileTransfer.hh0000644765153500003110000000301212220061556025561 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @guestFileTransfer.hh -- * * File transfer object for guest. */ #ifndef GUEST_FILE_TRANSFER_HH #define GUEST_FILE_TRANSFER_HH #include #include "fileTransferRpc.hh" #include "dndCPTransport.h" extern "C" { #include "hgfsServerManager.h" } class GuestFileTransfer : public sigc::trackable { public: GuestFileTransfer(DnDCPTransport *transport); ~GuestFileTransfer(void); private: void OnRpcRecvHgfsPacket(uint32 sessionId, const uint8 *packet, size_t packetSize); FileTransferRpc *mRpc; HgfsServerMgrData mHgfsServerMgrData; }; #endif // GUEST_FILE_TRANSFER_HH open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/guestDnD.hh0000644765153500003110000001342312220061556023651 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @guestDnD.hh -- * * DnD common layer classes for guest. */ #ifndef GUEST_DND_HH #define GUEST_DND_HH #include #include "dndRpcV4.hh" #include "guestFileTransfer.hh" #include "capsProvider.h" #include extern "C" { #include "dnd.h" #include "vmware/tools/plugin.h" } enum GUEST_DND_STATE { GUEST_DND_INVALID = 0, GUEST_DND_READY, /* As destination. */ GUEST_DND_QUERY_EXITING, GUEST_DND_DEST_DRAGGING, /* In private dragging mode. */ GUEST_DND_PRIV_DRAGGING, /* As source. */ GUEST_DND_SRC_DRAGBEGIN_PENDING, GUEST_DND_SRC_CANCEL_PENDING, GUEST_DND_SRC_DRAGGING, }; class GuestDnDSrc; class GuestDnDDest; class GuestDnDMgr : public sigc::trackable, public CapsProvider { public: GuestDnDMgr(DnDCPTransport *transport, ToolsAppCtx *ctx); ~GuestDnDMgr(void); sigc::signal moveMouseChanged; sigc::signal updateDetWndChanged; sigc::signal updateUnityDetWndChanged; sigc::signal stateChanged; sigc::signal srcDragBeginChanged; sigc::signal srcDropChanged; sigc::signal srcCancelChanged; sigc::signal getFilesDoneChanged; sigc::signal destCancelChanged; sigc::signal privDropChanged; sigc::signal destMoveDetWndToMousePosChanged; GuestDnDSrc *GetDnDSrc(void) { return mSrc; } GuestDnDDest *GetDnDDest(void) { return mDest; } /* Common DnD layer API exposed to UI (all platforms) for DnD source. */ void SrcUIDragBeginDone(void); void SrcUIUpdateFeedback(DND_DROPEFFECT feedback); void DestUIDragEnter(const CPClipboard *clip); DnDRpc *GetRpc(void) { return mRpc; } GUEST_DND_STATE GetState(void) { return mDnDState; } void SetState(GUEST_DND_STATE state); void UpdateDetWnd(bool show, int32 x, int32 y); void HideDetWnd(void) { UpdateDetWnd(false, 0, 0); } void ShowDetWnd(int32 x, int32 y) { UpdateDetWnd(true, x, y); } void UnityDnDDetTimeout(void); uint32 GetSessionId(void) { return mSessionId; } void SetSessionId(uint32 id) { mSessionId = id; } void ResetDnD(void); void DelayHideDetWnd(void); void SetHideDetWndTimer(GSource *gs) { mHideDetWndTimer = gs; } void UngrabTimeout(void); void RemoveUngrabTimeout(void); bool IsDnDAllowed (void) { return mDnDAllowed; } void SetDnDAllowed(bool isDnDAllowed) { mDnDAllowed = isDnDAllowed;} void VmxDnDVersionChanged(uint32 version); bool IsDragEnterAllowed(void); Bool CheckCapability(uint32 capsRequest); private: void OnRpcSrcDragBegin(uint32 sessionId, const CPClipboard *clip); void OnRpcQueryExiting(uint32 sessionId, int32 x, int32 y); void OnRpcUpdateUnityDetWnd(uint32 sessionId, bool show, uint32 unityWndId); void OnRpcMoveMouse(uint32 sessionId, int32 x, int32 y); void OnPingReply(uint32 capabilities); GuestDnDSrc *mSrc; GuestDnDDest *mDest; DnDRpc *mRpc; GuestFileTransfer *mFileTransfer; GUEST_DND_STATE mDnDState; uint32 mSessionId; GSource *mHideDetWndTimer; GSource *mUnityDnDDetTimeout; GSource *mUngrabTimeout; ToolsAppCtx *mToolsAppCtx; bool mDnDAllowed; uint32 mVmxDnDVersion; DnDCPTransport *mDnDTransport; uint32 mCapabilities; }; class GuestDnDSrc : public sigc::trackable { public: GuestDnDSrc(GuestDnDMgr *mgr); ~GuestDnDSrc(void); /* Common DnD layer API exposed to UI (all platforms) for DnD source. */ void UIDragBeginDone(void); void UIUpdateFeedback(DND_DROPEFFECT feedback); void OnRpcDragBegin(const CPClipboard *clip); private: /* Callbacks from rpc for DnD source. */ void OnRpcUpdateMouse(uint32 sessionId, int32 x, int32 y); void OnRpcDrop(uint32 sessionId, int32 x, int32 y); void OnRpcCancel(uint32 sessionId); void OnRpcGetFilesDone(uint32 sessionId, bool success, const uint8 *stagingDirCP, uint32 sz); const std::string& SetupDestDir(const std::string &destDir); GuestDnDMgr *mMgr; DnDRpc *mRpc; std::string mStagingDir; CPClipboard mClipboard; }; class GuestDnDDest : public sigc::trackable { public: GuestDnDDest(GuestDnDMgr *mgr); ~GuestDnDDest(void); /* Common DnD layer API exposed to UI (all platforms) for DnD destination. */ void UIDragEnter(const CPClipboard *clip); private: /* Callbacks from rpc for DnD destination. */ void OnRpcPrivDragEnter(uint32 sessionId); void OnRpcPrivDragLeave(uint32 sessionId, int32 x, int32 y); void OnRpcPrivDrop(uint32 sessionId, int32 x, int32 y); void OnRpcDrop(uint32 sessionId, int32 x, int32 y); void OnRpcCancel(uint32 sessionId); GuestDnDMgr *mMgr; DnDRpc *mRpc; CPClipboard mClipboard; }; #endif // GUEST_DND_HH open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/copyPasteRpcV3.cc0000644765153500003110000001711612220061556024752 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * CopyPasteRpcV3.cc -- * * Implementation of the CopyPasteRpcV3 interface. */ #include "copyPasteRpcV3.hh" extern "C" { #include "dndMsg.h" #include "debug.h" #include "dndClipboard.h" } /** * Constructor. * * @param[in] transport for sending packets. */ CopyPasteRpcV3::CopyPasteRpcV3(DnDCPTransport *transport) : mTransport(transport), mTransportInterface(TRANSPORT_GUEST_CONTROLLER_CP) { ASSERT(mTransport); mUtil.Init(this); } /** * Destructor. */ CopyPasteRpcV3::~CopyPasteRpcV3(void) { } /** * Init. */ void CopyPasteRpcV3::Init(void) { Debug("%s: entering.\n", __FUNCTION__); ASSERT(mTransport); mTransport->RegisterRpc(this, mTransportInterface); } /** * Not needed for version 3. * * @param[ignored] caps capabilities mask */ void CopyPasteRpcV3::SendPing(uint32 caps) { Debug("%s: entering.\n", __FUNCTION__); } /** * Not needed for version 3. * * @param[ignored] sessionId active session id the controller assigned * @param[ignored] isActive active or passive CopyPaste * * @return always true. */ bool CopyPasteRpcV3::SrcRequestClip(uint32 sessionId, bool isActive) { Debug("%s: entering.\n", __FUNCTION__); return true; } /** * Send cmd CP_GH_GET_CLIPBOARD_DONE to controller. * * @param[ignored] sessionId active session id the controller assigned earlier. * @param[ignored] isActive active or passive CopyPaste * @param[in] clip cross-platform clipboard data. * * @return true on success, false otherwise. */ bool CopyPasteRpcV3::DestSendClip(uint32 sessionId, bool isActive, const CPClipboard* clip) { Debug("%s: entering.\n", __FUNCTION__); return mUtil.SendMsg(CP_GH_GET_CLIPBOARD_DONE, clip); } /** * Send cmd CP_HG_START_FILE_COPY to controller. * * @param[ignored] sessionId active session id the controller assigned earlier. * @param[in] stagingDirCP staging dir name in cross-platform format * @param[in] sz the staging dir name size in bytes * * @return true on success, false otherwise. */ bool CopyPasteRpcV3::RequestFiles(uint32 sessionId, const uint8 *stagingDirCP, uint32 sz) { DnDMsg msg; bool ret = false; Debug("%s: entering.\n", __FUNCTION__); DnDMsg_Init(&msg); /* Construct msg with both cmd CP_HG_START_FILE_COPY and stagingDirCP. */ DnDMsg_SetCmd(&msg, CP_HG_START_FILE_COPY); if (!DnDMsg_AppendArg(&msg, (void *)stagingDirCP, sz)) { Debug("%s: DnDMsg_AppendData failed.\n", __FUNCTION__); goto exit; } ret = mUtil.SendMsg(&msg); exit: DnDMsg_Destroy(&msg); return ret; } /** * Not needed for version 3. * * @param[ignored] sessionId active session id the controller assigned earlier. * @param[ignored] success the file transfer operation was successful or not * @param[ignored] stagingDirCP staging dir name in cross-platform format * @param[ignored] sz the staging dir name size in bytes * * @return always true. */ bool CopyPasteRpcV3::SendFilesDone(uint32 sessionId, bool success, const uint8 *stagingDirCP, uint32 sz) { Debug("%s: entering.\n", __FUNCTION__); return true; } /** * Not needed for version 3. * * @param[ignored] sessionId active session id the controller assigned earlier. * @param[ignored] success the file transfer operation was successful or not * * @return always true. */ bool CopyPasteRpcV3::GetFilesDone(uint32 sessionId, bool success) { Debug("%s: entering.\n", __FUNCTION__); return true; } /** * Send a packet. * * @param[in] destId destination address id. * @param[in] packet * @param[in] length packet length in byte * * @return true on success, false otherwise. */ bool CopyPasteRpcV3::SendPacket(uint32 destId, const uint8 *packet, size_t length) { Debug("%s: entering.\n", __FUNCTION__); return mTransport->SendPacket(destId, mTransportInterface, packet, length); } /** * Handle a received message. * * @param[in] params parameter list for received message. * @param[in] binary attached binary data for received message. * @param[in] binarySize in byte */ void CopyPasteRpcV3::HandleMsg(RpcParams *params, const uint8 *binary, uint32 binarySize) { DnDMsg msg; DnDMsgErr ret; DynBuf *buf = NULL; DnDMsg_Init(&msg); ret = DnDMsg_UnserializeHeader(&msg, (void *)binary, binarySize); if (DNDMSG_SUCCESS != ret) { Debug("%s: DnDMsg_UnserializeHeader failed %d\n", __FUNCTION__, ret); goto exit; } ret = DnDMsg_UnserializeArgs(&msg, (void *)(binary + DNDMSG_HEADERSIZE_V3), binarySize - DNDMSG_HEADERSIZE_V3); if (DNDMSG_SUCCESS != ret) { Debug("%s: DnDMsg_UnserializeArgs failed with %d\n", __FUNCTION__, ret); goto exit; } Debug("%s: Got %d, binary size %d.\n", __FUNCTION__, DnDMsg_GetCmd(&msg), binarySize); /* * Translate command and emit signal. Session Id 1 is used because version * 3 command does not provide session Id. */ switch (DnDMsg_GetCmd(&msg)) { case CP_HG_SET_CLIPBOARD: { CPClipboard clip; /* Unserialize clipboard data for the command. */ buf = DnDMsg_GetArg(&msg, 0); if (!CPClipboard_Unserialize(&clip, DynBuf_Get(buf), DynBuf_GetSize(buf))) { Debug("%s: CPClipboard_Unserialize failed.\n", __FUNCTION__); goto exit; } srcRecvClipChanged.emit(1, false, &clip); CPClipboard_Destroy(&clip); break; } case CP_HG_FILE_COPY_DONE: { bool success = false; buf = DnDMsg_GetArg(&msg, 0); if (sizeof success == DynBuf_GetSize(buf)) { memcpy(&success, DynBuf_Get(buf), DynBuf_GetSize(buf)); } getFilesDoneChanged.emit(1, success, NULL, 0); break; } case CP_GH_GET_CLIPBOARD: { destRequestClipChanged.emit(1, false); break; } default: Debug("%s: got unsupported new command %d.\n", __FUNCTION__, DnDMsg_GetCmd(&msg)); } exit: DnDMsg_Destroy(&msg); } /** * Callback from transport layer after received a packet from srcId. * * @param[in] srcId addressId where the packet is from * @param[in] packet * @param[in] packetSize */ void CopyPasteRpcV3::OnRecvPacket(uint32 srcId, const uint8 *packet, size_t packetSize) { Debug("%s: entering.\n", __FUNCTION__); mUtil.OnRecvPacket(srcId, packet, packetSize); } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/copyPasteRpcV3.hh0000644765153500003110000000523612220061556024764 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file copyPasteRpcV3.hh -- * * Rpc layer object for CopyPaste version 3. */ #ifndef COPY_PASTE_RPC_V3_HH #define COPY_PASTE_RPC_V3_HH #include #include "copyPasteRpc.hh" #include "dndCPTransport.h" #include "rpcV3Util.hpp" extern "C" { #include "vmware/tools/guestrpc.h" #include "dnd.h" #include "dndMsg.h" } class CopyPasteRpcV3 : public CopyPasteRpc, public sigc::trackable { public: CopyPasteRpcV3(DnDCPTransport *transport); virtual ~CopyPasteRpcV3(void); virtual void Init(void); virtual void SendPing(uint32 caps); /* CopyPaste Rpc functions. */ virtual bool SrcRequestClip(uint32 sessionId, bool isActive); virtual bool DestSendClip(uint32 sessionId, bool isActive, const CPClipboard* clip); virtual bool RequestFiles(uint32 sessionId, const uint8 *stagingDirCP, uint32 sz); virtual bool SendFilesDone(uint32 sessionId, bool success, const uint8 *stagingDirCP, uint32 sz); virtual bool GetFilesDone(uint32 sessionId, bool success); virtual void HandleMsg(RpcParams *params, const uint8 *binary, uint32 binarySize); virtual bool SendPacket(uint32 destId, const uint8 *packet, size_t length); virtual void OnRecvPacket(uint32 srcId, const uint8 *packet, size_t packetSize); private: DnDCPTransport *mTransport; TransportInterfaceType mTransportInterface; RpcV3Util mUtil; }; #endif // COPY_PASTE_RPC_V3_HH open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/guestDnDMgr.cc0000644765153500003110000003743612220061556024317 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @guestDnDMgr.cc -- * * Implementation of common layer GuestDnDMgr object for guest. */ #include "guestDnD.hh" #include "dndRpcV4.hh" #include "dndRpcV3.hh" #include "guestDnDCPMgr.hh" extern "C" { #include "debug.h" } #define UNGRAB_TIMEOUT 500 // 0.5s #define HIDE_DET_WND_TIMER 500 // 0.5s #define UNITY_DND_DET_TIMEOUT 500 // 0.5s /** * Callback for DnDUngrab timeout. This will be called if there is no pending * GH DnD when user dragged leaving the guest. * * @param[in] clientData * * @return FALSE always */ static gboolean DnDUngrabTimeout(void *clientData) { ASSERT(clientData); GuestDnDMgr *dnd = (GuestDnDMgr *)clientData; /* Call actual callback. */ dnd->UngrabTimeout(); return FALSE; } /** * Callback for HideDetWndTimer. * * @param[in] clientData * * @return FALSE always */ static gboolean DnDHideDetWndTimer(void *clientData) { Debug("%s: entering\n", __FUNCTION__); ASSERT(clientData); GuestDnDMgr *dnd = (GuestDnDMgr *)clientData; dnd->SetHideDetWndTimer(NULL); dnd->HideDetWnd(); return FALSE; } /** * Callback for UnityDnDDetTimeout. * * @param[in] clientData * * @return FALSE always */ static gboolean DnDUnityDetTimeout(void *clientData) { Debug("%s: entering\n", __FUNCTION__); ASSERT(clientData); GuestDnDMgr *dnd = (GuestDnDMgr *)clientData; dnd->UnityDnDDetTimeout(); return FALSE; } /** * Constructor. * * @param[in] transport for sending/receiving packets. * @param[in] eventQueue for event management */ GuestDnDMgr::GuestDnDMgr(DnDCPTransport *transport, ToolsAppCtx *ctx) : mSrc(NULL), mDest(NULL), mRpc(NULL), mFileTransfer(NULL), mDnDState(GUEST_DND_READY), mSessionId(0), mHideDetWndTimer(NULL), mUnityDnDDetTimeout(NULL), mUngrabTimeout(NULL), mToolsAppCtx(ctx), mDnDAllowed(false), mDnDTransport(transport), mCapabilities(0xffffffff) { ASSERT(transport); ASSERT(mToolsAppCtx); } /** * Destructor. */ GuestDnDMgr::~GuestDnDMgr(void) { delete mRpc; mRpc = NULL; /* Remove untriggered timers. */ if (mHideDetWndTimer) { g_source_destroy(mHideDetWndTimer); mHideDetWndTimer = NULL; } if (mUnityDnDDetTimeout) { g_source_destroy(mUnityDnDDetTimeout); mUnityDnDDetTimeout = NULL; } RemoveUngrabTimeout(); } /** * Reset state machine and session id. Delete mSrc and mDest. */ void GuestDnDMgr::ResetDnD(void) { Debug("%s: state %d, session id %d before reset\n", __FUNCTION__, mDnDState, mSessionId); if (mSrc) { srcCancelChanged.emit(); DelayHideDetWnd(); delete mSrc; mSrc = NULL; } if (mDest) { DelayHideDetWnd(); RemoveUngrabTimeout(); destCancelChanged.emit(); delete mDest; mDest = NULL; } SetState(GUEST_DND_READY); Debug("%s: change to state %d, session id %d\n", __FUNCTION__, mDnDState, mSessionId); } /** * Guest UI got dragBeginDone. Wrapper for mSrc->UIDragBeginDone. */ void GuestDnDMgr::SrcUIDragBeginDone(void) { if (mSrc) { mSrc->UIDragBeginDone(); } else { Debug("%s: mSrc is NULL\n", __FUNCTION__); } } /** * Guest UI got DnD feedback. Wrapper for mSrc->UIUpdateFeedback. * * @param[in] feedback */ void GuestDnDMgr::SrcUIUpdateFeedback(DND_DROPEFFECT feedback) { if (mSrc) { mSrc->UIUpdateFeedback(feedback); } else { Debug("%s: mSrc is NULL\n", __FUNCTION__); } } /** * Guest UI got dragEnter with valid data. Create mDest if the state machine * is ready. * * @param[in] clip cross-platform clipboard data. */ void GuestDnDMgr::DestUIDragEnter(const CPClipboard *clip) { Debug("%s: enter\n", __FUNCTION__); /* Remove untriggered ungrab timer. */ RemoveUngrabTimeout(); if (GUEST_DND_SRC_DRAGGING == mDnDState || GUEST_DND_DEST_DRAGGING == mDnDState) { /* * In GH DnD case, if DnD already happened, user may drag back into guest * VM and drag into the detection window again, and trigger the * DragEnter. In this case, ignore the DragEnter. * * In HG DnD case, if DnD already happened, user may also drag into the * detection window again. The DragEnter should also be ignored. */ return; } /* * In Unity mode, there is no QueryPendingDrag signal, so may get called * with state READY. */ if (mDnDState != GUEST_DND_QUERY_EXITING && mDnDState != GUEST_DND_READY) { Debug("%s: Bad state: %d, reset\n", __FUNCTION__, mDnDState); ResetDnD(); return; } /* Remove untriggered ungrab timer. */ if (mUngrabTimeout) { g_source_destroy(mUngrabTimeout); mUngrabTimeout = NULL; } if (mDest) { Debug("%s: mDest is not NULL\n", __FUNCTION__); delete mDest; mDest = NULL; } ASSERT(clip); mDest = new GuestDnDDest(this); mDest->UIDragEnter(clip); } /** * Got srcDragBegin from rpc with valid data. Create mSrc if the state machine * is ready. * * @param[in] sessionId active DnD session id * @param[in] capability controller capability * @param[in] clip cross-platform clipboard data. */ void GuestDnDMgr::OnRpcSrcDragBegin(uint32 sessionId, const CPClipboard *clip) { Debug("%s: enter\n", __FUNCTION__); if (!mDnDAllowed) { Debug("%s: DnD is not allowed.\n", __FUNCTION__); return; } if (GUEST_DND_READY != mDnDState) { Debug("%s: Bad state: %d, reset\n", __FUNCTION__, mDnDState); ResetDnD(); return; } if (mSrc) { Debug("%s: mSrc is not NULL\n", __FUNCTION__); delete mSrc; mSrc = NULL; } mSessionId = sessionId; Debug("%s: change sessionId to %d\n", __FUNCTION__, mSessionId); ASSERT(clip); mSrc = new GuestDnDSrc(this); mSrc->OnRpcDragBegin(clip); } /** * Got queryExiting from rpc. Show the detection window on (x, y) to try to * detect any pending GH DnD. * * @param[in] sessionId active DnD session id * @param[in] x detection window position x. * @param[in] y detection window position y. */ void GuestDnDMgr::OnRpcQueryExiting(uint32 sessionId, int32 x, int32 y) { if (!mDnDAllowed) { Debug("%s: DnD is not allowed.\n", __FUNCTION__); return; } if (GUEST_DND_READY != mDnDState) { /* Reset DnD for any wrong state. */ Debug("%s: Bad state: %d\n", __FUNCTION__, mDnDState); ResetDnD(); return; } /* Show detection window to detect pending GH DnD. */ ShowDetWnd(x, y); mSessionId = sessionId; SetState(GUEST_DND_QUERY_EXITING); Debug("%s: state changed to QUERY_EXITING, session id changed to %d\n", __FUNCTION__, mSessionId); /* * Add event to fire and hide our window if a DnD is not pending. Note that * this is here in case the drag isn't picked up by our drag detection window * for some reason. */ if (NULL == mUngrabTimeout) { Debug("%s: adding UngrabTimeout\n", __FUNCTION__); mUngrabTimeout = g_timeout_source_new(UNGRAB_TIMEOUT); VMTOOLSAPP_ATTACH_SOURCE(mToolsAppCtx, mUngrabTimeout, DnDUngrabTimeout, this, NULL); g_source_unref(mUngrabTimeout); } } /** * Callback for DnDUngrab timeout. This will be called if there is no pending * GH DnD when user dragged leaving the guest. Send dragNotPending command to * controller and reset local state machine. */ void GuestDnDMgr::UngrabTimeout(void) { mUngrabTimeout = NULL; if (mDnDState != GUEST_DND_QUERY_EXITING) { /* Reset DnD for any wrong state. */ Debug("%s: Bad state: %d\n", __FUNCTION__, mDnDState); ResetDnD(); return; } ASSERT(mRpc); mRpc->DragNotPending(mSessionId); HideDetWnd(); SetState(GUEST_DND_READY); Debug("%s: state changed to GUEST_DND_READY, session id changed to %d\n", __FUNCTION__, mSessionId); } /** * This callback is trigged when a user clicks into any Unity window or just * releases the mouse button. Either show the full-screen detection window * right after the Unity window, or hide the detection window. * * @param[in] sessionId Active session id the controller assigned earlier. * @param[in] show Show or hide unity DnD detection window. * @param[in] unityWndId The unity window id. */ void GuestDnDMgr::OnRpcUpdateUnityDetWnd(uint32 sessionId, bool show, uint32 unityWndId) { if (show && mDnDState != GUEST_DND_READY) { /* * Reset DnD for any wrong state. Only do this when host asked to * show the window. */ Debug("%s: Bad state: %d\n", __FUNCTION__, mDnDState); ResetDnD(); return; } if (mUnityDnDDetTimeout) { g_source_destroy(mUnityDnDDetTimeout); mUnityDnDDetTimeout = NULL; } if (show) { /* * When showing full screen window, also show the small top-most * window at (1, 1). After detected a GH DnD, the full screen * window will be hidden to avoid blocking other windows. So use * this window to accept drop in cancel case. */ UpdateDetWnd(show, 1, 1); mUnityDnDDetTimeout = g_timeout_source_new(UNITY_DND_DET_TIMEOUT); VMTOOLSAPP_ATTACH_SOURCE(mToolsAppCtx, mUnityDnDDetTimeout, DnDUnityDetTimeout, this, NULL); g_source_unref(mUnityDnDDetTimeout); mSessionId = sessionId; Debug("%s: change sessionId to %d\n", __FUNCTION__, mSessionId); } else { /* * If there is active DnD, the regular detection window will be hidden * after DnD is done. */ if (mDnDState == GUEST_DND_READY) { UpdateDetWnd(false, 0, 0); } } /* Show/hide the full screen detection window. */ updateUnityDetWndChanged.emit(show, unityWndId, false); Debug("%s: updating Unity detection window, show %d, id %u\n", __FUNCTION__, show, unityWndId); } /** * Can not detect pending GH DnD within UNITY_DND_DET_TIMEOUT, put the full * screen detection window to bottom most. */ void GuestDnDMgr::UnityDnDDetTimeout(void) { mUnityDnDDetTimeout = NULL; updateUnityDetWndChanged.emit(true, 0, true); } /** * Got moveMouse from rpc. Ask UI to update mouse position. * * @param[in] sessionId active DnD session id * @param[in] x mouse position x. * @param[in] y mouse position y. * @param[in] isButtonDown */ void GuestDnDMgr::OnRpcMoveMouse(uint32 sessionId, int32 x, int32 y) { if (GUEST_DND_SRC_DRAGGING != mDnDState && GUEST_DND_PRIV_DRAGGING != mDnDState) { Debug("%s: not in valid state %d, ignoring\n", __FUNCTION__, mDnDState); return; } Debug("%s: move to %d, %d\n", __FUNCTION__, x, y); moveMouseChanged.emit(x, y); } /** * Update the detection window. * * @param[in] show show/hide the detection window * @param[in] x detection window position x. * @param[in] y detection window position y. */ void GuestDnDMgr::UpdateDetWnd(bool show, int32 x, int32 y) { if (mHideDetWndTimer) { g_source_destroy(mHideDetWndTimer); mHideDetWndTimer = NULL; } Debug("%s: %s window at %d, %d\n", __FUNCTION__, show ? "show" : "hide", x, y); updateDetWndChanged.emit(show, x, y); } /** * Update the detection window. * * @param[in] show show/hide the detection window * @param[in] x detection window position x. * @param[in] y detection window position y. */ void GuestDnDMgr::DelayHideDetWnd(void) { if (NULL == mHideDetWndTimer) { Debug("%s: add timer to hide detection window.\n", __FUNCTION__); mHideDetWndTimer = g_timeout_source_new(HIDE_DET_WND_TIMER); VMTOOLSAPP_ATTACH_SOURCE(mToolsAppCtx, mHideDetWndTimer, DnDHideDetWndTimer, this, NULL); g_source_unref(mHideDetWndTimer); } else { Debug("%s: mHideDetWndTimer is not NULL, quit.\n", __FUNCTION__); } } /** * Remove any pending mUngrabTimeout. */ void GuestDnDMgr::RemoveUngrabTimeout(void) { if (mUngrabTimeout) { g_source_destroy(mUngrabTimeout); mUngrabTimeout = NULL; } } /** * Set state machine state. * * @param[in] state */ void GuestDnDMgr::SetState(GUEST_DND_STATE state) { mDnDState = state; stateChanged.emit(state); if (GUEST_DND_READY == state) { /* Reset sessionId if the state is reset. */ SetSessionId(0); } } /** * Check if DragEnter is allowed. * * @return true if DragEnter is allowed, false otherwise. */ bool GuestDnDMgr::IsDragEnterAllowed(void) { /* * Right after any DnD is finished, there may be some unexpected * DragEnter from UI, and may disturb our state machine. The * mHideDetWndTimer will only be valid for 0.5 second after each * DnD, and during this time UI DragEnter is not allowed. */ return mHideDetWndTimer == NULL; } /** * Handle version change in VMX. * * @param[in] version negotiated DnD version. */ void GuestDnDMgr::VmxDnDVersionChanged(uint32 version) { g_debug("GuestDnDMgr::%s: enter version %d\n", __FUNCTION__, version); ASSERT(version >= 3); /* Remove untriggered timers. */ if (mHideDetWndTimer) { g_source_destroy(mHideDetWndTimer); mHideDetWndTimer = NULL; } if (mRpc) { delete mRpc; } switch(version) { case 4: mRpc = new DnDRpcV4(mDnDTransport); break; case 3: mRpc = new DnDRpcV3(mDnDTransport); break; default: g_debug("%s: unsupported DnD version\n", __FUNCTION__); break; } if (mRpc) { mRpc->pingReplyChanged.connect( sigc::mem_fun(this, &GuestDnDMgr::OnPingReply)); mRpc->srcDragBeginChanged.connect( sigc::mem_fun(this, &GuestDnDMgr::OnRpcSrcDragBegin)); mRpc->queryExitingChanged.connect( sigc::mem_fun(this, &GuestDnDMgr::OnRpcQueryExiting)); mRpc->updateUnityDetWndChanged.connect( sigc::mem_fun(this, &GuestDnDMgr::OnRpcUpdateUnityDetWnd)); mRpc->moveMouseChanged.connect( sigc::mem_fun(this, &GuestDnDMgr::OnRpcMoveMouse)); mRpc->Init(); mRpc->SendPing(GuestDnDCPMgr::GetInstance()->GetCaps() & (DND_CP_CAP_DND | DND_CP_CAP_FORMATS_DND | DND_CP_CAP_VALID)); } ResetDnD(); } /** * Check if a request is allowed based on resolved capabilities. * * @param[in] capsRequest requested capabilities. * * @return TRUE if allowed, FALSE otherwise. */ Bool GuestDnDMgr::CheckCapability(uint32 capsRequest) { Bool allowed = FALSE; if ((mCapabilities & capsRequest) == capsRequest) { allowed = TRUE; } return allowed; } /** * Got pingReplyChanged message. Update capabilities. * * @param[in] capability modified capabilities from VMX controller. */ void GuestDnDMgr::OnPingReply(uint32 capabilities) { Debug("%s: dnd ping reply caps are %x\n", __FUNCTION__, capabilities); mCapabilities = capabilities; } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/guestCopyPasteDest.cc0000644765153500003110000000430012220061556025713 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @guestCopyPasteDest.cc -- * * Implementation of common layer GuestCopyPasteDest object for guest. */ #include "guestCopyPaste.hh" extern "C" { #include "dndClipboard.h" #include "debug.h" } /** * Constructor. * * @param[in] mgr guest CP manager */ GuestCopyPasteDest::GuestCopyPasteDest(GuestCopyPasteMgr *mgr) : mMgr(mgr) { ASSERT(mMgr); } /** * Got valid clipboard data from UI. Send sendClip cmd to controller. * * @param[in] clip cross-platform clipboard data. */ void GuestCopyPasteDest::UISendClip(const CPClipboard *clip) { ASSERT(clip); Debug("%s: state is %d\n", __FUNCTION__, mMgr->GetState()); if (mMgr->GetState() != GUEST_CP_READY) { /* Reset DnD for any wrong state. */ Debug("%s: Bad state: %d\n", __FUNCTION__, mMgr->GetState()); goto error; } if (!mMgr->GetRpc()->DestSendClip(mMgr->GetSessionId(), mIsActive, clip)) { Debug("%s: DestSendClip failed\n", __FUNCTION__); goto error; } return; error: mMgr->ResetCopyPaste(); } /** * Host is asking for clipboard data. Emit destRequestClipChanged signal. * * @param[in] isActive active or passive CopyPaste. */ void GuestCopyPasteDest::OnRpcRequestClip(bool isActive) { mIsActive = isActive; Debug("%s: state is %d\n", __FUNCTION__, mMgr->GetState()); mMgr->destRequestClipChanged.emit(); } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndGuest/fileTransferRpcV4.cc0000644765153500003110000001207312220061556025425 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @fileTransferRpcV4.cc -- * * Implementation of common layer file transfer rpc version 4 object. */ #include "fileTransferRpcV4.hh" #include "dndCPTransport.h" extern "C" { #include "dndMsg.h" #include "dndCPMsgV4.h" #include "hgfsServer.h" #include "str.h" #include "util.h" #if defined VMX86_TOOLS #include "debug.h" #define LOG(level, msg) (Debug msg) #else #define LOGLEVEL_MODULE dnd #include "loglevel_user.h" #endif } /** * Create transport object and register callback. * * @param[in] transport for sending/receiving messages. */ FileTransferRpcV4::FileTransferRpcV4(DnDCPTransport *transport) : mTransport(transport), #ifdef VMX86_TOOLS mTransportInterface(TRANSPORT_GUEST_CONTROLLER_FT) #else mTransportInterface(TRANSPORT_HOST_CONTROLLER_FT) #endif { ASSERT(mTransport); #ifdef VMX86_TOOLS mUtil.Init(this, DND_CP_MSG_SRC_GUEST, DND_CP_MSG_TYPE_FT); #else mUtil.Init(this, DND_CP_MSG_SRC_HOST, DND_CP_MSG_TYPE_FT); #endif } /** * Init. Register the rpc with transport. Send a ping message to controller to * to let it know our version and capability. * * XXX Capability is not implemented yet. */ void FileTransferRpcV4::Init(void) { ASSERT(mTransport); mTransport->RegisterRpc(this, mTransportInterface); } /** * Sends hgfs packet to peer. * * @param[in] sessionId DnD/CopyPaste session id. * @param[in] packet packet data. * @param[in] packetSize packet size. * * @return true on success, false otherwise. */ bool FileTransferRpcV4::SendHgfsPacket(uint32 sessionId, const uint8 *packet, uint32 packetSize) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = FT_CMD_HGFS_REQUEST; params.sessionId = sessionId; return mUtil.SendMsg(¶ms, packet, packetSize); } /** * Sends hgfs reply back to peer. * * @param[in] sessionId DnD/CopyPaste session id. * @param[in] packet reply packet data. * @param[in] packetSize reply packet size. * * @return true on success, false otherwise. */ bool FileTransferRpcV4::SendHgfsReply(uint32 sessionId, const uint8 *packet, uint32 packetSize) { RpcParams params; memset(¶ms, 0, sizeof params); params.addrId = DEFAULT_CONNECTION_ID; params.cmd = FT_CMD_HGFS_REPLY; params.sessionId = sessionId; return mUtil.SendMsg(¶ms, packet, packetSize); } /** * Send a packet. * * @param[in] destId destination address id. * @param[in] packet * @param[in] length packet length * * @return true on success, false otherwise. */ bool FileTransferRpcV4::SendPacket(uint32 destId, const uint8 *packet, size_t length) { return mTransport->SendPacket(destId, mTransportInterface, packet, length); } /** * Handle a received message. * * @param[in] params parameter list for received message. * @param[in] binary attached binary data for received message. * @param[in] binarySize */ void FileTransferRpcV4::HandleMsg(RpcParams *params, const uint8 *binary, uint32 binarySize) { ASSERT(params); LOG(4, ("%s: Got %s[%d], sessionId %d, srcId %d, binary size %d.\n", __FUNCTION__, DnDCPMsgV4_LookupCmd(params->cmd), params->cmd, params->sessionId, params->addrId, binarySize)); switch (params->cmd) { case FT_CMD_HGFS_REQUEST: HgfsPacketReceived.emit(params->sessionId, binary, binarySize); break; case FT_CMD_HGFS_REPLY: HgfsReplyReceived.emit(params->sessionId, binary, binarySize); break; case DNDCP_CMD_PING_REPLY: break; default: LOG(0, ("%s: Got unknown command %d.\n", __FUNCTION__, params->cmd)); break; } } /** * Callback from transport layer after received a packet from srcId. * * @param[in] srcId addressId where the packet is from * @param[in] packet * @param[in] packetSize */ void FileTransferRpcV4::OnRecvPacket(uint32 srcId, const uint8 *packet, size_t packetSize) { mUtil.OnRecvPacket(srcId, packet, packetSize); } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/cpFileContents.x0000644765153500003110000000470112220061556023146 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * cpFileContents.x -- * * Definition of the data structures used in the GuestRpc commands to * provide information about file contents for cross platform clipboard. */ /* * Enumerates the different versions of the messages. */ enum CPFileContentsVersion { CP_FILE_CONTENTS_V1 = 1 }; struct CPFileItem { uint64 validFlags; /* Valid members. */ uint32 type; /* File type */ uint64 size; /* File size (in bytes) */ uint64 createTime; /* Creation time. Ignored by POSIX */ uint64 accessTime; /* Time of last access */ uint64 writeTime; /* Time of last write */ uint64 attrChangeTime; /* Time file attributess were last * changed. Ignored by Windows */ uint64 permissions; /* Permissions bits */ uint64 attributes; /* File attributes. */ opaque cpName<>; /* File name in cross-platform format. */ opaque content<>; /* File contents. */ }; struct CPFileContentsList { uint64 totalFileSize; struct CPFileItem fileItem<>; }; /* * This defines the protocol for cross-platform file contents format. The union * allows us to create new versions of the protocol later by creating new values * in the CPFileContentsVersion enumeration, without having to change much of * the code calling the (de)serialization functions. * * Since the union doesn't have a default case, de-serialization will fail * if an unknown version is provided on the wire. */ union CPFileContents switch (CPFileContentsVersion ver) { case CP_FILE_CONTENTS_V1: struct CPFileContentsList *fileContentsV1; }; open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndcp.cpp0000644765153500003110000001170112220061556021627 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file dndcp.cpp -- * * Entry points for DnD and CP plugin. * * No platform-specific code belongs here. See copyPasteDnDWrapper.[h|cpp] * for abstraction API to platform implementations, and copyPasteDnDImpl.h * for implementation class inteface. To add a new platform, derive from * CopyPasteDnDImpl. */ extern "C" { #include "vmware.h" #include "vmware/guestrpc/tclodefs.h" #include "vmware/tools/plugin.h" #include "vmware/tools/utils.h" } #include #include "copyPasteDnDWrapper.h" extern "C" { /** * Cleanup internal data on shutdown. * * @param[in] src Unused. * @param[in] ctx Unused. * @param[in] data Unused. */ static void DnDCPShutdown(gpointer src, ToolsAppCtx *ctx, gpointer data) { g_debug("%s: enter\n", __FUNCTION__); CopyPasteDnDWrapper *p = CopyPasteDnDWrapper::GetInstance(); if (p) { p->UnregisterCP(); p->UnregisterDnD(); } CopyPasteDnDWrapper::Destroy(); } /** * Handle a reset signal. * * @param[in] src Unused. * @param[in] ctx Unused. * @param[in] data Unused. */ static void DnDCPReset(gpointer src, ToolsAppCtx *ctx, gpointer data) { g_debug("%s: enter\n", __FUNCTION__); CopyPasteDnDWrapper *p = CopyPasteDnDWrapper::GetInstance(); if (p) { p->OnReset(); } } /** * Returns the list of the plugin's capabilities. * * * @param[in] src Unused. * @param[in] ctx Unused. * @param[in] set Whether setting or unsetting the capability. * @param[in] data Unused. * * @return A list of capabilities. */ static GArray * DnDCPCapabilities(gpointer src, ToolsAppCtx *ctx, gboolean set, gpointer data) { g_debug("%s: enter\n", __FUNCTION__); CopyPasteDnDWrapper *p = CopyPasteDnDWrapper::GetInstance(); if (p) { p->OnCapReg(set); } return NULL; } /** * Handles SetOption callback. * * * @param[in] src Unused. * @param[in] ctx Unused. * @param[in] data Unused. * @param[in] option The option being set. * @param[in] value The value the option is being set to. * * @return TRUE on success, FALSE otherwise. */ static gboolean DnDCPSetOption(gpointer src, ToolsAppCtx *ctx, const gchar *option, const gchar *value, gpointer data) { gboolean ret = FALSE; ASSERT(option); ASSERT(value); g_debug("%s: enter option %s value %s\n", __FUNCTION__, option, value); CopyPasteDnDWrapper *p = CopyPasteDnDWrapper::GetInstance(); if (option == NULL || (strcmp(option, TOOLSOPTION_ENABLEDND) != 0 && strcmp(option, TOOLSOPTION_COPYPASTE) != 0)) { goto out; } if (value == NULL || (strcmp(value, "2") != 0 && strcmp(value, "1") != 0 && strcmp(value, "0") != 0)) { goto out; } if (p) { p->Init(ctx); ret = p->OnSetOption(option, value); } out: return ret; } /** * Plugin entry point. Initializes internal plugin state. * * @param[in] ctx The app context. * * @return The registration data. */ TOOLS_MODULE_EXPORT ToolsPluginData * ToolsOnLoad(ToolsAppCtx *ctx) { static ToolsPluginData regData = { "dndCP", NULL, NULL }; if (ctx->rpc != NULL) { ToolsPluginSignalCb sigs[] = { { TOOLS_CORE_SIG_CAPABILITIES, (void *) DnDCPCapabilities, NULL }, { TOOLS_CORE_SIG_RESET, (void *) DnDCPReset, NULL }, { TOOLS_CORE_SIG_SET_OPTION, (void *) DnDCPSetOption, NULL }, { TOOLS_CORE_SIG_SHUTDOWN, (void *) DnDCPShutdown, NULL } }; ToolsAppReg regs[] = { { TOOLS_APP_SIGNALS, VMTools_WrapArray(sigs, sizeof *sigs, ARRAYSIZE(sigs)) } }; /* * DnD/CP Initialization here. */ CopyPasteDnDWrapper *p = CopyPasteDnDWrapper::GetInstance(); if (p) { p->Init(ctx); p->PointerInit(); } regData.regs = VMTools_WrapArray(regs, sizeof *regs, ARRAYSIZE(regs)); return ®Data; } return NULL; } } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/copyPasteDnDWrapper.cpp0000644765153500003110000003752312220061556024447 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file copyPasteDnDWrapper.cpp * * This singleton class implements a wrapper around various versions of * copy and paste and dnd protocols, and provides some convenience functions * that help to make VMwareUser a bit cleaner. */ #define G_LOG_DOMAIN "dndcp" #if defined(HAVE_GTKMM) #include "copyPasteDnDX11.h" #endif #if defined(WIN32) #include "copyPasteDnDWin32.h" #endif #if defined(__APPLE__) #include "copyPasteDnDMac.h" #endif #include "copyPasteDnDWrapper.h" #include "guestDnDCPMgr.hh" extern "C" { #include "vmware.h" #include "rpcout.h" #include "vmware/guestrpc/tclodefs.h" #include "vmware/tools/plugin.h" #include "vmware/tools/utils.h" #include } /** * CopyPasteDnDWrapper is a singleton, here is a pointer to its only instance. */ CopyPasteDnDWrapper *CopyPasteDnDWrapper::m_instance = NULL; /** * * Get an instance of CopyPasteDnDWrapper, which is an application singleton. * * @return a pointer to the singleton CopyPasteDnDWrapper object, or NULL if * for some reason it could not be allocated. */ CopyPasteDnDWrapper * CopyPasteDnDWrapper::GetInstance() { if (!m_instance) { m_instance = new CopyPasteDnDWrapper; } ASSERT(m_instance); return m_instance; } /** * * Destroy the singleton object. */ void CopyPasteDnDWrapper::Destroy() { if (m_instance) { g_debug("%s: destroying self\n", __FUNCTION__); delete m_instance; m_instance = NULL; } } /** * * Constructor. */ CopyPasteDnDWrapper::CopyPasteDnDWrapper() : m_isCPEnabled(FALSE), m_isDnDEnabled(FALSE), m_isCPRegistered(FALSE), m_isDnDRegistered(FALSE), m_cpVersion(0), m_dndVersion(0), m_ctx(NULL), m_pimpl(NULL) { } /** * * Call the implementation class pointer/grab initialization code. See * the implementation code for further details. */ void CopyPasteDnDWrapper::PointerInit() { ASSERT(m_pimpl); m_pimpl->PointerInit(); } /** * * Initialize the wrapper by instantiating the platform specific impl * class. Effectively, this function is a factory that produces a * platform implementation of the DnD/Copy Paste UI layer. * * @param[in] ctx tools app context. */ void CopyPasteDnDWrapper::Init(ToolsAppCtx *ctx) { m_ctx = ctx; GuestDnDCPMgr *p = GuestDnDCPMgr::GetInstance(); ASSERT(p); p->Init(ctx); if (!m_pimpl) { #if defined(HAVE_GTKMM) m_pimpl = new CopyPasteDnDX11(); #endif #if defined(WIN32) m_pimpl = new CopyPasteDnDWin32(); #endif #if defined(__APPLE__) m_pimpl = new CopyPasteDnDMac(); #endif if (m_pimpl) { m_pimpl->Init(ctx); /* * Tell the Guest DnD Manager what capabilities we support. */ p->SetCaps(m_pimpl->GetCaps()); } } } /** * * Destructor. */ CopyPasteDnDWrapper::~CopyPasteDnDWrapper() { g_debug("%s: enter\n", __FUNCTION__); if (m_pimpl) { if (IsCPRegistered()) { m_pimpl->UnregisterCP(); } if (IsDnDRegistered()) { m_pimpl->UnregisterDnD(); } delete m_pimpl; } GuestDnDCPMgr::Destroy(); } /** * * Register copy and paste capabilities with the VMX. Try newest version * first, then fall back to the legacy implementation. * * @return TRUE on success, FALSE on failure */ gboolean CopyPasteDnDWrapper::RegisterCP() { g_debug("%s: enter\n", __FUNCTION__); ASSERT(m_pimpl); if (IsCPEnabled()) { return m_pimpl->RegisterCP(); } return false; } /** * * Register DnD capabilities with the VMX. Handled by the platform layer. * * @return TRUE on success, FALSE on failure */ gboolean CopyPasteDnDWrapper::RegisterDnD() { g_debug("%s: enter\n", __FUNCTION__); ASSERT(m_pimpl); if (IsDnDEnabled()) { return m_pimpl->RegisterDnD(); } return false; } /** * * Unregister copy paste capabilities. Handled by platform layer. */ void CopyPasteDnDWrapper::UnregisterCP() { g_debug("%s: enter\n", __FUNCTION__); ASSERT(m_pimpl); return m_pimpl->UnregisterCP(); } /** * * Unregister DnD capabilities. Handled by platform layer. */ void CopyPasteDnDWrapper::UnregisterDnD() { g_debug("%s: enter\n", __FUNCTION__); ASSERT(m_pimpl); return m_pimpl->UnregisterDnD(); } /** * * Get the version of the copy paste protocol being wrapped. * * @return copy paste protocol version. */ int CopyPasteDnDWrapper::GetCPVersion() { g_debug("%s: enter\n", __FUNCTION__); if (IsCPRegistered()) { char *reply = NULL; size_t replyLen; ToolsAppCtx *ctx = GetToolsAppCtx(); if (!RpcChannel_Send(ctx->rpc, QUERY_VMX_COPYPASTE_VERSION, strlen(QUERY_VMX_COPYPASTE_VERSION), &reply, &replyLen)) { g_debug("%s: could not get VMX copyPaste " "version capability: %s\n", __FUNCTION__, reply ? reply : "NULL"); m_cpVersion = 1; } else { m_cpVersion = atoi(reply); } free(reply); } g_debug("%s: got version %d\n", __FUNCTION__, m_cpVersion); return m_cpVersion; } /** * * Get the version of the DnD protocol being wrapped. * * @return DnD protocol version. */ int CopyPasteDnDWrapper::GetDnDVersion() { g_debug("%s: enter\n", __FUNCTION__); if (IsDnDRegistered()) { char *reply = NULL; size_t replyLen; ToolsAppCtx *ctx = GetToolsAppCtx(); if (!RpcChannel_Send(ctx->rpc, QUERY_VMX_DND_VERSION, strlen(QUERY_VMX_DND_VERSION), &reply, &replyLen)) { g_debug("%s: could not get VMX dnd " "version capability: %s\n", __FUNCTION__, reply ? reply : "NULL"); m_dndVersion = 1; } else { m_dndVersion = atoi(reply); } free(reply); } g_debug("%s: got version %d\n", __FUNCTION__, m_dndVersion); return m_dndVersion; } /** * * Set a flag indicating that we are wrapping an initialized and registered * copy paste implementation, or not. * * @param[in] isRegistered If TRUE, protocol is registered, otherwise FALSE. */ void CopyPasteDnDWrapper::SetCPIsRegistered(gboolean isRegistered) { g_debug("%s: enter\n", __FUNCTION__); m_isCPRegistered = isRegistered; } /** * * Get the flag indicating that we are wrapping an initialized and registered * copy paste implementation, or not. * * @return TRUE if copy paste is initialized, otherwise FALSE. */ gboolean CopyPasteDnDWrapper::IsCPRegistered() { g_debug("%s: enter\n", __FUNCTION__); return m_isCPRegistered; } /** * * Set a flag indicating that we are wrapping an initialized and registered * DnD implementation, or not. * * @param[in] isRegistered If TRUE, protocol is registered, otherwise FALSE. */ void CopyPasteDnDWrapper::SetDnDIsRegistered(gboolean isRegistered) { m_isDnDRegistered = isRegistered; } /** * * Get the flag indicating that we are wrapping an initialized and registered * DnD implementation, or not. * * @return TRUE if DnD is initialized, otherwise FALSE. */ gboolean CopyPasteDnDWrapper::IsDnDRegistered() { return m_isDnDRegistered; } /** * * Set a flag indicating that copy paste is enabled, or not. This is called * in response to SetOption RPC being received. * * @param[in] isEnabled If TRUE, copy paste is enabled, otherwise FALSE. */ void CopyPasteDnDWrapper::SetCPIsEnabled(gboolean isEnabled) { g_debug("%s: enter\n", __FUNCTION__); m_isCPEnabled = isEnabled; if (!isEnabled && IsCPRegistered()) { UnregisterCP(); } else if (isEnabled && !IsCPRegistered()) { RegisterCP(); } } /** * * Get the flag indicating that copy paste was enabled (via SetOption RPC). * * @return TRUE if copy paste is enabled, otherwise FALSE. */ gboolean CopyPasteDnDWrapper::IsCPEnabled() { return m_isCPEnabled; } /** * * Set a flag indicating that DnD is enabled, or not. This is called * in response to SetOption RPC being received. * * @param[in] isEnabled If TRUE, DnD is enabled, otherwise FALSE. */ void CopyPasteDnDWrapper::SetDnDIsEnabled(gboolean isEnabled) { m_isDnDEnabled = isEnabled; if (!isEnabled && IsDnDRegistered()) { UnregisterDnD(); } else if (isEnabled && !IsDnDRegistered()) { RegisterDnD(); } } /** * * Get the flag indicating that DnD was enabled (via SetOption) or not. * * @return TRUE if DnD is enabled, otherwise FALSE. */ gboolean CopyPasteDnDWrapper::IsDnDEnabled() { return m_isDnDEnabled; } /** * * Timer callback for reset. Handle it by calling the member function * that handles reset. * * @param[in] clientData pointer to the CopyPasteDnDWrapper instance that * issued the timer. * * @return FALSE always. */ static gboolean DnDPluginResetSent(void *clientData) { CopyPasteDnDWrapper *p = reinterpret_cast(clientData); ASSERT(p); p->OnResetInternal(); return FALSE; } /** * * Handle reset. */ void CopyPasteDnDWrapper::OnResetInternal() { g_debug("%s: enter\n", __FUNCTION__); /* * Reset DnD/Copy/Paste only if vmx said we can. The reason is that * we may also get reset request from vmx when user is taking snapshot * or recording. If there is an ongoing DnD/copy/paste, we should not * reset here. For details please refer to bug 375928. */ char *reply = NULL; size_t replyLen; ToolsAppCtx *ctx = GetToolsAppCtx(); if (RpcChannel_Send(ctx->rpc, "dnd.is.active", strlen("dnd.is.active"), &reply, &replyLen) && (1 == atoi(reply))) { g_debug("%s: ignore reset while file transfer is busy.\n", __FUNCTION__); return; } if (IsDnDRegistered()) { UnregisterDnD(); } if (IsCPRegistered()) { UnregisterCP(); } if (IsCPEnabled() && !IsCPRegistered()) { RegisterCP(); } if (IsDnDEnabled() && !IsDnDRegistered()) { RegisterDnD(); } if (!IsDnDRegistered() || !IsCPRegistered()) { g_debug("%s: unable to reset fully DnD %d CP %d!\n", __FUNCTION__, IsDnDRegistered(), IsCPRegistered()); } } /** * * Handle reset. * * Schedule the post-reset actions to happen a little after one cycle of the * RpcIn loop. This will give vmware a chance to receive the ATR * reinitialize the channel if appropriate. */ void CopyPasteDnDWrapper::OnReset() { GSource *src; g_debug("%s: enter\n", __FUNCTION__); src = VMTools_CreateTimer(RPC_POLL_TIME * 30); if (src) { VMTOOLSAPP_ATTACH_SOURCE(m_ctx, src, DnDPluginResetSent, this, NULL); g_source_unref(src); } } /** * * Handle cap reg. This is cross-platform so handle here instead of the * platform implementation. */ void CopyPasteDnDWrapper::OnCapReg(gboolean set) { g_debug("%s: enter\n", __FUNCTION__); char *reply; size_t replyLen; const char *toolsDnDVersion = TOOLS_DND_VERSION_4; char *toolsCopyPasteVersion = NULL; int version; ToolsAppCtx *ctx = GetToolsAppCtx(); if (ctx) { /* * First DnD. */ if (!RpcChannel_Send(ctx->rpc, toolsDnDVersion, strlen(toolsDnDVersion), NULL, NULL)) { g_debug("%s: could not set guest dnd version capability\n", __FUNCTION__); version = 1; SetDnDVersion(version); } else { char const *vmxDnDVersion = QUERY_VMX_DND_VERSION; if (!RpcChannel_Send(ctx->rpc, vmxDnDVersion, strlen(vmxDnDVersion), &reply, &replyLen)) { g_debug("%s: could not get VMX dnd version capability, assuming v1\n", __FUNCTION__); version = 1; SetDnDVersion(version); } else { int version = atoi(reply); ASSERT(version >= 1); SetDnDVersion(version); g_debug("%s: VMX is dnd version %d\n", __FUNCTION__, GetDnDVersion()); if (version == 3) { /* * VMDB still has version 4 in it, which will cause a V3 * host to fail. So, change to version 3. Since we don't * support any other version, we only do this for V3. */ toolsDnDVersion = TOOLS_DND_VERSION_3; if (!RpcChannel_Send(ctx->rpc, toolsDnDVersion, strlen(toolsDnDVersion), NULL, NULL)) { g_debug("%s: could not set VMX dnd version capability, assuming v1\n", __FUNCTION__); version = 1; SetDnDVersion(version); } } } vm_free(reply); } /* * Now CopyPaste. */ toolsCopyPasteVersion = g_strdup_printf(TOOLS_COPYPASTE_VERSION" %d", 4); if (!RpcChannel_Send(ctx->rpc, toolsCopyPasteVersion, strlen(toolsCopyPasteVersion), NULL, NULL)) { g_debug("%s: could not set guest copypaste version capability\n", __FUNCTION__); version = 1; SetCPVersion(version); } else { char const *vmxCopyPasteVersion = QUERY_VMX_COPYPASTE_VERSION; if (!RpcChannel_Send(ctx->rpc, vmxCopyPasteVersion, strlen(vmxCopyPasteVersion), &reply, &replyLen)) { g_debug("%s: could not get VMX copypaste version capability, assuming v1\n", __FUNCTION__); version = 1; SetCPVersion(version); } else { version = atoi(reply); ASSERT(version >= 1); SetCPVersion(version); g_debug("%s: VMX is copypaste version %d\n", __FUNCTION__, GetCPVersion()); if (version == 3) { /* * VMDB still has version 4 in it, which will cause a V3 * host to fail. So, change to version 3. Since we don't * support any other version, we only do this for V3. */ g_free(toolsCopyPasteVersion); toolsCopyPasteVersion = g_strdup_printf(TOOLS_COPYPASTE_VERSION" %d", 3); if (!RpcChannel_Send(ctx->rpc, toolsCopyPasteVersion, strlen(toolsCopyPasteVersion), NULL, NULL)) { g_debug("%s: could not set VMX copypaste version, assuming v1\n", __FUNCTION__); version = 1; SetCPVersion(version); } } } vm_free(reply); } g_free(toolsCopyPasteVersion); } } /** * * Handle SetOption */ gboolean CopyPasteDnDWrapper::OnSetOption(const char *option, const char *value) { gboolean ret = false; bool bEnable; ASSERT(option); ASSERT(value); bEnable = strcmp(value, "1") ? false : true; g_debug("%s: setting option '%s' to '%s'\n", __FUNCTION__, option, value); if (strcmp(option, TOOLSOPTION_ENABLEDND) == 0) { SetDnDIsEnabled(bEnable); ret = true; } else if (strcmp(option, TOOLSOPTION_COPYPASTE) == 0) { SetCPIsEnabled(bEnable); ret = true; } return ret; } /** * Get capabilities by calling platform implementation. * * @return 32-bit mask of DnD/CP capabilities. */ uint32 CopyPasteDnDWrapper::GetCaps() { ASSERT(m_pimpl); return m_pimpl->GetCaps(); } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/copyPasteDnDWrapper.h0000644765153500003110000000525512220061556024111 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file copyPasteDnDWrapper.h * * This singleton class implements an abstraction around the concrete classes * that implement DnD, and copy and paste. */ #ifndef __COPYPASTEDNDWRAPPER_H__ #define __COPYPASTEDNDWRAPPER_H__ #include "vmware/tools/plugin.h" #include "copyPasteDnDImpl.h" #include "dndPluginInt.h" class CopyPasteDnDWrapper { public: ~CopyPasteDnDWrapper(); static CopyPasteDnDWrapper *GetInstance(); static void Destroy(); gboolean RegisterCP(); void UnregisterCP(); gboolean RegisterDnD(); void UnregisterDnD(); void SetDnDVersion(int version) {m_dndVersion = version;}; int GetDnDVersion(); void SetCPVersion(int version) {m_cpVersion = version;}; int GetCPVersion(); void SetCPIsRegistered(gboolean isRegistered); gboolean IsCPRegistered(); void SetDnDIsRegistered(gboolean isRegistered); gboolean IsDnDRegistered(); void SetDnDIsEnabled(gboolean isEnabled); gboolean IsDnDEnabled(); void SetCPIsEnabled(gboolean isEnabled); gboolean IsCPEnabled(); void OnReset(); void OnResetInternal(); void OnCapReg(gboolean set); gboolean OnSetOption(const char *option, const char *value); void Init(ToolsAppCtx *ctx); void PointerInit(void); ToolsAppCtx *GetToolsAppCtx() {return m_ctx;}; uint32 GetCaps(); private: /* * We're a singleton, so it is a compile time error to call these. */ CopyPasteDnDWrapper(); CopyPasteDnDWrapper(const CopyPasteDnDWrapper &wrapper); CopyPasteDnDWrapper& operator=(const CopyPasteDnDWrapper &wrapper); private: gboolean m_isCPEnabled; gboolean m_isDnDEnabled; gboolean m_isCPRegistered; gboolean m_isDnDRegistered; int m_cpVersion; int m_dndVersion; static CopyPasteDnDWrapper *m_instance; ToolsAppCtx *m_ctx; CopyPasteDnDImpl *m_pimpl; }; #endif // __COPYPASTEDNDWRAPPER_H__ open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndPluginIntX11.h0000644765153500003110000000240012220061556023071 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * dndPluginX11Int.h -- * * Common defines used by Linux DnD plugin implementation. */ #ifndef __DNDPLUGIN_INTX11_H__ #define __DNDPLUGIN_INTX11_H__ #include #include #include #undef Bool #include "vm_basic_types.h" #include "dnd.h" #define UNGRABBED_POS (-100) extern Display *gXDisplay; extern Window gXRoot; extern GtkWidget *gUserMainWidget; #endif open-vm-tools-9.4.0-1280544/services/plugins/dndcp/copyPasteUIX11.cpp0000644765153500003110000013634412220061556023251 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * copyPasteUIX11.cpp -- * * This class implements the methods that allows CopyPaste between host * and guest. * * For a perspective on X copy/paste, see * http://www.jwz.org/doc/x-cut-and-paste.html */ /* * A Word on Selection Timestamps * * ICCCM §2.6.2 Target Atoms * The TIMESTAMP property is an INTEGER. * * ICCCM §2.7 Use of Selection Properties * The format of INTEGER is 32. * * XGetWindowProperty(3) * “If the returned format is 32, the property will be stored as an * array of longs (which in a 64-bit application will be 64-bit values * that are padded in the upper 4 bytes).” * * For all intents and purposes, on x86 and x86_64 X selection timestamps * are a 32-bit quantity. (X11/Xproto.h's xSetSelectionOwnerReq defines the * “time” member as the lower 32 bits of type Time.) X clients, on the * other hand, operate on Time as either a CARD32 (uint32) or an unsigned * long (i.e., on a 64-bit machine Time may occupy 8 bytes). * * Breaking it down: * · When Gtk+ provides a X11 selection via Gtk::SelectionData, on a * 32-bit machine we'll have 4 bytes of raw data. Everything's copacetic. * · On a 64-bit machine, even if the source client provides on 32 bits * of timestamp data, Gtk+ will decode as an unsigned long and provide 8 * bytes of raw data. * · On a 64-bit machine with a wacky application which actually tries * to record a full 64 bits of timestamp data, Gtk+ will provide 16 bytes: * <32 bits of 0s> <32 bits of 0s>. (See * PR 882322, mrxvt.) * * In all instances, we're interested in _only_ the lowest 32 bits, so we'll * ignore everything else. */ #define G_LOG_DOMAIN "dndcp" #include #include #include #include "copyPasteDnDWrapper.h" #include "copyPasteUIX11.h" #include "dndFileList.hh" #include "guestDnDCPMgr.hh" extern "C" { #include "vmblock.h" #include "file.h" #include "dnd.h" #include "dndMsg.h" #include "dndClipboard.h" #include "cpName.h" #include "cpNameUtil.h" #include "rpcout.h" #include "vmware/guestrpc/tclodefs.h" } /* * Gtk 1.2 doesn't know about the CLIPBOARD selection, but that doesn't * matter, we just create the atom we need directly in main(). * * This is for V1 text copy paste only! */ #ifndef GDK_SELECTION_CLIPBOARD GdkAtom GDK_SELECTION_CLIPBOARD; #endif #ifndef GDK_SELECTION_TYPE_TIMESTAMP GdkAtom GDK_SELECTION_TYPE_TIMESTAMP; #endif #ifndef GDK_SELECTION_TYPE_UTF8_STRING GdkAtom GDK_SELECTION_TYPE_UTF8_STRING; #endif /* *----------------------------------------------------------------------------- * * CopyPasteUIX11::CopyPasteUIX11 -- * * Constructor. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ CopyPasteUIX11::CopyPasteUIX11() : mClipboardEmpty(true), mHGStagingDir(""), mIsClipboardOwner(false), mClipTime(0), mPrimTime(0), mLastTimestamp(0), mHGGetFileStatus(DND_FILE_TRANSFER_NOT_STARTED), mBlockAdded(false), mBlockCtrl(0), mInited(false), mTotalFileSize(0), mGetTimestampOnly(false) { GuestDnDCPMgr *p = GuestDnDCPMgr::GetInstance(); ASSERT(p); mCP = p->GetCopyPasteMgr(); ASSERT(mCP); } /* *----------------------------------------------------------------------------- * * CopyPasteUIX11::Init -- * * Initialize copy paste UI class and register for V3 or greater copy * paste. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ bool CopyPasteUIX11::Init() { g_debug("%s: enter\n", __FUNCTION__); if (mInited) { return true; } CPClipboard_Init(&mClipboard); Gtk::TargetEntry gnome(FCP_TARGET_NAME_GNOME_COPIED_FILES); Gtk::TargetEntry kde(FCP_TARGET_NAME_URI_LIST); gnome.set_info(FCP_TARGET_INFO_GNOME_COPIED_FILES); kde.set_info(FCP_TARGET_INFO_URI_LIST); mListTargets.push_back(gnome); mListTargets.push_back(kde); mCP->srcRecvClipChanged.connect( sigc::mem_fun(this, &CopyPasteUIX11::GetRemoteClipboardCB)); mCP->destRequestClipChanged.connect( sigc::mem_fun(this, &CopyPasteUIX11::GetLocalClipboard)); mCP->getFilesDoneChanged.connect( sigc::mem_fun(this, &CopyPasteUIX11::GetLocalFilesDone)); mInited = true; return true; } /* *----------------------------------------------------------------------------- * * CopyPasteUIX11::~CopyPaste -- * * Destructor. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ CopyPasteUIX11::~CopyPasteUIX11() { g_debug("%s: enter\n", __FUNCTION__); CPClipboard_Destroy(&mClipboard); /* Any files from last unfinished file transfer should be deleted. */ if (DND_FILE_TRANSFER_IN_PROGRESS == mHGGetFileStatus && !mHGStagingDir.empty()) { uint64 totalSize = File_GetSizeEx(mHGStagingDir.c_str()); if (mTotalFileSize != totalSize) { g_debug("%s: deleting %s, expecting %"FMT64"d, finished %"FMT64"d\n", __FUNCTION__, mHGStagingDir.c_str(), mTotalFileSize, totalSize); DnD_DeleteStagingFiles(mHGStagingDir.c_str(), FALSE); } else { g_debug("%s: file size match %s\n", __FUNCTION__, mHGStagingDir.c_str()); } } if (mBlockAdded) { g_debug("%s: removing block for %s\n", __FUNCTION__, mHGStagingDir.c_str()); /* We need to make sure block subsystem has not been shut off. */ if (DnD_BlockIsReady(mBlockCtrl)) { mBlockCtrl->RemoveBlock(mBlockCtrl->fd, mHGStagingDir.c_str()); } mBlockAdded = false; } } /* *----------------------------------------------------------------------------- * * CopyPasteUIX11::VmxCopyPasteVersionChanged -- * * Update version information in mCP. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void CopyPasteUIX11::VmxCopyPasteVersionChanged(RpcChannel *chan, // IN uint32 version) // IN { ASSERT(mCP); g_debug("%s: new version is %d\n", __FUNCTION__, version); mCP->VmxCopyPasteVersionChanged(version); } /* *----------------------------------------------------------------------------- * * CopyPasteUIX11::GetLocalClipboard -- * * Retrives the data from local clipboard and sends it to host. Send empty * data back if there is no data or can not get data successfully. For * guest->host copy/paste. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void CopyPasteUIX11::GetLocalClipboard(void) { g_debug("%s: enter.\n", __FUNCTION__); if (mIsClipboardOwner) { /* If we are clipboard owner, send a not-changed clip to host. */ g_debug("%s: we are owner, send unchanged clip back.\n", __FUNCTION__); SendClipNotChanged(); return; } if (!mCP->IsCopyPasteAllowed()) { g_debug("%s: copyPaste is not allowed\n", __FUNCTION__); return; } Glib::RefPtr refClipboard = Gtk::Clipboard::get(GDK_SELECTION_CLIPBOARD); mClipTime = 0; mPrimTime = 0; mGHSelection = GDK_SELECTION_CLIPBOARD; mGetTimestampOnly = false; g_debug("%s: retrieving timestamps\n", __FUNCTION__); refClipboard->request_contents(TARGET_NAME_TIMESTAMP, sigc::mem_fun(this, &CopyPasteUIX11::LocalClipboardTimestampCB)); } /* *----------------------------------------------------------------------------- * * CopyPasteUIX11::GetCurrentTime -- * * Get current time in microseconds. * * Results: * Time in microseconds. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VmTimeType CopyPasteUIX11::GetCurrentTime(void) { struct timeval tv; VmTimeType curTime; if (gettimeofday(&tv, NULL) != 0) { g_debug("%s: gettimeofday failed!\n", __FUNCTION__); return (VmTimeType) 0; } curTime = (tv.tv_sec * 1000000 + tv.tv_usec); return curTime; } /* *----------------------------------------------------------------------------- * * CopyPasteUIX11::LocalGetFileRequestCB -- * * Callback from a file paste request from another guest application. * Begins copying the files from host to guest and return the file list. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void CopyPasteUIX11::LocalGetFileRequestCB(Gtk::SelectionData& sd, // IN: guint info) // IN: { g_debug("%s: enter.\n", __FUNCTION__); VmTimeType curTime; curTime = GetCurrentTime(); /* * Some applications may ask for clipboard contents right after clipboard * owner changed. So HG FCP will return nothing for some time after switch * from guest OS to host OS. */ if ((curTime - mHGGetListTime) < FCP_COPY_DELAY) { g_debug("%s: time delta less than FCP_COPY_DELAY, returning.\n", __FUNCTION__); return; } if (!mIsClipboardOwner || !mCP->IsCopyPasteAllowed()) { g_debug("%s: not clipboard ownder, or copy paste not allowed, returning.\n", __FUNCTION__); sd.set(sd.get_target().c_str(), ""); return; } g_debug("%s: Got paste request, target is %s\n", __FUNCTION__, sd.get_target().c_str()); if (mHGGetFileStatus != DND_FILE_TRANSFER_NOT_STARTED) { /* * On KDE (at least), we can see this multiple times, so ignore if * we are already getting files. */ g_debug("%s: GetFiles already started, returning uriList [%s]\n", __FUNCTION__, mHGCopiedUriList.c_str()); sd.set(sd.get_target().c_str(), mHGCopiedUriList.c_str()); return; } else { utf::string str; utf::string hgStagingDir; utf::string stagingDirName; utf::string pre; utf::string post; size_t index = 0; hgStagingDir = static_cast(mCP->SrcUIRequestFiles()); g_debug("%s: Getting files. Staging dir: %s", __FUNCTION__, hgStagingDir.c_str()); if (0 == hgStagingDir.bytes()) { g_debug("%s: Can not create staging directory\n", __FUNCTION__); sd.set(sd.get_target().c_str(), ""); return; } mHGGetFileStatus = DND_FILE_TRANSFER_IN_PROGRESS; mBlockAdded = false; if (DnD_BlockIsReady(mBlockCtrl) && mBlockCtrl->AddBlock(mBlockCtrl->fd, hgStagingDir.c_str())) { g_debug("%s: add block for %s.\n", __FUNCTION__, hgStagingDir.c_str()); mBlockAdded = true; } else { g_debug("%s: unable to add block for %s.\n", __FUNCTION__, hgStagingDir.c_str()); } mHGStagingDir = hgStagingDir; /* Provide URIs for each path in the guest's file list. */ if (FCP_TARGET_INFO_GNOME_COPIED_FILES == info) { mHGCopiedUriList = "copy\n"; pre = FCP_GNOME_LIST_PRE; post = FCP_GNOME_LIST_POST; } else if (FCP_TARGET_INFO_URI_LIST == info) { pre = DND_URI_LIST_PRE_KDE; post = DND_URI_LIST_POST; } else { g_debug("%s: Unknown request target: %s\n", __FUNCTION__, sd.get_target().c_str()); sd.set(sd.get_target().c_str(), ""); return; } /* Provide path within vmblock file system instead of actual path. */ stagingDirName = GetLastDirName(hgStagingDir); if (0 == stagingDirName.bytes()) { g_debug("%s: Can not get staging directory name\n", __FUNCTION__); sd.set(sd.get_target().c_str(), ""); return; } while ((str = GetNextPath(mHGFCPData, index).c_str()).bytes() != 0) { g_debug("%s: Path: %s", __FUNCTION__, str.c_str()); mHGCopiedUriList += pre; if (mBlockAdded) { mHGCopiedUriList += mBlockCtrl->blockRoot; mHGCopiedUriList += DIRSEPS + stagingDirName + DIRSEPS + str + post; } else { mHGCopiedUriList += DIRSEPS + hgStagingDir + DIRSEPS + str + post; } } /* Nautilus does not expect FCP_GNOME_LIST_POST after the last uri. See bug 143147. */ if (FCP_TARGET_INFO_GNOME_COPIED_FILES == info) { mHGCopiedUriList.erase(mHGCopiedUriList.size() - 1, 1); } } if (0 == mHGCopiedUriList.bytes()) { g_debug("%s: Can not get uri list\n", __FUNCTION__); sd.set(sd.get_target().c_str(), ""); return; } if (!mBlockAdded) { /* * If there is no blocking driver, wait here till file copy is done. * 2 reasons to keep this: * 1. If run vmware-user stand-alone as non-root, blocking driver can * not be opened. g_debug purpose only. * 2. Other platforms (Solaris, etc) may also use this code, * and there is no blocking driver yet. * * Polling here will not be sufficient for large files (experiments * showed it was sufficient for a 256MB file, and failed for a 1GB * file, but those numbers are of course context-sensitive and so YMMV). * The reason is we are executing in the context of gtkmm callback, and * apparently it only has so much patience regarding how quickly we * return. */ CopyPasteDnDWrapper *wrapper = CopyPasteDnDWrapper::GetInstance(); ToolsAppCtx *ctx = wrapper->GetToolsAppCtx(); while (mHGGetFileStatus == DND_FILE_TRANSFER_IN_PROGRESS) { struct timeval tv; tv.tv_sec = 0; g_main_context_iteration(g_main_loop_get_context(ctx->mainLoop), FALSE); if (select(0, NULL, NULL, NULL, &tv) == -1) { g_debug("%s: error in select (%s).\n", __FUNCTION__, strerror(errno)); sd.set(sd.get_target().c_str(), ""); return; } } g_debug("%s: file transfer done!\n", __FUNCTION__); } g_debug("%s: providing file list [%s]\n", __FUNCTION__, mHGCopiedUriList.c_str()); sd.set(sd.get_target().c_str(), mHGCopiedUriList.c_str()); } /* *----------------------------------------------------------------------------- * * CopyPasteUIX11::LocalGetTextOrRTFRequestCB -- * * Callback from a text or RTF paste request from another guest application. * H->G copy paste only. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void CopyPasteUIX11::LocalGetTextOrRTFRequestCB(Gtk::SelectionData& sd, // IN/OUT guint info) // Ignored { sd.set(sd.get_target().c_str(), ""); if (!mCP->IsCopyPasteAllowed()) { return; } const utf::string target = sd.get_target().c_str(); g_debug("%s: Got paste request, target is %s\n", __FUNCTION__, target.c_str()); if (target == TARGET_NAME_APPLICATION_RTF || target == TARGET_NAME_TEXT_RICHTEXT) { if (0 == mHGRTFData.size()) { g_debug("%s: Can not get valid RTF data\n", __FUNCTION__); return; } g_debug("%s: providing RTF data, size %"FMTSZ"u\n", __FUNCTION__, mHGRTFData.size()); sd.set(target.c_str(), mHGRTFData.c_str()); } if (target == TARGET_NAME_STRING || target == TARGET_NAME_TEXT_PLAIN || target == TARGET_NAME_UTF8_STRING || target == TARGET_NAME_COMPOUND_TEXT) { if (0 == mHGTextData.bytes()) { g_debug("%s: Can not get valid text data\n", __FUNCTION__); return; } g_debug("%s: providing plain text, size %"FMTSZ"u\n", __FUNCTION__, mHGTextData.bytes()); sd.set(target.c_str(), mHGTextData.c_str()); } } /* *----------------------------------------------------------------------------- * * CopyPaste::LocalClearClipboardCB -- * * Clear clipboard request from another host application. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void CopyPasteUIX11::LocalClearClipboardCB(void) { g_debug("%s: got clear callback\n", __FUNCTION__); mIsClipboardOwner = FALSE; } /* *---------------------------------------------------------------------- * * CopyPasteUIX11::LocalClipboardTimestampCB -- * * Got the local clipboard timestamp. Ask for the primary timestamp. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void CopyPasteUIX11::LocalClipboardTimestampCB(const Gtk::SelectionData& sd) // IN { int length = sd.get_length(); /* * See “A Word on Selection Timestamps” above. */ if ( ( sd.get_data_type().compare("INTEGER") == 0 || sd.get_data_type().compare("TIMESTAMP") == 0) && sd.get_format() == 32 && length >= 4 /* sizeof uint32 */) { mClipTime = reinterpret_cast(sd.get_data())[0]; } else { g_debug("%s: Unable to get mClipTime (sd: len %d, type %s, fmt %d).", __FUNCTION__, length, length >= 0 ? sd.get_data_type().c_str() : "(n/a)", sd.get_format()); } Glib::RefPtr refClipboard = Gtk::Clipboard::get(GDK_SELECTION_PRIMARY); refClipboard->request_contents(TARGET_NAME_TIMESTAMP, sigc::mem_fun(this, &CopyPasteUIX11::LocalPrimTimestampCB)); } /* *---------------------------------------------------------------------- * * CopyPasteUIX11::LocalPrimTimestampCB -- * * Got the local primary timestamp. Choose the most recently changed * clipboard and get the selection from it. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void CopyPasteUIX11::LocalPrimTimestampCB(const Gtk::SelectionData& sd) // IN { int length = sd.get_length(); /* * See “A Word on Selection Timestamps” above. */ if ( ( sd.get_data_type().compare("INTEGER") == 0 || sd.get_data_type().compare("TIMESTAMP") == 0) && sd.get_format() == 32 && length >= 4 /* sizeof uint32 */) { mPrimTime = reinterpret_cast(sd.get_data())[0]; } else { g_debug("%s: Unable to get mPrimTime (sd: len %d, type %s, fmt %d).", __FUNCTION__, length, length >= 0 ? sd.get_data_type().c_str() : "(n/a)", sd.get_format()); } if (mGetTimestampOnly) { mLastTimestamp = mClipTime > mPrimTime ? mClipTime : mPrimTime; return; } /* After got both timestamp, choose latest one as active selection. */ if (mClipTime > mPrimTime) { mGHSelection = GDK_SELECTION_CLIPBOARD; if (mClipTime > 0 && mClipTime == mLastTimestamp) { g_debug("%s: clip is not changed\n", __FUNCTION__); SendClipNotChanged(); return; } mLastTimestamp = mClipTime; } else { mGHSelection = GDK_SELECTION_PRIMARY; if (mPrimTime > 0 && mPrimTime == mLastTimestamp) { g_debug("%s: clip is not changed\n", __FUNCTION__); SendClipNotChanged(); return; } mLastTimestamp = mPrimTime; } Glib::RefPtr refClipboard; bool flipped = false; again: bool validDataInClip = false; refClipboard = Gtk::Clipboard::get(mGHSelection); g_debug("%s: trying %s selection.\n", __FUNCTION__, mGHSelection == GDK_SELECTION_PRIMARY ? "Primary" : "Clip"); CPClipboard_Clear(&mClipboard); /* First check for URIs. This must always be done first */ bool haveURIs = false; std::string format; if (mCP->CheckCapability(DND_CP_CAP_FILE_CP) && refClipboard->wait_is_target_available(FCP_TARGET_NAME_GNOME_COPIED_FILES)) { format = FCP_TARGET_NAME_GNOME_COPIED_FILES; haveURIs = true; } else if (mCP->CheckCapability(DND_CP_CAP_FILE_CP) && refClipboard->wait_is_target_available(FCP_TARGET_NAME_URI_LIST)) { format = FCP_TARGET_NAME_URI_LIST; haveURIs = true; } if (haveURIs) { refClipboard->request_contents(format, sigc::mem_fun(this, &CopyPasteUIX11::LocalReceivedFileListCB)); return; } /* Try to get image data from clipboard. */ Glib::RefPtr img = refClipboard->wait_for_image(); gsize bufSize; if (mCP->CheckCapability(DND_CP_CAP_IMAGE_CP) && img) { gchar *buf = NULL; img->save_to_buffer(buf, bufSize, Glib::ustring("png")); if (bufSize > 0 && bufSize <= (int)CPCLIPITEM_MAX_SIZE_V3 && CPClipboard_SetItem(&mClipboard, CPFORMAT_IMG_PNG, buf, bufSize)) { validDataInClip = true; g_debug("%s: Got PNG: %"FMTSZ"u\n", __FUNCTION__, bufSize); } else { g_debug("%s: Failed to get PNG\n", __FUNCTION__); } g_free(buf); } /* Try to get RTF data from clipboard. */ bool haveRTF = false; if (refClipboard->wait_is_target_available(TARGET_NAME_APPLICATION_RTF)) { g_debug("%s: RTF is available\n", __FUNCTION__); format = TARGET_NAME_APPLICATION_RTF; haveRTF = true; } if (refClipboard->wait_is_target_available(TARGET_NAME_TEXT_RICHTEXT)) { g_debug("%s: RICHTEXT is available\n", __FUNCTION__); format = TARGET_NAME_TEXT_RICHTEXT; haveRTF = true; } if (mCP->CheckCapability(DND_CP_CAP_RTF_CP) && haveRTF) { /* * There is a function for waiting for rtf data, but that was leading * to crashes. It's use required we instantiate a class that implements * Gtk::TextBuffer and then query that class for a reference to it's * TextBuffer instance. This all compiled fine but crashed in testing * so we opt to use the more generic API here which seemed more stable. */ Gtk::SelectionData sdata = refClipboard->wait_for_contents(format); bufSize = sdata.get_length(); if (bufSize > 0 && bufSize <= (int)CPCLIPITEM_MAX_SIZE_V3 && CPClipboard_SetItem(&mClipboard, CPFORMAT_RTF, (const void *)sdata.get_data(), bufSize + 1)) { validDataInClip = true; g_debug("%s: Got RTF\n", __FUNCTION__); } else { g_debug("%s: Failed to get RTF size %d max %d\n", __FUNCTION__, (int) bufSize, (int)CPCLIPITEM_MAX_SIZE_V3); } } /* Try to get Text data from clipboard. */ if (mCP->CheckCapability(DND_CP_CAP_PLAIN_TEXT_CP) && refClipboard->wait_is_text_available()) { g_debug("%s: ask for text\n", __FUNCTION__); Glib::ustring str = refClipboard->wait_for_text(); bufSize = str.bytes(); if (bufSize > 0 && bufSize <= (int)CPCLIPITEM_MAX_SIZE_V3 && CPClipboard_SetItem(&mClipboard, CPFORMAT_TEXT, (const void *)str.data(), bufSize + 1)) { validDataInClip = true; g_debug("%s: Got TEXT: %"FMTSZ"u\n", __FUNCTION__, bufSize); } else { g_debug("%s: Failed to get TEXT\n", __FUNCTION__); } } if (validDataInClip) { /* * RTF or text data (or both) in the clipboard. */ mCP->DestUISendClip(&mClipboard); } else if (!flipped) { /* * If we get here, we got nothing (no image, URI, text) so * try the other selection. */ g_debug("%s: got nothing for this selection, try the other.\n", __FUNCTION__); mGHSelection = mGHSelection == GDK_SELECTION_PRIMARY ? GDK_SELECTION_CLIPBOARD : GDK_SELECTION_PRIMARY; flipped = true; goto again; } else { g_debug("%s: got nothing, send empty clip back.\n", __FUNCTION__); mCP->DestUISendClip(&mClipboard); } } /* *---------------------------------------------------------------------- * * CopyPasteUIX11::LocalReceivedFileListCB -- * * Got clipboard or primary selection file list. Parse it and add * it to the crossplaform clipboard. Send clipboard to the host. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void CopyPasteUIX11::LocalReceivedFileListCB(const Gtk::SelectionData& sd) // IN { g_debug("%s: enter", __FUNCTION__); const utf::string target = sd.get_target().c_str(); if (!mCP->CheckCapability(DND_CP_CAP_FILE_CP)) { /* * Disallowed based on caps settings, return. */ return; } if (target == FCP_TARGET_NAME_GNOME_COPIED_FILES || target == FCP_TARGET_NAME_URI_LIST) { LocalGetSelectionFileList(sd); mCP->DestUISendClip(&mClipboard); } } /* *----------------------------------------------------------------------------- * * CopyPasteUIX11::LocalGetFileContentsRequestCB -- * * Callback from a file paste request from another guest application. * Return the file list. * * H->G only. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void CopyPasteUIX11::LocalGetFileContentsRequestCB(Gtk::SelectionData& sd, // IN guint info) // IN { std::vector::const_iterator iter; utf::string uriList = ""; utf::string pre; utf::string post; if (!mCP->CheckCapability(DND_CP_CAP_FILE_CONTENT_CP)) { /* * Disallowed based on caps settings, return. */ return; } sd.set(sd.get_target().c_str(), ""); /* Provide URIs for each path in the guest's file list. */ if (FCP_TARGET_INFO_GNOME_COPIED_FILES == info) { uriList = "copy\n"; pre = FCP_GNOME_LIST_PRE; post = FCP_GNOME_LIST_POST; } else if (FCP_TARGET_INFO_URI_LIST == info) { pre = DND_URI_LIST_PRE_KDE; post = DND_URI_LIST_POST; } else { g_debug("%s: Unknown request target: %s\n", __FUNCTION__, sd.get_target().c_str()); return; } for (iter = mHGFileContentsList.begin(); iter != mHGFileContentsList.end(); iter++) { uriList += pre + *iter + post; } /* Nautilus does not expect FCP_GNOME_LIST_POST after the last uri. See bug 143147. */ if (FCP_TARGET_INFO_GNOME_COPIED_FILES == info) { uriList.erase(uriList.size() - 1, 1); } if (0 == uriList.bytes()) { g_debug("%s: Can not get uri list\n", __FUNCTION__); return; } g_debug("%s: providing file list [%s]\n", __FUNCTION__, uriList.c_str()); sd.set(sd.get_target().c_str(), uriList.c_str()); } /* *----------------------------------------------------------------------------- * * CopyPasteUIX11::LocalGetSelectionFileList -- * * Construct local file list and remote file list from selection data. * Called by both DnD and FCP. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void CopyPasteUIX11::LocalGetSelectionFileList(const Gtk::SelectionData& sd) // IN { utf::string source; char *newPath; char *newRelPath; size_t newPathLen; size_t index = 0; DnDFileList fileList; DynBuf buf; uint64 totalSize = 0; int64 size; /* * Turn the uri list into two \0 delimited lists. One for full paths and * one for just the last path component. */ source = sd.get_data_as_string().c_str(); g_debug("%s: Got file list: [%s]\n", __FUNCTION__, source.c_str()); /* * In gnome, before file list there may be a extra line indicating it * is a copy or cut. */ if (source.startsWith("copy\n")) { source = source.erase(0, 5); } if (source.startsWith("cut\n")) { source = source.erase(0, 4); } while (source.bytes() > 0 && (source[0] == '\n' || source[0] == '\r' || source[0] == ' ')) { source = source.erase(0, 1); } while ((newPath = DnD_UriListGetNextFile(source.c_str(), &index, &newPathLen)) != NULL) { #if defined(linux) if (DnD_UriIsNonFileSchemes(newPath)) { /* Try to get local file path for non file uri. */ GFile *file = g_file_new_for_uri(newPath); free(newPath); if (!file) { g_debug("%s: g_file_new_for_uri failed\n", __FUNCTION__); return; } newPath = g_file_get_path(file); g_object_unref(file); if (!newPath) { g_debug("%s: g_file_get_path failed\n", __FUNCTION__); return; } } #endif /* * Parse relative path. */ newRelPath = Str_Strrchr(newPath, DIRSEPC) + 1; // Point to char after '/' /* Keep track of how big the fcp files are. */ if ((size = File_GetSizeEx(newPath)) >= 0) { totalSize += size; } else { g_debug("%s: Unable to get file size for %s\n", __FUNCTION__, newPath); } g_debug("%s: Adding newPath '%s' newRelPath '%s'\n", __FUNCTION__, newPath, newRelPath); fileList.AddFile(newPath, newRelPath); free(newPath); } DynBuf_Init(&buf); fileList.SetFileSize(totalSize); g_debug("%s: totalSize is %"FMT64"u\n", __FUNCTION__, totalSize); fileList.ToCPClipboard(&buf, false); CPClipboard_SetItem(&mClipboard, CPFORMAT_FILELIST, DynBuf_Get(&buf), DynBuf_GetSize(&buf)); DynBuf_Destroy(&buf); } /* *----------------------------------------------------------------------------- * * CopyPasteUIX11::GetLastDirName -- * * Try to get last directory name from a full path name. * * Results: * Last dir name in the full path name if sucess, empty str otherwise * * Side effects: * None. * *----------------------------------------------------------------------------- */ utf::string CopyPasteUIX11::GetLastDirName(const utf::string &str) // IN { utf::string ret; size_t start; size_t end; end = str.bytes() - 1; if (end >= 0 && DIRSEPC == str[end]) { end--; } if (end <= 0 || str[0] != DIRSEPC) { return ""; } start = end; while (str[start] != DIRSEPC) { start--; } return str.substr(start + 1, end - start); } /* *---------------------------------------------------------------------------- * * CopyPasteUIX11::GetNextPath -- * * Provides a substring containing the next path from the provided * NUL-delimited string starting at the provided index. * * Results: * A string with the next path or "" if there are no more paths. * * Side effects: * None. * *---------------------------------------------------------------------------- */ utf::utf8string CopyPasteUIX11::GetNextPath(utf::utf8string& str, // IN: NUL-delimited path list size_t& index) // IN/OUT: current index into string { utf::utf8string ret; size_t start; if (index >= str.length()) { return ""; } for (start = index; str[index] != '\0' && index < str.length(); index++) { /* * Escape reserved characters according to RFC 1630. We'd use * Escape_Do() if this wasn't a utf::string, but let's use the same table * replacement approach. */ static char const Dec2Hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', }; unsigned char ubyte = str[index]; if (ubyte == '#' || /* Fragment identifier delimiter */ ubyte == '?' || /* Query string delimiter */ ubyte == '*' || /* "Special significance within specific schemes" */ ubyte == '!' || /* "Special significance within specific schemes" */ ubyte == '%' || /* Escape character */ ubyte >= 0x80) { /* UTF-8 encoding bytes */ str.replace(index, 1, "%"); str.insert(index + 1, 1, Dec2Hex[ubyte >> 4]); str.insert(index + 2, 1, Dec2Hex[ubyte & 0xF]); index += 2; } } ret = str.substr(start, index - start); g_debug("%s: nextpath: %s", __FUNCTION__, ret.c_str()); index++; return ret; } /* *----------------------------------------------------------------------------- * * CopyPasteUIX11::GetRemoteClipboardCB -- * * Invoked when got data from host. Update the internal data to get the file * names or the text that needs to be transferred. * * Method for copy and paste from host to guest. * * Results: * None * * Side effects: * None. * *----------------------------------------------------------------------------- */ void CopyPasteUIX11::GetRemoteClipboardCB(const CPClipboard *clip) // IN { Glib::RefPtr refClipboard = Gtk::Clipboard::get(GDK_SELECTION_CLIPBOARD); Glib::RefPtr refPrimary = Gtk::Clipboard::get(GDK_SELECTION_PRIMARY); void *buf; size_t sz; g_debug("%s: enter\n", __FUNCTION__); if (!clip) { g_debug("%s: No clipboard contents.", __FUNCTION__); return; } /* Clear the clipboard contents if we are the owner. */ if (mIsClipboardOwner) { refClipboard->clear(); refPrimary->clear(); mIsClipboardOwner = false; g_debug("%s: Cleared local clipboard", __FUNCTION__); } mHGTextData.clear(); mHGRTFData.clear(); mHGFCPData.clear(); if (CPClipboard_ItemExists(clip, CPFORMAT_TEXT) || CPClipboard_ItemExists(clip, CPFORMAT_RTF)) { std::list targets; /* * rtf should be first in the target list otherwise OpenOffice may not * accept paste. */ if (CPClipboard_GetItem(clip, CPFORMAT_RTF, &buf, &sz)) { g_debug("%s: RTF data, size %"FMTSZ"u.\n", __FUNCTION__, sz); Gtk::TargetEntry appRtf(TARGET_NAME_APPLICATION_RTF); Gtk::TargetEntry textRtf(TARGET_NAME_TEXT_RICHTEXT); targets.push_back(appRtf); targets.push_back(textRtf); mHGRTFData = std::string((const char *)buf); mIsClipboardOwner = true; } if (CPClipboard_GetItem(clip, CPFORMAT_TEXT, &buf, &sz)) { Gtk::TargetEntry stringText(TARGET_NAME_STRING); Gtk::TargetEntry plainText(TARGET_NAME_TEXT_PLAIN); Gtk::TargetEntry utf8Text(TARGET_NAME_UTF8_STRING); Gtk::TargetEntry compountText(TARGET_NAME_COMPOUND_TEXT); g_debug("%s: Text data, size %"FMTSZ"u.\n", __FUNCTION__, sz); targets.push_back(stringText); targets.push_back(plainText); targets.push_back(utf8Text); targets.push_back(compountText); mHGTextData = utf::string(reinterpret_cast(buf), STRING_ENCODING_UTF8); mIsClipboardOwner = true; } refClipboard->set(targets, sigc::mem_fun(this, &CopyPasteUIX11::LocalGetTextOrRTFRequestCB), sigc::mem_fun(this, &CopyPasteUIX11::LocalClearClipboardCB)); refPrimary->set(targets, sigc::mem_fun(this, &CopyPasteUIX11::LocalGetTextOrRTFRequestCB), sigc::mem_fun(this, &CopyPasteUIX11::LocalClearClipboardCB)); return; } if (CPClipboard_GetItem(clip, CPFORMAT_IMG_PNG, &buf, &sz)) { g_debug("%s: PNG data, size %"FMTSZ"u.\n", __FUNCTION__, sz); /* Try to load buf into pixbuf, and write to local clipboard. */ try { Glib::RefPtr loader = Gdk::PixbufLoader::create(); loader->write((const guint8 *)buf, sz); loader->close(); refClipboard->set_image(loader->get_pixbuf()); refPrimary->set_image(loader->get_pixbuf()); /* * Record current clipboard timestamp to prevent unexpected clipboard * exchange. * * XXX We should do this for all formats. */ mClipTime = 0; mPrimTime = 0; mGetTimestampOnly = true; refClipboard->request_contents(TARGET_NAME_TIMESTAMP, sigc::mem_fun(this, &CopyPasteUIX11::LocalClipboardTimestampCB)); } catch (const Gdk::PixbufError& e) { g_message("%s: caught Gdk::PixbufError %s\n", __FUNCTION__, e.what().c_str()); } catch (std::exception& e) { g_message("%s: caught std::exception %s\n", __FUNCTION__, e.what()); } catch (...) { g_message("%s: caught unknown exception (typename %s)\n", __FUNCTION__, __cxxabiv1::__cxa_current_exception_type()->name()); } return; } if (CPClipboard_GetItem(clip, CPFORMAT_FILELIST, &buf, &sz)) { g_debug("%s: File data.\n", __FUNCTION__); DnDFileList flist; flist.FromCPClipboard(buf, sz); mTotalFileSize = flist.GetFileSize(); mHGFCPData = flist.GetRelPathsStr(); refClipboard->set(mListTargets, sigc::mem_fun(this, &CopyPasteUIX11::LocalGetFileRequestCB), sigc::mem_fun(this, &CopyPasteUIX11::LocalClearClipboardCB)); refPrimary->set(mListTargets, sigc::mem_fun(this, &CopyPasteUIX11::LocalGetFileRequestCB), sigc::mem_fun(this, &CopyPasteUIX11::LocalClearClipboardCB)); mIsClipboardOwner = true; mHGGetListTime = GetCurrentTime(); mHGGetFileStatus = DND_FILE_TRANSFER_NOT_STARTED; mHGCopiedUriList = ""; } if (CPClipboard_ItemExists(clip, CPFORMAT_FILECONTENTS)) { g_debug("%s: File contents data\n", __FUNCTION__); if (LocalPrepareFileContents(clip)) { refClipboard->set(mListTargets, sigc::mem_fun(this, &CopyPasteUIX11::LocalGetFileContentsRequestCB), sigc::mem_fun(this, &CopyPasteUIX11::LocalClearClipboardCB)); refPrimary->set(mListTargets, sigc::mem_fun(this, &CopyPasteUIX11::LocalGetFileContentsRequestCB), sigc::mem_fun(this, &CopyPasteUIX11::LocalClearClipboardCB)); mIsClipboardOwner = true; } } } /* *---------------------------------------------------------------------------- * * CopyPasteUIX11::LocalPrepareFileContents -- * * Try to extract file contents from mClipboard. Write all files to a * temporary staging directory. Construct uri list. * * Results: * true if success, false otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ bool CopyPasteUIX11::LocalPrepareFileContents(const CPClipboard *clip) // IN { void *buf = NULL; size_t sz = 0; XDR xdrs; CPFileContents fileContents; CPFileContentsList *contentsList = NULL; size_t nFiles = 0; CPFileItem *fileItem = NULL; Unicode tempDir = NULL; size_t i = 0; bool ret = false; if (!CPClipboard_GetItem(clip, CPFORMAT_FILECONTENTS, &buf, &sz)) { g_debug("%s: CPClipboard_GetItem failed\n", __FUNCTION__); return false; } /* Extract file contents from buf. */ xdrmem_create(&xdrs, (char *)buf, sz, XDR_DECODE); memset(&fileContents, 0, sizeof fileContents); if (!xdr_CPFileContents(&xdrs, &fileContents)) { g_debug("%s: xdr_CPFileContents failed.\n", __FUNCTION__); xdr_destroy(&xdrs); return false; } xdr_destroy(&xdrs); contentsList = fileContents.CPFileContents_u.fileContentsV1; if (!contentsList) { g_debug("%s: invalid contentsList.\n", __FUNCTION__); goto exit; } nFiles = contentsList->fileItem.fileItem_len; if (0 == nFiles) { g_debug("%s: invalid nFiles.\n", __FUNCTION__); goto exit; } fileItem = contentsList->fileItem.fileItem_val; if (!fileItem) { g_debug("%s: invalid fileItem.\n", __FUNCTION__); goto exit; } /* * Write files into a temporary staging directory. These files will be moved * to final destination, or deleted on next reboot. */ tempDir = DnD_CreateStagingDirectory(); if (!tempDir) { g_debug("%s: DnD_CreateStagingDirectory failed.\n", __FUNCTION__); goto exit; } mHGFileContentsList.clear(); for (i = 0; i < nFiles; i++) { utf::string fileName; utf::string filePathName; VmTimeType createTime = -1; VmTimeType accessTime = -1; VmTimeType writeTime = -1; VmTimeType attrChangeTime = -1; if (!fileItem[i].cpName.cpName_val || 0 == fileItem[i].cpName.cpName_len) { g_debug("%s: invalid fileItem[%"FMTSZ"u].cpName.\n", __FUNCTION__, i); goto exit; } /* * '\0' is used as directory separator in cross-platform name. Now turn * '\0' in data into DIRSEPC. * * Note that we don't convert the final '\0' into DIRSEPC so the string * is NUL terminated. */ CPNameUtil_CharReplace(fileItem[i].cpName.cpName_val, fileItem[i].cpName.cpName_len - 1, '\0', DIRSEPC); fileName = fileItem[i].cpName.cpName_val; filePathName = tempDir; filePathName += DIRSEPS + fileName; if (fileItem[i].validFlags & CP_FILE_VALID_TYPE && CP_FILE_TYPE_DIRECTORY == fileItem[i].type) { if (!File_CreateDirectory(filePathName.c_str())) { goto exit; } g_debug("%s: created directory [%s].\n", __FUNCTION__, filePathName.c_str()); } else if (fileItem[i].validFlags & CP_FILE_VALID_TYPE && CP_FILE_TYPE_REGULAR == fileItem[i].type) { FileIODescriptor file; FileIOResult fileErr; FileIO_Invalidate(&file); fileErr = FileIO_Open(&file, filePathName.c_str(), FILEIO_ACCESS_WRITE, FILEIO_OPEN_CREATE_EMPTY); if (!FileIO_IsSuccess(fileErr)) { goto exit; } fileErr = FileIO_Write(&file, fileItem[i].content.content_val, fileItem[i].content.content_len, NULL); FileIO_Close(&file); g_debug("%s: created file [%s].\n", __FUNCTION__, filePathName.c_str()); } else { /* * Right now only Windows can provide CPFORMAT_FILECONTENTS data. * Symlink file is not expected. Continue with next file if the * type is not valid. */ continue; } /* Update file time attributes. */ createTime = fileItem->validFlags & CP_FILE_VALID_CREATE_TIME ? fileItem->createTime: -1; accessTime = fileItem->validFlags & CP_FILE_VALID_ACCESS_TIME ? fileItem->accessTime: -1; writeTime = fileItem->validFlags & CP_FILE_VALID_WRITE_TIME ? fileItem->writeTime: -1; attrChangeTime = fileItem->validFlags & CP_FILE_VALID_CHANGE_TIME ? fileItem->attrChangeTime: -1; if (!File_SetTimes(filePathName.c_str(), createTime, accessTime, writeTime, attrChangeTime)) { /* Not a critical error, only log it. */ g_debug("%s: File_SetTimes failed with file [%s].\n", __FUNCTION__, filePathName.c_str()); } /* Update file permission attributes. */ if (fileItem->validFlags & CP_FILE_VALID_PERMS) { if (Posix_Chmod(filePathName.c_str(), fileItem->permissions) < 0) { /* Not a critical error, only log it. */ g_debug("%s: Posix_Chmod failed with file [%s].\n", __FUNCTION__, filePathName.c_str()); } } /* * If there is no DIRSEPC inside the fileName, this file/directory is a * top level one. We only put top level name into uri list. */ if (fileName.find(DIRSEPS, 0) == utf::string::npos) { mHGFileContentsList.push_back(filePathName); } } g_debug("%s: created uri list\n", __FUNCTION__); ret = true; exit: xdr_free((xdrproc_t)xdr_CPFileContents, (char *)&fileContents); if (tempDir && !ret) { DnD_DeleteStagingFiles(tempDir, FALSE); } free(tempDir); return ret; } /* *----------------------------------------------------------------------------- * * CopyPasteUIX11::GetLocalFilesDone -- * * Callback when CopyPasteUIX11::GetLocalFiles is done, which finishes the file * copying from host to guest staging directory. This function notifies * the Copy/Paste data object and end its waiting state in order to continue * the file copying from local staging directory to local target directory. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void CopyPasteUIX11::GetLocalFilesDone(bool success) { g_debug("%s: enter success %d\n", __FUNCTION__, success); if (mBlockAdded) { g_debug("%s: removing block for %s\n", __FUNCTION__, mHGStagingDir.c_str()); /* We need to make sure block subsystem has not been shut off. */ if (DnD_BlockIsReady(mBlockCtrl)) { mBlockCtrl->RemoveBlock(mBlockCtrl->fd, mHGStagingDir.c_str()); } mBlockAdded = false; } mHGGetFileStatus = DND_FILE_TRANSFER_FINISHED; if (success) { /* * Mark current staging dir to be deleted on next reboot for FCP. The * file will not be deleted after reboot if it is moved to another * location by target application. */ DnD_DeleteStagingFiles(mHGStagingDir.c_str(), TRUE); } else { /* Copied files are already removed in common layer. */ mHGStagingDir.clear(); } } /* *----------------------------------------------------------------------------- * * CopyPasteUIX11::SendClipNotChanged -- * * Send a not-changed clip to host. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void CopyPasteUIX11::SendClipNotChanged(void) { CPClipboard clip; g_debug("%s: enter.\n", __FUNCTION__); CPClipboard_Init(&clip); CPClipboard_SetChanged(&clip, FALSE); mCP->DestUISendClip(&clip); CPClipboard_Destroy(&clip); } /* *----------------------------------------------------------------------------- * * CopyPasteUIX11::Reset -- * * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void CopyPasteUIX11::Reset(void) { g_debug("%s: enter\n", __FUNCTION__); /* Cancel any pending file transfer. */ } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndPluginInt.h0000644765153500003110000000307312220061556022606 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * dndPluginInt.h * * Various DnD plugin defines. * */ #if !defined (__DNDPLUGIN_INT_H__) #define __DNDPLUGIN_INT_H__ extern "C" { #include "conf.h" } #define DEBUG_PREFIX "vmusr" #define RPC_POLL_TIME 10 #define POINTER_POLL_TIME 10 #define UNGRABBED_POS (-100) #define VMWARE_CLIP_FORMAT_NAME L"VMwareClipFormat" #define TOOLS_DND_VERSION_3 "tools.capability.dnd_version 3" #define TOOLS_DND_VERSION_4 "tools.capability.dnd_version 4" #define QUERY_VMX_DND_VERSION "vmx.capability.dnd_version" #define TOOLS_COPYPASTE_VERSION "tools.capability.copypaste_version" #define QUERY_VMX_COPYPASTE_VERSION "vmx.capability.copypaste_version" #endif open-vm-tools-9.4.0-1280544/services/plugins/dndcp/copyPasteUIX11.h0000644765153500003110000001001412220061556022677 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file copyPasteUIX11.h * * This class implements the methods that allows Copy/Paste * between host and guest using version 3+ of the protocol. * */ #ifndef __COPYPASTE_UI_X11_H__ #define __COPYPASTE_UI_X11_H__ #include "stringxx/string.hh" extern "C" { #include "dnd.h" #include "debug.h" #include "str.h" #include "dndClipboard.h" #include "dynbuf.h" #include "../dnd/dndFileContentsUtil.h" #include "dynxdr.h" #include "cpNameUtil.h" #include "posix.h" #include "vmware/tools/guestrpc.h" } #include "unicodeOperations.h" #include "guestCopyPaste.hh" /* * Make sure exception types are public and therefore shared between libg*mm * and this plugin. * * See * http://gcc.gnu.org/wiki/Visibility#Problems_with_C.2B-.2B-_exceptions_.28please_read.21.29 */ #pragma GCC visibility push(default) #include #pragma GCC visibility pop #include #include #include #include #include #include "vmware/guestrpc/tclodefs.h" class CopyPasteUIX11 : public sigc::trackable { public: CopyPasteUIX11(); virtual ~CopyPasteUIX11(); bool Init(); void VmxCopyPasteVersionChanged(RpcChannel *chan, uint32 version); void SetCopyPasteAllowed(bool isCopyPasteAllowed) { mCP->SetCopyPasteAllowed(isCopyPasteAllowed); } void Reset(void); void SetBlockControl(DnDBlockControl *blockCtrl) { Debug("Setting mBlockCtrl to %p\n", blockCtrl); mBlockCtrl = blockCtrl; } private: /* hg */ void GetRemoteClipboardCB(const CPClipboard *clip); void RemoteGetFilesDone(void); void LocalGetFileRequestCB(Gtk::SelectionData& selection_data, guint info); void LocalGetTextOrRTFRequestCB(Gtk::SelectionData& sd, guint info); void LocalGetSelectionFileList(const Gtk::SelectionData& sd); void LocalGetFileContentsRequestCB(Gtk::SelectionData& sd, guint info); void LocalClearClipboardCB(void); /* gh */ void GetLocalClipboard(void); void LocalClipboardTimestampCB(const Gtk::SelectionData& sd); void LocalPrimTimestampCB(const Gtk::SelectionData& sd); void LocalReceivedFileListCB(const Gtk::SelectionData& selection_data); void GetLocalFilesDone(bool success); void SendClipNotChanged(void); /* Conversion methods. */ utf::utf8string GetNextPath(utf::utf8string &str, size_t& index); utf::string GetLastDirName(const utf::string &str); bool LocalPrepareFileContents(const CPClipboard *clip); VmTimeType GetCurrentTime(void); // Member variables GuestCopyPasteMgr *mCP; bool mClipboardEmpty; utf::string mHGStagingDir; std::list mListTargets; bool mIsClipboardOwner; uint64 mClipTime; uint64 mPrimTime; uint64 mLastTimestamp; GdkAtom mGHSelection; CPClipboard mClipboard; /* File vars. */ VmTimeType mHGGetListTime; utf::string mHGCopiedUriList; utf::utf8string mHGFCPData; utf::string mHGTextData; std::string mHGRTFData; std::vector mHGFileContentsList; DND_FILE_TRANSFER_STATUS mHGGetFileStatus; bool mBlockAdded; DnDBlockControl *mBlockCtrl; bool mInited; uint64 mTotalFileSize; bool mGetTimestampOnly; }; #endif // __COPYPASTE_UI_X11_H__ open-vm-tools-9.4.0-1280544/services/plugins/dndcp/pointer.cpp0000644765153500003110000002466012220061556022227 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * pointer.cpp -- * * Pointer functions. */ #define G_LOG_DOMAIN "dndcp" #if defined(WIN32) #include "dndPluginInt.h" #else #include "dndPluginIntX11.h" #endif extern "C" { #include "copyPasteCompat.h" } #include "copyPasteDnDWrapper.h" #include "pointer.h" #include "vmware/tools/utils.h" extern "C" { #include "vm_assert.h" #include "backdoor_def.h" #include "backdoor.h" #include "rpcvmx.h" } typedef enum { ABSMOUSE_UNAVAILABLE, ABSMOUSE_AVAILABLE, ABSMOUSE_UNKNOWN } AbsoluteMouseState; static Bool mouseIsGrabbed; static AbsoluteMouseState absoluteMouseState = ABSMOUSE_UNKNOWN; static uint8 gHostClipboardTries = 0; #if defined(WIN32) extern BOOL vmx86WantsSelection; #endif static void PointerGrabbed(void); static void PointerUngrabbed(void); static gboolean PointerUpdatePointerLoop(gpointer clientData); #define POINTER_UPDATE_TIMEOUT 100 /* *---------------------------------------------------------------------------- * * PointerGetAbsoluteMouseState * * Are the host/guest capable of using absolute mouse mode? * * Results: * TRUE if host is in absolute mouse mode, FALSE otherwise. * * Side effects: * Issues Tools RPC. * *---------------------------------------------------------------------------- */ static AbsoluteMouseState PointerGetAbsoluteMouseState(void) { Backdoor_proto bp; AbsoluteMouseState state = ABSMOUSE_UNKNOWN; bp.in.cx.halfs.low = BDOOR_CMD_ISMOUSEABSOLUTE; Backdoor(&bp); if (bp.out.ax.word == 0) { state = ABSMOUSE_UNAVAILABLE; } else if (bp.out.ax.word == 1) { state = ABSMOUSE_AVAILABLE; } return state; } #if !defined(WIN32) /* *----------------------------------------------------------------------------- * * PointerGetXCursorPos -- * * Return the position in pixels of the X (mouse) pointer in the root * window. * * Results: * x and y coordinates. * * Side effects: * None. *----------------------------------------------------------------------------- */ void PointerGetXCursorPos(int *rootX, int *rootY) { Window rootWin; Window childWin; int x; int y; unsigned int mask; XQueryPointer(gXDisplay, gXRoot, &rootWin, &childWin, rootX, rootY, &x, &y, &mask); } /* *----------------------------------------------------------------------------- * * PointerSetXCursorPos * * Set the position in pixels of the X (mouse) pointer in the root window * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void PointerSetXCursorPos(int x, int y) { XWarpPointer(gXDisplay, None, gXRoot, 0, 0, 0, 0, x, y); } #endif /* *----------------------------------------------------------------------------- * * PointerGetPos -- * * Retrieve the host notion of the guest pointer location. * * Results: * '*x' and '*y' are the coordinates (top left corner is 0, 0) of the * host notion of the guest pointer location. (-100, -100) means that the * mouse is not grabbed on the host. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void PointerGetPos(int16 *x, // OUT int16 *y) // OUT { Backdoor_proto bp; bp.in.cx.halfs.low = BDOOR_CMD_GETPTRLOCATION; Backdoor(&bp); *x = bp.out.ax.word >> 16; *y = bp.out.ax.word; } /* *----------------------------------------------------------------------------- * * PointerSetPos -- * * Update the host notion of the guest pointer location. 'x' and 'y' are * the coordinates (top left corner is 0, 0). * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static void PointerSetPos(uint16 x, // IN uint16 y) // IN { Backdoor_proto bp; bp.in.cx.halfs.low = BDOOR_CMD_SETPTRLOCATION; bp.in.size = (x << 16) | y; Backdoor(&bp); } /* *----------------------------------------------------------------------------- * * PointerGrabbed -- * * Called when the pointer's state switches from released to grabbed. * We warp the cursor to whatever position the vmx tells us, and then * setup the loop which attempts to get the host clipboard. * * Result: * None.. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void PointerGrabbed(void) { short hostPosX; short hostPosY; PointerGetPos(&hostPosX, &hostPosY); #if defined(WIN32) SetCursorPos(hostPosX, hostPosY); #else PointerSetXCursorPos(hostPosX, hostPosY); #endif gHostClipboardTries = 9; } /* *----------------------------------------------------------------------------- * * PointerUngrabbed -- * * Called by the background thread when the pointer's state switches * from grabbed to ungrabbed * * Result: * None.. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void PointerUngrabbed() { #if defined(WIN32) if (vmx86WantsSelection) { /* * vmx agrees to exchange selections. This is a little * optimization to avoid an unnecessary backdoor call if vmx * disagrees. */ CopyPaste_RequestSelection(); } #else CopyPaste_RequestSelection(); #endif } /* *----------------------------------------------------------------------------- * * PointerUpdatePointerLoop -- * * Event Manager function for tracking the mouse/pointer/clipboard state. * Manage grabbed/ungrab state based on x/y data from backdoor. On the * transition to grabbed, call PointerHasBeenGrabbed(). While grabbed, * send guest pointer coordinates thru the backdoor. Also, make several * attempts to get the host clipboard from the backdoor. When changing * to ungrabbed, call PointerHasBeenUngrabbed, which will push our * clipboard thru the backdoor. While ungrabbed, don't do a thing. * * This function is queued in Event Manager only when vmx doesn't support * RPC copy/paste because newer vmx initiates copy/paste from UI through * RPC, and doesn't need cursor grab/ungrab state to start copy/paste. * * Results: * FALSE. * * Side effects: * Lots. The vmx's notion of guest cursor position could change, the * vmx's clipboard could change, and the guest's clipboard could change. * *----------------------------------------------------------------------------- */ static gboolean PointerUpdatePointerLoop(gpointer clientData) // IN: unused { int16 hostPosX, hostPosY; #if defined(WIN32) POINT guestPos; #else int guestX, guestY; #endif PointerGetPos(&hostPosX, &hostPosY); if (mouseIsGrabbed) { if (hostPosX == UNGRABBED_POS) { /* We transitioned from grabbed to ungrabbed */ mouseIsGrabbed = FALSE; g_debug("PointerUpdatePointerLoop: ungrabbed\n"); PointerUngrabbed(); } else { #if defined(WIN32) /* * We used to return early if GetCursorPos() failed, but we at least want to * continue and do the selection work. Also, I'm not sure we need this code anymore * since all new tools have absolute pointing device */ if (!GetCursorPos(&guestPos)) { g_debug("PointerIsGrabbed: GetCursorPos() failed!\n"); } else { if ( hostPosX != guestPos.x || hostPosY != guestPos.y) { /* * Report the new guest pointer location (It is used to teach VMware * where to position the outside pointer if the user releases the guest * pointer via the key combination). */ PointerSetPos(guestPos.x, guestPos.y); } } #else PointerGetXCursorPos(&guestX, &guestY); if ( hostPosX != guestX || hostPosY != guestY) { PointerSetPos(guestX, guestY); } #endif CopyPasteDnDWrapper *wrapper = CopyPasteDnDWrapper::GetInstance(); ASSERT(wrapper); if (gHostClipboardTries > 0) { gHostClipboardTries--; if (wrapper->IsCPEnabled() && gHostClipboardTries < 6 && CopyPaste_GetBackdoorSelections()) { gHostClipboardTries = 0; } } } } else { if (hostPosX != UNGRABBED_POS) { mouseIsGrabbed = TRUE; g_debug("PointerUpdatePointerLoop: grabbed\n"); PointerGrabbed(); } } if (!CopyPaste_IsRpcCPSupported() || (absoluteMouseState == ABSMOUSE_UNAVAILABLE)) { GSource *src; CopyPasteDnDWrapper *wrapper = CopyPasteDnDWrapper::GetInstance(); ToolsAppCtx *ctx = wrapper->GetToolsAppCtx(); if (ctx) { src = VMTools_CreateTimer(POINTER_UPDATE_TIMEOUT); VMTOOLSAPP_ATTACH_SOURCE(ctx, src, PointerUpdatePointerLoop, NULL, NULL); g_source_unref(src); } } return FALSE; } /* *----------------------------------------------------------------------------- * * Pointer_Init -- * * One time pointer initialization stuff. Enter the pointer update * loop which will check mouse position and put pointer in grabbed * and ungrabbed state, accordingly (see PointerUpdatePointerLoop() * for details.) * * Results: * None.. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void Pointer_Init(ToolsAppCtx *ctx) { absoluteMouseState = PointerGetAbsoluteMouseState(); PointerUpdatePointerLoop(NULL); mouseIsGrabbed = FALSE; } open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dragDetWndX11.cpp0000644765153500003110000001473012220061556023061 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file dragDetWndX11.cpp * * Detection window code for Linux/X11, based on Gtkmm. Includes unit test * code. */ #define G_LOG_DOMAIN "dndcp" #include "dragDetWndX11.h" #include "dndUIX11.h" #include /** * * Constructor. */ DragDetWnd::DragDetWnd() : m_isVisible(false) { #if defined(DETWNDDEBUG) DebugSetAttributes(); #endif } /** * * Destructor. */ DragDetWnd::~DragDetWnd() { } /** * Flush the X connection. */ void DragDetWnd::Flush() { Glib::RefPtr gdkdisplay = Gdk::Display::get_default(); if (gdkdisplay) { gdkdisplay->sync(); gdkdisplay->flush(); } } /** * * Show the window. */ void DragDetWnd::Show(void) { show(); Flush(); } /** * * Hide the window. */ void DragDetWnd::Hide(void) { hide(); Flush(); } /** * * Raise the window. */ void DragDetWnd::Raise(void) { Glib::RefPtr gdkwin = get_window(); if (gdkwin) { gdkwin->raise(); } Flush(); } /** * * Lower the window. */ void DragDetWnd::Lower(void) { Glib::RefPtr gdkwin = get_window(); if (gdkwin) { gdkwin->lower(); } Flush(); } /** * * Get the width of the screen associated with this window. * * @return width of screen, in pixels. */ int DragDetWnd::GetScreenWidth(void) { Glib::RefPtr gdkscreen = get_screen(); return gdkscreen->get_width(); } /** * * Get the height of the screen associated with this window. * * @return height of screen, in pixels. */ int DragDetWnd::GetScreenHeight(void) { Glib::RefPtr gdkscreen = get_screen(); return gdkscreen->get_height(); } #if defined(DETWNDDEBUG) /** * * Set default window attributes appropriate for debugging detection windows. * * @note This only applies to instances of DragDetWnd that are derived from * GTK::Window. */ void DragDetWnd::DebugSetAttributes(void) { set_default_size(1, 1); set_resizable(true); set_decorated(false); set_type_hint(Gdk::WINDOW_TYPE_HINT_DOCK); } #endif /** * * Set the geometry of the window. * * @param[in] x desired x-coordinate of the window. * @param[in] y desired y-coordinate of the window. * @param[in] width desired width of the window. * @param[in] height desired height of the window. */ void DragDetWnd::SetGeometry(const int x, const int y, const int width, const int height) { Glib::RefPtr gdkwin = get_window(); if (gdkwin) { gdkwin->move_resize(x, y, width, height); Flush(); } } /** * * Get the current geometry of the window. * * @param[out] x current x-coordinate of the window. * @param[out] y current y-coordinate of the window. * @param[out] width current width of the window. * @param[out] height current height of the window. * * @note The current geometry may be inaccurate if retrieved too quickly * after a change made by SetGeometry(). This is due to the realities of * X and window managers. Some of this is mitigated by the use of flush() * and sync() calls in SetGeometry(), but these are no guarantee. */ void DragDetWnd::GetGeometry(int &x, int &y, int &width, int &height) { int dummy; Glib::RefPtr gdkwin = get_window(); if (gdkwin) { gdkwin->get_geometry(x, y, width, height, dummy); #if defined(DETWNDTEST) Flush(); #endif } } /* * Code below here is for unit tests. */ #if defined(DETWNDTEST) /** * * Add a button to launch unit tests to the drag detection window. */ void DragDetWndTest::CreateTestUI() { m_button.set_label("Start Unit Tests"); add(m_button); m_button.signal_clicked().connect(sigc::mem_fun(*this, &DragDetWndTest::RunUnitTests)); m_button.show(); } /** * * Run some unit tests, then exit. Requires a main program, refer to * bora-vmsoft/toolbox/linux/vmwareuser/detWndTest/main.cpp for an * example. */ void DragDetWndTest::RunUnitTests() { DragDetWnd testWnd; int testCount = 0; int failCount = 0; #if defined(DETWNDDEBUG) testWnd.SetAttributes(); #endif testWnd.Show(); int x, y, width, height; testWnd.GetGeometry(x, y, width, height); printf("Geometry is x %d y %d width %d height %d\n", x, y, width, height); for (int i = 10; i < 50; Gtk::Main::iteration(), i++) { testCount++; printf("Setting geometry to x %d y %d w %d h %d\n", i * 10, i * 10, i * 10, i * 10); testWnd.SetGeometry(i * 10, i * 10, i * 10, i * 10); sleep(1); testWnd.GetGeometry(x, y, width, height); printf("Geometry is x %d y %d width %d height %d\n", x, y, width, height); if (x != i * 10 || y != i * 10 || width != i * 10) { printf("FAIL x or y not correct\n"); failCount++; } } for (int i = 49; i > 0; Gtk::Main::iteration(), i--) { testCount++; printf("Setting geometry to x %d y %d w %d h %d\n", i * 10, i * 10, i * 10, i * 10); testWnd.SetGeometry(i * 10, i * 10, i * 10, i * 10); sleep(1); testWnd.GetGeometry(x, y, width, height); printf("Geometry is x %d y %d width %d height %d\n", x, y, width, height); if (x != i * 10 || y != i * 10 || width != i * 10) { printf("FAIL width or height not correct\n"); failCount++; } } testWnd.SetGeometry(500, 500, 300, 300); for (int i = 0; i < 60; Gtk::Main::iteration(), i++) { if (i % 2) { printf("Hide\n"); testWnd.Hide(); } else { printf("Show\n"); testWnd.Show(); testWnd.Raise(); } sleep(1); } printf("Done fail count %d (%.2f%%)\n", failCount, 100.0 * failCount/testCount); Gtk::Main::quit(); } #endif open-vm-tools-9.4.0-1280544/services/plugins/dndcp/dndUIX11.h0000644765153500003110000001462512220061556021511 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file dndUIX11.h * * Implement the methods that allow DnD between host and guest for * protocols V3 or greater. * */ #ifndef __DND_UI_X11_H__ #define __DND_UI_X11_H__ #include "stringxx/string.hh" extern "C" { #include "debug.h" #include "dnd.h" #include "str.h" #include "util.h" #include "vmblock.h" #include "dndClipboard.h" #include "dynbuf.h" #include "../dnd/dndFileContentsUtil.h" #include "dynxdr.h" #include "cpNameUtil.h" #include "posix.h" #include "vmware/tools/guestrpc.h" #include "vmware/tools/plugin.h" } #include "guestDnD.hh" #include "dndFileList.hh" #include "dragDetWndX11.h" struct DblLnkLst_Links; /** * The DnDUI class implements the UI portion of DnD V3 and greater * versions of the protocol. */ class DnDUIX11 : public sigc::trackable { public: DnDUIX11(ToolsAppCtx *ctx); ~DnDUIX11(); bool Init(); void VmxDnDVersionChanged(RpcChannel *chan, uint32 version); void SetDnDAllowed(bool isDnDAllowed) {ASSERT(m_DnD); m_DnD->SetDnDAllowed(isDnDAllowed);} void SetBlockControl(DnDBlockControl *blockCtrl); void SetUnityMode(Bool mode) {m_unityMode = mode;}; DragDetWnd *GetFullDetWnd() {return m_detWnd;} GtkWidget *GetDetWndAsWidget(); private: /** * Blocking FS Helper Functions. */ void AddBlock(); void RemoveBlock(); bool TryXTestFakeDeviceButtonEvent(void); /** * Callbacks from Common DnD layer. */ void CommonResetCB(); void CommonUpdateMouseCB(int32 x, int32 y); /** * Source functions for HG DnD. */ void CommonDragStartCB(const CPClipboard *clip, std::string stagingDir); void CommonSourceDropCB(void); /** * Called when HG Dnd is completed. */ void CommonSourceCancelCB(void); /** * Called when GH DnD is completed. */ void CommonDestPrivateDropCB(int32 x, int32 y); void CommonDestCancelCB(void); /** * Source functions for file transfer. */ void CommonSourceFileCopyDoneCB(bool success); /** * Callbacks for showing/hiding detection window. */ void CommonUpdateDetWndCB(bool bShow, int32 x, int32 y); void CommonUpdateUnityDetWndCB(bool bShow, uint32 unityWndId, bool bottom); void CommonMoveDetWndToMousePos(void); /** * Gtk+ Callbacks: Drag Destination. */ void GtkDestDragDataReceivedCB(const Glib::RefPtr &dc, int x, int y, const Gtk::SelectionData &sd, guint info, guint time); bool GtkDestDragDropCB(const Glib::RefPtr &dc, int x, int y, guint time); void GtkDestDragLeaveCB(const Glib::RefPtr &dc, guint time); bool GtkDestDragMotionCB(const Glib::RefPtr &dc, int x, int y, guint time); /** * Gtk+ Callbacks: Drag Source. */ void GtkSourceDragBeginCB(const Glib::RefPtr& context); void GtkSourceDragDataGetCB(const Glib::RefPtr& context, Gtk::SelectionData& selection_data, guint info, guint time); void GtkSourceDragEndCB(const Glib::RefPtr& context); /** * Source functions for HG DnD. Makes calls to common layer. */ void SourceDragStartDone(void); void SourceUpdateFeedback(DND_DROPEFFECT effect); /** * Target function for GH DnD. Makes call to common layer. */ void TargetDragEnter(void); /* * Other signal handlers for tracing. */ bool GtkEnterEventCB(GdkEventCrossing *event); bool GtkLeaveEventCB(GdkEventCrossing *event); bool GtkMapEventCB(GdkEventAny *event); bool GtkUnmapEventCB(GdkEventAny *event); void GtkRealizeEventCB(); void GtkUnrealizeEventCB(); bool GtkMotionNotifyEventCB(GdkEventMotion *event); bool GtkConfigureEventCB(GdkEventConfigure *event); bool GtkButtonPressEventCB(GdkEventButton *event); bool GtkButtonReleaseEventCB(GdkEventButton *event); /** * Misc methods. */ bool SetCPClipboardFromGtk(const Gtk::SelectionData& sd); bool RequestData(const Glib::RefPtr &dc, guint timeValue); std::string GetLastDirName(const std::string &str); utf::utf8string GetNextPath(utf::utf8string &str, size_t& index); DND_DROPEFFECT ToDropEffect(Gdk::DragAction action); void SetTargetsAndCallbacks(); bool SendFakeXEvents(const bool showWidget, const bool buttonEvent, const bool buttonPress, const bool moveWindow, const bool coordsProvided, const int xCoord, const int yCoord); bool SendFakeMouseMove(const int x, const int y); bool WriteFileContentsToStagingDir(); unsigned long GetTimeInMillis(); ToolsAppCtx *m_ctx; GuestDnDMgr *m_DnD; std::string m_HGStagingDir; utf::string m_HGFileContentsUriList; DragDetWnd *m_detWnd; CPClipboard m_clipboard; DnDBlockControl *m_blockCtrl; DND_FILE_TRANSFER_STATUS m_HGGetFileStatus; int m_HGEffect; bool m_blockAdded; /* State to determine if drag motion is a drag enter. */ bool m_GHDnDInProgress; /* Icon updates from the guest. */ /* Only update mouse when we have clipboard contents from the host. */ bool m_GHDnDDataReceived; bool m_GHDnDDropOccurred; bool m_unityMode; bool m_inHGDrag; DND_DROPEFFECT m_effect; int32 m_mousePosX; int32 m_mousePosY; GdkDragContext *m_dc; int m_numPendingRequest; unsigned long m_destDropTime; uint64 mTotalFileSize; }; #endif // __DND_UI_X11_H__ open-vm-tools-9.4.0-1280544/services/plugins/dndcp/Makefile.in0000644765153500003110000020034512220061624022100 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = services/plugins/dndcp DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(plugin_LTLIBRARIES) libdndcp_la_DEPENDENCIES = am_libdndcp_la_OBJECTS = libdndcp_la-dndClipboard.lo \ libdndcp_la-dndCommon.lo libdndcp_la-dndCPMsgV4.lo \ libdndcp_la-dndLinux.lo libdndcp_la-dndMsg.lo \ libdndcp_la-copyPasteRpcV3.lo libdndcp_la-dndFileList.lo \ libdndcp_la-dndRpcV3.lo libdndcp_la-guestCopyPasteDest.lo \ libdndcp_la-guestCopyPasteMgr.lo \ libdndcp_la-guestCopyPasteSrc.lo libdndcp_la-guestDnDCPMgr.lo \ libdndcp_la-guestDnDDest.lo libdndcp_la-guestDnDMgr.lo \ libdndcp_la-guestDnDSrc.lo libdndcp_la-guestFileTransfer.lo \ libdndcp_la-copyPasteRpcV4.lo libdndcp_la-dndRpcV4.lo \ libdndcp_la-fileTransferRpcV4.lo libdndcp_la-rpcV3Util.lo \ libdndcp_la-rpcV4Util.lo libdndcp_la-dndCPTransportGuestRpc.lo \ libdndcp_la-string.lo libdndcp_la-copyPasteCompat.lo \ libdndcp_la-copyPasteCompatX11.lo \ libdndcp_la-copyPasteDnDWrapper.lo \ libdndcp_la-copyPasteDnDX11.lo libdndcp_la-copyPasteUIX11.lo \ libdndcp_la-dndUIX11.lo libdndcp_la-dndcp.lo \ libdndcp_la-dragDetWndX11.lo libdndcp_la-pointer.lo \ libdndcp_la-cpFileContents_xdr.lo libdndcp_la_OBJECTS = $(am_libdndcp_la_OBJECTS) libdndcp_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(libdndcp_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libdndcp_la_SOURCES) DIST_SOURCES = $(libdndcp_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ -Wno-unused COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ plugindir = @VMUSR_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libdndcp.la libdndcp_la_CPPFLAGS = @GTK_CPPFLAGS@ @GTKMM_CPPFLAGS@ \ @PLUGIN_CPPFLAGS@ -I$(top_srcdir)/services/plugins/dndcp/dnd \ -I$(top_srcdir)/services/plugins/dndcp/dndGuest \ -I$(top_srcdir)/services/plugins/dndcp/stringxx \ -I$(top_builddir)/include libdndcp_la_LDFLAGS = @PLUGIN_LDFLAGS@ libdndcp_la_LIBADD = @COMMON_XLIBS@ @GTK_LIBS@ @GTKMM_LIBS@ \ @VMTOOLS_LIBS@ @HGFS_LIBS@ $(am__empty) libdndcp_la_SOURCES = dnd/dndClipboard.c dnd/dndCommon.c \ dnd/dndCPMsgV4.c dnd/dndLinux.c dnd/dndMsg.c \ dndGuest/copyPasteRpcV3.cc dndGuest/dndFileList.cc \ dndGuest/dndRpcV3.cc dndGuest/guestCopyPasteDest.cc \ dndGuest/guestCopyPasteMgr.cc dndGuest/guestCopyPasteSrc.cc \ dndGuest/guestDnDCPMgr.cc dndGuest/guestDnDDest.cc \ dndGuest/guestDnDMgr.cc dndGuest/guestDnDSrc.cc \ dndGuest/guestFileTransfer.cc dndGuest/copyPasteRpcV4.cc \ dndGuest/dndRpcV4.cc dndGuest/fileTransferRpcV4.cc \ dndGuest/rpcV3Util.cpp dndGuest/rpcV4Util.cpp \ dndGuest/dndCPTransportGuestRpc.cpp stringxx/string.cc \ copyPasteCompat.c copyPasteCompatX11.c copyPasteDnDWrapper.cpp \ copyPasteDnDX11.cpp copyPasteUIX11.cpp dndUIX11.cpp dndcp.cpp \ dragDetWndX11.cpp pointer.cpp cpFileContents_xdr.c BUILT_SOURCES = cpFileContents.h cpFileContents_xdr.c CLEANFILES = $(BUILT_SOURCES) all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .cc .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu services/plugins/dndcp/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu services/plugins/dndcp/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ } uninstall-pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ done clean-pluginLTLIBRARIES: -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) @list='$(plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libdndcp.la: $(libdndcp_la_OBJECTS) $(libdndcp_la_DEPENDENCIES) $(EXTRA_libdndcp_la_DEPENDENCIES) $(libdndcp_la_LINK) -rpath $(plugindir) $(libdndcp_la_OBJECTS) $(libdndcp_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-copyPasteCompat.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-copyPasteCompatX11.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-copyPasteDnDWrapper.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-copyPasteDnDX11.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-copyPasteRpcV3.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-copyPasteRpcV4.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-copyPasteUIX11.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-cpFileContents_xdr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-dndCPMsgV4.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-dndCPTransportGuestRpc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-dndClipboard.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-dndCommon.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-dndFileList.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-dndLinux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-dndMsg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-dndRpcV3.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-dndRpcV4.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-dndUIX11.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-dndcp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-dragDetWndX11.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-fileTransferRpcV4.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-guestCopyPasteDest.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-guestCopyPasteMgr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-guestCopyPasteSrc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-guestDnDCPMgr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-guestDnDDest.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-guestDnDMgr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-guestDnDSrc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-guestFileTransfer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-pointer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-rpcV3Util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-rpcV4Util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdndcp_la-string.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libdndcp_la-dndClipboard.lo: dnd/dndClipboard.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdndcp_la-dndClipboard.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-dndClipboard.Tpo -c -o libdndcp_la-dndClipboard.lo `test -f 'dnd/dndClipboard.c' || echo '$(srcdir)/'`dnd/dndClipboard.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-dndClipboard.Tpo $(DEPDIR)/libdndcp_la-dndClipboard.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dnd/dndClipboard.c' object='libdndcp_la-dndClipboard.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdndcp_la-dndClipboard.lo `test -f 'dnd/dndClipboard.c' || echo '$(srcdir)/'`dnd/dndClipboard.c libdndcp_la-dndCommon.lo: dnd/dndCommon.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdndcp_la-dndCommon.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-dndCommon.Tpo -c -o libdndcp_la-dndCommon.lo `test -f 'dnd/dndCommon.c' || echo '$(srcdir)/'`dnd/dndCommon.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-dndCommon.Tpo $(DEPDIR)/libdndcp_la-dndCommon.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dnd/dndCommon.c' object='libdndcp_la-dndCommon.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdndcp_la-dndCommon.lo `test -f 'dnd/dndCommon.c' || echo '$(srcdir)/'`dnd/dndCommon.c libdndcp_la-dndCPMsgV4.lo: dnd/dndCPMsgV4.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdndcp_la-dndCPMsgV4.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-dndCPMsgV4.Tpo -c -o libdndcp_la-dndCPMsgV4.lo `test -f 'dnd/dndCPMsgV4.c' || echo '$(srcdir)/'`dnd/dndCPMsgV4.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-dndCPMsgV4.Tpo $(DEPDIR)/libdndcp_la-dndCPMsgV4.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dnd/dndCPMsgV4.c' object='libdndcp_la-dndCPMsgV4.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdndcp_la-dndCPMsgV4.lo `test -f 'dnd/dndCPMsgV4.c' || echo '$(srcdir)/'`dnd/dndCPMsgV4.c libdndcp_la-dndLinux.lo: dnd/dndLinux.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdndcp_la-dndLinux.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-dndLinux.Tpo -c -o libdndcp_la-dndLinux.lo `test -f 'dnd/dndLinux.c' || echo '$(srcdir)/'`dnd/dndLinux.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-dndLinux.Tpo $(DEPDIR)/libdndcp_la-dndLinux.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dnd/dndLinux.c' object='libdndcp_la-dndLinux.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdndcp_la-dndLinux.lo `test -f 'dnd/dndLinux.c' || echo '$(srcdir)/'`dnd/dndLinux.c libdndcp_la-dndMsg.lo: dnd/dndMsg.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdndcp_la-dndMsg.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-dndMsg.Tpo -c -o libdndcp_la-dndMsg.lo `test -f 'dnd/dndMsg.c' || echo '$(srcdir)/'`dnd/dndMsg.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-dndMsg.Tpo $(DEPDIR)/libdndcp_la-dndMsg.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dnd/dndMsg.c' object='libdndcp_la-dndMsg.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdndcp_la-dndMsg.lo `test -f 'dnd/dndMsg.c' || echo '$(srcdir)/'`dnd/dndMsg.c libdndcp_la-copyPasteCompat.lo: copyPasteCompat.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdndcp_la-copyPasteCompat.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-copyPasteCompat.Tpo -c -o libdndcp_la-copyPasteCompat.lo `test -f 'copyPasteCompat.c' || echo '$(srcdir)/'`copyPasteCompat.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-copyPasteCompat.Tpo $(DEPDIR)/libdndcp_la-copyPasteCompat.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='copyPasteCompat.c' object='libdndcp_la-copyPasteCompat.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdndcp_la-copyPasteCompat.lo `test -f 'copyPasteCompat.c' || echo '$(srcdir)/'`copyPasteCompat.c libdndcp_la-copyPasteCompatX11.lo: copyPasteCompatX11.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdndcp_la-copyPasteCompatX11.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-copyPasteCompatX11.Tpo -c -o libdndcp_la-copyPasteCompatX11.lo `test -f 'copyPasteCompatX11.c' || echo '$(srcdir)/'`copyPasteCompatX11.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-copyPasteCompatX11.Tpo $(DEPDIR)/libdndcp_la-copyPasteCompatX11.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='copyPasteCompatX11.c' object='libdndcp_la-copyPasteCompatX11.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdndcp_la-copyPasteCompatX11.lo `test -f 'copyPasteCompatX11.c' || echo '$(srcdir)/'`copyPasteCompatX11.c libdndcp_la-cpFileContents_xdr.lo: cpFileContents_xdr.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdndcp_la-cpFileContents_xdr.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-cpFileContents_xdr.Tpo -c -o libdndcp_la-cpFileContents_xdr.lo `test -f 'cpFileContents_xdr.c' || echo '$(srcdir)/'`cpFileContents_xdr.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-cpFileContents_xdr.Tpo $(DEPDIR)/libdndcp_la-cpFileContents_xdr.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cpFileContents_xdr.c' object='libdndcp_la-cpFileContents_xdr.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdndcp_la-cpFileContents_xdr.lo `test -f 'cpFileContents_xdr.c' || echo '$(srcdir)/'`cpFileContents_xdr.c .cc.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< libdndcp_la-copyPasteRpcV3.lo: dndGuest/copyPasteRpcV3.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-copyPasteRpcV3.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-copyPasteRpcV3.Tpo -c -o libdndcp_la-copyPasteRpcV3.lo `test -f 'dndGuest/copyPasteRpcV3.cc' || echo '$(srcdir)/'`dndGuest/copyPasteRpcV3.cc @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-copyPasteRpcV3.Tpo $(DEPDIR)/libdndcp_la-copyPasteRpcV3.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dndGuest/copyPasteRpcV3.cc' object='libdndcp_la-copyPasteRpcV3.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-copyPasteRpcV3.lo `test -f 'dndGuest/copyPasteRpcV3.cc' || echo '$(srcdir)/'`dndGuest/copyPasteRpcV3.cc libdndcp_la-dndFileList.lo: dndGuest/dndFileList.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-dndFileList.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-dndFileList.Tpo -c -o libdndcp_la-dndFileList.lo `test -f 'dndGuest/dndFileList.cc' || echo '$(srcdir)/'`dndGuest/dndFileList.cc @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-dndFileList.Tpo $(DEPDIR)/libdndcp_la-dndFileList.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dndGuest/dndFileList.cc' object='libdndcp_la-dndFileList.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-dndFileList.lo `test -f 'dndGuest/dndFileList.cc' || echo '$(srcdir)/'`dndGuest/dndFileList.cc libdndcp_la-dndRpcV3.lo: dndGuest/dndRpcV3.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-dndRpcV3.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-dndRpcV3.Tpo -c -o libdndcp_la-dndRpcV3.lo `test -f 'dndGuest/dndRpcV3.cc' || echo '$(srcdir)/'`dndGuest/dndRpcV3.cc @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-dndRpcV3.Tpo $(DEPDIR)/libdndcp_la-dndRpcV3.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dndGuest/dndRpcV3.cc' object='libdndcp_la-dndRpcV3.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-dndRpcV3.lo `test -f 'dndGuest/dndRpcV3.cc' || echo '$(srcdir)/'`dndGuest/dndRpcV3.cc libdndcp_la-guestCopyPasteDest.lo: dndGuest/guestCopyPasteDest.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-guestCopyPasteDest.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-guestCopyPasteDest.Tpo -c -o libdndcp_la-guestCopyPasteDest.lo `test -f 'dndGuest/guestCopyPasteDest.cc' || echo '$(srcdir)/'`dndGuest/guestCopyPasteDest.cc @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-guestCopyPasteDest.Tpo $(DEPDIR)/libdndcp_la-guestCopyPasteDest.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dndGuest/guestCopyPasteDest.cc' object='libdndcp_la-guestCopyPasteDest.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-guestCopyPasteDest.lo `test -f 'dndGuest/guestCopyPasteDest.cc' || echo '$(srcdir)/'`dndGuest/guestCopyPasteDest.cc libdndcp_la-guestCopyPasteMgr.lo: dndGuest/guestCopyPasteMgr.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-guestCopyPasteMgr.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-guestCopyPasteMgr.Tpo -c -o libdndcp_la-guestCopyPasteMgr.lo `test -f 'dndGuest/guestCopyPasteMgr.cc' || echo '$(srcdir)/'`dndGuest/guestCopyPasteMgr.cc @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-guestCopyPasteMgr.Tpo $(DEPDIR)/libdndcp_la-guestCopyPasteMgr.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dndGuest/guestCopyPasteMgr.cc' object='libdndcp_la-guestCopyPasteMgr.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-guestCopyPasteMgr.lo `test -f 'dndGuest/guestCopyPasteMgr.cc' || echo '$(srcdir)/'`dndGuest/guestCopyPasteMgr.cc libdndcp_la-guestCopyPasteSrc.lo: dndGuest/guestCopyPasteSrc.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-guestCopyPasteSrc.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-guestCopyPasteSrc.Tpo -c -o libdndcp_la-guestCopyPasteSrc.lo `test -f 'dndGuest/guestCopyPasteSrc.cc' || echo '$(srcdir)/'`dndGuest/guestCopyPasteSrc.cc @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-guestCopyPasteSrc.Tpo $(DEPDIR)/libdndcp_la-guestCopyPasteSrc.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dndGuest/guestCopyPasteSrc.cc' object='libdndcp_la-guestCopyPasteSrc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-guestCopyPasteSrc.lo `test -f 'dndGuest/guestCopyPasteSrc.cc' || echo '$(srcdir)/'`dndGuest/guestCopyPasteSrc.cc libdndcp_la-guestDnDCPMgr.lo: dndGuest/guestDnDCPMgr.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-guestDnDCPMgr.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-guestDnDCPMgr.Tpo -c -o libdndcp_la-guestDnDCPMgr.lo `test -f 'dndGuest/guestDnDCPMgr.cc' || echo '$(srcdir)/'`dndGuest/guestDnDCPMgr.cc @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-guestDnDCPMgr.Tpo $(DEPDIR)/libdndcp_la-guestDnDCPMgr.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dndGuest/guestDnDCPMgr.cc' object='libdndcp_la-guestDnDCPMgr.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-guestDnDCPMgr.lo `test -f 'dndGuest/guestDnDCPMgr.cc' || echo '$(srcdir)/'`dndGuest/guestDnDCPMgr.cc libdndcp_la-guestDnDDest.lo: dndGuest/guestDnDDest.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-guestDnDDest.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-guestDnDDest.Tpo -c -o libdndcp_la-guestDnDDest.lo `test -f 'dndGuest/guestDnDDest.cc' || echo '$(srcdir)/'`dndGuest/guestDnDDest.cc @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-guestDnDDest.Tpo $(DEPDIR)/libdndcp_la-guestDnDDest.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dndGuest/guestDnDDest.cc' object='libdndcp_la-guestDnDDest.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-guestDnDDest.lo `test -f 'dndGuest/guestDnDDest.cc' || echo '$(srcdir)/'`dndGuest/guestDnDDest.cc libdndcp_la-guestDnDMgr.lo: dndGuest/guestDnDMgr.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-guestDnDMgr.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-guestDnDMgr.Tpo -c -o libdndcp_la-guestDnDMgr.lo `test -f 'dndGuest/guestDnDMgr.cc' || echo '$(srcdir)/'`dndGuest/guestDnDMgr.cc @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-guestDnDMgr.Tpo $(DEPDIR)/libdndcp_la-guestDnDMgr.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dndGuest/guestDnDMgr.cc' object='libdndcp_la-guestDnDMgr.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-guestDnDMgr.lo `test -f 'dndGuest/guestDnDMgr.cc' || echo '$(srcdir)/'`dndGuest/guestDnDMgr.cc libdndcp_la-guestDnDSrc.lo: dndGuest/guestDnDSrc.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-guestDnDSrc.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-guestDnDSrc.Tpo -c -o libdndcp_la-guestDnDSrc.lo `test -f 'dndGuest/guestDnDSrc.cc' || echo '$(srcdir)/'`dndGuest/guestDnDSrc.cc @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-guestDnDSrc.Tpo $(DEPDIR)/libdndcp_la-guestDnDSrc.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dndGuest/guestDnDSrc.cc' object='libdndcp_la-guestDnDSrc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-guestDnDSrc.lo `test -f 'dndGuest/guestDnDSrc.cc' || echo '$(srcdir)/'`dndGuest/guestDnDSrc.cc libdndcp_la-guestFileTransfer.lo: dndGuest/guestFileTransfer.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-guestFileTransfer.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-guestFileTransfer.Tpo -c -o libdndcp_la-guestFileTransfer.lo `test -f 'dndGuest/guestFileTransfer.cc' || echo '$(srcdir)/'`dndGuest/guestFileTransfer.cc @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-guestFileTransfer.Tpo $(DEPDIR)/libdndcp_la-guestFileTransfer.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dndGuest/guestFileTransfer.cc' object='libdndcp_la-guestFileTransfer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-guestFileTransfer.lo `test -f 'dndGuest/guestFileTransfer.cc' || echo '$(srcdir)/'`dndGuest/guestFileTransfer.cc libdndcp_la-copyPasteRpcV4.lo: dndGuest/copyPasteRpcV4.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-copyPasteRpcV4.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-copyPasteRpcV4.Tpo -c -o libdndcp_la-copyPasteRpcV4.lo `test -f 'dndGuest/copyPasteRpcV4.cc' || echo '$(srcdir)/'`dndGuest/copyPasteRpcV4.cc @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-copyPasteRpcV4.Tpo $(DEPDIR)/libdndcp_la-copyPasteRpcV4.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dndGuest/copyPasteRpcV4.cc' object='libdndcp_la-copyPasteRpcV4.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-copyPasteRpcV4.lo `test -f 'dndGuest/copyPasteRpcV4.cc' || echo '$(srcdir)/'`dndGuest/copyPasteRpcV4.cc libdndcp_la-dndRpcV4.lo: dndGuest/dndRpcV4.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-dndRpcV4.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-dndRpcV4.Tpo -c -o libdndcp_la-dndRpcV4.lo `test -f 'dndGuest/dndRpcV4.cc' || echo '$(srcdir)/'`dndGuest/dndRpcV4.cc @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-dndRpcV4.Tpo $(DEPDIR)/libdndcp_la-dndRpcV4.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dndGuest/dndRpcV4.cc' object='libdndcp_la-dndRpcV4.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-dndRpcV4.lo `test -f 'dndGuest/dndRpcV4.cc' || echo '$(srcdir)/'`dndGuest/dndRpcV4.cc libdndcp_la-fileTransferRpcV4.lo: dndGuest/fileTransferRpcV4.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-fileTransferRpcV4.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-fileTransferRpcV4.Tpo -c -o libdndcp_la-fileTransferRpcV4.lo `test -f 'dndGuest/fileTransferRpcV4.cc' || echo '$(srcdir)/'`dndGuest/fileTransferRpcV4.cc @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-fileTransferRpcV4.Tpo $(DEPDIR)/libdndcp_la-fileTransferRpcV4.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dndGuest/fileTransferRpcV4.cc' object='libdndcp_la-fileTransferRpcV4.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-fileTransferRpcV4.lo `test -f 'dndGuest/fileTransferRpcV4.cc' || echo '$(srcdir)/'`dndGuest/fileTransferRpcV4.cc libdndcp_la-rpcV3Util.lo: dndGuest/rpcV3Util.cpp @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-rpcV3Util.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-rpcV3Util.Tpo -c -o libdndcp_la-rpcV3Util.lo `test -f 'dndGuest/rpcV3Util.cpp' || echo '$(srcdir)/'`dndGuest/rpcV3Util.cpp @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-rpcV3Util.Tpo $(DEPDIR)/libdndcp_la-rpcV3Util.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dndGuest/rpcV3Util.cpp' object='libdndcp_la-rpcV3Util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-rpcV3Util.lo `test -f 'dndGuest/rpcV3Util.cpp' || echo '$(srcdir)/'`dndGuest/rpcV3Util.cpp libdndcp_la-rpcV4Util.lo: dndGuest/rpcV4Util.cpp @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-rpcV4Util.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-rpcV4Util.Tpo -c -o libdndcp_la-rpcV4Util.lo `test -f 'dndGuest/rpcV4Util.cpp' || echo '$(srcdir)/'`dndGuest/rpcV4Util.cpp @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-rpcV4Util.Tpo $(DEPDIR)/libdndcp_la-rpcV4Util.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dndGuest/rpcV4Util.cpp' object='libdndcp_la-rpcV4Util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-rpcV4Util.lo `test -f 'dndGuest/rpcV4Util.cpp' || echo '$(srcdir)/'`dndGuest/rpcV4Util.cpp libdndcp_la-dndCPTransportGuestRpc.lo: dndGuest/dndCPTransportGuestRpc.cpp @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-dndCPTransportGuestRpc.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-dndCPTransportGuestRpc.Tpo -c -o libdndcp_la-dndCPTransportGuestRpc.lo `test -f 'dndGuest/dndCPTransportGuestRpc.cpp' || echo '$(srcdir)/'`dndGuest/dndCPTransportGuestRpc.cpp @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-dndCPTransportGuestRpc.Tpo $(DEPDIR)/libdndcp_la-dndCPTransportGuestRpc.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dndGuest/dndCPTransportGuestRpc.cpp' object='libdndcp_la-dndCPTransportGuestRpc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-dndCPTransportGuestRpc.lo `test -f 'dndGuest/dndCPTransportGuestRpc.cpp' || echo '$(srcdir)/'`dndGuest/dndCPTransportGuestRpc.cpp libdndcp_la-string.lo: stringxx/string.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-string.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-string.Tpo -c -o libdndcp_la-string.lo `test -f 'stringxx/string.cc' || echo '$(srcdir)/'`stringxx/string.cc @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-string.Tpo $(DEPDIR)/libdndcp_la-string.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='stringxx/string.cc' object='libdndcp_la-string.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-string.lo `test -f 'stringxx/string.cc' || echo '$(srcdir)/'`stringxx/string.cc libdndcp_la-copyPasteDnDWrapper.lo: copyPasteDnDWrapper.cpp @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-copyPasteDnDWrapper.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-copyPasteDnDWrapper.Tpo -c -o libdndcp_la-copyPasteDnDWrapper.lo `test -f 'copyPasteDnDWrapper.cpp' || echo '$(srcdir)/'`copyPasteDnDWrapper.cpp @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-copyPasteDnDWrapper.Tpo $(DEPDIR)/libdndcp_la-copyPasteDnDWrapper.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='copyPasteDnDWrapper.cpp' object='libdndcp_la-copyPasteDnDWrapper.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-copyPasteDnDWrapper.lo `test -f 'copyPasteDnDWrapper.cpp' || echo '$(srcdir)/'`copyPasteDnDWrapper.cpp libdndcp_la-copyPasteDnDX11.lo: copyPasteDnDX11.cpp @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-copyPasteDnDX11.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-copyPasteDnDX11.Tpo -c -o libdndcp_la-copyPasteDnDX11.lo `test -f 'copyPasteDnDX11.cpp' || echo '$(srcdir)/'`copyPasteDnDX11.cpp @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-copyPasteDnDX11.Tpo $(DEPDIR)/libdndcp_la-copyPasteDnDX11.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='copyPasteDnDX11.cpp' object='libdndcp_la-copyPasteDnDX11.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-copyPasteDnDX11.lo `test -f 'copyPasteDnDX11.cpp' || echo '$(srcdir)/'`copyPasteDnDX11.cpp libdndcp_la-copyPasteUIX11.lo: copyPasteUIX11.cpp @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-copyPasteUIX11.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-copyPasteUIX11.Tpo -c -o libdndcp_la-copyPasteUIX11.lo `test -f 'copyPasteUIX11.cpp' || echo '$(srcdir)/'`copyPasteUIX11.cpp @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-copyPasteUIX11.Tpo $(DEPDIR)/libdndcp_la-copyPasteUIX11.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='copyPasteUIX11.cpp' object='libdndcp_la-copyPasteUIX11.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-copyPasteUIX11.lo `test -f 'copyPasteUIX11.cpp' || echo '$(srcdir)/'`copyPasteUIX11.cpp libdndcp_la-dndUIX11.lo: dndUIX11.cpp @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-dndUIX11.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-dndUIX11.Tpo -c -o libdndcp_la-dndUIX11.lo `test -f 'dndUIX11.cpp' || echo '$(srcdir)/'`dndUIX11.cpp @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-dndUIX11.Tpo $(DEPDIR)/libdndcp_la-dndUIX11.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dndUIX11.cpp' object='libdndcp_la-dndUIX11.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-dndUIX11.lo `test -f 'dndUIX11.cpp' || echo '$(srcdir)/'`dndUIX11.cpp libdndcp_la-dndcp.lo: dndcp.cpp @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-dndcp.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-dndcp.Tpo -c -o libdndcp_la-dndcp.lo `test -f 'dndcp.cpp' || echo '$(srcdir)/'`dndcp.cpp @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-dndcp.Tpo $(DEPDIR)/libdndcp_la-dndcp.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dndcp.cpp' object='libdndcp_la-dndcp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-dndcp.lo `test -f 'dndcp.cpp' || echo '$(srcdir)/'`dndcp.cpp libdndcp_la-dragDetWndX11.lo: dragDetWndX11.cpp @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-dragDetWndX11.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-dragDetWndX11.Tpo -c -o libdndcp_la-dragDetWndX11.lo `test -f 'dragDetWndX11.cpp' || echo '$(srcdir)/'`dragDetWndX11.cpp @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-dragDetWndX11.Tpo $(DEPDIR)/libdndcp_la-dragDetWndX11.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dragDetWndX11.cpp' object='libdndcp_la-dragDetWndX11.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-dragDetWndX11.lo `test -f 'dragDetWndX11.cpp' || echo '$(srcdir)/'`dragDetWndX11.cpp libdndcp_la-pointer.lo: pointer.cpp @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdndcp_la-pointer.lo -MD -MP -MF $(DEPDIR)/libdndcp_la-pointer.Tpo -c -o libdndcp_la-pointer.lo `test -f 'pointer.cpp' || echo '$(srcdir)/'`pointer.cpp @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libdndcp_la-pointer.Tpo $(DEPDIR)/libdndcp_la-pointer.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='pointer.cpp' object='libdndcp_la-pointer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdndcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdndcp_la-pointer.lo `test -f 'pointer.cpp' || echo '$(srcdir)/'`pointer.cpp .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(plugindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pluginLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pluginLTLIBRARIES .MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-pluginLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-pluginLTLIBRARIES install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-pluginLTLIBRARIES cpFileContents.h: cpFileContents.x @RPCGEN_WRAPPER@ services/plugins/dndcp/cpFileContents.x $@ cpFileContents_xdr.c: cpFileContents.x cpFileContents.h @RPCGEN_WRAPPER@ services/plugins/dndcp/cpFileContents.x $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/services/plugins/vix/0000755765153500003110000000000012220061625017546 5ustar dtormtsopen-vm-tools-9.4.0-1280544/services/plugins/vix/vixPluginInt.h0000644765153500003110000000333212220061556022363 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _VIXPLUGININT_H_ #define _VIXPLUGININT_H_ /** * @file vixPluginInt.h * * Prototypes of VIX RPC handlers found in foundryToolsDaemon.c. */ #define Debug g_debug #define Warning g_warning #include "vmware/tools/guestrpc.h" #include "vmware/tools/plugin.h" void FoundryToolsDaemon_Initialize(ToolsAppCtx *ctx); void FoundryToolsDaemon_Uninitialize(ToolsAppCtx *ctx); gboolean FoundryToolsDaemonGetToolsProperties(RpcInData *data); gboolean ToolsDaemonHgfsImpersonated(RpcInData *data); gboolean ToolsDaemonTcloMountHGFS(RpcInData *data); gboolean ToolsDaemonTcloReceiveVixCommand(RpcInData *data); gboolean FoundryToolsDaemonRunProgram(RpcInData *data); #if defined(linux) || defined(_WIN32) gboolean ToolsDaemonTcloSyncDriverFreeze(RpcInData *data); gboolean ToolsDaemonTcloSyncDriverThaw(RpcInData *data); #endif #endif /* _VIXPLUGININT_H_ */ open-vm-tools-9.4.0-1280544/services/plugins/vix/vixPlugin.c0000644765153500003110000000707412220061556021712 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file vixPlugin.c * * Tools Service entry point for the VIX plugin. */ #define G_LOG_DOMAIN "vix" #include #include "vmware.h" #include "syncDriver.h" #include "vixCommands.h" #include "vixPluginInt.h" #include "vmware/tools/utils.h" #if !defined(__APPLE__) #include "embed_version.h" #include "vmtoolsd_version.h" VM_EMBED_VERSION(VMTOOLSD_VERSION_STRING); #endif /** * Clean up internal state on shutdown. * * @param[in] src The source object. * @param[in] ctx Unused. * @param[in] plugin Plugin registration data. */ static void VixShutdown(gpointer src, ToolsAppCtx *ctx, ToolsPluginData *plugin) { FoundryToolsDaemon_Uninitialize(ctx); } /** * Returns the registration data for either the guestd or userd process. * * @param[in] ctx The application context. * * @return The registration data. */ TOOLS_MODULE_EXPORT ToolsPluginData * ToolsOnLoad(ToolsAppCtx *ctx) { static ToolsPluginData regData = { "vix", NULL, NULL }; RpcChannelCallback rpcs[] = { { VIX_BACKDOORCOMMAND_RUN_PROGRAM, FoundryToolsDaemonRunProgram, NULL, NULL, NULL, 0 }, { VIX_BACKDOORCOMMAND_GET_PROPERTIES, FoundryToolsDaemonGetToolsProperties, NULL, NULL, 0 }, { VIX_BACKDOORCOMMAND_SEND_HGFS_PACKET, ToolsDaemonHgfsImpersonated, NULL, NULL, NULL, 0 }, { VIX_BACKDOORCOMMAND_COMMAND, ToolsDaemonTcloReceiveVixCommand, NULL, NULL, 0 }, { VIX_BACKDOORCOMMAND_MOUNT_VOLUME_LIST, ToolsDaemonTcloMountHGFS, NULL, NULL, NULL, 0 }, #if defined(_WIN32) || defined(linux) { VIX_BACKDOORCOMMAND_SYNCDRIVER_FREEZE, ToolsDaemonTcloSyncDriverFreeze, NULL, NULL, NULL, 0 }, { VIX_BACKDOORCOMMAND_SYNCDRIVER_THAW, ToolsDaemonTcloSyncDriverThaw, NULL, NULL, NULL, 0 } #endif }; ToolsPluginSignalCb sigs[] = { { TOOLS_CORE_SIG_SHUTDOWN, VixShutdown, ®Data } }; ToolsAppReg regs[] = { { TOOLS_APP_GUESTRPC, VMTools_WrapArray(rpcs, sizeof *rpcs, ARRAYSIZE(rpcs)) }, { TOOLS_APP_SIGNALS, VMTools_WrapArray(sigs, sizeof *sigs, ARRAYSIZE(sigs)) } }; #if defined(G_PLATFORM_WIN32) ToolsCore_InitializeCOM(ctx); #endif FoundryToolsDaemon_Initialize(ctx); regData.regs = VMTools_WrapArray(regs, sizeof *regs, ARRAYSIZE(regs)); /* * If running the user daemon or if the sync driver is not active, remove * the last two elements of the RPC registration array, so that the sync * driver RPC commands are ignored. */ #if defined(_WIN32) || defined(linux) if (strcmp(ctx->name, VMTOOLS_GUEST_SERVICE) != 0 || !SyncDriver_Init()) { g_array_remove_range(regs[0].data, regs[0].data->len - 2, 2); } #endif return ®Data; } open-vm-tools-9.4.0-1280544/services/plugins/vix/COPYING0000644765153500003110000006347112220061556020617 0ustar dtormts GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! open-vm-tools-9.4.0-1280544/services/plugins/vix/Makefile.am0000644765153500003110000000302512220061556021605 0ustar dtormts################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ plugindir = @COMMON_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libvix.la libvix_la_CPPFLAGS = libvix_la_CPPFLAGS += @PLUGIN_CPPFLAGS@ libvix_la_LDFLAGS = libvix_la_LDFLAGS += @PLUGIN_LDFLAGS@ libvix_la_LIBADD = libvix_la_LIBADD += @VIX_LIBADD@ libvix_la_LIBADD += @VMTOOLS_LIBS@ libvix_la_LIBADD += @HGFS_LIBS@ libvix_la_LIBADD += $(top_builddir)/lib/auth/libAuth.la libvix_la_LIBADD += $(top_builddir)/lib/foundryMsg/libFoundryMsg.la libvix_la_LIBADD += $(top_builddir)/lib/impersonate/libImpersonate.la libvix_la_SOURCES = libvix_la_SOURCES += foundryToolsDaemon.c libvix_la_SOURCES += vixPlugin.c libvix_la_SOURCES += vixTools.c libvix_la_SOURCES += vixToolsEnvVars.c open-vm-tools-9.4.0-1280544/services/plugins/vix/vixToolsInt.h0000644765153500003110000001515112220061556022227 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vixToolsInt.h -- * * Helper routines shared between different files in the vixTools * module. */ #ifndef __VIX_TOOLS_INT_H__ #define __VIX_TOOLS_INT_H__ #include "vmware.h" #include "vix.h" #include "vixCommands.h" #include #define PROCESS_CREATOR_USER_TOKEN ((void *)1) #ifdef _WIN32 #define VIX_TOOLS_MAX_SSPI_SESSIONS 50 #define VIX_TOOLS_MAX_TICKETED_SESSIONS 50 #endif typedef struct VixToolsEnvIterator VixToolsEnvIterator; typedef struct VixToolsUserEnvironment VixToolsUserEnvironment; typedef void (*VixToolsReportProgramDoneProcType)(const char *requestName, VixError err, int exitCode, int64 pid, void *clientData); VixError VixTools_Initialize(Bool thisProcessRunsAsRootArg, const char * const *originalEnvp, VixToolsReportProgramDoneProcType reportProgramDoneProc, void *clientData); void VixTools_Uninitialize(void); VixError VixToolsImpersonateUser(VixCommandRequestHeader *requestMsg, void **userToken); void VixTools_SetConsoleUserPolicy(Bool allowConsoleUserOpsParam); void VixTools_SetRunProgramCallback(VixToolsReportProgramDoneProcType reportProgramDoneProc, void *clientData); /* * These are internal procedures that are exposed for the legacy * tclo callbacks. */ VixError VixToolsRunProgramImpl(char *requestName, const char *commandLine, const char *commandLineArgs, int runProgramOptions, void *userToken, void *eventQueue, int64 *pid); VixError VixTools_GetToolsPropertiesImpl(GKeyFile *confDictRef, char **resultBuffer, size_t *resultBufferLength); VixError VixTools_ProcessVixCommand(VixCommandRequestHeader *requestMsg, char *requestName, size_t maxResultBufferSize, GKeyFile *confDictRef, GMainLoop *eventQueue, char **resultBuffer, size_t *resultLen, Bool *deleteResultBufferResult); uint32 VixTools_GetAdditionalError(uint32 opCode, VixError error); Bool VixToolsImpersonateUserImpl(char const *credentialTypeStr, int credentialType, char const *password, void **userToken); void VixToolsUnimpersonateUser(void *userToken); void VixToolsLogoutUser(void *userToken); VixError VixToolsNewEnvIterator(void *userToken, #ifdef __FreeBSD__ char **envp, #endif VixToolsEnvIterator **envItr); char *VixToolsGetNextEnvVar(VixToolsEnvIterator *envItr); void VixToolsDestroyEnvIterator(VixToolsEnvIterator *envItr); VixError VixToolsNewUserEnvironment(void *userToken, VixToolsUserEnvironment **env); char *VixToolsGetEnvFromUserEnvironment(const VixToolsUserEnvironment *env, const char *name); void VixToolsDestroyUserEnvironment(VixToolsUserEnvironment *env); VixError VixToolsValidateEnviron(char const * const *environ); char *VixToolsGetEnvVarFromEnvBlock(const wchar_t *envBlock, const char *envVarName); char *VixToolsEscapeXMLString(const char *str); #ifdef _WIN32 VixError VixToolsInitializeWin32(); Bool VixToolsGetUserName(wchar_t **userName); VixError VixToolsGetEnvBlock(void *userToken, wchar_t **envBlock); Bool VixToolsDestroyEnvironmentBlock(wchar_t *envBlock); VixError VixToolsEnvironToEnvBlock(char const * const *environ, wchar_t **envBlock); VixError VixToolsGetUserTmpDir(void *userToken, char **tmpDirPath); Bool VixToolsUserIsMemberOfAdministratorGroup(VixCommandRequestHeader *requestMsg); void VixToolsDeinitSspiSessionList(); void VixToolsDeinitTicketedSessionList(); VixError VixToolsAuthenticateWithSSPI(VixCommandRequestHeader *requestMsg, GMainLoop *eventQueue, char **resultBuffer); VixError VixToolsGetTokenHandleFromTicketID(const char *ticketID, char **username, HANDLE *hToken); VixError VixToolsReleaseCredentialsImpl(VixCommandRequestHeader *requestMsg); VixError VixToolsCreateRegKeyImpl(VixCommandRequestHeader *requestMsg); VixError VixToolsListRegKeysImpl(VixCommandRequestHeader *requestMsg, size_t maxBufferSize, void *eventQueue, char **result); VixError VixToolsDeleteRegKeyImpl(VixCommandRequestHeader *requestMsg); VixError VixToolsSetRegValueImpl(VixCommandRequestHeader *requestMsg); VixError VixToolsListRegValuesImpl(VixCommandRequestHeader *requestMsg, size_t maxBufferSize, void *eventQueue, char **result); VixError VixToolsDeleteRegValueImpl(VixCommandRequestHeader *requestMsg); #endif // _WIN32 #ifdef VMX86_DEVEL void TestVixToolsEnvVars(void); #endif #endif // #ifndef __VIX_TOOLS_INT_H__ open-vm-tools-9.4.0-1280544/services/plugins/vix/vixToolsEnvVars.c0000644765153500003110000004157512220061556023065 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vixToolsEnvVars.c -- * * Routines that encapsulate the complexity of dealing with * environment variables when the process may be impersonating * a user. */ #include #ifdef __APPLE__ #include #endif #include "util.h" #include "unicode.h" #include "dynbuf.h" #include "str.h" #include "posix.h" #include "vixToolsInt.h" #ifndef _WIN32 extern char **environ; #endif struct VixToolsEnvIterator { #ifdef _WIN32 enum { VIX_TOOLS_ENV_TYPE_ENV_BLOCK = 1, VIX_TOOLS_ENV_TYPE_ENVIRON, } envType; union { /* Used when envType is VIX_TOOLS_ENV_TYPE_ENV_BLOCK. */ struct { wchar_t *envBlock; // Keep the original around to free. wchar_t *currEnvVar; } eb; /* Used when envType is VIX_TOOLS_ENV_TYPE_ENVIRON. */ wchar_t **environ; } data; #else char **environ; #endif }; struct VixToolsUserEnvironment { #ifdef _WIN32 Bool impersonated; wchar_t *envBlock; // Only used when impersonated == TRUE. #else // The POSIX versions don't need any state currently. #endif }; /* *----------------------------------------------------------------------------- * * VixToolsNewEnvIterator -- * * Create a new environment variable iterator for the user * represented by 'userToken'. * The resulting VixToolsEnvIterator must be freed using * VixToolsDestroyEnvIterator. * * Results: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsNewEnvIterator(void *userToken, // IN #ifdef __FreeBSD__ char **envp, // IN #endif VixToolsEnvIterator **envItr) // OUT { VixError err = VIX_OK; VixToolsEnvIterator *it = Util_SafeMalloc(sizeof *it); if (NULL == envItr) { err = VIX_E_FAIL; goto abort; } *envItr = NULL; #ifdef _WIN32 if (PROCESS_CREATOR_USER_TOKEN != userToken) { /* * The process is impersonating a user, so retrieve the user's * environment block instead of using the process's environment. */ it->envType = VIX_TOOLS_ENV_TYPE_ENV_BLOCK; err = VixToolsGetEnvBlock(userToken, &it->data.eb.envBlock); if (VIX_FAILED(err)) { goto abort; } it->data.eb.currEnvVar = it->data.eb.envBlock; } else { /* * The action is being performed as the user running the process * so the process's environment is fine. * TODO: Is this totally equivilent to the behavior when impersonated? * Would fetching the environment block include changes to the user's * or system's environment made after the process is running? */ it->envType = VIX_TOOLS_ENV_TYPE_ENVIRON; it->data.environ = _wenviron; } #elif defined(__APPLE__) it->environ = *_NSGetEnviron(); #elif defined(__FreeBSD__) it->environ = envp; #else it->environ = environ; #endif *envItr = it; abort: if (VIX_FAILED(err)) { free(it); } return err; } /* *----------------------------------------------------------------------------- * * VixToolsGetNextEnvVar -- * * Get the next envariable variable pair in the form NAME=VALUE. * * Results: * A heap-allocated UTF-8 string, or NULL when the iterator has * reached the end. * * Side effects: * Advances the iterator. * *----------------------------------------------------------------------------- */ char * VixToolsGetNextEnvVar(VixToolsEnvIterator *envItr) // IN { char *envVar; if (NULL == envItr) { return NULL; } #ifdef _WIN32 if (VIX_TOOLS_ENV_TYPE_ENV_BLOCK == envItr->envType) { if (L'\0' == envItr->data.eb.currEnvVar[0]) { envVar = NULL; } else { envVar = Unicode_AllocWithUTF16(envItr->data.eb.currEnvVar); while(*envItr->data.eb.currEnvVar++); } } else if (VIX_TOOLS_ENV_TYPE_ENVIRON == envItr->envType) { if (NULL == *envItr->data.environ) { envVar = NULL; } else { envVar = Unicode_AllocWithUTF16(*envItr->data.environ); envItr->data.environ++; } } else { /* Is someone using uninitialized memory? */ NOT_IMPLEMENTED(); } #else if (NULL == *envItr->environ) { envVar = NULL; } else { envVar = Unicode_Alloc(*envItr->environ, STRING_ENCODING_DEFAULT); envItr->environ++; } #endif return envVar; } /* *----------------------------------------------------------------------------- * * VixToolsDestroyEnvIterator -- * * Free()s any memory associated with the VixToolsEnvIterator. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void VixToolsDestroyEnvIterator(VixToolsEnvIterator *envItr) // IN { if (NULL != envItr) { #ifdef _WIN32 if (VIX_TOOLS_ENV_TYPE_ENV_BLOCK == envItr->envType) { if (NULL != envItr->data.eb.envBlock) { VixToolsDestroyEnvironmentBlock(envItr->data.eb.envBlock); } } #endif free(envItr); } } /* *----------------------------------------------------------------------------- * * VixToolsNewUserEnvironment -- * * Create a new UserEnvironment that can be used to query for * environment variables. * * Results: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsNewUserEnvironment(void *userToken, // IN VixToolsUserEnvironment **env) // OUT { VixError err = VIX_OK; VixToolsUserEnvironment *myEnv = Util_SafeMalloc(sizeof *myEnv); if (NULL == env) { err = VIX_E_FAIL; goto abort; } *env = NULL; #ifdef _WIN32 if (PROCESS_CREATOR_USER_TOKEN != userToken) { myEnv->impersonated = TRUE; err = VixToolsGetEnvBlock(userToken, &myEnv->envBlock); if (VIX_FAILED(err)) { goto abort; } } else { myEnv->impersonated = FALSE; /* We will just read from the process's environment. */ } #endif *env = myEnv; abort: if (VIX_FAILED(err)) { free(myEnv); } return err; } /* *----------------------------------------------------------------------------- * * VixToolsGetEnvFromUserEnvironment -- * * Looks up the environment variable given by 'name' in the provided * user environment. * * Results: * A heap-allocated UTF-8 string, or NULL if the environment variable * is not found. * * Side effects: * None * *----------------------------------------------------------------------------- */ char * VixToolsGetEnvFromUserEnvironment(const VixToolsUserEnvironment *env, // IN const char *name) // IN { char *envVar; if (NULL == env) { return NULL; } #ifdef _WIN32 if (env->impersonated) { envVar = VixToolsGetEnvVarFromEnvBlock(env->envBlock, name); } else { envVar = Util_SafeStrdup(Posix_Getenv(name)); } #else envVar = Util_SafeStrdup(Posix_Getenv(name)); #endif return envVar; } /* *----------------------------------------------------------------------------- * * VixToolsDestroyUserEnvironment -- * * Releases any resources used by the VixToolsUserEnvironment. * The VixToolsUserEnvironment must not be used after calling * this function. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void VixToolsDestroyUserEnvironment(VixToolsUserEnvironment *env) // IN { if (NULL != env) { #ifdef _WIN32 if (NULL != env->envBlock) { if (env->impersonated) { VixToolsDestroyEnvironmentBlock(env->envBlock); } } #endif free(env); } } #ifdef _WIN32 /* *----------------------------------------------------------------------------- * * VixToolsEnvironToEnvBlock -- * * Converts a NULL terminated array of UTF-8 environment variables in * the form NAME=VALUE to an Win32 environment block, which is a single * contiguous array containing UTF-16 environment variables in the same * form, each separated by a UTF-16 null character, followed by two * training null characters. * * Results: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsEnvironToEnvBlock(char const * const *environ, // IN: UTF-8 wchar_t **envBlock) // OUT { VixError err; DynBuf buf; Bool res; static const wchar_t nullTerm[] = { L'\0', L'\0' }; DynBuf_Init(&buf); if ((NULL == environ) || (NULL == envBlock)) { err = VIX_E_FAIL; goto abort; } *envBlock = NULL; while (NULL != *environ) { wchar_t *envVar = Unicode_GetAllocUTF16(*environ); res = DynBuf_Append(&buf, envVar, (wcslen(envVar) + 1) * sizeof(*envVar)); free(envVar); if (!res) { err = VIX_E_OUT_OF_MEMORY; goto abort; } environ++; } /* * Append two null characters at the end. This adds an extra (third) null * if there was at least one environment variable (since there already * is one after the last string) but we need both if there were no * environment variables in the input array. I'll waste two bytes to * keep the code a little simpler. */ res = DynBuf_Append(&buf, nullTerm, sizeof nullTerm); if (!res) { err = VIX_E_OUT_OF_MEMORY; goto abort; } *envBlock = DynBuf_Detach(&buf); err = VIX_OK; abort: DynBuf_Destroy(&buf); return err; } #endif /* *----------------------------------------------------------------------------- * * VixToolsValidateEnviron -- * * Ensures that the NULL terminated array of strings contains * properly formated environment variables. * * Results: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsValidateEnviron(char const * const *environ) // IN { if (NULL == environ) { return VIX_E_FAIL; } while (NULL != *environ) { /* * Each string should contain at least one '=', to delineate between * the name and the value. */ if (NULL == Str_Strchr(*environ, '=')) { return VIX_E_INVALID_ARG; } environ++; } return VIX_OK; } #ifdef VMX86_DEVEL #ifdef _WIN32 /* *----------------------------------------------------------------------------- * * TestVixToolsEnvironToEnvBlockEmptyEnviron -- * * Tests VixToolsEnvironToEnvBlock() with an empty environment: an * char ** pointing to a single NULL pointer. * * Results: * Passes or ASSERTs. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void TestVixToolsEnvironToEnvBlockEmptyEnviron(void) { const char *environ1[] = { NULL }; wchar_t *envBlock; VixError err; err = VixToolsEnvironToEnvBlock(environ1, &envBlock); ASSERT(VIX_OK == err); ASSERT((L'\0' == envBlock[0]) && (L'\0' == envBlock[1])); free(envBlock); } /* *----------------------------------------------------------------------------- * * TestVixToolsEnvironToEnvBlockTwoGood -- * * Tests VixToolsEnvironToEnvBlock() with an environment containing * two valid entries. * * Results: * Passes or ASSERTs * * Side effects: * None * *----------------------------------------------------------------------------- */ static void TestVixToolsEnvironToEnvBlockTwoGood(void) { const char *environ1[] = { "foo=bar", "env=block", NULL }; wchar_t *envBlock, *currPos; VixError err; err = VixToolsEnvironToEnvBlock(environ1, &envBlock); ASSERT(VIX_OK == err); currPos = envBlock; ASSERT(wcscmp(currPos, L"foo=bar") == 0); currPos += wcslen(L"foo=bar") + 1; ASSERT(wcscmp(currPos, L"env=block") == 0); free(envBlock); } /* *----------------------------------------------------------------------------- * * TestVixToolsEnvironToEnvBlock -- * * Runs unit tests for VixToolsEnvironToEnvBlock(). * * Results: * Passes or ASSERTs. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void TestVixToolsEnvironToEnvBlock(void) { TestVixToolsEnvironToEnvBlockEmptyEnviron(); TestVixToolsEnvironToEnvBlockTwoGood(); } #endif // #ifdef _WIN32 /* *----------------------------------------------------------------------------- * * TestVixToolsValidateEnvironEmptyEnviron -- * * Tests VixToolsEnvironToEnvBlock() with an empty environment. * * Results: * Passes or ASSERTs. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void TestVixToolsValidateEnvironEmptyEnviron(void) { const char *environ1[] = { NULL }; VixError err; err = VixToolsValidateEnviron(environ1); ASSERT(VIX_OK == err); } /* *----------------------------------------------------------------------------- * * TestVixToolsValidateEnvironTwoGoodVars -- * * Tests VixToolsEnvironToEnvBlock() with an environment containing * two valid environment variables. * * Results: * Passes or ASSERTs. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void TestVixToolsValidateEnvironTwoGoodVars(void) { const char *environ1[] = { "foo=bar", "vix=api", NULL }; VixError err; err = VixToolsValidateEnviron(environ1); ASSERT(VIX_OK == err); } /* *----------------------------------------------------------------------------- * * TestVixToolsValidateEnvironOneBad -- * * Tests VixToolsEnvironToEnvBlock() with an environment containing * one invalid environment variable. * * Results: * Passes or ASSERTs. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void TestVixToolsValidateEnvironOneBad(void) { const char *environ1[] = { "noequals", NULL }; VixError err; err = VixToolsValidateEnviron(environ1); ASSERT(VIX_E_INVALID_ARG == err); } /* *----------------------------------------------------------------------------- * * TestVixToolsValidateEnvironSecondBad -- * * Tests VixToolsEnvironToEnvBlock() with an environment containing * one valid environment variable followed by one invalid environment * variable. * * Results: * Passes or ASSERTs. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void TestVixToolsValidateEnvironSecondBad(void) { const char *environ1[] = { "foo=bar", "noequals", NULL }; VixError err; err = VixToolsValidateEnviron(environ1); ASSERT(VIX_E_INVALID_ARG == err); } /* *----------------------------------------------------------------------------- * * TestVixToolsValidateEnviron -- * * Run unit tests for VixToolsValidateEnviron(). * * Results: * Passes or ASSERTs. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void TestVixToolsValidateEnviron(void) { TestVixToolsValidateEnvironEmptyEnviron(); TestVixToolsValidateEnvironTwoGoodVars(); TestVixToolsValidateEnvironOneBad(); TestVixToolsValidateEnvironSecondBad(); } /* *----------------------------------------------------------------------------- * * TextVixToolsEnvVars -- * * Run unit tests for functions in this file. * * Results: * Passes or ASSERTs. * * Side effects: * None * *----------------------------------------------------------------------------- */ void TestVixToolsEnvVars(void) { #ifdef _WIN32 TestVixToolsEnvironToEnvBlock(); #endif TestVixToolsValidateEnviron(); } #endif // #ifdef VMX86_DEVEL open-vm-tools-9.4.0-1280544/services/plugins/vix/vixTools.c0000644765153500003110000120004112220061556021542 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vixTools.c -- * * VIX commands that run in the guest OS. */ /* * When adding new functions, be sure to update * VixToolsCheckIfVixCommandEnabled() and VixToolsSetAPIEnabledProperties() * (adding a property and associated code in apps/lib/foundry/foundryVM.c * if necessary). The enabled properties provide hints to an API developer * as to which APIs are available, and can be affected to guest OS attributes * or guest-side configuration. * * See Vim.Vm.Guest.QueryDisabledMethods() * */ #include #include #include #include #include #include #ifdef _WIN32 #include #include #include "wminic.h" #include "win32u.h" #include #include #define SECURITY_WIN32 #include #else #include #endif #if defined(sun) || defined(__FreeBSD__) || defined(__APPLE__) #include #endif #ifdef _MSC_VER # include #elif _WIN32 # include "win95.h" #endif #include "vmware.h" #include "procMgr.h" #include "timeutil.h" #include "vm_version.h" #include "message.h" #include "dynarray.h" #define G_LOG_DOMAIN "vix" #define Debug g_debug #define Warning g_warning #include #include "util.h" #include "strutil.h" #include "str.h" #include "file.h" #include "err.h" #include "guestInfo.h" // MAX_VALUE_LEN #include "hostinfo.h" #include "guest_os.h" #include "guest_msg_def.h" #include "conf.h" #include "vixCommands.h" #include "base64.h" #include "hostinfo.h" #include "hgfsServerManager.h" #include "hgfs.h" #include "system.h" #include "codeset.h" #include "posix.h" #include "unicode.h" #include "hashTable.h" #include "su.h" #include "escape.h" #if defined(linux) || defined(_WIN32) #include "netutil.h" #endif #include "impersonate.h" #include "vixOpenSource.h" #include "vixToolsInt.h" #include "vmware/tools/plugin.h" #ifdef _WIN32 #include "registryWin32.h" #include "win32u.h" #endif /* _WIN32 */ #include "hgfsHelper.h" #ifdef linux #include "mntinfo.h" #include #endif /* * Only support Linux right now. * * On Windows, the SAML impersonation story is too shaky to trust, * and without that, there's no reason to support AliasManager APIs. * * No support for open-vm-tools. */ #if defined(linux) && !defined(OPEN_VM_TOOLS) /* * XXX turned off for prod2013-stage branch */ #define SUPPORT_VGAUTH 0 #else #define SUPPORT_VGAUTH 0 #endif #if SUPPORT_VGAUTH #include "VGAuthCommon.h" #include "VGAuthError.h" #include "VGAuthAuthentication.h" #include "VGAuthAlias.h" #define VMTOOLSD_APP_NAME "vmtoolsd" #define VIXTOOLS_CONFIG_USE_VGAUTH_NAME "useVGAuth" /* * XXX Leave this off by default until the VGAuth service is being * officially installed. */ #define USE_VGAUTH_DEFAULT FALSE static gboolean gSupportVGAuth = USE_VGAUTH_DEFAULT; static gboolean QueryVGAuthConfig(GKeyFile *confDictRef); /* * XXX * * Holds the current impersonation token. * * This is a hack, dependent on there only being one impersonation * possible at a time anyways. We need the HANDLE from inside the * VGAuthUserHandle to pass to other functions, so we can't throw * it out until Unimpersonate(). * * A cleaner solution would be to not treat the userToken as a void * * (which is really a HANDLE on Windows) but instead make a small wrapper * struct containing a type and an optional HANDLE. But this would * require massive changes all over, and make it very hard to turn off * VGAuth compilation. */ static VGAuthUserHandle *currentUserHandle = NULL; #endif #define SECONDS_BETWEEN_POLL_TEST_FINISHED 1 /* * This is used by the PRODUCT_VERSION_STRING macro. */ #ifndef PRODUCT_VERSION_NUMBER #define PRODUCT_VERSION_NUMBER "1.0.0" #endif /* * The config file groupname for API configuration. */ #define VIX_TOOLS_CONFIG_API_GROUPNAME "guestoperations" /* * The switch that controls all APIs */ #define VIX_TOOLS_CONFIG_API_ALL_NAME "disabled" /* * Individual API names for configuration. * * These match the WSDL names in the vSphere API. */ #define VIX_TOOLS_CONFIG_API_START_PROGRAM_NAME "StartProgramInGuest" #define VIX_TOOLS_CONFIG_API_LIST_PROCESSES_NAME "ListProcessesInGuest" #define VIX_TOOLS_CONFIG_API_TERMINATE_PROCESS_NAME "TerminateProcessInGuest" #define VIX_TOOLS_CONFIG_API_READ_ENV_VARS_NAME "ReadEnvironmentVariableInGuest" #define VIX_TOOLS_CONFIG_API_MAKE_DIRECTORY_NAME "MakeDirectoryInGuest" #define VIX_TOOLS_CONFIG_API_DELETE_FILE_NAME "DeleteFileInGuest" #define VIX_TOOLS_CONFIG_API_DELETE_DIRECTORY_NAME "DeleteDirectoryInGuest" #define VIX_TOOLS_CONFIG_API_MOVE_DIRECTORY_NAME "MoveDirectoryInGuest" #define VIX_TOOLS_CONFIG_API_MOVE_FILE_NAME "MoveFileInGuest" #define VIX_TOOLS_CONFIG_API_CREATE_TMP_FILE_NAME "CreateTemporaryFileInGuest" #define VIX_TOOLS_CONFIG_API_CREATE_TMP_DIRECTORY_NAME "CreateTemporaryDirectoryInGuest" #define VIX_TOOLS_CONFIG_API_LIST_FILES_NAME "ListFilesInGuest" #define VIX_TOOLS_CONFIG_API_CHANGE_FILE_ATTRS_NAME "ChangeFileAttributesInGuest" #define VIX_TOOLS_CONFIG_API_INITIATE_FILE_TRANSFER_FROM_GUEST_NAME "InitiateFileTransferFromGuest" #define VIX_TOOLS_CONFIG_API_INITIATE_FILE_TRANSFER_TO_GUEST_NAME "InitiateFileTransferToGuest" #define VIX_TOOLS_CONFIG_API_VALIDATE_CREDENTIALS_NAME "ValidateCredentialsInGuest" #define VIX_TOOLS_CONFIG_API_ACQUIRE_CREDENTIALS_NAME "AcquireCredentialsInGuest" #define VIX_TOOLS_CONFIG_API_RELEASE_CREDENTIALS_NAME "ReleaseCredentialsInGuest" #define VIX_TOOLS_CONFIG_API_ADD_GUEST_ALIAS_NAME "AddGuestAlias" // controls both RemoveGuestAlias and RemoveGuestAliasByCert #define VIX_TOOLS_CONFIG_API_REMOVE_GUEST_ALIAS_NAME "RemoveGuestAlias" #define VIX_TOOLS_CONFIG_API_LIST_GUEST_ALIASES_NAME "ListGuestAliases" #define VIX_TOOLS_CONFIG_API_LIST_GUEST_MAPPED_ALIASES_NAME "ListGuestMappedAliases" #define VIX_TOOLS_CONFIG_API_CREATE_REGISTRY_KEY_NAME "CreateRegistryKeyInGuest" #define VIX_TOOLS_CONFIG_API_LIST_REGISTRY_KEYS_NAME "ListRegistryKeysInGuest" #define VIX_TOOLS_CONFIG_API_DELETE_REGISTRY_KEY_NAME "DeleteRegistryKeyInGuest" #define VIX_TOOLS_CONFIG_API_SET_REGISTRY_VALUE_NAME "SetRegistryValueInGuest" #define VIX_TOOLS_CONFIG_API_LIST_REGISTRY_VALUES_NAME "ListRegistryValuesInGuest" #define VIX_TOOLS_CONFIG_API_DELETE_REGISTRY_VALUE_NAME "DeleteRegistryValueInGuest" /* * State of a single asynch runProgram. */ typedef struct VixToolsRunProgramState { VixRunProgramOptions runProgramOptions; ProcMgr_AsyncProc *procState; char *tempScriptFilePath; char *requestName; char *userName; char *password; void *eventQueue; } VixToolsRunProgramState; /* * State of a single asynch startProgram. */ typedef struct VixToolsStartProgramState { ProcMgr_AsyncProc *procState; void *eventQueue; } VixToolsStartProgramState; /* * Tracks processes started via StartProgram, so their exit information can * be returned with ListProcessesEx() * * We need live and dead because the exit status is fetched by from * a timer loop, and StartProgram of a very short lived program * followed immediately by a ListProcesses could miss the program * if we don't save it off for before the timer fires. * * Note that we save off the procState so that we keep an open * handle to the process, to prevent its PID from being recycled. * We need to hold this open until we no longer save the result * of the exited program. This is documented as 5 minutes * (VIX_TOOLS_EXITED_PROGRAM_REAP_TIME) in the VMODL. */ typedef struct VixToolsExitedProgramState { char *cmdName; char *fullCommandLine; char *user; uint64 pid; time_t startTime; int exitCode; time_t endTime; Bool isRunning; ProcMgr_AsyncProc *procState; struct VixToolsExitedProgramState *next; } VixToolsExitedProgramState; static VixToolsExitedProgramState *exitedProcessList = NULL; /* * How long we keep the info of exited processes about. */ #define VIX_TOOLS_EXITED_PROGRAM_REAP_TIME (5 * 60) /* * This is used to cache the results of ListProcessesEx when the reply * is too large to fit over the backdoor, so multiple trips are needed * to fetch it. */ static GHashTable *listProcessesResultsTable = NULL; /* * How long to keep around cached results in case the Vix side dies. * * Err on the very large; would hate to have it kick in just because * the other side is slow or there's an immense ammount of data. */ #define SECONDS_UNTIL_LISTPROC_CACHE_CLEANUP (10 * 60) typedef struct VixToolsCachedListProcessesResult { char *resultBuffer; size_t resultBufferLen; int key; #ifdef _WIN32 wchar_t *userName; #else uid_t euid; #endif } VixToolsCachedListProcessesResult; /* * Simple unique hashkey used for ListProcessesEx results. */ static uint32 listProcessesResultsKey = 1; static void VixToolsFreeCachedResult(gpointer p); /* * This structure is designed to implemente CreateTemporaryFile, * CreateTemporaryDirectory VI guest operations. */ typedef struct VixToolsGetTempFileCreateNameFuncData { char *filePrefix; char *tag; char *fileSuffix; } VixToolsGetTempFileCreateNameFuncData; /* * Global state. */ static Bool thisProcessRunsAsRoot = FALSE; static Bool allowConsoleUserOps = FALSE; static VixToolsReportProgramDoneProcType reportProgramDoneProc = NULL; static void *reportProgramDoneData = NULL; #ifndef _WIN32 typedef struct VixToolsEnvironmentTableIterator { char **envp; size_t pos; } VixToolsEnvironmentTableIterator; /* * Stores the environment variables to use when executing guest applications. */ static HashTable *userEnvironmentTable = NULL; #endif static HgfsServerMgrData gVixHgfsBkdrConn; #define SECONDS_BETWEEN_INVALIDATING_HGFS_SESSIONS 120 static VixError VixToolsGetFileInfo(VixCommandRequestHeader *requestMsg, char **result); static VixError VixToolsSetFileAttributes(VixCommandRequestHeader *requestMsg); static gboolean VixToolsMonitorAsyncProc(void *clientData); static gboolean VixToolsMonitorStartProgram(void *clientData); static void VixToolsRegisterHgfsSessionInvalidator(void *clientData); static gboolean VixToolsInvalidateInactiveHGFSSessions(void *clientData); static GSource *gHgfsSessionInvalidatorTimer = NULL; static guint gHgfsSessionInvalidatorTimerId; static void VixToolsPrintFileInfo(const char *filePathName, char *fileName, Bool escapeStrs, char **destPtr, char *endDestPtr); static int VixToolsGetFileExtendedInfoLength(const char *filePathName, const char *fileName); static char *VixToolsPrintFileExtendedInfoEx(const char *filePathName, const char *fileName); static void VixToolsPrintFileExtendedInfo(const char *filePathName, const char *fileName, char **destPtr, char *endDestPtr); static const char *fileInfoFormatString = "" "%s" "%d" "%"FMT64"d" "%"FMT64"d" ""; #if !defined(OPEN_VM_TOOLS) || defined(HAVE_GLIB_REGEX) static const char *listFilesRemainingFormatString = "%d"; #endif #ifdef _WIN32 static const char *fileExtendedInfoWindowsFormatString = "" "%s" "%d" "%"FMT64"u" "%"FMT64"u" "%"FMT64"u" "%"FMT64"u" ""; #else static const char *fileExtendedInfoLinuxFormatString = "" "%s" "%d" "%"FMT64"u" "%"FMT64"u" "%"FMT64"u" "%d" "%d" "%d" "%s" ""; #endif static VixError VixToolsGetTempFile(VixCommandRequestHeader *requestMsg, void *userToken, char **tempFile, int *tempFileFd); static void VixToolsFreeRunProgramState(VixToolsRunProgramState *asyncState); static void VixToolsFreeStartProgramState(VixToolsStartProgramState *asyncState); static void VixToolsUpdateExitedProgramList(VixToolsExitedProgramState *state); static void VixToolsFreeExitedProgramState(VixToolsExitedProgramState *state); static VixError VixToolsStartProgramImpl(const char *requestName, const char *programPath, const char *arguments, const char *workingDir, int numEnvVars, const char **envVars, Bool startMinimized, void *userToken, void *eventQueue, int64 *pid); static char *VixToolsGetImpersonatedUsername(void *userToken); static const char *scriptFileBaseName = "vixScript"; static VixError VixToolsMoveObject(VixCommandRequestHeader *requestMsg); static VixError VixToolsCreateTempFile(VixCommandRequestHeader *requestMsg, char **result); static VixError VixToolsReadVariable(VixCommandRequestHeader *requestMsg, char **result); static VixError VixToolsGetEnvForUser(void *userToken, const char *name, char **value); static VixError VixToolsReadEnvVariables(VixCommandRequestHeader *requestMsg, char **result); static VixError VixToolsGetMultipleEnvVarsForUser(void *userToken, const char *names, unsigned int numNames, char **result); static VixError VixToolsGetAllEnvVarsForUser(void *userToken, char **result); static VixError VixToolsWriteVariable(VixCommandRequestHeader *requestMsg); static VixError VixToolsListProcesses(VixCommandRequestHeader *requestMsg, size_t maxBufferSize, char **result); static VixError VixToolsPrintProcInfoEx(DynBuf *dstBuffer, const char *cmd, const char *name, uint64 pid, const char *user, int start, int exitCode, int exitTime); static VixError VixToolsListDirectory(VixCommandRequestHeader *requestMsg, size_t maxBufferSize, char **result); static VixError VixToolsListFiles(VixCommandRequestHeader *requestMsg, size_t maxBufferSize, char **result); static VixError VixToolsInitiateFileTransferFromGuest(VixCommandRequestHeader *requestMsg, char **result); static VixError VixToolsInitiateFileTransferToGuest(VixCommandRequestHeader *requestMsg); static VixError VixToolsKillProcess(VixCommandRequestHeader *requestMsg); static VixError VixToolsCreateDirectory(VixCommandRequestHeader *requestMsg); static VixError VixToolsRunScript(VixCommandRequestHeader *requestMsg, char *requestName, void *eventQueue, char **result); static VixError VixToolsCheckUserAccount(VixCommandRequestHeader *requestMsg); static VixError VixToolsProcessHgfsPacket(VixCommandHgfsSendPacket *requestMsg, GMainLoop *eventQueue, char **result, size_t *resultValueResult); static VixError VixToolsListFileSystems(VixCommandRequestHeader *requestMsg, char **result); #if defined(_WIN32) || defined(linux) static VixError VixToolsPrintFileSystemInfo(char **destPtr, const char *endDestPtr, const char *name, uint64 size, uint64 freeSpace, const char *type, Bool escapeStrs, Bool *truncated); #endif static VixError VixToolsValidateCredentials(VixCommandRequestHeader *requestMsg); static VixError VixToolsAcquireCredentials(VixCommandRequestHeader *requestMsg, GMainLoop *eventQueue, char **result); static VixError VixToolsReleaseCredentials(VixCommandRequestHeader *requestMsg); static VixError VixToolsCreateRegKey(VixCommandRequestHeader *requestMsg); static VixError VixToolsListRegKeys(VixCommandRequestHeader *requestMsg, size_t maxBufferSize, void *eventQueue, char **result); static VixError VixToolsDeleteRegKey(VixCommandRequestHeader *requestMsg); static VixError VixToolsSetRegValue(VixCommandRequestHeader *requestMsg); static VixError VixToolsListRegValues(VixCommandRequestHeader *requestMsg, size_t maxBufferSize, void *eventQueue, char **result); static VixError VixToolsDeleteRegValue(VixCommandRequestHeader *requestMsg); #if defined(__linux__) || defined(_WIN32) static VixError VixToolsGetGuestNetworkingConfig(VixCommandRequestHeader *requestMsg, char **resultBuffer, size_t *resultBufferLength); #endif #if defined(_WIN32) static VixError VixToolsSetGuestNetworkingConfig(VixCommandRequestHeader *requestMsg); #endif static VixError VixTools_Base64EncodeBuffer(char **resultValuePtr, size_t *resultValLengthPtr); static VixError VixToolsSetSharedFoldersProperties(VixPropertyListImpl *propList); static VixError VixToolsSetAPIEnabledProperties(VixPropertyListImpl *propList, GKeyFile *confDictRef); #if defined(_WIN32) static HRESULT VixToolsEnableDHCPOnPrimary(void); static HRESULT VixToolsEnableStaticOnPrimary(const char *ipAddr, const char *subnetMask); #endif static VixError VixToolsImpersonateUserImplEx(char const *credentialTypeStr, int credentialType, char const *obfuscatedNamePassword, void **userToken); static VixError VixToolsDoesUsernameMatchCurrentUser(const char *username); static Bool VixToolsPidRefersToThisProcess(ProcMgr_Pid pid); #ifndef _WIN32 static void VixToolsBuildUserEnvironmentTable(const char * const *envp); static char **VixToolsEnvironmentTableToEnvp(const HashTable *envTable); static int VixToolsEnvironmentTableEntryToEnvpEntry(const char *key, void *value, void *clientData); static void VixToolsFreeEnvp(char **envp); #endif static VixError VixToolsRewriteError(uint32 opCode, VixError origError); static size_t VixToolsXMLStringEscapedLen(const char *str, Bool escapeStr); static Bool GuestAuthEnabled(void); VixError GuestAuthPasswordAuthenticateImpersonate( char const *obfuscatedNamePassword, void **userToken); VixError GuestAuthSAMLAuthenticateAndImpersonate( char const *obfuscatedNamePassword, void **userToken); void GuestAuthUnimpersonate(); #if SUPPORT_VGAUTH VGAuthError TheVGAuthContext(VGAuthContext **ctx); #endif /* *----------------------------------------------------------------------------- * * VixTools_Initialize -- * * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixTools_Initialize(Bool thisProcessRunsAsRootParam, // IN const char * const *originalEnvp, // IN VixToolsReportProgramDoneProcType reportProgramDoneProcParam, // IN void *clientData) // IN { VixError err = VIX_OK; #if SUPPORT_VGAUTH ToolsAppCtx *ctx = (ToolsAppCtx *) clientData; #endif /* * Run unit tests on DEVEL builds. */ DEVEL_ONLY(TestVixToolsEnvVars()); thisProcessRunsAsRoot = thisProcessRunsAsRootParam; reportProgramDoneProc = reportProgramDoneProcParam; reportProgramDoneData = clientData; #ifndef _WIN32 VixToolsBuildUserEnvironmentTable(originalEnvp); #endif /* Register a straight through connection with the Hgfs server. */ HgfsServerManager_DataInit(&gVixHgfsBkdrConn, VIX_BACKDOORCOMMAND_COMMAND, NULL, // no RPC registration NULL); // rpc callback HgfsServerManager_Register(&gVixHgfsBkdrConn); listProcessesResultsTable = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, VixToolsFreeCachedResult); #if SUPPORT_VGAUTH /* * We don't set up the VGAuth log handler, since the default * does what we want, and trying to redirect VGAuth messages * to Log() causes recursion and a crash. */ #endif #if SUPPORT_VGAUTH gSupportVGAuth = QueryVGAuthConfig(ctx->config); #endif #ifdef _WIN32 err = VixToolsInitializeWin32(); if (VIX_FAILED(err)) { return err; } #endif return(err); } // VixTools_Initialize /* *----------------------------------------------------------------------------- * * VixTools_Uninitialize -- * * * Return value: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void VixTools_Uninitialize(void) // IN { if (NULL != gHgfsSessionInvalidatorTimer) { g_source_remove(gHgfsSessionInvalidatorTimerId); g_source_unref(gHgfsSessionInvalidatorTimer); gHgfsSessionInvalidatorTimer = NULL; gHgfsSessionInvalidatorTimerId = 0; Log("%s: HGFS session Invalidator detached\n", __FUNCTION__); } HgfsServerManager_Unregister(&gVixHgfsBkdrConn); } #ifndef _WIN32 /* *----------------------------------------------------------------------------- * * VixToolsBuildUserEnvironmentTable -- * * Takes an array of strings of the form "=" storing the * environment variables (as per environ(7)) that should be used when * running programs, and populates the hash table with them. * * If 'envp' is NULL, skip creating the user environment table, so that * we just use the current environment. * * Results: * None * * Side effects: * May initialize the global userEnvironmentTable. * *----------------------------------------------------------------------------- */ static void VixToolsBuildUserEnvironmentTable(const char * const *envp) // IN: optional { if (NULL == envp) { ASSERT(NULL == userEnvironmentTable); return; } if (NULL == userEnvironmentTable) { userEnvironmentTable = HashTable_Alloc(64, // buckets (power of 2) HASH_STRING_KEY | HASH_FLAG_COPYKEY, free); // freeFn for the values } else { /* * If we're being reinitialized, we can just clear the table and * load the new values into it. They shouldn't have changed, but * in case they ever do this will cover it. */ HashTable_Clear(userEnvironmentTable); } for (; NULL != *envp; envp++) { char *name; char *value; char *whereToSplit; size_t nameLen; whereToSplit = strchr(*envp, '='); if (NULL == whereToSplit) { /* Our code generated this list, so this shouldn't happen. */ ASSERT(0); continue; } nameLen = whereToSplit - *envp; name = Util_SafeMalloc(nameLen + 1); memcpy(name, *envp, nameLen); name[nameLen] = '\0'; whereToSplit++; // skip over '=' value = Util_SafeStrdup(whereToSplit); HashTable_Insert(userEnvironmentTable, name, value); DEBUG_ONLY(value = NULL;) // the hash table now owns 'value' free(name); DEBUG_ONLY(name = NULL;) } } /* *----------------------------------------------------------------------------- * * VixToolsEnvironmentTableToEnvp -- * * Take a hash table storing environment variables names and values and * build an array out of them. * * Results: * char ** - envp array as per environ(7). Must be freed using * VixToolsFreeEnvp * * Side effects: * None * *----------------------------------------------------------------------------- */ static char ** VixToolsEnvironmentTableToEnvp(const HashTable *envTable) // IN { char **envp; if (NULL != envTable) { VixToolsEnvironmentTableIterator itr; size_t numEntries = HashTable_GetNumElements(envTable); itr.envp = envp = Util_SafeMalloc((numEntries + 1) * sizeof *envp); itr.pos = 0; HashTable_ForEach(envTable, VixToolsEnvironmentTableEntryToEnvpEntry, &itr); ASSERT(numEntries == itr.pos); envp[numEntries] = NULL; } else { envp = NULL; } return envp; } /* *----------------------------------------------------------------------------- * * VixToolsEnvironmentTableEntryToEnvpEntry -- * * Callback for HashTable_ForEach(). Gets called for each entry in an * environment table, converting the key (environment variable name) and * value (environment variable value) into a string of the form * "=" and adding that to the envp array passed in with the * VixToolsEnvironmentTableIterator client data. * * Results: * int - always 0 * * Side effects: * Sets one entry in the envp. * *----------------------------------------------------------------------------- */ static int VixToolsEnvironmentTableEntryToEnvpEntry(const char *key, // IN void *value, // IN void *clientData) // IN/OUT { VixToolsEnvironmentTableIterator *itr = clientData; itr->envp[itr->pos++] = Str_SafeAsprintf(NULL, "%s=%s", key, (char *)value); return 0; } /* *----------------------------------------------------------------------------- * * VixToolsFreeEnvp -- * * Free's an array of strings where both the strings and the array * were heap allocated. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static void VixToolsFreeEnvp(char **envp) // IN { if (NULL != envp) { char **itr; for (itr = envp; NULL != *itr; itr++) { free(*itr); } free(envp); } } #endif // #ifndef _WIN32 /* *----------------------------------------------------------------------------- * * VixTools_SetConsoleUserPolicy -- * * This allows an external client of the tools to enable/disable this security * setting. This may be controlled by config or higher level user settings * that are not available to this library. * * Return value: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void VixTools_SetConsoleUserPolicy(Bool allowConsoleUserOpsParam) // IN { allowConsoleUserOps = allowConsoleUserOpsParam; } // VixTools_SetConsoleUserPolicy /* *----------------------------------------------------------------------------- * * VixTools_SetRunProgramCallback -- * * Register a callback that reports when a program has completed. * Different clients of this library will use different IPC mechanisms for * sending this message. For example, it may use the backdoor or a socket. * Different sockets may use different message protocols, such as the backdoor-on-a-socket * or the Foundry network message. * * Return value: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void VixTools_SetRunProgramCallback(VixToolsReportProgramDoneProcType reportProgramDoneProcParam, // IN void *clientData) // IN { reportProgramDoneProc = reportProgramDoneProcParam; reportProgramDoneData = clientData; } // VixTools_SetRunProgramCallback /* *----------------------------------------------------------------------------- * * VixTools_RunProgram -- * * Run a named program on the guest. * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixTools_RunProgram(VixCommandRequestHeader *requestMsg, // IN char *requestName, // IN void *eventQueue, // IN char **result) // OUT { VixError err = VIX_OK; VixMsgRunProgramRequest *runProgramRequest; const char *commandLine = NULL; const char *commandLineArgs = NULL; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; int64 pid; static char resultBuffer[32]; VMAutomationRequestParser parser; err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *runProgramRequest); if (VIX_OK != err) { goto abort; } runProgramRequest = (VixMsgRunProgramRequest *) requestMsg; err = VMAutomationRequestParserGetString(&parser, runProgramRequest->programNameLength, &commandLine); if (VIX_OK != err) { goto abort; } if (0 == *commandLine) { err = VIX_E_INVALID_ARG; goto abort; } if (runProgramRequest->commandLineArgsLength > 0) { err = VMAutomationRequestParserGetString(&parser, runProgramRequest->commandLineArgsLength, &commandLineArgs); if (VIX_OK != err) { goto abort; } } #ifdef _WIN32 if (runProgramRequest->runProgramOptions & VIX_RUNPROGRAM_RUN_AS_LOCAL_SYSTEM) { if (!VixToolsUserIsMemberOfAdministratorGroup(requestMsg)) { err = VIX_E_GUEST_USER_PERMISSIONS; goto abort; } userToken = PROCESS_CREATOR_USER_TOKEN; } #endif if (NULL == userToken) { err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; } err = VixToolsRunProgramImpl(requestName, commandLine, commandLineArgs, runProgramRequest->runProgramOptions, userToken, eventQueue, &pid); abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); Str_Sprintf(resultBuffer, sizeof(resultBuffer), "%"FMT64"d", pid); *result = resultBuffer; return err; } // VixTools_RunProgram /* *----------------------------------------------------------------------------- * * VixTools_StartProgram -- * * Start a program on the guest. Much like RunProgram, but * with additional arguments. Another key difference is that * the program's exitCode and endTime will be available to ListProcessesEx * for a short time. * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixTools_StartProgram(VixCommandRequestHeader *requestMsg, // IN char *requestName, // IN void *eventQueue, // IN char **result) // OUT { VixError err = VIX_OK; VixMsgStartProgramRequest *startProgramRequest; const char *programPath = NULL; const char *arguments = NULL; const char *workingDir = NULL; const char **envVars = NULL; const char *bp = NULL; const char *cmdNameBegin = NULL; Bool impersonatingVMWareUser = FALSE; int64 pid = -1; int i; void *userToken = NULL; static char resultBuffer[32]; // more than enough to hold a 64 bit pid VixToolsExitedProgramState *exitState; VMAutomationRequestParser parser; err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *startProgramRequest); if (VIX_OK != err) { goto abort; } startProgramRequest = (VixMsgStartProgramRequest *) requestMsg; /* * It seems that this functions uses the a string format that includes * the '\0' terminator in the length fields. * This is different from other "old" vix guest command format. */ err = VMAutomationRequestParserGetOptionalString(&parser, startProgramRequest->programPathLength, &programPath); if (VIX_OK != err) { goto abort; } if (NULL == programPath || 0 == *programPath) { err = VIX_E_INVALID_ARG; goto abort; } err = VMAutomationRequestParserGetOptionalString(&parser, startProgramRequest->argumentsLength, &arguments); if (VIX_OK != err) { goto abort; } err = VMAutomationRequestParserGetOptionalString(&parser, startProgramRequest->workingDirLength, &workingDir); if (VIX_OK != err) { goto abort; } if (NULL != workingDir && '\0' == workingDir[0]) { /* Let's treat an empty string the same as NULL: use the default. */ workingDir = NULL; } err = VMAutomationRequestParserGetOptionalStrings(&parser, startProgramRequest->numEnvVars, startProgramRequest->envVarLength, &bp); if (VIX_OK != err) { goto abort; } if (startProgramRequest->numEnvVars > 0) { envVars = Util_SafeMalloc(sizeof(char*) * (startProgramRequest->numEnvVars + 1)); for (i = 0; i < startProgramRequest->numEnvVars; i++) { envVars[i] = bp; bp += strlen(envVars[i]) + 1; } envVars[i] = NULL; err = VixToolsValidateEnviron(envVars); if (VIX_OK != err) { goto abort; } } err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; Debug("%s: args: progamPath: '%s', arguments: '%s'', workingDir: %s'\n", __FUNCTION__, programPath, (NULL != arguments) ? arguments : "", (NULL != workingDir) ? workingDir : ""); err = VixToolsStartProgramImpl(requestName, programPath, arguments, workingDir, startProgramRequest->numEnvVars, envVars, startProgramRequest->startMinimized, userToken, eventQueue, &pid); if (VIX_OK == err) { /* * Save off the program so ListProcessesEx can find it. * * We store it here to avoid the hole between starting it and the * exited process polling proc. */ exitState = Util_SafeMalloc(sizeof(VixToolsExitedProgramState)); /* * Build up the command line so the args are passed to the command. * To be safe, always put quotes around the program name. If the name * contains spaces (either in the file name of its directory path), * then the quotes are required. If the name doesn't contain spaces, then * unnecessary quotes don't seem to create a problem for both Windows and * Linux. */ if (NULL != arguments) { exitState->fullCommandLine = Str_SafeAsprintf(NULL, "\"%s\" %s", programPath, arguments); } else { exitState->fullCommandLine = Str_SafeAsprintf(NULL, "\"%s\"", programPath); } #if defined(_WIN32) /* * For windows, we let the VIX client parse the * command line to get the real command name. */ exitState->cmdName = NULL; #else /* * Find the last path separator, to get the cmd name. * If no separator is found, then use the whole name. */ cmdNameBegin = strrchr(programPath, '/'); if (NULL == cmdNameBegin) { cmdNameBegin = programPath; } else { /* * Skip over the last separator. */ cmdNameBegin++; } exitState->cmdName = Str_SafeAsprintf(NULL, "%s", cmdNameBegin); #endif exitState->user = VixToolsGetImpersonatedUsername(&userToken); exitState->pid = (uint64) pid; exitState->startTime = time(NULL); exitState->exitCode = 0; exitState->endTime = 0; exitState->isRunning = TRUE; exitState->next = NULL; exitState->procState = NULL; // add it to the list of exited programs VixToolsUpdateExitedProgramList(exitState); } abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); Str_Sprintf(resultBuffer, sizeof(resultBuffer), "%"FMT64"d", pid); *result = resultBuffer; free((char **) envVars); return err; } // VixTools_StartProgram /* *----------------------------------------------------------------------------- * * VixToolsRunProgramImpl -- * * Run a named program on the guest. * * Return value: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsRunProgramImpl(char *requestName, // IN const char *commandLine, // IN const char *commandLineArgs, // IN int runProgramOptions, // IN void *userToken, // IN void *eventQueue, // IN int64 *pid) // OUT,OPTIONAL { VixError err = VIX_OK; char *fullCommandLine = NULL; VixToolsRunProgramState *asyncState = NULL; char *tempCommandLine = NULL; char *startProgramFileName; char *stopProgramFileName; Bool programExists; Bool programIsExecutable; ProcMgr_ProcArgs procArgs; #if defined(_WIN32) Bool forcedRoot = FALSE; STARTUPINFO si; wchar_t *envBlock = NULL; #endif GSource *timer; if (NULL != pid) { *pid = (int64) -1; } tempCommandLine = Util_SafeStrdup(commandLine); startProgramFileName = tempCommandLine; while (' ' == *startProgramFileName) { startProgramFileName++; } if ('\"' == *startProgramFileName) { startProgramFileName++; stopProgramFileName = strstr(startProgramFileName, "\""); } else { stopProgramFileName = NULL; } if (NULL == stopProgramFileName) { stopProgramFileName = startProgramFileName + strlen(startProgramFileName); } *stopProgramFileName = 0; /* * Check that the program exists. * On linux, we run the program by exec'ing /bin/sh, and that does not * return a clear error code indicating that the program does not exist * or cannot be executed. * This is a common and user-correctable error, however, so we want to * check for it and return a specific error code in this case. * */ programExists = File_Exists(startProgramFileName); programIsExecutable = (FileIO_Access(startProgramFileName, FILEIO_ACCESS_EXEC) == FILEIO_SUCCESS); free(tempCommandLine); if (!programExists) { err = VIX_E_FILE_NOT_FOUND; goto abort; } if (!programIsExecutable) { err = VIX_E_GUEST_USER_PERMISSIONS; goto abort; } /* * Build up the command line so the args are passed to the command. * To be safe, always put quotes around the program name. If the name * contains spaces (either in the file name of its directory path), * then the quotes are required. If the name doesn't contain spaces, then * unnecessary quotes don't seem to create a problem for both Windows and * Linux. */ if (NULL != commandLineArgs) { fullCommandLine = Str_SafeAsprintf(NULL, "\"%s\" %s", commandLine, commandLineArgs); } else { fullCommandLine = Str_SafeAsprintf(NULL, "\"%s\"", commandLine); } if (NULL == fullCommandLine) { err = VIX_E_OUT_OF_MEMORY; goto abort; } /* * Save some strings in the state. */ asyncState = Util_SafeCalloc(1, sizeof *asyncState); asyncState->requestName = Util_SafeStrdup(requestName); asyncState->runProgramOptions = runProgramOptions; memset(&procArgs, 0, sizeof procArgs); #if defined(_WIN32) if (PROCESS_CREATOR_USER_TOKEN != userToken) { /* * If we are impersonating a user then use the user's environment * block. That way the user-specific environment variables will * be available to the application (such as the user's TEMP * directory instead of the system-wide one). */ err = VixToolsGetEnvBlock(userToken, &envBlock); if (VIX_OK != err) { goto abort; } forcedRoot = Impersonate_ForceRoot(); } memset(&si, 0, sizeof si); procArgs.hToken = (PROCESS_CREATOR_USER_TOKEN == userToken) ? NULL : userToken; procArgs.bInheritHandles = TRUE; procArgs.lpStartupInfo = &si; si.cb = sizeof si; procArgs.dwCreationFlags = CREATE_UNICODE_ENVIRONMENT; procArgs.lpEnvironment = envBlock; si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = (VIX_RUNPROGRAM_ACTIVATE_WINDOW & runProgramOptions) ? SW_SHOWNORMAL : SW_MINIMIZE; #elif !defined(__FreeBSD__) procArgs.envp = VixToolsEnvironmentTableToEnvp(userEnvironmentTable); #endif asyncState->procState = ProcMgr_ExecAsync(fullCommandLine, &procArgs); #if defined(_WIN32) if (forcedRoot) { Impersonate_UnforceRoot(); } #else VixToolsFreeEnvp(procArgs.envp); DEBUG_ONLY(procArgs.envp = NULL;) #endif if (NULL == asyncState->procState) { err = VIX_E_PROGRAM_NOT_STARTED; goto abort; } if (NULL != pid) { *pid = (int64) ProcMgr_GetPid(asyncState->procState); } /* * Start a periodic procedure to check the app periodically */ asyncState->eventQueue = eventQueue; timer = g_timeout_source_new(SECONDS_BETWEEN_POLL_TEST_FINISHED * 1000); g_source_set_callback(timer, VixToolsMonitorAsyncProc, asyncState, NULL); g_source_attach(timer, g_main_loop_get_context(eventQueue)); g_source_unref(timer); /* * VixToolsMonitorAsyncProc will clean asyncState up when the program finishes. */ asyncState = NULL; abort: free(fullCommandLine); #ifdef _WIN32 if (NULL != envBlock) { VixToolsDestroyEnvironmentBlock(envBlock); } #endif if (VIX_FAILED(err)) { VixToolsFreeRunProgramState(asyncState); } return err; } // VixToolsRunProgramImpl /* *----------------------------------------------------------------------------- * * VixToolsStartProgramImpl -- * * Start a named program on the guest. * * Return value: * VixError * * Side effects: * Saves off its state. * *----------------------------------------------------------------------------- */ VixError VixToolsStartProgramImpl(const char *requestName, // IN const char *programPath, // IN const char *arguments, // IN const char *workingDir, // IN int numEnvVars, // IN const char **envVars, // IN Bool startMinimized, // IN void *userToken, // IN void *eventQueue, // IN int64 *pid) // OUT { VixError err = VIX_OK; char *fullCommandLine = NULL; VixToolsStartProgramState *asyncState = NULL; char *tempCommandLine = NULL; char *startProgramFileName; char *stopProgramFileName; Bool programExists; Bool programIsExecutable; ProcMgr_ProcArgs procArgs; char *workingDirectory = NULL; #if defined(_WIN32) Bool forcedRoot = FALSE; STARTUPINFO si; wchar_t *envBlock = NULL; Bool envBlockFromMalloc = TRUE; #endif GSource *timer; /* * Initialize this here so we can call free on its member variables in abort */ memset(&procArgs, 0, sizeof procArgs); if (NULL != pid) { *pid = (int64) -1; } tempCommandLine = Util_SafeStrdup(programPath); startProgramFileName = tempCommandLine; while (' ' == *startProgramFileName) { startProgramFileName++; } if ('\"' == *startProgramFileName) { startProgramFileName++; stopProgramFileName = strstr(startProgramFileName, "\""); } else { stopProgramFileName = NULL; } if (NULL == stopProgramFileName) { stopProgramFileName = startProgramFileName + strlen(startProgramFileName); } *stopProgramFileName = 0; /* * Check that the program exists. * On linux, we run the program by exec'ing /bin/sh, and that does not * return a clear error code indicating that the program does not exist * or cannot be executed. * This is a common and user-correctable error, however, so we want to * check for it and return a specific error code in this case. * */ programExists = File_Exists(startProgramFileName); programIsExecutable = (FileIO_Access(startProgramFileName, FILEIO_ACCESS_EXEC) == FILEIO_SUCCESS); free(tempCommandLine); if (!programExists) { err = VIX_E_FILE_NOT_FOUND; goto abort; } if (!programIsExecutable) { err = VIX_E_GUEST_USER_PERMISSIONS; goto abort; } /* sanity check workingDir if set */ if (NULL != workingDir && !File_IsDirectory(workingDir)) { err = VIX_E_NOT_A_DIRECTORY; goto abort; } /* * Adjust the workingDir if needed. * For non-Windows, we use the user's $HOME if workingDir isn't supplied. */ if (NULL == workingDir) { #if defined(linux) || defined(sun) || defined(__FreeBSD__) || defined(__APPLE__) char *username = NULL; if (!ProcMgr_GetImpersonatedUserInfo(&username, &workingDirectory)) { Debug("%s: ProcMgr_GetImpersonatedUserInfo() failed fetching workingDirectory\n", __FUNCTION__); err = VIX_E_FAIL; goto abort; } free(username); #elif defined(_WIN32) workingDirectory = (char *)workingDir; #else /* * we shouldn't ever get here for unsupported guests, so just * be sure it builds. */ workingDirectory = NULL; #endif } else { workingDirectory = Util_SafeStrdup(workingDir); } /* * Build up the command line so the args are passed to the command. * To be safe, always put quotes around the program name. If the name * contains spaces (either in the file name of its directory path), * then the quotes are required. If the name doesn't contain spaces, then * unnecessary quotes don't seem to create a problem for both Windows and * Linux. */ if (NULL != arguments) { fullCommandLine = Str_SafeAsprintf(NULL, "\"%s\" %s", programPath, arguments); } else { fullCommandLine = Str_SafeAsprintf(NULL, "\"%s\"", programPath); } if (NULL == fullCommandLine) { err = VIX_E_OUT_OF_MEMORY; goto abort; } /* * Save some state for when it completes. */ asyncState = Util_SafeCalloc(1, sizeof *asyncState); #if defined(_WIN32) if (NULL != envVars) { err = VixToolsEnvironToEnvBlock(envVars, &envBlock); if (VIX_OK != err) { goto abort; } } else if (PROCESS_CREATOR_USER_TOKEN != userToken) { /* * If we are impersonating a user and that user did not supply * environment variables to pass, then use the user's environment * block. That way the user-specific environment variables will * be available to the application (such as the user's TEMP * directory instead of the system-wide one). */ err = VixToolsGetEnvBlock(userToken, &envBlock); if (VIX_OK != err) { goto abort; } envBlockFromMalloc = FALSE; } if (PROCESS_CREATOR_USER_TOKEN != userToken) { forcedRoot = Impersonate_ForceRoot(); } memset(&si, 0, sizeof si); procArgs.hToken = (PROCESS_CREATOR_USER_TOKEN == userToken) ? NULL : userToken; procArgs.bInheritHandles = TRUE; procArgs.lpStartupInfo = &si; procArgs.lpCurrentDirectory = UNICODE_GET_UTF16(workingDirectory); /* * The lpEnvironment is in UTF-16, so we need the CREATE_UNICODE_ENVIRONMENT * flag. */ procArgs.dwCreationFlags = CREATE_UNICODE_ENVIRONMENT; procArgs.lpEnvironment = envBlock; si.cb = sizeof si; si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = (startMinimized) ? SW_MINIMIZE : SW_SHOWNORMAL; #else procArgs.workingDirectory = workingDirectory; procArgs.envp = (char **)envVars; #endif asyncState->procState = ProcMgr_ExecAsync(fullCommandLine, &procArgs); #if defined(_WIN32) if (forcedRoot) { Impersonate_UnforceRoot(); } #endif if (NULL == asyncState->procState) { err = VIX_E_PROGRAM_NOT_STARTED; goto abort; } if (NULL != pid) { *pid = (int64) ProcMgr_GetPid(asyncState->procState); } Debug("%s started '%s', pid %"FMT64"d\n", __FUNCTION__, fullCommandLine, *pid); /* * Start a periodic procedure to check the app periodically */ asyncState->eventQueue = eventQueue; timer = g_timeout_source_new(SECONDS_BETWEEN_POLL_TEST_FINISHED * 1000); g_source_set_callback(timer, VixToolsMonitorStartProgram, asyncState, NULL); g_source_attach(timer, g_main_loop_get_context(eventQueue)); g_source_unref(timer); /* * VixToolsMonitorStartProgram will clean asyncState up when the program * finishes. */ asyncState = NULL; abort: free(fullCommandLine); free(workingDirectory); #ifdef _WIN32 if (envBlockFromMalloc) { free(envBlock); } else { VixToolsDestroyEnvironmentBlock(envBlock); } UNICODE_RELEASE_UTF16(procArgs.lpCurrentDirectory); #endif if (VIX_FAILED(err)) { VixToolsFreeStartProgramState(asyncState); } return err; } // VixToolsStartProgramImpl /* *----------------------------------------------------------------------------- * * VixToolsMonitorAsyncProc -- * * This polls a program running in the guest to see if it has completed. * It is used by the test/dev code to detect when a test application * completes. * * Return value: * TRUE on non-glib implementation. * FALSE on glib implementation. * * Side effects: * None * *----------------------------------------------------------------------------- */ static gboolean VixToolsMonitorAsyncProc(void *clientData) // IN { VixError err = VIX_OK; VixToolsRunProgramState *asyncState; Bool procIsRunning = FALSE; int exitCode = 0; ProcMgr_Pid pid = -1; int result = -1; GSource *timer; char *requestName = NULL; VixRunProgramOptions runProgramOptions; asyncState = (VixToolsRunProgramState *)clientData; ASSERT(asyncState); /* * Check if the program has completed. */ procIsRunning = ProcMgr_IsAsyncProcRunning(asyncState->procState); if (!procIsRunning) { goto done; } timer = g_timeout_source_new(SECONDS_BETWEEN_POLL_TEST_FINISHED * 1000); g_source_set_callback(timer, VixToolsMonitorAsyncProc, asyncState, NULL); g_source_attach(timer, g_main_loop_get_context(asyncState->eventQueue)); g_source_unref(timer); return FALSE; done: /* * We need to always check the exit code, even if there is no need to * report it. On POSIX systems, ProcMgr_GetExitCode() does things like * call waitpid() to clean up the child process. */ result = ProcMgr_GetExitCode(asyncState->procState, &exitCode); pid = ProcMgr_GetPid(asyncState->procState); if (0 != result) { exitCode = -1; } runProgramOptions = asyncState->runProgramOptions; requestName = Util_SafeStrdup(asyncState->requestName); VixToolsFreeRunProgramState(asyncState); /* * We may just be running to clean up after running a script, with the * results already reported. */ if ((NULL != reportProgramDoneProc) && !(runProgramOptions & VIX_RUNPROGRAM_RETURN_IMMEDIATELY)) { (*reportProgramDoneProc)(requestName, err, exitCode, (int64) pid, reportProgramDoneData); } free(requestName); return FALSE; } // VixToolsMonitorAsyncProc /* *---------------------------------------------------------------------------- * * VixToolsInvalidateInactiveHGFSSessions -- * * Send a request to HGFS server to invalidate inactive sessions. * Registers a timer to call the invalidator. * * Return value: * TRUE if the timer needs to be re-registerd. * FALSE if the timer needs to be deleted. * * Side effects: * None * *---------------------------------------------------------------------------- */ static gboolean VixToolsInvalidateInactiveHGFSSessions(void *clientData) // IN: { if (HgfsServerManager_InvalidateInactiveSessions(&gVixHgfsBkdrConn) > 0) { /* * There are still active sessions, so keep the periodic timer * registered. */ return TRUE; } else { Log("%s: HGFS session Invalidator is successfully detached\n", __FUNCTION__); g_source_unref(gHgfsSessionInvalidatorTimer); gHgfsSessionInvalidatorTimer = NULL; gHgfsSessionInvalidatorTimerId = 0; return FALSE; } } /* *---------------------------------------------------------------------------- * * VixToolsRegisterHgfsSessionInvalidator -- * * Check bug 783263 for more details. This function is designed to * cleanup any hgfs state left by remote clients that got * disconnected abruptly during a file copy process. * * If there is a timer already registered, then this function doesn't * do anything. * * Return value: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VixToolsRegisterHgfsSessionInvalidator(void *clientData) // IN: { ASSERT(clientData); if (NULL != gHgfsSessionInvalidatorTimer) { return; } gHgfsSessionInvalidatorTimer = g_timeout_source_new(SECONDS_BETWEEN_INVALIDATING_HGFS_SESSIONS * 1000); g_source_set_callback(gHgfsSessionInvalidatorTimer, VixToolsInvalidateInactiveHGFSSessions, NULL, NULL); gHgfsSessionInvalidatorTimerId = g_source_attach(gHgfsSessionInvalidatorTimer, g_main_loop_get_context((GMainLoop *) clientData)); Log("%s: HGFS session Invalidator registered\n", __FUNCTION__); } /* *----------------------------------------------------------------------------- * * VixToolsMonitorStartProgram -- * * This polls a program started by StartProgram to see if it has completed. * If it has, saves off its exitCode and endTime so they can be queried * via ListProcessesEx. * * Return value: * TRUE on non-glib implementation. * FALSE on glib implementation. * * Side effects: * None * *----------------------------------------------------------------------------- */ static gboolean VixToolsMonitorStartProgram(void *clientData) // IN { VixToolsStartProgramState *asyncState; Bool procIsRunning = FALSE; int exitCode = 0; ProcMgr_Pid pid = -1; int result = -1; VixToolsExitedProgramState *exitState; GSource *timer; asyncState = (VixToolsStartProgramState *) clientData; ASSERT(asyncState); /* * Check if the program has completed. */ procIsRunning = ProcMgr_IsAsyncProcRunning(asyncState->procState); if (!procIsRunning) { goto done; } timer = g_timeout_source_new(SECONDS_BETWEEN_POLL_TEST_FINISHED * 1000); g_source_set_callback(timer, VixToolsMonitorStartProgram, asyncState, NULL); g_source_attach(timer, g_main_loop_get_context(asyncState->eventQueue)); g_source_unref(timer); return FALSE; done: result = ProcMgr_GetExitCode(asyncState->procState, &exitCode); pid = ProcMgr_GetPid(asyncState->procState); if (0 != result) { exitCode = -1; } /* * Save off the program exit state so ListProcessesEx can find it. * * We only bother to set pid, exitCode and endTime -- we have the * other data from when we made the initial record whne the * progrtam started; that record will be updated with the exitCode * and endTime. */ exitState = Util_SafeMalloc(sizeof(VixToolsExitedProgramState)); exitState->cmdName = NULL; exitState->fullCommandLine = NULL; exitState->user = NULL; exitState->pid = pid; exitState->startTime = 0; exitState->exitCode = exitCode; exitState->endTime = time(NULL); exitState->isRunning = FALSE; exitState->next = NULL; exitState->procState = asyncState->procState; // add it to the list of exited programs VixToolsUpdateExitedProgramList(exitState); VixToolsFreeStartProgramState(asyncState); return FALSE; } // VixToolsMonitorStartProgram /* *----------------------------------------------------------------------------- * * VixToolsUpdateExitedProgramList -- * * Adds a new exited program's state to the saved list, and * removes any that have been there too long. * * Return value: * None * * Side effects: * Apps that have been saved past their expiration date are dropped. * *----------------------------------------------------------------------------- */ static void VixToolsUpdateExitedProgramList(VixToolsExitedProgramState *state) // IN { VixToolsExitedProgramState *epList = NULL; VixToolsExitedProgramState *last = NULL; VixToolsExitedProgramState *old = NULL; time_t now; now = time(NULL); /* * Update the 'running' record if the process has completed. */ if (state && (state->isRunning == FALSE)) { epList = exitedProcessList; while (epList) { if (epList->pid == state->pid) { /* * Update the two exit fields now that we have them */ epList->exitCode = state->exitCode; epList->endTime = state->endTime; epList->isRunning = FALSE; epList->procState = state->procState; // don't let the procState be free'd state->procState = NULL; VixToolsFreeExitedProgramState(state); // NULL it out so we don't try to add it later in this function state = NULL; break; } else { epList = epList->next; } } } /* * Find and toss any old records. */ last = NULL; epList = exitedProcessList; while (epList) { /* * Sanity check we don't have a duplicate entry -- this should * only happen when the OS re-uses the PID before we reap the record * of its exit status. */ if (state) { if (state->pid == epList->pid) { // XXX just whine for M/N, needs better fix in *main Warning("%s: found duplicate entry in exitedProcessList\n", __FUNCTION__); } } if (!epList->isRunning && (epList->endTime < (now - VIX_TOOLS_EXITED_PROGRAM_REAP_TIME))) { if (last) { last->next = epList->next; } else { exitedProcessList = epList->next; } old = epList; epList = epList->next; VixToolsFreeExitedProgramState(old); } else { last = epList; epList = epList->next; } } /* * Add any new record to the list */ if (state) { if (last) { last->next = state; } else { exitedProcessList = state; } } } // VixToolsUpdateExitedProgramList /* *----------------------------------------------------------------------------- * * VixToolsFreeExitedProgramState -- * * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void VixToolsFreeExitedProgramState(VixToolsExitedProgramState *exitState) // IN { if (NULL == exitState) { return; } free(exitState->cmdName); free(exitState->fullCommandLine); free(exitState->user); if (NULL != exitState->procState) { ProcMgr_Free(exitState->procState); } free(exitState); } // VixToolsFreeExitedProgramState /* *----------------------------------------------------------------------------- * * VixToolsFindExitedProgramState -- * * Searches the list of running/exited apps to see if the given * pid was started via StartProgram. * * Results: * Any state matching the given pid. * * Side effects: * None * *----------------------------------------------------------------------------- */ VixToolsExitedProgramState * VixToolsFindExitedProgramState(uint64 pid) { VixToolsExitedProgramState *epList; epList = exitedProcessList; while (epList) { if (epList->pid == pid) { return epList; } epList = epList->next; } return NULL; } /* *----------------------------------------------------------------------------- * * FoundryToolsDaemon_TranslateSystemErr -- * * Looks at errno/GetLastError() and returns the foundry errcode * that it best maps to. * * Return value: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static VixError FoundryToolsDaemon_TranslateSystemErr(void) { #ifdef _WIN32 return Vix_TranslateSystemError(GetLastError()); #else return Vix_TranslateSystemError(errno); #endif } #if SUPPORT_VGAUTH /* *----------------------------------------------------------------------------- * * FoundryToolsDaemon_TranslateSystemErr -- * * Looks at errno/GetLastError() and returns the foundry errcode * that it best maps to. * * Return value: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static VixError VixToolsTranslateVGAuthError(VGAuthError vgErr) { VixError err; switch (VGAUTH_ERROR_CODE(vgErr)) { case VGAUTH_E_OK: err = VIX_OK; break; case VGAUTH_E_INVALID_ARGUMENT: err = VIX_E_INVALID_ARG; break; case VGAUTH_E_INVALID_CERTIFICATE: err = VIX_E_INVALID_ARG; // XXX -- needs a Vix equiv break; case VGAUTH_E_PERMISSION_DENIED: err = VIX_E_GUEST_USER_PERMISSIONS; break; case VGAUTH_E_OUT_OF_MEMORY: err = VIX_E_OUT_OF_MEMORY; break; case VGAUTH_E_COMM: err = VIX_E_FAIL; case VGAUTH_E_NOTIMPLEMENTED: err = VIX_E_NOT_SUPPORTED; break; case VGAUTH_E_NOT_CONNECTED: err = VIX_E_FAIL; break; case VGAUTH_E_VERSION_MISMATCH: err = VIX_E_FAIL; break; case VGAUTH_E_SECURITY_VIOLATION: err = VIX_E_FAIL; break; case VGAUTH_E_CERT_ALREADY_EXISTS: err = VIX_E_INVALID_ARG; break; case VGAUTH_E_AUTHENTICATION_DENIED: err = VIX_E_INVALID_LOGIN_CREDENTIALS; break; case VGAUTH_E_INVALID_TICKET: err = VIX_E_INVALID_ARG; break; case VGAUTH_E_MULTIPLE_MAPPINGS: err = VIX_E_GUEST_AUTH_MULIPLE_MAPPINGS; break; case VGAUTH_E_ALREADY_IMPERSONATING: err = VIX_E_FAIL; break; case VGAUTH_E_NO_SUCH_USER: err = VIX_E_INVALID_ARG; break; case VGAUTH_E_SERVICE_NOT_RUNNING: case VGAUTH_E_SYSTEM_ERRNO: case VGAUTH_E_SYSTEM_WINDOWS: case VGAUTH_E_TOO_MANY_CONNECTIONS: err = VIX_E_FAIL; break; case VGAUTH_E_UNSUPPORTED: err = VIX_E_NOT_SUPPORTED; break; default: err = VIX_E_FAIL; Warning("%s: error code "VGAUTHERR_FMT64X" has no translation\n", __FUNCTION__, vgErr); break; } Debug("%s: translated VGAuth err "VGAUTHERR_FMT64X" to Vix err %"FMT64"d\n", __FUNCTION__, vgErr, err); return err; } #endif /* *----------------------------------------------------------------------------- * * VixTools_GetToolsPropertiesImpl -- * * Get information about test features. * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixTools_GetToolsPropertiesImpl(GKeyFile *confDictRef, // IN char **resultBuffer, // OUT size_t *resultBufferLength) // OUT { VixError err = VIX_OK; VixPropertyListImpl propList; char *serializedBuffer = NULL; size_t serializedBufferLength = 0; #if !defined(__FreeBSD__) char *guestName; int osFamily; char *packageList = NULL; const char *powerOffScript = NULL; const char *powerOnScript = NULL; const char *resumeScript = NULL; const char *suspendScript = NULL; char *osName = NULL; char *osNameFull = NULL; Bool foundHostName; char *tempDir = NULL; int wordSize = 32; VixPropertyList_Initialize(&propList); /* * Collect some values about the host. * * XXX: 512 is the old hardcoded value for the size of the "guestName" * buffer. Since Win32U_GetComputerName returns a new buffer, we do this * hack, since the GuestInfo API expects a pre-allocated buffer. */ guestName = Util_SafeMalloc(512); foundHostName = System_GetNodeName(512, guestName); if (!foundHostName) { free(guestName); #ifdef _WIN32 /* * Give it another try to read NetBIOS name. */ guestName = Win32U_GetComputerName(); #else guestName = Util_SafeStrdup(""); #endif } #ifdef _WIN32 osFamily = GUEST_OS_FAMILY_WINDOWS; #else osFamily = GUEST_OS_FAMILY_LINUX; #endif osNameFull = Hostinfo_GetOSName(); if (osNameFull == NULL) { osNameFull = Util_SafeStrdup(""); } osName = Hostinfo_GetOSGuestString(); if (osName == NULL) { osName = Util_SafeStrdup(""); } wordSize = Hostinfo_GetSystemBitness(); if (wordSize <= 0) { wordSize = 32; } /* * TODO: Something with this. */ packageList = ""; if (confDictRef != NULL) { powerOffScript = g_key_file_get_string(confDictRef, "powerops", CONFNAME_POWEROFFSCRIPT, NULL); powerOnScript = g_key_file_get_string(confDictRef, "powerops", CONFNAME_POWERONSCRIPT, NULL); resumeScript = g_key_file_get_string(confDictRef, "powerops", CONFNAME_RESUMESCRIPT, NULL); suspendScript = g_key_file_get_string(confDictRef, "powerops", CONFNAME_SUSPENDSCRIPT, NULL); } tempDir = File_GetSafeTmpDir(TRUE); /* * Now, record these values in a property list. */ err = VixPropertyList_SetString(&propList, VIX_PROPERTY_GUEST_OS_VERSION, osNameFull); if (VIX_OK != err) { goto abort; } err = VixPropertyList_SetString(&propList, VIX_PROPERTY_GUEST_OS_VERSION_SHORT, osName); if (VIX_OK != err) { goto abort; } err = VixPropertyList_SetString(&propList, VIX_PROPERTY_GUEST_TOOLS_PRODUCT_NAM, PRODUCT_SHORT_NAME); if (VIX_OK != err) { goto abort; } err = VixPropertyList_SetString(&propList, VIX_PROPERTY_GUEST_TOOLS_VERSION, PRODUCT_VERSION_STRING); if (VIX_OK != err) { goto abort; } err = VixPropertyList_SetString(&propList, VIX_PROPERTY_GUEST_NAME, guestName); if (VIX_OK != err) { goto abort; } err = VixPropertyList_SetInteger(&propList, VIX_PROPERTY_GUEST_TOOLS_API_OPTIONS, VIX_TOOLSFEATURE_SUPPORT_GET_HANDLE_STATE); if (VIX_OK != err) { goto abort; } err = VixPropertyList_SetInteger(&propList, VIX_PROPERTY_GUEST_OS_FAMILY, osFamily); if (VIX_OK != err) { goto abort; } err = VixPropertyList_SetString(&propList, VIX_PROPERTY_GUEST_OS_PACKAGE_LIST, packageList); if (VIX_OK != err) { goto abort; } if (NULL != powerOffScript) { err = VixPropertyList_SetString(&propList, VIX_PROPERTY_GUEST_POWER_OFF_SCRIPT, powerOffScript); if (VIX_OK != err) { goto abort; } } if (NULL != resumeScript) { err = VixPropertyList_SetString(&propList, VIX_PROPERTY_GUEST_RESUME_SCRIPT, resumeScript); if (VIX_OK != err) { goto abort; } } if (NULL != powerOnScript) { err = VixPropertyList_SetString(&propList, VIX_PROPERTY_GUEST_POWER_ON_SCRIPT, powerOnScript); if (VIX_OK != err) { goto abort; } } if (NULL != suspendScript) { err = VixPropertyList_SetString(&propList, VIX_PROPERTY_GUEST_SUSPEND_SCRIPT, suspendScript); if (VIX_OK != err) { goto abort; } } err = VixPropertyList_SetString(&propList, VIX_PROPERTY_VM_GUEST_TEMP_DIR_PROPERTY, tempDir); if (VIX_OK != err) { goto abort; } err = VixPropertyList_SetInteger(&propList, VIX_PROPERTY_GUEST_TOOLS_WORD_SIZE, wordSize); if (VIX_OK != err) { goto abort; } /* Retrieve the share folders UNC root path. */ err = VixToolsSetSharedFoldersProperties(&propList); if (VIX_OK != err) { goto abort; } /* Set up the API status properties */ err = VixToolsSetAPIEnabledProperties(&propList, confDictRef); if (VIX_OK != err) { goto abort; } /* * Serialize the property list to buffer then encode it. * This is the string we return to the VMX process. */ err = VixPropertyList_Serialize(&propList, FALSE, &serializedBufferLength, &serializedBuffer); if (VIX_OK != err) { goto abort; } *resultBuffer = serializedBuffer; *resultBufferLength = (int)serializedBufferLength; serializedBuffer = NULL; abort: VixPropertyList_RemoveAllWithoutHandles(&propList); free(guestName); free(serializedBuffer); free(tempDir); free(osName); free(osNameFull); #else /* * FreeBSD. We do not require all the properties above. * We only Support VMODL Guest Ops for now (Bug 228398). */ VixPropertyList_Initialize(&propList); /* InitiateFileTransfer(From|To)Guest operations require this */ err = VixPropertyList_SetInteger(&propList, VIX_PROPERTY_GUEST_OS_FAMILY, GUEST_OS_FAMILY_LINUX); if (VIX_OK != err) { goto abort; } /* Retrieve the share folders UNC root path. */ err = VixToolsSetSharedFoldersProperties(&propList); if (VIX_OK != err) { goto abort; } /* * Set up the API status properties. * This is done so that the client side can tell the * difference between OutOfDate tools and NotSupported. */ err = VixToolsSetAPIEnabledProperties(&propList, confDictRef); if (VIX_OK != err) { goto abort; } /* * Serialize the property list to buffer then encode it. * This is the string we return to the VMX process. */ err = VixPropertyList_Serialize(&propList, FALSE, &serializedBufferLength, &serializedBuffer); if (VIX_OK != err) { goto abort; } *resultBuffer = serializedBuffer; *resultBufferLength = (int)serializedBufferLength; serializedBuffer = NULL; abort: VixPropertyList_RemoveAllWithoutHandles(&propList); free(serializedBuffer); #endif // __FreeBSD__ return err; } // VixTools_GetToolsPropertiesImpl /* *----------------------------------------------------------------------------- * * VixToolsSetSharedFoldersProperties -- * * Set information about the shared folders feature. * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ static VixError VixToolsSetSharedFoldersProperties(VixPropertyListImpl *propList) // IN { VixError err = VIX_OK; /* Retrieve the share folders UNC root path. */ Unicode hgfsRootPath = NULL; if (!HgfsHlpr_QuerySharesDefaultRootPath(&hgfsRootPath)) { /* Exit ok as we have nothing to set from shared folders. */ goto exit; } ASSERT(hgfsRootPath != NULL); err = VixPropertyList_SetString(propList, VIX_PROPERTY_GUEST_SHAREDFOLDERS_SHARES_PATH, UTF8(hgfsRootPath)); if (VIX_OK != err) { goto exit; } exit: if (hgfsRootPath != NULL) { HgfsHlpr_FreeSharesRootPath(hgfsRootPath); } return err; } /* *----------------------------------------------------------------------------- * * VixToolsGetAPIDisabledFromConf -- * * Helper function for fetching the API config setting. * * If the varName is NULL, only the global switch is checked. * * Return value: * Bool * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool VixToolsGetAPIDisabledFromConf(GKeyFile *confDictRef, // IN const char *varName) // IN { gboolean disabled = FALSE; char disabledName[128]; /* * g_key_get_file_boolean() will also return FALSE if there's no * entry in the config file. */ /* * First check the global kill-switch, which will override the * per-API configs if its set. */ if (confDictRef != NULL) { disabled = g_key_file_get_boolean(confDictRef, VIX_TOOLS_CONFIG_API_GROUPNAME, VIX_TOOLS_CONFIG_API_ALL_NAME, NULL); if (disabled) { return TRUE; } } /* * Check the individual API if the global kill-switch isn't on. */ if (NULL != varName) { Str_Snprintf(disabledName, sizeof(disabledName), "%s.disabled", varName); if (confDictRef != NULL) { disabled = g_key_file_get_boolean(confDictRef, VIX_TOOLS_CONFIG_API_GROUPNAME, disabledName, NULL); } } #if !SUPPORT_VGAUTH /* * Make sure vgauth related stuff does not show as enabled. */ if (NULL != varName) { if ((strcmp(varName, VIX_TOOLS_CONFIG_API_ADD_GUEST_ALIAS_NAME) == 0) || (strcmp(varName, VIX_TOOLS_CONFIG_API_REMOVE_GUEST_ALIAS_NAME) == 0) || (strcmp(varName, VIX_TOOLS_CONFIG_API_LIST_GUEST_ALIASES_NAME) == 0) || (strcmp(varName, VIX_TOOLS_CONFIG_API_LIST_GUEST_MAPPED_ALIASES_NAME) == 0)) { disabled = TRUE; } } #endif return disabled; } /* *----------------------------------------------------------------------------- * * VixToolsComputeEnabledProperty -- * * Wrapper function for setting ENABLED properties for VMODL APIs. * For supported guest OSes, it uses VixToolsGetAPIDisabledFromConf() to * check. Otherwise its FALSE. * * * Return value: * Bool * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool VixToolsComputeEnabledProperty(GKeyFile *confDictRef, // IN const char *varName) // IN { return VixToolsGetAPIDisabledFromConf(confDictRef, varName); } /* *----------------------------------------------------------------------------- * * VixToolsSetAPIEnabledProperties -- * * Set information about the state of APIs. * * This is done for all guests, even those that can't do VMODL * guest APIs, so that the client side knows if the tools are * up-to-date. If the client side doesn't see an ENABLED property * for an API it knows about, it assumes the tools are out-of-date, * and returns the appropriate error. * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ static VixError VixToolsSetAPIEnabledProperties(VixPropertyListImpl *propList, // IN GKeyFile *confDictRef) // IN { VixError err = VIX_OK; err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_START_PROGRAM_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_START_PROGRAM_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_LIST_PROCESSES_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_LIST_PROCESSES_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_TERMINATE_PROCESS_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_TERMINATE_PROCESS_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_READ_ENVIRONMENT_VARIABLE_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_READ_ENV_VARS_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_VALIDATE_CREDENTIALS_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_VALIDATE_CREDENTIALS_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_ACQUIRE_CREDENTIALS_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_ACQUIRE_CREDENTIALS_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_RELEASE_CREDENTIALS_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_RELEASE_CREDENTIALS_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_MAKE_DIRECTORY_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_MAKE_DIRECTORY_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_DELETE_FILE_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_DELETE_FILE_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_DELETE_DIRECTORY_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_DELETE_DIRECTORY_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_MOVE_DIRECTORY_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_MOVE_DIRECTORY_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_MOVE_FILE_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_MOVE_FILE_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_CREATE_TEMP_FILE_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_CREATE_TMP_FILE_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_CREATE_TEMP_DIRECTORY_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_CREATE_TMP_DIRECTORY_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_LIST_FILES_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_LIST_FILES_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_CHANGE_FILE_ATTRIBUTES_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_CHANGE_FILE_ATTRS_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_INITIATE_FILE_TRANSFER_FROM_GUEST_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_INITIATE_FILE_TRANSFER_FROM_GUEST_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_INITIATE_FILE_TRANSFER_TO_GUEST_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_INITIATE_FILE_TRANSFER_TO_GUEST_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_ADD_AUTH_ALIAS_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_ADD_GUEST_ALIAS_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_REMOVE_AUTH_ALIAS_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_REMOVE_GUEST_ALIAS_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_LIST_AUTH_ALIASES_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_LIST_GUEST_ALIASES_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_LIST_MAPPED_ALIASES_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_LIST_GUEST_MAPPED_ALIASES_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_CREATE_REGISTRY_KEY_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_CREATE_REGISTRY_KEY_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_LIST_REGISTRY_KEYS_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_LIST_REGISTRY_KEYS_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_DELETE_REGISTRY_KEY_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_DELETE_REGISTRY_KEY_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_SET_REGISTRY_VALUE_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_SET_REGISTRY_VALUE_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_LIST_REGISTRY_VALUES_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_LIST_REGISTRY_VALUES_NAME)); if (VIX_OK != err) { goto exit; } err = VixPropertyList_SetBool(propList, VIX_PROPERTY_GUEST_DELETE_REGISTRY_VALUE_ENABLED, VixToolsComputeEnabledProperty(confDictRef, VIX_TOOLS_CONFIG_API_DELETE_REGISTRY_VALUE_NAME)); if (VIX_OK != err) { goto exit; } exit: Debug("finished %s, err %"FMT64"d\n", __FUNCTION__, err); return err; } // VixToolsSetAPIEnabledProperties /* *----------------------------------------------------------------------------- * * VixToolsReadRegistry -- * * Read an int from the registry on the guest. * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsReadRegistry(VixCommandRequestHeader *requestMsg, // IN char **result) // OUT { #ifdef _WIN32 VixError err = VIX_OK; char *registryPathName = NULL; int valueInt = 0; int errResult; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; char *valueStr = NULL; VixMsgRegistryRequest *registryRequest; VMAutomationRequestParser parser; /* * Parse the argument */ err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *registryRequest); if (VIX_OK != err) { goto abort; } registryRequest = (VixMsgRegistryRequest *) requestMsg; err = VMAutomationRequestParserGetString(&parser, registryRequest->registryKeyLength, &(const char*)registryPathName); if (VIX_OK != err) { goto abort; } if (0 == *registryPathName) { err = VIX_E_INVALID_ARG; goto abort; } err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; if (VIX_PROPERTYTYPE_INTEGER == registryRequest->expectedRegistryKeyType) { errResult = Registry_ReadInteger(registryPathName, &valueInt); if (ERROR_SUCCESS != errResult) { /* * E_UNEXPECTED isn't a system err. Don't use Vix_TranslateSystemError */ if (E_UNEXPECTED == errResult) { err = VIX_E_REG_INCORRECT_VALUE_TYPE; } else { err = Vix_TranslateSystemError(errResult); } goto abort; } valueStr = Str_SafeAsprintf(NULL, "%d", valueInt); if (NULL == valueStr) { err = VIX_E_OUT_OF_MEMORY; goto abort; } } else if (VIX_PROPERTYTYPE_STRING == registryRequest->expectedRegistryKeyType) { errResult = Registry_ReadString(registryPathName, &valueStr); if (ERROR_SUCCESS != errResult) { /* * E_UNEXPECTED isn't a system err. Don't use Vix_TranslateSystemError */ if (E_UNEXPECTED == errResult) { err = VIX_E_REG_INCORRECT_VALUE_TYPE; } else { err = Vix_TranslateSystemError(errResult); } goto abort; } } else { err = VIX_E_INVALID_ARG; goto abort; } abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); if (NULL == valueStr) { valueStr = Util_SafeStrdup(""); } *result = valueStr; return err; #else return VIX_E_OP_NOT_SUPPORTED_ON_GUEST; #endif } // VixToolsReadRegistry /* *----------------------------------------------------------------------------- * * VixToolsWriteRegistry -- * * Write an integer to the registry on the guest. * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsWriteRegistry(VixCommandRequestHeader *requestMsg) // IN { #ifdef _WIN32 VixError err = VIX_OK; char *registryPathName = NULL; char *registryData = NULL; int errResult; int intValue; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; VixMsgRegistryRequest *registryRequest; VMAutomationRequestParser parser; /* * Parse the argument */ err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *registryRequest); if (VIX_OK != err) { goto abort; } registryRequest = (VixMsgRegistryRequest *) requestMsg; err = VMAutomationRequestParserGetString(&parser, registryRequest->registryKeyLength, &(const char*)registryPathName); if (VIX_OK != err) { goto abort; } if (0 == *registryPathName) { err = VIX_E_INVALID_ARG; goto abort; } err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; if (VIX_PROPERTYTYPE_INTEGER == registryRequest->expectedRegistryKeyType) { err = VMAutomationRequestParserGetData(&parser, registryRequest->dataToWriteSize, &(const char*)registryData); if (VIX_OK != err) { goto abort; } intValue = *((int *) registryData); errResult = Registry_WriteInteger(registryPathName, intValue); if (ERROR_SUCCESS != errResult) { err = Vix_TranslateSystemError(errResult); goto abort; } } else if (VIX_PROPERTYTYPE_STRING == registryRequest->expectedRegistryKeyType) { err = VMAutomationRequestParserGetOptionalString(&parser, registryRequest->dataToWriteSize, &(const char*)registryData); if (VIX_OK != err) { goto abort; } errResult = Registry_WriteString(registryPathName, registryData); if (ERROR_SUCCESS != errResult) { err = Vix_TranslateSystemError(errResult); goto abort; } } else { err = VIX_E_INVALID_ARG; goto abort; } abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); return err; #else return VIX_E_OP_NOT_SUPPORTED_ON_GUEST; #endif } // VixToolsWriteRegistry /* *----------------------------------------------------------------------------- * * VixToolsDeleteObject -- * * Delete a file on the guest. * * Return value: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsDeleteObject(VixCommandRequestHeader *requestMsg) // IN { VixError err = VIX_OK; const char *pathName = NULL; int resultInt; Bool resultBool; Bool success; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; VixMsgSimpleFileRequest *fileRequest; VMAutomationRequestParser parser; /* * Parse the argument */ err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *fileRequest); if (VIX_OK != err) { goto abort; } fileRequest = (VixMsgSimpleFileRequest *) requestMsg; err = VMAutomationRequestParserGetString(&parser, fileRequest->guestPathNameLength, &pathName); if (VIX_OK != err) { goto abort; } if (0 == *pathName) { err = VIX_E_INVALID_ARG; goto abort; } err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; /////////////////////////////////////////// if ((VIX_COMMAND_DELETE_GUEST_FILE == requestMsg->opCode) || (VIX_COMMAND_DELETE_GUEST_FILE_EX == requestMsg->opCode)) { /* * if pathName is an invalid symbolic link, we still want to delete it. */ if (FALSE == File_IsSymLink(pathName)) { if (!(File_Exists(pathName))) { err = VIX_E_FILE_NOT_FOUND; goto abort; } if (!(File_IsFile(pathName))) { err = VIX_E_NOT_A_FILE; goto abort; } } resultInt = File_UnlinkNoFollow(pathName); if (0 != resultInt) { err = FoundryToolsDaemon_TranslateSystemErr(); } /////////////////////////////////////////// } else if (VIX_COMMAND_DELETE_GUEST_REGISTRY_KEY == requestMsg->opCode) { #ifdef _WIN32 err = VIX_E_OP_NOT_SUPPORTED_ON_GUEST; #else err = VIX_E_OP_NOT_SUPPORTED_ON_GUEST; #endif /////////////////////////////////////////// } else if (VIX_COMMAND_DELETE_GUEST_DIRECTORY == requestMsg->opCode) { resultBool = File_Exists(pathName); if (!resultBool) { err = VIX_E_FILE_NOT_FOUND; goto abort; } resultBool = File_IsDirectory(pathName); if (!resultBool) { err = VIX_E_NOT_A_DIRECTORY; goto abort; } success = File_DeleteDirectoryTree(pathName); if (!success) { err = FoundryToolsDaemon_TranslateSystemErr(); goto abort; } /////////////////////////////////////////// } else if (VIX_COMMAND_DELETE_GUEST_EMPTY_DIRECTORY == requestMsg->opCode) { resultBool = File_Exists(pathName); if (!resultBool) { err = VIX_E_FILE_NOT_FOUND; goto abort; } resultBool = File_IsDirectory(pathName); if (!resultBool) { err = VIX_E_NOT_A_DIRECTORY; goto abort; } success = File_DeleteEmptyDirectory(pathName); if (!success) { #if !defined(_WIN32) /* * If the specified directory is not empty then * File_DeleteEmptyDirectory() fails and * 1. errno is set to either EEXIST or ENOTEMPTY on linux platforms. * 2. errno is set EEXIST on Solaris platforms. * * To maintain consistency across different Posix platforms, lets * re-write the error before returning. */ if (EEXIST == errno) { errno = ENOTEMPTY; } #endif err = FoundryToolsDaemon_TranslateSystemErr(); goto abort; } /////////////////////////////////////////// } else { err = VIX_E_INVALID_ARG; goto abort; } abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); return err; } // VixToolsDeleteObject /* *----------------------------------------------------------------------------- * * VixToolsDeleteDirectory -- * * Delete a directory on the guest. * * Return value: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsDeleteDirectory(VixCommandRequestHeader *requestMsg) // IN { VixError err = VIX_OK; const char *directoryPath = NULL; Bool success; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; Bool recursive = TRUE; VixMsgDeleteDirectoryRequest *deleteDirectoryRequest; VMAutomationRequestParser parser; ASSERT(NULL != requestMsg); /* * Parse the argument */ err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *deleteDirectoryRequest); if (VIX_OK != err) { goto abort; } deleteDirectoryRequest = (VixMsgDeleteDirectoryRequest *) requestMsg; err = VMAutomationRequestParserGetString(&parser, deleteDirectoryRequest->guestPathNameLength, &directoryPath); if (VIX_OK != err) { goto abort; } if ('\0' == *directoryPath) { err = VIX_E_INVALID_ARG; goto abort; } recursive = deleteDirectoryRequest->recursive; err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; success = File_Exists(directoryPath); if (!success) { err = VIX_E_FILE_NOT_FOUND; goto abort; } if (File_IsSymLink(directoryPath) || File_IsFile(directoryPath)) { err = VIX_E_NOT_A_DIRECTORY; goto abort; } if (recursive) { success = File_DeleteDirectoryTree(directoryPath); } else { success = File_DeleteEmptyDirectory(directoryPath); } if (!success) { if (!recursive) { #if !defined(_WIN32) /* * If the specified directory is not empty then * File_DeleteEmptyDirectory() fails and * 1. errno is set to either EEXIST or ENOTEMPTY on linux platforms. * 2. errno is set EEXIST on Solaris platforms. * * To maintain consistency across different Posix platforms, lets * re-write the error before returning. */ if (EEXIST == errno) { errno = ENOTEMPTY; } #endif } err = FoundryToolsDaemon_TranslateSystemErr(); goto abort; } abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); return err; } // VixToolsDeleteDirectory /* *----------------------------------------------------------------------------- * * VixToolsObjectExists -- * * Find a file on the guest. * * Return value: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsObjectExists(VixCommandRequestHeader *requestMsg, // IN char **result) // OUT { VixError err = VIX_OK; char *pathName = NULL; int resultInt = 0; Bool resultBool; static char resultBuffer[32]; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; VixMsgSimpleFileRequest *fileRequest; VMAutomationRequestParser parser; /* * Parse the argument */ err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *fileRequest); if (VIX_OK != err) { goto abort; } fileRequest = (VixMsgSimpleFileRequest *) requestMsg; err = VMAutomationRequestParserGetString(&parser, fileRequest->guestPathNameLength, (const char **)&pathName); if (VIX_OK != err) { goto abort; } if (0 == *pathName) { err = VIX_E_INVALID_ARG; goto abort; } err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; /* * Do the action appropriate for this type of object. */ /////////////////////////////////////////// if (VIX_COMMAND_GUEST_FILE_EXISTS == requestMsg->opCode) { resultBool = File_IsFile(pathName); if (resultBool) { resultInt = 1; } else { resultInt = 0; } /////////////////////////////////////////// } else if (VIX_COMMAND_REGISTRY_KEY_EXISTS == requestMsg->opCode) { #ifdef _WIN32 resultInt = Registry_KeyExists(pathName); #else resultInt = 0; err = VIX_E_OP_NOT_SUPPORTED_ON_GUEST; #endif /////////////////////////////////////////// } else if (VIX_COMMAND_DIRECTORY_EXISTS == requestMsg->opCode) { resultBool = File_IsDirectory(pathName); if (resultBool) { resultInt = 1; } else { resultInt = 0; } /////////////////////////////////////////// } else { err = VIX_E_INVALID_ARG; goto abort; } abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); Str_Sprintf(resultBuffer, sizeof(resultBuffer), "%d", resultInt); *result = resultBuffer; return err; } // VixToolsObjectExists /* *----------------------------------------------------------------------------- * * VixToolsCreateTempFile -- * * Create a temporary file on the guest. * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsCreateTempFile(VixCommandRequestHeader *requestMsg, // IN char **result) // OUT: UTF-8 { VixError err = VIX_OK; char *filePathName = NULL; int fd = -1; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; if ((VIX_COMMAND_CREATE_TEMPORARY_FILE != requestMsg->opCode) && (VIX_COMMAND_CREATE_TEMPORARY_FILE_EX != requestMsg->opCode) && (VIX_COMMAND_CREATE_TEMPORARY_DIRECTORY != requestMsg->opCode)) { ASSERT(0); err = VIX_E_FAIL; Debug("%s: Received a request with an invalid opcode: %d\n", __FUNCTION__, requestMsg->opCode); goto abort; } err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; err = VixToolsGetTempFile(requestMsg, userToken, &filePathName, &fd); if (VIX_FAILED(err)) { goto abort; } /* * Just close() the file, since we're not going to use it. But, when we * create a temporary directory, VixToolsGetTempFile() sets 'fd' to 0 on * success. On windows, close() shouldn't be called for invalid fd values. * So, call close() only if 'fd' is valid. */ if (fd > 0) { if (close(fd) < 0) { Debug("Unable to close a file, errno is %d.\n", errno); } } *result = filePathName; abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); return err; } // VixToolsCreateTempFile /* *----------------------------------------------------------------------------- * * VixToolsReadVariable -- * * Read an environment variable in the guest. The name of the environment * variable is expected to be in UTF-8. * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsReadVariable(VixCommandRequestHeader *requestMsg, // IN char **result) // OUT: UTF-8 { VixError err = VIX_OK; char *value = ""; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; VixMsgReadVariableRequest *readRequest; const char *valueName = NULL; VMAutomationRequestParser parser; err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *readRequest); if (VIX_OK != err) { goto abort; } readRequest = (VixMsgReadVariableRequest *) requestMsg; err = VMAutomationRequestParserGetString(&parser, readRequest->nameLength, &valueName); if (VIX_OK != err) { goto abort; } err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; switch (readRequest->variableType) { case VIX_GUEST_ENVIRONMENT_VARIABLE: /* * Alwasy get environment variable for the current user, even if the * current user is root/administrator */ #ifndef _WIN32 /* * If we are maintaining our own set of environment variables * because the application we're running from changed the user's * environment, then we should be reading from that. */ if (NULL != userEnvironmentTable) { if (HashTable_Lookup(userEnvironmentTable, valueName, (void **) &value)) { value = Util_SafeStrdup(value); } else { value = Util_SafeStrdup(""); } break; } #endif err = VixToolsGetEnvForUser(userToken, valueName, &value); if (VIX_OK != err) { goto abort; } break; case VIX_GUEST_CONFIG: case VIX_VM_CONFIG_RUNTIME_ONLY: case VIX_VM_GUEST_VARIABLE: default: err = VIX_E_OP_NOT_SUPPORTED_ON_GUEST; break; } // switch (readRequest->variableType) *result = value; abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); return err; } // VixToolsReadVariable /* *----------------------------------------------------------------------------- * * VixToolsGetEnvVarForUser -- * * Reads a single environment variable from the given user's * environment. * * Results: * VixError * 'value' points to a heap-allocated string containing the value. * * Side effects: * None * *----------------------------------------------------------------------------- */ static VixError VixToolsGetEnvForUser(void *userToken, // IN const char *name, // IN char **value) // OUT { VixError err; VixToolsUserEnvironment *env; ASSERT(NULL != value); err = VixToolsNewUserEnvironment(userToken, &env); if (VIX_FAILED(err)) { return err; } *value = VixToolsGetEnvFromUserEnvironment(env, name); VixToolsDestroyUserEnvironment(env); if (NULL == *value) { *value = Util_SafeStrdup(""); } return err; } /* *----------------------------------------------------------------------------- * * VixToolsReadEnvVariables -- * * Read environment variables in the guest. The name of the environment * variables are expected to be in UTF-8. * * If a variable doesn't exist, nothing is returned for it. * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsReadEnvVariables(VixCommandRequestHeader *requestMsg, // IN char **result) // OUT: UTF-8 { VixError err = VIX_OK; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; VixMsgReadEnvironmentVariablesRequest *readRequest; char *results = NULL; VMAutomationRequestParser parser; const char *names = NULL; err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *readRequest); if (VIX_OK != err) { goto abort; } readRequest = (VixMsgReadEnvironmentVariablesRequest *) requestMsg; err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; err = VMAutomationRequestParserGetOptionalStrings(&parser, readRequest->numNames, readRequest->namesLength, &names); if (VIX_OK != err) { goto abort; } if (readRequest->numNames > 0) { err = VixToolsGetMultipleEnvVarsForUser(userToken, names, readRequest->numNames, &results); if (VIX_FAILED(err)) { goto abort; } } else { /* * If none are specified, return all of them. */ err = VixToolsGetAllEnvVarsForUser(userToken, &results); if (VIX_FAILED(err)) { goto abort; } } *result = results; abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); return err; } // VixToolsReadEnvVariables /* *----------------------------------------------------------------------------- * * VixToolsGetMultipleEnvVarsForUser -- * * Populates result with an XML-like string containing all the * environment variables listed starting at 'names' (each name is * separated by a null character). * The result string will contain zero or more entries of the form * NAME=VALUE without any delimiting characters. * * Results: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ static VixError VixToolsGetMultipleEnvVarsForUser(void *userToken, // IN const char *names, // IN unsigned int numNames, // IN char **result) // OUT { VixError err; unsigned int i; char *resultLocal = Util_SafeStrdup(""); // makes the loop cleaner. VixToolsUserEnvironment *env; #ifdef __FreeBSD__ if (NULL == userEnvironmentTable) { err = VIX_E_FAIL; free(resultLocal); return err; } #endif err = VixToolsNewUserEnvironment(userToken, &env); if (VIX_FAILED(err)) { env = NULL; goto abort; } for (i = 0; i < numNames; i++) { char *value; #ifdef __FreeBSD__ /* * We should check the original envp for all vars except * a few whitelisted ones that we set/unset on impersonate * user start/stop. for them we need to do getenv() */ if (!strcmp(names, "USER") || !strcmp(names, "HOME") || !strcmp(names, "SHELL")) { value = VixToolsGetEnvFromUserEnvironment(env, names); } else { if (HashTable_Lookup(userEnvironmentTable, names, (void **) &value)) { value = Util_SafeStrdup(value); } else { value = Util_SafeStrdup(""); } } #else value = VixToolsGetEnvFromUserEnvironment(env, names); #endif if (NULL != value) { char *tmp = resultLocal; char *tmpVal; char *escapedName; escapedName = VixToolsEscapeXMLString(names); if (NULL == escapedName) { err = VIX_E_OUT_OF_MEMORY; goto loopCleanup; } tmpVal = VixToolsEscapeXMLString(value); if (NULL == tmpVal) { err = VIX_E_OUT_OF_MEMORY; goto loopCleanup; } free(value); value = tmpVal; resultLocal = Str_SafeAsprintf(NULL, "%s%s=%s", tmp, escapedName, value); free(tmp); if (NULL == resultLocal) { err = VIX_E_OUT_OF_MEMORY; } loopCleanup: free(value); free(escapedName); if (VIX_OK != err) { goto abort; } } names += strlen(names) + 1; } *result = resultLocal; resultLocal = NULL; err = VIX_OK; abort: free(resultLocal); VixToolsDestroyUserEnvironment(env); return err; } /* *----------------------------------------------------------------------------- * * VixToolsGetAllEnvVarsForUser -- * * Populates result with an XML-like string containing all the * environment variables set for the user represented by 'userToken'. * The result string will contain zero or more entries of the form * NAME=VALUE without any delimiting characters. * * Results: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ static VixError VixToolsGetAllEnvVarsForUser(void *userToken, // IN char **result) // OUT { VixError err; char *resultLocal; VixToolsEnvIterator *itr; char *envVar; #ifdef __FreeBSD__ char **envp; if (NULL == userEnvironmentTable) { err = VIX_E_FAIL; return err; } envp = VixToolsEnvironmentTableToEnvp(userEnvironmentTable); #endif if (NULL == result) { err = VIX_E_FAIL; return err; } resultLocal = Util_SafeStrdup(""); // makes the loop cleaner. #ifdef __FreeBSD__ err = VixToolsNewEnvIterator(userToken, envp, &itr); #else err = VixToolsNewEnvIterator(userToken, &itr); #endif if (VIX_FAILED(err)) { goto abort; } while ((envVar = VixToolsGetNextEnvVar(itr)) != NULL) { char *tmp = resultLocal; char *tmpVal; #ifdef __FreeBSD__ /* * For variables we change during Impersonatation of user, * we need to fetch from getenv() system call, all else * can be read from the hash table of the original envp. */ if (StrUtil_StartsWith(envVar, "USER=") || StrUtil_StartsWith(envVar, "HOME=") || StrUtil_StartsWith(envVar, "SHELL=")) { char *name = NULL; char *escapedName = NULL; char *whereToSplit; size_t nameLen; whereToSplit = strchr(envVar, '='); if (NULL == whereToSplit) { /* Our code generated this list, so this shouldn't happen. */ ASSERT(0); continue; } nameLen = whereToSplit - envVar; name = Util_SafeMalloc(nameLen + 1); memcpy(name, envVar, nameLen); name[nameLen] = '\0'; escapedName = VixToolsEscapeXMLString(name); free(envVar); envVar = Str_SafeAsprintf(NULL, "%s=%s", escapedName, Posix_Getenv(name)); free(name); free(escapedName); } #endif tmpVal = VixToolsEscapeXMLString(envVar); free(envVar); if (NULL == tmpVal) { err = VIX_E_OUT_OF_MEMORY; goto abort; } envVar = tmpVal; resultLocal = Str_SafeAsprintf(NULL, "%s%s", tmp, envVar); free(tmp); free(envVar); if (NULL == resultLocal) { Debug("%s: Out of memory.\n", __FUNCTION__); err = VIX_E_OUT_OF_MEMORY; goto abort; } } abort: VixToolsDestroyEnvIterator(itr); #ifdef __FreeBSD__ VixToolsFreeEnvp(envp); #endif *result = resultLocal; return err; } /* *----------------------------------------------------------------------------- * * VixToolsWriteVariable -- * * Write an environment variable in the guest. The name of the environment * variable and its value are expected to be in UTF-8. * * Return value: * VixError * * Side effects: * Yes, may change the environment variables. * *----------------------------------------------------------------------------- */ VixError VixToolsWriteVariable(VixCommandRequestHeader *requestMsg) // IN { VixError err = VIX_OK; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; VixMsgWriteVariableRequest *writeRequest; char *valueName = NULL; char *value = NULL; int result; writeRequest = (VixMsgWriteVariableRequest *) requestMsg; err = VixMsg_ParseWriteVariableRequest(writeRequest, &valueName, &value); if (VIX_OK != err) { goto abort; } err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; switch (writeRequest->variableType) { case VIX_GUEST_ENVIRONMENT_VARIABLE: #if !defined(_WIN32) /* * On Linux, we only allow root to set environment variables. * On Windows we can put ACLs on the registry keys, but we can't do that * on Linux. The threat is if an unpriveleged user changes path or lib * settings, which could cause a later call from a priveleged user * to RunProgramInGuest to misbehave by using compromised libs or environment. */ if (1 != Util_HasAdminPriv()) { err = VIX_E_GUEST_USER_PERMISSIONS; goto abort; } #endif /* * At this point, we want to set environmental variable for current * user, even if the current user is root/administrator */ result = System_SetEnv(FALSE, valueName, value); if (0 != result) { err = FoundryToolsDaemon_TranslateSystemErr(); goto abort; } #ifndef _WIN32 /* * We need to make sure that this change is reflected in the table of * environment variables we use when launching programs. This is so if a * a user sets LD_LIBRARY_PATH with WriteVariable, and then calls * RunProgramInGuest, that program will see the new value. */ if (NULL != userEnvironmentTable) { /* * The hash table will make a copy of valueName, but we have to supply * a deep copy of the value. */ HashTable_ReplaceOrInsert(userEnvironmentTable, valueName, Util_SafeStrdup(value)); } #endif break; case VIX_GUEST_CONFIG: case VIX_VM_CONFIG_RUNTIME_ONLY: case VIX_VM_GUEST_VARIABLE: default: err = VIX_E_OP_NOT_SUPPORTED_ON_GUEST; break; } // switch (readRequest->variableType) abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); return err; } // VixToolsWriteVariable /* *----------------------------------------------------------------------------- * * VixToolsMoveObject -- * * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsMoveObject(VixCommandRequestHeader *requestMsg) // IN { VixError err = VIX_OK; const char *srcFilePathName = NULL; const char *destFilePathName = NULL; Bool success; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; Bool overwrite = TRUE; VMAutomationRequestParser parser; int srcPathLen, destPathLen; if (VIX_COMMAND_MOVE_GUEST_FILE == requestMsg->opCode) { VixCommandRenameFileRequest *renameRequest; err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *renameRequest); if (VIX_OK != err) { goto abort; } renameRequest = (VixCommandRenameFileRequest *) requestMsg; srcPathLen = renameRequest->oldPathNameLength; destPathLen = renameRequest->newPathNameLength; } else if ((VIX_COMMAND_MOVE_GUEST_FILE_EX == requestMsg->opCode) || (VIX_COMMAND_MOVE_GUEST_DIRECTORY == requestMsg->opCode)) { VixCommandRenameFileRequestEx *renameRequest; err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *renameRequest); if (VIX_OK != err) { goto abort; } renameRequest = (VixCommandRenameFileRequestEx *) requestMsg; srcPathLen = renameRequest->oldPathNameLength; destPathLen = renameRequest->newPathNameLength; overwrite = renameRequest->overwrite; } else { ASSERT(0); Debug("%s: Invalid request with opcode %d received\n ", __FUNCTION__, requestMsg->opCode); err = VIX_E_FAIL; goto abort; } err = VMAutomationRequestParserGetString(&parser, srcPathLen, &srcFilePathName); if (VIX_OK != err) { goto abort; } err = VMAutomationRequestParserGetString(&parser, destPathLen, &destFilePathName); if (VIX_OK != err) { goto abort; } if ((0 == *srcFilePathName) || (0 == *destFilePathName)) { err = VIX_E_INVALID_ARG; goto abort; } Debug("%s: src = %s, dest=%s\n", __FUNCTION__, srcFilePathName, destFilePathName); err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; if (!(File_Exists(srcFilePathName))) { err = VIX_E_FILE_NOT_FOUND; goto abort; } /* * Be careful. Renaming a file to itself can cause it to be deleted. * This should be a no-op anyway. */ #if !defined(sun) && !defined(__FreeBSD__) if (File_IsSameFile(srcFilePathName, destFilePathName)) { err = VIX_OK; goto abort; } #else /* * Do something better for Solaris and FreeBSD once we support them. */ if (strcmp(srcFilePathName, destFilePathName) == 0) { err = VIX_OK; goto abort; } #endif /* * pre-check the dest arg -- File_Move() will return * diff err codes depending on OS, so catch it up front (bug 133165) */ if (File_IsDirectory(destFilePathName)) { if ((VIX_COMMAND_MOVE_GUEST_FILE_EX == requestMsg->opCode) || (VIX_COMMAND_MOVE_GUEST_DIRECTORY == requestMsg->opCode)) { /* * If File_IsDirectory() returns true, it doesn't mean the * filepath points to a real directory. It may point to a symlink. * So perform a quick symlink check. Do this only for opcodes * related to VI Guest Operations. Otherwise, it may affect * the existing tests. */ if (!File_IsSymLink(destFilePathName)) { /* * If we are implementing opcodes related to VI Guest operations, * then return VIX_E_FILE_ALREADY_EXISTS. Don't change the error * code for opcode related to VIX C api. It will break the existing * tests. */ err = VIX_E_FILE_ALREADY_EXISTS; goto abort; } } else { err = VIX_E_ALREADY_EXISTS; goto abort; } } if (VIX_COMMAND_MOVE_GUEST_FILE_EX == requestMsg->opCode) { if (File_IsDirectory(srcFilePathName)) { /* * Be careful while executing File_[File|Directory] operations. * In case of symlinks, these functions are smart engough to * resolve the final component pointed by the symlink and do * the check on the final component. * * For VI guest operations, MoveFile should return * VIX_E_NOT_A_FILE if the file path points to a real directory. * File_IsDirectory() returns true if it is invoked on a * symlink that points to a directory. So, we have to * filter out that case before returning VIX_E_NOT_A_FILE. */ if (!File_IsSymLink(srcFilePathName)) { err = VIX_E_NOT_A_FILE; goto abort; } } if (!overwrite) { if (File_Exists(destFilePathName)) { err = VIX_E_FILE_ALREADY_EXISTS; goto abort; } } } else if (VIX_COMMAND_MOVE_GUEST_DIRECTORY == requestMsg->opCode) { /* * For VI guest operations, MoveDirectory should return * VIX_E_NOT_A_DIRECTORY if the file path doesn't point to a real * directory. File_IsDirectory() returns false if it is invoked on * a symlink that points to a file. So, we should include that * check before returning VIX_E_NOT_A_DIRECTORY. */ if (!(File_IsDirectory(srcFilePathName)) || (File_IsSymLink(srcFilePathName))) { err = VIX_E_NOT_A_DIRECTORY; goto abort; } /* * In case of moving a directory, File_Move() returns different * errors on different Guest Os if the destination file path points * to an existing file. We should catch them upfront and report them * to the user. * As per the documentation for rename() on linux, if the source * file points to an existing directory, then destionation file * should not point to anything other than a directory. */ if (File_IsSymLink(destFilePathName) || File_IsFile(destFilePathName)) { err = VIX_E_FILE_ALREADY_EXISTS; goto abort; } } success = File_Move(srcFilePathName, destFilePathName, NULL); if (!success) { err = FoundryToolsDaemon_TranslateSystemErr(); Debug("%s: File_Move failed.\n", __FUNCTION__); goto abort; } abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); return err; } // VixToolsMoveObject /* *----------------------------------------------------------------------------- * * VixToolsInitiateFileTransferFromGuest -- * * This function is called to implement * InitiateFileTransferFromGuest VI guest operation. Specified filepath * should not point to a directory or a symlink. * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsInitiateFileTransferFromGuest(VixCommandRequestHeader *requestMsg, // IN char **result) // OUT { VixError err = VIX_OK; const char *filePathName = NULL; char *resultBuffer = NULL; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; VixMsgListFilesRequest *commandRequest = NULL; VMAutomationRequestParser parser; ASSERT(NULL != requestMsg); ASSERT(NULL != result); err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *commandRequest); if (VIX_OK != err) { goto abort; } commandRequest = (VixMsgListFilesRequest *) requestMsg; err = VMAutomationRequestParserGetString(&parser, commandRequest->guestPathNameLength, &filePathName); if (VIX_OK != err) { goto abort; } if (0 == *filePathName) { err = VIX_E_INVALID_ARG; goto abort; } err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; if (File_IsSymLink(filePathName)){ Debug("%s: File path cannot point to a symlink.\n", __FUNCTION__); err = VIX_E_INVALID_ARG; goto abort; } if (File_IsDirectory(filePathName)) { err = VIX_E_NOT_A_FILE; goto abort; } if (!File_Exists(filePathName)) { err = VIX_E_FILE_NOT_FOUND; goto abort; } resultBuffer = VixToolsPrintFileExtendedInfoEx(filePathName, filePathName); abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); if (NULL == resultBuffer) { resultBuffer = Util_SafeStrdup(""); } *result = resultBuffer; return err; } // VixToolsInitiateFileTransferFromGuest /* *----------------------------------------------------------------------------- * * VixToolsInitiateFileTransferToGuest -- * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsInitiateFileTransferToGuest(VixCommandRequestHeader *requestMsg) // IN { VixError err = VIX_OK; const char *guestPathName = NULL; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; Bool overwrite = TRUE; char *dirName = NULL; char *baseName = NULL; int32 fileAttributeOptions = 0; #if defined(_WIN32) int fd = -1; char *tempFilePath = NULL; static char *tempFileBaseName = "vmware"; #endif FileIOResult res; VixCommandInitiateFileTransferToGuestRequest *commandRequest; VMAutomationRequestParser parser; ASSERT(NULL != requestMsg); /* * Parse the argument */ err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *commandRequest); if (VIX_OK != err) { goto abort; } commandRequest = (VixCommandInitiateFileTransferToGuestRequest *) requestMsg; overwrite = commandRequest->overwrite; err = VMAutomationRequestParserGetString(&parser, commandRequest->guestPathNameLength, &guestPathName); if (VIX_OK != err) { goto abort; } if ('\0' == *guestPathName) { err = VIX_E_INVALID_ARG; goto abort; } fileAttributeOptions = commandRequest->options; #if defined(_WIN32) if ((fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_UNIX_OWNERID) || (fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_UNIX_GROUPID) || (fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_UNIX_PERMISSIONS)) { Debug("%s: Invalid attributes received for Windows Guest\n", __FUNCTION__); err = VIX_E_INVALID_ARG; goto abort; } #else if ((fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_HIDDEN) || (fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_READONLY)) { Debug("%s: Invalid attributes received for Unix Guest\n", __FUNCTION__); err = VIX_E_INVALID_ARG; goto abort; } #endif err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; if (File_IsSymLink(guestPathName)) { Debug("%s: Filepath cannot point to a symlink.\n", __FUNCTION__); err = VIX_E_INVALID_ARG; goto abort; } if (File_Exists(guestPathName)) { if (File_IsDirectory(guestPathName)) { err = VIX_E_NOT_A_FILE; } else if (!overwrite) { err = VIX_E_FILE_ALREADY_EXISTS; } else { /* * If the file exists and overwrite flag is true, then check * if the file is writable. If not, return a proper error. */ res = FileIO_Access(guestPathName, FILEIO_ACCESS_WRITE); if (FILEIO_SUCCESS != res) { /* * On Linux guests, FileIO_Access sets the proper errno * on failure. On Windows guests, last errno is not * set when FileIO_Access fails. So, we cannot use * FoundryToolsDaemon_TranslateSystemErr() to translate the * error. To maintain consistency for all the guests, * return an explicit VIX_E_FILE_ACCESS_ERROR. */ err = VIX_E_FILE_ACCESS_ERROR; Debug("Unable to get access permissions for the file: %s\n", guestPathName); } } goto abort; } File_GetPathName(guestPathName, &dirName, &baseName); if ((NULL == dirName) || (NULL == baseName)) { err = VIX_E_FILE_NAME_INVALID; goto abort; } if (!File_IsDirectory(dirName)) { err = VIX_E_FILE_NAME_INVALID; goto abort; } #if defined(_WIN32) /* * Ideally, we just need to check if the user has proper write * access to create a child inside the directory. This can be * checked by calling FileIO_Access(). FileIO_Access works perfectly * fine for linux platforms. But on Windows, FileIO_Access just * checks the read-only attribute of the directory and returns the result * based on that. This is not the proper way to check the write * permissions. * * One other way to check the write access is to call CreateFile() * with GENERIC_WRITE and OPEN_EXISTING flags. Check the documentation * for CreateFile() at * http://msdn.microsoft.com/en-us/library/aa363858%28v=VS.85%29.aspx. * But this has got few limitations. CreateFile() doesn't return proper * result when called for directories on NTFS systems. * Checks the KB article available at * http://support.microsoft.com/kb/810881. * * So, for windows, the best bet is to create an empty temporary file * inside the directory and immediately unlink that. If creation is * successful, it ensures that the user has proper write access for * the directory. * * Since we are just checking the write access, there is no need to * create the temporary file with the exact specified filename. Any name * would be fine. */ fd = File_MakeTempEx(dirName, tempFileBaseName, &tempFilePath); if (fd > 0) { close(fd); File_UnlinkNoFollow(tempFilePath); } else { /* * File_MakeTempEx() function internally uses Posix variant * functions and proper error will be stuffed in errno variable. * If File_MakeTempEx() fails, then use Vix_TranslateErrno() * to translate the errno to a proper foundry error. */ err = Vix_TranslateErrno(errno); Debug("Unable to create a temp file to test directory permissions," " errno is %d\n", errno); goto abort; } free(tempFilePath); #else /* * We need to check if the user has write access to create * a child inside the directory. Call FileIO_Access() to check * for the proper write permissions for the directory. */ res = FileIO_Access(dirName, FILEIO_ACCESS_WRITE); if (FILEIO_SUCCESS != res) { /* * On Linux guests, FileIO_Access sets the proper errno * on failure. On Windows guests, last errno is not * set when FileIO_Access fails. So, we cannot use * FoundryToolsDaemon_TranslateSystemErr() to translate the * error. To maintain consistency for all the guests, * return an explicit VIX_E_FILE_ACCESS_ERROR. */ err = VIX_E_FILE_ACCESS_ERROR; Debug("Unable to get access permissions for the directory: %s\n", dirName); goto abort; } #endif abort: free(baseName); free(dirName); if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); return err; } // VixToolsInitiateFileTransferToGuest /* *----------------------------------------------------------------------------- * * VixToolsListProcesses -- * * * Return value: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsListProcesses(VixCommandRequestHeader *requestMsg, // IN size_t maxBufferSize, // IN char **result) // OUT { VixError err = VIX_OK; int i; static char resultBuffer[GUESTMSG_MAX_IN_SIZE]; ProcMgrProcInfoArray *procList = NULL; ProcMgrProcInfo *procInfo; char *destPtr; char *endDestPtr; char *cmdNamePtr = NULL; char *procBufPtr = NULL; size_t procBufSize; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; Bool escapeStrs; char *escapedName = NULL; char *escapedUser = NULL; char *escapedCmd = NULL; size_t procCount; ASSERT(maxBufferSize <= GUESTMSG_MAX_IN_SIZE); destPtr = resultBuffer; *destPtr = 0; err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; escapeStrs = (requestMsg->requestFlags & VIX_REQUESTMSG_ESCAPE_XML_DATA) != 0; procList = ProcMgr_ListProcesses(); if (NULL == procList) { err = FoundryToolsDaemon_TranslateSystemErr(); goto abort; } endDestPtr = resultBuffer + maxBufferSize; if (escapeStrs) { destPtr += Str_Sprintf(destPtr, endDestPtr - destPtr, "%s", VIX_XML_ESCAPED_TAG); } procCount = ProcMgrProcInfoArray_Count(procList); for (i = 0; i < procCount; i++) { const char *name; const char *user; procInfo = ProcMgrProcInfoArray_AddressOf(procList, i); if (NULL != procInfo->procCmdName) { if (escapeStrs) { escapedCmd = VixToolsEscapeXMLString(procInfo->procCmdName); if (NULL == escapedCmd) { err = VIX_E_OUT_OF_MEMORY; goto abort; } cmdNamePtr = Str_SafeAsprintf(NULL, "%s", escapedCmd); } else { cmdNamePtr = Str_SafeAsprintf(NULL, "%s", procInfo->procCmdName); } } else { cmdNamePtr = Util_SafeStrdup(""); } if (escapeStrs) { name = escapedName = VixToolsEscapeXMLString(procInfo->procCmdLine); if (NULL == escapedName) { err = VIX_E_OUT_OF_MEMORY; goto abort; } } else { name = procInfo->procCmdLine; } if (NULL != procInfo->procOwner) { if (escapeStrs) { user = escapedUser = VixToolsEscapeXMLString(procInfo->procOwner); if (NULL == escapedUser) { err = VIX_E_OUT_OF_MEMORY; goto abort; } } else { user = procInfo->procOwner; } } else { user = ""; } procBufPtr = Str_SafeAsprintf(&procBufSize, "" "%s" // has ... tags if there is cmd, else ""; "%s" "%d" #if defined(_WIN32) "%d" #endif "%s" "%d" "", cmdNamePtr, name, (int) procInfo->procId, #if defined(_WIN32) (int) procInfo->procDebugged, #endif user, (int) procInfo->procStartTime); if (NULL == procBufPtr) { err = VIX_E_OUT_OF_MEMORY; goto abort; } if ((destPtr + procBufSize) < endDestPtr) { destPtr += Str_Sprintf(destPtr, endDestPtr - destPtr, "%s", procBufPtr); } else { // out of space Log("%s: proc list results too large, truncating", __FUNCTION__); goto abort; } free(cmdNamePtr); cmdNamePtr = NULL; free(procBufPtr); procBufPtr = NULL; free(escapedName); escapedName = NULL; free(escapedUser); escapedUser = NULL; free(escapedCmd); escapedCmd = NULL; } abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); ProcMgr_FreeProcList(procList); free(cmdNamePtr); free(procBufPtr); free(escapedName); free(escapedUser); free(escapedCmd); *result = resultBuffer; return(err); } // VixToolsListProcesses /* *----------------------------------------------------------------------------- * * VixToolsFreeCachedResult -- * * Hash table value destroy func. * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ static void VixToolsFreeCachedResult(gpointer ptr) // IN { VixToolsCachedListProcessesResult *p = (VixToolsCachedListProcessesResult *) ptr; if (NULL != p) { free(p->resultBuffer); #ifdef _WIN32 free(p->userName); #endif free(p); } } /* *----------------------------------------------------------------------------- * * VixToolsListProcCacheCleanup -- * * * Return value: * FALSE -- tells glib not to clean up * * Side effects: * None * *----------------------------------------------------------------------------- */ static gboolean VixToolsListProcCacheCleanup(void *clientData) // IN { int key = (int)(intptr_t)clientData; gboolean ret; ret = g_hash_table_remove(listProcessesResultsTable, &key); Debug("%s: list proc cache timed out, purged key %d (found? %d)\n", __FUNCTION__, key, ret); return FALSE; } /* *----------------------------------------------------------------------------- * * VixToolsListProcessesExGenerateData -- * * Does the work to generate the results into a string buffer. * * Return value: * VixError * * Side effects: * Allocates and creates the result buffer. * *----------------------------------------------------------------------------- */ VixError VixToolsListProcessesExGenerateData(uint32 numPids, // IN const uint64 *pids, // IN size_t *resultSize, // OUT char **resultBuffer) // OUT { VixError err = VIX_OK; ProcMgrProcInfoArray *procList = NULL; ProcMgrProcInfo *procInfo; DynBuf dynBuffer; VixToolsExitedProgramState *epList; int i; int j; Bool bRet; size_t procCount; DynBuf_Init(&dynBuffer); /* * XXX optimize -- we should only do this if we can't find * all requested processes on the exitedProcessList, which is * a common case, when a client is watching for a single pid * from StartProgram to exit. */ procList = ProcMgr_ListProcesses(); if (NULL == procList) { err = FoundryToolsDaemon_TranslateSystemErr(); goto abort; } /* * First check the processes we've started via StartProgram, which * will find those running and recently deceased. */ VixToolsUpdateExitedProgramList(NULL); if (numPids > 0) { for (i = 0; i < numPids; i++) { epList = exitedProcessList; while (epList) { if (pids[i] == epList->pid) { err = VixToolsPrintProcInfoEx(&dynBuffer, epList->cmdName, epList->fullCommandLine, epList->pid, epList->user, (int) epList->startTime, epList->exitCode, (int) epList->endTime); if (VIX_OK != err) { goto abort; } break; } epList = epList->next; } } } else { epList = exitedProcessList; while (epList) { err = VixToolsPrintProcInfoEx(&dynBuffer, epList->cmdName, epList->fullCommandLine, epList->pid, epList->user, (int) epList->startTime, epList->exitCode, (int) epList->endTime); if (VIX_OK != err) { goto abort; } epList = epList->next; } } /* * Now look at the running list. Note that we set endTime * and exitCode to dummy values, since we'll be getting results on * the Vix side with GetNthProperty, and can have a mix of live and * dead processes. */ procCount = ProcMgrProcInfoArray_Count(procList); if (numPids > 0) { for (i = 0; i < numPids; i++) { // ignore it if its on the exited list -- we added it above if (VixToolsFindExitedProgramState(pids[i])) { continue; } for (j = 0; j < procCount; j++) { procInfo = ProcMgrProcInfoArray_AddressOf(procList, j); if (pids[i] == procInfo->procId) { err = VixToolsPrintProcInfoEx(&dynBuffer, procInfo->procCmdName, procInfo->procCmdLine, procInfo->procId, (NULL == procInfo->procOwner) ? "" : procInfo->procOwner, (int) procInfo->procStartTime, 0, 0); if (VIX_OK != err) { goto abort; } } } } } else { for (i = 0; i < procCount; i++) { procInfo = ProcMgrProcInfoArray_AddressOf(procList, i); // ignore it if its on the exited list -- we added it above if (VixToolsFindExitedProgramState(procInfo->procId)) { continue; } err = VixToolsPrintProcInfoEx(&dynBuffer, procInfo->procCmdName, procInfo->procCmdLine, procInfo->procId, (NULL == procInfo->procOwner) ? "" : procInfo->procOwner, (int) procInfo->procStartTime, 0, 0); if (VIX_OK != err) { goto abort; } } } // add the final NUL bRet = DynBuf_Append(&dynBuffer, "", 1); if (!bRet) { err = VIX_E_OUT_OF_MEMORY; goto abort; } DynBuf_Trim(&dynBuffer); *resultSize = DynBuf_GetSize(&dynBuffer); *resultBuffer = DynBuf_Detach(&dynBuffer); abort: DynBuf_Destroy(&dynBuffer); ProcMgr_FreeProcList(procList); return err; } /* *----------------------------------------------------------------------------- * * VixToolsListProcessesEx -- * * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsListProcessesEx(VixCommandRequestHeader *requestMsg, // IN size_t maxBufferSize, // IN void *eventQueue, // IN char **result) // OUT { VixError err = VIX_OK; char *fullResultBuffer; char *finalResultBuffer = NULL; size_t fullResultSize = 0; size_t curPacketLen = 0; int32 leftToSend = 0; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; VixMsgListProcessesExRequest *listRequest; uint64 *pids = NULL; uint32 numPids; uint32 key; uint32 offset; int len; VixToolsCachedListProcessesResult *cachedResult = NULL; GSource *timer; #ifdef _WIN32 Bool bRet; wchar_t *userName = NULL; #endif static const char resultHeaderFormatString[] = "%u%d" "%d"; // room for header plus 3 32-bit ints int resultHeaderSize = sizeof(resultHeaderFormatString) + 3 * 10; static const char leftHeaderFormatString[] = "%d"; // room for header plus 1 32-bit ints int leftHeaderSize = sizeof(leftHeaderFormatString) + 10; ASSERT(maxBufferSize <= GUESTMSG_MAX_IN_SIZE); ASSERT(maxBufferSize > resultHeaderSize); listRequest = (VixMsgListProcessesExRequest *) requestMsg; err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; #if defined(__APPLE__) /* * On MacOS, to fetch info on processes owned by others * we need to be root. Even /bin/ps and /bin/top in * MacOS have the setuid bit set to allow any user * list all processes. For linux & FreeBSD, this API * does return info on all processes by all users. So * to keep the result consistent on MacOS, we need to * stop impersonating user for this API. * * NOTE: We still do the impersonation before this * to authenticate the user as usual. */ VixToolsUnimpersonateUser(userToken); impersonatingVMWareUser = FALSE; #endif key = listRequest->key; offset = listRequest->offset; /* * If the request has a key, then go look up the cached results * it should point to. */ if (0 != key) { // find the cached data cachedResult = g_hash_table_lookup(listProcessesResultsTable, &key); if (NULL == cachedResult) { Debug("%s: failed to find cached data with key %d\n", __FUNCTION__, key); err = VIX_E_FAIL; goto abort; } // sanity check offset if (listRequest->offset > cachedResult->resultBufferLen) { /* * Since this isn't user-set, assume any problem is in the * code and return VIX_E_FAIL */ err = VIX_E_FAIL; goto abort; } // security check -- validate user #ifdef _WIN32 bRet = VixToolsGetUserName(&userName); if (!bRet) { Debug("%s: VixToolsGetUserName() failed\n", __FUNCTION__); err = VIX_E_FAIL; goto abort; } if (0 != wcscmp(userName, cachedResult->userName)) { /* * Since this isn't user-set, assume any problem is in the * code and return VIX_E_FAIL */ Debug("%s: username mismatch validating cached data (have %S, want %S)\n", __FUNCTION__, userName, cachedResult->userName); err = VIX_E_FAIL; goto abort; } #else if (cachedResult->euid != Id_GetEUid()) { /* * Since this isn't user-set, assume any problem is in the * code and return VIX_E_FAIL */ err = VIX_E_FAIL; Debug("%s: euid mismatch validating cached data (want %d, got %d)\n", __FUNCTION__, (int) cachedResult->euid, (int) Id_GetEUid()); goto abort; } #endif } else { /* * No key, so this is the initial/only request. Generate data, * cache if necessary. */ numPids = listRequest->numPids; if (numPids > 0) { pids = (uint64 *)((char *)requestMsg + sizeof(*listRequest)); } err = VixToolsListProcessesExGenerateData(numPids, pids, &fullResultSize, &fullResultBuffer); /* * Check if the result is large enough to require more than one trip. * Stuff it in the hash table if so. */ if ((fullResultSize + resultHeaderSize) > maxBufferSize) { Debug("%s: answer requires caching. have %d bytes\n", __FUNCTION__, (int) (fullResultSize + resultHeaderSize)); /* * Save it off in the hashtable. */ key = listProcessesResultsKey++; cachedResult = Util_SafeMalloc(sizeof(*cachedResult)); cachedResult->resultBufferLen = fullResultSize; cachedResult->resultBuffer = fullResultBuffer; cachedResult->key = key; #ifdef _WIN32 bRet = VixToolsGetUserName(&cachedResult->userName); if (!bRet) { Debug("%s: failed to get current userName\n", __FUNCTION__); goto abort; } #else cachedResult->euid = Id_GetEUid(); #endif g_hash_table_replace(listProcessesResultsTable, &cachedResult->key, cachedResult); /* * Set timer callback to clean this up in case the Vix side * never finishes */ timer = g_timeout_source_new(SECONDS_UNTIL_LISTPROC_CACHE_CLEANUP * 1000); g_source_set_callback(timer, VixToolsListProcCacheCleanup, (void *)(intptr_t) key, NULL); g_source_attach(timer, g_main_loop_get_context(eventQueue)); g_source_unref(timer); } } /* * Now package up the return data. */ if (NULL != cachedResult) { int hdrSize; /* * For the first packet, sent the key and total size and leftToSend. * After that, just send leftToSend. */ if (0 == offset) { hdrSize = resultHeaderSize; } else { hdrSize = leftHeaderSize; } leftToSend = cachedResult->resultBufferLen - offset; if (leftToSend > (maxBufferSize - hdrSize)) { curPacketLen = maxBufferSize - hdrSize; } else { curPacketLen = leftToSend; } leftToSend -= curPacketLen; finalResultBuffer = Util_SafeMalloc(curPacketLen + hdrSize + 1); if (0 == offset) { len = Str_Sprintf(finalResultBuffer, maxBufferSize, resultHeaderFormatString, key, (int) cachedResult->resultBufferLen, leftToSend); } else { len = Str_Sprintf(finalResultBuffer, maxBufferSize, leftHeaderFormatString, leftToSend); } memcpy(finalResultBuffer + len, cachedResult->resultBuffer + offset, curPacketLen); finalResultBuffer[curPacketLen + len] = '\0'; /* * All done, clean it out of the hash table. */ if (0 == leftToSend) { g_hash_table_remove(listProcessesResultsTable, &key); } } else { /* * In the simple/common case, just return the basic proces info. */ finalResultBuffer = fullResultBuffer; } abort: #ifdef _WIN32 free(userName); #endif if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); *result = finalResultBuffer; return(err); } // VixToolsListProcessesEx /* *----------------------------------------------------------------------------- * * VixToolsPrintProcInfoEx -- * * Appends a single process entry to the XML-like string starting at * *destPtr. * * Results: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ static VixError VixToolsPrintProcInfoEx(DynBuf *dstBuffer, // IN/OUT const char *cmd, // IN const char *name, // IN uint64 pid, // IN const char *user, // IN int start, // IN int exitCode, // IN int exitTime) // IN { VixError err; char *escapedName = NULL; char *escapedCmd = NULL; char *escapedUser = NULL; char *cmdNamePtr = NULL; size_t bytesPrinted; char *procInfoEntry; Bool success; if (NULL != cmd) { escapedCmd = VixToolsEscapeXMLString(cmd); if (NULL == escapedCmd) { err = VIX_E_OUT_OF_MEMORY; goto abort; } cmdNamePtr = Str_SafeAsprintf(NULL, "%s", escapedCmd); } else { cmdNamePtr = Util_SafeStrdup(""); } escapedName = VixToolsEscapeXMLString(name); if (NULL == escapedName) { err = VIX_E_OUT_OF_MEMORY; goto abort; } escapedUser = VixToolsEscapeXMLString(user); if (NULL == escapedUser) { err = VIX_E_OUT_OF_MEMORY; goto abort; } procInfoEntry = Str_SafeAsprintf(&bytesPrinted, "" "%s" // has ... tags if there is cmd, else ""; "%s" "%"FMT64"d" "%s" "%d" "%d" "%d" "", cmdNamePtr, escapedName, pid, escapedUser, start, exitCode, exitTime); if (NULL == procInfoEntry) { err = VIX_E_OUT_OF_MEMORY; goto abort; } success = DynBuf_Append(dstBuffer, procInfoEntry, bytesPrinted); free(procInfoEntry); if (!success) { err = VIX_E_OUT_OF_MEMORY; goto abort; } err = VIX_OK; abort: free(cmdNamePtr); free(escapedName); free(escapedUser); free(escapedCmd); return err; } /* *----------------------------------------------------------------------------- * * VixToolsKillProcess -- * * * Return value: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsKillProcess(VixCommandRequestHeader *requestMsg) // IN { VixError err = VIX_OK; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; VixCommandKillProcessRequest *killProcessRequest; #ifdef _WIN32 DWORD dwErr; const VixToolsExitedProgramState *exitedState; #else int sysErrno; #endif err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; killProcessRequest = (VixCommandKillProcessRequest *) requestMsg; /* * This is here for two reasons: * 1) If you kill this process, then it cannot report back to * you that the command succeeded. * 2) On Linux, you can either always send a signal to youself, * or it just compares the source and destination real, effective, * and saved UIDs. Anyway, no matter who guestd is impersonating, * this will succeed. However, normally a regular user cannot * kill guestd, and should not be able to because of an implementation * detail. */ if (VixToolsPidRefersToThisProcess(killProcessRequest->pid)) { err = VIX_E_GUEST_USER_PERMISSIONS; goto abort; } if (!ProcMgr_KillByPid(killProcessRequest->pid)) { /* * Save off the error code so any Debug() statements added later * (or when debugging something else) doesn't change the error code. */ #ifdef _WIN32 dwErr = GetLastError(); #else sysErrno = errno; #endif #ifdef _WIN32 /* * If we know it's already gone, just say so. If this gets called * on a process we started but is still on the 'exited' list, * then Windows returns an ACCESS_ERROR. So rewrite it. */ exitedState = VixToolsFindExitedProgramState(killProcessRequest->pid); if ((NULL != exitedState) && !exitedState->isRunning) { err = VIX_E_NO_SUCH_PROCESS; goto abort; } #endif /* * Vix_TranslateSystemError() assumes that any perm error * is file related, and returns VIX_E_FILE_ACCESS_ERROR. Bogus * for this case, so rewrite it here. */ #ifdef _WIN32 if (ERROR_ACCESS_DENIED == dwErr) { err = VIX_E_GUEST_USER_PERMISSIONS; goto abort; } #else if ((EPERM == sysErrno) || (EACCES == sysErrno)) { err = VIX_E_GUEST_USER_PERMISSIONS; goto abort; } #endif #ifdef _WIN32 /* * Windows doesn't give us an obvious error for a non-existent * PID. But we can make a pretty good guess that it returned * ERROR_INVALID_PARAMETER because the PID was bad, so rewrite * that error if we see it. */ if (ERROR_INVALID_PARAMETER == dwErr) { err = VIX_E_NO_SUCH_PROCESS; goto abort; } #endif #ifdef _WIN32 err = Vix_TranslateSystemError(dwErr); #else err = Vix_TranslateSystemError(sysErrno); #endif goto abort; } abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); return err; } // VixToolsKillProcess /* *----------------------------------------------------------------------------- * * VixToolsCreateDirectory -- * * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsCreateDirectory(VixCommandRequestHeader *requestMsg) // IN { VixError err = VIX_OK; const char *dirPathName = NULL; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; Bool createParentDirectories = TRUE; VMAutomationRequestParser parser; int dirPathLen; if (VIX_COMMAND_CREATE_DIRECTORY == requestMsg->opCode) { VixMsgCreateFileRequest *dirRequest = NULL; err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *dirRequest); if (VIX_OK != err) { goto abort; } dirRequest = (VixMsgCreateFileRequest *) requestMsg; dirPathLen = dirRequest->guestPathNameLength; } else if (VIX_COMMAND_CREATE_DIRECTORY_EX == requestMsg->opCode) { VixMsgCreateFileRequestEx *dirRequest = NULL; err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *dirRequest); if (VIX_OK != err) { goto abort; } dirRequest = (VixMsgCreateFileRequestEx *) requestMsg; dirPathLen = dirRequest->guestPathNameLength; createParentDirectories = dirRequest->createParentDirectories; } else { ASSERT(0); Debug("%s: Invalid request with opcode %d received\n ", __FUNCTION__, requestMsg->opCode); err = VIX_E_FAIL; goto abort; } err = VMAutomationRequestParserGetString(&parser, dirPathLen, &dirPathName); if (VIX_OK != err) { goto abort; } if (0 == *dirPathName) { err = VIX_E_INVALID_ARG; goto abort; } err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; if (File_Exists(dirPathName)) { err = VIX_E_FILE_ALREADY_EXISTS; goto abort; } if (createParentDirectories) { if (!(File_CreateDirectoryHierarchyEx(dirPathName, 0700, NULL))) { err = FoundryToolsDaemon_TranslateSystemErr(); goto abort; } } else { if (!(File_CreateDirectoryEx(dirPathName, 0700))) { err = FoundryToolsDaemon_TranslateSystemErr(); goto abort; } } abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); return err; } // VixToolsCreateDirectory /* *----------------------------------------------------------------------------- * * VixToolsListDirectory -- * * * Return value: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsListDirectory(VixCommandRequestHeader *requestMsg, // IN size_t maxBufferSize, // IN char **result) // OUT { VixError err = VIX_OK; const char *dirPathName = NULL; char *fileList = NULL; char **fileNameList = NULL; size_t resultBufferSize = 0; size_t lastGoodResultBufferSize = 0; int numFiles = 0; int lastGoodNumFiles = 0; int fileNum; char *currentFileName; char *destPtr; char *endDestPtr; Bool impersonatingVMWareUser = FALSE; size_t formatStringLength; void *userToken = NULL; VixMsgListDirectoryRequest *listRequest = NULL; VixMsgSimpleFileRequest *legacyListRequest = NULL; Bool truncated = FALSE; int64 offset = 0; Bool isLegacyFormat; VMAutomationRequestParser parser; int dirPathLen; Bool escapeStrs; legacyListRequest = (VixMsgSimpleFileRequest *) requestMsg; if (legacyListRequest->fileOptions & VIX_LIST_DIRECTORY_USE_OFFSET) { /* * Support updated ListDirectory format. */ err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *listRequest); if (VIX_OK != err) { goto abort; } listRequest = (VixMsgListDirectoryRequest *) requestMsg; offset = listRequest->offset; dirPathLen = listRequest->guestPathNameLength; isLegacyFormat = FALSE; } else { /* * Support legacy ListDirectory format. */ err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *legacyListRequest); if (VIX_OK != err) { goto abort; } dirPathLen = legacyListRequest->guestPathNameLength; isLegacyFormat = TRUE; } err = VMAutomationRequestParserGetString(&parser, dirPathLen, &dirPathName); if (VIX_OK != err) { goto abort; } if (0 == *dirPathName) { err = VIX_E_INVALID_ARG; goto abort; } err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; escapeStrs = (requestMsg->requestFlags & VIX_REQUESTMSG_ESCAPE_XML_DATA) != 0; if (!(File_IsDirectory(dirPathName))) { err = VIX_E_NOT_A_DIRECTORY; goto abort; } numFiles = File_ListDirectory(dirPathName, &fileNameList); if (numFiles < 0) { err = FoundryToolsDaemon_TranslateSystemErr(); goto abort; } /* * Calculate the size of the result buffer and keep track of the * max number of entries we can store. */ resultBufferSize = 3; // truncation bool + space + '\0' if (escapeStrs) { resultBufferSize += strlen(VIX_XML_ESCAPED_TAG); } lastGoodResultBufferSize = resultBufferSize; ASSERT_NOT_IMPLEMENTED(lastGoodResultBufferSize < maxBufferSize); formatStringLength = strlen(fileInfoFormatString); for (fileNum = offset; fileNum < numFiles; fileNum++) { currentFileName = fileNameList[fileNum]; resultBufferSize += formatStringLength; resultBufferSize += VixToolsXMLStringEscapedLen(currentFileName, escapeStrs); resultBufferSize += 2; // DIRSEPC chars resultBufferSize += 10 + 20 + 20; // properties + size + modTime if (resultBufferSize < maxBufferSize) { /* * lastGoodNumFiles is a count (1 based), while fileNum is * an array index (zero based). So lastGoodNumFiles is * fileNum + 1. */ lastGoodNumFiles = fileNum + 1; lastGoodResultBufferSize = resultBufferSize; } else { truncated = TRUE; break; } } resultBufferSize = lastGoodResultBufferSize; /* * Print the result buffer. */ fileList = Util_SafeMalloc(resultBufferSize); destPtr = fileList; endDestPtr = fileList + resultBufferSize; /* * Indicate if we have a truncated buffer with "1 ", otherwise "0 ". * This should only happen for non-legacy requests. */ if (!isLegacyFormat) { if ((destPtr + 2) < endDestPtr) { *destPtr++ = truncated ? '1' : '0'; *destPtr++ = ' '; } else { ASSERT(0); err = VIX_E_OUT_OF_MEMORY; goto abort; } } if (escapeStrs) { destPtr += Str_Sprintf(destPtr, endDestPtr - destPtr, "%s", VIX_XML_ESCAPED_TAG); } for (fileNum = offset; fileNum < lastGoodNumFiles; fileNum++) { /* File_ListDirectory never returns "." or ".." */ char *pathName; currentFileName = fileNameList[fileNum]; pathName = Str_SafeAsprintf(NULL, "%s%s%s", dirPathName, DIRSEPS, currentFileName); VixToolsPrintFileInfo(pathName, currentFileName, escapeStrs, &destPtr, endDestPtr); free(pathName); } // for (fileNum = 0; fileNum < lastGoodNumFiles; fileNum++) *destPtr = '\0'; abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); if (NULL == fileList) { fileList = Util_SafeStrdup(""); } *result = fileList; if (NULL != fileNameList) { for (fileNum = 0; fileNum < numFiles; fileNum++) { free(fileNameList[fileNum]); } free(fileNameList); } return err; } // VixToolsListDirectory /* *----------------------------------------------------------------------------- * * VixToolsListFiles -- * * This function is called to implement ListFilesInGuest VI Guest operation. * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsListFiles(VixCommandRequestHeader *requestMsg, // IN size_t maxBufferSize, // IN char **result) // OUT { #if !defined(OPEN_VM_TOOLS) || defined(HAVE_GLIB_REGEX) VixError err = VIX_OK; const char *dirPathName = NULL; char *fileList = NULL; char **fileNameList = NULL; size_t resultBufferSize = 0; size_t lastGoodResultBufferSize = 0; int numFiles = 0; int fileNum; char *currentFileName; char *destPtr; char *endDestPtr; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; VixMsgListFilesRequest *listRequest = NULL; Bool truncated = FALSE; uint64 offset = 0; Bool listingSingleFile = FALSE; const char *pattern = NULL; int index = 0; int maxResults = 0; int count = 0; int remaining = 0; int numResults; GRegex *regex = NULL; GError *gerr = NULL; char *pathName; VMAutomationRequestParser parser; ASSERT(NULL != requestMsg); err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *listRequest); if (VIX_OK != err) { goto abort; } listRequest = (VixMsgListFilesRequest *) requestMsg; offset = listRequest->offset; index = listRequest->index; maxResults = listRequest->maxResults; err = VMAutomationRequestParserGetString(&parser, listRequest->guestPathNameLength, &dirPathName); if (VIX_OK != err) { goto abort; } if (listRequest->patternLength > 0) { err = VMAutomationRequestParserGetString(&parser, listRequest->patternLength, &pattern); if (VIX_OK != err) { goto abort; } Debug("%s: pattern length is %d, value is '%s'\n", __FUNCTION__, listRequest->patternLength, pattern); } if (0 == *dirPathName) { err = VIX_E_INVALID_ARG; goto abort; } err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; Debug("%s: listing files in '%s' with pattern '%s'\n", __FUNCTION__, dirPathName, (NULL != pattern) ? pattern : ""); if (pattern) { regex = g_regex_new(pattern, 0, 0, &gerr); if (!regex) { Debug("%s: bad regex pattern '%s'; failing with INVALID_ARG\n", __FUNCTION__, pattern); err = VIX_E_INVALID_ARG; goto abort; } } /* * First check for symlink -- File_IsDirectory() will lie * if its a symlink to a directory. */ if (!File_IsSymLink(dirPathName) && File_IsDirectory(dirPathName)) { numFiles = File_ListDirectory(dirPathName, &fileNameList); if (numFiles < 0) { err = FoundryToolsDaemon_TranslateSystemErr(); goto abort; } /* * File_ListDirectory() doesn't return '.' and '..', but we want them, * so add '.' and '..' to the list. Place them in front since that's * a more normal location. */ numFiles += 2; { char **newFileNameList = NULL; newFileNameList = Util_SafeMalloc(numFiles * sizeof(char *)); newFileNameList[0] = Unicode_Alloc(".", STRING_ENCODING_UTF8); newFileNameList[1] = Unicode_Alloc("..", STRING_ENCODING_UTF8); memcpy(newFileNameList + 2, fileNameList, (numFiles - 2) * sizeof(char *)); free(fileNameList); fileNameList = newFileNameList; } } else { if (File_Exists(dirPathName)) { listingSingleFile = TRUE; numFiles = 1; fileNameList = Util_SafeMalloc(sizeof(char *)); fileNameList[0] = Util_SafeStrdup(dirPathName); } else { /* * We don't know what they intended to list, but we'll * assume file since that gives a fairly sane error. */ err = VIX_E_FILE_NOT_FOUND; goto abort; } } /* * Calculate the size of the result buffer and keep track of the * max number of entries we can store. Also compute the number * we won't be returning (anything > maxResults). */ resultBufferSize = 3; // truncation bool + space + '\0' // space for the 'remaining' tag up front resultBufferSize += strlen(listFilesRemainingFormatString) + 10; lastGoodResultBufferSize = resultBufferSize; ASSERT_NOT_IMPLEMENTED(lastGoodResultBufferSize < maxBufferSize); for (fileNum = offset + index; fileNum < numFiles; fileNum++) { currentFileName = fileNameList[fileNum]; if (regex) { if (!g_regex_match(regex, currentFileName, 0, NULL)) { continue; } } if (count < maxResults) { count++; } else { remaining++; continue; // stop computing buffersize } if (listingSingleFile) { resultBufferSize += VixToolsGetFileExtendedInfoLength(currentFileName, currentFileName); } else { pathName = Str_SafeAsprintf(NULL, "%s%s%s", dirPathName, DIRSEPS, currentFileName); resultBufferSize += VixToolsGetFileExtendedInfoLength(pathName, currentFileName); free(pathName); } if (resultBufferSize < maxBufferSize) { lastGoodResultBufferSize = resultBufferSize; } else { truncated = TRUE; break; } } resultBufferSize = lastGoodResultBufferSize; numResults = count; /* * Print the result buffer. */ fileList = Util_SafeMalloc(resultBufferSize); destPtr = fileList; endDestPtr = fileList + resultBufferSize; /* * Indicate if we have a truncated buffer with "1 ", otherwise "0 ". * This should only happen for non-legacy requests. */ if ((destPtr + 2) < endDestPtr) { *destPtr++ = truncated ? '1' : '0'; *destPtr++ = ' '; } else { ASSERT(0); err = VIX_E_OUT_OF_MEMORY; goto abort; } destPtr += Str_Sprintf(destPtr, endDestPtr - destPtr, listFilesRemainingFormatString, remaining); for (fileNum = offset + index, count = 0; count < numResults; fileNum++) { currentFileName = fileNameList[fileNum]; if (regex) { if (!g_regex_match(regex, currentFileName, 0, NULL)) { continue; } } if (listingSingleFile) { pathName = Util_SafeStrdup(currentFileName); } else { pathName = Str_SafeAsprintf(NULL, "%s%s%s", dirPathName, DIRSEPS, currentFileName); } VixToolsPrintFileExtendedInfo(pathName, currentFileName, &destPtr, endDestPtr); free(pathName); count++; } // for (fileNum = 0; fileNum < lastGoodNumFiles; fileNum++) *destPtr = '\0'; abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); if (NULL == fileList) { fileList = Util_SafeStrdup(""); } *result = fileList; if (NULL != fileNameList) { for (fileNum = 0; fileNum < numFiles; fileNum++) { free(fileNameList[fileNum]); } free(fileNameList); } return err; #else return VIX_E_NOT_SUPPORTED; #endif } // VixToolsListFiles /* *----------------------------------------------------------------------------- * * VixToolsGetFileExtendedInfoLength -- * * This function calculates the total number of bytes required to hold * the extended info about the specified file. * * Return value: * Size of extended info buffer. * * Side effects: * None * *----------------------------------------------------------------------------- */ int VixToolsGetFileExtendedInfoLength(const char *filePathName, // IN const char *fileName) // IN { int fileExtendedInfoBufferSize = 0; ASSERT(NULL != filePathName); ASSERT(NULL != fileName); #ifdef _WIN32 fileExtendedInfoBufferSize = strlen(fileExtendedInfoWindowsFormatString); #else fileExtendedInfoBufferSize = strlen(fileExtendedInfoLinuxFormatString); #endif fileExtendedInfoBufferSize += 2; // DIRSEPC chars fileExtendedInfoBufferSize += 10 + 20 + (20 * 2); // properties + size + times #ifdef _WIN32 fileExtendedInfoBufferSize += 20; // createTime #else fileExtendedInfoBufferSize += 10 * 3; // uid, gid, perms #endif #if defined(linux) || defined(sun) || defined(__FreeBSD__) if (File_IsSymLink(filePathName)) { char *symlinkTarget; symlinkTarget = Posix_ReadLink(filePathName); if (NULL != symlinkTarget) { fileExtendedInfoBufferSize += VixToolsXMLStringEscapedLen(symlinkTarget, TRUE); } free(symlinkTarget); } #endif fileExtendedInfoBufferSize += VixToolsXMLStringEscapedLen(fileName, TRUE); return fileExtendedInfoBufferSize; } /* *----------------------------------------------------------------------------- * * VixToolsGetFileInfo -- * * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsGetFileInfo(VixCommandRequestHeader *requestMsg, // IN char **result) // OUT { VixError err = VIX_OK; char *resultBuffer = NULL; size_t resultBufferSize = 0; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; char *destPtr; const char *filePathName; VixMsgSimpleFileRequest *simpleFileReq; VMAutomationRequestParser parser; err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *simpleFileReq); if (VIX_OK != err) { goto abort; } simpleFileReq = (VixMsgSimpleFileRequest *)requestMsg; err = VMAutomationRequestParserGetString(&parser, simpleFileReq->guestPathNameLength, &filePathName); if (VIX_OK != err) { goto abort; } if (0 == *filePathName) { err = VIX_E_INVALID_ARG; goto abort; } err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; if (!(File_Exists(filePathName))) { err = VIX_E_FILE_NOT_FOUND; goto abort; } /* * Calculate the size of the result buffer. */ resultBufferSize = strlen(fileInfoFormatString) + 1 // strlen("") + 20 + 20 + 10; // space for the modTime, size and flags. resultBuffer = Util_SafeMalloc(resultBufferSize); /* * Print the result buffer */ destPtr = resultBuffer; VixToolsPrintFileInfo(filePathName, "", FALSE, &destPtr, resultBuffer + resultBufferSize); abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); if (NULL == resultBuffer) { resultBuffer = Util_SafeStrdup(""); } *result = resultBuffer; return err; } // VixToolsGetFileInfo /* *----------------------------------------------------------------------------- * * VixToolsSetFileAttributes -- * * Set the file attributes for a specified file. * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsSetFileAttributes(VixCommandRequestHeader *requestMsg) // IN { VixError err = VIX_OK; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; const char *filePathName = NULL; VixMsgSetGuestFileAttributesRequest *setGuestFileAttributesRequest = NULL; struct timespec timeBuf; Bool success = FALSE; int64 createTime; int64 accessTime; int64 modificationTime; VMAutomationRequestParser parser; int64 tempTime; Bool timeAttributeSpecified = FALSE; Bool windowsAttributeSpecified = FALSE; int32 fileAttributeOptions = 0; #ifdef _WIN32 DWORD fileAttr = 0; #else int ownerId = 0; int groupId = 0; struct stat statbuf; #endif ASSERT(NULL != requestMsg); /* * Parse the argument */ err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *setGuestFileAttributesRequest); if (VIX_OK != err) { goto abort; } setGuestFileAttributesRequest = (VixMsgSetGuestFileAttributesRequest *) requestMsg; err = VMAutomationRequestParserGetString(&parser, setGuestFileAttributesRequest->guestPathNameLength, &filePathName); if (VIX_OK != err) { goto abort; } if ('\0' == *filePathName) { err = VIX_E_INVALID_ARG; goto abort; } fileAttributeOptions = setGuestFileAttributesRequest->fileOptions; if ((fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_HIDDEN) || (fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_READONLY)) { windowsAttributeSpecified = TRUE; } if ((fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_ACCESS_DATE) || (fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_MODIFY_DATE)) { timeAttributeSpecified = TRUE; } #if defined(_WIN32) if ((fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_UNIX_OWNERID) || (fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_UNIX_GROUPID) || (fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_UNIX_PERMISSIONS)) { Debug("%s: Invalid attributes received for Windows Guest\n", __FUNCTION__); err = VIX_E_INVALID_ARG; goto abort; } #else if (windowsAttributeSpecified) { Debug("%s: Invalid attributes received for Posix Guest\n", __FUNCTION__); err = VIX_E_INVALID_ARG; goto abort; } #endif err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; if (!(File_Exists(filePathName))) { err = FoundryToolsDaemon_TranslateSystemErr(); goto abort; } if (timeAttributeSpecified) { success = File_GetTimes(filePathName, &createTime, &accessTime, &modificationTime, &tempTime); if (!success) { Debug("%s: Failed to get the times.\n", __FUNCTION__); err = FoundryToolsDaemon_TranslateSystemErr(); goto abort; } /* * User specifies the time in Unix Time Format. File_SetTimes() * accepts times in Windows NT Format. We should convert the time * from Unix Format to Windows NT Format. */ if (fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_ACCESS_DATE ) { timeBuf.tv_sec = setGuestFileAttributesRequest->accessTime; timeBuf.tv_nsec = 0; accessTime = TimeUtil_UnixTimeToNtTime(timeBuf); } if (fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_MODIFY_DATE) { timeBuf.tv_sec = setGuestFileAttributesRequest->modificationTime; timeBuf.tv_nsec = 0; modificationTime = TimeUtil_UnixTimeToNtTime(timeBuf); } success = File_SetTimes(filePathName, createTime, accessTime, modificationTime, modificationTime); if (!success) { Debug("%s: Failed to set the times.\n", __FUNCTION__); err = FoundryToolsDaemon_TranslateSystemErr(); goto abort; } } #if defined(_WIN32) if (windowsAttributeSpecified) { fileAttr = Win32U_GetFileAttributes(filePathName); if (fileAttr != INVALID_FILE_ATTRIBUTES) { if (fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_HIDDEN) { if (setGuestFileAttributesRequest->hidden) { fileAttr |= FILE_ATTRIBUTE_HIDDEN; } else { fileAttr &= (~FILE_ATTRIBUTE_HIDDEN); } } if (fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_READONLY) { if (setGuestFileAttributesRequest->readOnly) { fileAttr |= FILE_ATTRIBUTE_READONLY; } else { fileAttr &= (~FILE_ATTRIBUTE_READONLY); } } if (!Win32U_SetFileAttributes(filePathName, fileAttr)) { err = FoundryToolsDaemon_TranslateSystemErr(); Debug("%s: Failed to set the file attributes\n", __FUNCTION__); goto abort; } } else { err = FoundryToolsDaemon_TranslateSystemErr(); Debug("%s: Failed to get the file attributes\n", __FUNCTION__); goto abort; } } #else if (fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_UNIX_PERMISSIONS) { success = File_SetFilePermissions(filePathName, setGuestFileAttributesRequest->permissions); if (!success) { err = FoundryToolsDaemon_TranslateSystemErr(); Debug("%s: Failed to set the file permissions\n", __FUNCTION__); goto abort; } } if ((fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_UNIX_OWNERID) || (fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_UNIX_GROUPID)) { if (-1 != Posix_Stat(filePathName, &statbuf)) { ownerId = statbuf.st_uid; groupId = statbuf.st_gid; } else { err = FoundryToolsDaemon_TranslateSystemErr(); Debug("%s: Posix_Stat(%s) failed with %d\n", __FUNCTION__, filePathName, errno); goto abort; } if (fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_UNIX_OWNERID) { ownerId = setGuestFileAttributesRequest->ownerId; } if (fileAttributeOptions & VIX_FILE_ATTRIBUTE_SET_UNIX_GROUPID) { groupId = setGuestFileAttributesRequest->groupId; } if (Posix_Chown(filePathName, ownerId, groupId)) { err = FoundryToolsDaemon_TranslateSystemErr(); Debug("%s: Failed to set the owner/group Id\n", __FUNCTION__); goto abort; } } #endif abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); return err; } // VixToolsSetGuestFileAttributes /* *----------------------------------------------------------------------------- * * VixToolsPrintFileInfo -- * * This does not retrieve some of the more interesting properties, like * read-only, owner name, and permissions. I'll add those later. * * This also does not yet provide UTF-8 versions of some of the File_ functions, * so that may create problems on international guests. * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ static void VixToolsPrintFileInfo(const char *filePathName, // IN char *fileName, // IN Bool escapeStrs, // IN char **destPtr, // IN/OUT char *endDestPtr) // IN { int64 fileSize = 0; int64 modTime; int32 fileProperties = 0; char *escapedFileName = NULL; modTime = File_GetModTime(filePathName); if (File_IsDirectory(filePathName)) { fileProperties |= VIX_FILE_ATTRIBUTES_DIRECTORY; } else { if (File_IsSymLink(filePathName)) { fileProperties |= VIX_FILE_ATTRIBUTES_SYMLINK; } if (File_IsFile(filePathName)) { fileSize = File_GetSize(filePathName); } } if (escapeStrs) { fileName = escapedFileName = VixToolsEscapeXMLString(fileName); ASSERT_MEM_ALLOC(NULL != escapedFileName); } *destPtr += Str_Sprintf(*destPtr, endDestPtr - *destPtr, fileInfoFormatString, fileName, fileProperties, fileSize, modTime); free(escapedFileName); } // VixToolsPrintFileInfo /* *----------------------------------------------------------------------------- * * VixToolsPrintFileExtendedInfo -- * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ static void VixToolsPrintFileExtendedInfo(const char *filePathName, // IN const char *fileName, // IN char **destPtr, // IN/OUT char *endDestPtr) // IN { int64 fileSize = 0; VmTimeType modTime = 0; VmTimeType accessTime = 0; int32 fileProperties = 0; #ifdef _WIN32 DWORD fileAttr = 0; Bool hidden = FALSE; Bool readOnly = FALSE; VmTimeType createTime = 0; #else int permissions = 0; int ownerId = 0; int groupId = 0; char *symlinkTarget = NULL; char *tmp; #endif struct stat statbuf; char *escapedFileName = NULL; /* * First check for symlink -- File_IsDirectory() will lie * if its a symlink to a directory. */ if (File_IsSymLink(filePathName)) { fileProperties |= VIX_FILE_ATTRIBUTES_SYMLINK; } else if (File_IsDirectory(filePathName)) { fileProperties |= VIX_FILE_ATTRIBUTES_DIRECTORY; } else if (File_IsFile(filePathName)) { fileSize = File_GetSize(filePathName); } #if !defined(_WIN32) /* * If the file is a symlink, figure out where it points. */ if (fileProperties & VIX_FILE_ATTRIBUTES_SYMLINK) { symlinkTarget = Posix_ReadLink(filePathName); } /* * Have a nice empty value if it's not a link or there's some error * reading the link. */ if (NULL == symlinkTarget) { symlinkTarget = Util_SafeStrdup(""); } tmp = VixToolsEscapeXMLString(symlinkTarget); ASSERT_MEM_ALLOC(NULL != tmp); free(symlinkTarget); symlinkTarget = tmp; #endif #ifdef _WIN32 fileAttr = Win32U_GetFileAttributes(filePathName); if (fileAttr != INVALID_FILE_ATTRIBUTES) { if (fileAttr & FILE_ATTRIBUTE_HIDDEN) { fileProperties |= VIX_FILE_ATTRIBUTES_HIDDEN; } if (fileAttr & FILE_ATTRIBUTE_READONLY) { fileProperties |= VIX_FILE_ATTRIBUTES_READONLY; } } #endif if (Posix_Stat(filePathName, &statbuf) != -1) { #if !defined(_WIN32) ownerId = statbuf.st_uid; groupId = statbuf.st_gid; permissions = statbuf.st_mode; #endif /* * We want create time. ctime is the inode change time for Linux, * so we can't report anything. */ #ifdef _WIN32 createTime = statbuf.st_ctime; #endif modTime = statbuf.st_mtime; accessTime = statbuf.st_atime; } else { Debug("%s: Posix_Stat(%s) failed with %d\n", __FUNCTION__, filePathName, errno); } escapedFileName = VixToolsEscapeXMLString(fileName); ASSERT_MEM_ALLOC(NULL != escapedFileName); #ifdef _WIN32 *destPtr += Str_Sprintf(*destPtr, endDestPtr - *destPtr, fileExtendedInfoWindowsFormatString, escapedFileName, fileProperties, fileSize, modTime, createTime, accessTime, hidden, readOnly); #else *destPtr += Str_Sprintf(*destPtr, endDestPtr - *destPtr, fileExtendedInfoLinuxFormatString, escapedFileName, fileProperties, fileSize, modTime, accessTime, ownerId, groupId, permissions, symlinkTarget); free(symlinkTarget); #endif free(escapedFileName); } // VixToolsPrintFileExtendedInfo /* *----------------------------------------------------------------------------- * * VixToolsPrintFileExtendedInfoEx -- * * Given a specified file, this function returns a properly XML * formatted string representing the extended information of the file. * * Return value: * char * - Dynamically allocated string that holds the extended info * about the specified file. It is the responsibility of the caller * to free the memory. * * Side effects: * None * *----------------------------------------------------------------------------- */ static char * VixToolsPrintFileExtendedInfoEx(const char *filePathName, // IN const char *fileName) // IN { int resultBufferSize; char *destPtr = NULL; char *endDestPtr = NULL; char *resultBuffer = NULL; resultBufferSize = VixToolsGetFileExtendedInfoLength(filePathName, fileName); resultBuffer = Util_SafeMalloc(resultBufferSize); destPtr = resultBuffer; endDestPtr = resultBuffer + resultBufferSize; VixToolsPrintFileExtendedInfo(filePathName, filePathName, &destPtr, endDestPtr); *destPtr = '\0'; return resultBuffer; } /* *----------------------------------------------------------------------------- * * VixToolsCheckUserAccount -- * * * Return value: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsCheckUserAccount(VixCommandRequestHeader *requestMsg) // IN { VixError err = VIX_OK; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); return err; } // VixToolsCheckUserAccount /* *----------------------------------------------------------------------------- * * VixToolsRunScript -- * * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsRunScript(VixCommandRequestHeader *requestMsg, // IN char *requestName, // IN void *eventQueue, // IN char **result) // OUT { VixError err = VIX_OK; const char *propertiesString = NULL; const char *script = NULL; const char *interpreterName = NULL; char *fileSuffix = ""; Bool impersonatingVMWareUser = FALSE; VixToolsRunProgramState *asyncState = NULL; void *userToken = NULL; char *tempDirPath = NULL; char *tempScriptFilePath = NULL; char *fullCommandLine = NULL; int var; int fd = -1; int writeResult; Bool programExists; Bool programIsExecutable; int64 pid = (int64) -1; static char resultBuffer[32]; VixMsgRunScriptRequest *scriptRequest; const char *interpreterFlags = ""; ProcMgr_ProcArgs procArgs; #if defined(_WIN32) Bool forcedRoot = FALSE; wchar_t *envBlock = NULL; #endif GSource *timer; VMAutomationRequestParser parser; err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *scriptRequest); if (VIX_OK != err) { goto abort; } scriptRequest = (VixMsgRunScriptRequest *) requestMsg; err = VMAutomationRequestParserGetString(&parser, scriptRequest->interpreterNameLength, &interpreterName); if (VIX_OK != err) { goto abort; } err = VMAutomationRequestParserGetString(&parser, scriptRequest->propertiesLength, &propertiesString); if (VIX_OK != err) { goto abort; } err = VMAutomationRequestParserGetString(&parser, scriptRequest->scriptLength, &script); if (VIX_OK != err) { goto abort; } err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; if (0 == *interpreterName) { #ifdef _WIN32 //interpreterName = "cmd.exe"; fileSuffix = ".bat"; #else interpreterName = "/bin/sh"; #endif } if (*interpreterName) { programExists = File_Exists(interpreterName); /* * TODO: replace FileIO_Access with something more UTF8/forward- * thinking. */ programIsExecutable = (FileIO_Access(interpreterName, FILEIO_ACCESS_EXEC) == FILEIO_SUCCESS); if (!programExists) { err = VIX_E_FILE_NOT_FOUND; goto abort; } if (!programIsExecutable) { err = VIX_E_GUEST_USER_PERMISSIONS; goto abort; } } /* * Create a temporary file that we can run as a script. * TODO: Plumb a file suffix/extention throught to the File * module's code, so that we can avoid duplicating this code. */ #ifdef _WIN32 if (PROCESS_CREATOR_USER_TOKEN != userToken) { err = VixToolsGetUserTmpDir(userToken, &tempDirPath); /* * Don't give up if VixToolsGetUserTmpDir() failed. It might just * have failed to load DLLs, so we might be running on Win 9x. * Just fall through to use the old fashioned File_GetSafeTmpDir(). */ err = VIX_OK; } #endif if (NULL == tempDirPath) { tempDirPath = File_GetSafeTmpDir(TRUE); if (NULL == tempDirPath) { err = FoundryToolsDaemon_TranslateSystemErr(); goto abort; } } for (var = 0; var <= 0xFFFFFFFF; var++) { free(tempScriptFilePath); tempScriptFilePath = Str_SafeAsprintf(NULL, "%s"DIRSEPS"%s%d%s", tempDirPath, scriptFileBaseName, var, fileSuffix); if (NULL == tempScriptFilePath) { err = VIX_E_OUT_OF_MEMORY; goto abort; } fd = Posix_Open(tempScriptFilePath, // UTF-8 O_CREAT | O_EXCL #if defined(_WIN32) | O_BINARY #endif #if defined(linux) && defined(GLIBC_VERSION_21) | O_LARGEFILE #endif | O_RDWR, 0600); if (fd >= 0) { break; } #if defined(_WIN32) if ((errno == EACCES) && (File_Exists(tempScriptFilePath))) { /* * On windows, Posix_Open() fails with EACCES if there is any * permissions check failure while creating the file. Also, EACCES is * returned if a directory already exists with the same name. In such * case, we need to check if a file already exists and ignore * EACCES error. */ continue; } #endif if (errno != EEXIST) { /* * While persistence is generally a worthwhile trail, if something * happens to the temp directory while we're using it (e.g., someone * deletes it), we should not try 4+ billion times. */ break; } } if (fd < 0) { /* * We use Posix variant function i.e. Posix_Open to create a * temporary file. If Posix_Open() fails, then proper error is * stuffed in errno variable. So, use Vix_TranslateErrno() * to translate the errno to a proper foundry error. */ err = Vix_TranslateErrno(errno); Debug("Unable to create a temporary file, errno is %d.\n", errno); goto abort; } #if defined(_WIN32) writeResult = _write(fd, script, (unsigned int)strlen(script)); #else writeResult = write(fd, script, strlen(script)); #endif if (writeResult < 0) { /* * Yes, I'm duplicating code by running this check before the call to * close(), but if close() succeeds it will clobber the errno, causing * something confusing to be reported to the user. */ err = Vix_TranslateErrno(errno); Debug("Unable to write the script to the temporary file, errno is %d.\n", errno); if (close(fd) < 0) { Debug("Unable to close a file, errno is %d\n", errno); } goto abort; } if (close(fd) < 0) { /* * If close() fails, we don't want to try to run the script. According to * the man page: * "Not checking the return value of close is a common but nevertheless * serious programming error. It is quite possible that errors on a * previous write(2) operation are first reported at the final close. Not * checking the return value when closing the file may lead to silent loss * of data. This can especially be observed with NFS and disk quotas." */ err = Vix_TranslateErrno(errno); Debug("Unable to close a file, errno is %d\n", errno); goto abort; } if ((NULL != interpreterName) && (*interpreterName)) { fullCommandLine = Str_SafeAsprintf(NULL, // resulting string length "\"%s\" %s \"%s\"", interpreterName, interpreterFlags, tempScriptFilePath); } else { fullCommandLine = Str_SafeAsprintf(NULL, // resulting string length "\"%s\"", tempScriptFilePath); } if (NULL == fullCommandLine) { err = VIX_E_OUT_OF_MEMORY; goto abort; } /* * Save some strings in the state. */ asyncState = Util_SafeCalloc(1, sizeof *asyncState); asyncState->tempScriptFilePath = tempScriptFilePath; tempScriptFilePath = NULL; asyncState->requestName = Util_SafeStrdup(requestName); asyncState->runProgramOptions = scriptRequest->scriptOptions; memset(&procArgs, 0, sizeof procArgs); #if defined(_WIN32) if (PROCESS_CREATOR_USER_TOKEN != userToken) { /* * If we are impersonating a user then use the user's environment * block. That way the user-specific environment variables will * be available to the application (such as the user's TEMP * directory instead of the system-wide one). */ err = VixToolsGetEnvBlock(userToken, &envBlock); if (VIX_OK != err) { goto abort; } forcedRoot = Impersonate_ForceRoot(); } procArgs.hToken = (PROCESS_CREATOR_USER_TOKEN == userToken) ? NULL : userToken; procArgs.bInheritHandles = TRUE; procArgs.dwCreationFlags = CREATE_UNICODE_ENVIRONMENT; procArgs.lpEnvironment = envBlock; #else procArgs.envp = VixToolsEnvironmentTableToEnvp(userEnvironmentTable); #endif asyncState->procState = ProcMgr_ExecAsync(fullCommandLine, &procArgs); #if defined(_WIN32) if (forcedRoot) { Impersonate_UnforceRoot(); } #else VixToolsFreeEnvp(procArgs.envp); DEBUG_ONLY(procArgs.envp = NULL;) #endif if (NULL == asyncState->procState) { err = VIX_E_PROGRAM_NOT_STARTED; goto abort; } pid = (int64) ProcMgr_GetPid(asyncState->procState); asyncState->eventQueue = eventQueue; timer = g_timeout_source_new(SECONDS_BETWEEN_POLL_TEST_FINISHED * 1000); g_source_set_callback(timer, VixToolsMonitorAsyncProc, asyncState, NULL); g_source_attach(timer, g_main_loop_get_context(eventQueue)); g_source_unref(timer); /* * VixToolsMonitorAsyncProc will clean asyncState up when the program finishes. */ asyncState = NULL; abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); if (VIX_FAILED(err)) { VixToolsFreeRunProgramState(asyncState); } #ifdef _WIN32 if (NULL != envBlock) { VixToolsDestroyEnvironmentBlock(envBlock); } #endif free(fullCommandLine); free(tempDirPath); free(tempScriptFilePath); Str_Sprintf(resultBuffer, sizeof(resultBuffer), "%"FMT64"d", pid); *result = resultBuffer; return err; } // VixToolsRunScript /* *----------------------------------------------------------------------------- * * VixToolsImpersonateUser -- * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsImpersonateUser(VixCommandRequestHeader *requestMsg, // IN void **userToken) // OUT { VixError err = VIX_OK; char *credentialField; int credentialType; Debug(">%s\n", __FUNCTION__); credentialField = ((char *) requestMsg) + requestMsg->commonHeader.headerLength + requestMsg->commonHeader.bodyLength; credentialType = requestMsg->userCredentialType; switch (credentialType) { case VIX_USER_CREDENTIAL_TICKETED_SESSION: { VixCommandTicketedSession *commandTicketedSession = (VixCommandTicketedSession *) credentialField; size_t ticketLength = commandTicketedSession->ticketLength; credentialField += sizeof(VixCommandTicketedSession); if (ticketLength != strlen(credentialField)) { Debug("%s: Ticket Length Does Not Match Expected\n", __FUNCTION__); return VIX_E_INVALID_MESSAGE_BODY; } err = VixToolsImpersonateUserImplEx(NULL, credentialType, credentialField, userToken); break; } case VIX_USER_CREDENTIAL_ROOT: case VIX_USER_CREDENTIAL_CONSOLE_USER: err = VixToolsImpersonateUserImplEx(NULL, credentialType, NULL, userToken); break; case VIX_USER_CREDENTIAL_NAME_PASSWORD: case VIX_USER_CREDENTIAL_NAME_PASSWORD_OBFUSCATED: case VIX_USER_CREDENTIAL_NAMED_INTERACTIVE_USER: { VixCommandNamePassword *namePasswordStruct = (VixCommandNamePassword *) credentialField; credentialField += sizeof(*namePasswordStruct); err = VixToolsImpersonateUserImplEx(NULL, credentialType, credentialField, userToken); if ((VIX_OK != err) && ((VIX_USER_CREDENTIAL_NAME_PASSWORD_OBFUSCATED == credentialType) || (VIX_USER_CREDENTIAL_NAME_PASSWORD == credentialType))) { /* * Windows does not allow you to login with an empty password. Only * the console allows this login, which means the console does not * call the simple public LogonUser api. * * See the description for ERROR_ACCOUNT_RESTRICTION. * For example, the error codes are described here: * http://support.microsoft.com/kb/155012 */ #ifdef _WIN32 if (namePasswordStruct->passwordLength <= 0) { err = VIX_E_EMPTY_PASSWORD_NOT_ALLOWED_IN_GUEST; } #endif } break; } case VIX_USER_CREDENTIAL_SAML_BEARER_TOKEN: { VixCommandSAMLToken *samlStruct = (VixCommandSAMLToken *) credentialField; credentialField += sizeof(*samlStruct); err = VixToolsImpersonateUserImplEx(NULL, credentialType, credentialField, userToken); break; } case VIX_USER_CREDENTIAL_SSPI: /* * SSPI currently only supported in ticketed sessions */ default: Debug("%s: credentialType = %d\n", __FUNCTION__, credentialType); err = VIX_E_NOT_SUPPORTED; } Debug("<%s\n", __FUNCTION__); return(err); } // VixToolsImpersonateUser /* *----------------------------------------------------------------------------- * * VixToolsImpersonateUserImpl -- * * Little compatability wrapper for legacy Foundry Tools implementations. * * Return value: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool VixToolsImpersonateUserImpl(char const *credentialTypeStr, // IN int credentialType, // IN char const *obfuscatedNamePassword, // IN void **userToken) // OUT { return(VIX_OK == VixToolsImpersonateUserImplEx(credentialTypeStr, credentialType, obfuscatedNamePassword, userToken)); } // VixToolsImpersonateUserImpl /* *----------------------------------------------------------------------------- * * VixToolsImpersonateUserImplEx -- * * On Windows: * To retrieve the security context of another user * call LogonUser to log the user whom you want to impersonate on to the * local computer, specifying the name of the user account, the user's * domain, and the user's password. This function returns a pointer to * a handle to the access token of the logged-on user as an out parameter. * Call ImpersonateLoggedOnUser using the handle to the access token obtained * in the call to LogonUser. * Run RegEdt32 to load the registry hive of the impersonated user manually. * * Return value: * VIX_OK on success, or an appropriate error code on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsImpersonateUserImplEx(char const *credentialTypeStr, // IN int credentialType, // IN char const *obfuscatedNamePassword, // IN void **userToken) // OUT { VixError err = VIX_E_INVALID_LOGIN_CREDENTIALS; if (NULL == userToken) { Debug("%s: Invalid userToken pointer\n", __FUNCTION__); return VIX_E_FAIL; } *userToken = NULL; /////////////////////////////////////////////////////////////////////// // NOTE: The following lines need to be uncommented to disable either // FreeBSD and/or MacOS support for VMODL Guest Operations completely. //#if defined(__FreeBSD__) // return VIX_E_NOT_SUPPORTED; //#endif //#if defined(__APPLE__) // return VIX_E_NOT_SUPPORTED; //#endif /////////////////////////////////////////////////////////////////////// { AuthToken authToken; char *unobfuscatedUserName = NULL; char *unobfuscatedPassword = NULL; Bool success = FALSE; if (NULL != credentialTypeStr) { if (!StrUtil_StrToInt(&credentialType, credentialTypeStr)) { /* * This is an internal error, since the VMX supplies this string. */ err = VIX_E_FAIL; goto abort; } } /* * If the VMX asks to be root, then we allow them. * The VMX will make sure that only it will pass this value in, * and only when the VM and host are configured to allow this. */ if ((VIX_USER_CREDENTIAL_ROOT == credentialType) && (thisProcessRunsAsRoot)) { *userToken = PROCESS_CREATOR_USER_TOKEN; err = VIX_OK; goto abort; } /* * If the VMX asks to be root, then we allow them. * The VMX will make sure that only it will pass this value in, * and only when the VM and host are configured to allow this. */ if ((VIX_USER_CREDENTIAL_CONSOLE_USER == credentialType) && ((allowConsoleUserOps) || !(thisProcessRunsAsRoot))) { *userToken = PROCESS_CREATOR_USER_TOKEN; err = VIX_OK; goto abort; } /* * If the VMX asks us to run commands in the context of the current * user, make sure that the user who requested the command is the * same as the current user. * We don't need to make sure the password is valid (in fact we should * not receive one) because the VMX should have validated the * password by other means. Currently it sends it to the Tools daemon. */ if (VIX_USER_CREDENTIAL_NAMED_INTERACTIVE_USER == credentialType) { if (!thisProcessRunsAsRoot) { err = VixMsg_DeObfuscateNamePassword(obfuscatedNamePassword, &unobfuscatedUserName, &unobfuscatedPassword); if (err != VIX_OK) { goto abort; } /* * Make sure that the user who requested the command is the * current user. */ err = VixToolsDoesUsernameMatchCurrentUser(unobfuscatedUserName); if (VIX_OK != err) { goto abort; } *userToken = PROCESS_CREATOR_USER_TOKEN; goto abort; } else { /* * This should only be sent to vmware-user, not guestd. * Something is wrong. */ ASSERT(0); err = VIX_E_FAIL; goto abort; } } /* * Other credential types, like guest, are all turned into a name/password * by the VMX. If this is something else, then we are talking to a newer * version of the VMX. */ if ((VIX_USER_CREDENTIAL_NAME_PASSWORD != credentialType) && (VIX_USER_CREDENTIAL_NAME_PASSWORD_OBFUSCATED != credentialType) && (VIX_USER_CREDENTIAL_TICKETED_SESSION != credentialType) #if SUPPORT_VGAUTH && (VIX_USER_CREDENTIAL_SAML_BEARER_TOKEN != credentialType) #endif ) { err = VIX_E_NOT_SUPPORTED; goto abort; } /* * Use the GuestAuth library to do name-password authentication * and impersonation. */ if (GuestAuthEnabled() && ((VIX_USER_CREDENTIAL_NAME_PASSWORD == credentialType) || (VIX_USER_CREDENTIAL_NAME_PASSWORD_OBFUSCATED == credentialType))) { err = GuestAuthPasswordAuthenticateImpersonate(obfuscatedNamePassword, userToken); goto abort; } if (VIX_USER_CREDENTIAL_SAML_BEARER_TOKEN == credentialType) { if (GuestAuthEnabled()) { err = GuestAuthSAMLAuthenticateAndImpersonate(obfuscatedNamePassword, userToken); } else { err = VIX_E_NOT_SUPPORTED; } goto abort; } /* Get the authToken and impersonate */ if (VIX_USER_CREDENTIAL_TICKETED_SESSION == credentialType) { #ifdef _WIN32 char *username; err = VixToolsGetTokenHandleFromTicketID(obfuscatedNamePassword, &username, &authToken); if (VIX_OK != err) { goto abort; } unobfuscatedUserName = Util_SafeStrdup(username); *userToken = (void *) authToken; #else err = VIX_E_NOT_SUPPORTED; goto abort; #endif } else { err = VixMsg_DeObfuscateNamePassword(obfuscatedNamePassword, &unobfuscatedUserName, &unobfuscatedPassword); if (err != VIX_OK) { goto abort; } authToken = Auth_AuthenticateUser(unobfuscatedUserName, unobfuscatedPassword); if (NULL == authToken) { err = VIX_E_INVALID_LOGIN_CREDENTIALS; goto abort; } *userToken = (void *) authToken; } #ifdef _WIN32 success = Impersonate_Do(unobfuscatedUserName, authToken); #else /* * Use a tools-special version of user impersonation, since * lib/impersonate model isn't quite what we want on linux. */ success = ProcMgr_ImpersonateUserStart(unobfuscatedUserName, authToken); #endif if (!success) { err = VIX_E_INVALID_LOGIN_CREDENTIALS; goto abort; } err = VIX_OK; abort: free(unobfuscatedUserName); Util_ZeroFreeString(unobfuscatedPassword); } return err; } // VixToolsImpersonateUserImplEx /* *----------------------------------------------------------------------------- * * VixToolsUnimpersonateUser -- * * * Return value: * * Side effects: * None * *----------------------------------------------------------------------------- */ void VixToolsUnimpersonateUser(void *userToken) { #if SUPPORT_VGAUTH if (NULL != currentUserHandle) { GuestAuthUnimpersonate(); return; } #endif if (PROCESS_CREATOR_USER_TOKEN != userToken) { #if defined(_WIN32) Impersonate_Undo(); #else ProcMgr_ImpersonateUserStop(); #endif } } // VixToolsUnimpersonateUser /* *----------------------------------------------------------------------------- * * VixToolsLogoutUser -- * * * Return value: * * Side effects: * None * *----------------------------------------------------------------------------- */ void VixToolsLogoutUser(void *userToken) // IN { if (PROCESS_CREATOR_USER_TOKEN == userToken) { return; } #if SUPPORT_VGAUTH if (NULL != currentUserHandle) { #ifdef _WIN32 // close the handle we copied out CloseHandle((HANDLE) userToken); #endif VGAuth_UserHandleFree(currentUserHandle); currentUserHandle = NULL; return; } #endif if (NULL != userToken) { AuthToken authToken = (AuthToken) userToken; Auth_CloseToken(authToken); } } // VixToolsLogoutUser /* *----------------------------------------------------------------------------- * * VixToolsGetImpersonatedUsername -- * * Return value: * The name of the user currently being impersonated. Must be freed * by caller. * * Side effects: * None * *----------------------------------------------------------------------------- */ static char * VixToolsGetImpersonatedUsername(void *userToken) { char *userName = NULL; char *homeDir = NULL; #if SUPPORT_VGAUTH if (NULL != currentUserHandle) { VGAuthContext *ctx; VGAuthError vgErr = TheVGAuthContext(&ctx); ASSERT(vgErr == VGAUTH_E_OK); vgErr = VGAuth_UserHandleUsername(ctx, currentUserHandle, &userName); if (VGAUTH_FAILED(vgErr)) { Warning("%s: Unable to get username from userhandle %p\n", __FUNCTION__, currentUserHandle); } return userName; } #endif if (!ProcMgr_GetImpersonatedUserInfo(&userName, &homeDir)) { return Util_SafeStrdup("XXX failed to get username XXX"); } free(homeDir); return userName; } // VixToolsUnimpersonateUser /* *----------------------------------------------------------------------------- * * VixToolsFreeRunProgramState -- * * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void VixToolsFreeRunProgramState(VixToolsRunProgramState *asyncState) // IN { if (NULL == asyncState) { return; } if (NULL != asyncState->tempScriptFilePath) { /* * Use UnlinkNoFollow() since we created the file and we know it is not * a symbolic link. */ File_UnlinkNoFollow(asyncState->tempScriptFilePath); } if (NULL != asyncState->procState) { ProcMgr_Free(asyncState->procState); } free(asyncState->requestName); free(asyncState->tempScriptFilePath); free(asyncState); } // VixToolsFreeRunProgramState /* *----------------------------------------------------------------------------- * * VixToolsFreeStartProgramState -- * * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void VixToolsFreeStartProgramState(VixToolsStartProgramState *asyncState) // IN { if (NULL == asyncState) { return; } free(asyncState); } // VixToolsFreeStartProgramState /* *---------------------------------------------------------------------------- * * VixToolsGetTempFileCreateNameFunc -- * * This function is designed as part of implementing CreateTempFile, * CreateTempDirectory VI guest operations. * * This function will be passed to File_MakeTempEx2 when * VixToolsGetTempFile() is called. * * Return Value: * If success, a dynamically allocated string with the base name of * of the file. NULL otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static char * VixToolsGetTempFileCreateNameFunc(uint32 num, // IN: void *payload) // IN: { char *fileName = NULL; VixToolsGetTempFileCreateNameFuncData *data = (VixToolsGetTempFileCreateNameFuncData *) payload; if (payload == NULL) { goto abort; } if ((data->filePrefix == NULL) || (data->tag == NULL) || (data->fileSuffix == NULL)) { goto abort; } fileName = Str_SafeAsprintf(NULL, "%s%s%u%s", data->filePrefix, data->tag, num, data->fileSuffix); abort: return fileName; } // VixToolsGetTempFileCreateNameFunc /* *----------------------------------------------------------------------------- * * VixToolsGetTempFile -- * * Creates and opens a new temporary file, appropriate for the user * that is represented by the userToken. * * Return value: * VixError * *tempFile will point to the name of the temporary file, or NULL on error. * *fd will be the file descriptor of the temporary file, or -1 on error. * * Side effects: * The temp file will be created and opened. * *----------------------------------------------------------------------------- */ static VixError VixToolsGetTempFile(VixCommandRequestHeader *requestMsg, // IN void *userToken, // IN char **tempFile, // OUT int *tempFileFd) // OUT { VixError err = VIX_E_FAIL; char *tempFilePath = NULL; int fd = -1; char *directoryPath = NULL; VixToolsGetTempFileCreateNameFuncData data; Bool createTempFile = TRUE; if (NULL == tempFile || NULL == tempFileFd) { ASSERT(0); return err; } *tempFile = NULL; *tempFileFd = -1; data.filePrefix = NULL; data.fileSuffix = NULL; data.tag = Util_SafeStrdup("vmware"); if ((VIX_COMMAND_CREATE_TEMPORARY_FILE_EX == requestMsg->opCode) || (VIX_COMMAND_CREATE_TEMPORARY_DIRECTORY == requestMsg->opCode)) { VixMsgCreateTempFileRequestEx *makeTempFileRequest; char *tempPtr = NULL; makeTempFileRequest = (VixMsgCreateTempFileRequestEx *) requestMsg; if ((requestMsg->commonHeader.bodyLength + requestMsg->commonHeader.headerLength) != (((uint64) sizeof(*makeTempFileRequest)) + makeTempFileRequest->filePrefixLength + 1 + makeTempFileRequest->fileSuffixLength + 1 + makeTempFileRequest->directoryPathLength + 1 + makeTempFileRequest->propertyListLength)) { ASSERT(0); Debug("%s: Invalid request message received\n", __FUNCTION__); err = VIX_E_INVALID_MESSAGE_BODY; goto abort; } tempPtr = ((char *) makeTempFileRequest) + sizeof(*makeTempFileRequest); if ('\0' != *(tempPtr + makeTempFileRequest->filePrefixLength)) { ASSERT(0); Debug("%s: Invalid request message received\n", __FUNCTION__); err = VIX_E_INVALID_MESSAGE_BODY; goto abort; } data.filePrefix = Util_SafeStrdup(tempPtr); tempPtr += makeTempFileRequest->filePrefixLength + 1; if ('\0' != *(tempPtr + makeTempFileRequest->fileSuffixLength)) { ASSERT(0); Debug("%s: Invalid request message received\n", __FUNCTION__); err = VIX_E_INVALID_MESSAGE_BODY; goto abort; } data.fileSuffix = Util_SafeStrdup(tempPtr); tempPtr += makeTempFileRequest->fileSuffixLength + 1; if ('\0' != *(tempPtr + makeTempFileRequest->directoryPathLength)) { ASSERT(0); Debug("%s: Invalid request message received\n", __FUNCTION__); err = VIX_E_INVALID_MESSAGE_BODY; goto abort; } if (VIX_COMMAND_CREATE_TEMPORARY_DIRECTORY == requestMsg->opCode) { createTempFile = FALSE; } directoryPath = Util_SafeStrdup(tempPtr); } else { data.filePrefix = Util_SafeStrdup(""); data.fileSuffix = Util_SafeStrdup(""); directoryPath = Util_SafeStrdup(""); } #ifdef _WIN32 /* * Don't try this if we're not impersonating anyone, since either * 1) It's running as System and System won't have the environment variables * we want. * 2) It's the console user and then it's running within the user's session and * we don't know who we're impersonating and also the environment variables * will be directly present in the environment, so GetTempPath will do the * trick. */ if (PROCESS_CREATOR_USER_TOKEN != userToken) { if (!(strcmp(directoryPath, ""))) { free(directoryPath); directoryPath = NULL; err = VixToolsGetUserTmpDir(userToken, &directoryPath); } else { /* * Initially, when 'err' variable is defined, it is initialized to * VIX_E_FAIL. At this point in the code, user has already specified * the directory path in which the temporary file has to be created. * This is completely fine. So, just set 'err' to VIX_OK. */ err = VIX_OK; } if (VIX_SUCCEEDED(err)) { /* * If the specified directory path doesn't exist or points to an * existing regular file, then File_MakeTempEx2() returns different * errors on Windows and Linux platforms. So, check for the proper * filetype and return proper errors before calling * File_MakeTempEx2(). */ if (!File_Exists(directoryPath)) { err = VIX_E_FILE_NOT_FOUND; goto abort; } if (File_IsFile(directoryPath)) { err = VIX_E_NOT_A_DIRECTORY; goto abort; } fd = File_MakeTempEx2(directoryPath, createTempFile, VixToolsGetTempFileCreateNameFunc, &data, &tempFilePath); if (fd < 0) { /* * File_MakeTempEx() function internally uses Posix variant * functions and proper error will be stuffed in errno variable. * If File_MakeTempEx() fails, then use Vix_TranslateErrno() * to translate the errno to a proper foundry error. */ err = Vix_TranslateErrno(errno); goto abort; } } else { /* * Don't give up if VixToolsGetUserTmpDir() failed. It might just * have failed to load DLLs, so we might be running on Win 9x. * Just fall through to use the old fashioned File_GetSafeTmpDir(). */ ASSERT(directoryPath == NULL); directoryPath = Util_SafeStrdup(""); err = VIX_OK; } } #endif if (NULL == tempFilePath) { if (!strcmp(directoryPath, "")) { free(directoryPath); directoryPath = NULL; directoryPath = File_GetSafeTmpDir(TRUE); } /* * If the specified directory path doesn't exist or points to an * existing regular file, then File_MakeTempEx2() returns different * errors on Windows and Linux platforms. So, check for the proper * filetype and return proper errors before calling * File_MakeTempEx2(). */ if (!File_Exists(directoryPath)) { err = VIX_E_FILE_NOT_FOUND; goto abort; } if (File_IsFile(directoryPath)) { err = VIX_E_NOT_A_DIRECTORY; goto abort; } fd = File_MakeTempEx2(directoryPath, createTempFile, VixToolsGetTempFileCreateNameFunc, &data, &tempFilePath); if (fd < 0) { /* * File_MakeTempEx2() function internally uses Posix variant * functions and proper error will be stuffed in errno variable. * If File_MakeTempEx2() fails, then use Vix_TranslateErrno() * to translate the errno to a proper foundry error. */ err = Vix_TranslateErrno(errno); goto abort; } } *tempFile = tempFilePath; *tempFileFd = fd; err = VIX_OK; abort: free(data.filePrefix); free(data.fileSuffix); free(data.tag); free(directoryPath); return err; } // VixToolsGetTempFile /* *----------------------------------------------------------------------------- * * VixToolsProcessHgfsPacket -- * * This sends a packet to the HGFS server in the guest. * We pass in the user credential type and authenication * information as strings, followed by the actual HGFS packet * to send to the HGFS Server in the guest Tools. * The recipient of this string is ToolsDaemonHgfsImpersonated, * which lives in foundryToolsDaemon.c. It parses the authentication * information, impersonates a user in the guest using * ToolsDaemonImpersonateUser, and then calls HgfsServerManager_ProcessPacket * to issue the HGFS packet to the HGFS Server. The HGFS Server * replies with an HGFS packet, which will be forwarded back to * us and handled in VMAutomationOnBackdoorCallReturns. * * Results: * VIX_OK if success, VixError error code otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsProcessHgfsPacket(VixCommandHgfsSendPacket *requestMsg, // IN GMainLoop *eventQueue, // IN char **result, // OUT size_t *resultValueResult) // OUT { VixError err = VIX_OK; void *userToken = NULL; Bool impersonatingVMWareUser = FALSE; const char *hgfsPacket; size_t hgfsReplyPacketSize = 0; static char hgfsReplyPacket[HGFS_LARGE_PACKET_MAX]; VMAutomationRequestParser parser; if ((NULL == requestMsg) || (0 == requestMsg->hgfsPacketSize)) { ASSERT(0); err = VIX_E_FAIL; goto abort; } err = VMAutomationRequestParserInit(&parser, &requestMsg->header, sizeof *requestMsg); if (VIX_OK != err) { goto abort; } err = VixToolsImpersonateUser((VixCommandRequestHeader *) requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; err = VMAutomationRequestParserGetData(&parser, requestMsg->hgfsPacketSize, &hgfsPacket); if (VIX_OK != err) { goto abort; } hgfsReplyPacketSize = sizeof hgfsReplyPacket; /* * Impersonation was okay, so let's give our packet to * the HGFS server and forward the reply packet back. */ HgfsServerManager_ProcessPacket(&gVixHgfsBkdrConn, // connection hgfsPacket, // packet in buf requestMsg->hgfsPacketSize, // packet in size hgfsReplyPacket, // packet out buf &hgfsReplyPacketSize); // in/out size if (eventQueue != NULL) { /* * Register a timer to periodically invalidate any inactive * HGFS sessions. */ VixToolsRegisterHgfsSessionInvalidator(eventQueue); } if (NULL != resultValueResult) { *resultValueResult = hgfsReplyPacketSize; } if (NULL != result) { *result = hgfsReplyPacket; } abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); return err; } // VixToolsProcessHgfsPacket /* *----------------------------------------------------------------------------- * * VixToolsListFileSystems -- * * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsListFileSystems(VixCommandRequestHeader *requestMsg, // IN char **result) // OUT { VixError err = VIX_OK; static char resultBuffer[GUESTMSG_MAX_IN_SIZE]; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; char *destPtr; char *endDestPtr; Bool escapeStrs; #if defined(_WIN32) || defined(linux) Bool truncated; #endif #if defined(_WIN32) Unicode *driveList = NULL; int numDrives = -1; uint64 freeBytesToUser = 0; uint64 totalBytesToUser = 0; uint64 freeBytes = 0; Unicode fileSystemType; int i; #endif #ifdef linux MNTHANDLE fp; DECLARE_MNTINFO(mnt); const char *mountfile = NULL; #endif Debug(">%s\n", __FUNCTION__); destPtr = resultBuffer; *destPtr = 0; endDestPtr = resultBuffer + sizeof(resultBuffer); err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; escapeStrs = (requestMsg->requestFlags & VIX_REQUESTMSG_ESCAPE_XML_DATA) != 0; #if defined(_WIN32) numDrives = Win32U_GetLogicalDriveStrings(&driveList); if (-1 == numDrives) { Warning("unable to get drive listing: windows error code %d\n", GetLastError()); err = FoundryToolsDaemon_TranslateSystemErr(); goto abort; } if (escapeStrs) { destPtr += Str_Sprintf(destPtr, endDestPtr - destPtr, "%s", VIX_XML_ESCAPED_TAG); } for (i = 0; i < numDrives; i++) { if (!Win32U_GetDiskFreeSpaceEx(driveList[i], (PULARGE_INTEGER) &freeBytesToUser, (PULARGE_INTEGER) &totalBytesToUser, (PULARGE_INTEGER) &freeBytes)) { /* * If we encounter an error, just return 0 values for the space info */ freeBytesToUser = 0; totalBytesToUser = 0; freeBytes = 0; Warning("unable to get drive size info: windows error code %d\n", GetLastError()); } // If it fails, fileSystemType will be NULL Win32U_GetVolumeInformation(driveList[i], NULL, NULL, NULL, NULL, &fileSystemType); err = VixToolsPrintFileSystemInfo(&destPtr, endDestPtr, driveList[i], totalBytesToUser, freeBytesToUser, fileSystemType ? fileSystemType : "", escapeStrs, &truncated); if ((VIX_OK != err) || truncated) { goto abort; } Unicode_Free(fileSystemType); } #elif defined(linux) mountfile = "/etc/mtab"; fp = Posix_Setmntent(mountfile, "r"); if (fp == NULL) { Warning("failed to open mount file\n"); err = VIX_E_FILE_NOT_FOUND; goto abort; } while (GETNEXT_MNTINFO(fp, mnt)) { struct statfs statfsbuf; uint64 size, freeSpace; if (Posix_Statfs(MNTINFO_MNTPT(mnt), &statfsbuf)) { Warning("%s unable to stat mount point %s\n", __FUNCTION__, MNTINFO_MNTPT(mnt)); continue; } size = (uint64) statfsbuf.f_blocks * (uint64) statfsbuf.f_bsize; freeSpace = (uint64) statfsbuf.f_bfree * (uint64) statfsbuf.f_bsize; err = VixToolsPrintFileSystemInfo(&destPtr, endDestPtr, MNTINFO_NAME(mnt), size, freeSpace, MNTINFO_FSTYPE(mnt), escapeStrs, &truncated); if ((VIX_OK != err) || truncated) { goto abort; } } CLOSE_MNTFILE(fp); #else err = VIX_E_NOT_SUPPORTED; #endif abort: #if defined(_WIN32) for (i = 0; i < numDrives; i++) { Unicode_Free(driveList[i]); } free(driveList); #endif if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); *result = resultBuffer; Debug("<%s\n", __FUNCTION__); return(err); } // VixToolsListFileSystems #if defined(_WIN32) || defined(linux) /* *----------------------------------------------------------------------------- * * VixToolsPrintFileSystemInfo -- * * Appends a single file system entry to the XML-like string starting at * *destPtr. * * Results: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ static VixError VixToolsPrintFileSystemInfo(char **destPtr, // IN/OUT const char *endDestPtr, // IN const char *name, // IN uint64 size, // IN uint64 freeSpace, // IN const char *type, // IN Bool escapeStrs, // IN Bool *truncated) // OUT { VixError err; char *escapedName = NULL; char *escapedType = NULL; int bytesPrinted; ASSERT(endDestPtr > *destPtr); *truncated = FALSE; if (escapeStrs) { name = escapedName = VixToolsEscapeXMLString(name); if (NULL == escapedName) { err = VIX_E_OUT_OF_MEMORY; goto abort; } type = escapedType = VixToolsEscapeXMLString(type); if (NULL == escapedType) { err = VIX_E_OUT_OF_MEMORY; goto abort; } } bytesPrinted = Str_Snprintf(*destPtr, endDestPtr - *destPtr, "" "%s" "%"FMT64"u" "%"FMT64"u" "%s" "", name, size, freeSpace, type); if (bytesPrinted != -1) { *destPtr += bytesPrinted; } else { // out of space **destPtr = '\0'; Debug("%s: file system list results too large, truncating", __FUNCTION__); *truncated = TRUE; err = VIX_OK; goto abort; } err = VIX_OK; abort: free(escapedName); free(escapedType); return err; } #endif // #if defined(_WIN32) || defined(linux) /* *----------------------------------------------------------------------------- * * VixToolsValidateCredentials -- * * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsValidateCredentials(VixCommandRequestHeader *requestMsg) // IN { VixError err = VIX_OK; void *userToken = NULL; Bool impersonatingVMWareUser = FALSE; Debug(">%s\n", __FUNCTION__); if (NULL == requestMsg) { ASSERT(0); err = VIX_E_FAIL; goto abort; } err = VixToolsImpersonateUser((VixCommandRequestHeader *) requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); Debug("<%s\n", __FUNCTION__); return err; } /* *----------------------------------------------------------------------------- * * VixToolsAcquireCredentials -- * * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsAcquireCredentials(VixCommandRequestHeader *requestMsg, // IN GMainLoop *eventQueue, // IN char **result) // OUT { VixError err; Debug(">%s\n", __FUNCTION__); #if !defined(_WIN32) err = VIX_E_NOT_SUPPORTED; goto abort; #else err = VixToolsAuthenticateWithSSPI(requestMsg, eventQueue, result); if (VIX_OK != err) { Debug("%s: Failed to authenticate with SSPI with error %d\n", __FUNCTION__, err); goto abort; } #endif abort: Debug("<%s\n", __FUNCTION__); return err; } /* *----------------------------------------------------------------------------- * * VixToolsReleaseCredentials -- * * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsReleaseCredentials(VixCommandRequestHeader *requestMsg) // IN { VixError err = VIX_OK; Debug(">%s\n", __FUNCTION__); #if !defined(_WIN32) err = VIX_E_NOT_SUPPORTED; #else err = VixToolsReleaseCredentialsImpl(requestMsg); #endif Debug("<%s\n", __FUNCTION__); return err; } /* *----------------------------------------------------------------------------- * * VixToolsGetGuestNetworkingConfig -- * * * Return value: * VIX_OK on success * VixError on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ #if defined(__linux__) || defined(_WIN32) VixError VixToolsGetGuestNetworkingConfig(VixCommandRequestHeader *requestMsg, // IN char **resultBuffer, // OUT size_t *resultBufferLength) // OUT { VixError err = VIX_OK; VixPropertyListImpl propList; char *serializedBuffer = NULL; size_t serializedBufferLength = 0; GuestNic *nicEntry = NULL; VmIpAddress *ipAddr; ASSERT(NULL != requestMsg); ASSERT(NULL != resultBuffer); ASSERT(NULL != resultBufferLength); VixPropertyList_Initialize(&propList); nicEntry = NetUtil_GetPrimaryNic(); if (NULL == nicEntry) { err = FoundryToolsDaemon_TranslateSystemErr(); goto abort; } ipAddr = &nicEntry->ips.ips_val[0]; /* * Now, record these values in a property list. */ err = VixPropertyList_SetString(&propList, VIX_PROPERTY_VM_IP_ADDRESS, ipAddr->ipAddress); if (VIX_OK != err) { goto abort; } #if defined(_WIN32) err = VixPropertyList_SetBool(&propList, VIX_PROPERTY_VM_DHCP_ENABLED, ipAddr->dhcpEnabled); if (VIX_OK != err) { goto abort; } err = VixPropertyList_SetString(&propList, VIX_PROPERTY_VM_SUBNET_MASK, ipAddr->subnetMask); if (VIX_OK != err) { goto abort; } #endif /* * Serialize the property list to buffer then encode it. * This is the string we return to the VMX process. */ err = VixPropertyList_Serialize(&propList, FALSE, &serializedBufferLength, &serializedBuffer); if (VIX_OK != err) { goto abort; } *resultBuffer = serializedBuffer; *resultBufferLength = serializedBufferLength; serializedBuffer = NULL; abort: VixPropertyList_RemoveAllWithoutHandles(&propList); if (NULL != nicEntry) { VMX_XDR_FREE(xdr_GuestNic, nicEntry); free(nicEntry); } return err; } // VixToolsGetGuestNetworkingConfig #endif /* *----------------------------------------------------------------------------- * * VixToolsSetGuestNetworkingConfig -- * * * Return value: * Vix_OK on success * VixError on failure * * Side effects: * networking configuration on hte guest may change * *----------------------------------------------------------------------------- */ #if defined(_WIN32) VixError VixToolsSetGuestNetworkingConfig(VixCommandRequestHeader *requestMsg) // IN { VixError err = VIX_OK; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; VixMsgSetGuestNetworkingConfigRequest *setGuestNetworkingConfigRequest = NULL; VixPropertyListImpl propList; VixPropertyValue *propertyPtr = NULL; char *messageBody = NULL; char ipAddr[IP_ADDR_SIZE]; char subnetMask[IP_ADDR_SIZE]; Bool dhcpEnabled = FALSE; HRESULT hrErr; ASSERT(NULL != requestMsg); ipAddr[0] = '\0'; subnetMask[0] = '\0'; err = VixToolsImpersonateUser(requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; setGuestNetworkingConfigRequest = (VixMsgSetGuestNetworkingConfigRequest *)requestMsg; messageBody = (char *) requestMsg + sizeof(*setGuestNetworkingConfigRequest); VixPropertyList_Initialize(&propList); err = VixPropertyList_Deserialize(&propList, messageBody, setGuestNetworkingConfigRequest -> bufferSize, VIX_PROPERTY_LIST_BAD_ENCODING_ERROR); if (VIX_OK != err) { goto abort; } propertyPtr = propList.properties; while (propertyPtr != NULL) { switch (propertyPtr->propertyID) { /////////////////////////////////////////// case VIX_PROPERTY_VM_DHCP_ENABLED: if (propertyPtr->value.boolValue) { dhcpEnabled = TRUE; } break; /////////////////////////////////////////// case VIX_PROPERTY_VM_IP_ADDRESS: if (strlen(propertyPtr->value.strValue) < sizeof ipAddr) { Str_Strcpy(ipAddr, propertyPtr->value.strValue, sizeof ipAddr); } else { err = VIX_E_INVALID_ARG; goto abort; } break; /////////////////////////////////////////// case VIX_PROPERTY_VM_SUBNET_MASK: if (strlen(propertyPtr->value.strValue) < sizeof subnetMask) { Str_Strcpy(subnetMask, propertyPtr->value.strValue, sizeof subnetMask); } else { err = VIX_E_INVALID_ARG; goto abort; } break; /////////////////////////////////////////// default: /* * Be more tolerant. Igonore unknown properties. */ break; } // switch propertyPtr = propertyPtr->next; } // while {propList.properties != NULL) if (dhcpEnabled) { hrErr = VixToolsEnableDHCPOnPrimary(); } else { if (('\0' != ipAddr[0]) || ('\0' != subnetMask[0])) { hrErr = VixToolsEnableStaticOnPrimary(ipAddr, subnetMask); } else { /* * Setting static ip, both ip and subnet mask are missing */ err = VIX_E_MISSING_REQUIRED_PROPERTY; goto abort; } } if (S_OK != hrErr) { if (FACILITY_WIN32 != HRESULT_FACILITY(hrErr)) { err = Vix_TranslateCOMError(hrErr); } else { err = Vix_TranslateSystemError(hrErr); } } abort: VixPropertyList_RemoveAllWithoutHandles(&propList); if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); return err; } // VixToolsSetGuestNetworkingConfig #endif #if SUPPORT_VGAUTH /* *----------------------------------------------------------------------------- * * VixToolsAddAuthAlias -- * * Calls to VGAuth to add a new alias. * * Return value: * VixError * * Side effects: * VGAuth alias store is updated. * *----------------------------------------------------------------------------- */ VixError VixToolsAddAuthAlias(VixCommandRequestHeader *requestMsg) // IN { VixError err = VIX_OK; VGAuthError vgErr; void *userToken = NULL; VGAuthContext *ctx = NULL; VixMsgAddAuthAliasRequest *req; const char *userName; const char *pemCert; const char *subjectName; const char *aliasComment; VGAuthAliasInfo ai; VMAutomationRequestParser parser; Bool impersonatingVMWareUser = FALSE; Debug(">%s\n", __FUNCTION__); err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *req); if (VIX_OK != err) { goto abort; } req = (VixMsgAddAuthAliasRequest *) requestMsg; err = VMAutomationRequestParserGetOptionalString(&parser, req->userNameLen, &userName); if (VIX_OK != err) { goto abort; } if (NULL == userName || 0 == *userName) { err = VIX_E_INVALID_ARG; goto abort; } err = VMAutomationRequestParserGetOptionalString(&parser, req->pemCertLen, &pemCert); if (VIX_OK != err) { goto abort; } if (NULL == pemCert || 0 == *pemCert) { err = VIX_E_INVALID_ARG; goto abort; } if ((req->subjectType != VIX_GUEST_AUTH_SUBJECT_TYPE_NAMED) && (req->subjectType != VIX_GUEST_AUTH_SUBJECT_TYPE_ANY)) { err = VIX_E_INVALID_ARG; goto abort; } err = VMAutomationRequestParserGetOptionalString(&parser, req->subjectNameLen, &subjectName); if (VIX_OK != err) { goto abort; } if ((req->subjectType == VIX_GUEST_AUTH_SUBJECT_TYPE_NAMED) && (NULL == subjectName || 0 == *subjectName)) { err = VIX_E_INVALID_ARG; goto abort; } err = VMAutomationRequestParserGetOptionalString(&parser, req->aliasCommentLen, &aliasComment); if (VIX_OK != err) { goto abort; } err = VixToolsImpersonateUser((VixCommandRequestHeader *) requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; /* * For aliasStore APIs, make a fresh context so we know * the security is correct. */ vgErr = VGAuth_Init(VMTOOLSD_APP_NAME, 0, NULL, &ctx); if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); goto abort; } ai.subject.type = (req->subjectType == VIX_GUEST_AUTH_SUBJECT_TYPE_NAMED) ? VGAUTH_SUBJECT_NAMED : VGAUTH_SUBJECT_ANY; ai.subject.val.name = (char *) subjectName; ai.comment = (char *) aliasComment; vgErr = VGAuth_AddAlias(ctx, userName, req->addMapping, pemCert, &ai, 0, NULL); if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); } abort: if (ctx) { vgErr = VGAuth_Shutdown(ctx); if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); // fall thru } } if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); Debug("<%s\n", __FUNCTION__); return err; } /* *----------------------------------------------------------------------------- * * VixToolsRemoveAuthAlias -- * * Calls to VGAuth to remove an alias. * * Return value: * VixError * * Side effects: * VGAuth Alias store is updated. * *----------------------------------------------------------------------------- */ VixError VixToolsRemoveAuthAlias(VixCommandRequestHeader *requestMsg) // IN { VixError err = VIX_OK; VGAuthError vgErr; void *userToken = NULL; VGAuthContext *ctx = NULL; VixMsgRemoveAuthAliasRequest *req; const char *userName; const char *pemCert; const char *subjectName; VGAuthSubject subj; VMAutomationRequestParser parser; Bool impersonatingVMWareUser = FALSE; Debug(">%s\n", __FUNCTION__); err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *req); if (VIX_OK != err) { goto abort; } req = (VixMsgRemoveAuthAliasRequest *) requestMsg; err = VMAutomationRequestParserGetOptionalString(&parser, req->userNameLen, &userName); if (VIX_OK != err) { goto abort; } if (NULL == userName || 0 == *userName) { err = VIX_E_INVALID_ARG; goto abort; } err = VMAutomationRequestParserGetOptionalString(&parser, req->pemCertLen, &pemCert); if (VIX_OK != err) { goto abort; } if (NULL == pemCert || 0 == *pemCert) { err = VIX_E_INVALID_ARG; goto abort; } if ((req->subjectType != VIX_GUEST_AUTH_SUBJECT_TYPE_NONE) && (req->subjectType != VIX_GUEST_AUTH_SUBJECT_TYPE_NAMED) && (req->subjectType != VIX_GUEST_AUTH_SUBJECT_TYPE_ANY)) { err = VIX_E_INVALID_ARG; goto abort; } err = VMAutomationRequestParserGetOptionalString(&parser, req->subjectNameLen, &subjectName); if (VIX_OK != err) { goto abort; } if ((req->subjectType == VIX_GUEST_AUTH_SUBJECT_TYPE_NAMED) && (NULL == subjectName || 0 == *subjectName)) { err = VIX_E_INVALID_ARG; goto abort; } err = VixToolsImpersonateUser((VixCommandRequestHeader *) requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; /* * For aliasStore APIs, make a fresh context so we know * the security is correct. */ vgErr = VGAuth_Init(VMTOOLSD_APP_NAME, 0, NULL, &ctx); if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); goto abort; } if (VIX_GUEST_AUTH_SUBJECT_TYPE_NONE == req->subjectType) { vgErr = VGAuth_RemoveAliasByCert(ctx, userName, pemCert, 0, NULL); } else { subj.type = (req->subjectType == VIX_GUEST_AUTH_SUBJECT_TYPE_NAMED) ? VGAUTH_SUBJECT_NAMED : VGAUTH_SUBJECT_ANY; subj.val.name = (char *) subjectName; vgErr = VGAuth_RemoveAlias(ctx, userName, pemCert, &subj, 0, NULL); } if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); } abort: if (ctx) { vgErr = VGAuth_Shutdown(ctx); if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); // fall thru } } if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); Debug("<%s\n", __FUNCTION__); return err; } /* *----------------------------------------------------------------------------- * * VixToolsListAuthAliases -- * * Calls to VGAuth to list user aliases. * * Return value: * VixError * * Side effects: * VGAuth Alias store is updated. * *----------------------------------------------------------------------------- */ VixError VixToolsListAuthAliases(VixCommandRequestHeader *requestMsg, // IN size_t maxBufferSize, // IN char **result) // OUT { VixError err = VIX_OK; VGAuthError vgErr; void *userToken = NULL; VGAuthContext *ctx = NULL; VixMsgListAuthAliasesRequest *req; const char *userName; VMAutomationRequestParser parser; Bool impersonatingVMWareUser = FALSE; int num = 0; int i; int j; VGAuthUserAlias *uaList = NULL; static char resultBuffer[GUESTMSG_MAX_IN_SIZE]; char *destPtr; char *endDestPtr; char *tmpBuf = NULL; char *tmpBuf2 = NULL; char *recordBuf; size_t recordSize; char *escapedStr = NULL; char *escapedStr2 = NULL; Debug(">%s\n", __FUNCTION__); ASSERT(maxBufferSize <= GUESTMSG_MAX_IN_SIZE); *result = NULL; destPtr = resultBuffer; *destPtr = 0; err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *req); if (VIX_OK != err) { goto abort; } req = (VixMsgListAuthAliasesRequest *) requestMsg; err = VMAutomationRequestParserGetOptionalString(&parser, req->userNameLen, &userName); if (VIX_OK != err) { goto abort; } if (NULL == userName || 0 == *userName) { err = VIX_E_INVALID_ARG; goto abort; } err = VixToolsImpersonateUser((VixCommandRequestHeader *) requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; /* * For aliasStore APIs, make a fresh context so we know * the security is correct. */ vgErr = VGAuth_Init(VMTOOLSD_APP_NAME, 0, NULL, &ctx); if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); goto abort; } vgErr = VGAuth_QueryUserAliases(ctx, userName, 0, NULL, &num, &uaList); if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); goto abort; } endDestPtr = resultBuffer + maxBufferSize; destPtr += Str_Sprintf(destPtr, endDestPtr - destPtr, "%s", VIX_XML_ESCAPED_TAG); for (i = 0; i < num; i++) { escapedStr = VixToolsEscapeXMLString(uaList[i].pemCert); if (escapedStr == NULL) { err = VIX_E_OUT_OF_MEMORY; goto abort; } tmpBuf2 = Str_Asprintf(NULL, "%s", escapedStr); free(escapedStr); escapedStr = NULL; if (tmpBuf2 == NULL) { err = VIX_E_OUT_OF_MEMORY; goto abort; } for (j = 0; j < uaList[i].numInfos; j++) { if (uaList[i].infos[j].comment) { escapedStr = VixToolsEscapeXMLString(uaList[i].infos[j].comment); if (escapedStr == NULL) { err = VIX_E_OUT_OF_MEMORY; goto abort; } } if (uaList[i].infos[j].subject.type == VGAUTH_SUBJECT_NAMED) { escapedStr2 = VixToolsEscapeXMLString(uaList[i].infos[j].subject.val.name); if (escapedStr2 == NULL) { err = VIX_E_OUT_OF_MEMORY; goto abort; } } tmpBuf = Str_Asprintf(NULL, "%s" "" "%d" "%s" "%s" "", tmpBuf2, (uaList[i].infos[j].subject.type == VGAUTH_SUBJECT_NAMED) ? VIX_GUEST_AUTH_SUBJECT_TYPE_NAMED : VIX_GUEST_AUTH_SUBJECT_TYPE_ANY, escapedStr2 ? escapedStr2 : "", escapedStr ? escapedStr : ""); if (tmpBuf == NULL) { err = VIX_E_OUT_OF_MEMORY; goto abort; } free(tmpBuf2); tmpBuf2 = tmpBuf; free(escapedStr); escapedStr = NULL; free(escapedStr2); escapedStr2 = NULL; } recordBuf = Str_Asprintf(&recordSize, "%s", tmpBuf); free(tmpBuf); tmpBuf = tmpBuf2 = NULL; if (recordBuf == NULL) { err = VIX_E_OUT_OF_MEMORY; goto abort; } if ((destPtr + recordSize) < endDestPtr) { destPtr += Str_Sprintf(destPtr, endDestPtr - destPtr, "%s", recordBuf); } else { free(recordBuf); recordBuf = NULL; Log("%s: ListAuth list results too large, truncating", __FUNCTION__); goto abort; } } *result = resultBuffer; abort: free(tmpBuf); free(tmpBuf2); free(escapedStr); free(escapedStr2); VGAuth_FreeUserAliasList(num, uaList); if (ctx) { vgErr = VGAuth_Shutdown(ctx); if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); goto abort; } } if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); Debug("<%s\n", __FUNCTION__); return err; } /* *----------------------------------------------------------------------------- * * VixToolsListMappedAliases -- * * Calls to VGAuth to list mapped aliases. * * Return value: * VixError * * Side effects: * VGAuth Alias store is updated. * *----------------------------------------------------------------------------- */ VixError VixToolsListMappedAliases(VixCommandRequestHeader *requestMsg, // IN size_t maxBufferSize, // IN char **result) // OUT { VixError err = VIX_OK; VGAuthError vgErr; void *userToken = NULL; VGAuthContext *ctx = NULL; VixMsgListMappedAliasesRequest *req; VMAutomationRequestParser parser; Bool impersonatingVMWareUser = FALSE; int num = 0; int i; int j; VGAuthMappedAlias *maList = NULL; static char resultBuffer[GUESTMSG_MAX_IN_SIZE]; char *destPtr; char *endDestPtr; char *tmpBuf = NULL; char *tmpBuf2 = NULL; char *recordBuf; char *escapedStr = NULL; char *escapedStr2 = NULL; size_t recordSize; Debug(">%s\n", __FUNCTION__); ASSERT(maxBufferSize <= GUESTMSG_MAX_IN_SIZE); *result = NULL; destPtr = resultBuffer; *destPtr = 0; err = VMAutomationRequestParserInit(&parser, requestMsg, sizeof *req); if (VIX_OK != err) { goto abort; } req = (VixMsgListMappedAliasesRequest *) requestMsg; err = VixToolsImpersonateUser((VixCommandRequestHeader *) requestMsg, &userToken); if (VIX_OK != err) { goto abort; } impersonatingVMWareUser = TRUE; vgErr = TheVGAuthContext(&ctx); if (vgErr != VGAUTH_E_OK) { err = VixToolsTranslateVGAuthError(vgErr); goto abort; } /* * For aliasStore APIs, make a fresh context so we know * the security is correct. */ vgErr = VGAuth_Init(VMTOOLSD_APP_NAME, 0, NULL, &ctx); if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); goto abort; } vgErr = VGAuth_QueryMappedAliases(ctx, 0, NULL, &num, &maList); if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); goto abort; } endDestPtr = resultBuffer + maxBufferSize; destPtr += Str_Sprintf(destPtr, endDestPtr - destPtr, "%s", VIX_XML_ESCAPED_TAG); for (i = 0; i < num; i++) { escapedStr = VixToolsEscapeXMLString(maList[i].pemCert); if (escapedStr == NULL) { err = VIX_E_OUT_OF_MEMORY; goto abort; } escapedStr2 = VixToolsEscapeXMLString(maList[i].userName); if (escapedStr2 == NULL) { err = VIX_E_OUT_OF_MEMORY; goto abort; } tmpBuf2 = Str_Asprintf(NULL, "%s" "%s", escapedStr, escapedStr2); g_free(escapedStr2); g_free(escapedStr); escapedStr = NULL; escapedStr2 = NULL; if (tmpBuf2 == NULL) { err = VIX_E_OUT_OF_MEMORY; goto abort; } for (j = 0; j < maList[i].numSubjects; j++) { if (maList[i].subjects[j].type == VGAUTH_SUBJECT_NAMED) { escapedStr = VixToolsEscapeXMLString(maList[i].subjects[j].val.name); if (escapedStr == NULL) { err = VIX_E_OUT_OF_MEMORY; goto abort; } } tmpBuf = Str_Asprintf(NULL, "%s" "" "%d" "%s" "", tmpBuf2, (maList[i].subjects[j].type == VGAUTH_SUBJECT_NAMED) ? VIX_GUEST_AUTH_SUBJECT_TYPE_NAMED : VIX_GUEST_AUTH_SUBJECT_TYPE_ANY, escapedStr ? escapedStr : ""); if (tmpBuf == NULL) { err = VIX_E_OUT_OF_MEMORY; goto abort; } free(tmpBuf2); tmpBuf2 = tmpBuf; free(escapedStr); escapedStr = NULL; } recordBuf = Str_Asprintf(&recordSize, "%s", tmpBuf); free(tmpBuf); tmpBuf = tmpBuf2 = NULL; if (recordBuf == NULL) { err = VIX_E_OUT_OF_MEMORY; goto abort; } if ((destPtr + recordSize) < endDestPtr) { destPtr += Str_Sprintf(destPtr, endDestPtr - destPtr, "%s", recordBuf); } else { free(recordBuf); recordBuf = NULL; Log("%s: ListMapped results too large, truncating", __FUNCTION__); goto abort; } } *result = resultBuffer; abort: free(tmpBuf); free(tmpBuf2); free(escapedStr); free(escapedStr2); VGAuth_FreeMappedAliasList(num, maList); if (ctx) { vgErr = VGAuth_Shutdown(ctx); if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); // fall thru } } if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); Debug("<%s\n", __FUNCTION__); return err; } #endif // SUPPORT_VGAUTH /* *----------------------------------------------------------------------------- * * VixToolsCreateRegKey -- * * Calls the function to create a new Windows Registry Key. * * Return value: * VixError * * Side effects: * May affect applications reading the key. * *----------------------------------------------------------------------------- */ VixError VixToolsCreateRegKey(VixCommandRequestHeader *requestMsg) // IN { #ifdef _WIN32 return VixToolsCreateRegKeyImpl(requestMsg); #else return VIX_E_OP_NOT_SUPPORTED_ON_GUEST; #endif } /* *----------------------------------------------------------------------------- * * VixToolsListRegKeys -- * * Calls the function to list all subkeys for a given Windows Registry Key. * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsListRegKeys(VixCommandRequestHeader *requestMsg, // IN size_t maxBufferSize, // IN void *eventQueue, // IN char **result) // OUT { #ifdef _WIN32 return VixToolsListRegKeysImpl(requestMsg, maxBufferSize, eventQueue, result); #else return VIX_E_OP_NOT_SUPPORTED_ON_GUEST; #endif } /* *----------------------------------------------------------------------------- * * VixToolsDeleteRegKey -- * * Calls the function to delete a Windows Registry Key. * * Return value: * VixError * * Side effects: * May affect applications reading the key. * *----------------------------------------------------------------------------- */ VixError VixToolsDeleteRegKey(VixCommandRequestHeader *requestMsg) // IN { #ifdef _WIN32 return VixToolsDeleteRegKeyImpl(requestMsg); #else return VIX_E_OP_NOT_SUPPORTED_ON_GUEST; #endif } /* *----------------------------------------------------------------------------- * * VixToolsSetRegValue -- * * Calls the function to set/create a Windows Registry Value for a given Key. * * Return value: * VixError * * Side effects: * May affect applications reading the key. * *----------------------------------------------------------------------------- */ VixError VixToolsSetRegValue(VixCommandRequestHeader *requestMsg) // IN { #ifdef _WIN32 return VixToolsSetRegValueImpl(requestMsg); #else return VIX_E_OP_NOT_SUPPORTED_ON_GUEST; #endif } /* *----------------------------------------------------------------------------- * * VixToolsListRegValues -- * * Calls the function to list all values for a given Windows Registry Key. * * Return value: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsListRegValues(VixCommandRequestHeader *requestMsg, // IN size_t maxBufferSize, // IN void *eventQueue, // IN char **result) // OUT { #ifdef _WIN32 return VixToolsListRegValuesImpl(requestMsg, maxBufferSize, eventQueue, result); #else return VIX_E_OP_NOT_SUPPORTED_ON_GUEST; #endif } /* *----------------------------------------------------------------------------- * * VixToolsDeleteRegValue -- * * Calls the function to delete a Windows Registry Value for a given Key. * * Return value: * VixError * * Side effects: * May affect applications reading the key. * *----------------------------------------------------------------------------- */ VixError VixToolsDeleteRegValue(VixCommandRequestHeader *requestMsg) // IN { #ifdef _WIN32 return VixToolsDeleteRegValueImpl(requestMsg); #else return VIX_E_OP_NOT_SUPPORTED_ON_GUEST; #endif } /* *----------------------------------------------------------------------------- * * VixToolsDoesUsernameMatchCurrentUser -- * * Check if the provider username matches the current user. * * Return value: * VIX_OK if it does, otherwise an appropriate error code. * * Side effects: * None * *----------------------------------------------------------------------------- */ static VixError VixToolsDoesUsernameMatchCurrentUser(const char *username) // IN { VixError err = VIX_E_FAIL; #ifdef _WIN32 char *currentUser = NULL; DWORD currentUserSize = 0; DWORD retVal = 0; HANDLE processToken = INVALID_HANDLE_VALUE; PTOKEN_USER processTokenInfo = NULL; DWORD processTokenInfoSize = 0; Unicode sidUserName = NULL; DWORD sidUserNameSize = 0; Unicode sidDomainName = NULL; DWORD sidDomainNameSize = 0; SID_NAME_USE sidNameUse; /* * Check to see if the user provided a '\' formatted username */ if (NULL != Str_Strchr(username, '\\')) { /* * A '\' formatted username was provided. * We must retrieve the domain as well as the username to verify * the current vixtools user matches the username provided */ retVal = OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &processToken); if (!retVal || !processToken) { err = FoundryToolsDaemon_TranslateSystemErr(); Warning("unable to open process token: windows error code %d\n", GetLastError()); goto abort; } // Determine necessary buffer size GetTokenInformation(processToken, TokenUser, NULL, 0, &processTokenInfoSize); if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) { err = FoundryToolsDaemon_TranslateSystemErr(); Warning("unable to get token info: windows error code %d\n", GetLastError()); goto abort; } processTokenInfo = Util_SafeMalloc(processTokenInfoSize); if (!GetTokenInformation(processToken, TokenUser, processTokenInfo, processTokenInfoSize, &processTokenInfoSize)) { err = FoundryToolsDaemon_TranslateSystemErr(); Warning("unable to get token info: windows error code %d\n", GetLastError()); goto abort; } // Retrieve user name and domain name based on user's SID. Win32U_LookupAccountSid(NULL, processTokenInfo->User.Sid, NULL, &sidUserNameSize, NULL, &sidDomainNameSize, &sidNameUse); if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) { err = FoundryToolsDaemon_TranslateSystemErr(); Warning("unable to lookup account sid: windows error code %d\n", GetLastError()); goto abort; } sidUserName = Util_SafeMalloc(sidUserNameSize); sidDomainName = Util_SafeMalloc(sidDomainNameSize); if (!Win32U_LookupAccountSid(NULL, processTokenInfo->User.Sid, sidUserName, &sidUserNameSize, sidDomainName, &sidDomainNameSize, &sidNameUse)) { err = FoundryToolsDaemon_TranslateSystemErr(); Warning("unable to lookup account sid: windows error code %d\n", GetLastError()); goto abort; } // Populate currentUser with Domain + '\' + Username currentUser = Str_SafeAsprintf(NULL, "%s\\%s", sidDomainName, sidUserName); } else { /* * For Windows, get the name of the owner of this process, then * compare it to the provided username. */ if (!Win32U_GetUserName(currentUser, ¤tUserSize)) { if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) { err = FoundryToolsDaemon_TranslateSystemErr(); goto abort; } currentUser = Util_SafeMalloc(currentUserSize); if (!Win32U_GetUserName(currentUser, ¤tUserSize)) { err = FoundryToolsDaemon_TranslateSystemErr(); goto abort; } } } if (0 != Unicode_CompareIgnoreCase(username, currentUser)) { err = VIX_E_INTERACTIVE_SESSION_USER_MISMATCH; goto abort; } err = VIX_OK; abort: free(sidDomainName); free(sidUserName); free(processTokenInfo); CloseHandle(processToken); free(currentUser); #else /* Below is the POSIX case. */ uid_t currentUid; struct passwd pwd; struct passwd *ppwd = &pwd; char *buffer = NULL; // a pool of memory for Posix_Getpwnam_r() to use. size_t bufferSize; /* * For POSIX systems, look up the uid of 'username', and compare * it to the uid of the owner of this process. This handles systems * where multiple usernames map to the name user. */ /* * Get the maximum size buffer needed by getpwuid_r. * Multiply by 4 to compensate for the conversion to UTF-8 by * the Posix_Getpwnam_r() wrapper. */ bufferSize = (size_t) sysconf(_SC_GETPW_R_SIZE_MAX) * 4; buffer = Util_SafeMalloc(bufferSize); if (Posix_Getpwnam_r(username, &pwd, buffer, bufferSize, &ppwd) != 0 || NULL == ppwd) { /* * This username should exist, since it should have already * been validated by guestd. Assume it is a system error. */ err = FoundryToolsDaemon_TranslateSystemErr(); Warning("Unable to get the uid for username %s.\n", username); goto abort; } /* * In the Windows version, GetUserNameW() returns the name of the * user the thread is impersonating (if it is impersonating someone), * so geteuid() seems to be the moral equivalent. */ currentUid = geteuid(); if (currentUid != ppwd->pw_uid) { err = VIX_E_INTERACTIVE_SESSION_USER_MISMATCH; goto abort; } err = VIX_OK; abort: Util_ZeroFree(buffer, bufferSize); #endif return err; } /* *----------------------------------------------------------------------------- * * VixToolsPidRefersToThisProcess -- * * Determines if the given pid refers to the current process, in * that if it passed to the appropriate OS-specific process killing * function, will this process get killed. * * Return value: * TRUE if killing pid kills us, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool VixToolsPidRefersToThisProcess(ProcMgr_Pid pid) // IN { #ifdef _WIN32 return (GetCurrentProcessId() == pid); #else /* * POSIX is complicated. Pid could refer to this process directly, * be 0 which kills all processes in this process's group, be -1 * which kill everything to which it can send a signal, or be -1 times * the process group ID of this process. */ return ((getpid() == pid) || (0 == pid) || (-1 == pid) || ((pid < -1) && (getpgrp() == (pid * -1)))); #endif } /* *----------------------------------------------------------------------------- * * VixToolsCheckIfVixCommandEnabled -- * * Checks to see if the opcode has been disabled via the tools * configuration. * * This does not affect VIX_COMMAND_GET_TOOLS_STATE; that always * needs to work. * * Many non-VMODL APIs do not have an API specific option; those * are only affected by the global setting. * * Return value: * TRUE if enabled, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool VixToolsCheckIfVixCommandEnabled(int opcode, // IN GKeyFile *confDictRef) // IN { Bool enabled = TRUE; switch (opcode) { /* * We always let this through, since its needed to do basic * init work. */ case VIX_COMMAND_GET_TOOLS_STATE: enabled = TRUE; break; case VIX_COMMAND_LIST_PROCESSES: case VIX_COMMAND_LIST_PROCESSES_EX: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_LIST_PROCESSES_NAME); break; case VIX_COMMAND_LIST_FILES: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_LIST_FILES_NAME); break; case VIX_COMMAND_DELETE_GUEST_FILE: case VIX_COMMAND_DELETE_GUEST_FILE_EX: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_DELETE_FILE_NAME); break; case VIX_COMMAND_DELETE_GUEST_DIRECTORY: case VIX_COMMAND_DELETE_GUEST_EMPTY_DIRECTORY: case VIX_COMMAND_DELETE_GUEST_DIRECTORY_EX: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_DELETE_DIRECTORY_NAME); break; case VIX_COMMAND_KILL_PROCESS: case VIX_COMMAND_TERMINATE_PROCESS: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_TERMINATE_PROCESS_NAME); break; case VIX_COMMAND_CREATE_DIRECTORY: case VIX_COMMAND_CREATE_DIRECTORY_EX: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_MAKE_DIRECTORY_NAME); break; case VIX_COMMAND_MOVE_GUEST_FILE: case VIX_COMMAND_MOVE_GUEST_FILE_EX: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_MOVE_FILE_NAME); break; case VIX_COMMAND_MOVE_GUEST_DIRECTORY: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_MOVE_DIRECTORY_NAME); break; case VIX_COMMAND_START_PROGRAM: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_START_PROGRAM_NAME); break; case VIX_COMMAND_CREATE_TEMPORARY_FILE: case VIX_COMMAND_CREATE_TEMPORARY_FILE_EX: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_CREATE_TMP_FILE_NAME); break; case VIX_COMMAND_CREATE_TEMPORARY_DIRECTORY: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_CREATE_TMP_DIRECTORY_NAME); break; case VIX_COMMAND_READ_ENV_VARIABLES: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_READ_ENV_VARS_NAME); break; case VIX_COMMAND_SET_GUEST_FILE_ATTRIBUTES: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_CHANGE_FILE_ATTRS_NAME); break; case VIX_COMMAND_INITIATE_FILE_TRANSFER_FROM_GUEST: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_INITIATE_FILE_TRANSFER_FROM_GUEST_NAME); break; case VIX_COMMAND_INITIATE_FILE_TRANSFER_TO_GUEST: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_INITIATE_FILE_TRANSFER_TO_GUEST_NAME); break; case VIX_COMMAND_VALIDATE_CREDENTIALS: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_VALIDATE_CREDENTIALS_NAME); break; case VIX_COMMAND_ACQUIRE_CREDENTIALS: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_ACQUIRE_CREDENTIALS_NAME); break; case VIX_COMMAND_RELEASE_CREDENTIALS: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_RELEASE_CREDENTIALS_NAME); break; case VIX_COMMAND_ADD_AUTH_ALIAS: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_ADD_GUEST_ALIAS_NAME); break; case VIX_COMMAND_REMOVE_AUTH_ALIAS: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_REMOVE_GUEST_ALIAS_NAME); break; case VIX_COMMAND_LIST_AUTH_PROVIDER_ALIASES: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_LIST_GUEST_ALIASES_NAME); break; case VIX_COMMAND_LIST_AUTH_MAPPED_ALIASES: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_LIST_GUEST_MAPPED_ALIASES_NAME); break; case VIX_COMMAND_CREATE_REGISTRY_KEY: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_CREATE_REGISTRY_KEY_NAME); break; case VIX_COMMAND_LIST_REGISTRY_KEYS: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_LIST_REGISTRY_KEYS_NAME); break; case VIX_COMMAND_DELETE_REGISTRY_KEY: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_DELETE_REGISTRY_KEY_NAME); break; case VIX_COMMAND_SET_REGISTRY_VALUE: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_SET_REGISTRY_VALUE_NAME); break; case VIX_COMMAND_LIST_REGISTRY_VALUES: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_LIST_REGISTRY_VALUES_NAME); break; case VIX_COMMAND_DELETE_REGISTRY_VALUE: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, VIX_TOOLS_CONFIG_API_DELETE_REGISTRY_VALUE_NAME); break; /* * None of these opcode have a matching config entry (yet), * so they can all share. */ case VIX_COMMAND_CHECK_USER_ACCOUNT: case VIX_COMMAND_LOGOUT_IN_GUEST: case VIX_COMMAND_GUEST_FILE_EXISTS: case VIX_COMMAND_DIRECTORY_EXISTS: case VIX_COMMAND_GET_FILE_INFO: case VIX_COMMAND_LIST_FILESYSTEMS: case VIX_COMMAND_READ_VARIABLE: case VIX_COMMAND_WRITE_VARIABLE: case VIX_COMMAND_GET_GUEST_NETWORKING_CONFIG: case VIX_COMMAND_SET_GUEST_NETWORKING_CONFIG: case VIX_COMMAND_REGISTRY_KEY_EXISTS: case VIX_COMMAND_READ_REGISTRY: case VIX_COMMAND_WRITE_REGISTRY: case VIX_COMMAND_DELETE_GUEST_REGISTRY_KEY: /* * These may want to use the VMODL API name that most closely * matches, but for now, leave them alone. */ case VIX_COMMAND_RUN_SCRIPT_IN_GUEST: case VIX_COMMAND_RUN_PROGRAM: case VIX_COMMAND_LIST_DIRECTORY: case VMXI_HGFS_SEND_PACKET_COMMAND: default: enabled = !VixToolsGetAPIDisabledFromConf(confDictRef, NULL); break; } return enabled; } /* *----------------------------------------------------------------------------- * * VixTools_ProcessVixCommand -- * * * Return value: * VIX_OK on success * VixError on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixTools_ProcessVixCommand(VixCommandRequestHeader *requestMsg, // IN char *requestName, // IN size_t maxResultBufferSize, // IN GKeyFile *confDictRef, // IN GMainLoop *eventQueue, // IN char **resultBuffer, // OUT size_t *resultLen, // OUT Bool *deleteResultBufferResult) // OUT { VixError err = VIX_OK; char *resultValue = NULL; size_t resultValueLength = 0; Bool mustSetResultValueLength = TRUE; Bool deleteResultValue = FALSE; if (NULL != resultBuffer) { *resultBuffer = NULL; } if (NULL != resultLen) { *resultLen = 0; } if (NULL != deleteResultBufferResult) { *deleteResultBufferResult = FALSE; } Debug("%s: command %d\n", __FUNCTION__, requestMsg->opCode); if (!VixToolsCheckIfVixCommandEnabled(requestMsg->opCode, confDictRef)) { err = VIX_E_OPERATION_DISABLED; Debug("%s: command %d disabled by configuration\n", __FUNCTION__, requestMsg->opCode); goto abort; } switch (requestMsg->opCode) { //////////////////////////////////// case VIX_COMMAND_CHECK_USER_ACCOUNT: case VIX_COMMAND_LOGOUT_IN_GUEST: err = VixToolsCheckUserAccount(requestMsg); break; //////////////////////////////////// case VIX_COMMAND_GET_TOOLS_STATE: err = VixTools_GetToolsPropertiesImpl(confDictRef, &resultValue, &resultValueLength); if (VIX_FAILED(err)) { /* * VixTools_GetToolsPropertiesImpl failed, so resultVal is still NULL, * so let it get replaced with the empty string at the abort label. */ goto abort; } /* * resultVal always points to something heap-allocated after this point */ deleteResultValue = TRUE; err = VixTools_Base64EncodeBuffer(&resultValue, &resultValueLength); mustSetResultValueLength = FALSE; break; //////////////////////////////////// case VIX_COMMAND_LIST_PROCESSES: err = VixToolsListProcesses(requestMsg, maxResultBufferSize, &resultValue); // resultValue is static. Do not free it. break; //////////////////////////////////// case VIX_COMMAND_LIST_PROCESSES_EX: err = VixToolsListProcessesEx(requestMsg, maxResultBufferSize, eventQueue, &resultValue); deleteResultValue = TRUE; break; //////////////////////////////////// case VIX_COMMAND_LIST_DIRECTORY: err = VixToolsListDirectory(requestMsg, maxResultBufferSize, &resultValue); deleteResultValue = TRUE; break; //////////////////////////////////// case VIX_COMMAND_LIST_FILES: err = VixToolsListFiles(requestMsg, maxResultBufferSize, &resultValue); deleteResultValue = TRUE; break; //////////////////////////////////// case VIX_COMMAND_DELETE_GUEST_FILE: case VIX_COMMAND_DELETE_GUEST_FILE_EX: case VIX_COMMAND_DELETE_GUEST_REGISTRY_KEY: case VIX_COMMAND_DELETE_GUEST_DIRECTORY: case VIX_COMMAND_DELETE_GUEST_EMPTY_DIRECTORY: err = VixToolsDeleteObject(requestMsg); break; //////////////////////////////////// case VIX_COMMAND_DELETE_GUEST_DIRECTORY_EX: err = VixToolsDeleteDirectory(requestMsg); break; //////////////////////////////////// case VIX_COMMAND_REGISTRY_KEY_EXISTS: case VIX_COMMAND_GUEST_FILE_EXISTS: case VIX_COMMAND_DIRECTORY_EXISTS: err = VixToolsObjectExists(requestMsg, &resultValue); // resultValue is static. Do not free it. break; //////////////////////////////////// case VIX_COMMAND_READ_REGISTRY: err = VixToolsReadRegistry(requestMsg, &resultValue); deleteResultValue = TRUE; break; //////////////////////////////////// case VIX_COMMAND_WRITE_REGISTRY: err = VixToolsWriteRegistry(requestMsg); break; //////////////////////////////////// case VIX_COMMAND_KILL_PROCESS: case VIX_COMMAND_TERMINATE_PROCESS: err = VixToolsKillProcess(requestMsg); break; //////////////////////////////////// case VIX_COMMAND_CREATE_DIRECTORY: case VIX_COMMAND_CREATE_DIRECTORY_EX: err = VixToolsCreateDirectory(requestMsg); break; //////////////////////////////////// case VIX_COMMAND_MOVE_GUEST_FILE: case VIX_COMMAND_MOVE_GUEST_FILE_EX: case VIX_COMMAND_MOVE_GUEST_DIRECTORY: err = VixToolsMoveObject(requestMsg); break; //////////////////////////////////// case VIX_COMMAND_RUN_SCRIPT_IN_GUEST: err = VixToolsRunScript(requestMsg, requestName, eventQueue, &resultValue); // resultValue is static. Do not free it. break; //////////////////////////////////// case VIX_COMMAND_RUN_PROGRAM: err = VixTools_RunProgram(requestMsg, requestName, eventQueue, &resultValue); // resultValue is static. Do not free it. break; //////////////////////////////////// case VIX_COMMAND_START_PROGRAM: err = VixTools_StartProgram(requestMsg, requestName, eventQueue, &resultValue); // resultValue is static. Do not free it. break; //////////////////////////////////// case VIX_COMMAND_CREATE_TEMPORARY_FILE: case VIX_COMMAND_CREATE_TEMPORARY_FILE_EX: case VIX_COMMAND_CREATE_TEMPORARY_DIRECTORY: err = VixToolsCreateTempFile(requestMsg, &resultValue); deleteResultValue = TRUE; break; /////////////////////////////////// case VIX_COMMAND_READ_VARIABLE: err = VixToolsReadVariable(requestMsg, &resultValue); deleteResultValue = TRUE; break; /////////////////////////////////// case VIX_COMMAND_READ_ENV_VARIABLES: err = VixToolsReadEnvVariables(requestMsg, &resultValue); deleteResultValue = TRUE; break; /////////////////////////////////// case VIX_COMMAND_WRITE_VARIABLE: err = VixToolsWriteVariable(requestMsg); break; /////////////////////////////////// case VIX_COMMAND_GET_FILE_INFO: err = VixToolsGetFileInfo(requestMsg, &resultValue); deleteResultValue = TRUE; break; /////////////////////////////////// case VIX_COMMAND_SET_GUEST_FILE_ATTRIBUTES: err = VixToolsSetFileAttributes(requestMsg); break; /////////////////////////////////// case VMXI_HGFS_SEND_PACKET_COMMAND: err = VixToolsProcessHgfsPacket((VixCommandHgfsSendPacket *) requestMsg, eventQueue, &resultValue, &resultValueLength); deleteResultValue = FALSE; // TRUE; mustSetResultValueLength = FALSE; break; #if defined(__linux__) || defined(_WIN32) //////////////////////////////////// case VIX_COMMAND_GET_GUEST_NETWORKING_CONFIG: err = VixToolsGetGuestNetworkingConfig(requestMsg, &resultValue, &resultValueLength); if (VIX_FAILED(err)) { /* * VixToolsGetGuestNetworkingConfig() failed, so resultVal is still NULL, * so let it get replaced with the empty string at the abort label. */ goto abort; } /* * resultVal always points to something heap-allocated after this point */ deleteResultValue = TRUE; mustSetResultValueLength = FALSE; break; #endif #if defined(_WIN32) //////////////////////////////////// case VIX_COMMAND_SET_GUEST_NETWORKING_CONFIG: err = VixToolsSetGuestNetworkingConfig(requestMsg); break; #endif //////////////////////////////////// case VIX_COMMAND_LIST_FILESYSTEMS: err = VixToolsListFileSystems(requestMsg, &resultValue); // resultValue is static. Do not free it. break; //////////////////////////////////// case VIX_COMMAND_INITIATE_FILE_TRANSFER_FROM_GUEST: err = VixToolsInitiateFileTransferFromGuest(requestMsg, &resultValue); deleteResultValue = TRUE; break; //////////////////////////////////// case VIX_COMMAND_INITIATE_FILE_TRANSFER_TO_GUEST: err = VixToolsInitiateFileTransferToGuest(requestMsg); break; //////////////////////////////////// case VIX_COMMAND_VALIDATE_CREDENTIALS: err = VixToolsValidateCredentials(requestMsg); break; //////////////////////////////////// case VIX_COMMAND_ACQUIRE_CREDENTIALS: err = VixToolsAcquireCredentials(requestMsg, eventQueue, &resultValue); // resultValue is static. Do not free it. break; //////////////////////////////////// case VIX_COMMAND_RELEASE_CREDENTIALS: err = VixToolsReleaseCredentials(requestMsg); break; //////////////////////////////////// case VIX_COMMAND_WAIT_FOR_TOOLS: /* * Older VMX's can send this. We don't want to do anything, but * we also don't want it to be treated as unknown and return * VIX_E_UNRECOGNIZED_COMMAND_IN_GUEST. */ break; case VIX_COMMAND_CAPTURE_SCREEN: /* * The VMX sends this through just to validate the auth info. * Just no-op it so we don't fall through to the 'default'. */ break; #if SUPPORT_VGAUTH case VIX_COMMAND_ADD_AUTH_ALIAS: err = VixToolsAddAuthAlias(requestMsg); break; case VIX_COMMAND_REMOVE_AUTH_ALIAS: err = VixToolsRemoveAuthAlias(requestMsg); break; case VIX_COMMAND_LIST_AUTH_PROVIDER_ALIASES: err = VixToolsListAuthAliases(requestMsg, maxResultBufferSize, &resultValue); // resultValue is static. Do not free it. break; case VIX_COMMAND_LIST_AUTH_MAPPED_ALIASES: err = VixToolsListMappedAliases(requestMsg, maxResultBufferSize, &resultValue); // resultValue is static. Do not free it. break; #endif //////////////////////////////////// case VIX_COMMAND_CREATE_REGISTRY_KEY: err = VixToolsCreateRegKey(requestMsg); break; //////////////////////////////////// case VIX_COMMAND_LIST_REGISTRY_KEYS: err = VixToolsListRegKeys(requestMsg, maxResultBufferSize, eventQueue, &resultValue); deleteResultValue = TRUE; break; //////////////////////////////////// case VIX_COMMAND_DELETE_REGISTRY_KEY: err = VixToolsDeleteRegKey(requestMsg); break; //////////////////////////////////// case VIX_COMMAND_SET_REGISTRY_VALUE: err = VixToolsSetRegValue(requestMsg); break; //////////////////////////////////// case VIX_COMMAND_LIST_REGISTRY_VALUES: err = VixToolsListRegValues(requestMsg, maxResultBufferSize, eventQueue, &resultValue); deleteResultValue = TRUE; break; //////////////////////////////////// case VIX_COMMAND_DELETE_REGISTRY_VALUE: err = VixToolsDeleteRegValue(requestMsg); break; //////////////////////////////////// default: /* * If the opcode is not recognized, tools might be old and the * VIX client might be sending new opcodes. In such case, * we should return VIX_E_UNRECOGNIZED_COMMAND_IN_GUEST. */ err = VIX_E_UNRECOGNIZED_COMMAND_IN_GUEST; break; } // switch (requestMsg->opCode) abort: if (NULL == resultValue) { // Prevent "(null)" from getting sprintf'ed into the result buffer resultValue = ""; deleteResultValue = FALSE; } /* * Some commands return both a result and its length. Some return just * the result. Others return nothing at all. Previously, we assumed that * all results are based on plain-text, but this is incorrect (for example, * VixToolsProcessHgfsPacket will return a binary packet). * * Instead, let's assume that commands returning without a length are based * on plain-text. This seems reasonable, because any binary result must * provide a length if one is to make sense of it. */ if (mustSetResultValueLength) { resultValueLength = strlen(resultValue); } if (NULL != resultBuffer) { *resultBuffer = resultValue; } if (NULL != resultLen) { *resultLen = resultValueLength; } if (NULL != deleteResultBufferResult) { *deleteResultBufferResult = deleteResultValue; } /* * Remaps specific errors for backward compatibility purposes. */ err = VixToolsRewriteError(requestMsg->opCode, err); return(err); } // VixTools_ProcessVixCommand /* *----------------------------------------------------------------------------- * * VixToolsRewriteError -- * * Rewrites the error if necessary. * * Some errors returned by tools need to be changed so * that error code consistency with old VIX is maintained. * * So specific errors from specific operations are rewritten here. * * Results: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixToolsRewriteError(uint32 opCode, // IN VixError origError) // IN { VixError newError = origError; switch (opCode) { /* * This should include all non-VI guest operations. */ case VIX_COMMAND_CHECK_USER_ACCOUNT: case VIX_COMMAND_LOGOUT_IN_GUEST: case VIX_COMMAND_GET_TOOLS_STATE: case VIX_COMMAND_LIST_PROCESSES: case VIX_COMMAND_LIST_DIRECTORY: case VIX_COMMAND_DELETE_GUEST_FILE: case VIX_COMMAND_DELETE_GUEST_REGISTRY_KEY: case VIX_COMMAND_DELETE_GUEST_DIRECTORY: case VIX_COMMAND_DELETE_GUEST_EMPTY_DIRECTORY: case VIX_COMMAND_REGISTRY_KEY_EXISTS: case VIX_COMMAND_GUEST_FILE_EXISTS: case VIX_COMMAND_DIRECTORY_EXISTS: case VIX_COMMAND_READ_REGISTRY: case VIX_COMMAND_WRITE_REGISTRY: case VIX_COMMAND_KILL_PROCESS: case VIX_COMMAND_CREATE_DIRECTORY: case VIX_COMMAND_MOVE_GUEST_FILE: case VIX_COMMAND_RUN_SCRIPT_IN_GUEST: case VIX_COMMAND_RUN_PROGRAM: case VIX_COMMAND_CREATE_TEMPORARY_FILE: case VIX_COMMAND_READ_VARIABLE: case VIX_COMMAND_WRITE_VARIABLE: case VIX_COMMAND_GET_FILE_INFO: case VMXI_HGFS_SEND_PACKET_COMMAND: case VIX_COMMAND_GET_GUEST_NETWORKING_CONFIG: case VIX_COMMAND_LIST_FILESYSTEMS: case VIX_COMMAND_WAIT_FOR_TOOLS: case VIX_COMMAND_CAPTURE_SCREEN: ASSERT(VIX_ERROR_CODE(origError) == origError); switch (origError) { case VIX_E_INVALID_LOGIN_CREDENTIALS: newError = VIX_E_GUEST_USER_PERMISSIONS; break; } break; } return newError; } /* *----------------------------------------------------------------------------- * * VixTools_GetAdditionalError -- * * Gets the vix extra/additional error if any. * * Some errors returned by tools may have extra error in * the higher order 32 bits. We need to pass that back. * * Results: * uint32 * * Side effects: * None * *----------------------------------------------------------------------------- */ uint32 VixTools_GetAdditionalError(uint32 opCode, // IN VixError error) // IN { uint32 err; switch (opCode) { case VIX_COMMAND_CREATE_REGISTRY_KEY: case VIX_COMMAND_LIST_REGISTRY_KEYS: case VIX_COMMAND_DELETE_REGISTRY_KEY: case VIX_COMMAND_SET_REGISTRY_VALUE: case VIX_COMMAND_LIST_REGISTRY_VALUES: case VIX_COMMAND_DELETE_REGISTRY_VALUE: err = VIX_ERROR_EXTRA_ERROR(error); break; default: err = Err_Errno(); } return err; } /* *----------------------------------------------------------------------------- * * VixTools_Base64EncodeBuffer -- * * Return value: * VIX_OK on success * VixError on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixTools_Base64EncodeBuffer(char **resultValuePtr, // IN/OUT size_t *resultValLengthPtr) // IN/OUT { VixError err = VIX_OK; char *base64Buffer = NULL; size_t base64BufferLength = 0; Bool success = FALSE; ASSERT(resultValuePtr != NULL); ASSERT(*resultValuePtr != NULL); ASSERT(resultValLengthPtr != NULL); base64BufferLength = Base64_EncodedLength(*resultValuePtr, *resultValLengthPtr) + 1; base64Buffer = Util_SafeMalloc(base64BufferLength); success = Base64_Encode(*resultValuePtr, *resultValLengthPtr, base64Buffer, base64BufferLength, &base64BufferLength); if (!success) { (*resultValuePtr)[0] = 0; free(base64Buffer); base64Buffer = NULL; err = VIX_E_FAIL; goto abort; } base64Buffer[base64BufferLength] = 0; free(*resultValuePtr); *resultValuePtr = base64Buffer; *resultValLengthPtr = base64BufferLength; abort: return err; } // VixTools_Base64EncodeBuffer /* *----------------------------------------------------------------------------- * * VixToolsEnableDHCPOnPrimary -- * * Enable DHCP on primary NIC. A primary NIC is the * first interface you get using ipconfig. You can change the order * of NIC cards on a computer via Windows GUI. * * Results: * S_OK on success. COM error codes on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ #if defined(_WIN32) HRESULT VixToolsEnableDHCPOnPrimary(void) { HRESULT ret; GuestNic *primaryNic; primaryNic = NetUtil_GetPrimaryNic(); if (NULL == primaryNic) { return HRESULT_FROM_WIN32(GetLastError()); } ret = WMI_EnableDHCP(primaryNic->macAddress); VMX_XDR_FREE(xdr_GuestNic, primaryNic); free(primaryNic); return ret; } /* *----------------------------------------------------------------------------- * * VixToolsEnableStaticOnPrimary -- * * Set the IP address and/or subnet mask of the primary NIC. A primary NIC * is the first interface you get using ipconfig. You can change the order * of NIC cards on a computer via Windows GUI. * * Results: * S_OK on success. COM error codes on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ HRESULT VixToolsEnableStaticOnPrimary(const char *ipAddr, // IN const char *subnetMask) // IN { HRESULT ret; GuestNic *primaryNic; VmIpAddress *primaryIp; char actualIpAddress[IP_ADDR_SIZE]; char actualSubnetMask[IP_ADDR_SIZE]; if ((NULL == ipAddr) || (NULL == subnetMask)) { return E_INVALIDARG; } actualIpAddress[0] = '\0'; actualSubnetMask[0] = '\0'; primaryNic = NetUtil_GetPrimaryNic(); if (NULL == primaryNic) { return HRESULT_FROM_WIN32(GetLastError()); } /* * Set IP address if client provides it. */ primaryIp = &primaryNic->ips.ips_val[0]; if ('\0' != ipAddr[0]) { Str_Strcpy(actualIpAddress, ipAddr, sizeof actualIpAddress); } else { Str_Strcpy(actualIpAddress, primaryIp->ipAddress, sizeof actualIpAddress); } /* * Set subnet mask if client provides it. */ if ('\0' != subnetMask[0]) { Str_Strcpy(actualSubnetMask, subnetMask, sizeof actualSubnetMask); } else { Str_Strcpy(actualSubnetMask, primaryIp->subnetMask, sizeof actualSubnetMask); } ret = WMI_EnableStatic(primaryNic->macAddress, actualIpAddress, actualSubnetMask); VMX_XDR_FREE(xdr_GuestNic, primaryNic); free(primaryNic); return ret; } #endif /* *----------------------------------------------------------------------------- * * VixToolsEscapeXMLString -- * * Escapes a string to be included in VMAutomation XML. * * Results: * Pointer to a heap-allocated escaped string. * * Side effects: * None * *----------------------------------------------------------------------------- */ char * VixToolsEscapeXMLString(const char *str) // IN { static const int bytesToEscape[] = { 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // '%' 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, // '<' and '>' 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, 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, 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, 0, 0, 0, }; return Escape_Do(VIX_XML_ESCAPE_CHARACTER, bytesToEscape, str, strlen(str), NULL); } /* *----------------------------------------------------------------------------- * * VixToolsXMLStringEscapedLen -- * * Computes the length of the supplied string if it were escaped * (if escapeStr is TRUE), or the length of the string as is. * * Results: * The length. * * Side effects: * None * *----------------------------------------------------------------------------- */ static size_t VixToolsXMLStringEscapedLen(const char *str, // IN Bool escapeStr) // IN { if (escapeStr) { size_t totalLen = 0; while (TRUE) { size_t nextLen = strcspn(str, "<>%"); totalLen += nextLen; if ('\0' == str[nextLen]) { break; } /* * str[nextLen] is a character that needs to be escaped. Each * escapeStr that is escaped will take up 3 bytes (an escape * character and two hex digits) in the escaped string. */ totalLen += 3; str += nextLen + 1; } return totalLen; } else { return strlen(str); } } /* *----------------------------------------------------------------------------- * * GuestAuthEnabled -- * * Returns whether we use the guest auth library. * * Results: * TRUE if we do. FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool GuestAuthEnabled(void) { #if SUPPORT_VGAUTH return gSupportVGAuth; #else return FALSE; #endif } /* *----------------------------------------------------------------------------- * * GuestAuthPasswordAuthenticateImpersonate * * Do name-password authentication and impersonation using * the GuestAuth library. * * Results: * VIX_OK if successful.Other VixError code otherwise. * * Side effects: * Current process impersonates. * *----------------------------------------------------------------------------- */ VixError GuestAuthPasswordAuthenticateImpersonate( char const *obfuscatedNamePassword, // IN void **userToken) // OUT { #if SUPPORT_VGAUTH VixError err; char *username; char *password; VGAuthContext *ctx = NULL; VGAuthError vgErr; VGAuthUserHandle *newHandle = NULL; Debug(">%s\n", __FUNCTION__); err = VixMsg_DeObfuscateNamePassword(obfuscatedNamePassword, &username, &password); if (err != VIX_OK) { goto done; } err = VIX_E_INVALID_LOGIN_CREDENTIALS; vgErr = TheVGAuthContext(&ctx); if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); goto done; } vgErr = VGAuth_ValidateUsernamePassword(ctx, username, password, 0, NULL, &newHandle); if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); goto done; } vgErr = VGAuth_Impersonate(ctx, newHandle, 0, NULL); if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); goto done; } #ifdef _WIN32 // this is making a copy of the token, be sure to close it err = VGAuth_UserHandleAccessToken(ctx, newHandle, userToken); if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); goto done; } #endif currentUserHandle = newHandle; err = VIX_OK; done: Debug("<%s\n", __FUNCTION__); return err; #else return VIX_E_NOT_SUPPORTED; #endif } /* *----------------------------------------------------------------------------- * * GuestAuthSAMLAuthenticateAndImpersonate * * Do SAML bearer token authentication and impersonation using * the GuestAuth library. * * Results: * VIX_OK if successful. Other VixError code otherwise. * * Side effects: * Current process impersonates. * *----------------------------------------------------------------------------- */ VixError GuestAuthSAMLAuthenticateAndImpersonate( char const *obfuscatedNamePassword, // IN void **userToken) // OUT { #if SUPPORT_VGAUTH VixError err; char *token; char *username; VGAuthContext *ctx = NULL; VGAuthError vgErr; VGAuthUserHandle *newHandle = NULL; Debug(">%s\n", __FUNCTION__); err = VixMsg_DeObfuscateNamePassword(obfuscatedNamePassword, &token, &username); if (err != VIX_OK) { goto done; } err = VIX_E_INVALID_LOGIN_CREDENTIALS; vgErr = TheVGAuthContext(&ctx); if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); goto done; } vgErr = VGAuth_ValidateSamlBearerToken(ctx, token, username, 0, NULL, &newHandle); if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); goto done; } vgErr = VGAuth_Impersonate(ctx, newHandle, 0, NULL); if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); goto done; } #ifdef _WIN32 // this is making a copy of the token, be sure to close it err = VGAuth_UserHandleAccessToken(ctx, newHandle, userToken); if (VGAUTH_FAILED(vgErr)) { err = VixToolsTranslateVGAuthError(vgErr); goto done; } #endif currentUserHandle = newHandle; err = VIX_OK; done: Debug("<%s\n", __FUNCTION__); return err; #else return VIX_E_NOT_SUPPORTED; #endif } /* *----------------------------------------------------------------------------- * * GuestAuthUnimpersonate * * End the current impersonation using the VGAuth library. * * Results: * None * * Side effects: * Current process un-impersonates. * *----------------------------------------------------------------------------- */ void GuestAuthUnimpersonate(void) { #if SUPPORT_VGAUTH VGAuthContext *ctx; VGAuthError vgErr = TheVGAuthContext(&ctx); ASSERT(vgErr == VGAUTH_E_OK); vgErr = VGAuth_EndImpersonation(ctx); ASSERT(vgErr == VGAUTH_E_OK); #else ASSERT(0); #endif } #if SUPPORT_VGAUTH /* *----------------------------------------------------------------------------- * * QueryVGAuthConfig * * Check the tools configuration to see if VGAuth should be used. * * Results: * TRUE if vgauth should be used, FALSE if not. * * Side effects: * None * *----------------------------------------------------------------------------- */ static gboolean QueryVGAuthConfig(GKeyFile *confDictRef) // IN { gboolean useVGAuth; gboolean retVal = USE_VGAUTH_DEFAULT; GError *gErr = NULL; if (confDictRef != NULL) { useVGAuth = g_key_file_get_boolean(confDictRef, VIX_TOOLS_CONFIG_API_GROUPNAME, VIXTOOLS_CONFIG_USE_VGAUTH_NAME, &gErr); /* * g_key_file_get_boolean() will return FALSE and set an error * if the value isn't in config, so use the default in that * case. */ if (!useVGAuth && (NULL != gErr)) { g_error_free(gErr); retVal = USE_VGAUTH_DEFAULT; } else { retVal = useVGAuth; } } Debug("%s: vgauth usage is: %d\n", __FUNCTION__, retVal); return retVal; } /* *----------------------------------------------------------------------------- * * TheVGAuthContext * * Get the global VGAuthContext object. * * Lazily create the global VGAuthContext when needed. * We need a single shared context to handle authentication in order to * properly share the SSPI handshake state(s). * * Creating the global context may also cause the VGAuth Service to * be started. * * This context should only be used when not impersonating, since it * will be running over the SUPER_USER connection and can cause * security issues if used when impersonating. * * * Results: * VGAUTH_E_OK if successful, the global context object is returned in * the OUT parameter ctx. * * Side effects: * None * *----------------------------------------------------------------------------- */ VGAuthError TheVGAuthContext(VGAuthContext **ctx) // OUT { static VGAuthContext *vgaCtx = NULL; VGAuthError vgaCode = VGAUTH_E_OK; /* * XXX This needs to handle errors better -- if the service gets * reset, the context will point to junk and anything using it will * fail. * * Maybe add a no-op API here to poke it? Or make the underlying * VGAuth code smarter. */ if (vgaCtx == NULL) { vgaCode = VGAuth_Init(VMTOOLSD_APP_NAME, 0, NULL, &vgaCtx); } *ctx = vgaCtx; return vgaCode; } #endif open-vm-tools-9.4.0-1280544/services/plugins/vix/Makefile.in0000644765153500003110000006252512220061625021625 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = services/plugins/vix DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(plugin_LTLIBRARIES) libvix_la_DEPENDENCIES = $(top_builddir)/lib/auth/libAuth.la \ $(top_builddir)/lib/foundryMsg/libFoundryMsg.la \ $(top_builddir)/lib/impersonate/libImpersonate.la am_libvix_la_OBJECTS = libvix_la-foundryToolsDaemon.lo \ libvix_la-vixPlugin.lo libvix_la-vixTools.lo \ libvix_la-vixToolsEnvVars.lo libvix_la_OBJECTS = $(am_libvix_la_OBJECTS) libvix_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libvix_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libvix_la_SOURCES) DIST_SOURCES = $(libvix_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ plugindir = @COMMON_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libvix.la libvix_la_CPPFLAGS = @PLUGIN_CPPFLAGS@ libvix_la_LDFLAGS = @PLUGIN_LDFLAGS@ libvix_la_LIBADD = @VIX_LIBADD@ @VMTOOLS_LIBS@ @HGFS_LIBS@ \ $(top_builddir)/lib/auth/libAuth.la \ $(top_builddir)/lib/foundryMsg/libFoundryMsg.la \ $(top_builddir)/lib/impersonate/libImpersonate.la libvix_la_SOURCES = foundryToolsDaemon.c vixPlugin.c vixTools.c \ vixToolsEnvVars.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu services/plugins/vix/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu services/plugins/vix/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ } uninstall-pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ done clean-pluginLTLIBRARIES: -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) @list='$(plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libvix.la: $(libvix_la_OBJECTS) $(libvix_la_DEPENDENCIES) $(EXTRA_libvix_la_DEPENDENCIES) $(libvix_la_LINK) -rpath $(plugindir) $(libvix_la_OBJECTS) $(libvix_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvix_la-foundryToolsDaemon.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvix_la-vixPlugin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvix_la-vixTools.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvix_la-vixToolsEnvVars.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libvix_la-foundryToolsDaemon.lo: foundryToolsDaemon.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvix_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libvix_la-foundryToolsDaemon.lo -MD -MP -MF $(DEPDIR)/libvix_la-foundryToolsDaemon.Tpo -c -o libvix_la-foundryToolsDaemon.lo `test -f 'foundryToolsDaemon.c' || echo '$(srcdir)/'`foundryToolsDaemon.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libvix_la-foundryToolsDaemon.Tpo $(DEPDIR)/libvix_la-foundryToolsDaemon.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='foundryToolsDaemon.c' object='libvix_la-foundryToolsDaemon.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvix_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libvix_la-foundryToolsDaemon.lo `test -f 'foundryToolsDaemon.c' || echo '$(srcdir)/'`foundryToolsDaemon.c libvix_la-vixPlugin.lo: vixPlugin.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvix_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libvix_la-vixPlugin.lo -MD -MP -MF $(DEPDIR)/libvix_la-vixPlugin.Tpo -c -o libvix_la-vixPlugin.lo `test -f 'vixPlugin.c' || echo '$(srcdir)/'`vixPlugin.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libvix_la-vixPlugin.Tpo $(DEPDIR)/libvix_la-vixPlugin.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vixPlugin.c' object='libvix_la-vixPlugin.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvix_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libvix_la-vixPlugin.lo `test -f 'vixPlugin.c' || echo '$(srcdir)/'`vixPlugin.c libvix_la-vixTools.lo: vixTools.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvix_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libvix_la-vixTools.lo -MD -MP -MF $(DEPDIR)/libvix_la-vixTools.Tpo -c -o libvix_la-vixTools.lo `test -f 'vixTools.c' || echo '$(srcdir)/'`vixTools.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libvix_la-vixTools.Tpo $(DEPDIR)/libvix_la-vixTools.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vixTools.c' object='libvix_la-vixTools.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvix_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libvix_la-vixTools.lo `test -f 'vixTools.c' || echo '$(srcdir)/'`vixTools.c libvix_la-vixToolsEnvVars.lo: vixToolsEnvVars.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvix_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libvix_la-vixToolsEnvVars.lo -MD -MP -MF $(DEPDIR)/libvix_la-vixToolsEnvVars.Tpo -c -o libvix_la-vixToolsEnvVars.lo `test -f 'vixToolsEnvVars.c' || echo '$(srcdir)/'`vixToolsEnvVars.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libvix_la-vixToolsEnvVars.Tpo $(DEPDIR)/libvix_la-vixToolsEnvVars.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vixToolsEnvVars.c' object='libvix_la-vixToolsEnvVars.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvix_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libvix_la-vixToolsEnvVars.lo `test -f 'vixToolsEnvVars.c' || echo '$(srcdir)/'`vixToolsEnvVars.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(plugindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pluginLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pluginLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-pluginLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-pluginLTLIBRARIES install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-pluginLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/services/plugins/vix/foundryToolsDaemon.c0000644765153500003110000010472612220061556023562 0ustar dtormts/********************************************************* * Copyright (C) 2003 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * foundryToolsDaemon.c -- * * VIX-specific TCLO cmds that are called through the backdoor */ #include #include #include #include #include #if defined(linux) #include #include #include #endif #ifdef _WIN32 #include #else #include #include #endif #ifdef _MSC_VER # include # include # include # include "win32u.h" #elif _WIN32 # include "win95.h" #endif #include "vmware.h" #include "procMgr.h" #include "vm_version.h" #include "message.h" #include "vixPluginInt.h" #include "vmware/tools/utils.h" #include "util.h" #include "strutil.h" #include "str.h" #include "file.h" #include "err.h" #include "hostinfo.h" #include "guest_os.h" #include "guest_msg_def.h" #include "conf.h" #include "vixCommands.h" #include "base64.h" #include "syncDriver.h" #include "hgfsServerManager.h" #include "hgfs.h" #include "system.h" #include "codeset.h" #include "vixToolsInt.h" #if defined(linux) #include "hgfsDevLinux.h" #endif /* Only Win32, Linux, Solaris and FreeBSD use impersonation functions. */ #if !defined(__APPLE__) #include "impersonate.h" #endif #include "vixOpenSource.h" #define MAX64_DECIMAL_DIGITS 20 /* 2^64 = 18,446,744,073,709,551,616 */ #if defined(linux) || defined(_WIN32) # if defined(_WIN32) # define DECLARE_SYNCDRIVER_ERROR(name) DWORD name = ERROR_SUCCESS # define SYNCDRIVERERROR ERROR_GEN_FAILURE # else # define DECLARE_SYNCDRIVER_ERROR(name) int name = 0 # define SYNCDRIVERERROR errno # endif static SyncDriverHandle gSyncDriverHandle = SYNCDRIVER_INVALID_HANDLE; static Bool ToolsDaemonSyncDriverThawCallback(void *clientData); #endif static char *ToolsDaemonTcloGetQuotedString(const char *args, const char **endOfArg); static VixError ToolsDaemonTcloGetEncodedQuotedString(const char *args, const char **endOfArg, char **result); gboolean ToolsDaemonTcloReceiveVixCommand(RpcInData *data); static HgfsServerMgrData gFoundryHgfsBkdrConn; gboolean ToolsDaemonHgfsImpersonated(RpcInData *data); #if defined(linux) || defined(_WIN32) gboolean ToolsDaemonTcloSyncDriverFreeze(RpcInData *data); gboolean ToolsDaemonTcloSyncDriverThaw(RpcInData *data); #endif gboolean ToolsDaemonTcloMountHGFS(RpcInData *data); void ToolsDaemonTcloReportProgramCompleted(const char *requestName, VixError err, int exitCode, int64 pid, void *clientData); /* * These constants are a bad hack. I really should generate the result * strings twice, once to compute the length and then allocate the buffer, * and a second time to write the buffer. */ #define DEFAULT_RESULT_MSG_MAX_LENGTH 1024 static Bool thisProcessRunsAsRoot = FALSE; /* *----------------------------------------------------------------------------- * * FoundryToolsDaemonRunProgram -- * * Run a named program on the guest. * * Return value: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ gboolean FoundryToolsDaemonRunProgram(RpcInData *data) // IN { VixError err = VIX_OK; char *requestName = NULL; char *commandLine = NULL; char *commandLineArgs = NULL; char *credentialTypeStr = NULL; char *obfuscatedNamePassword = NULL; char *directoryPath = NULL; char *environmentVariables = NULL; static char resultBuffer[DEFAULT_RESULT_MSG_MAX_LENGTH]; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; ProcMgr_Pid pid; GMainLoop *eventQueue = ((ToolsAppCtx *)data->appCtx)->mainLoop; /* * Parse the arguments. Some of these are optional, so they * may be NULL. */ requestName = ToolsDaemonTcloGetQuotedString(data->args, &data->args); err = ToolsDaemonTcloGetEncodedQuotedString(data->args, &data->args, &commandLine); if (err != VIX_OK) { goto abort; } err = ToolsDaemonTcloGetEncodedQuotedString(data->args, &data->args, &commandLineArgs); if (err != VIX_OK) { goto abort; } credentialTypeStr = ToolsDaemonTcloGetQuotedString(data->args, &data->args); obfuscatedNamePassword = ToolsDaemonTcloGetQuotedString(data->args, &data->args); directoryPath = ToolsDaemonTcloGetQuotedString(data->args, &data->args); environmentVariables = ToolsDaemonTcloGetQuotedString(data->args, &data->args); /* * Make sure we are passed the correct arguments. * Some of these arguments (like credentialTypeStr and obfuscatedNamePassword) are optional, * so they may be NULL. */ if ((NULL == requestName) || (NULL == commandLine)) { err = VIX_E_INVALID_ARG; goto abort; } if ((NULL != credentialTypeStr) && (*credentialTypeStr) && (thisProcessRunsAsRoot)) { impersonatingVMWareUser = VixToolsImpersonateUserImpl(credentialTypeStr, VIX_USER_CREDENTIAL_NONE, obfuscatedNamePassword, &userToken); if (!impersonatingVMWareUser) { err = VIX_E_GUEST_USER_PERMISSIONS; goto abort; } } err = VixToolsRunProgramImpl(requestName, commandLine, commandLineArgs, 0, userToken, eventQueue, (int64 *) &pid); abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); /* * All VMXI tools commands return results that start with a VMXI error * and a guest-OS-specific error. */ Str_Sprintf(resultBuffer, sizeof(resultBuffer), "%"FMT64"d %d %"FMT64"d", err, Err_Errno(), (int64) pid); RPCIN_SETRETVALS(data, resultBuffer, TRUE); /* * These were allocated by ToolsDaemonTcloGetQuotedString. */ free(requestName); free(commandLine); free(credentialTypeStr); free(obfuscatedNamePassword); free(directoryPath); free(environmentVariables); free(commandLineArgs); return TRUE; } // FoundryToolsDaemonRunProgram /* *----------------------------------------------------------------------------- * * FoundryToolsDaemonGetToolsProperties -- * * Get information about test features. * * Return value: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ gboolean FoundryToolsDaemonGetToolsProperties(RpcInData *data) // IN { VixError err = VIX_OK; int additionalError = 0; static char resultBuffer[DEFAULT_RESULT_MSG_MAX_LENGTH]; char *serializedBuffer = NULL; size_t serializedBufferLength = 0; char *base64Buffer = NULL; size_t base64BufferLength = 0; Bool success; char *returnBuffer = NULL; GKeyFile *confDictRef; /* * Collect some values about the host. */ confDictRef = data->clientData; err = VixTools_GetToolsPropertiesImpl(confDictRef, &serializedBuffer, &serializedBufferLength); if (VIX_OK == err) { base64BufferLength = Base64_EncodedLength(serializedBuffer, serializedBufferLength) + 1; base64Buffer = Util_SafeMalloc(base64BufferLength); success = Base64_Encode(serializedBuffer, serializedBufferLength, base64Buffer, base64BufferLength, &base64BufferLength); if (!success) { base64Buffer[0] = 0; err = VIX_E_FAIL; goto abort; } base64Buffer[base64BufferLength] = 0; } abort: returnBuffer = base64Buffer; if (NULL == base64Buffer) { returnBuffer = ""; } if (VIX_OK != err) { additionalError = Err_Errno(); } /* * All VMXI tools commands return results that start with a VMXI error * and a guest-OS-specific error. */ Str_Sprintf(resultBuffer, sizeof(resultBuffer), "%"FMT64"d %d %s", err, additionalError, returnBuffer); RPCIN_SETRETVALS(data, resultBuffer, TRUE); free(serializedBuffer); free(base64Buffer); return TRUE; } // FoundryToolsDaemonGetToolsProperties /** * Initializes internal state of the Foundry daemon. * * @param[in] ctx Application context. */ void FoundryToolsDaemon_Initialize(ToolsAppCtx *ctx) { thisProcessRunsAsRoot = (strcmp(ctx->name, VMTOOLS_GUEST_SERVICE) == 0); /* * TODO: Add the original/native environment (envp) to ToolsAppContext so * we can know what the environment variables were before the loader scripts * changed them. */ (void) VixTools_Initialize(thisProcessRunsAsRoot, #if defined(__FreeBSD__) ctx->envp, // envp #else NULL, // envp #endif ToolsDaemonTcloReportProgramCompleted, ctx); #if !defined(__APPLE__) if (thisProcessRunsAsRoot) { Impersonate_Init(); } #endif /* Register a straight through connection with the Hgfs server. */ HgfsServerManager_DataInit(&gFoundryHgfsBkdrConn, VIX_BACKDOORCOMMAND_SEND_HGFS_PACKET, NULL, // rpc - no rpc registered NULL); // rpc callback HgfsServerManager_Register(&gFoundryHgfsBkdrConn); } /** * Uninitializes internal state of the Foundry daemon. * * @param[in] ctx Application context. */ void FoundryToolsDaemon_Uninitialize(ToolsAppCtx *ctx) { HgfsServerManager_Unregister(&gFoundryHgfsBkdrConn); VixTools_Uninitialize(); } /* *----------------------------------------------------------------------------- * * ToolsDaemonTcloGetQuotedString -- * * Extract a quoted string from the middle of an argument string. * This is different than normal tokenizing in a few ways: * * Whitespace is a separator outside quotes, but not inside quotes. * * Quotes always come in pairs, so "" is am empty string. An empty * string may appear anywhere in the string, even at the end, so * a string that is "" contains 1 empty string, not 2. * * The string may use whitespace to separate the op-name from the params, * and then quoted params to skip whitespace inside a param. * * Return value: * Allocates the string. * * Side effects: * None * *----------------------------------------------------------------------------- */ static char * ToolsDaemonTcloGetQuotedString(const char *args, // IN const char **endOfArg) // OUT { char *resultStr = NULL; char *endStr; Debug(">ToolsDaemonTcloGetQuotedString\n"); while ((*args) && ('\"' != *args)) { args++; } if ('\"' == *args) { args++; } resultStr = Util_SafeStrdup(args); endStr = resultStr; while (*endStr) { if (('\\' == *endStr) && (*(endStr + 1))) { endStr += 2; } else if ('\"' == *endStr) { *endStr = 0; endStr++; break; } else { endStr++; } } if (NULL != endOfArg) { args += (endStr - resultStr); while (' ' == *args) { args++; } *endOfArg = args; } Debug("appCtx; GSource *timer; Debug(">ToolsDaemonTcloSyncDriverFreeze\n"); /* * Parse the arguments */ driveList = ToolsDaemonTcloGetQuotedString(data->args, &data->args); timeout = ToolsDaemonTcloGetQuotedString(data->args, &data->args); /* * Validate the arguments. */ if (NULL == driveList || NULL == timeout) { err = VIX_E_INVALID_ARG; Debug("ToolsDaemonTcloSyncDriverFreeze: Failed to get string args\n"); goto abort; } if (!StrUtil_StrToInt(&timeoutVal, timeout) || timeoutVal < 0) { Debug("ToolsDaemonTcloSyncDriverFreeze: Bad args, timeout '%s'\n", timeout); err = VIX_E_INVALID_ARG; goto abort; } Debug("SYNCDRIVE: Got request to freeze '%s', timeout %d\n", driveList, timeoutVal); /* Disallow multiple freeze calls. */ if (gSyncDriverHandle != SYNCDRIVER_INVALID_HANDLE) { err = VIX_E_OBJECT_IS_BUSY; goto abort; } /* Perform the actual freeze. */ if (!SyncDriver_Freeze(driveList, &gSyncDriverHandle) || SyncDriver_QueryStatus(gSyncDriverHandle, INFINITE) != SYNCDRIVER_IDLE) { Debug("ToolsDaemonTcloSyncDriverFreeze: Failed to Freeze drives '%s'\n", driveList); err = VIX_E_FAIL; sysError = SYNCDRIVERERROR; if (gSyncDriverHandle != SYNCDRIVER_INVALID_HANDLE) { SyncDriver_Thaw(gSyncDriverHandle); SyncDriver_CloseHandle(&gSyncDriverHandle); } goto abort; } /* Start the timer callback to automatically thaw. */ if (0 != timeoutVal) { Debug("ToolsDaemonTcloSyncDriverFreeze: Starting timer callback %d\n", timeoutVal); timer = g_timeout_source_new(timeoutVal * 10); VMTOOLSAPP_ATTACH_SOURCE(ctx, timer, ToolsDaemonSyncDriverThawCallback, NULL, NULL); g_source_unref(timer); } abort: /* * These were allocated by ToolsDaemonTcloGetQuotedString. */ free(driveList); free(timeout); /* * All Foundry tools commands return results that start with a * foundry error and a guest-OS-specific error. */ Str_Sprintf(resultBuffer, sizeof resultBuffer, "%"FMT64"d %d", err, sysError); Debug("ToolsDaemonSyncDriverThawCallback\n"); Debug("ToolsDaemonSyncDriverThawCallback: Timed out waiting for thaw.\n"); if (gSyncDriverHandle == SYNCDRIVER_INVALID_HANDLE) { Debug("ToolsDaemonTcloSyncDriverThaw\n"); /* * This function has no arguments that we care about. */ Debug("SYNCDRIVE: Got request to thaw\n"); if (gSyncDriverHandle == SYNCDRIVER_INVALID_HANDLE) { err = VIX_E_GUEST_VOLUMES_NOT_FROZEN; sysError = SYNCDRIVERERROR; Debug("ToolsDaemonTcloSyncDriverThaw: No drives are frozen.\n"); } else if (!SyncDriver_Thaw(gSyncDriverHandle)) { err = VIX_E_FAIL; sysError = SYNCDRIVERERROR; Debug("ToolsDaemonTcloSyncDriverThaw: Failed to Thaw drives\n"); } SyncDriver_CloseHandle(&gSyncDriverHandle); /* * All Foundry tools commands return results that start with a * foundry error and a guest-OS-specific error. */ Str_Sprintf(resultBuffer, sizeof resultBuffer, "%"FMT64"d %d", err, sysError); Debug("mnt_fsname, ".host:/") == 0) && (strcmp(mnt->mnt_type, HGFS_NAME) == 0) && (strcmp(mnt->mnt_dir, "/mnt/hgfs") == 0)) { vmhgfsMntFound = TRUE; break; } } endmntent(mtab); if (!vmhgfsMntFound) { /* * We need to call the mount program, not the mount system call. The * mount program does several additional things, like compute the mount * options from the contents of /etc/fstab, and invoke custom mount * programs like the one needed for HGFS. */ int ret = system("mount -t vmhgfs .host:/ /mnt/hgfs"); if (ret == -1 || WIFSIGNALED(ret) || (WIFEXITED(ret) && WEXITSTATUS(ret) != 0)) { err = VIX_E_HGFS_MOUNT_FAIL; } } } #endif /* * All tools commands return results that start with an error * and a guest-OS-specific error. */ Str_Sprintf(resultBuffer, sizeof(resultBuffer), "%"FMT64"d %d", err, Err_Errno()); RPCIN_SETRETVALS(data, resultBuffer, TRUE); return TRUE; } // ToolsDaemonTcloMountHGFS #if !defined(N_PLAT_NLM) /* *----------------------------------------------------------------------------- * * ToolsDaemonHgfsImpersonated -- * * Tclo cmd handler for hgfs requests. * * Here we receive guest user credentials and an HGFS packet to * be processed by the HGFS server under the context of * the guest user credentials. * * We pre-allocate a HGFS reply packet buffer and leave some space at * the beginning of the buffer for foundry error codes. * The format of the foundry error codes is a 64 bit number (as text), * followed by a 32 bit number (as text), followed by a hash, * all delimited by space (' '). The hash is needed * to make it easier for text parsers to know where the * HGFS reply packet begins, since it can start with a space. * * We do this funky "allocate an HGFS packet with extra * room for foundry error codes" to avoid copying buffers * around. The HGFS packet buffer is roughly 62k for large V3 Hgfs request * or 6k for other request , so it would be bad to copy that for every packet. * * It is guaranteed that we will not be called twice * at the same time, so it is safe for resultPacket to be static. * The TCLO processing loop (RpcInLoop()) is synchronous. * * * Results: * TRUE on TCLO success (*result contains the hgfs reply) * FALSE on TCLO error (not supposed to happen) * * Side effects: * None * *----------------------------------------------------------------------------- */ gboolean ToolsDaemonHgfsImpersonated(RpcInData *data) // IN { VixError err; size_t hgfsPacketSize = 0; size_t hgfsReplySize = 0; const char *origArgs = data->args; Bool impersonatingVMWareUser = FALSE; char *credentialTypeStr = NULL; char *obfuscatedNamePassword = NULL; void *userToken = NULL; int actualUsed; #define STRLEN_OF_MAX_64_BIT_NUMBER_AS_STRING 20 #define OTHER_TEXT_SIZE 4 /* strlen(space zero space quote) */ static char resultPacket[STRLEN_OF_MAX_64_BIT_NUMBER_AS_STRING + OTHER_TEXT_SIZE + HGFS_LARGE_PACKET_MAX]; char *hgfsReplyPacket = resultPacket + STRLEN_OF_MAX_64_BIT_NUMBER_AS_STRING + OTHER_TEXT_SIZE; Debug(">ToolsDaemonHgfsImpersonated\n"); err = VIX_OK; /* * We assume VixError is 64 bits. If it changes, we need * to adjust STRLEN_OF_MAX_64_BIT_NUMBER_AS_STRING. * * There isn't much point trying to return gracefully * if sizeof(VixError) is larger than we expected: we didn't * allocate enough space to actually represent the error! * So we're stuck. Panic at this point. */ ASSERT_ON_COMPILE(sizeof (uint64) == sizeof err); /* * Get the authentication information. */ credentialTypeStr = ToolsDaemonTcloGetQuotedString(data->args, &data->args); obfuscatedNamePassword = ToolsDaemonTcloGetQuotedString(data->args, &data->args); /* * Make sure we are passed the correct arguments. */ if ((NULL == credentialTypeStr) || (NULL == obfuscatedNamePassword)) { err = VIX_E_INVALID_ARG; goto abort; } /* * Skip over our token that is right before the HGFS packet. * This makes ToolsDaemonTcloGetQuotedString parsing predictable, * since it will try to eat trailing spaces after a quoted string, * and the HGFS packet might begin with a space. */ if (((data->args - origArgs) >= data->argsSize) || ('#' != *(data->args))) { /* * Buffer too small or we got an unexpected token. */ err = VIX_E_FAIL; goto abort; } data->args++; /* * At this point args points to the HGFS packet. * If we're pointing beyond the end of the buffer, we'll * get a negative HGFS packet length and abort. */ hgfsPacketSize = data->argsSize - (data->args - origArgs); if (hgfsPacketSize <= 0) { err = VIX_E_FAIL; goto abort; } if (thisProcessRunsAsRoot) { impersonatingVMWareUser = VixToolsImpersonateUserImpl(credentialTypeStr, VIX_USER_CREDENTIAL_NONE, obfuscatedNamePassword, &userToken); if (!impersonatingVMWareUser) { err = VIX_E_GUEST_USER_PERMISSIONS; goto abort; } } /* * Impersonation was okay, so let's give our packet to * the HGFS server and forward the reply packet back. */ hgfsReplySize = sizeof resultPacket - (hgfsReplyPacket - resultPacket); HgfsServerManager_ProcessPacket(&gFoundryHgfsBkdrConn, // hgfs server connection data->args, // packet in buf hgfsPacketSize, // packet in size hgfsReplyPacket, // packet out buf &hgfsReplySize); // reply buf/data size abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); /* * These were allocated by ToolsDaemonTcloGetQuotedString. */ free(credentialTypeStr); free(obfuscatedNamePassword); data->result = resultPacket; data->resultLen = STRLEN_OF_MAX_64_BIT_NUMBER_AS_STRING + OTHER_TEXT_SIZE + hgfsReplySize; /* * Render the foundry error codes into the buffer. */ actualUsed = Str_Snprintf(resultPacket, STRLEN_OF_MAX_64_BIT_NUMBER_AS_STRING + OTHER_TEXT_SIZE, "%"FMT64"d 0 ", err); if (actualUsed < 0) { /* * We computed our string length wrong! This should never happen. * But if it does, let's try to recover gracefully. The "1" in * the string below is VIX_E_FAIL. We don't try to use %d since * we couldn't even do that right the first time around. * That hash is needed for the parser on the other * end to stop before the HGFS packet, since the HGFS packet * can contain a space (and the parser can eat trailing spaces). */ ASSERT(0); actualUsed = Str_Snprintf(resultPacket, STRLEN_OF_MAX_64_BIT_NUMBER_AS_STRING, "1 0 #"); data->resultLen = actualUsed; } else { /* * We computed the string length correctly. Great! * * We allocated enough space to cover a large 64 bit number * for VixError. Chances are we didn't use all that space. * Instead, pad it with whitespace so the text parser can skip * over it. */ memset(resultPacket + actualUsed, ' ', STRLEN_OF_MAX_64_BIT_NUMBER_AS_STRING + OTHER_TEXT_SIZE - actualUsed); /* * Put a hash right before the HGFS packet. * So the buffer will look something like this: * "0 0 #" followed by the HGFS packet. */ resultPacket[STRLEN_OF_MAX_64_BIT_NUMBER_AS_STRING + OTHER_TEXT_SIZE - 1] = '#'; } Debug("<<rpc, msg, strlen(msg) + 1, NULL, NULL); g_free(msg); if (!sentResult) { Warning("Unable to send results from polling the result program.\n\n"); } } // ToolsDaemonTcloReportProgramCompleted /* *----------------------------------------------------------------------------- * * ToolsDaemonTcloReceiveVixCommand -- * * * Return value: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ gboolean ToolsDaemonTcloReceiveVixCommand(RpcInData *data) // IN { VixError err = VIX_OK; uint32 additionalError = 0; char *requestName = NULL; VixCommandRequestHeader *requestMsg = NULL; size_t maxResultBufferSize; size_t tcloBufferLen; char *resultValue = NULL; size_t resultValueLength = 0; Bool deleteResultValue = FALSE; char *destPtr = NULL; int vixPrefixDataSize = (MAX64_DECIMAL_DIGITS * 2) + (sizeof(' ') * 2) + sizeof('\0') + sizeof(' ') * 10; // for RPC header /* * Our temporary buffer will be the same size as what the * Tclo/RPC system can handle, which is GUESTMSG_MAX_IN_SIZE. */ static char tcloBuffer[GUESTMSG_MAX_IN_SIZE]; ToolsAppCtx *ctx = data->appCtx; GMainLoop *eventQueue = ctx->mainLoop; GKeyFile *confDictRef = ctx->config; requestName = ToolsDaemonTcloGetQuotedString(data->args, &data->args); /* * Skip the NULL, char, and then the rest of the buffer should just * be a Vix command object. */ while (*data->args) { data->args += 1; } data->args += 1; err = VixMsg_ValidateMessage((char *) data->args, data->argsSize); if (VIX_OK != err) { goto abort; } requestMsg = (VixCommandRequestHeader *) data->args; maxResultBufferSize = sizeof(tcloBuffer) - vixPrefixDataSize; err = VixTools_ProcessVixCommand(requestMsg, requestName, maxResultBufferSize, confDictRef, eventQueue, &resultValue, &resultValueLength, &deleteResultValue); /* * NOTE: We have always been returning an additional 32 bit error (errno, * or GetLastError() for Windows) along with the 64 bit VixError. The VMX * side has been dropping the higher order 32 bits of VixError (by copying * it onto a 32 bit error). They do save the additional error but as far * as we can tell, it was not getting used by foundry. So at this place, * for certain guest commands that have extra error information tucked into * the higher order 32 bits of the VixError, we use that extra error as the * additional error to be sent back to VMX. */ additionalError = VixTools_GetAdditionalError(requestMsg->opCode, err); Debug("%s: additionalError = %u\n", __FUNCTION__, additionalError); abort: tcloBufferLen = resultValueLength + vixPrefixDataSize; /* * If we generated a message larger than tclo/Rpc can handle, * we did something wrong. Our code should never have done this. */ if (tcloBufferLen > sizeof tcloBuffer) { ASSERT(0); resultValue[0] = 0; tcloBufferLen = tcloBufferLen - resultValueLength; err = VIX_E_OUT_OF_MEMORY; } /* * All Foundry tools commands return results that start with a foundry error * and a guest-OS-specific error. */ Str_Sprintf(tcloBuffer, sizeof tcloBuffer, "%"FMT64"d %d ", err, additionalError); destPtr = tcloBuffer + strlen(tcloBuffer); /* * If this is a binary result, then we put a # at the end of the ascii to * mark the end of ascii and the start of the binary data. */ if ((NULL != requestMsg) && (requestMsg->commonHeader.commonFlags & VIX_COMMAND_GUEST_RETURNS_BINARY)) { *(destPtr++) = '#'; data->resultLen = destPtr - tcloBuffer + resultValueLength; } /* * Copy the result. Don't use a strcpy, since this may be a binary buffer. */ memcpy(destPtr, resultValue, resultValueLength); destPtr += resultValueLength; /* * If this is not binary data, then it should be a NULL terminated string. */ if ((NULL == requestMsg) || !(requestMsg->commonHeader.commonFlags & VIX_COMMAND_GUEST_RETURNS_BINARY)) { *(destPtr++) = 0; data->resultLen = strlen(tcloBuffer) + 1; } data->result = tcloBuffer; if (deleteResultValue) { free(resultValue); } free(requestName); Debug("/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @HAVE_X11_TRUE@am__append_1 = desktopEvents @HAVE_GTKMM_TRUE@am__append_2 = dndcp @HAVE_X11_TRUE@am__append_3 = resolutionSet subdir = services/plugins DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = desktopEvents dndcp guestInfo hgfsServer powerOps \ resolutionSet timeSync vix vmbackup DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = $(am__append_1) $(am__append_2) guestInfo hgfsServer \ powerOps $(am__append_3) timeSync vix vmbackup all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu services/plugins/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu services/plugins/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done cscopelist-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) cscopelist); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-exec-local install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) \ cscopelist-recursive ctags-recursive install-am install-strip \ tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ cscopelist cscopelist-recursive ctags ctags-recursive \ distclean distclean-generic distclean-libtool distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-exec-local \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am # # plugin_LTLIBRARIES causes both .la and .so files to be installed to the # plugin directories. Clean up the .la files and keep just the shared # libraries around. Sometimes, even though we're passing "-shared" to # libtool, .a files are also generated, so clean up those too. # install-exec-local: rm -f $(DESTDIR)$(VMSVC_PLUGIN_INSTALLDIR)/*.a rm -f $(DESTDIR)$(VMSVC_PLUGIN_INSTALLDIR)/*.la rm -f $(DESTDIR)$(VMUSR_PLUGIN_INSTALLDIR)/*.a rm -f $(DESTDIR)$(VMUSR_PLUGIN_INSTALLDIR)/*.la # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/services/plugins/powerOps/0000755765153500003110000000000012220061625020556 5ustar dtormtsopen-vm-tools-9.4.0-1280544/services/plugins/powerOps/COPYING0000644765153500003110000006347112220061556021627 0ustar dtormts GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! open-vm-tools-9.4.0-1280544/services/plugins/powerOps/Makefile.am0000644765153500003110000000231512220061556022616 0ustar dtormts################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ plugindir = @VMSVC_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libpowerOps.la libpowerOps_la_CPPFLAGS = libpowerOps_la_CPPFLAGS += @PLUGIN_CPPFLAGS@ libpowerOps_la_LDFLAGS = libpowerOps_la_LDFLAGS += @PLUGIN_LDFLAGS@ libpowerOps_la_LIBADD = libpowerOps_la_LIBADD += @VMTOOLS_LIBS@ libpowerOps_la_SOURCES = libpowerOps_la_SOURCES += powerOps.c open-vm-tools-9.4.0-1280544/services/plugins/powerOps/powerOps.c0000644765153500003110000003742712220061556022560 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file powerOps.c * * Plugin that handles power operation events from the VMX. */ #define G_LOG_DOMAIN "powerops" #include "vm_assert.h" #include "vm_basic_defs.h" #include "conf.h" #include "procMgr.h" #include "system.h" #include "vmware/guestrpc/powerops.h" #include "vmware/tools/plugin.h" #include "vmware/tools/utils.h" #if defined(G_PLATFORM_WIN32) # define INVALID_PID NULL #else # define INVALID_PID (GPid) -1 #endif #if !defined(__APPLE__) #include "embed_version.h" #include "vmtoolsd_version.h" VM_EMBED_VERSION(VMTOOLSD_VERSION_STRING); #endif static const char *stateChgConfNames[] = { NULL, CONFNAME_POWEROFFSCRIPT, CONFNAME_POWEROFFSCRIPT, CONFNAME_POWERONSCRIPT, CONFNAME_RESUMESCRIPT, CONFNAME_SUSPENDSCRIPT, }; /** Internal plugin state. */ typedef struct PowerOpState { GuestOsState stateChgInProgress; GuestOsState lastFailedStateChg; #if defined(G_PLATFORM_WIN32) ProcMgr_AsyncProc *pid; #else GPid pid; #endif ToolsAppCtx *ctx; gboolean scriptEnabled[GUESTOS_STATECHANGE_LAST]; } PowerOpState; /** * Returns the capabilities of the power ops plugin. * * @param[in] src The source object. * @param[in] ctx The application context. * @param[in] set Whether capabilities are being set. * @param[in] data Unused. * * @return List of capabilities. */ static GArray * PowerOpsCapabilityCb(gpointer src, ToolsAppCtx *ctx, gboolean set, gpointer data) { const ToolsAppCapability caps[] = { { TOOLS_CAP_OLD_NOVAL, "statechange", 0, 1 }, { TOOLS_CAP_OLD_NOVAL, "softpowerop_retry", 0, 1 }, }; return VMTools_WrapArray(caps, sizeof *caps, ARRAYSIZE(caps)); } /** * Handles power ops-related options. * * @param[in] src The source object. * @param[in] ctx The app context. * @param[in] option Option being set. * @param[in] value Option value. * @param[in] plugin Plugin registration data. * * @return TRUE on success. */ static gboolean PowerOpsSetOption(gpointer src, ToolsAppCtx *ctx, const gchar *option, const gchar *value, ToolsPluginData *plugin) { gboolean enabled; PowerOpState *state = plugin->_private; if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) { return FALSE; } enabled = (strcmp(value, "1") == 0); if (strcmp(option, TOOLSOPTION_SCRIPTS_POWERON) == 0) { state->scriptEnabled[GUESTOS_STATECHANGE_POWERON] = enabled; } else if (strcmp(option, TOOLSOPTION_SCRIPTS_POWEROFF) == 0) { state->scriptEnabled[GUESTOS_STATECHANGE_HALT] = state->scriptEnabled[GUESTOS_STATECHANGE_REBOOT] = enabled; } else if (strcmp(option, TOOLSOPTION_SCRIPTS_SUSPEND) == 0) { state->scriptEnabled[GUESTOS_STATECHANGE_SUSPEND] = enabled; } else if (strcmp(option, TOOLSOPTION_SCRIPTS_RESUME) == 0) { state->scriptEnabled[GUESTOS_STATECHANGE_RESUME] = enabled; } else { return FALSE; } return TRUE; } /** * Clean up internal state on shutdown. * * @param[in] src The source object. * @param[in] ctx Unused. * @param[in] plugin Plugin registration data. */ static void PowerOpsShutdown(gpointer src, ToolsAppCtx *ctx, ToolsPluginData *plugin) { PowerOpState *state = plugin->_private; g_free(state); } /** * Called when a state change script is done running. Sends the state change * status to the VMX. * * @note This may halt/reboot the VM. Also the VMX may suspend the VM upon * receipt of a positive status. * * @param[in] state Plugin state. * @param[in] success Whether the script was successful. */ static void PowerOpsStateChangeDone(PowerOpState *state, gboolean success) { gchar *msg; g_debug("State change complete, success = %d.\n", success); /* * We execute the requested action if the script succeeded, or if the * same action was tried before but didn't finish due to a script failure. * See bug 168568 for discussion. */ if (success || state->lastFailedStateChg == state->stateChgInProgress) { success = TRUE; state->lastFailedStateChg = GUESTOS_STATECHANGE_NONE; } if (!success) { state->lastFailedStateChg = state->stateChgInProgress; } /* Send the status message to the VMX. */ msg = g_strdup_printf("tools.os.statechange.status %d %d", success, state->stateChgInProgress); if (!RpcChannel_Send(state->ctx->rpc, msg, strlen(msg) + 1, NULL, NULL)) { g_warning("Unable to send the status RPC."); } g_free(msg); /* Finally, perform the requested operation. */ if (success) { if (state->stateChgInProgress == GUESTOS_STATECHANGE_REBOOT) { g_debug("Initiating reboot.\n"); System_Shutdown(TRUE); } else if (state->stateChgInProgress == GUESTOS_STATECHANGE_HALT) { g_debug("Initiating halt.\n"); System_Shutdown(FALSE); } } state->stateChgInProgress = GUESTOS_STATECHANGE_NONE; } #if defined(G_PLATFORM_WIN32) /** * Callback for when the script process finishes on Win32 systems. * * @param[in] _state Plugin state. * * @return TRUE if the process is not finished yet. */ static gboolean PowerOpsScriptCallback(gpointer _state) { PowerOpState *state = _state; ASSERT(state->pid != INVALID_PID); if (!ProcMgr_IsAsyncProcRunning(state->pid)) { int exitcode; gboolean success; success = (ProcMgr_GetExitCode(state->pid, &exitcode) == 0 && exitcode == 0); g_debug("Script exit code: %d, success = %d\n", exitcode, success); PowerOpsStateChangeDone(state, success); ProcMgr_Free(state->pid); state->pid = INVALID_PID; return FALSE; } return TRUE; } /** * Starts a process using the ProcMgr library. For some reason the glib * spawn functions are a pain to use under Windows, and ProcMgr works * fine since we can use the "selectable" handle to monitor the child * process. * * XXX: as soon as I figure out what's wrong with the "gspawn-win32-helper" * process and why it's not working, this should probably be merged with the * POSIX code below. * * @param[in] state Plugin state. * @param[in] script Path to the script to be run. * * @return Whether started the process successfully. */ static gboolean PowerOpsRunScript(PowerOpState *state, gchar *script) { gchar *quoted = NULL; ProcMgr_ProcArgs procArgs; /* * Pass the CREATE_NO_WINDOW flag to CreateProcess so that the * cmd.exe window will not be visible to the user in the guest. */ memset(&procArgs, 0, sizeof procArgs); procArgs.bInheritHandles = TRUE; procArgs.dwCreationFlags = CREATE_NO_WINDOW; /* Quote the path if it's not yet quoted. */ if (script[0] != '"') { quoted = g_strdup_printf("\"%s\"", script); } g_debug("Executing script: %s\n", (quoted != NULL) ? quoted : script); state->pid = ProcMgr_ExecAsync((quoted != NULL) ? quoted : script, &procArgs); g_free(quoted); if (state->pid != NULL) { HANDLE h = ProcMgr_GetAsyncProcSelectable(state->pid); GSource *watch = VMTools_NewHandleSource(h); VMTOOLSAPP_ATTACH_SOURCE(state->ctx, watch, PowerOpsScriptCallback, state, NULL); g_source_unref(watch); return TRUE; } else { g_warning("Failed to start script: out of memory?\n"); return FALSE; } } #else /** * Callback for when the script process finishes on POSIX systems. * * @param[in] pid Child pid. * @param[in] exitcode Exit status of script. * @param[in] _state Plugin state. * * @return FALSE. */ static gboolean PowerOpsScriptCallback(GPid pid, gint exitcode, gpointer _state) { PowerOpState *state = _state; gboolean success = exitcode == 0; ASSERT(state->pid != INVALID_PID); g_debug("Script exit code: %d, success = %d\n", exitcode, success); PowerOpsStateChangeDone(_state, success); g_spawn_close_pid(state->pid); state->pid = INVALID_PID; return FALSE; } /** * Starts a process using glib. This works better in the non-Windows case, * since glib provides a nice API for monitoring when a process exits * (instead of having to poll the process every once in a while when using * ProcMgr.) * * @param[in] state Plugin state. * @param[in] script Path to the script to be run. * * @return Whether started the process successfully. */ static gboolean PowerOpsRunScript(PowerOpState *state, gchar *script) { gchar *argv[2]; GSource *watch; GError *err = NULL; argv[0] = g_locale_from_utf8(script, -1, NULL, NULL, &err); if (err != NULL) { g_debug("Conversion error: %s\n", err->message); g_clear_error(&err); /* * If we could not convert to current locate let's hope that * what we have is a useable script name and use it directly. */ argv[0] = g_strdup(script); } argv[1] = NULL; if (!g_spawn_async(NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, NULL, NULL, &state->pid, &err)) { g_warning("Error starting script: %s\n", err->message); g_clear_error(&err); g_free(argv[0]); return FALSE; } /* Setup a watch for when the child is done. */ watch = g_child_watch_source_new(state->pid); VMTOOLSAPP_ATTACH_SOURCE(state->ctx, watch, PowerOpsScriptCallback, state, NULL); g_source_unref(watch); g_free(argv[0]); return TRUE; } #endif /** * Handler for commands which invoke state change scripts. Runs the configured * script for the power operation signaled by the host. * * @param[in] data RPC data. * * @return TRUE on success. */ static gboolean PowerOpsStateChange(RpcInData *data) { size_t i; PowerOpState *state = data->clientData; if (state->pid != INVALID_PID) { g_debug("State change already in progress.\n"); return RPCIN_SETRETVALS(data, "State change already in progress", FALSE); } g_debug("State change: %s\n", data->name); for (i = 0; i < ARRAYSIZE(stateChangeCmdTable); i++) { if (strcmp(data->name, stateChangeCmdTable[i].tcloCmd) == 0) { gchar *script; const char *result; const char *confName; Bool ret; state->stateChgInProgress = stateChangeCmdTable[i].id; /* Check for the toolScripts option. */ if (!state->scriptEnabled[stateChangeCmdTable[i].id]) { PowerOpsStateChangeDone(state, TRUE); g_debug("Script for %s not configured to run\n", stateChangeCmdTable[i].tcloCmd); return RPCIN_SETRETVALS(data, "", TRUE); } confName = stateChgConfNames[stateChangeCmdTable[i].id]; script = g_key_file_get_string(state->ctx->config, "powerops", confName, NULL); if (script == NULL) { /* Use default script if not set in config file. */ const char *dfltScript = GuestApp_GetDefaultScript(confName); if (dfltScript == NULL) { g_debug("No default script to run for state change %s.\n", stateChangeCmdTable[i].name); PowerOpsStateChangeDone(state, TRUE); return RPCIN_SETRETVALS(data, "", TRUE); } script = g_strdup(dfltScript); } else if (strlen(script) == 0) { g_debug("No script to run for state change %s.\n", stateChangeCmdTable[i].name); g_free(script); PowerOpsStateChangeDone(state, TRUE); return RPCIN_SETRETVALS(data, "", TRUE); } /* If script path is not absolute, assume the Tools install path. */ if (!g_path_is_absolute(script)) { char *dfltPath; char *tmp; dfltPath = GuestApp_GetInstallPath(); ASSERT(dfltPath != NULL); /* * Before the switch to vmtoolsd, the config file was saved with * quotes around the script path to make the old VMware dict code * happy. Now we need to undo that when modifying the script path. * * PowerOpsRunScript will "re-quote" the script path. */ if (script[0] == '"') { script[strlen(script) - 1] = '\0'; tmp = g_strdup_printf("%s%c%s", dfltPath, DIRSEPC, script + 1); } else { tmp = g_strdup_printf("%s%c%s", dfltPath, DIRSEPC, script); } g_free(script); vm_free(dfltPath); script = tmp; } if (PowerOpsRunScript(state, script)) { result = ""; ret = TRUE; } else { PowerOpsStateChangeDone(state, FALSE); result = "Error starting script"; ret = FALSE; } g_free(script); return RPCIN_SETRETVALS(data, (char *) result, ret); } } g_warning("Invalid state change command.\n"); return RPCIN_SETRETVALS(data, "Invalid state change command", FALSE); } /** * Plugin entry point. Returns the registration data. * * @param[in] ctx Unused. * * @return The registration data. */ TOOLS_MODULE_EXPORT ToolsPluginData * ToolsOnLoad(ToolsAppCtx *ctx) { static ToolsPluginData regData = { "powerops", NULL, NULL }; size_t i; PowerOpState *state; ToolsPluginSignalCb sigs[] = { { TOOLS_CORE_SIG_CAPABILITIES, PowerOpsCapabilityCb, NULL }, { TOOLS_CORE_SIG_SET_OPTION, PowerOpsSetOption, ®Data }, { TOOLS_CORE_SIG_SHUTDOWN, PowerOpsShutdown, ®Data } }; ToolsAppReg regs[] = { { TOOLS_APP_GUESTRPC, NULL }, { TOOLS_APP_SIGNALS, VMTools_WrapArray(sigs, sizeof *sigs, ARRAYSIZE(sigs)) } }; state = g_malloc0(sizeof *state); state->ctx = ctx; state->pid = INVALID_PID; for (i = 0; i < GUESTOS_STATECHANGE_LAST; i++) { state->scriptEnabled[i] = TRUE; } regs[0].data = g_array_sized_new(FALSE, TRUE, sizeof (RpcChannelCallback), ARRAYSIZE(stateChangeCmdTable)); for (i = 0; i < ARRAYSIZE(stateChangeCmdTable); i++) { RpcChannelCallback cb = { stateChangeCmdTable[i].tcloCmd, PowerOpsStateChange, state, NULL, NULL, 0 }; g_array_append_val(regs[0].data, cb); } regData.regs = VMTools_WrapArray(regs, sizeof *regs, ARRAYSIZE(regs)); regData._private = state; return ®Data; } open-vm-tools-9.4.0-1280544/services/plugins/powerOps/Makefile.in0000644765153500003110000005335412220061625022635 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = services/plugins/powerOps DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(plugin_LTLIBRARIES) libpowerOps_la_DEPENDENCIES = am_libpowerOps_la_OBJECTS = libpowerOps_la-powerOps.lo libpowerOps_la_OBJECTS = $(am_libpowerOps_la_OBJECTS) libpowerOps_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libpowerOps_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libpowerOps_la_SOURCES) DIST_SOURCES = $(libpowerOps_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ plugindir = @VMSVC_PLUGIN_INSTALLDIR@ plugin_LTLIBRARIES = libpowerOps.la libpowerOps_la_CPPFLAGS = @PLUGIN_CPPFLAGS@ libpowerOps_la_LDFLAGS = @PLUGIN_LDFLAGS@ libpowerOps_la_LIBADD = @VMTOOLS_LIBS@ libpowerOps_la_SOURCES = powerOps.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu services/plugins/powerOps/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu services/plugins/powerOps/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ } uninstall-pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ done clean-pluginLTLIBRARIES: -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) @list='$(plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libpowerOps.la: $(libpowerOps_la_OBJECTS) $(libpowerOps_la_DEPENDENCIES) $(EXTRA_libpowerOps_la_DEPENDENCIES) $(libpowerOps_la_LINK) -rpath $(plugindir) $(libpowerOps_la_OBJECTS) $(libpowerOps_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpowerOps_la-powerOps.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libpowerOps_la-powerOps.lo: powerOps.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpowerOps_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpowerOps_la-powerOps.lo -MD -MP -MF $(DEPDIR)/libpowerOps_la-powerOps.Tpo -c -o libpowerOps_la-powerOps.lo `test -f 'powerOps.c' || echo '$(srcdir)/'`powerOps.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpowerOps_la-powerOps.Tpo $(DEPDIR)/libpowerOps_la-powerOps.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='powerOps.c' object='libpowerOps_la-powerOps.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpowerOps_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpowerOps_la-powerOps.lo `test -f 'powerOps.c' || echo '$(srcdir)/'`powerOps.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(plugindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pluginLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pluginLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-pluginLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-pluginLTLIBRARIES install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-pluginLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/services/Makefile.am0000644765153500003110000000164712220061556017326 0ustar dtormts################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ SUBDIRS = SUBDIRS += vmtoolsd SUBDIRS += plugins open-vm-tools-9.4.0-1280544/services/vmtoolsd/0000755765153500003110000000000012220061625017126 5ustar dtormtsopen-vm-tools-9.4.0-1280544/services/vmtoolsd/svcSignals.gm0000644765153500003110000000225012220061556021571 0ustar dtormts########################################################## # Copyright (C) 2009 VMware, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public # License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # ########################################################## ## # @file svcSignals.gm # # Defines the custom GClosure marshal functions for the core services signals. # # @see plugin.h # # The "capabilities" signal. POINTER:POINTER,BOOLEAN # The "set option" signal. BOOLEAN:POINTER,STRING,STRING # The "service control" signal. # Used on Win32 only. UINT:POINTER,POINTER,UINT,UINT,POINTER open-vm-tools-9.4.0-1280544/services/vmtoolsd/toolsCoreInt.h0000644765153500003110000000730512220061556021733 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _TOOLSCOREINT_H_ #define _TOOLSCOREINT_H_ /** * @file toolsCoreInt.h * * Internal functions for the tools daemon. */ #define VMW_TEXT_DOMAIN "vmtoolsd" #define G_LOG_DOMAIN VMW_TEXT_DOMAIN #define TOOLSCORE_COMMON "common" #include #include #include #include "vmware/tools/plugin.h" #include "vmware/tools/rpcdebug.h" /* Used by the Windows implementation to communicate with other processes. */ #if defined(G_PLATFORM_WIN32) # define QUIT_EVENT_NAME_FMT L"%S\\VMwareToolsQuitEvent_%s" # define DUMP_STATE_EVENT_NAME_FMT L"%S\\VMwareToolsDumpStateEvent_%s" #endif /* On Mac OS, G_MODULE_SUFFIX seems to be defined to "so"... */ #if defined(__APPLE__) # if defined(G_MODULE_SUFFIX) # undef G_MODULE_SUFFIX # endif # define G_MODULE_SUFFIX "dylib" #endif /** State of app providers. */ typedef enum { TOOLS_PROVIDER_IDLE, TOOLS_PROVIDER_ACTIVE, TOOLS_PROVIDER_ERROR, /* Keep this as the last one, always. */ TOOLS_PROVIDER_MAX } ToolsAppProviderState; /** Defines the internal app provider data. */ typedef struct ToolsAppProviderReg { ToolsAppProvider *prov; ToolsAppProviderState state; } ToolsAppProviderReg; /** Defines internal service state. */ typedef struct ToolsServiceState { gchar *name; gchar *configFile; time_t configMtime; guint configCheckTask; gboolean mainService; gboolean capsRegistered; gchar *commonPath; gchar *pluginPath; GPtrArray *plugins; #if defined(_WIN32) gchar *displayName; #else gchar *pidFile; #endif GModule *debugLib; gchar *debugPlugin; RpcDebugLibData *debugData; ToolsAppCtx ctx; GArray *providers; } ToolsServiceState; gboolean ToolsCore_ParseCommandLine(ToolsServiceState *state, int argc, char *argv[]); void ToolsCore_DumpPluginInfo(ToolsServiceState *state); void ToolsCore_DumpState(ToolsServiceState *state); const char * ToolsCore_GetTcloName(ToolsServiceState *state); int ToolsCore_Run(ToolsServiceState *state); void ToolsCore_Setup(ToolsServiceState *state); gboolean ToolsCore_InitRpc(ToolsServiceState *state); gboolean ToolsCore_LoadPlugins(ToolsServiceState *state); void ToolsCore_ReloadConfig(ToolsServiceState *state, gboolean reset); void ToolsCore_RegisterPlugins(ToolsServiceState *state); void ToolsCore_SetCapabilities(RpcChannel *chan, GArray *caps, gboolean set); void ToolsCore_UnloadPlugins(ToolsServiceState *state); #if defined(__APPLE__) void ToolsCore_CFRunLoop(ToolsServiceState *state); #endif void ToolsCorePool_Init(ToolsAppCtx *ctx); void ToolsCorePool_Shutdown(ToolsAppCtx *ctx); #endif /* _TOOLSCOREINT_H_ */ open-vm-tools-9.4.0-1280544/services/vmtoolsd/cmdLine.c0000644765153500003110000002357512220061556020664 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file cmdLine.c * * Parses the daemon's command line arguments. Some commands may cause the * process to exit. */ #include "toolsCoreInt.h" #include #include #include #if !defined(G_PLATFORM_WIN32) # include #endif #include #include "vm_assert.h" #include "conf.h" #include "rpcout.h" #include "str.h" #include "vmcheck.h" #include "vmtoolsd_version.h" #include "vmware/tools/log.h" #include "vmware/tools/utils.h" #include "vmware/tools/i18n.h" /** * Runs the given Tools RPC command, printing the result to the terminal and * exiting the application afterwards. * * @param[in] option Unused. * @param[in] value RPC command. * @param[in] data Unused. * @param[out] error Unused. * * @return This function doesn't return. */ static gboolean ToolsCoreRunCommand(const gchar *option, const gchar *value, gpointer data, GError **error) { #if defined(_WIN32) VMTools_AttachConsole(); #endif if (VmCheck_IsVirtualWorld()) { char *result = NULL; Bool status = FALSE; status = RpcOut_sendOne(&result, NULL, "%s", value); if (!status) { g_printerr("%s\n", result ? result : "NULL"); } else { g_print("%s\n", result); } vm_free(result); exit(status ? 0 : 1); } g_printerr("%s\n", SU_(cmdline.rpcerror, "Unable to send command to VMware hypervisor.")); exit(1); } #if defined(G_PLATFORM_WIN32) /** * Function used to ignore command line arguments. * * @param[in] option Unused. * @param[in] value Unused. * @param[in] data Unused. * @param[out] error Unused. * * @return TRUE */ static gboolean ToolsCoreIgnoreArg(const gchar *option, const gchar *value, gpointer data, GError **error) { return TRUE; } /** * Signals a specific event in a running service instance. Since this function * doesn't know whether the service is running through the SCM, it first tries * to open a local event, and if that fails, tries a global event. * * @param[in] svcname Name of the service to be signaled. * @param[in] evtFmt Format string for the event name. It should expect * a single string parameter. * * @return Whether successfully signaled the running service. */ static gboolean ToolsCoreSignalEvent(const gchar *svcname, const wchar_t *evtFmt) { gboolean ret = FALSE; gchar *msg; wchar_t *evt; HANDLE h = NULL; ASSERT(svcname != NULL); evt = Str_Aswprintf(NULL, evtFmt, L"Local", svcname); if (evt == NULL) { g_printerr("Out of memory!\n"); goto exit; } h = OpenEvent(EVENT_MODIFY_STATE, FALSE, evt); if (h != NULL) { goto dispatch; } vm_free(evt); evt = Str_Aswprintf(NULL, evtFmt, L"Global", svcname); if (evt == NULL) { g_printerr("Out of memory!\n"); goto exit; } h = OpenEvent(EVENT_MODIFY_STATE, FALSE, evt); if (h == NULL) { goto error; } dispatch: if (!SetEvent(h)) { goto error; } ret = TRUE; goto exit; error: msg = g_win32_error_message(GetLastError()); g_printerr("Cannot open event: %s\n", msg); g_free(msg); exit: vm_free(evt); CloseHandle(h); return ret; } #endif /** * Error hook called when command line parsing fails. On Win32, make sure we * have a terminal where to show the error message. * * @param[in] context Unused. * @param[in] group Unused. * @param[in] data Unused. * @param[in] error Unused. */ static void ToolsCoreCmdLineError(GOptionContext *context, GOptionGroup *group, gpointer data, GError **error) { #if defined(_WIN32) VMTools_AttachConsole(); #endif } /** * Parses the command line. For a list of available options, look at the source * below, where the option array is declared. * * @param[out] state Parsed options will be placed in this struct. * @param[in] argc Argument count. * @param[in] argv Argument array. * * @return TRUE on success. */ gboolean ToolsCore_ParseCommandLine(ToolsServiceState *state, int argc, char *argv[]) { gboolean ret = FALSE; gboolean version = FALSE; #if defined(G_PLATFORM_WIN32) gboolean dumpState = FALSE; gboolean kill = FALSE; #endif gboolean unused; GOptionEntry clOptions[] = { { "name", 'n', 0, G_OPTION_ARG_STRING, &state->name, SU_(cmdline.name, "Name of the service being started."), SU_(cmdline.name.argument, "svcname") }, { "common-path", '\0', 0, G_OPTION_ARG_FILENAME, &state->commonPath, SU_(cmdline.commonpath, "Path to the common plugin directory."), SU_(cmdline.path, "path") }, { "plugin-path", 'p', 0, G_OPTION_ARG_FILENAME, &state->pluginPath, SU_(cmdline.pluginpath, "Path to the plugin directory."), SU_(cmdline.path, "path") }, { "cmd", '\0', 0, G_OPTION_ARG_CALLBACK, ToolsCoreRunCommand, SU_(cmdline.rpc, "Sends an RPC command to the host and exits."), SU_(cmdline.rpc.command, "command") }, #if defined(G_PLATFORM_WIN32) { "dump-state", 's', 0, G_OPTION_ARG_NONE, &dumpState, SU_(cmdline.state, "Dumps the internal state of a running service instance to the logs."), NULL }, { "kill", 'k', 0, G_OPTION_ARG_NONE, &kill, SU_(cmdline.kill, "Stops a running instance of a tools service."), NULL }, { "install", 'i', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, ToolsCoreIgnoreArg, SU_(cmdline.install, "Installs the service with the Service Control Manager."), SU_(cmdline.install.args, "args") }, { "uninstall", 'u', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, ToolsCoreIgnoreArg, SU_(cmdline.uninstall, "Uninstalls the service from the Service Control Manager."), NULL }, { "displayname", 'd', 0, G_OPTION_ARG_STRING, &state->displayName, SU_(cmdline.displayname, "Service display name (only used with -i)."), SU_(cmdline.displayname.argument, "name") }, #else { "background", 'b', 0, G_OPTION_ARG_FILENAME, &state->pidFile, SU_(cmdline.background, "Runs in the background and creates a pid file."), SU_(cmdline.background.pidfile, "pidfile") }, { "blockFd", '\0', 0, G_OPTION_ARG_INT, &state->ctx.blockFD, SU_(cmdline.blockfd, "File descriptor for the VMware blocking fs."), SU_(cmdline.blockfd.fd, "fd") }, #endif { "config", 'c', 0, G_OPTION_ARG_FILENAME, &state->configFile, SU_(cmdline.config, "Uses the config file at the given path."), SU_(cmdline.path, "path") }, { "debug", 'g', 0, G_OPTION_ARG_FILENAME, &state->debugPlugin, SU_(cmdline.debug, "Runs in debug mode, using the given plugin."), SU_(cmdline.path, "path") }, { "log", 'l', 0, G_OPTION_ARG_NONE, &unused, SU_(cmdline.log, "Ignored, kept for backwards compatibility."), NULL }, { "version", 'v', 0, G_OPTION_ARG_NONE, &version, SU_(cmdline.version, "Prints the daemon version and exits."), NULL }, { NULL } }; GError *error = NULL; GOptionContext *context = NULL; #if !defined(G_PLATFORM_WIN32) state->ctx.blockFD = -1; #endif context = g_option_context_new(NULL); #if GLIB_CHECK_VERSION(2, 12, 0) g_option_context_set_summary(context, N_("Runs the VMware Tools daemon.")); #endif g_option_context_add_main_entries(context, clOptions, NULL); g_option_group_set_error_hook(g_option_context_get_main_group(context), ToolsCoreCmdLineError); if (!g_option_context_parse(context, &argc, &argv, &error)) { g_printerr("%s: %s\n", N_("Command line parsing failed"), error->message); goto exit; } if (version) { g_print("%s %s (%s)\n", _("VMware Tools daemon, version"), VMTOOLSD_VERSION_STRING, BUILD_NUMBER); exit(0); } if (state->name == NULL) { state->name = VMTOOLS_GUEST_SERVICE; state->mainService = TRUE; } else { if (strcmp(state->name, TOOLSCORE_COMMON) == 0) { g_printerr("%s is an invalid container name.\n", state->name); goto exit; } state->mainService = (strcmp(state->name, VMTOOLS_GUEST_SERVICE) == 0); } VMTools_ConfigLogging(state->name, NULL, TRUE, TRUE); #if defined(G_PLATFORM_WIN32) if (kill) { exit(ToolsCoreSignalEvent(state->name, QUIT_EVENT_NAME_FMT) ? 0 : 1); } if (dumpState) { exit(ToolsCoreSignalEvent(state->name, DUMP_STATE_EVENT_NAME_FMT) ? 0 : 1); } #else /* If not running the "vmusr" service, ignore the blockFd parameter. */ if (strcmp(state->name, VMTOOLS_USER_SERVICE) != 0) { if (state->ctx.blockFD >= 0) { close(state->ctx.blockFD); } state->ctx.blockFD = -1; } #endif ret = TRUE; exit: g_clear_error(&error); g_option_context_free(context); return ret; } open-vm-tools-9.4.0-1280544/services/vmtoolsd/serviceObj.h0000644765153500003110000000413212220061556021375 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _SERVICEOBJ_H_ #define _SERVICEOBJ_H_ /** * @file serviceObj.h * * Interface of the "core service" object. This interface is not really * public, just the type itself, so that plugins can provide their own * signals for communicating with other plugins in the same process. For * this reason, it doesn't provide all the GObject boilerplate macros. */ #include #define TOOLSCORE_TYPE_SERVICE ToolsCore_Service_get_type() #define TOOLSCORESERVICE_GET_CLASS(object) \ (G_TYPE_INSTANCE_GET_CLASS((object), TOOLSCORE_TYPE_SERVICE, ToolsCoreServiceClass)) #define TOOLSCORE_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \ TOOLSCORE_TYPE_SERVICE, \ ToolsCoreService)) typedef struct ToolsCoreService { GObject parent; GMutex *lock; GArray *props; } ToolsCoreService; typedef struct ToolsCoreServiceClass { GObjectClass parentClass; } ToolsCoreServiceClass; GType ToolsCore_Service_get_type(void); void ToolsCoreService_RegisterProperty(ToolsCoreService *obj, ToolsServiceProperty *prop); #endif /* _SERVICEOBJ_H_ */ open-vm-tools-9.4.0-1280544/services/vmtoolsd/toolsRpc.c0000644765153500003110000002712012220061556021104 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file toolsRpc.c * * Functions related to the GuestRPC channel provided by the service. * Provides the interface for the service to bring up the RPC channel, * and handlers for the RPC messages which are handled by the service * itself. */ #include #include #include "vm_assert.h" #include "conf.h" #include "str.h" #include "strutil.h" #include "toolsCoreInt.h" #include "vm_tools_version.h" #include "vmware/tools/utils.h" #if defined(__linux__) #include #include #include #include "ioplGet.h" #endif /** * Take action after an RPC channel reset. * * @param[in] chan The RPC channel. * @param[in] success Whether reset was successful. * @param[in] _state The service state. */ static void ToolsCoreCheckReset(struct RpcChannel *chan, gboolean success, gpointer _state) { ToolsServiceState *state = _state; ASSERT(state != NULL); if (success) { const gchar *app; gchar *msg; app = ToolsCore_GetTcloName(state); if (app == NULL) { app = state->name; } msg = g_strdup_printf("vmx.capability.unified_loop %s", app); if (!RpcChannel_Send(state->ctx.rpc, msg, strlen(msg) + 1, NULL, NULL)) { g_warning("VMX doesn't support the Tools unified loop.\n" "Some functionality (like setting options) may not work.\n"); } g_free(msg); /* * Log the Tools build number to the VMX log file. We don't really care * if sending the message fails. */ msg = g_strdup_printf("log %s: Version: %s", app, BUILD_NUMBER); RpcChannel_Send(state->ctx.rpc, msg, strlen(msg) + 1, NULL, NULL); g_free(msg); g_signal_emit_by_name(state->ctx.serviceObj, TOOLS_CORE_SIG_RESET, &state->ctx); } else { VMTOOLSAPP_ERROR(&state->ctx, EXIT_FAILURE); } } /** * Checks all loaded plugins for their capabilities, and sends the data to the * host. The code will try to send all capabilities, just logging errors as * they occur. * * @param[in] data The RPC data. * * @return TRUE. */ static gboolean ToolsCoreRpcCapReg(RpcInData *data) { char *confPath = GuestApp_GetConfPath(); gchar *msg; GArray *pcaps = NULL; ToolsServiceState *state = data->clientData; g_signal_emit_by_name(state->ctx.serviceObj, TOOLS_CORE_SIG_CAPABILITIES, &state->ctx, TRUE, &pcaps); if (pcaps != NULL) { ToolsCore_SetCapabilities(state->ctx.rpc, pcaps, TRUE); g_array_free(pcaps, TRUE); } /* Tell the host the location of the conf directory. */ msg = g_strdup_printf("tools.capability.guest_conf_directory %s", confPath); if (!RpcChannel_Send(state->ctx.rpc, msg, strlen(msg) + 1, NULL, NULL)) { g_debug("Unable to register guest conf directory capability.\n"); } g_free(msg); msg = NULL; /* Send the tools version to the VMX. */ if (state->mainService) { uint32 version; char *result = NULL; size_t resultLen; gchar *toolsVersion; #if defined(OPEN_VM_TOOLS) version = TOOLS_VERSION_UNMANAGED; #else gboolean disableVersion; disableVersion = g_key_file_get_boolean(state->ctx.config, "vmtools", CONFNAME_DISABLETOOLSVERSION, NULL); version = disableVersion ? TOOLS_VERSION_UNMANAGED : TOOLS_VERSION_CURRENT; #endif toolsVersion = g_strdup_printf("tools.set.version %u", version); if (!RpcChannel_Send(state->ctx.rpc, toolsVersion, strlen(toolsVersion) + 1, &result, &resultLen)) { g_debug("Error setting tools version: %s.\n", result); } vm_free(result); g_free(toolsVersion); } #if defined (__linux__) /* Send the IOPL elevation capability to VMX. */ if (state->mainService) { unsigned int oldLevel; char *result = NULL; size_t resultLen; const char ioplElev[] = "tools.capability.iopl_elevation"; oldLevel = Iopl_Get(); g_debug("%s: old IOPL = %u\n", __FUNCTION__, oldLevel); if (iopl(3) < 0) { g_debug("Error raising the IOPL, %s", strerror(errno)); } g_debug("%s: new IOPL = %u\n", __FUNCTION__, Iopl_Get()); if (!RpcChannel_Send(state->ctx.rpc, ioplElev, sizeof ioplElev, &result, &resultLen)) { g_debug("Error setting tools iopl elevation capability: %s\n", result); vm_free(result); } if (iopl(oldLevel) < 0) { g_debug("Error restoring the IOPL, %s", strerror(errno)); } } #endif state->capsRegistered = TRUE; free(confPath); return RPCIN_SETRETVALS(data, "", TRUE); } /** * Handles a "set option" RPC. Calls the plugins which have registered interest * in the option being set. * * @param[in] data The RPC data. * * @return Whether the option was successfully processed. */ static gboolean ToolsCoreRpcSetOption(RpcInData *data) { gboolean retVal = FALSE; char *option; char *value; unsigned int index = 0; ToolsServiceState *state = data->clientData; /* Parse the option & value string. */ option = StrUtil_GetNextToken(&index, data->args, " "); /* Ignore leading space before value. */ index++; value = StrUtil_GetNextToken(&index, data->args, ""); if (option != NULL && value != NULL && strlen(value) != 0) { g_debug("Setting option '%s' to '%s'.\n", option, value); g_signal_emit_by_name(state->ctx.serviceObj, TOOLS_CORE_SIG_SET_OPTION, &state->ctx, option, value, &retVal); } vm_free(option); vm_free(value); RPCIN_SETRETVALS(data, retVal ? "" : "Unknown or invalid option", retVal); return retVal; } /** * Initializes the RPC channel. Currently this instantiates an RpcIn loop. * This function should only be called once. * * @param[in] state The service state. * * @return TRUE on success. */ gboolean ToolsCore_InitRpc(ToolsServiceState *state) { static RpcChannelCallback rpcs[] = { { "Capabilities_Register", ToolsCoreRpcCapReg, NULL, NULL, NULL, 0 }, { "Set_Option", ToolsCoreRpcSetOption, NULL, NULL, NULL, 0 }, }; size_t i; const gchar *app; GMainContext *mainCtx = g_main_loop_get_context(state->ctx.mainLoop); ASSERT(state->ctx.rpc == NULL); if (state->debugPlugin != NULL) { app = "debug"; state->ctx.rpc = state->debugData->newDebugChannel(&state->ctx, state->debugData); } else { /* * Currently we try to bring up an RpcIn channel, which will only run * inside a Virtual Machine. Some plugins may still want to launch and at * least begin even in not in a VM (typically because the installation is dual * purposed between a VM and Bootcamp) - plugins may wish to undo some state * if not in a VM. * * XXX: this should be relaxed when we try to bring up a VMCI or TCP channel. */ if (!state->ctx.isVMware) { g_warning("The %s service needs to run inside a virtual machine.\n", state->name); state->ctx.rpc = NULL; } else { state->ctx.rpc = BackdoorChannel_New(); } app = ToolsCore_GetTcloName(state); if (app == NULL) { g_warning("Trying to start RPC channel for invalid %s container.", state->name); return FALSE; } } if (state->ctx.rpc) { RpcChannel_Setup(state->ctx.rpc, app, mainCtx, &state->ctx, ToolsCoreCheckReset, state); /* Register the "built in" RPCs. */ for (i = 0; i < ARRAYSIZE(rpcs); i++) { RpcChannelCallback *rpc = &rpcs[i]; rpc->clientData = state; RpcChannel_RegisterCallback(state->ctx.rpc, rpc); } } return TRUE; } /** * Sends a list of capabilities to the host. * * @param[in] chan The RPC channel. * @param[in] caps The list of capabilities. * @param[in] set TRUE is setting capabilities (otherwise they're set to 0). */ void ToolsCore_SetCapabilities(RpcChannel *chan, GArray *caps, gboolean set) { char *result; size_t resultLen; guint i; gchar *newcaps = NULL; for (i = 0; i < caps->len; i++) { gchar *tmp; ToolsAppCapability *cap = &g_array_index(caps, ToolsAppCapability, i); switch (cap->type) { case TOOLS_CAP_OLD: result = NULL; tmp = g_strdup_printf("tools.capability.%s %u", cap->name, set ? cap->value : 0); if (!RpcChannel_Send(chan, tmp, strlen(tmp) + 1, &result, &resultLen)) { g_warning("Error sending capability %s: %s\n", cap->name, result); } vm_free(result); g_free(tmp); break; case TOOLS_CAP_OLD_NOVAL: /* * This is kind of weird, because of the way the VMX treats RPCs and * what is expected of these capabilities without arguments. For a * few details, see the comments in RpcOut_sendOne() (rpcout.c). * Basically, for the VMX handlers not to complain, we need to send the * RPC with the empty space at the end, and not consider the NULL * character when counting the bytes. */ if (set) { tmp = g_strdup_printf("tools.capability.%s ", cap->name); if (!RpcChannel_Send(chan, tmp, strlen(tmp), &result, &resultLen)) { g_warning("Error sending capability %s: %s\n", cap->name, result); } vm_free(result); g_free(tmp); } break; case TOOLS_CAP_NEW: if (newcaps == NULL) { newcaps = g_strdup(GUEST_CAP_FEATURES); } tmp = g_strdup_printf("%s %d=%u", newcaps, cap->index, set ? cap->value : 0); g_free(newcaps); newcaps = tmp; break; default: g_error("Invalid capability type: %d\n", cap->type); } } if (newcaps != NULL) { result = NULL; if (!RpcChannel_Send(chan, newcaps, strlen(newcaps) + 1, &result, &resultLen)) { g_warning("Error sending new-style capabilities: %s\n", result); } vm_free(result); g_free(newcaps); } } open-vm-tools-9.4.0-1280544/services/vmtoolsd/mainPosix.c0000644765153500003110000001655012220061556021253 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file mainPosix.c * * Service entry point for the POSIX version of the tools daemon. */ #include "toolsCoreInt.h" #include #include #include #include #include #include "file.h" #include "guestApp.h" #include "hostinfo.h" #include "system.h" #include "unicode.h" #include "util.h" #include "vmware/tools/log.h" #include "vmware/tools/i18n.h" #include "vmware/tools/utils.h" #if !defined(__APPLE__) #include "embed_version.h" #include "vmtoolsd_version.h" VM_EMBED_VERSION(VMTOOLSD_VERSION_STRING); #endif static ToolsServiceState gState = { NULL, }; /** * Reloads the service configuration - including forcing rotation of log * files by reinitializing the logging subsystem. * * @param[in] info Unused. * @param[in] data Service state. * * @return TRUE */ static gboolean ToolsCoreSigHUPCb(const siginfo_t *info, gpointer data) { ToolsCore_ReloadConfig(data, TRUE); return TRUE; } /** * Handles a signal that would terminate the process. Asks the main loop * to exit nicely. * * @param[in] info Unused. * @param[in] data Pointer to the main loop to be stopped. * * @return FALSE */ static gboolean ToolsCoreSigHandler(const siginfo_t *info, gpointer data) { g_main_loop_quit((GMainLoop *)data); return FALSE; } /** * Handles a USR1 signal; logs the current service state. * * @param[in] info Unused. * @param[in] data Unused. * * @return TRUE */ static gboolean ToolsCoreSigUsrHandler(const siginfo_t *info, gpointer data) { ToolsCore_DumpState(&gState); return TRUE; } /** * Perform (optional) work before or after running the main loop. * * @param[in] state Service state. * @param[in] before TRUE if before running the main loop, FALSE if after. */ static void ToolsCoreWorkAroundLoop(ToolsServiceState *state, gboolean before) { #ifdef __APPLE__ if (state->mainService) { char *libDir = GuestApp_GetInstallPath(); char *argv[] = { NULL, before ? "--startInternal" : "--stopInternal", NULL, }; if (!libDir) { g_error("Failed to retrieve libDir.\n"); } argv[0] = g_strdup_printf("%s/services.sh", libDir); free(libDir); if (!argv[0]) { g_error("Failed to construct argv[0].\n"); } g_spawn_sync(NULL, argv, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL); free(argv[0]); } #endif } /** * Tools daemon entry function. * * @param[in] argc Argument count. * @param[in] argv Argument array. * @param[in] envp User environment. * * @return 0 on successful execution, error code otherwise. */ int main(int argc, char *argv[], const char *envp[]) { int i; int ret = EXIT_FAILURE; char **argvCopy; GSource *src; Unicode_Init(argc, &argv, NULL); /* * ToolsCore_ParseCommandLine() uses g_option_context_parse(), which modifies * argv. We don't want that to happen, so we make a copy of the array and * use that as the argument instead. */ argvCopy = g_malloc(argc * sizeof *argvCopy); for (i = 0; i < argc; i++) { argvCopy[i] = argv[i]; } setlocale(LC_ALL, ""); VMTools_ConfigLogging(G_LOG_DOMAIN, NULL, FALSE, FALSE); VMTools_BindTextDomain(VMW_TEXT_DOMAIN, NULL, NULL); if (!ToolsCore_ParseCommandLine(&gState, argc, argvCopy)) { g_free(argvCopy); goto exit; } g_free(argvCopy); argvCopy = NULL; if (gState.pidFile != NULL) { /* * If argv[0] is not an absolute path, make it so; all other path * arguments should have been given as absolute paths if '--background' * was used, or things may not work as expected. */ if (!g_path_is_absolute(argv[0])) { gchar *abs = g_find_program_in_path(argv[0]); if (abs == NULL || strcmp(abs, argv[0]) == 0) { char *cwd = File_Cwd(NULL); g_free(abs); abs = g_strdup_printf("%s%c%s", cwd, DIRSEPC, argv[0]); vm_free(cwd); } argv[0] = abs; } /* * Need to remove --background from the command line or we'll get * into an infinite loop. ToolsCore_ParseCommandLine() already * validated that "-b" has an argument, so it's safe to assume the * data is there. */ for (i = 1; i < argc; i++) { size_t count = 0; if (strcmp(argv[i], "--background") == 0 || strcmp(argv[i], "-b") == 0) { count = 2; } else if (g_str_has_prefix(argv[i], "--background=")) { count = 1; } if (count) { memmove(argv + i, argv + i + count, (argc - i - count) * sizeof *argv); argv[argc - count] = NULL; break; } } if (!Hostinfo_Daemonize(argv[0], argv, HOSTINFO_DAEMONIZE_LOCKPID, gState.pidFile, NULL, 0)) { goto exit; } return 0; } ToolsCore_Setup(&gState); src = VMTools_NewSignalSource(SIGHUP); VMTOOLSAPP_ATTACH_SOURCE(&gState.ctx, src, ToolsCoreSigHUPCb, &gState, NULL); g_source_unref(src); src = VMTools_NewSignalSource(SIGINT); VMTOOLSAPP_ATTACH_SOURCE(&gState.ctx, src, ToolsCoreSigHandler, gState.ctx.mainLoop, NULL); g_source_unref(src); src = VMTools_NewSignalSource(SIGQUIT); VMTOOLSAPP_ATTACH_SOURCE(&gState.ctx, src, ToolsCoreSigHandler, gState.ctx.mainLoop, NULL); g_source_unref(src); /* On Mac OS, launchd uses SIGTERM. */ src = VMTools_NewSignalSource(SIGTERM); VMTOOLSAPP_ATTACH_SOURCE(&gState.ctx, src, ToolsCoreSigHandler, gState.ctx.mainLoop, NULL); g_source_unref(src); src = VMTools_NewSignalSource(SIGUSR1); VMTOOLSAPP_ATTACH_SOURCE(&gState.ctx, src, ToolsCoreSigUsrHandler, NULL, NULL); g_source_unref(src); /* Ignore SIGUSR2 by default. */ signal(SIGUSR2, SIG_IGN); /* * Save the original environment so that we can safely spawn other * applications (since we may have to modify the original environment * to launch vmtoolsd successfully). */ gState.ctx.envp = System_GetNativeEnviron(envp); ToolsCoreWorkAroundLoop(&gState, TRUE); ret = ToolsCore_Run(&gState); ToolsCoreWorkAroundLoop(&gState, FALSE); if (gState.pidFile != NULL) { g_unlink(gState.pidFile); } exit: return ret; } open-vm-tools-9.4.0-1280544/services/vmtoolsd/l10n/0000755765153500003110000000000012220061556017703 5ustar dtormtsopen-vm-tools-9.4.0-1280544/services/vmtoolsd/l10n/de.vmsg0000644765153500003110000000441112220061556021171 0ustar dtormts########################################################## # Copyright (C) 2010 VMware, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public # License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # ########################################################## cmdline.background = "Wird im Hintergrund ausgeführt und erstellt eine pid-Datei." cmdline.background.pidfile = "pidfile" cmdline.blockfd = "Dateideskriptor für das Dateisystem, das VMware blockiert." cmdline.blockfd.fd = "fd" cmdline.commonpath = "Pfad zum Plug-In-Verzeichnis." cmdline.config = "Verwendet die Konfigurationsdatei im angegebenen Pfad." cmdline.debug = "Wird unter Verwendung des angegebenen Plug-Ins im Debug-Modus ausgeführt." cmdline.displayname = "Anzeigename des Dienstes (wird nur mit -i verwendet)." cmdline.displayname.argument = "Name" cmdline.install = "Installiert den Dienst mit dem Service Control Manager (SCM)." cmdline.install.args = "args" cmdline.kill = "Stoppt eine laufende Instanz eines Tools-Dienstes." cmdline.log = "Ignoriert; für Abwärtskompatibilität beibehalten." cmdline.name = "Name des Dienstes, der gestartet wird." cmdline.name.argument = "svcname" cmdline.path = "Pfad" cmdline.pluginpath = "Pfad des Plug-In-Verzeichnisses." cmdline.rpc = "Sendet einen RPC-Befehl an den Host und wird beendet." cmdline.rpc.command = "Befehl" cmdline.rpcerror = "Befehl konnte nicht an VMware-Hypervisor gesendet werden." cmdline.state = "Führt einen Dump des internen Zustands der Instanz eines laufenden Dienstes in die Protokolle aus." cmdline.uninstall = "Deinstalliert den Dienst vom Service Control Manager (SCM)." cmdline.version = "Druckt die Version des Daemons und wird beendet." open-vm-tools-9.4.0-1280544/services/vmtoolsd/l10n/ja.vmsg0000644765153500003110000000475112220061556021202 0ustar dtormts########################################################## # Copyright (C) 2010 VMware, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public # License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # ########################################################## cmdline.background = "バックグラウンドで実行し、pid ファイルを作成します。" cmdline.background.pidfile = "pidfile" cmdline.blockfd = "VMware ブロック fs のファイル記述子です。" cmdline.blockfd.fd = "fd" cmdline.commonpath = "共通プラグイン ディレクトリのパスです。" cmdline.config = "指定されたパスで構成ファイルを使用します。" cmdline.debug = "指定されたプラグインを使用して、デバッグ モードで実行します。" cmdline.displayname = "サービス表示名 (-i のみで使用)。" cmdline.displayname.argument = "名前" cmdline.install = "Service Control Manager を使ってサービスをインストールします。" cmdline.install.args = "args" cmdline.kill = "ツール サービスの実行中のインスタンスを停止します。" cmdline.log = "無視されます。後方互換性のために保持されています。" cmdline.name = "開始されているサービスの名前です。" cmdline.name.argument = "svcname" cmdline.path = "path" cmdline.pluginpath = "プラグイン ディレクトリのパスです。" cmdline.rpc = "ホストへ RPC コマンドを送信し、終了します。" cmdline.rpc.command = "コマンド" cmdline.rpcerror = "VMware ハイパーバイザーにコマンドを送信できません。" cmdline.state = "実行中のサービス インスタンスの内部状態をログにダンプします。" cmdline.uninstall = "Service Control Manager からサービスをアンインストールします。" cmdline.version = "デーモンのバージョンを出力し、終了します。" open-vm-tools-9.4.0-1280544/services/vmtoolsd/l10n/ko.vmsg0000644765153500003110000000455612220061556021224 0ustar dtormts########################################################## # Copyright (C) 2010 VMware, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public # License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # ########################################################## cmdline.background = "백그라운드로 실행하고 pid 파일을 생성합니다." cmdline.background.pidfile = "pidfile" cmdline.blockfd = "VMware 차단 fs에 대한 파일 설명자입니다." cmdline.blockfd.fd = "fd" cmdline.commonpath = "일반 플러그인 디렉토리에 대한 경로입니다." cmdline.config = "지정된 경로에 있는 구성 파일을 사용합니다." cmdline.debug = "지정된 플러그인을 사용하여 디버그 모드를 실행합니다." cmdline.displayname = "서비스 표시 이름입니다(-i와 함께 사용)." cmdline.displayname.argument = "이름" cmdline.install = "서비스 제어 관리자를 사용하여 서비스를 설치합니다." cmdline.install.args = "args" cmdline.kill = "실행 중인 VMware Tools 서비스의 인스턴스를 중지합니다." cmdline.log = "무시되며, 이전 버전과의 호환성을 위해 유지됩니다." cmdline.name = "시작될 서비스의 이름입니다." cmdline.name.argument = "svcname" cmdline.path = "경로" cmdline.pluginpath = "플러그인 디렉토리에 대한 경로입니다." cmdline.rpc = "RPC 명령을 호스트에 보내고 종료합니다." cmdline.rpc.command = "명령" cmdline.rpcerror = "VMware 하이퍼바이저에 명령을 보낼 수 없습니다." cmdline.state = "실행 중인 서비스 인스턴스의 내부 상태를 로그에 덤프합니다." cmdline.uninstall = "서비스 제어 관리자에서 서비스를 제거합니다." cmdline.version = "대몬 버전을 출력하고 종료합니다." open-vm-tools-9.4.0-1280544/services/vmtoolsd/pluginMgr.c0000644765153500003110000006537512220061556021261 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file pluginMgr.c * * Provides functions for loading and manipulating Tools plugins. */ #include #include "toolsCoreInt.h" #include "vm_assert.h" #include "guestApp.h" #include "serviceObj.h" #include "util.h" #include "vmware/tools/i18n.h" #include "vmware/tools/log.h" #include "vmware/tools/utils.h" /** Defines the internal data about a plugin. */ typedef struct ToolsPlugin { gchar *fileName; GModule *module; ToolsPluginOnLoad onload; ToolsPluginData *data; } ToolsPlugin; #ifdef USE_APPLOADER static Bool (*LoadDependencies)(char *libName, Bool useShipped); #endif typedef void (*PluginDataCallback)(ToolsServiceState *state, ToolsPluginData *plugin); typedef gboolean (*PluginAppRegCallback)(ToolsServiceState *state, ToolsPluginData *plugin, ToolsAppType type, ToolsAppProviderReg *preg, gpointer reg); /** * State dump callback for application registration information. * * @param[in] state The service state. * @param[in] plugin The plugin information. * @param[in] type Application type. * @param[in] preg Provider information. * @param[in] reg Application registration. * * @return TRUE */ static gboolean ToolsCoreDumpAppInfo(ToolsServiceState *state, ToolsPluginData *plugin, ToolsAppType type, ToolsAppProviderReg *preg, gpointer reg) { if (preg != NULL) { if (preg->prov->dumpState != NULL) { preg->prov->dumpState(&state->ctx, preg->prov, reg); } else { ToolsCore_LogState(TOOLS_STATE_LOG_PLUGIN, "App type %u (no provider info).\n", type); } } else { ToolsCore_LogState(TOOLS_STATE_LOG_PLUGIN, "App type %u (no provider).\n", type); } return TRUE; } /** * State dump callback for generic plugin information. * * @param[in] state The service state. * @param[in] plugin The plugin information. */ static void ToolsCoreDumpPluginInfo(ToolsServiceState *state, ToolsPluginData *plugin) { ToolsCore_LogState(TOOLS_STATE_LOG_CONTAINER, "Plugin: %s\n", plugin->name); if (plugin->regs == NULL) { ToolsCore_LogState(TOOLS_STATE_LOG_PLUGIN, "No registrations.\n"); } } /** * State dump callback for service properties. * * @param[in] ctx The application context. * @param[in] prov Unused. * @param[in] reg The application registration data. */ static void ToolsCoreDumpProperty(ToolsAppCtx *ctx, ToolsAppProvider *prov, gpointer reg) { if (reg != NULL) { ToolsCore_LogState(TOOLS_STATE_LOG_PLUGIN, "Service property: %s.\n", ((ToolsServiceProperty *)reg)->name); } } /** * State dump callback for GuestRPC applications. * * @param[in] ctx The application context. * @param[in] prov Unused. * @param[in] reg The application registration data. */ static void ToolsCoreDumpRPC(ToolsAppCtx *ctx, ToolsAppProvider *prov, gpointer reg) { if (reg != NULL) { RpcChannelCallback *cb = reg; ToolsCore_LogState(TOOLS_STATE_LOG_PLUGIN, "RPC callback: %s\n", cb->name); } } /** * State dump callback for signal connections. * * @param[in] ctx The application context. * @param[in] prov Unused. * @param[in] reg The application registration data. */ static void ToolsCoreDumpSignal(ToolsAppCtx *ctx, ToolsAppProvider *prov, gpointer reg) { if (reg != NULL) { ToolsPluginSignalCb *sig = reg; ToolsCore_LogState(TOOLS_STATE_LOG_PLUGIN, "Signal callback: %s\n", sig->signame); } } /** * Frees memory associated with a ToolsPlugin instance. If the plugin hasn't * been initialized yet, this will unload the shared object. * * @param[in] plugin ToolsPlugin instance. */ static void ToolsCoreFreePlugin(ToolsPlugin *plugin) { if (plugin->module != NULL && !g_module_close(plugin->module)) { g_warning("Error unloading plugin '%s': %s\n", plugin->fileName, g_module_error()); } g_free(plugin->fileName); g_free(plugin); } /** * Callback to register applications with the given provider. * * @param[in] state The service state. * @param[in] plugin The plugin information. * @param[in] type Application type. * @param[in] preg Provider information. * @param[in] reg Application registration. * * @return Whether to continue registering other apps. */ static gboolean ToolsCoreRegisterApp(ToolsServiceState *state, ToolsPluginData *plugin, ToolsAppType type, ToolsAppProviderReg *preg, gpointer reg) { gboolean error = TRUE; if (type == TOOLS_APP_PROVIDER) { /* We should already have registered all providers. */ return TRUE; } ASSERT(preg != NULL); if (preg->state == TOOLS_PROVIDER_ERROR) { g_warning("Plugin %s wants to register app of type %d but the " "provider failed to activate.\n", plugin->name, type); goto exit; } /* * Register the app with the provider, activating it if necessary. If * it fails to activate, tag it so we don't try again. */ if (preg->state == TOOLS_PROVIDER_IDLE) { if (preg->prov->activate != NULL) { GError *err = NULL; preg->prov->activate(&state->ctx, preg->prov, &err); if (err != NULL) { g_warning("Error activating provider %s: %s.\n", preg->prov->name, err->message); preg->state = TOOLS_PROVIDER_ERROR; g_clear_error(&err); goto exit; } } preg->state = TOOLS_PROVIDER_ACTIVE; } if (!preg->prov->registerApp(&state->ctx, preg->prov, plugin, reg)) { g_warning("Failed registration of app type %d (%s) from plugin %s.", type, preg->prov->name, plugin->name); goto exit; } error = FALSE; exit: if (error && plugin->errorCb != NULL) { return plugin->errorCb(&state->ctx, type, reg, plugin); } return TRUE; } /** * Callback to register application providers. * * @param[in] state The service state. * @param[in] plugin The plugin information. * @param[in] type Application type. * @param[in] preg Provider information. * @param[in] reg Application registration. * * @return TRUE */ static gboolean ToolsCoreRegisterProvider(ToolsServiceState *state, ToolsPluginData *plugin, ToolsAppType type, ToolsAppProviderReg *preg, gpointer reg) { if (type == TOOLS_APP_PROVIDER) { guint k; ToolsAppProvider *prov = reg; ToolsAppProviderReg newreg = { prov, TOOLS_PROVIDER_IDLE }; ASSERT(prov->name != NULL); ASSERT(prov->registerApp != NULL); /* Assert that no two providers choose the same app type. */ for (k = 0; k < state->providers->len; k++) { ToolsAppProviderReg *existing = &g_array_index(state->providers, ToolsAppProviderReg, k); ASSERT(prov->regType != existing->prov->regType); g_return_val_if_fail(prov->regType != existing->prov->regType, TRUE); } g_array_append_val(state->providers, newreg); } return TRUE; } /** * Iterates through the list of plugins, and through each plugin's app * registration data, calling the appropriate callback for each piece * of data. * * One of the two callback arguments must be provided. * * @param[in] state Service state. * @param[in] pluginCb Callback called for each plugin data instance. * @param[in] appRegCb Callback called for each application registration. */ static void ToolsCoreForEachPlugin(ToolsServiceState *state, PluginDataCallback pluginCb, PluginAppRegCallback appRegCb) { guint i; ASSERT(pluginCb != NULL || appRegCb != NULL); for (i = 0; i < state->plugins->len; i++) { ToolsPlugin *plugin = g_ptr_array_index(state->plugins, i); GArray *regs = (plugin->data != NULL) ? plugin->data->regs : NULL; guint j; if (pluginCb != NULL) { pluginCb(state, plugin->data); } if (regs == NULL || appRegCb == NULL) { continue; } for (j = 0; j < regs->len; j++) { guint k; guint pregIdx; ToolsAppReg *reg = &g_array_index(regs, ToolsAppReg, j); ToolsAppProviderReg *preg = NULL; /* Find the provider for the desired reg type. */ for (k = 0; k < state->providers->len; k++) { ToolsAppProviderReg *tmp = &g_array_index(state->providers, ToolsAppProviderReg, k); if (tmp->prov->regType == reg->type) { preg = tmp; pregIdx = k; break; } } if (preg == NULL) { g_message("Cannot find provider for app type %d, plugin %s may not work.\n", reg->type, plugin->data->name); if (plugin->data->errorCb != NULL && !plugin->data->errorCb(&state->ctx, reg->type, NULL, plugin->data)) { break; } continue; } for (k = 0; k < reg->data->len; k++) { gpointer appdata = ®->data->data[preg->prov->regSize * k]; if (!appRegCb(state, plugin->data, reg->type, preg, appdata)) { /* Break out of the outer loop. */ j = regs->len; break; } /* * The registration callback may have modified the provider array, * so we need to re-read the provider pointer. */ preg = &g_array_index(state->providers, ToolsAppProviderReg, pregIdx); } } } } /** * Callback to register service properties. * * @param[in] ctx The application context. * @param[in] prov Unused. * @param[in] plugin Unused. * @param[in] reg The property registration data. * * @return TRUE */ static gboolean ToolsCoreRegisterProperty(ToolsAppCtx *ctx, ToolsAppProvider *prov, ToolsPluginData *plugin, gpointer reg) { ToolsCoreService_RegisterProperty(ctx->serviceObj, reg); return TRUE; } /** * Registration callback for GuestRPC applications. * * @param[in] ctx The application context. * @param[in] prov Unused. * @param[in] plugin Unused. * @param[in] reg The application registration data. * * @return TRUE. */ static gboolean ToolsCoreRegisterRPC(ToolsAppCtx *ctx, ToolsAppProvider *prov, ToolsPluginData *plugin, gpointer reg) { RpcChannel_RegisterCallback(ctx->rpc, reg); return TRUE; } /** * Registration callback for signal connections. * * @param[in] ctx The application context. * @param[in] prov Unused. * @param[in] plugin Unused. * @param[in] reg The application registration data. * * @return TRUE if the signal exists. */ static gboolean ToolsCoreRegisterSignal(ToolsAppCtx *ctx, ToolsAppProvider *prov, ToolsPluginData *plugin, gpointer reg) { gboolean valid; guint sigId; GQuark sigDetail; ToolsPluginSignalCb *sig = reg; valid = g_signal_parse_name(sig->signame, G_OBJECT_TYPE(ctx->serviceObj), &sigId, &sigDetail, FALSE); if (valid) { g_signal_connect(ctx->serviceObj, sig->signame, sig->callback, sig->clientData); return TRUE; } g_debug("Plugin '%s' unable to connect to signal '%s'.\n", plugin->name, sig->signame); return FALSE; } /** * Compares two strings. To be used with g_ptr_array_sort. * * @param[in] _str1 Pointer to string for comparison. * @param[in] _str2 Pointer to string for comparison. * * @return Result of strcmp. */ static gint ToolsCoreStrPtrCompare(gconstpointer _str1, gconstpointer _str2) { const gchar *str1 = *((const gchar **) _str1); const gchar *str2 = *((const gchar **) _str2); return strcmp(str1, str2); } /** * Loads all the plugins found in the given directory, adding the registration * data to the given array. * * @param[in] ctx Application context. * @param[in] pluginPath Path where to look for plugins. * @param[out] regs Array where to store plugin registration info. */ static gboolean ToolsCoreLoadDirectory(ToolsAppCtx *ctx, const gchar *pluginPath, GPtrArray *regs) { gboolean ret = FALSE; const gchar *staticEntry; guint i; GDir *dir = NULL; GError *err = NULL; GPtrArray *plugins; dir = g_dir_open(pluginPath, 0, &err); if (dir == NULL) { g_warning("Error opening dir: %s\n", err->message); goto exit; } plugins = g_ptr_array_new(); /* * Load plugins in alphabetical order, so the load order is the same * regardless of how the filesystem returns entries. */ while ((staticEntry = g_dir_read_name(dir)) != NULL) { if (g_str_has_suffix(staticEntry, "." G_MODULE_SUFFIX)) { g_ptr_array_add(plugins, g_strdup(staticEntry)); } } g_dir_close(dir); g_ptr_array_sort(plugins, ToolsCoreStrPtrCompare); for (i = 0; i < plugins->len; i++) { gchar *entry; gchar *path; GModule *module = NULL; ToolsPlugin *plugin = NULL; ToolsPluginOnLoad onload; entry = g_ptr_array_index(plugins, i); path = g_strdup_printf("%s%c%s", pluginPath, DIRSEPC, entry); if (!g_file_test(path, G_FILE_TEST_IS_REGULAR)) { g_warning("File '%s' is not a regular file, skipping.\n", entry); goto next; } #ifdef USE_APPLOADER /* Trying loading the plugins with system libraries */ if (!LoadDependencies(path, FALSE)) { g_warning("Loading of library dependencies for %s failed.\n", entry); goto next; } #endif module = g_module_open(path, G_MODULE_BIND_LOCAL); #ifdef USE_APPLOADER if (module == NULL) { /* Falling back to the shipped libraries */ if (!LoadDependencies(path, TRUE)) { g_warning("Loading of shipped library dependencies for %s failed.\n", entry); goto next; } module = g_module_open(path, G_MODULE_BIND_LOCAL); } #endif if (module == NULL) { g_warning("Opening plugin '%s' failed: %s.\n", entry, g_module_error()); goto next; } if (!g_module_symbol(module, "ToolsOnLoad", (gpointer *) &onload)) { g_warning("Lookup of plugin entry point for '%s' failed.\n", entry); goto next; } plugin = g_malloc(sizeof *plugin); plugin->fileName = entry; plugin->data = NULL; plugin->module = module; plugin->onload = onload; g_ptr_array_add(regs, plugin); next: g_free(path); if (plugin == NULL && module != NULL) { if (!g_module_close(module)) { g_warning("Error unloading plugin '%s': %s\n", entry, g_module_error()); } } } g_ptr_array_free(plugins, TRUE); ret = TRUE; exit: return ret; } /** * State dump callback for logging information about loaded plugins. * * @param[in] state The service state. */ void ToolsCore_DumpPluginInfo(ToolsServiceState *state) { if (state->plugins == NULL) { g_message(" No plugins loaded."); } else { ToolsCoreForEachPlugin(state, ToolsCoreDumpPluginInfo, ToolsCoreDumpAppInfo); } } /** * Loads all plugins present in the plugin directory. If the plugin path * is NULL, then default directories are used in case the service is either * the main tools service of the user daemon, otherwise failure is returned. * * @param[in] state The service state. * * @return Whether loading the plugins was successful. */ gboolean ToolsCore_LoadPlugins(ToolsServiceState *state) { gboolean pluginDirExists; gboolean ret = FALSE; gchar *pluginRoot; guint i; GPtrArray *plugins = NULL; #if defined(sun) && defined(__x86_64__) const char *subdir = "/amd64"; #else const char *subdir = ""; #endif #if defined(OPEN_VM_TOOLS) pluginRoot = g_strdup(VMTOOLSD_PLUGIN_ROOT); #else char *instPath = GuestApp_GetInstallPath(); pluginRoot = g_strdup_printf("%s%cplugins", instPath, DIRSEPC); vm_free(instPath); #endif ASSERT(g_module_supported()); #ifdef USE_APPLOADER { Bool ret = FALSE; GModule *mainModule = g_module_open(NULL, G_MODULE_BIND_LAZY); ASSERT(mainModule); ret = g_module_symbol(mainModule, "AppLoader_LoadLibraryDependencies", (gpointer *)&LoadDependencies); g_module_close(mainModule); if (!ret) { g_critical("Unable to locate library dependency loading function.\n"); goto exit; } } #endif plugins = g_ptr_array_new(); /* * First, load plugins from the common directory. The common directory * is not required to exist unless provided on the command line. */ if (state->commonPath == NULL) { state->commonPath = g_strdup_printf("%s%s%c%s", pluginRoot, subdir, DIRSEPC, TOOLSCORE_COMMON); } else if (!g_file_test(state->commonPath, G_FILE_TEST_IS_DIR)) { g_warning("Common plugin path is not a directory: %s\n", state->commonPath); goto exit; } if (g_file_test(state->commonPath, G_FILE_TEST_IS_DIR) && !ToolsCoreLoadDirectory(&state->ctx, state->commonPath, plugins)) { goto exit; } /* * Load the container-specific plugins. Ignore if the plugin directory * doesn't exist when running in debug mode. */ if (state->pluginPath == NULL) { state->pluginPath = g_strdup_printf("%s%s%c%s", pluginRoot, subdir, DIRSEPC, state->name); } pluginDirExists = g_file_test(state->pluginPath, G_FILE_TEST_IS_DIR); if (state->debugPlugin == NULL && !pluginDirExists) { g_warning("Plugin path is not a directory: %s\n", state->pluginPath); goto exit; } if (pluginDirExists && !ToolsCoreLoadDirectory(&state->ctx, state->pluginPath, plugins)) { goto exit; } /* * All plugins are loaded, now initialize them. */ state->plugins = g_ptr_array_new(); for (i = 0; i < plugins->len; i++) { ToolsPlugin *plugin = g_ptr_array_index(plugins, i); plugin->data = plugin->onload(&state->ctx); if (plugin->data == NULL) { g_info("Plugin '%s' didn't provide deployment data, unloading.\n", plugin->fileName); ToolsCoreFreePlugin(plugin); } else if (state->ctx.errorCode != 0) { /* Break early if a plugin has requested the container to quit. */ ToolsCoreFreePlugin(plugin); break; } else { ASSERT(plugin->data->name != NULL); g_module_make_resident(plugin->module); g_ptr_array_add(state->plugins, plugin); VMTools_BindTextDomain(plugin->data->name, NULL, NULL); g_debug("Plugin '%s' initialized.\n", plugin->data->name); } } /* * If there is a debug plugin, see if it exports standard plugin registration * data too. */ if (state->debugData != NULL && state->debugData->debugPlugin->plugin != NULL) { ToolsPluginData *data = state->debugData->debugPlugin->plugin; ToolsPlugin *plugin = g_malloc(sizeof *plugin); plugin->fileName = NULL; plugin->module = NULL; plugin->data = data; VMTools_BindTextDomain(data->name, NULL, NULL); g_ptr_array_add(state->plugins, plugin); } ret = TRUE; exit: if (plugins != NULL) { g_ptr_array_free(plugins, TRUE); } g_free(pluginRoot); return ret; } /** * Registers all RPC handlers provided by the loaded and enabled plugins. * * @param[in] state The service state. */ void ToolsCore_RegisterPlugins(ToolsServiceState *state) { ToolsAppProvider *fakeProv; ToolsAppProviderReg fakeReg; if (state->plugins == NULL) { return; } /* * Create "fake" app providers for the functionality provided by * vmtoolsd (GuestRPC channel, glib signals, custom app providers). */ state->providers = g_array_new(FALSE, TRUE, sizeof (ToolsAppProviderReg)); if (state->ctx.rpc != NULL) { fakeProv = g_malloc0(sizeof *fakeProv); fakeProv->regType = TOOLS_APP_GUESTRPC; fakeProv->regSize = sizeof (RpcChannelCallback); fakeProv->name = "GuestRPC"; fakeProv->registerApp = ToolsCoreRegisterRPC; fakeProv->dumpState = ToolsCoreDumpRPC; fakeReg.prov = fakeProv; fakeReg.state = TOOLS_PROVIDER_ACTIVE; g_array_append_val(state->providers, fakeReg); } fakeProv = g_malloc0(sizeof *fakeProv); fakeProv->regType = TOOLS_APP_SIGNALS; fakeProv->regSize = sizeof (ToolsPluginSignalCb); fakeProv->name = "Signals"; fakeProv->registerApp = ToolsCoreRegisterSignal; fakeProv->dumpState = ToolsCoreDumpSignal; fakeReg.prov = fakeProv; fakeReg.state = TOOLS_PROVIDER_ACTIVE; g_array_append_val(state->providers, fakeReg); fakeProv = g_malloc0(sizeof *fakeProv); fakeProv->regType = TOOLS_APP_PROVIDER; fakeProv->regSize = sizeof (ToolsAppProvider); fakeProv->name = "App Provider"; fakeProv->registerApp = NULL; fakeProv->dumpState = NULL; fakeReg.prov = fakeProv; fakeReg.state = TOOLS_PROVIDER_ACTIVE; g_array_append_val(state->providers, fakeReg); fakeProv = g_malloc0(sizeof *fakeProv); fakeProv->regType = TOOLS_SVC_PROPERTY; fakeProv->regSize = sizeof (ToolsServiceProperty); fakeProv->name = "Service Properties"; fakeProv->registerApp = ToolsCoreRegisterProperty; fakeProv->dumpState = ToolsCoreDumpProperty; fakeReg.prov = fakeProv; fakeReg.state = TOOLS_PROVIDER_ACTIVE; g_array_append_val(state->providers, fakeReg); /* * First app providers need to be identified, so that we know that they're * available for use by plugins who need them. */ ToolsCoreForEachPlugin(state, NULL, ToolsCoreRegisterProvider); /* * Now that we know all app providers, register all the apps, activating * individual app providers as necessary. */ ToolsCoreForEachPlugin(state, NULL, ToolsCoreRegisterApp); } /** * Calls the shutdown callback for all loaded plugins, and cleans up the list * of loaded plugins. Plugins are unloaded in the opposite order they were * loaded. * * Note that if a plugin does not provide a shutdown callback, it may leak * data that may have been dynamically allocated in the plugin registration * info. Since this function is intended to be called once during service * shutdown, this it not that big of a deal. * * @param[in] state The service state. */ void ToolsCore_UnloadPlugins(ToolsServiceState *state) { guint i; if (state->plugins == NULL) { return; } if (state->capsRegistered) { GArray *pcaps = NULL; g_signal_emit_by_name(state->ctx.serviceObj, TOOLS_CORE_SIG_CAPABILITIES, &state->ctx, FALSE, &pcaps); if (pcaps != NULL) { if (state->ctx.rpc) { ToolsCore_SetCapabilities(state->ctx.rpc, pcaps, FALSE); } g_array_free(pcaps, TRUE); } } /* * Stop all app providers, and free the memory we allocated for the * internal app providers. */ for (i = 0; state->providers != NULL && i < state->providers->len; i++) { ToolsAppProviderReg *preg = &g_array_index(state->providers, ToolsAppProviderReg, i); if (preg->prov->shutdown != NULL && preg->state == TOOLS_PROVIDER_ACTIVE) { preg->prov->shutdown(&state->ctx, preg->prov); } if (preg->prov->regType == TOOLS_APP_GUESTRPC || preg->prov->regType == TOOLS_APP_SIGNALS || preg->prov->regType == TOOLS_APP_PROVIDER || preg->prov->regType == TOOLS_SVC_PROPERTY) { g_free(preg->prov); } } g_signal_emit_by_name(state->ctx.serviceObj, TOOLS_CORE_SIG_SHUTDOWN, &state->ctx); while (state->plugins->len > 0) { ToolsPlugin *plugin = g_ptr_array_index(state->plugins, state->plugins->len - 1); GArray *regs = (plugin->data != NULL) ? plugin->data->regs : NULL; g_debug("Unloading plugin '%s'.\n", plugin->data->name); if (regs != NULL) { guint i; for (i = 0; i < regs->len; i++) { ToolsAppReg *reg = &g_array_index(regs, ToolsAppReg, i); if (reg->data != NULL) { g_array_free(reg->data, TRUE); } } g_array_free(regs, TRUE); } g_ptr_array_remove_index(state->plugins, state->plugins->len - 1); ToolsCoreFreePlugin(plugin); } if (state->providers != NULL) { g_array_free(state->providers, TRUE); state->providers = NULL; } g_ptr_array_free(state->plugins, TRUE); state->plugins = NULL; } open-vm-tools-9.4.0-1280544/services/vmtoolsd/serviceObj.c0000644765153500003110000003345412220061556021401 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file serviceObj.c * * Implementation of the "ToolsCore_Service" gobject. */ #include "toolsCoreInt.h" #include "serviceObj.h" #include "svcSignals.h" typedef struct ServiceProperty { guint id; gchar *name; gpointer value; } ServiceProperty; static gpointer gToolsCoreServiceParentClass; /** * Accumulator function for the "set option" signal. If a handler returns * TRUE, sets the result of the signal propagation to TRUE. * * @param[in] ihint Unused. * @param[out] retval Return value of the signal. * @param[in] handlerRet Return value from the current handler. * @param[in] data Unused. * * @return TRUE */ static gboolean ToolsCoreSetOptionAccumulator(GSignalInvocationHint *ihint, GValue *retval, const GValue *handlerRet, gpointer data) { if (!g_value_get_boolean(retval)) { g_value_set_boolean(retval, g_value_get_boolean(handlerRet)); } return TRUE; } /** * Accumulator function for the "capabilities" signal. Just puts the contents * of all returned GArray instances into a "master" instance. * * @param[in] ihint Unused. * @param[out] retval Return value of the signal. * @param[in] handlerRet Return value from the current handler. * @param[in] data Unused. * * @return TRUE. */ static gboolean ToolsCoreCapabilitiesAccumulator(GSignalInvocationHint *ihint, GValue *retval, const GValue *handlerRet, gpointer data) { GArray *caps = g_value_get_pointer(handlerRet); if (caps != NULL) { guint i; GArray *acc = g_value_get_pointer(retval); if (acc == NULL) { acc = g_array_new(FALSE, TRUE, sizeof (ToolsAppCapability)); g_value_set_pointer(retval, acc); } for (i = 0; i < caps->len; i++) { g_array_append_val(acc, g_array_index(caps, ToolsAppCapability, i)); } g_array_free(caps, TRUE); } return TRUE; } #if defined(_WIN32) /** * Accumulator function for the "service control" signal. Updates the return * value according to the signal's documentation. * * The gobject library initializes the return value to "0" regardless of * what the signal emitter sets it to. So the accumulator does two things * to have a non-zero default return value: * * - if the current return value is zero, it's set to the default return * value (ERROR_CALL_NOT_IMPLEMENTED). * - the return value is always offset by one; so the signal emitter * should decrement the return value when looking at it. * * @param[in] ihint Unused. * @param[in,out] retval Return value of the signal (offset by 1). * @param[in] handlerRet Return value from the current handler. * @param[in] data Unused. * * @return TRUE. */ static gboolean ToolsCoreServiceControlAccumulator(GSignalInvocationHint *ihint, GValue *retval, const GValue *handlerRet, gpointer data) { guint ret = g_value_get_uint(retval); guint handlerVal = g_value_get_uint(handlerRet); if (ret == 0) { ret = ERROR_CALL_NOT_IMPLEMENTED + 1; } switch (ret) { case ERROR_CALL_NOT_IMPLEMENTED + 1: ret = handlerVal + 1; break; case NO_ERROR + 1: if (handlerVal != ERROR_CALL_NOT_IMPLEMENTED) { ret = handlerVal + 1; } break; default: break; } g_value_set_uint(retval, ret); return TRUE; } #endif /* ******************************************************************************* * ToolsCoreServiceGetProperty -- */ /** * * Gets the value of a property in the object. * * @param[in] object The instance. * @param[in] id Property ID. * @param[out] value Where to set the value. * @param[in] pspec Unused. * ******************************************************************************* */ static void ToolsCoreServiceGetProperty(GObject *object, guint id, GValue *value, GParamSpec *pspec) { ToolsCoreService *self = (ToolsCoreService *) object; id -= 1; g_mutex_lock(self->lock); if (id < self->props->len) { ServiceProperty *p = &g_array_index(self->props, ServiceProperty, id); g_value_set_pointer(value, p->value); } g_mutex_unlock(self->lock); } /* ******************************************************************************* * ToolsCoreServiceSetProperty -- */ /** * * Sets a property in the given object. If the property is found, a "notify" * signal is sent so that interested listeners can act on the change. * * @param[in] object The instance. * @param[in] id Property ID. * @param[in] value Value to set. * @param[in] pspec Unused. * ******************************************************************************* */ static void ToolsCoreServiceSetProperty(GObject *object, guint id, const GValue *value, GParamSpec *pspec) { ServiceProperty *p = NULL; ToolsCoreService *self = (ToolsCoreService *) object; id -= 1; g_mutex_lock(self->lock); if (id < self->props->len) { p = &g_array_index(self->props, ServiceProperty, id); p->value = g_value_get_pointer(value); } g_mutex_unlock(self->lock); if (p != NULL) { g_object_notify(object, p->name); } } /* ******************************************************************************* * ToolsCoreServiceCtor -- */ /** * * Object constructor. Initialize internal state. * * @param[in] type Object type. * @param[in] nparams Param count. * @param[in] params Construction parameters. * * @return A new instance. * ******************************************************************************* */ static GObject * ToolsCoreServiceCtor(GType type, guint nparams, GObjectConstructParam *params) { GObject *object; ToolsCoreService *self; object = G_OBJECT_CLASS(gToolsCoreServiceParentClass)->constructor(type, nparams, params); self = TOOLSCORE_SERVICE(object); self->lock = g_mutex_new(); self->props = g_array_new(FALSE, FALSE, sizeof (ServiceProperty)); return object; } /* ******************************************************************************* * ToolsCoreServiceDtor -- */ /** * * Object destructor. Frees memory associated with the object. Goes through the * list of properties to make sure all of them have been cleaned up before the * service exits, printing a warning otherwise. * * @param[in] object The object being destructed. * ******************************************************************************* */ static void ToolsCoreServiceDtor(GObject *object) { ToolsCoreService *self = (ToolsCoreService *) object; guint i; for (i = 0; i < self->props->len; i++) { ServiceProperty *p = &g_array_index(self->props, ServiceProperty, i); if (p->value != NULL) { g_warning("Property '%s' was not cleaned up before shut down.", p->name); } g_free(p->name); } g_array_free(self->props, TRUE); g_mutex_free(self->lock); } /** * Initializes the ToolsCoreService class. Sets up the signals that are sent * by the vmtoolsd service. * * @param[in] klass The class instance to initialize. */ static void ToolsCore_Service_class_init(gpointer _klass, gpointer klassData) { ToolsCoreServiceClass *klass = _klass; gToolsCoreServiceParentClass = g_type_class_peek_parent(_klass); g_signal_new(TOOLS_CORE_SIG_CAPABILITIES, G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_LAST, 0, ToolsCoreCapabilitiesAccumulator, NULL, g_cclosure_user_marshal_POINTER__POINTER_BOOLEAN, G_TYPE_POINTER, 2, G_TYPE_POINTER, G_TYPE_BOOLEAN); g_signal_new(TOOLS_CORE_SIG_CONF_RELOAD, G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); g_signal_new(TOOLS_CORE_SIG_DUMP_STATE, G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); g_signal_new(TOOLS_CORE_SIG_RESET, G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); g_signal_new(TOOLS_CORE_SIG_SET_OPTION, G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_LAST, 0, ToolsCoreSetOptionAccumulator, NULL, g_cclosure_user_marshal_BOOLEAN__POINTER_STRING_STRING, G_TYPE_BOOLEAN, 3, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING); g_signal_new(TOOLS_CORE_SIG_SHUTDOWN, G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); #if defined(G_PLATFORM_WIN32) g_signal_new(TOOLS_CORE_SIG_SERVICE_CONTROL, G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_LAST, 0, ToolsCoreServiceControlAccumulator, NULL, g_cclosure_user_marshal_UINT__POINTER_POINTER_UINT_UINT_POINTER, G_TYPE_UINT, 5, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_POINTER); #endif G_OBJECT_CLASS(klass)->constructor = ToolsCoreServiceCtor; G_OBJECT_CLASS(klass)->finalize = ToolsCoreServiceDtor; G_OBJECT_CLASS(klass)->set_property = ToolsCoreServiceSetProperty; G_OBJECT_CLASS(klass)->get_property = ToolsCoreServiceGetProperty; } /** * Initializes the ToolsCoreService type if it hasn't been done yet, and * return the type instance. This method is not thread safe. * * @return The ToolsCoreService type. */ GType ToolsCore_Service_get_type(void) { static GType type = 0; if (type == 0) { static const GTypeInfo info = { sizeof (ToolsCoreServiceClass), NULL, /* base_init */ NULL, /* base_finalize */ ToolsCore_Service_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (ToolsCoreService), 0, /* n_preallocs */ NULL, /* instance_init */ }; type = g_type_register_static(G_TYPE_OBJECT, "ToolsCoreService", &info, 0); } return type; } /* ******************************************************************************* * ToolsCoreService_RegisterProperty -- */ /** * * Installs a new property in the service object. * * @param[in] obj Service object. * @param[in] prop Property to install. * ******************************************************************************* */ void ToolsCoreService_RegisterProperty(ToolsCoreService *obj, ToolsServiceProperty *prop) { static guint PROP_ID_SEQ = 0; ServiceProperty sprop; ToolsCoreServiceClass *klass = TOOLSCORESERVICE_GET_CLASS(obj); GParamSpec *pspec = g_param_spec_pointer(prop->name, prop->name, prop->name, G_PARAM_READWRITE); g_mutex_lock(obj->lock); sprop.id = ++PROP_ID_SEQ; sprop.name = g_strdup(prop->name); sprop.value = NULL; g_array_append_val(obj->props, sprop); g_object_class_install_property(G_OBJECT_CLASS(klass), sprop.id, pspec); g_mutex_unlock(obj->lock); } open-vm-tools-9.4.0-1280544/services/vmtoolsd/threadPool.c0000644765153500003110000003760512220061556021411 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file threadPool.c * * Implementation of the shared thread pool defined in threadPool.h. */ #include #include #include "vmware.h" #include "toolsCoreInt.h" #include "serviceObj.h" #include "vmware/tools/threadPool.h" #define DEFAULT_MAX_IDLE_TIME 5000 #define DEFAULT_MAX_THREADS 5 #define DEFAULT_MAX_UNUSED_THREADS 0 typedef struct ThreadPoolState { ToolsCorePool funcs; gboolean active; ToolsAppCtx *ctx; GThreadPool *pool; GQueue *workQueue; GPtrArray *threads; GMutex *lock; guint nextWorkId; } ThreadPoolState; typedef struct WorkerTask { guint id; guint srcId; ToolsCorePoolCb cb; gpointer data; GDestroyNotify dtor; } WorkerTask; typedef struct StandaloneTask { gboolean active; ToolsCorePoolCb cb; ToolsCorePoolCb interrupt; gpointer data; GThread *thread; GDestroyNotify dtor; } StandaloneTask; static ThreadPoolState gState; /* ******************************************************************************* * ToolsCorePoolCompareTask -- */ /** * * Compares two WorkerTask instances. * * @param[in] p1 Pointer to WorkerTask. * @param[in] p2 Pointer to WorkerTask. * * @return > 0, 0, < 0 if p1's ID is less than, equal, or greater than p2's. * ******************************************************************************* */ static gint ToolsCorePoolCompareTask(gconstpointer p1, gconstpointer p2) { const WorkerTask *t1 = p1; const WorkerTask *t2 = p2; if (t1 != NULL && t2 != NULL) { return (t2->id - t1->id); } if (t1 == NULL && t2 == NULL) { return 0; } return (t1 != NULL) ? -1 : 1; } /* ******************************************************************************* * ToolsCorePoolDestroyThread -- */ /** * * Releases resources associated with a StandaloneTask, joining the thread * that's executing it. * * @param[in] data A StandaloneTask. * ******************************************************************************* */ static void ToolsCorePoolDestroyThread(gpointer data) { StandaloneTask *task = data; g_thread_join(task->thread); if (task->dtor != NULL) { task->dtor(task->data); } g_free(task); } /* ******************************************************************************* * ToolsCorePoolDestroyTask -- */ /** * * Frees memory associated with a WorkerTask, calling its destructor if one is * registered. * * @param[in] data A WorkerTask. * ******************************************************************************* */ static void ToolsCorePoolDestroyTask(gpointer data) { WorkerTask *work = data; if (work->dtor != NULL) { work->dtor(work->data); } g_free(work); } /* ******************************************************************************* * ToolsCorePoolDoWork -- */ /** * * Execute a work item. * * @param[in] data A WorkerTask. * * @return FALSE * ******************************************************************************* */ static gboolean ToolsCorePoolDoWork(gpointer data) { WorkerTask *work = data; /* * In single threaded mode, remove the task being executed from the queue. * In multi-threaded mode, the thread pool callback already did this. */ if (gState.pool == NULL) { g_mutex_lock(gState.lock); g_queue_remove(gState.workQueue, work); g_mutex_unlock(gState.lock); } work->cb(gState.ctx, work->data); return FALSE; } /* ******************************************************************************* * ToolsCorePoolNoOp -- */ /** * * Idle callback for destroying a standalone thread. Does nothing, since the * actual destruction is done by ToolsCorePoolDestroyThread. * * @param[in] data Unused. * * @return FALSE * ******************************************************************************* */ static gboolean ToolsCorePoolNoOp(gpointer data) { return FALSE; } /* ******************************************************************************* * ToolsCorePoolRunThread -- */ /** * * Standalone thread runner. Executes the task associated with the thread, and * schedule a task to clean up the thread state when done. * * @param[in] data A StandaloneTask. * * @return NULL * ******************************************************************************* */ static gpointer ToolsCorePoolRunThread(gpointer data) { StandaloneTask *task = data; task->cb(gState.ctx, task->data); task->active = FALSE; g_mutex_lock(gState.lock); /* If not active, the shutdown function will clean things up. */ if (gState.active) { g_ptr_array_remove(gState.threads, task); g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, ToolsCorePoolNoOp, task, ToolsCorePoolDestroyThread); } g_mutex_unlock(gState.lock); return NULL; } /* ******************************************************************************* * ToolsCorePoolRunWorker -- */ /** * * Thread pool callback function. Dequeues the next work item from the work * queue and execute it. * * @param[in] state Description of state. * @param[in] clientData Description of clientData. * ******************************************************************************* */ static void ToolsCorePoolRunWorker(gpointer state, gpointer clientData) { WorkerTask *work; g_mutex_lock(gState.lock); work = g_queue_pop_tail(gState.workQueue); g_mutex_unlock(gState.lock); ASSERT(work != NULL); ToolsCorePoolDoWork(work); ToolsCorePoolDestroyTask(work); } /* ******************************************************************************* * ToolsCorePoolSubmit -- */ /** * * Submits a new task for execution in one of the shared worker threads. * * @see ToolsCorePool_SubmitTask() * * @param[in] ctx Application context. * @param[in] cb Function to execute the task. * @param[in] data Opaque data for the task. * @param[in] dtor Destructor for the task data. * * @return New task's ID, or 0 on error. * ******************************************************************************* */ static guint ToolsCorePoolSubmit(ToolsAppCtx *ctx, ToolsCorePoolCb cb, gpointer data, GDestroyNotify dtor) { guint id = 0; WorkerTask *task = g_malloc0(sizeof *task); task->srcId = 0; task->cb = cb; task->data = data; task->dtor = dtor; g_mutex_lock(gState.lock); if (!gState.active) { g_free(task); goto exit; } /* * XXX: a reeeeeeeeeally long running task could cause clashes (e.g., reusing * the same task ID after the counter wraps). That shouldn't really happen in * practice (and is an abuse of the thread pool, and could cause issues if * someone sets the pool size to 0 or 1), but it might be good to have more * fail-safe code here. */ if (gState.nextWorkId + 1 == UINT_MAX) { task->id = UINT_MAX; gState.nextWorkId = 0; } else { task->id = ++gState.nextWorkId; } id = task->id; /* * We always add the task to the queue, even in single threaded mode, so * that it can be canceled. In single threaded mode, it's unlikely someone * will be able to cancel it before it runs, but they can try. */ g_queue_push_head(gState.workQueue, task); if (gState.pool != NULL) { GError *err = NULL; /* The client data pointer is bogus, just to avoid passing NULL. */ g_thread_pool_push(gState.pool, &gState, &err); if (err == NULL) { goto exit; } else { g_warning("error sending work request, executing in service thread: %s", err->message); g_clear_error(&err); } } /* Run the task in the service's thread. */ task->srcId = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, ToolsCorePoolDoWork, task, ToolsCorePoolDestroyTask); exit: g_mutex_unlock(gState.lock); return id; } /* ******************************************************************************* * ToolsCorePoolCancel -- */ /** * * Cancels a queue task. * * @see ToolsCorePool_CancelTask() * * @param[in] id Task ID. * ******************************************************************************* */ static void ToolsCorePoolCancel(guint id) { GList *taskLnk; WorkerTask *task = NULL; WorkerTask search = { id, }; g_return_if_fail(id != 0); g_mutex_lock(gState.lock); if (!gState.active) { goto exit; } taskLnk = g_queue_find_custom(gState.workQueue, &search, ToolsCorePoolCompareTask); if (taskLnk != NULL) { task = taskLnk->data; g_queue_delete_link(gState.workQueue, taskLnk); } exit: g_mutex_unlock(gState.lock); if (task != NULL) { if (task->srcId > 0) { g_source_remove(task->srcId); } else { ToolsCorePoolDestroyTask(task); } } } /* ******************************************************************************* * ToolsCorePoolStart -- */ /** * * Start a new task in a dedicated thread. * * @see ToolsCorePool_StartThread() * * @param[in] ctx Application context. * @param[in] cb Callback that executes the task. * @param[in] interrupt Callback that interrupts the task. * @param[in] data Opaque data. * @param[in] dtor Destructor for the task data. * * @return TRUE iff thread was successfully started. * ******************************************************************************* */ static gboolean ToolsCorePoolStart(ToolsAppCtx *ctx, ToolsCorePoolCb cb, ToolsCorePoolCb interrupt, gpointer data, GDestroyNotify dtor) { GError *err = NULL; StandaloneTask *task = NULL; g_mutex_lock(gState.lock); if (!gState.active) { goto exit; } task = g_malloc0(sizeof *task); task->active = TRUE; task->cb = cb; task->interrupt = interrupt; task->data = data; task->dtor = dtor; task->thread = g_thread_create(ToolsCorePoolRunThread, task, TRUE, &err); if (err == NULL) { g_ptr_array_add(gState.threads, task); } else { g_warning("failed to start thread: %s.", err->message); g_clear_error(&err); g_free(task); task = NULL; } exit: g_mutex_unlock(gState.lock); return task != NULL; } /* ******************************************************************************* * ToolsCorePool_Init -- */ /** * * Initializes the shared thread pool. Reads configuration data from the * container-specific section of the config dictionary, so different containers * can have different configuration. Exports the thread pool functions through * the service's object. * * @param[in] ctx Application context. * ******************************************************************************* */ void ToolsCorePool_Init(ToolsAppCtx *ctx) { gint maxThreads; GError *err = NULL; ToolsServiceProperty prop = { TOOLS_CORE_PROP_TPOOL }; gState.funcs.submit = ToolsCorePoolSubmit; gState.funcs.cancel = ToolsCorePoolCancel; gState.funcs.start = ToolsCorePoolStart; gState.ctx = ctx; maxThreads = g_key_file_get_integer(ctx->config, ctx->name, "pool.maxThreads", &err); if (err != NULL) { maxThreads = DEFAULT_MAX_THREADS; g_clear_error(&err); } if (maxThreads > 0) { gState.pool = g_thread_pool_new(ToolsCorePoolRunWorker, NULL, maxThreads, FALSE, &err); if (err == NULL) { #if GLIB_CHECK_VERSION(2, 10, 0) gint maxIdleTime; gint maxUnused; maxIdleTime = g_key_file_get_integer(ctx->config, ctx->name, "pool.maxIdleTime", &err); if (err != NULL || maxIdleTime <= 0) { maxIdleTime = DEFAULT_MAX_IDLE_TIME; g_clear_error(&err); } maxUnused = g_key_file_get_integer(ctx->config, ctx->name, "pool.maxUnusedThreads", &err); if (err != NULL || maxUnused < 0) { maxUnused = DEFAULT_MAX_UNUSED_THREADS; g_clear_error(&err); } g_thread_pool_set_max_idle_time(maxIdleTime); g_thread_pool_set_max_unused_threads(maxUnused); #endif } else { g_warning("error initializing thread pool, running single threaded: %s", err->message); g_clear_error(&err); } } gState.active = TRUE; gState.lock = g_mutex_new(); gState.threads = g_ptr_array_new(); gState.workQueue = g_queue_new(); ToolsCoreService_RegisterProperty(ctx->serviceObj, &prop); g_object_set(ctx->serviceObj, TOOLS_CORE_PROP_TPOOL, &gState.funcs, NULL); } /* ******************************************************************************* * ToolsCorePool_Shutdown -- */ /** * * Shuts down the shared thread pool. This function will interrupt any running * threads (by calling their registered interrupt function), and wait for all * running tasks to finish before cleaning the remaining tasks and shared state. * * @param[in] ctx Application context. * ******************************************************************************* */ void ToolsCorePool_Shutdown(ToolsAppCtx *ctx) { guint i; g_mutex_lock(gState.lock); gState.active = FALSE; g_mutex_unlock(gState.lock); /* Notify all spawned threads to stop. */ for (i = 0; i < gState.threads->len; i++) { StandaloneTask *task = g_ptr_array_index(gState.threads, i); if (task->active && task->interrupt) { task->interrupt(gState.ctx, task->data); } } /* Stop the thread pool. */ if (gState.pool != NULL) { g_thread_pool_free(gState.pool, TRUE, TRUE); } /* Join all spawned threads. */ for (i = 0; i < gState.threads->len; i++) { StandaloneTask *task = g_ptr_array_index(gState.threads, i); ToolsCorePoolDestroyThread(task); } /* Destroy all pending tasks. */ while (1) { WorkerTask *task = g_queue_pop_tail(gState.workQueue); if (task != NULL) { ToolsCorePoolDestroyTask(task); } else { break; } } /* Cleanup. */ g_ptr_array_free(gState.threads, TRUE); g_queue_free(gState.workQueue); g_mutex_free(gState.lock); memset(&gState, 0, sizeof gState); g_object_set(ctx->serviceObj, TOOLS_CORE_PROP_TPOOL, NULL, NULL); } open-vm-tools-9.4.0-1280544/services/vmtoolsd/COPYING0000644765153500003110000006347112220061556020177 0ustar dtormts GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! open-vm-tools-9.4.0-1280544/services/vmtoolsd/Makefile.am0000644765153500003110000000550212220061556021167 0ustar dtormts################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ bin_PROGRAMS = vmtoolsd pamdir = $(PAM_PREFIX)/pam.d vmtoolsd_CPPFLAGS = vmtoolsd_CPPFLAGS += @VMTOOLS_CPPFLAGS@ vmtoolsd_CPPFLAGS += @GMODULE_CPPFLAGS@ vmtoolsd_CPPFLAGS += @GOBJECT_CPPFLAGS@ vmtoolsd_CPPFLAGS += @GTHREAD_CPPFLAGS@ vmtoolsd_CPPFLAGS += -I$(builddir) vmtoolsd_CPPFLAGS += -DVMTOOLSD_PLUGIN_ROOT=\"$(pkglibdir)/plugins\" vmtoolsd_LDADD = vmtoolsd_LDADD += @VMTOOLS_LIBS@ vmtoolsd_LDADD += @GMODULE_LIBS@ vmtoolsd_LDADD += @GOBJECT_LIBS@ vmtoolsd_LDADD += @GTHREAD_LIBS@ vmtoolsd_SOURCES = vmtoolsd_SOURCES += cmdLine.c vmtoolsd_SOURCES += mainLoop.c vmtoolsd_SOURCES += mainPosix.c vmtoolsd_SOURCES += pluginMgr.c vmtoolsd_SOURCES += serviceObj.c vmtoolsd_SOURCES += threadPool.c vmtoolsd_SOURCES += toolsRpc.c vmtoolsd_SOURCES += svcSignals.c BUILT_SOURCES = BUILT_SOURCES += svcSignals.c BUILT_SOURCES += svcSignals.h CLEANFILES = CLEANFILES += svcSignals.c CLEANFILES += svcSignals.h EXTRA_DIST = EXTRA_DIST += svcSignals.gm svcSignals.c: $(top_srcdir)/services/vmtoolsd/svcSignals.gm glib-genmarshal --body $(top_srcdir)/services/vmtoolsd/svcSignals.gm > \ $@ || (rm -f $@ && exit 1) svcSignals.h: $(top_srcdir)/services/vmtoolsd/svcSignals.gm glib-genmarshal --header $(top_srcdir)/services/vmtoolsd/svcSignals.gm > \ $@ || (rm -f $@ && exit 1) if HAVE_ICU vmtoolsd_LDADD += @ICU_LIBS@ vmtoolsd_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXX) \ $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ else vmtoolsd_LINK = $(LINK) endif # PAM support is currently only available for Linux, so HAVE_PAM is only # defined for that OS. if HAVE_PAM pam_SCRIPTS = $(top_srcdir)/scripts/linux/pam.d/vmtoolsd endif HAVE_PAM # Message catalogs. install-data-hook: @INSTVMSG@ vmtoolsd $(srcdir)/l10n $(DESTDIR)$(datadir) install-exec-hook: $(INSTALL) -d $(DESTDIR)/etc/vmware-tools uninstall-hook: rm -rf $(DESTDIR)/etc/vmware-tools open-vm-tools-9.4.0-1280544/services/vmtoolsd/mainLoop.c0000644765153500003110000003064112220061556021057 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file mainLoop.c * * Functions for running the tools service's main loop. */ #if defined(_WIN32) # define MODULE_NAME(x) #x "." G_MODULE_SUFFIX #else # define MODULE_NAME(x) "lib" #x "." G_MODULE_SUFFIX #endif #include #include "toolsCoreInt.h" #include "conf.h" #include "guestApp.h" #include "serviceObj.h" #include "system.h" #include "util.h" #include "vmcheck.h" #include "vm_tools_version.h" #include "vmware/guestrpc/tclodefs.h" #include "vmware/tools/log.h" #include "vmware/tools/utils.h" #include "vmware/tools/vmbackup.h" /* ****************************************************************************** * ToolsCoreCleanup -- */ /** * * Cleans up the main loop after it has executed. After this function * returns, the fields of the state object shouldn't be used anymore. * * @param[in] state Service state. * ****************************************************************************** */ static void ToolsCoreCleanup(ToolsServiceState *state) { ToolsCorePool_Shutdown(&state->ctx); ToolsCore_UnloadPlugins(state); if (state->ctx.rpc != NULL) { RpcChannel_Destroy(state->ctx.rpc); state->ctx.rpc = NULL; } g_key_file_free(state->ctx.config); g_main_loop_unref(state->ctx.mainLoop); #if defined(G_PLATFORM_WIN32) if (state->ctx.comInitialized) { CoUninitialize(); state->ctx.comInitialized = FALSE; } #endif #if !defined(_WIN32) if (state->ctx.envp) { System_FreeNativeEnviron(state->ctx.envp); state->ctx.envp = NULL; } #endif g_object_set(state->ctx.serviceObj, TOOLS_CORE_PROP_CTX, NULL, NULL); g_object_unref(state->ctx.serviceObj); state->ctx.serviceObj = NULL; state->ctx.config = NULL; state->ctx.mainLoop = NULL; } /** * Loads the debug library and calls its initialization function. This function * panics is something goes wrong. * * @param[in] state Service state. */ static void ToolsCoreInitializeDebug(ToolsServiceState *state) { RpcDebugLibData *libdata; RpcDebugInitializeFn initFn; state->debugLib = g_module_open(MODULE_NAME(vmrpcdbg), G_MODULE_BIND_LOCAL); if (state->debugLib == NULL) { g_error("Cannot load vmrpcdbg library.\n"); } if (!g_module_symbol(state->debugLib, "RpcDebug_Initialize", (gpointer *) &initFn)) { g_error("Cannot find symbol: RpcDebug_Initialize\n"); } libdata = initFn(&state->ctx, state->debugPlugin); ASSERT(libdata != NULL); ASSERT(libdata->debugPlugin != NULL); state->debugData = libdata; #if defined(_WIN32) VMTools_AttachConsole(); #endif } /** * Timer callback that just calls ToolsCore_ReloadConfig(). * * @param[in] clientData Service state. * * @return TRUE. */ static gboolean ToolsCoreConfFileCb(gpointer clientData) { ToolsCore_ReloadConfig(clientData, FALSE); return TRUE; } /** * IO freeze signal handler. Disables the conf file check task if I/O is * frozen, re-enable it otherwise. See bug 529653. * * @param[in] src The source object. * @param[in] ctx Unused. * @param[in] freeze Whether I/O is being frozen. * @param[in] state Service state. */ static void ToolsCoreIOFreezeCb(gpointer src, ToolsAppCtx *ctx, gboolean freeze, ToolsServiceState *state) { if (state->configCheckTask > 0 && freeze) { g_source_remove(state->configCheckTask); state->configCheckTask = 0; } else if (state->configCheckTask == 0 && !freeze) { state->configCheckTask = g_timeout_add(CONF_POLL_TIME * 10, ToolsCoreConfFileCb, state); } } /* ****************************************************************************** * ToolsCoreRunLoop -- */ /** * * Loads and registers all plugins, and runs the service's main loop. * * @param[in] state Service state. * * @return Exit code. * ****************************************************************************** */ static int ToolsCoreRunLoop(ToolsServiceState *state) { if (!ToolsCore_InitRpc(state)) { return 1; } /* * Start the RPC channel if it's been created. The channel may be NULL if this is * not running in the context of a VM. */ if (state->ctx.rpc && !RpcChannel_Start(state->ctx.rpc)) { return 1; } if (!ToolsCore_LoadPlugins(state)) { return 1; } /* * The following criteria needs to hold for the main loop to be run: * * . no plugin has requested the service to shut down during initialization. * . we're either on a VMware hypervisor, or running an unknown service name. * . we're running in debug mode. * * In the non-VMware hypervisor case, just exit with a '0' return status (see * bug 297528 for why '0'). */ if (state->ctx.errorCode == 0 && (state->ctx.isVMware || ToolsCore_GetTcloName(state) == NULL || state->debugPlugin != NULL)) { ToolsCore_RegisterPlugins(state); /* * Listen for the I/O freeze signal. We have to disable the config file * check when I/O is frozen or the (Win32) sync driver may cause the service * to hang (and make the VM unusable until it times out). */ if (g_signal_lookup(TOOLS_CORE_SIG_IO_FREEZE, G_OBJECT_TYPE(state->ctx.serviceObj)) != 0) { g_signal_connect(state->ctx.serviceObj, TOOLS_CORE_SIG_IO_FREEZE, G_CALLBACK(ToolsCoreIOFreezeCb), state); } state->configCheckTask = g_timeout_add(CONF_POLL_TIME * 10, ToolsCoreConfFileCb, state); #if defined(__APPLE__) ToolsCore_CFRunLoop(state); #else g_main_loop_run(state->ctx.mainLoop); #endif } ToolsCoreCleanup(state); return state->ctx.errorCode; } /** * Logs some information about the runtime state of the service: loaded * plugins, registered GuestRPC callbacks, etc. Also fires a signal so * that plugins can log their state if they want to. * * @param[in] state The service state. */ void ToolsCore_DumpState(ToolsServiceState *state) { guint i; const char *providerStates[] = { "idle", "active", "error" }; ASSERT_ON_COMPILE(ARRAYSIZE(providerStates) == TOOLS_PROVIDER_MAX); if (!g_main_loop_is_running(state->ctx.mainLoop)) { ToolsCore_LogState(TOOLS_STATE_LOG_ROOT, "VM Tools Service '%s': not running.\n", state->name); return; } ToolsCore_LogState(TOOLS_STATE_LOG_ROOT, "VM Tools Service '%s':\n", state->name); ToolsCore_LogState(TOOLS_STATE_LOG_CONTAINER, "Plugin path: %s\n", state->pluginPath); for (i = 0; i < state->providers->len; i++) { ToolsAppProviderReg *prov = &g_array_index(state->providers, ToolsAppProviderReg, i); ToolsCore_LogState(TOOLS_STATE_LOG_CONTAINER, "App provider: %s (%s)\n", prov->prov->name, providerStates[prov->state]); if (prov->prov->dumpState != NULL) { prov->prov->dumpState(&state->ctx, prov->prov, NULL); } } ToolsCore_DumpPluginInfo(state); g_signal_emit_by_name(state->ctx.serviceObj, TOOLS_CORE_SIG_DUMP_STATE, &state->ctx); } /** * Returns the name of the TCLO app name. This will only return non-NULL * if the service is either the tools "guestd" or "userd" service. * * @param[in] state The service state. * * @return The app name, or NULL if not running a known TCLO app. */ const char * ToolsCore_GetTcloName(ToolsServiceState *state) { if (state->mainService) { return TOOLS_DAEMON_NAME; } else if (strcmp(state->name, VMTOOLS_USER_SERVICE) == 0) { return TOOLS_DND_NAME; } else { return NULL; } } /** * Reloads the config file and re-configure the logging subsystem if the * log file was updated. If the config file is being loaded for the first * time, try to upgrade it to the new version if an old version is * detected. * * @param[in] state Service state. * @param[in] reset Whether to reset the logging subsystem. */ void ToolsCore_ReloadConfig(ToolsServiceState *state, gboolean reset) { gboolean first = state->ctx.config == NULL; gboolean loaded; loaded = VMTools_LoadConfig(state->configFile, G_KEY_FILE_NONE, &state->ctx.config, &state->configMtime); if (!first && loaded) { g_debug("Config file reloaded.\n"); /* Inform plugins of config file update. */ g_signal_emit_by_name(state->ctx.serviceObj, TOOLS_CORE_SIG_CONF_RELOAD, &state->ctx); } if (state->ctx.config == NULL) { /* Couldn't load the config file. Just create an empty dictionary. */ state->ctx.config = g_key_file_new(); } if (reset || loaded) { VMTools_ConfigLogging(state->name, state->ctx.config, TRUE, reset); } } /** * Performs any initial setup steps for the service's main loop. * * @param[in] state Service state. */ void ToolsCore_Setup(ToolsServiceState *state) { GMainContext *gctx; ToolsServiceProperty ctxProp = { TOOLS_CORE_PROP_CTX }; if (!g_thread_supported()) { g_thread_init(NULL); } ToolsCore_ReloadConfig(state, FALSE); /* * Useful for debugging purposes. Log the vesion and build information. */ g_message("Tools Version: %s (%s)\n", TOOLS_VERSION_EXT_CURRENT_STR, BUILD_NUMBER); /* Initializes the app context. */ gctx = g_main_context_default(); state->ctx.version = TOOLS_CORE_API_V1; state->ctx.name = state->name; state->ctx.errorCode = EXIT_SUCCESS; #if defined(__APPLE__) /* * Mac OS doesn't use g_main_loop_run(), so need to create the loop as * "running". */ state->ctx.mainLoop = g_main_loop_new(gctx, TRUE); #else state->ctx.mainLoop = g_main_loop_new(gctx, FALSE); #endif state->ctx.isVMware = VmCheck_IsVirtualWorld(); g_main_context_unref(gctx); g_type_init(); state->ctx.serviceObj = g_object_new(TOOLSCORE_TYPE_SERVICE, NULL); /* Register the core properties. */ ToolsCoreService_RegisterProperty(state->ctx.serviceObj, &ctxProp); g_object_set(state->ctx.serviceObj, TOOLS_CORE_PROP_CTX, &state->ctx, NULL); ToolsCorePool_Init(&state->ctx); /* Initializes the debug library if needed. */ if (state->debugPlugin != NULL) { ToolsCoreInitializeDebug(state); } } /** * Runs the service's main loop. * * @param[in] state Service state. * * @return Exit code. */ int ToolsCore_Run(ToolsServiceState *state) { if (state->debugData != NULL) { int ret = state->debugData->run(&state->ctx, ToolsCoreRunLoop, state, state->debugData); g_module_close(state->debugLib); state->debugData = NULL; state->debugLib = NULL; return ret; } return ToolsCoreRunLoop(state); } open-vm-tools-9.4.0-1280544/services/vmtoolsd/Makefile.in0000644765153500003110000011560212220061625021200 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = vmtoolsd$(EXEEXT) @HAVE_ICU_TRUE@am__append_1 = @ICU_LIBS@ subdir = services/vmtoolsd DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pamdir)" PROGRAMS = $(bin_PROGRAMS) am_vmtoolsd_OBJECTS = vmtoolsd-cmdLine.$(OBJEXT) \ vmtoolsd-mainLoop.$(OBJEXT) vmtoolsd-mainPosix.$(OBJEXT) \ vmtoolsd-pluginMgr.$(OBJEXT) vmtoolsd-serviceObj.$(OBJEXT) \ vmtoolsd-threadPool.$(OBJEXT) vmtoolsd-toolsRpc.$(OBJEXT) \ vmtoolsd-svcSignals.$(OBJEXT) vmtoolsd_OBJECTS = $(am_vmtoolsd_OBJECTS) am__DEPENDENCIES_1 = vmtoolsd_DEPENDENCIES = $(am__DEPENDENCIES_1) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } SCRIPTS = $(pam_SCRIPTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(vmtoolsd_SOURCES) DIST_SOURCES = $(vmtoolsd_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pamdir = $(PAM_PREFIX)/pam.d vmtoolsd_CPPFLAGS = @VMTOOLS_CPPFLAGS@ @GMODULE_CPPFLAGS@ \ @GOBJECT_CPPFLAGS@ @GTHREAD_CPPFLAGS@ -I$(builddir) \ -DVMTOOLSD_PLUGIN_ROOT=\"$(pkglibdir)/plugins\" vmtoolsd_LDADD = @VMTOOLS_LIBS@ @GMODULE_LIBS@ @GOBJECT_LIBS@ \ @GTHREAD_LIBS@ $(am__append_1) vmtoolsd_SOURCES = cmdLine.c mainLoop.c mainPosix.c pluginMgr.c \ serviceObj.c threadPool.c toolsRpc.c svcSignals.c BUILT_SOURCES = svcSignals.c svcSignals.h CLEANFILES = svcSignals.c svcSignals.h EXTRA_DIST = svcSignals.gm @HAVE_ICU_FALSE@vmtoolsd_LINK = $(LINK) @HAVE_ICU_TRUE@vmtoolsd_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ @HAVE_ICU_TRUE@ $(LIBTOOLFLAGS) --mode=link $(CXX) \ @HAVE_ICU_TRUE@ $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ @HAVE_ICU_TRUE@ $(LDFLAGS) -o $@ # PAM support is currently only available for Linux, so HAVE_PAM is only # defined for that OS. @HAVE_PAM_TRUE@pam_SCRIPTS = $(top_srcdir)/scripts/linux/pam.d/vmtoolsd all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu services/vmtoolsd/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu services/vmtoolsd/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list vmtoolsd$(EXEEXT): $(vmtoolsd_OBJECTS) $(vmtoolsd_DEPENDENCIES) $(EXTRA_vmtoolsd_DEPENDENCIES) @rm -f vmtoolsd$(EXEEXT) $(vmtoolsd_LINK) $(vmtoolsd_OBJECTS) $(vmtoolsd_LDADD) $(LIBS) install-pamSCRIPTS: $(pam_SCRIPTS) @$(NORMAL_INSTALL) @list='$(pam_SCRIPTS)'; test -n "$(pamdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pamdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pamdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(pamdir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(pamdir)$$dir" || exit $$?; \ } \ ; done uninstall-pamSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(pam_SCRIPTS)'; test -n "$(pamdir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ dir='$(DESTDIR)$(pamdir)'; $(am__uninstall_files_from_dir) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmtoolsd-cmdLine.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmtoolsd-mainLoop.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmtoolsd-mainPosix.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmtoolsd-pluginMgr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmtoolsd-serviceObj.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmtoolsd-svcSignals.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmtoolsd-threadPool.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmtoolsd-toolsRpc.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< vmtoolsd-cmdLine.o: cmdLine.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vmtoolsd-cmdLine.o -MD -MP -MF $(DEPDIR)/vmtoolsd-cmdLine.Tpo -c -o vmtoolsd-cmdLine.o `test -f 'cmdLine.c' || echo '$(srcdir)/'`cmdLine.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmtoolsd-cmdLine.Tpo $(DEPDIR)/vmtoolsd-cmdLine.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cmdLine.c' object='vmtoolsd-cmdLine.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vmtoolsd-cmdLine.o `test -f 'cmdLine.c' || echo '$(srcdir)/'`cmdLine.c vmtoolsd-cmdLine.obj: cmdLine.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vmtoolsd-cmdLine.obj -MD -MP -MF $(DEPDIR)/vmtoolsd-cmdLine.Tpo -c -o vmtoolsd-cmdLine.obj `if test -f 'cmdLine.c'; then $(CYGPATH_W) 'cmdLine.c'; else $(CYGPATH_W) '$(srcdir)/cmdLine.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmtoolsd-cmdLine.Tpo $(DEPDIR)/vmtoolsd-cmdLine.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cmdLine.c' object='vmtoolsd-cmdLine.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vmtoolsd-cmdLine.obj `if test -f 'cmdLine.c'; then $(CYGPATH_W) 'cmdLine.c'; else $(CYGPATH_W) '$(srcdir)/cmdLine.c'; fi` vmtoolsd-mainLoop.o: mainLoop.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vmtoolsd-mainLoop.o -MD -MP -MF $(DEPDIR)/vmtoolsd-mainLoop.Tpo -c -o vmtoolsd-mainLoop.o `test -f 'mainLoop.c' || echo '$(srcdir)/'`mainLoop.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmtoolsd-mainLoop.Tpo $(DEPDIR)/vmtoolsd-mainLoop.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mainLoop.c' object='vmtoolsd-mainLoop.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vmtoolsd-mainLoop.o `test -f 'mainLoop.c' || echo '$(srcdir)/'`mainLoop.c vmtoolsd-mainLoop.obj: mainLoop.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vmtoolsd-mainLoop.obj -MD -MP -MF $(DEPDIR)/vmtoolsd-mainLoop.Tpo -c -o vmtoolsd-mainLoop.obj `if test -f 'mainLoop.c'; then $(CYGPATH_W) 'mainLoop.c'; else $(CYGPATH_W) '$(srcdir)/mainLoop.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmtoolsd-mainLoop.Tpo $(DEPDIR)/vmtoolsd-mainLoop.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mainLoop.c' object='vmtoolsd-mainLoop.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vmtoolsd-mainLoop.obj `if test -f 'mainLoop.c'; then $(CYGPATH_W) 'mainLoop.c'; else $(CYGPATH_W) '$(srcdir)/mainLoop.c'; fi` vmtoolsd-mainPosix.o: mainPosix.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vmtoolsd-mainPosix.o -MD -MP -MF $(DEPDIR)/vmtoolsd-mainPosix.Tpo -c -o vmtoolsd-mainPosix.o `test -f 'mainPosix.c' || echo '$(srcdir)/'`mainPosix.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmtoolsd-mainPosix.Tpo $(DEPDIR)/vmtoolsd-mainPosix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mainPosix.c' object='vmtoolsd-mainPosix.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vmtoolsd-mainPosix.o `test -f 'mainPosix.c' || echo '$(srcdir)/'`mainPosix.c vmtoolsd-mainPosix.obj: mainPosix.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vmtoolsd-mainPosix.obj -MD -MP -MF $(DEPDIR)/vmtoolsd-mainPosix.Tpo -c -o vmtoolsd-mainPosix.obj `if test -f 'mainPosix.c'; then $(CYGPATH_W) 'mainPosix.c'; else $(CYGPATH_W) '$(srcdir)/mainPosix.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmtoolsd-mainPosix.Tpo $(DEPDIR)/vmtoolsd-mainPosix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mainPosix.c' object='vmtoolsd-mainPosix.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vmtoolsd-mainPosix.obj `if test -f 'mainPosix.c'; then $(CYGPATH_W) 'mainPosix.c'; else $(CYGPATH_W) '$(srcdir)/mainPosix.c'; fi` vmtoolsd-pluginMgr.o: pluginMgr.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vmtoolsd-pluginMgr.o -MD -MP -MF $(DEPDIR)/vmtoolsd-pluginMgr.Tpo -c -o vmtoolsd-pluginMgr.o `test -f 'pluginMgr.c' || echo '$(srcdir)/'`pluginMgr.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmtoolsd-pluginMgr.Tpo $(DEPDIR)/vmtoolsd-pluginMgr.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pluginMgr.c' object='vmtoolsd-pluginMgr.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vmtoolsd-pluginMgr.o `test -f 'pluginMgr.c' || echo '$(srcdir)/'`pluginMgr.c vmtoolsd-pluginMgr.obj: pluginMgr.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vmtoolsd-pluginMgr.obj -MD -MP -MF $(DEPDIR)/vmtoolsd-pluginMgr.Tpo -c -o vmtoolsd-pluginMgr.obj `if test -f 'pluginMgr.c'; then $(CYGPATH_W) 'pluginMgr.c'; else $(CYGPATH_W) '$(srcdir)/pluginMgr.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmtoolsd-pluginMgr.Tpo $(DEPDIR)/vmtoolsd-pluginMgr.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pluginMgr.c' object='vmtoolsd-pluginMgr.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vmtoolsd-pluginMgr.obj `if test -f 'pluginMgr.c'; then $(CYGPATH_W) 'pluginMgr.c'; else $(CYGPATH_W) '$(srcdir)/pluginMgr.c'; fi` vmtoolsd-serviceObj.o: serviceObj.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vmtoolsd-serviceObj.o -MD -MP -MF $(DEPDIR)/vmtoolsd-serviceObj.Tpo -c -o vmtoolsd-serviceObj.o `test -f 'serviceObj.c' || echo '$(srcdir)/'`serviceObj.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmtoolsd-serviceObj.Tpo $(DEPDIR)/vmtoolsd-serviceObj.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='serviceObj.c' object='vmtoolsd-serviceObj.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vmtoolsd-serviceObj.o `test -f 'serviceObj.c' || echo '$(srcdir)/'`serviceObj.c vmtoolsd-serviceObj.obj: serviceObj.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vmtoolsd-serviceObj.obj -MD -MP -MF $(DEPDIR)/vmtoolsd-serviceObj.Tpo -c -o vmtoolsd-serviceObj.obj `if test -f 'serviceObj.c'; then $(CYGPATH_W) 'serviceObj.c'; else $(CYGPATH_W) '$(srcdir)/serviceObj.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmtoolsd-serviceObj.Tpo $(DEPDIR)/vmtoolsd-serviceObj.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='serviceObj.c' object='vmtoolsd-serviceObj.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vmtoolsd-serviceObj.obj `if test -f 'serviceObj.c'; then $(CYGPATH_W) 'serviceObj.c'; else $(CYGPATH_W) '$(srcdir)/serviceObj.c'; fi` vmtoolsd-threadPool.o: threadPool.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vmtoolsd-threadPool.o -MD -MP -MF $(DEPDIR)/vmtoolsd-threadPool.Tpo -c -o vmtoolsd-threadPool.o `test -f 'threadPool.c' || echo '$(srcdir)/'`threadPool.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmtoolsd-threadPool.Tpo $(DEPDIR)/vmtoolsd-threadPool.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='threadPool.c' object='vmtoolsd-threadPool.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vmtoolsd-threadPool.o `test -f 'threadPool.c' || echo '$(srcdir)/'`threadPool.c vmtoolsd-threadPool.obj: threadPool.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vmtoolsd-threadPool.obj -MD -MP -MF $(DEPDIR)/vmtoolsd-threadPool.Tpo -c -o vmtoolsd-threadPool.obj `if test -f 'threadPool.c'; then $(CYGPATH_W) 'threadPool.c'; else $(CYGPATH_W) '$(srcdir)/threadPool.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmtoolsd-threadPool.Tpo $(DEPDIR)/vmtoolsd-threadPool.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='threadPool.c' object='vmtoolsd-threadPool.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vmtoolsd-threadPool.obj `if test -f 'threadPool.c'; then $(CYGPATH_W) 'threadPool.c'; else $(CYGPATH_W) '$(srcdir)/threadPool.c'; fi` vmtoolsd-toolsRpc.o: toolsRpc.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vmtoolsd-toolsRpc.o -MD -MP -MF $(DEPDIR)/vmtoolsd-toolsRpc.Tpo -c -o vmtoolsd-toolsRpc.o `test -f 'toolsRpc.c' || echo '$(srcdir)/'`toolsRpc.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmtoolsd-toolsRpc.Tpo $(DEPDIR)/vmtoolsd-toolsRpc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='toolsRpc.c' object='vmtoolsd-toolsRpc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vmtoolsd-toolsRpc.o `test -f 'toolsRpc.c' || echo '$(srcdir)/'`toolsRpc.c vmtoolsd-toolsRpc.obj: toolsRpc.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vmtoolsd-toolsRpc.obj -MD -MP -MF $(DEPDIR)/vmtoolsd-toolsRpc.Tpo -c -o vmtoolsd-toolsRpc.obj `if test -f 'toolsRpc.c'; then $(CYGPATH_W) 'toolsRpc.c'; else $(CYGPATH_W) '$(srcdir)/toolsRpc.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmtoolsd-toolsRpc.Tpo $(DEPDIR)/vmtoolsd-toolsRpc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='toolsRpc.c' object='vmtoolsd-toolsRpc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vmtoolsd-toolsRpc.obj `if test -f 'toolsRpc.c'; then $(CYGPATH_W) 'toolsRpc.c'; else $(CYGPATH_W) '$(srcdir)/toolsRpc.c'; fi` vmtoolsd-svcSignals.o: svcSignals.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vmtoolsd-svcSignals.o -MD -MP -MF $(DEPDIR)/vmtoolsd-svcSignals.Tpo -c -o vmtoolsd-svcSignals.o `test -f 'svcSignals.c' || echo '$(srcdir)/'`svcSignals.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmtoolsd-svcSignals.Tpo $(DEPDIR)/vmtoolsd-svcSignals.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='svcSignals.c' object='vmtoolsd-svcSignals.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vmtoolsd-svcSignals.o `test -f 'svcSignals.c' || echo '$(srcdir)/'`svcSignals.c vmtoolsd-svcSignals.obj: svcSignals.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vmtoolsd-svcSignals.obj -MD -MP -MF $(DEPDIR)/vmtoolsd-svcSignals.Tpo -c -o vmtoolsd-svcSignals.obj `if test -f 'svcSignals.c'; then $(CYGPATH_W) 'svcSignals.c'; else $(CYGPATH_W) '$(srcdir)/svcSignals.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vmtoolsd-svcSignals.Tpo $(DEPDIR)/vmtoolsd-svcSignals.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='svcSignals.c' object='vmtoolsd-svcSignals.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vmtoolsd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vmtoolsd-svcSignals.obj `if test -f 'svcSignals.c'; then $(CYGPATH_W) 'svcSignals.c'; else $(CYGPATH_W) '$(srcdir)/svcSignals.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(PROGRAMS) $(SCRIPTS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pamdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pamSCRIPTS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-pamSCRIPTS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-hook .MAKE: all check install install-am install-data-am install-exec-am \ install-strip uninstall-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libtool cscopelist ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-data-hook install-dvi install-dvi-am \ install-exec install-exec-am install-exec-hook install-html \ install-html-am install-info install-info-am install-man \ install-pamSCRIPTS install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-binPROGRAMS uninstall-hook \ uninstall-pamSCRIPTS svcSignals.c: $(top_srcdir)/services/vmtoolsd/svcSignals.gm glib-genmarshal --body $(top_srcdir)/services/vmtoolsd/svcSignals.gm > \ $@ || (rm -f $@ && exit 1) svcSignals.h: $(top_srcdir)/services/vmtoolsd/svcSignals.gm glib-genmarshal --header $(top_srcdir)/services/vmtoolsd/svcSignals.gm > \ $@ || (rm -f $@ && exit 1) # Message catalogs. install-data-hook: @INSTVMSG@ vmtoolsd $(srcdir)/l10n $(DESTDIR)$(datadir) install-exec-hook: $(INSTALL) -d $(DESTDIR)/etc/vmware-tools uninstall-hook: rm -rf $(DESTDIR)/etc/vmware-tools # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/services/Makefile.in0000644765153500003110000004755312220061624017341 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = services DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = vmtoolsd plugins all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu services/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu services/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done cscopelist-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) cscopelist); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) \ cscopelist-recursive ctags-recursive install-am install-strip \ tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ cscopelist cscopelist-recursive ctags ctags-recursive \ distclean distclean-generic distclean-libtool distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-recursive uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/checkvm/0000755765153500003110000000000012220061621015050 5ustar dtormtsopen-vm-tools-9.4.0-1280544/checkvm/checkvm_version.h0000644765153500003110000000301012220061556020407 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * checkvm_version.h -- * * Version definitions for the VM checking utility. */ #ifndef _CHECKVM_VERSION_H_ #define _CHECKVM_VERSION_H_ /* * This component's version is coupled with Tools versioning. The effect * is that the version increments with each build, and with each Tools * version bump. If and when it becomes necessary to version the component * manually, make sure that the version is bumped any time the component or * its dependencies are changed. */ #include "vm_tools_version.h" #define CHECKVM_VERSION_COMMAS TOOLS_VERSION_EXT_CURRENT_CSV #define CHECKVM_VERSION_STRING TOOLS_VERSION_EXT_CURRENT_STR #endif /* _CHECKVM_VERSION_H_ */ open-vm-tools-9.4.0-1280544/checkvm/checkvm.c0000644765153500003110000000661212220061556016650 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * checkvm.c -- * * Check if we are running in a VM or not */ #include #include #if !defined(_WIN32) #include #endif #include "vm_version.h" #include "backdoor.h" #include "backdoor_def.h" #include "vm_basic_types.h" #include "vmcheck.h" #if defined(_WIN32) #include "getoptwin32.h" #endif #include "checkvm_version.h" #include "embed_version.h" VM_EMBED_VERSION(CHECKVM_VERSION_STRING); /* * getHWVersion - Read VM HW version through backdoor */ void getHWVersion(uint32 *hwVersion) { Backdoor_proto bp; bp.in.cx.halfs.low = BDOOR_CMD_GETHWVERSION; Backdoor(&bp); *hwVersion = bp.out.ax.word; } /* * getScreenSize - Get screen size of the host */ void getScreenSize(uint32 *screensize) { Backdoor_proto bp; bp.in.cx.halfs.low = BDOOR_CMD_GETSCREENSIZE; Backdoor(&bp); *screensize = bp.out.ax.word; } /* * Start of main program. Check if we are in a VM, by reading * a backdoor port. Then process any other commands. */ int main(int argc, char *argv[]) { uint32 version[2]; int opt; int width, height; uint32 screensize = 0; uint32 hwVersion; if (!VmCheck_IsVirtualWorld()) { fprintf(stdout, "Not running in a virtual machine.\n"); return 1; } if (!VmCheck_GetVersion(&version[0], &version[1])) { fprintf(stdout, "Couldn't get version\n"); return 1; } /* * OK, we're in a VM, check if there are any other requests */ while ((opt = getopt(argc, argv, "rph")) != EOF) { switch (opt) { case 'r': getScreenSize(&screensize); width = (screensize >> 16) & 0xffff; height = screensize & 0xffff; if ((width <= 0x7fff) && (height <= 0x7fff)) { printf("%d %d\n", width, height); } else { printf("0 0\n"); } return 0; case 'p': /* * Print out product that we're running on based on code * obtained from getVersion(). */ switch (version[1]) { case VMX_TYPE_SCALABLE_SERVER: printf("ESX Server\n"); break; case VMX_TYPE_WORKSTATION: printf("Workstation\n"); break; default: printf("Unknown\n"); break; } return 0; case 'h': getHWVersion(&hwVersion); printf("VM's hw version is %u\n", hwVersion); break; default: break; } } printf("%s version %d (good)\n", PRODUCT_LINE_NAME, version[0]); return 0; } open-vm-tools-9.4.0-1280544/checkvm/COPYING0000644765153500003110000006347112220061556016125 0ustar dtormts GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! open-vm-tools-9.4.0-1280544/checkvm/Makefile.am0000644765153500003110000000256212220061556017120 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ bin_PROGRAMS = vmware-checkvm vmware_checkvm_SOURCES = vmware_checkvm_SOURCES += checkvm.c vmware_checkvm_LDADD = vmware_checkvm_LDADD += @VMTOOLS_LIBS@ if HAVE_ICU vmware_checkvm_LDADD += @ICU_LIBS@ vmware_checkvm_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXX) \ $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ else vmware_checkvm_LINK = $(LINK) endif open-vm-tools-9.4.0-1280544/checkvm/Makefile.in0000644765153500003110000005026412220061621017124 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = vmware-checkvm$(EXEEXT) @HAVE_ICU_TRUE@am__append_1 = @ICU_LIBS@ subdir = checkvm DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_vmware_checkvm_OBJECTS = checkvm.$(OBJEXT) vmware_checkvm_OBJECTS = $(am_vmware_checkvm_OBJECTS) am__DEPENDENCIES_1 = vmware_checkvm_DEPENDENCIES = $(am__DEPENDENCIES_1) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(vmware_checkvm_SOURCES) DIST_SOURCES = $(vmware_checkvm_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ vmware_checkvm_SOURCES = checkvm.c vmware_checkvm_LDADD = @VMTOOLS_LIBS@ $(am__append_1) @HAVE_ICU_FALSE@vmware_checkvm_LINK = $(LINK) @HAVE_ICU_TRUE@vmware_checkvm_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ @HAVE_ICU_TRUE@ $(LIBTOOLFLAGS) --mode=link $(CXX) \ @HAVE_ICU_TRUE@ $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ @HAVE_ICU_TRUE@ $(LDFLAGS) -o $@ all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu checkvm/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu checkvm/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list vmware-checkvm$(EXEEXT): $(vmware_checkvm_OBJECTS) $(vmware_checkvm_DEPENDENCIES) $(EXTRA_vmware_checkvm_DEPENDENCIES) @rm -f vmware-checkvm$(EXEEXT) $(vmware_checkvm_LINK) $(vmware_checkvm_OBJECTS) $(vmware_checkvm_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/checkvm.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libtool cscopelist ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-binPROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/scripts/0000755765153500003110000000000012220061624015122 5ustar dtormtsopen-vm-tools-9.4.0-1280544/scripts/solaris/0000755765153500003110000000000012220061556016602 5ustar dtormtsopen-vm-tools-9.4.0-1280544/scripts/solaris/network0000644765153500003110000000504312220061556020220 0ustar dtormts#!/bin/sh ########################################################## # Copyright (C) 2006-2010 VMware, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public # License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # ########################################################## ########################################################################## # DO NOT modify this file directly as it will be overwritten the next # time the VMware Tools are installed. ########################################################################## # # network (Solaris 10+) # # Solaris's ifconfig conveniently handles DHCP arguments directly, so we # may use it to release and renew DHCP leases upon receipt of suspend # and resume events, respectively. # echo `date` ": Executing '$0'" echo # # main -- # # Script entry point. # # Results: # # Side effects: # main() { activeList=/var/run/vmware-active-nics exitCode=0 case "$1" in poweron-vm) rm -f $activeList ;; suspend-vm) >$activeList # Release DHCP addresses and note each interface in our active list # so it can be brought back up on resume for nic in `ifconfig -a | awk -F: '/DHCP/ { print $1; }'`; do # Sometimes interfaces will claim DHCP and not actually be "under # DHCP control". Let's double check the status to ensure this # isn't the case. if ifconfig "$nic" dhcp status > /dev/null 2>&1; then echo "$0: releasing DHCP address for $nic" echo "$nic" >> $activeList ifconfig "$nic" dhcp release fi done ;; resume-vm) if [ -s $activeList ]; then while read nic; do echo "$0: bringing up DHCP on $nic" ifconfig "$nic" dhcp exitCode=`expr $exitCode \| $?` done < $activeList fi ;; *) ;; esac return $exitCode } main "$@" open-vm-tools-9.4.0-1280544/scripts/linux/0000755765153500003110000000000012220061556016265 5ustar dtormtsopen-vm-tools-9.4.0-1280544/scripts/linux/network0000644765153500003110000002064612220061556017711 0ustar dtormts#!/bin/sh ########################################################## # Copyright (C) 2001-2010 VMware, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public # License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # ########################################################## # # network (Linux) # # Using a combination of a system networking script, ifconfig, and ifup, # attempt to release and renew DHCP leases upon receipt of suspend and resume # events, respectively. # echo `date` ": Executing '$0'" echo . `dirname "$0"`/../../statechange.subr # # find_networking_script -- # # Searches common Linux distro init/rc paths to find a singular network # services script. # # Result: # Returns a valid networking script path on success or "error" on failure. # # Side effects: # None. # find_networking_script() { local script="error" for dir in "/etc/init.d" "/sbin/init.d" "/etc" "/etc/rc.d" ; do if [ -d "$dir/rc0.d" ] && [ -d "$dir/rc1.d" ] && [ -d "$dir/rc2.d" ] && [ -d "$dir/rc3.d" ] && [ -d "$dir/rc4.d" ] && [ -d "$dir/rc5.d" ] && [ -d "$dir/rc6.d" ]; then # Now find the appropriate networking script. if [ -d "$dir/init.d" ]; then if [ -x "$dir/init.d/network" ]; then script="$dir/init.d/network" elif [ -x "$dir/init.d/networking" ]; then script="$dir/init.d/networking" fi else if [ -x "$dir/network" ]; then script="$dir/network" elif [ -x "$dir/networking" ]; then script="$dir/networking" fi fi fi done echo "$script" } # # run_network_script -- # # Finds out how to run the system's script used to control networking, and # runs it with the given argument (which should be one of the usual SysV # init script arguments). # run_network_script() { script=`find_networking_script` [ "$script" != "error" ] || Panic "Cannot find system networking script." # Using SysV "service" if it exists, otherwise fall back to run the script directly service=`which service 2>/dev/null` if [ $? = 0 -a -n "$service" ]; then serviceName=`basename "$script"` "$service" "$serviceName" "$1" else "$script" "$1" fi } # # save_active_NIC_list -- # # Records a list of every active NIC to /var/run/vmware-active-nics. # # XXX What's the story on aliases? Should they still be included, or will # they be recreated automatically upon resume? # # Results: # $activeList has, one per line, a list of all active NICs. # # Side effects: # None. # save_active_NIC_list() { >$activeList for nic in `ifconfig | awk '/^eth/ { print $1 }'`; do ifconfig $nic | egrep -q '\bUP\b' && echo $nic >> $activeList exitCode=`expr $exitCode \| $?` done } # # rescue_NIC -- # # For each NIC recorded in $activeList that is not currently "up", run # "ifup $nic". # # Results: # All downed NICs should be active. # rescue_NIC() { if [ -f "$activeList" ]; then while read nic; do if ifconfig $nic | egrep -q '\bUP\b'; then echo `date` "[rescue_nic] $nic is already active." else echo `date` "[rescue_nic] activating $nic ..." ifup $nic exitCode=`expr $exitCode \| $?` fi done < $activeList rm -f $activeList fi } # # TranquilizeNetworkManager -- # # Put the NetworkManager daemon to sleep (maybe). # # See http://projects.gnome.org/NetworkManager/developers/spec.html . # # Results: # Sleep(true) request is sent to the NetworkManager D-Bus interface. # # Side effects: # None. # TranquilizeNetworkManager() { # `which' may be a bit noisy, so we'll shush it. dbusSend=`which dbus-send 2>/dev/null` rc=$? if [ $rc = 0 ]; then # NetworkManager 0.8.0 $dbusSend --system --print-reply \ --dest=org.freedesktop.NetworkManager \ /org/freedesktop/NetworkManager \ org.freedesktop.NetworkManager.Enable boolean:false rc=$? if [ $rc = 0 ]; then return $rc fi # NetworkManager 0.7.0 $dbusSend --system --print-reply \ --dest=org.freedesktop.NetworkManager \ /org/freedesktop/NetworkManager \ org.freedesktop.NetworkManager.Sleep boolean:true rc=$? if [ $rc = 0 ]; then return $rc fi # NetworkManager 0.6 $dbusSend --system --print-reply \ --dest=org.freedesktop.NetworkManager \ /org/freedesktop/NetworkManager \ org.freedesktop.NetworkManager.sleep rc=$? fi return $rc } # # WakeNetworkManager -- # # Wake the NetworkManager daemon (maybe). # # See http://projects.gnome.org/NetworkManager/developers/spec.html . # # Results: # Sleep(false)request is sent to the NetworkManager D-Bus interface. # # Side effects: # None. # WakeNetworkManager() { # `which' may be a bit noisy, so we'll shush it. dbusSend=`which dbus-send 2>/dev/null` rc=$? if [ $rc = 0 ]; then # NetworkManager 0.8.0 $dbusSend --system --print-reply \ --dest=org.freedesktop.NetworkManager \ /org/freedesktop/NetworkManager \ org.freedesktop.NetworkManager.Enable boolean:true rc=$? if [ $rc = 0 ]; then return $rc fi # NetworkManager 0.7.0 $dbusSend --system --print-reply \ --dest=org.freedesktop.NetworkManager \ /org/freedesktop/NetworkManager \ org.freedesktop.NetworkManager.Sleep boolean:false rc=$? if [ $rc = 0 ]; then return $rc fi # NetworkManager 0.6 $dbusSend --system --print-reply \ --dest=org.freedesktop.NetworkManager \ /org/freedesktop/NetworkManager \ org.freedesktop.NetworkManager.wake rc=$? fi return $rc } # # main -- # # Main entry point. Perform some sanity checking, then map state change # events to relevant networking operations. # # Results: # See comment at top of file. # main() { exitCode=0 activeList=/var/run/vmware-active-nics # XXX Are these really necessary? If so, we should have seen customer # complaints by now. which ifup >/dev/null 2>&1 || Panic "ifup not in search path." which ifconfig >/dev/null 2>&1 || Panic "ifconfig not in search path." case "$1" in poweron-vm) rm -f $activeList ;; suspend-vm) TranquilizeNetworkManager exitCode=$? if [ $exitCode != 0 ]; then save_active_NIC_list run_network_script stop exitCode=$? fi ;; resume-vm) WakeNetworkManager exitCode=$? if [ $exitCode != 0 ]; then # According to hfu, "/etc/init.d/networking restart" on Debian 5.0 # may bring down ethernet interfaces tagged as "allow-hotplug" without # bringing them back up. # # This is especially a problem when reverting to a live, running # VM snapshot where an active NIC list hadn't yet been generated, # resulting in sudden loss of an otherwise operational NIC. # # So, if the active list doesn't exist, assume we're coming back to # a live snapshot and capture the current active list now for # rescue later. if [ ! -s $activeList ]; then save_active_NIC_list fi # We shall use start not restart here. Otherwise we may not be able # to bring back active list on distros like sles11sp2 # -- PR 816791 run_network_script start rescue_NIC exitCode=$? fi ;; *) ;; esac return $exitCode } main "$@" open-vm-tools-9.4.0-1280544/scripts/linux/pam.d/0000755765153500003110000000000012220061556017264 5ustar dtormtsopen-vm-tools-9.4.0-1280544/scripts/linux/pam.d/vmtoolsd0000644765153500003110000000045112220061556021056 0ustar dtormts#%PAM-1.0 auth sufficient pam_unix2.so nullok auth sufficient pam_unix.so shadow nullok auth required pam_unix_auth.so shadow nullok account sufficient pam_unix2.so account sufficient pam_unix.so account required pam_unix_acct.so open-vm-tools-9.4.0-1280544/scripts/common/0000755765153500003110000000000012220061556016416 5ustar dtormtsopen-vm-tools-9.4.0-1280544/scripts/common/vmware-toolbox.desktop0000644765153500003110000000042512220061556022777 0ustar dtormts[Desktop Entry] Encoding=UTF-8 Name=VMware Toolbox Comment=VMware Guest Toolbox utility # have to use the full path here otherwise help won't work Exec=/usr/lib/vmware-tools/bin/vmware-toolbox Icon=vmware-toolbox Terminal=false Type=Application Categories=Application;Utility; open-vm-tools-9.4.0-1280544/scripts/common/vmware-xdg-detect-de0000644765153500003110000000634012220061556022261 0ustar dtormts#!/bin/sh # # vmware-xdg-detect-de -- # # Determines which Freedesktop.Org compliant desktop environment we're # running under. # # usage: vmware-xdg-detect-de # # Simply prints the detected environment (GNOME, KDE, or XFCE). Shamelessly # lifted from detectDE() routine found in many Portland xdg-* scripts. # # Copyright 2010-2011, VMware, Inc. All rights reserved. # Copyright 2009-2010, Fathi Boudra # Copyright 2009-2010, Rex Dieter # Copyright 2006, Kevin Krammer # Copyright 2006, Jeremy White # # LICENSE: # # 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. # #--------------------------------------------- #-------------------------------------- # Checks for known desktop environments # set variable DE to the desktop environments name, lowercase # see https://bugs.freedesktop.org/show_bug.cgi?id=34164 unset GREP_OPTIONS if [ -n "${XDG_CURRENT_DESKTOP}" ]; then # # This script deals in (case sensitive) desktop environment names as found in # menu-spec (http://standards.freedesktop.org/menu-spec/latest/apb.html), # xdgDE="${XDG_CURRENT_DESKTOP}" DE=`echo "${XDG_CURRENT_DESKTOP}" | tr '[:upper:]' '[:lower:]'` fi if [ x"$DE" = x"" ]; then # classic fallbacks if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce fi fi if [ x"$DE" = x"" ]; then # fallback to checking $DESKTOP_SESSION case "$DESKTOP_SESSION" in gnome) DE=gnome; ;; LXDE) DE=lxde; ;; xfce|xfce4) DE=xfce; ;; esac fi if [ x"$DE" = x ]; then exit 1 fi if [ -z "$xdgDE" ]; then case "$DE" in gnome) xdgDE=GNOME ;; kde) xdgDE=KDE ;; xfce) xdgDE=XFCE ;; esac fi echo $xdgDE open-vm-tools-9.4.0-1280544/scripts/common/statechange.sh0000644765153500003110000001040712220061556021242 0ustar dtormts#!/bin/sh ########################################################## # Copyright (C) 2010 VMware, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public # License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # ########################################################## ########################################################################## # DO NOT modify this file directly as it will be overwritten the next # time the VMware Tools are installed. ########################################################################## # # statechange.sh # # This script is a refactored version of the legacy power scripts (e.g., # poweron-vm-default). It expects to be installed in their places -- # in other words, `basename "$0"` might be poweron-vm-default. # # Handy reference/shorthand used in this doc/scripts: # TOOLS_CONFDIR ::= Depends on platform and installation settings. Likely # "/etc/vmware-tools" or # "/Library/Application Support/VMware Tools" # powerOp ::= One of "poweron-vm", "poweroff-vm", "suspend-vm", and # "resume-vm". # vmwScriptDir ::= $TOOLS_CONFDIR/scripts/vmware # userScriptDir ::= $TOOLS_CONFDIR/scripts/${powerOp}-default.d # # End users may install scripts of their own under $userScriptDir. They # are executed in alphabetical order with "$powerOp" as the only argument. # # NB: This directory layout remains to preserve backwards compatibility. End # users are free to write a single script which uses its only parameter # (${powerOp}) as a discriminator, and then install symlinks to it in each # of the ${powerOp}-default.d directories. # # On power-on and resume, VMware's scripts execute before the end user's. On # suspend and power-off, the end user's execute before VMware's. (This way, # VMware stops services only after the user's scripts have finished their # work, and conversely restores the same services before the user's scripts # attempt to use them.) # # Should any script exit non-zero, only its value will be saved to exitCode. # (Any further non-zero exits will have no effect on exitCode.) This script # exits with $exitCode. # # XXX Consider using the available/enabled pattern for VMware's scripts. # # XXX This should be staged as a single executable whereby the desired # power operation is passed in as a parameter. (I.e., one would run # "/path/to/statechange.sh suspend-vm" rather than having to install # statechange.sh as suspend-vm-default.) # echo `date` ": Executing '$0'" # See above. TOOLS_CONFDIR=`dirname "$0"` export TOOLS_CONFDIR # Pull in subroutines like Panic. . "$TOOLS_CONFDIR"/statechange.subr # # RunScripts -- # # Executes scripts installed under $scriptDir. # # Side effects: # exitCode may be incremented. # RunScripts() { scriptDir="$1" if [ -d "$scriptDir" ]; then for scriptFile in "$scriptDir"/*; do if [ -x "$scriptFile" ]; then "$scriptFile" $powerOp exitCode=`expr $exitCode \| $?` fi done fi } # # main -- # # Entry point. See comments at top of file for details. # # Results: # Exits with $exitCode. # main() { # This is sanity checked in the case/esac bit below. powerOp=`basename "$0" | sed 's,-default,,'` exitCode=0 vmwScriptDir="$TOOLS_CONFDIR/scripts/vmware" userScriptDir="$TOOLS_CONFDIR/scripts/${powerOp}-default.d" case "$powerOp" in poweron-vm|resume-vm) RunScripts "$vmwScriptDir" RunScripts "$userScriptDir" ;; poweroff-vm|suspend-vm) RunScripts "$userScriptDir" RunScripts "$vmwScriptDir" ;; *) Panic "Invalid argument: $powerOp" ;; esac return $exitCode } main open-vm-tools-9.4.0-1280544/scripts/common/vm-support0000644765153500003110000001665212220061556020507 0ustar dtormts#!/bin/sh ########################################################## # Copyright (C) 2006-2010 VMware, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public # License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # ########################################################## # usage(): prints how to use this script usage() { echo "" echo "Usage: $0 [-h]" echo " -h prints this usage statement" exit } TARFILE=vm-`date +%Y-%m-%d`.$$.tar VER=0.88 OUTPUT_DIR=vm-support.$$ # banner(): prints any number of strings padded with # newlines before and after. banner() { echo for option in "$@" do echo $option done echo } # The status constants are important and have to be kept # in sync with VMware Workstation implementation # vm-support script is not running VMSUPPORT_NOT_RUNNING=0 # vm-support script is beginning VMSUPPORT_BEGINNING=1 # vm-support script running in progress VMSUPPORT_RUNNING=2 # vm-support script is ending VMSUPPORT_ENDING=3 # vm-support script failed VMSUPPORT_ERROR=10 # vm-support collection not supported VMSUPPORT_UNKNOWN=100 #internal state machine state for update update=0 # UpdateState($state): Updates the VM with the given state. UpdateState() { if [ $update -eq 1 ]; then vmware-xferlogs upd $1 fi } # addfile(): copies whatever files and directories you give it to # a self contained output directory for later tar'ing # Working on copies could slow this down with VERY large files but: # 1) We don't expect VERY large files # 2) Since /proc files can be copied this preserves the tree without # having to cat them all into a file. # 3) tar barfs on open files like logs if it changes while it's tar'ing. # Copying file first makes sure tar doesn't complain addfile() { file=$1 dir=`dirname "$file"` if [ ! -d "${OUTPUT_DIR}$dir" ]; then mkdir -p "${OUTPUT_DIR}$dir" if [ $? != 0 ]; then banner "Could not create ./${OUTPUT_DIR}$dir... " \ "Have you run out of disk space?" "Continuing" return fi fi # Ignore stdout and handle errors. cp -pRP "$file" "${OUTPUT_DIR}$dir" 2>/dev/null if [ $? != 0 ]; then banner "Could not copy '$file' to the tar area." fi } # addfiles(): adds a list of files to the archive. addfiles() { for i in "$@"; do addfile $i done } # runcmd($cmd, $out): executes the command redirected to a file and then adds # that file to the list of files to tar. It then deletes the temp file since # addfile makes a copy in its own self-contained area. runcmd() { $1 > $2 2>/dev/null if [ $? != 0 ]; then echo 3 banner "Either could not run $1 or could not write to $2" \ "Do you have a full disk? Continuing..." else addfile "$2" rm -f "$2" fi } # error(): prints an error message using the "banner" funtion and quits. error() { banner "$@" UpdateState $VMSUPPORT_ERROR exit 1 } # Parse args for option in $@ do case $option in "-h") usage ;; "-u") update=1 ;; *) usage ;; esac done # Start message UpdateState $VMSUPPORT_BEGINNING banner "VMware UNIX Support Script $VER" # Check for root privledge if [ `whoami` != 'root' ]; then banner "You are not root, some system information can't be collected." fi # Source /etc/profile. If we can't find it, it's the users problem to get # their paths straight. if [ -f /etc/profile ]; then . /etc/profile fi # Protect against non-default values of $IFS (Not all scripts in /etc/profile.d/ # are good citizens). if [ `uname` != 'SunOS' ]; then unset IFS 2>/dev/null fi # make a subdir to put all your files in. die if it does not create mkdir $OUTPUT_DIR if [ $? != 0 ]; then error "Could not create ./${OUTPUT_DIR}. Please cd to a directory to which " "you can write." fi banner "Collecting support information..." # Common stuff that we gather for all OSes. runcmd "echo vm-support version: $VER" "/tmp/vm-support-version.$$.txt" addfiles /etc/vmware-tools addfiles /var/log/boot* addfiles /var/log/secure* addfiles /var/log/messages* addfiles /var/log/syslog* addfiles /var/run/vmware-* runcmd "df" "/tmp/df.$$.txt" runcmd "ifconfig -a" "/tmp/ifconfig.$$.txt" runcmd "mount" "/tmp/mount.$$.txt" runcmd "dmesg" "/tmp/dmesg.$$.txt" runcmd "ulimit -a" "/tmp/ulimit-a.$$.txt" runcmd "uptime" "/tmp/uptime.$$.txt" runcmd "date" "/tmp/date.$$.txt" runcmd "umask" "/tmp/umask.$$.txt" # stageLinux(): gather information for troubleshooting Linux guests. stageLinux() { # Try to collect bootloader config. if [ -e /etc/lilo.conf ]; then addfiles /etc/lilo.conf fi # And for grub we are not sure about the exact default location so collect them # all. if [ -e /boot/grub/grub.conf ]; then addfile /boot/grub/grub.conf fi if [ -e /boot/grub/menu.lst ]; then addfile /boot/grub/menu.lst fi if [ -e /etc/grub.conf ]; then addfile /etc/grub.conf fi addfile /etc/cron.daily addfile /etc/cron.hourly addfile /etc/cron.monthly addfile /etc/cron.weekly addfile /etc/crontab addfile /etc/modules.conf addfile /etc/ntp.conf addfile /etc/security addfile /etc/services # Commands to run ($1) and redirect to logs ($2) for inclusion. runcmd "ps auwwx" "/tmp/ps-auwwx.$$.txt" runcmd "lspci -H1 -M" "/tmp/lspci1.$$.txt" runcmd "lspci -H1 -M -vn" "/tmp/lspci2.$$.txt" runcmd "/sbin/lsmod" "/tmp/modules.$$.txt" runcmd "uname -a" "/tmp/uname.$$.txt" runcmd "cat /etc/issue" "/tmp/issue.$$.txt" runcmd "rpm -qa" "/tmp/rpm-qa.$$.txt" runcmd "netstat -lan" "/tmp/netstat-lan.$$.txt" runcmd "route" "/tmp/route.$$.txt" runcmd "free" "/tmp/free.$$.txt" } # stageFreeBSD(): gather information for troubleshooting FreeBSD guests. stageFreeBSD() { runcmd "ps auwwx" "/tmp/ps-auwwx.$$.txt" } # stageSolaris(): gather information for troubleshooting Solaris guests. stageSolaris() { runcmd "ps eaf" "/tmp/ps-eaf.$$.txt" } case `uname` in Linux) stageLinux # tar options: 'S' for sparse core files. TAR_OPTS=-cSf ;; FreeBSD) stageFreeBSD TAR_OPTS=-cf ;; SunOS) stageSolaris TAR_OPTS=-cf ;; esac UpdateState $VMSUPPORT_RUNNING banner "Creating tar archive..." tar $TAR_OPTS $TARFILE $OUTPUT_DIR if [ $? != 0 ]; then banner "The tar process did not successfully complete!" \ "If tar reports that a file changed while reading, please attempt " \ "to rerun this script." fi gzip $TARFILE TARFILE=${TARFILE}.gz banner "Uploading archive to host..." vmware-xferlogs enc $TARFILE 2>/dev/null if [ $? != 0 ]; then banner "Could not transmit logs successfully: either the vmware-xferlogs " \ "binary is not in the path, or you are not in a virtual machine." fi # Clean up temporary files rm -rf $OUTPUT_DIR if [ $? != 0 ]; then banner "$OUTPUT_DIR was not successfully removed. Please remove manually." fi UpdateState $VMSUPPORT_ENDING banner "Done, support data available in '$TARFILE'." open-vm-tools-9.4.0-1280544/scripts/common/statechange.subr0000644765153500003110000000270112220061556021601 0ustar dtormts#!/bin/sh ########################################################## # Copyright (C) 2010 VMware, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public # License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # ########################################################## ########################################################################## # DO NOT modify this file directly as it will be overwritten the next # time the VMware Tools are installed. ########################################################################## # # Panic -- # # Write a formatted error message to stderr and exit. # # Results: # Stderr is spammed, program exits with exit code 1. # # Side effects: # None. # Panic() { fmt="`date '+%b %d %H:%M:%S'` `basename \"$0\"`" if [ -n "$1" ]; then fmt="${fmt}: $1" shift fi printf >&2 "${fmt}\n" "$@" exit 1 } open-vm-tools-9.4.0-1280544/scripts/build/0000755765153500003110000000000012220061556016225 5ustar dtormtsopen-vm-tools-9.4.0-1280544/scripts/build/instvmsg.sh0000644765153500003110000000321712220061556020436 0ustar dtormts#!/bin/sh ################################################################################ ### Copyright 2011 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ # # instvmsg.sh - VMSG catalog install script. # # This script installs a set of VMSG catalogs into their correct location. It # avoids having to copy and paste this logic into several makefiles, especially # since non-GNU make does not support $(call ...). # # Arguments: # prog ($1): program name (name of target catalog file) # src ($2): directory where catalogs are stored in the source tree. # dest ($3): $(datadir) # $@ : language codes # prog=$1 src=$2 dest=$3 if test -z $dest; then echo "Missing parameters." 1>&2 exit 1 fi for i in $src/*.vmsg; do ldest=`basename $i` ldest=${dest}/open-vm-tools/messages/`echo $ldest | cut -d . -f 1 -` if ! test -d $ldest; then mkdir -p $ldest fi cp -f $i ${ldest}/${prog}.vmsg || exit 1 done open-vm-tools-9.4.0-1280544/scripts/build/rpcgen_wrapper.sh.in0000644765153500003110000000630312220061556022206 0ustar dtormts#!/bin/sh ################################################################################ ### Copyright 2011 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ # # rpcgen_wrapper.sh - executes rpcgen. # # rpcgen is very finicky in the way it's invoked. It tends to pollute the # generated files with all sorts of weird stuff if you specify full paths to the # files being compiled. So this script copies the source file (plus any other # needed files) to the build directory before invoking rpcgen. # # The pattern to use in Makefile.am is: # # . have separate rules for generating the header and the source files, both # invoking rpcgen_wrapper.sh # . make the source depend on the header # # The script assumes that $(builddir) is ".". The generated header is copied # to the "lib/include" directory under $(top_builddir). # # Arguments: # input ($1): path of .x file, relative to $(top_srcdir) # output ($2): name of output header file # extra ($@): other files to copy into the build directory; paths # relative to $(top_srcdir) # set -e rpcgen=@RPCGEN@ rpcgenflags="@RPCGENFLAGS@" top_srcdir="@abs_top_srcdir@" top_builddir="@abs_top_builddir@" input=$1 output=$2 if [ -z "$output" ]; then echo "Invalid arguments." >&2 exit 1 fi shift 2 # need_update($target, $source) need_update() { test ! -f $1 -o $1 -ot $2 } # do_rpcgen($type) # type is either "-h" or "-c" do_rpcgen() { if need_update $output `basename $input`; then rm -f $output fi $rpcgen $rpcgenflags $1 -o $output `basename $input` sed 's,rpc/rpc\.h,vmxrpc.h,' $output > ${output}.tmp mv ${output}.tmp $output } do_header() { # # Check both if srcdir != blddir, and also if we're copying a .x file from # a different component. # top_builddir=`cd $top_builddir && pwd` top_srcdir=`cd $top_srcdir && pwd` if test $top_builddir != $top_srcdir -o \ `pwd` != `dirname $top_builddir/$input`; then for f in $@; do if need_update `basename $f` $top_srcdir/$f; then cp -f $top_srcdir/$f . fi done if need_update `basename $input` $top_srcdir/$input; then cp -f $top_srcdir/$input . fi fi do_rpcgen "-h" # Export the generated header. mkdir -p $top_builddir/lib/include/guestrpc cp $output $top_builddir/lib/include/guestrpc } do_impl() { do_rpcgen "-c" } case $output in *.h) do_header "$@" ;; *.c) do_impl "$@" ;; *) echo "Unknown output file type: $output" ;; esac open-vm-tools-9.4.0-1280544/scripts/freebsd/0000755765153500003110000000000012220061556016540 5ustar dtormtsopen-vm-tools-9.4.0-1280544/scripts/freebsd/network0000644765153500003110000000517512220061556020164 0ustar dtormts#!/bin/sh ########################################################## # Copyright (C) 2010 VMware, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public # License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # ########################################################## ########################################################################## # DO NOT modify this file directly as it will be overwritten the next # time the VMware Tools are installed. ########################################################################## # # network (FreeBSD 6.3 and above) # # This script uses FreeBSD's rc(8) scripts to stop and restart networking # services in response to suspend and resume events, respectively. # echo `date` ": Executing '$0'" echo . `dirname "$0"`/../../statechange.subr # # ToggleNetwork -- # # Sources native configuration files in a subshell and executes native # scripts to either start or stop networking services associated with # a single interface. # # Results: # See description above. # # Side effects: # All side effects implied by FreeBSD's netif script. # ToggleNetwork() { ( . /etc/rc.subr . /etc/network.subr load_rc_config network for intf in `list_net_interfaces dhcp`; do /etc/rc.d/netif $1 $intf ec=$? # Failure to stop an interface should not interfere with suspend. if [ "$1" != "stop" ]; then exitCode=`expr $exitCode \| $ec` fi done ) } # # main -- # # Main entry point. Perform some sanity checking, then map state change # events to relevant networking operations. # # Results: # See comment at top of file. # main() { exitCode=0 [ -r /etc/rc.subr ] || Panic "Cannot read /etc/rc.subr." [ -r /etc/network.subr ] || Panic "Cannot read /etc/network.subr" [ -x /etc/rc.d/netif ] || Panic "Cannot read /etc/rc.d/netif" case "$1" in suspend-vm) ToggleNetwork stop ;; resume-vm) ToggleNetwork start ;; *) ;; esac return $exitCode } main "$@" open-vm-tools-9.4.0-1280544/scripts/COPYING0000644765153500003110000006347112220061556016174 0ustar dtormts GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! open-vm-tools-9.4.0-1280544/scripts/Makefile.am0000644765153500003110000000074412220061556017167 0ustar dtormtsdefaultscripts = poweron-vm-default defaultscripts += poweroff-vm-default defaultscripts += suspend-vm-default defaultscripts += resume-vm-default confdir = /etc/vmware-tools conf_SCRIPTS = ./common/vm-support conf_SCRIPTS += ./common/statechange.subr conf_SCRIPTS += $(defaultscripts) vmwsrcdir = $(confdir)/scripts/vmware vmwsrc_SCRIPTS = $(MODULES_OS)/network $(defaultscripts): $(top_srcdir)/scripts/common/statechange.sh cp $(top_srcdir)/scripts/common/statechange.sh $@ open-vm-tools-9.4.0-1280544/scripts/Makefile.in0000644765153500003110000004157212220061624017200 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = scripts DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(confdir)" "$(DESTDIR)$(vmwsrcdir)" SCRIPTS = $(conf_SCRIPTS) $(vmwsrc_SCRIPTS) SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ defaultscripts = poweron-vm-default poweroff-vm-default \ suspend-vm-default resume-vm-default confdir = /etc/vmware-tools conf_SCRIPTS = ./common/vm-support ./common/statechange.subr \ $(defaultscripts) vmwsrcdir = $(confdir)/scripts/vmware vmwsrc_SCRIPTS = $(MODULES_OS)/network all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu scripts/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu scripts/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-confSCRIPTS: $(conf_SCRIPTS) @$(NORMAL_INSTALL) @list='$(conf_SCRIPTS)'; test -n "$(confdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(confdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(confdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(confdir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(confdir)$$dir" || exit $$?; \ } \ ; done uninstall-confSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(conf_SCRIPTS)'; test -n "$(confdir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ dir='$(DESTDIR)$(confdir)'; $(am__uninstall_files_from_dir) install-vmwsrcSCRIPTS: $(vmwsrc_SCRIPTS) @$(NORMAL_INSTALL) @list='$(vmwsrc_SCRIPTS)'; test -n "$(vmwsrcdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(vmwsrcdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(vmwsrcdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(vmwsrcdir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(vmwsrcdir)$$dir" || exit $$?; \ } \ ; done uninstall-vmwsrcSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(vmwsrc_SCRIPTS)'; test -n "$(vmwsrcdir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ dir='$(DESTDIR)$(vmwsrcdir)'; $(am__uninstall_files_from_dir) mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags: TAGS TAGS: ctags: CTAGS CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(SCRIPTS) installdirs: for dir in "$(DESTDIR)$(confdir)" "$(DESTDIR)$(vmwsrcdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-confSCRIPTS install-vmwsrcSCRIPTS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-confSCRIPTS uninstall-vmwsrcSCRIPTS .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-confSCRIPTS install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip install-vmwsrcSCRIPTS installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ uninstall-confSCRIPTS uninstall-vmwsrcSCRIPTS $(defaultscripts): $(top_srcdir)/scripts/common/statechange.sh cp $(top_srcdir)/scripts/common/statechange.sh $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/modules/0000755765153500003110000000000012220061624015103 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/solaris/0000755765153500003110000000000012220061556016563 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/solaris/vmxnet/0000755765153500003110000000000012220061556020104 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/solaris/vmxnet/COPYING0000644765153500003110000004331212220061556021142 0ustar dtormts COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 1. Definitions. 1.1. "Contributor" means each individual or entity that creates or contributes to the creation of Modifications. 1.2. "Contributor Version" means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor. 1.3. "Covered Software" means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof. 1.4. "Executable" means the Covered Software in any form other than Source Code. 1.5. "Initial Developer" means the individual or entity that first makes Original Software available under this License. 1.6. "Larger Work" means a work which combines Covered Software or portions thereof with code not governed by the terms of this License. 1.7. "License" means this document. 1.8. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. 1.9. "Modifications" means the Source Code and Executable form of any of the following: A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications; B. Any new file that contains any part of the Original Software or previous Modifications; or C. Any new file that is contributed or otherwise made available under the terms of this License. 1.10. "Original Software" means the Source Code and Executable form of computer software code that is originally released under this License. 1.11. "Patent Claims" means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. 1.12. "Source Code" means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code. 1.13. "You" (or "Your") means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants. 2.1. The Initial Developer Grant. Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license: (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof). (c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License. (d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices. 2.2. Contributor Grant. Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes or otherwise makes the Modifications available to a third party. (d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Contributor. 3. Distribution Obligations. 3.1. Availability of Source Code. Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used for software exchange. 3.2. Modifications. The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License. 3.3. Required Notices. You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer. 3.4. Application of Additional Terms. You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients' rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. 3.5. Distribution of Executable Versions. You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipient's rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable form under a different license, You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. 3.6. Larger Works. You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software. 4. Versions of the License. 4.1. New Versions. Sun Microsystems, Inc. is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License. 4.2. Effect of New Versions. You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. Otherwise, You may also choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version of the License published by the license steward. 4.3. Modified Versions. When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License. 5. DISCLAIMER OF WARRANTY. COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. 6. TERMINATION. 6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. 6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as "Participant") alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant, the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement with Participant. 6.3. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination. 7. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. 8. U.S. GOVERNMENT END USERS. The Covered Software is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" (as that term is defined at 48 C.F.R. 252.227-7014(a)(1)) and "commercial computer software documentation" as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License. 9. MISCELLANEOUS. This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdiction's conflict-of-law provisions. Any litigation relating to this License shall be subject to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the losing party responsible for costs, including, without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use, distribute or otherwise make available any Covered Software. 10. RESPONSIBILITY FOR CLAIMS. As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. open-vm-tools-9.4.0-1280544/modules/solaris/vmxnet/Makefile0000644765153500003110000000503312220061556021545 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 2009 VMware, Inc. All rights reserved. # # The contents of this file are subject to the terms of the Common # Development and Distribution License (the "License") version 1.0 # and no later version. You may not use this file except in # compliance with the License. # # You can obtain a copy of the License at # http://www.opensource.org/licenses/cddl1.php # # See the License for the specific language governing permissions # and limitations under the License. # ########################################################## ## ## General build locations and variables ## MODULE := vmxnet MODULE_32 := i386/$(MODULE) MODULE_64 := amd64/$(MODULE) CFLAGS := LDFLAGS := CFLAGS += -O2 CFLAGS += -Wall -Werror CFLAGS += -U_NO_LONGLONG CFLAGS += -D_KERNEL CFLAGS += -I../../../lib/include # for buildNumber.h ## ## Objects needed to build the HGFS kernel module ## VMXNET_OBJS := vmxnet.o VMXNET_32_OBJS := $(addprefix i386/, $(VMXNET_OBJS)) VMXNET_64_OBJS := $(addprefix amd64/, $(VMXNET_OBJS)) ifeq ($(shell echo "$(VM_UNAME)" | cut -c-4),5.9) # { # Solaris 9 MODULES := $(MODULE_32) else # } { # Assume Solaris 10 or 11. MODULES := $(MODULE_32) $(MODULE_64) CFLAGS += -ffreestanding CFLAGS += -nodefaultlibs endif # } ifdef OVT_SOURCE_DIR CFLAGS += -I$(OVT_SOURCE_DIR)/lib/include CFLAGS += -I$(OVT_SOURCE_DIR)/modules/shared/vmxnet endif CFLAGS_32 := $(CFLAGS) CFLAGS_32 += -m32 LDFLAGS_32 := $(LDFLAGS) CFLAGS_64 := $(CFLAGS) CFLAGS_64 += -m64 CFLAGS_64 += -mcmodel=kernel CFLAGS_64 += -mno-red-zone LDFLAGS_64 := $(LDFLAGS) ifdef HAVE_GNU_LD LDFLAGS_64 += -m elf_x86_64 else LDFLAGS_64 += -64 endif all: prepare_dirs $(MODULES) prepare_dirs: @echo "Creating build directories" mkdir -p i386 mkdir -p amd64 $(MODULE_32): $(VMXNET_32_OBJS) @echo "Linking $@" $(LD) $(LDFLAGS_32) -r $(VMXNET_32_OBJS) -o $@ $(VMXNET_32_OBJS): i386/%.o: %.c @echo "Compiling $( #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* * This used to be defined in sys/gld.h, but was flagged as private, * and we used it anyway. Now it no longer exists, and we're stuck * with it for the time being. */ #ifndef GLD_MAX_MULTICAST #define GLD_MAX_MULTICAST 64 #endif #define __intptr_t_defined #define _STDINT_H #include "vm_basic_types.h" #include "vmxnet2_def.h" #include "vm_device_version.h" #include "net.h" #include "buildNumber.h" #define SOLVMXNET_SUCCESS 1 #define SOLVMXNET_FAILURE 0 #ifdef SOLVMXNET_DEBUG_LEVEL static int vxn_debug = SOLVMXNET_DEBUG_LEVEL; #define DPRINTF(n, args) if (vxn_debug>(n)) cmn_err args #else #define DPRINTF(n, args) #endif static char ident[] = "VMware Ethernet Adapter b" BUILD_NUMBER_NUMERIC_STRING; char _depends_on[] = {"misc/gld"}; #define MAX_NUM_RECV_BUFFERS 128 #define DEFAULT_NUM_RECV_BUFFERS 100 #define MAX_NUM_XMIT_BUFFERS 128 #define DEFAULT_NUM_XMIT_BUFFERS 100 #define CRC_POLYNOMIAL_LE 0xedb88320UL #define SOLVMXNET_MAXNAME 20 #define MAX_TX_WAIT_ON_STOP 2000 #define ETHERALIGN 2 #define SLACKBYTES 4 #define MAXPKTBUF (14 + ETHERALIGN + ETHERMTU + SLACKBYTES) #define QHIWATER (MAX_NUM_RECV_BUFFERS*ETHERMTU) #define OUTB(dp, p, v) \ ddi_put8((dp)->vxnIOHdl, \ (uint8_t *)((caddr_t)((dp)->vxnIOp) + (p)), v) #define OUTW(dp, p, v) \ ddi_put16((dp)->vxnIOHdl, \ (uint16_t *)((caddr_t)((dp)->vxnIOp) + (p)), v) #define OUTL(dp, p, v) \ ddi_put32((dp)->vxnIOHdl, \ (uint32_t *)((caddr_t)((dp)->vxnIOp) + (p)), v) #define INB(dp, p) \ ddi_get8((dp)->vxnIOHdl, \ (uint8_t *)(((caddr_t)(dp)->vxnIOp) + (p))) #define INW(dp, p) \ ddi_get16((dp)->vxnIOHdl, \ (uint16_t *)(((caddr_t)(dp)->vxnIOp) + (p))) #define INL(dp, p) \ ddi_get32((dp)->vxnIOHdl, \ (uint32_t *)(((caddr_t)(dp)->vxnIOp) + (p))) #define VMXNET_INC(val, max) \ val++; \ if (UNLIKELY(val == max)) { \ val = 0; \ } #define TX_RINGBUF_MBLK(dp, idx) (dp->txRingBuf[idx].mblk) #define TX_RINGBUF_DMAMEM(dp, idx) (dp->txRingBuf[idx].dmaMem) typedef struct { caddr_t buf; /* Virtual address */ uint32_t phyBuf; /* Physical address */ size_t bufLen; /* Buffer length */ ddi_dma_cookie_t cookie; /* Dma cookie */ uint_t cookieCount; /* Cookie count */ ddi_dma_handle_t dmaHdl; /* Dma handle */ ddi_acc_handle_t dataAccHdl; /* Dada access handle */ } dma_buf_t; typedef struct rx_dma_buf { dma_buf_t dmaDesc; /* Dma descriptor */ mblk_t *mblk; /* Streams message block */ frtn_t freeCB; /* Free callback */ struct vxn_softc *softc; /* Back pointer to softc */ struct rx_dma_buf *next; /* Next one in list */ } rx_dma_buf_t; typedef struct vxn_stats { uint32_t errxmt; /* Transmit errors */ uint32_t errrcv; /* Receive errors */ uint32_t runt; /* Runt packets */ uint32_t norcvbuf; /* Buffer alloc errors */ uint32_t interrupts; /* Interrupts */ uint32_t defer; /* Deferred transmits */ } vxn_stats_t; typedef struct tx_ring_buf { mblk_t *mblk; dma_buf_t dmaMem; } tx_ring_buf_t; typedef struct vxn_softc { char drvName[SOLVMXNET_MAXNAME]; /* Driver name string */ int unit; /* Driver instance */ vxn_stats_t stats; /* Stats */ dev_info_t *dip; /* Info pointer */ ddi_iblock_cookie_t iblockCookie; /* Interrupt block cookie */ gld_mac_info_t *macInfo; /* GLD mac info */ ddi_acc_handle_t confHdl; /* Configuration space handle */ ddi_acc_handle_t vxnIOHdl; /* I/O space handle */ caddr_t vxnIOp; /* I/O space pointer */ boolean_t morphed; /* Adapter morphed ? */ kmutex_t intrlock; /* Interrupt lock */ kmutex_t xmitlock; /* Transmit lock */ kmutex_t rxlistlock; /* Rx free pool lock */ boolean_t nicActive; /* NIC active flag */ boolean_t inIntr; /* Interrupt processing flag */ struct ether_addr devAddr; /* MAC address */ uint32_t vxnNumRxBufs; /* Number of reveice buffers */ uint32_t vxnNumTxBufs; /* Number of transmit buffers */ dma_buf_t driverDataDmaMem; /* Driver Data (dma handle) */ Vmxnet2_DriverData *driverData; /* Driver Data */ void *driverDataPhy; /* Driver Data busaddr pointer */ Vmxnet2_RxRingEntry *rxRing; /* Receive ring */ Vmxnet2_TxRingEntry *txRing; /* Transmit ring */ ddi_dma_handle_t txDmaHdl; /* Tx buffers dma handle */ rx_dma_buf_t *rxRingBuffPtr[MAX_NUM_RECV_BUFFERS]; /* DMA buffers associated with rxRing */ tx_ring_buf_t txRingBuf[MAX_NUM_XMIT_BUFFERS]; /* tx Ring buffers */ rx_dma_buf_t *rxFreeBufList; uint32_t rxNumFreeBufs; /* current # of buffers in pool */ uint32_t rxMaxFreeBufs; /* max # of buffers in pool */ uint32_t txPending; /* Pending transmits */ uint32_t maxTxFrags; /* Max Tx fragments */ int multiCount; /* Multicast address count */ struct ether_addr multicastList[GLD_MAX_MULTICAST]; /* Multicast list */ struct vxn_softc *next; /* Circular list of instances */ struct vxn_softc *prev; } vxn_softc_t; /* used for rx buffers or buffers allocated by ddi_dma_mem_alloc() */ static ddi_dma_attr_t vxn_dma_attrs = { DMA_ATTR_V0, /* dma_attr version */ 0, /* dma_attr_addr_lo */ (uint64_t)0xFFFFFFFF, /* dma_attr_addr_hi */ 0x7FFFFFFF, /* dma_attr_count_max */ 4, /* dma_attr_align */ 0x3F, /* dma_attr_burstsizes */ 1, /* dma_attr_minxfer */ (uint64_t)0xFFFFFFFF, /* dma_attr_maxxfer */ (uint64_t)0xFFFFFFFF, /* dma_attr_seg */ 1, /* dma_attr_sgllen */ 1, /* dma_attr_granular */ 0, /* dma_attr_flags */ }; /* used for tx buffers */ static ddi_dma_attr_t vxn_dma_attrs_tx = { DMA_ATTR_V0, /* dma_attr version */ 0, /* dma_attr_addr_lo */ (uint64_t)0xFFFFFFFF, /* dma_attr_addr_hi */ 0x7FFFFFFF, /* dma_attr_count_max */ 1, /* dma_attr_align */ 0x3F, /* dma_attr_burstsizes */ 1, /* dma_attr_minxfer */ (uint64_t)0xFFFFFFFF, /* dma_attr_maxxfer */ (uint64_t)0xFFFFFFFF, /* dma_attr_seg */ 1, /* dma_attr_sgllen */ 1, /* dma_attr_granular */ 0, /* dma_attr_flags */ }; static struct ether_addr etherbroadcastaddr = { {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} }; static struct ddi_device_acc_attr vxn_buf_attrs = { DDI_DEVICE_ATTR_V0, DDI_STRUCTURE_LE_ACC, DDI_STRICTORDER_ACC }; static struct ddi_device_acc_attr dev_attr = { DDI_DEVICE_ATTR_V0, DDI_STRUCTURE_LE_ACC, DDI_STRICTORDER_ACC }; static vxn_softc_t vxnList; /* for debugging */ static kmutex_t vxnListLock; static void *Vxn_Memset(void *s, int c, size_t n); static int Vxn_Reset(gld_mac_info_t *macInfo); static int Vxn_SetPromiscuous(gld_mac_info_t *macInfo, int flag); static int Vxn_GetStats(gld_mac_info_t *macInfo, struct gld_stats *gs); static void Vxn_ApplyAddressFilter(vxn_softc_t *dp); static int Vxn_SetMulticast(gld_mac_info_t *macinfo, uint8_t *ep, int flag); static int Vxn_SetMacAddress(gld_mac_info_t *macInfo, uint8_t *mac); static int Vxn_Start(gld_mac_info_t *macInfo); static int Vxn_Stop(gld_mac_info_t *macInfo); static void Vxn_FreeTxBuf(vxn_softc_t *dp, int idx); static int Vxn_EncapTxBuf(vxn_softc_t *dp, mblk_t *mp, Vmxnet2_TxRingEntry *xre, tx_ring_buf_t *txBuf); static int Vxn_Send(gld_mac_info_t *macinfo, mblk_t *mp); static boolean_t Vxn_TxComplete(vxn_softc_t *dp, boolean_t *reschedp); static boolean_t Vxn_Receive(vxn_softc_t *dp); static u_int Vxn_Interrupt(gld_mac_info_t *macInfo); static void Vxn_ReclaimRxBuf(rx_dma_buf_t *rxDesc); static void Vxn_FreeRxBuf(rx_dma_buf_t *rxDesc); static rx_dma_buf_t *Vxn_AllocRxBuf(vxn_softc_t *dp, int cansleep); static void Vxn_FreeInitBuffers(vxn_softc_t *dp); static int Vxn_AllocInitBuffers(vxn_softc_t *dp); static void Vxn_FreeDmaMem(dma_buf_t *dma); static int Vxn_AllocDmaMem(vxn_softc_t *dp, int size, int cansleep, dma_buf_t *dma); static void Vxn_FreeDriverData(vxn_softc_t *dp); static int Vxn_AllocDriverData(vxn_softc_t *dp); static int Vxn_Attach(dev_info_t *dip, ddi_attach_cmd_t cmd); static int Vxn_Detach(dev_info_t *dip, ddi_detach_cmd_t cmd); static int Vxn_AllocRxBufPool(vxn_softc_t *dp); static void Vxn_FreeRxBufPool(vxn_softc_t *dp); static rx_dma_buf_t * Vxn_AllocRxBufFromPool(vxn_softc_t *dp); static void Vxn_FreeRxBufToPool(rx_dma_buf_t *rxDesc); /* *----------------------------------------------------------------------------- * Vxn_Memset -- * memset() (Because bzero does not get resolved by module loader) * * Results: * pointer to the memory area s * * Side effects: * None *----------------------------------------------------------------------------- */ static void * Vxn_Memset(void *s, int c, size_t n) { while (n--) { ((uint8_t *)s)[n] = c; } return s; } /* *----------------------------------------------------------------------------- * Vxn_Reset -- * Stub routine to reset hardware. Presently does nothing. Start/Stop should * take care of resets. * * Results: * None * * Side effects: * None *----------------------------------------------------------------------------- */ static int Vxn_Reset(gld_mac_info_t *macInfo) { return GLD_SUCCESS; } /* *----------------------------------------------------------------------------- * Vxn_SetPromiscuous -- * Set/Reset NIC to/from promiscuous mode * * Results: * GLD_SUCCESS * * Side effects: * None *----------------------------------------------------------------------------- */ static int Vxn_SetPromiscuous(gld_mac_info_t *macInfo, int flag) { vxn_softc_t *dp = (vxn_softc_t *)macInfo->gldm_private; Vmxnet2_DriverData *dd = dp->driverData; mutex_enter(&dp->intrlock); if (flag == GLD_MAC_PROMISC_PHYS) { dd->ifflags |= VMXNET_IFF_PROMISC; } else if (flag == GLD_MAC_PROMISC_MULTI) { /* * This should really set VMXNET_IFF_ALLMULTI, * but unfortunately it doesn't exist. The next * best thing would be to set the LADRFs to all * 0xFFs and set VMXNET_IFF_MULTICAST, but that * opens up a whole new set of potential pitfalls, * so this is a reasonable temporary solution. */ dd->ifflags |= VMXNET_IFF_PROMISC; } else if (flag == GLD_MAC_PROMISC_NONE) { dd->ifflags &= ~VMXNET_IFF_PROMISC; } else { /* This could be GLD_MAC_PROMISC_NOOP? */ mutex_exit(&dp->intrlock); cmn_err(CE_WARN, "%s%d: Vxn_SetPromiscuous: Unexpected mode flag: 0x%x", dp->drvName, dp->unit, flag); return GLD_FAILURE; } OUTL(dp, VMXNET_COMMAND_ADDR, VMXNET_CMD_UPDATE_IFF); mutex_exit(&dp->intrlock); return GLD_SUCCESS; } /* *----------------------------------------------------------------------------- * Vxn_GetStats -- * Get driver specific stats * * Results: * GLD_SUCCESS * * Side effects: * None *----------------------------------------------------------------------------- */ static int Vxn_GetStats(gld_mac_info_t *macInfo, struct gld_stats *gs) { vxn_softc_t *dp = (vxn_softc_t *)macInfo->gldm_private; gs->glds_errxmt = dp->stats.errxmt; gs->glds_errrcv = dp->stats.errrcv; gs->glds_short = dp->stats.runt; gs->glds_norcvbuf = dp->stats.norcvbuf; gs->glds_intr = dp->stats.interrupts; gs->glds_defer = dp->stats.defer; return GLD_SUCCESS; } /* *----------------------------------------------------------------------------- * Vxn_ApplyAddressFilter -- * Go over multicast list and compute/apply address filter * * Results: * None * * Side effects: * None *----------------------------------------------------------------------------- */ static void Vxn_ApplyAddressFilter(vxn_softc_t *dp) { uint8_t *ep; int i, j, bit, byte; uint32_t crc, poly = CRC_POLYNOMIAL_LE; Vmxnet2_DriverData *dd = dp->driverData; volatile uint16_t *mcastTable = (uint16_t *)dd->LADRF; ASSERT(MUTEX_HELD(&dp->intrlock)); /* clear the multicast filter */ dd->LADRF[0] = 0; dd->LADRF[1] = 0; for (i = 0; i < dp->multiCount; i++) { crc = 0xffffffff; ep = (uint8_t *)&dp->multicastList[i].ether_addr_octet; for (byte = 0; byte < 6; byte++) { for (bit = *ep++, j = 0; j < 8; j++, bit >>= 1) { int test; test = ((bit ^ crc) & 0x01); crc >>= 1; if (test) { crc = crc ^ poly; } } } crc = crc >> 26; mcastTable[crc >> 4] |= 1 << (crc & 0xf); } } /* *----------------------------------------------------------------------------- * Vxn_SetMulticast -- * Add delete entry from multicast list * * Results: * GLD_FAILURE on failure * GLD_SUCCESS on success * * Side effects: * None *----------------------------------------------------------------------------- */ static int Vxn_SetMulticast(gld_mac_info_t *macinfo, uint8_t *ep, int flag) { int i; int copyLen; vxn_softc_t *dp = (vxn_softc_t *)macinfo->gldm_private; Vmxnet2_DriverData *dd = dp->driverData; if (flag == GLD_MULTI_ENABLE) { /* * Exceeded multicast address limit */ if (dp->multiCount >= GLD_MAX_MULTICAST) { return GLD_FAILURE; } /* * Add mac address to multicast list */ bcopy(ep, dp->multicastList[dp->multiCount].ether_addr_octet, ETHERADDRL); dp->multiCount++; } else { for (i=0; imultiCount; i++) { if (bcmp(ep, dp->multicastList[i].ether_addr_octet, ETHERADDRL) == 0) { goto found; } } return GLD_FAILURE; found: /* * Delete mac address from multicast list */ copyLen = (dp->multiCount - (i+1)) * sizeof(struct ether_addr); if (copyLen > 0) { bcopy(&dp->multicastList[i+1], &dp->multicastList[i], copyLen); } dp->multiCount--; } /* * Compute address filter from list of addressed and apply it */ mutex_enter(&dp->intrlock); Vxn_ApplyAddressFilter(dp); if (dp->multiCount) { ASSERT(dd->LADRF[0] || dd->LADRF[1]); dd->ifflags |= VMXNET_IFF_MULTICAST; } else { ASSERT(!(dd->LADRF[0] || dd->LADRF[1])); dd->ifflags &= ~VMXNET_IFF_MULTICAST; } OUTL(dp, VMXNET_COMMAND_ADDR, VMXNET_CMD_UPDATE_IFF); OUTL(dp, VMXNET_COMMAND_ADDR, VMXNET_CMD_UPDATE_LADRF); mutex_exit(&dp->intrlock); return GLD_SUCCESS; } /* *----------------------------------------------------------------------------- * Vxn_SetMacAddress -- * Change device MAC address * * Results: * GLD_SUCCESS * GLD_FAILURE * * Side effects: * None *----------------------------------------------------------------------------- */ static int Vxn_SetMacAddress(gld_mac_info_t *macInfo, uint8_t *mac) { int i; int err = GLD_SUCCESS; vxn_softc_t * dp = (vxn_softc_t *)macInfo->gldm_private; mutex_enter(&dp->intrlock); mutex_enter(&dp->xmitlock); /* * Don't change MAC address on a running NIC */ if (dp->nicActive) { err = GLD_FAILURE; goto out; } /* * Save new MAC address */ for (i = 0; i < 6; i++) { dp->devAddr.ether_addr_octet[i] = mac[i]; } /* * Push new MAC address down into hardware */ for (i = 0; i < 6; i++) { OUTB(dp, VMXNET_MAC_ADDR + i, mac[i]); } out: mutex_exit(&dp->xmitlock); mutex_exit(&dp->intrlock); return err; } /* *----------------------------------------------------------------------------- * Vxn_Start -- * Device start routine. Called on "ifconfig plumb" * * Results: * GLD_SUCCESS * GLD_FAILURE * * Side effects: * None *----------------------------------------------------------------------------- */ static int Vxn_Start(gld_mac_info_t *macInfo) { int err = GLD_SUCCESS; uint32_t r, capabilities, features; vxn_softc_t * dp = (vxn_softc_t *)macInfo->gldm_private; mutex_enter(&dp->intrlock); mutex_enter(&dp->xmitlock); if (!dp->nicActive) { /* * Register ring structure with hardware * * This downcast is OK because we requested a 32-bit physical address */ OUTL(dp, VMXNET_INIT_ADDR, (uint32_t)(uintptr_t)dp->driverDataPhy); OUTL(dp, VMXNET_INIT_LENGTH, dp->driverData->length); /* * Make sure registeration succeded */ r = INL(dp, VMXNET_INIT_LENGTH); if (!r) { cmn_err(CE_WARN, "%s%d: Vxn_Start: failed to register ring", dp->drvName, dp->unit); err = GLD_FAILURE; goto out; } /* * Get maximum tx fragments supported */ OUTL(dp, VMXNET_COMMAND_ADDR, VMXNET_CMD_GET_CAPABILITIES); capabilities = INL(dp, VMXNET_COMMAND_ADDR); OUTL(dp, VMXNET_COMMAND_ADDR, VMXNET_CMD_GET_FEATURES); features = INL(dp, VMXNET_COMMAND_ADDR); DPRINTF(3, (CE_CONT, "%s%d: chip capabilities=0x%x features=0x%x\n", dp->drvName, dp->unit, capabilities, features)); if ((capabilities & VMNET_CAP_SG) && (features & VMXNET_FEATURE_ZERO_COPY_TX)) { dp->maxTxFrags = VMXNET2_SG_DEFAULT_LENGTH; } else { dp->maxTxFrags = 1; } ASSERT(dp->maxTxFrags >= 1); /* * Alloc Tx DMA handle */ vxn_dma_attrs_tx.dma_attr_sgllen = dp->maxTxFrags; if (ddi_dma_alloc_handle(dp->dip, &vxn_dma_attrs_tx, DDI_DMA_SLEEP, NULL, &dp->txDmaHdl) != DDI_SUCCESS) { cmn_err(CE_WARN, "%s%d: Vxn_Start: failed to alloc tx dma handle", dp->drvName, dp->unit); err = GLD_FAILURE; goto out; } /* * Enable interrupts on the card */ dp->driverData->ifflags |= VMXNET_IFF_BROADCAST | VMXNET_IFF_DIRECTED; OUTL(dp, VMXNET_COMMAND_ADDR, VMXNET_CMD_INTR_ENABLE); OUTL(dp, VMXNET_COMMAND_ADDR, VMXNET_CMD_UPDATE_IFF); OUTL(dp, VMXNET_COMMAND_ADDR, VMXNET_CMD_UPDATE_LADRF); dp->nicActive = TRUE; } out: mutex_exit(&dp->xmitlock); mutex_exit(&dp->intrlock); return err; } /* *----------------------------------------------------------------------------- * Vxn_Stop -- * Device stop routine. Called on "ifconfig unplumb" * * Results: * GLD_SUCCESS * GLD_FAILURE * * Side effects: * None *----------------------------------------------------------------------------- */ static int Vxn_Stop(gld_mac_info_t *macInfo) { int i; int err = GLD_SUCCESS; vxn_softc_t * dp = (vxn_softc_t *)macInfo->gldm_private; boolean_t resched; mutex_enter(&dp->intrlock); mutex_enter(&dp->xmitlock); if (!dp->nicActive) { goto out; } /* * Disable interrupts */ OUTL(dp, VMXNET_COMMAND_ADDR, VMXNET_CMD_INTR_DISABLE); /* * Wait for pending transmits */ if (dp->txPending) { for (i=0; i < MAX_TX_WAIT_ON_STOP && dp->txPending; i++) { delay(drv_usectohz(1000)); OUTL(dp, VMXNET_COMMAND_ADDR, VMXNET_CMD_CHECK_TX_DONE); (void) Vxn_TxComplete(dp, &resched); /* * Don't worry about rescheduling transmits - GLD handles * this automatically. */ } } if (dp->txPending) { cmn_err(CE_WARN, "%s%d: Vxn_Stop: giving up on %d pending transmits", dp->drvName, dp->unit, dp->txPending); } OUTL(dp, VMXNET_INIT_ADDR, 0); dp->nicActive = FALSE; /* * Free Tx DMA handle * * The ddi_dma_free_handle() man page says that ddi_dma_unbind_handle() must be called * prior to calling ddi_dma_free_handle(). * However, call to ddi_dma_unbind_handle() is not required here, because * ddi_dma_addr_bind_handle() and matching ddi_dma_unbind_handle() are called from * Vxn_EncapTxBuf(). * xmitlock is held in Vxn_EncapTxBuf() as well as acquired above in Vxn_Stop(). */ ddi_dma_free_handle(&dp->txDmaHdl); dp->txDmaHdl = NULL; out: mutex_exit(&dp->xmitlock); mutex_exit(&dp->intrlock); return err; } /* *----------------------------------------------------------------------------- * Vxn_FreeTxBuf -- * Free transmit buffer * * Results: * None * * Side effects: * None *----------------------------------------------------------------------------- */ static void Vxn_FreeTxBuf(vxn_softc_t *dp, int idx) { mblk_t **txMblkp = &TX_RINGBUF_MBLK(dp, idx); dma_buf_t *dmaMem = &TX_RINGBUF_DMAMEM(dp, idx); if (*txMblkp) { freemsg(*txMblkp); *txMblkp = NULL; } if (dmaMem->buf) { Vxn_FreeDmaMem(dmaMem); ASSERT(dmaMem->buf == NULL); } } /* *----------------------------------------------------------------------------- * Vxn_EncapTxBuf -- * Go over dma mappings of Tx buffers and drop buffer physical address * into ring entry * * Results: * SOLVMXNET_SUCCESS on success * SOLVMXNET_FAILURE on failure * * Side effects: * None *---------------- ------------------------------------------------------------- */ static int Vxn_EncapTxBuf(vxn_softc_t *dp, mblk_t *mp, Vmxnet2_TxRingEntry *xre, tx_ring_buf_t *txBuf) { int frag; int fragcount; int rval; mblk_t *tp; mblk_t *mblk; boolean_t needPullup = FALSE; boolean_t dmaMemAlloced = FALSE; ASSERT(txBuf); ASSERT(txBuf->mblk == NULL); ASSERT(MUTEX_HELD(&dp->xmitlock)); xre->sg.length = 0; xre->flags = 0; fragcount = 0; for (tp = mp; tp != NULL; tp = tp->b_cont) { fragcount++; } if (fragcount > dp->maxTxFrags) { needPullup = TRUE; } pullup: frag = 0; if (needPullup) { if (!(mblk = msgpullup(mp, -1))) { cmn_err(CE_WARN, "%s%d: Vxn_EncapTxBuf: msgpullup failed", dp->drvName, dp->unit); goto err; } } else { mblk = mp; } /* * Go through message chain and drop packet pointers into ring * scatter/gather array */ for (tp = mblk; tp != NULL; tp = tp->b_cont) { uint_t nCookies; ddi_dma_cookie_t dmaCookie; int len = tp->b_wptr - tp->b_rptr; if (len) { /* * Associate tx buffer with dma handle */ ASSERT(dp->txDmaHdl); if ((rval = ddi_dma_addr_bind_handle(dp->txDmaHdl, NULL, (caddr_t)tp->b_rptr, len, DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, NULL, &dmaCookie, &nCookies)) != DDI_DMA_MAPPED) { /* * Try to handle bind failure caused by a page boundary spill * by allocating a private dma buffer and copying data into it */ if ((rval == DDI_DMA_TOOBIG) && !dmaMemAlloced ) { /* * Force pullup */ if (!needPullup && (dp->maxTxFrags > 1)) { needPullup = TRUE; goto pullup; } if (Vxn_AllocDmaMem(dp, len, FALSE, &txBuf->dmaMem) != SOLVMXNET_SUCCESS) { goto err; } dmaMemAlloced = TRUE; /* * Copy data into DMA capable buffer */ bcopy(tp->b_rptr, txBuf->dmaMem.buf, len); /* * Stick buffer physical addr in the ring */ xre->sg.sg[frag].addrLow = txBuf->dmaMem.phyBuf; xre->sg.sg[frag].length = len; frag++; continue; } else { cmn_err(CE_WARN, "%s%d: Vxn_EncapTxBuf: failed (%d) to bind dma " "handle for len %d. [dmaMemAlloced=%d]", dp->drvName, dp->unit, rval, len, dmaMemAlloced); goto err; } } /* * Extract tx buffer physical addresses from cookie */ while (nCookies) { if (UNLIKELY(frag == dp->maxTxFrags)) { (void)ddi_dma_unbind_handle(dp->txDmaHdl); if (!needPullup) { ASSERT(!dmaMemAlloced); needPullup = TRUE; goto pullup; } else { cmn_err(CE_WARN, "%s%d: Vxn_EncapTxBuf: " "exceeded max (%d) fragments in message", dp->drvName, dp->unit, dp->maxTxFrags); goto err; } } /* * Stick it in the ring */ xre->sg.sg[frag].addrLow = dmaCookie.dmac_address; xre->sg.sg[frag].length = dmaCookie.dmac_size; frag++; if (--nCookies) { ddi_dma_nextcookie(dp->txDmaHdl, &dmaCookie); } } (void)ddi_dma_unbind_handle(dp->txDmaHdl); } } if (frag > 0) { xre->sg.length = frag; /* Give ownership to NIC */ xre->sg.addrType = NET_SG_PHYS_ADDR; xre->ownership = VMXNET2_OWNERSHIP_NIC; xre->flags |= VMXNET2_TX_CAN_KEEP; txBuf->mblk = mblk; /* * If we called msgpullup to concatenate fragments, free * original mblk now since we're going to return success. */ if (mblk != mp) { freemsg(mp); } return SOLVMXNET_SUCCESS; } err: if (mblk != NULL && mblk != mp) { /* * Free mblk allocated by msgpullup. */ freemsg(mblk); } if (dmaMemAlloced) { ASSERT(txBuf->dmaMem.buf); Vxn_FreeDmaMem(&txBuf->dmaMem); } return SOLVMXNET_FAILURE; } /* *----------------------------------------------------------------------------- * Vxn_Send -- * GLD Transmit routine. Starts packet hard tx. * * Results: * GLD_SUCCESS on success * GLD_FAILURE on failure * * Side effects: * None *----------------------------------------------------------------------------- */ static int Vxn_Send(gld_mac_info_t *macinfo, mblk_t *mp) { Vmxnet2_TxRingEntry *xre; int err = GLD_SUCCESS; vxn_softc_t *dp = (vxn_softc_t *)macinfo->gldm_private; Vmxnet2_DriverData *dd = dp->driverData; boolean_t resched = FALSE; mutex_enter(&dp->xmitlock); /* * Check if ring entry at drop pointer is available */ if (TX_RINGBUF_MBLK(dp, dd->txDriverNext) != NULL) { DPRINTF(3, (CE_NOTE, "%s%d: Vxn_Send: tx ring full", dp->drvName, dp->unit)); err = GLD_NORESOURCES; dd->txStopped = TRUE; dp->stats.defer++; goto out; } xre = &dp->txRing[dd->txDriverNext]; /* * Drop packet into ring entry */ if (Vxn_EncapTxBuf(dp, mp, xre, &dp->txRingBuf[dd->txDriverNext]) != SOLVMXNET_SUCCESS) { err = GLD_FAILURE; dp->stats.errxmt++; goto out; } /* * Increment drop pointer */ VMXNET_INC(dd->txDriverNext, dd->txRingLength); dd->txNumDeferred++; dp->txPending++; /* * Transmit, if number of pending packets > tx cluster length */ if (dd->txNumDeferred >= dd->txClusterLength) { dd->txNumDeferred = 0; /* * Call hardware transmit */ INL(dp, VMXNET_TX_ADDR); } /* * Clean up transmit ring. TX completion interrupts are not guaranteed */ (void) Vxn_TxComplete(dp, &resched); out: mutex_exit(&dp->xmitlock); if (resched) { /* Tell GLD to retry any deferred packets */ gld_sched(dp->macInfo); } return err; } /* *----------------------------------------------------------------------------- * Vxn_TxComplete -- * Scan Tx ring for completed transmits. Reclaim Tx buffers. * * Results: * Returns TRUE if it found a completed transmit, FALSE otherwise. * Also sets *reschedp to TRUE if the caller should call gld_sched * to reschedule transmits (once all locks are dropped). * * Side effects: * None *----------------------------------------------------------------------------- */ static boolean_t Vxn_TxComplete(vxn_softc_t *dp, boolean_t *reschedp) { Vmxnet2_DriverData *dd = dp->driverData; boolean_t found = FALSE; boolean_t needresched = FALSE; ASSERT(MUTEX_HELD(&dp->xmitlock)); while (1) { Vmxnet2_TxRingEntry *xre = &dp->txRing[dd->txDriverCur]; if (xre->ownership != VMXNET2_OWNERSHIP_DRIVER || (TX_RINGBUF_MBLK(dp, dd->txDriverCur) == NULL)) { break; } found = TRUE; Vxn_FreeTxBuf(dp, dd->txDriverCur); dp->txPending--; VMXNET_INC(dd->txDriverCur, dd->txRingLength); if (dd->txStopped) { needresched = TRUE; dd->txStopped = FALSE; } } *reschedp = needresched; return found; } /* *----------------------------------------------------------------------------- * Vxn_Receive -- * Rx handler. First assembles the packets into a chain of mblks, * then drops locks and passes them up the stack to GLD. * * Results: * Returns TRUE if it find a packet ready for processing, FALSE * otherwise. * * Side effects: * None *----------------------------------------------------------------------------- */ static boolean_t Vxn_Receive(vxn_softc_t *dp) { int ringnext; short pktlen; Vmxnet2_DriverData *dd = dp->driverData; rx_dma_buf_t *rxDesc; rx_dma_buf_t *newRxDesc; mblk_t *mblk; mblk_t *head = NULL; mblk_t **tail = &head; mblk_t *next; boolean_t found = FALSE; /* Did we find at least one packet? */ ASSERT(MUTEX_HELD(&dp->intrlock)); /* * Walk receive ring looking for entries with ownership * reverted back to driver */ while (1) { Vmxnet2_RxRingEntry *rre; rx_dma_buf_t **rbuf; ringnext = dd->rxDriverNext; rre = &dp->rxRing[ringnext]; rbuf = &dp->rxRingBuffPtr[ringnext]; if (rre->ownership != VMXNET2_OWNERSHIP_DRIVER) { break; } found = TRUE; pktlen = rre->actualLength; if (pktlen < (60 - 4)) { /* * Ethernet header vlan tags are 4 bytes. Some vendors generate * 60byte frames including vlan tags. When vlan tag * is stripped, such frames become 60 - 4. (PR106153) */ dp->stats.errrcv++; if (pktlen != 0) { DPRINTF(3, (CE_CONT, "%s%d: runt packet\n", dp->drvName, dp->unit)); dp->stats.runt++; } } else { /* * Alloc new Rx buffer to replace current one */ newRxDesc = Vxn_AllocRxBufFromPool(dp); if (newRxDesc) { rxDesc = *rbuf; mblk = rxDesc->mblk; *rbuf = newRxDesc; rre->paddr = newRxDesc->dmaDesc.phyBuf + ETHERALIGN; rre->bufferLength = MAXPKTBUF - ETHERALIGN; rre->actualLength = 0; /* * Advance write pointer past packet length */ mblk->b_wptr = mblk->b_rptr + pktlen; /* * Add to end of chain. */ mblk->b_next = NULL; *tail = mblk; tail = &mblk->b_next; } else { dp->stats.errrcv++; dp->stats.norcvbuf++; } } /* Give the descriptor back to NIC */ rre->ownership = VMXNET2_OWNERSHIP_NIC; VMXNET_INC(dd->rxDriverNext, dd->rxRingLength); } /* * Walk chain and pass mblks up to gld_recv one by one. */ mutex_exit(&dp->intrlock); for (mblk = head; mblk != NULL; mblk = next) { next = mblk->b_next; mblk->b_next = NULL; gld_recv(dp->macInfo, mblk); } mutex_enter(&dp->intrlock); return (found); } /* *----------------------------------------------------------------------------- * Vxn_Interrupt -- * GLD interrupt handler. Scan: Rx ring for received packets, Tx ring for * completed transmits * * Results: * - DDI_INTR_CLAIMED (if we found something to do) * - DDI_INTR_UNCLAIMED (if not) * * Side effects: * None *----------------------------------------------------------------------------- */ static u_int Vxn_Interrupt(gld_mac_info_t *macInfo) { u_int ret = DDI_INTR_UNCLAIMED; vxn_softc_t *dp = (vxn_softc_t *)macInfo->gldm_private; boolean_t foundRx, foundTx; boolean_t resched = FALSE; mutex_enter(&dp->intrlock); dp->inIntr = TRUE; if (!dp->nicActive) { goto out; } /* * Ack interrupt */ OUTL(dp, VMXNET_COMMAND_ADDR, VMXNET_CMD_INTR_ACK); foundRx = Vxn_Receive(dp); mutex_enter(&dp->xmitlock); foundTx = Vxn_TxComplete(dp, &resched); mutex_exit(&dp->xmitlock); if (foundRx || foundTx) { ret = DDI_INTR_CLAIMED; dp->stats.interrupts++; } out: dp->inIntr = FALSE; mutex_exit(&dp->intrlock); if (resched) { gld_sched(dp->macInfo); } return ret; } /* *----------------------------------------------------------------------------- * Vxn_ReclaimRxBuf -- * Callback handler invoked by freemsg(). Frees Rx buffer memory and mappings * * Results: * None * * Side effects: * None *----------------------------------------------------------------------------- */ static void Vxn_ReclaimRxBuf(rx_dma_buf_t *rxDesc) { Vxn_FreeRxBufToPool(rxDesc); } /* *----------------------------------------------------------------------------- * Vxn_FreeRxBuf -- * Free allocated Rx buffer * * Results: * None * * Side effects: * None *----------------------------------------------------------------------------- */ static void Vxn_FreeRxBuf(rx_dma_buf_t *rxDesc) { ASSERT(rxDesc); if (rxDesc->mblk) { freemsg(rxDesc->mblk); } else { Vxn_FreeDmaMem(&rxDesc->dmaDesc); kmem_free(rxDesc, sizeof(rx_dma_buf_t)); } } /* *----------------------------------------------------------------------------- * Vxn_AllocRxBuf -- * Allocate Rx buffer * * Results: * Pointer to Rx buffer descriptor - on success * NULL - on failure * * Side effects: * None *----------------------------------------------------------------------------- */ static rx_dma_buf_t * Vxn_AllocRxBuf(vxn_softc_t *dp, int cansleep) { rx_dma_buf_t *rxDesc; rxDesc = (rx_dma_buf_t *)kmem_zalloc(sizeof(rx_dma_buf_t), cansleep ? KM_SLEEP : KM_NOSLEEP); if (!rxDesc) { cmn_err(CE_WARN, "%s%d: Vxn_AllocRxBuf: kmem_zalloc failed", dp->drvName, dp->unit); return NULL; } rxDesc->softc = dp; /* * Alloc dma-able packet memory */ if (Vxn_AllocDmaMem(dp, MAXPKTBUF, cansleep, &rxDesc->dmaDesc) != SOLVMXNET_SUCCESS) { kmem_free(rxDesc, sizeof(rx_dma_buf_t)); return NULL; } /* * Fill in free callback; fired by freemsg() */ rxDesc->freeCB.free_func = &Vxn_ReclaimRxBuf; rxDesc->freeCB.free_arg = (caddr_t) rxDesc; rxDesc->mblk = NULL; return rxDesc; } /* *----------------------------------------------------------------------------- * Vxn_FreeInitBuffers -- * Free allocated Tx and Rx buffers * * Results: * None * * Side effects: * None *----------------------------------------------------------------------------- */ static void Vxn_FreeInitBuffers(vxn_softc_t *dp) { int i; for (i=0; ivxnNumRxBufs; i++) { if (dp->rxRingBuffPtr[i]) { Vxn_FreeRxBuf(dp->rxRingBuffPtr[i]); dp->rxRingBuffPtr[i] = NULL; } } for (i=0; ivxnNumTxBufs; i++) { if (TX_RINGBUF_MBLK(dp, i)) { Vxn_FreeTxBuf(dp, i); } } /* * Rx pool must get freed last. Rx buffers above will * show up on the pool when freemsg callback fires. */ Vxn_FreeRxBufPool(dp); } /* *----------------------------------------------------------------------------- * Vxn_AllocRxBufPool -- * Allocate pool of rx buffers - 3 * configured Rx buffers * * Results: * SOLVMXNET_SUCCESS/SOLVMXNET_FAILURE * * * Side effects: * None *----------------------------------------------------------------------------- */ static int Vxn_AllocRxBufPool(vxn_softc_t *dp) { int i; dp->rxFreeBufList = NULL; // Allow list to double in size if needed. Any additional buffers // that are allocated on the fly will be freed back to main memory. dp->rxMaxFreeBufs = dp->vxnNumRxBufs * 6; for (i = 0; i < dp->vxnNumRxBufs * 3; i++) { rx_dma_buf_t *rxDesc; /* * Alloc rx buffer */ if (!(rxDesc = Vxn_AllocRxBuf(dp, TRUE))) { cmn_err(CE_WARN, "%s%d: Vxn_AllocRxBufPool: failed to allocate memory", dp->drvName, dp->unit); dp->rxNumFreeBufs = i; return SOLVMXNET_FAILURE; } /* * Add to free list */ rxDesc->next = dp->rxFreeBufList; dp->rxFreeBufList = rxDesc; } dp->rxNumFreeBufs = i; return SOLVMXNET_SUCCESS; } /* *----------------------------------------------------------------------------- * Vxn_FreeRxBufPool -- * Free rx buffers pool * * Results: * None * * Side effects: * None *----------------------------------------------------------------------------- */ static void Vxn_FreeRxBufPool(vxn_softc_t *dp) { while (dp->rxFreeBufList) { rx_dma_buf_t *rxDesc = dp->rxFreeBufList; /* unlink */ dp->rxFreeBufList = rxDesc->next; ASSERT(rxDesc->mblk == NULL); Vxn_FreeDmaMem(&rxDesc->dmaDesc); kmem_free(rxDesc, sizeof(rx_dma_buf_t)); } dp->rxNumFreeBufs = 0; } /* *----------------------------------------------------------------------------- * Vxn_AllocRxBufFromPool -- * Allocate Rx buffer from free pool * * Results: * Pointer to Rx buffer descriptor - on success * NULL - on failure * * Side effects: * None *----------------------------------------------------------------------------- */ static rx_dma_buf_t * Vxn_AllocRxBufFromPool(vxn_softc_t *dp) { rx_dma_buf_t *rxDesc = NULL; mutex_enter(&dp->rxlistlock); if (dp->rxFreeBufList) { rxDesc = dp->rxFreeBufList; dp->rxFreeBufList = rxDesc->next; ASSERT(dp->rxNumFreeBufs >= 1); dp->rxNumFreeBufs--; } mutex_exit(&dp->rxlistlock); if (!rxDesc) { /* * Try to allocate new descriptor from memory. Can't block here * since we could be being called from interrupt context. */ DPRINTF(5, (CE_NOTE, "%s%d: allocating rx buf from memory", dp->drvName, dp->unit)); if (!(rxDesc = Vxn_AllocRxBuf(dp, FALSE))) { cmn_err(CE_WARN, "%s%d: Vxn_AllocRxBufFromPool : pool rx alloc failed", dp->drvName, dp->unit); return NULL; } } /* * Allocate new message block for this buffer */ rxDesc->mblk = desballoc((uchar_t *)rxDesc->dmaDesc.buf + ETHERALIGN, rxDesc->dmaDesc.bufLen - ETHERALIGN, BPRI_MED, &rxDesc->freeCB); if (!rxDesc->mblk) { cmn_err(CE_WARN, "%s%d: Vxn_AllocRxBufFromPool : desballoc failed", dp->drvName, dp->unit); /* put back on free list */ Vxn_FreeRxBufToPool(rxDesc); return NULL; } return rxDesc; } /* *----------------------------------------------------------------------------- * Vxn_FreeRxBufToPool -- * Return rx buffer to free pool * * Results: * None * * Side effects: * None *----------------------------------------------------------------------------- */ static void Vxn_FreeRxBufToPool(rx_dma_buf_t *rxDesc) { vxn_softc_t *dp = rxDesc->softc; rxDesc->mblk = NULL; /* * Insert on free list, or free if the list is full */ mutex_enter(&dp->rxlistlock); if (dp->rxNumFreeBufs >= dp->rxMaxFreeBufs) { DPRINTF(5, (CE_NOTE, "%s%d: freeing rx buf to memory", dp->drvName, dp->unit)); Vxn_FreeRxBuf(rxDesc); } else { rxDesc->next = dp->rxFreeBufList; dp->rxFreeBufList = rxDesc; dp->rxNumFreeBufs++; } mutex_exit(&dp->rxlistlock); } /* *----------------------------------------------------------------------------- * Vxn_AllocInitBuffers -- * Allocated Rx buffers and init ring entries * * Results: * SOLVMXNET_SUCCESS - on success * SOLVMXNET_FAILURE - on failure * * Side effects: * None *----------------------------------------------------------------------------- */ static int Vxn_AllocInitBuffers(vxn_softc_t *dp) { Vmxnet2_DriverData *dd; uint32_t i, offset; dd = dp->driverData; offset = sizeof(*dd); /* * Init shared structures */ dd->rxRingLength = dp->vxnNumRxBufs; dd->rxRingOffset = offset; dp->rxRing = (Vmxnet2_RxRingEntry *)((uintptr_t)dd + offset); offset += dp->vxnNumRxBufs * sizeof(Vmxnet2_RxRingEntry); dd->rxRingLength2 = 1; dd->rxRingOffset2 = offset; offset += sizeof(Vmxnet2_RxRingEntry); dd->txRingLength = dp->vxnNumTxBufs; dd->txRingOffset = offset; dp->txRing = (Vmxnet2_TxRingEntry *)((uintptr_t)dd + offset); offset += dp->vxnNumTxBufs * sizeof(Vmxnet2_TxRingEntry); /* * Alloc Rx buffers pool */ if ( Vxn_AllocRxBufPool(dp) != SOLVMXNET_SUCCESS) { cmn_err(CE_WARN, "%s%d: Vxn_AllocInitBuffers: failed to alloc buf pool", dp->drvName, dp->unit); return SOLVMXNET_FAILURE; } /* * Allocate receive buffers */ for (i = 0; i < dp->vxnNumRxBufs; i++) { rx_dma_buf_t *rxDesc; Vmxnet2_RxRingEntry *rre = &dp->rxRing[i]; if (!(rxDesc = Vxn_AllocRxBufFromPool(dp))) { cmn_err(CE_WARN, "%s%d: Vxn_AllocInitBuffers: " "failed to alloc buf from pool", dp->drvName, dp->unit); goto err; } /* * Init ring entries */ rre->paddr = rxDesc->dmaDesc.phyBuf + ETHERALIGN; rre->bufferLength = MAXPKTBUF - ETHERALIGN; rre->actualLength = 0; dp->rxRingBuffPtr[i] = rxDesc; rre->ownership = VMXNET2_OWNERSHIP_NIC; } dp->txDmaHdl = NULL; /* * Dummy recvRing2 tacked on to the end, with a single unusable entry */ dp->rxRing[i].paddr = 0; dp->rxRing[i].bufferLength = 0; dp->rxRing[i].actualLength = 0; dp->rxRingBuffPtr[i] = NULL; dp->rxRing[i].ownership = VMXNET2_OWNERSHIP_DRIVER; dd->rxDriverNext = 0; /* * Give xmit ring ownership to DRIVER */ for (i = 0; i < dp->vxnNumTxBufs; i++) { dp->txRing[i].ownership = VMXNET2_OWNERSHIP_DRIVER; dp->txRingBuf[i].mblk = NULL; dp->txRingBuf[i].dmaMem.buf = NULL; dp->txRing[i].sg.sg[0].addrHi = 0; } dd->txDriverCur = dd->txDriverNext = 0; dd->txStopped = FALSE; return SOLVMXNET_SUCCESS; err: for (i=0; ivxnNumRxBufs; i++) { if (dp->rxRingBuffPtr[i]) { Vxn_FreeRxBuf(dp->rxRingBuffPtr[i]); dp->rxRingBuffPtr[i] = NULL; } } Vxn_FreeRxBufPool(dp); return SOLVMXNET_FAILURE; } /* *----------------------------------------------------------------------------- * Vxn_FreeDmaMem -- * Free allocated dma memory * * Results: * None * * Side effects: * None *----------------------------------------------------------------------------- */ static void Vxn_FreeDmaMem(dma_buf_t *dma) { ddi_dma_unbind_handle(dma->dmaHdl); ddi_dma_mem_free(&dma->dataAccHdl); ddi_dma_free_handle(&dma->dmaHdl); dma->buf = NULL; dma->phyBuf = NULL; dma->bufLen = 0; } /* *----------------------------------------------------------------------------- * Vxn_AllocDmaMem -- * Allocate dma-able memory and fill passed in dma descriptor pointer * if successful * * Results: * SOLVMXNET_SUCCESS on success * SOLVMXNET_FAILURE on failure * * Side effects: * None *----------------------------------------------------------------------------- */ static int Vxn_AllocDmaMem(vxn_softc_t *dp, int size, int cansleep, dma_buf_t *dma) { /* * Allocate handle */ if (ddi_dma_alloc_handle(dp->dip, &vxn_dma_attrs, cansleep ? DDI_DMA_SLEEP : DDI_DMA_DONTWAIT, NULL, &dma->dmaHdl) != DDI_SUCCESS) { cmn_err(CE_WARN, "%s%d: Vxn_AllocDmaMem: failed to allocate handle", dp->drvName, dp->unit); return SOLVMXNET_FAILURE; } /* * Allocate memory */ if (ddi_dma_mem_alloc(dma->dmaHdl, size, &vxn_buf_attrs, DDI_DMA_CONSISTENT, cansleep ? DDI_DMA_SLEEP : DDI_DMA_DONTWAIT, NULL, &dma->buf, &dma->bufLen, &dma->dataAccHdl) != DDI_SUCCESS) { cmn_err(CE_WARN, "%s%d: Vxn_AllocDmaMem: " "ddi_dma_mem_alloc %d bytes failed", dp->drvName, dp->unit, size); ddi_dma_free_handle(&dma->dmaHdl); return SOLVMXNET_FAILURE; } /* * Mapin memory */ if (ddi_dma_addr_bind_handle(dma->dmaHdl, NULL, dma->buf, dma->bufLen, DDI_DMA_RDWR | DDI_DMA_STREAMING, cansleep ? DDI_DMA_SLEEP : DDI_DMA_DONTWAIT, NULL, &dma->cookie, &dma->cookieCount) != DDI_DMA_MAPPED) { cmn_err(CE_WARN, "%s%d: Vxn_AllocDmaMem: failed to bind handle", dp->drvName, dp->unit); ddi_dma_mem_free(&dma->dataAccHdl); ddi_dma_free_handle(&dma->dmaHdl); return SOLVMXNET_FAILURE; } if (dma->cookieCount != 1) { cmn_err(CE_WARN, "%s%d: Vxn_AllocDmaMem: too many DMA cookies", dp->drvName, dp->unit); Vxn_FreeDmaMem(dma); return SOLVMXNET_FAILURE; } /* * Save physical address (for easy use) */ dma->phyBuf = dma->cookie.dmac_address; return SOLVMXNET_SUCCESS; } /* *----------------------------------------------------------------------------- * Vxn_FreeDriverData -- * Free driver data structures and Tx Rx buffers * * Results: * None * * Side effects: * None *----------------------------------------------------------------------------- */ static void Vxn_FreeDriverData(vxn_softc_t *dp) { Vxn_FreeInitBuffers(dp); Vxn_FreeDmaMem(&dp->driverDataDmaMem); } /* *----------------------------------------------------------------------------- * Vxn_AllocDriverData -- * Allocate driver data structures and Tx Rx buffers on init * * Results: * SOLVMXNET_SUCCESS on success * SOLVMXNET_FAILURE on failure * * Side effects: * None *----------------------------------------------------------------------------- */ static int Vxn_AllocDriverData(vxn_softc_t *dp) { uint32_t r, driverDataSize; /* * Get configured receive buffers */ OUTL(dp, VMXNET_COMMAND_ADDR, VMXNET_CMD_GET_NUM_RX_BUFFERS); r = INL(dp, VMXNET_COMMAND_ADDR); if (r == 0 || r > MAX_NUM_RECV_BUFFERS) { r = DEFAULT_NUM_RECV_BUFFERS; } dp->vxnNumRxBufs = r; /* * Get configured transmit buffers */ OUTL(dp, VMXNET_COMMAND_ADDR, VMXNET_CMD_GET_NUM_TX_BUFFERS); r = INL(dp, VMXNET_COMMAND_ADDR); if (r == 0 || r > MAX_NUM_XMIT_BUFFERS) { r = DEFAULT_NUM_XMIT_BUFFERS; } dp->vxnNumTxBufs = r; /* * Calculate shared data size and allocate memory for it */ driverDataSize = sizeof(Vmxnet2_DriverData) + /* numRecvBuffers + 1 for the dummy recvRing2 (used only by Windows) */ (dp->vxnNumRxBufs + 1) * sizeof(Vmxnet2_RxRingEntry) + dp->vxnNumTxBufs * sizeof(Vmxnet2_TxRingEntry); if (Vxn_AllocDmaMem(dp, driverDataSize, TRUE, &dp->driverDataDmaMem) != SOLVMXNET_SUCCESS) { return SOLVMXNET_FAILURE; } /* * Clear memory (bzero isn't resolved by module loader for some reason) */ ASSERT(dp->driverDataDmaMem.buf && dp->driverDataDmaMem.bufLen); Vxn_Memset(dp->driverDataDmaMem.buf, 0, dp->driverDataDmaMem.bufLen); dp->driverData = (Vmxnet2_DriverData *)dp->driverDataDmaMem.buf; dp->driverDataPhy = (void *)(uintptr_t)dp->driverDataDmaMem.phyBuf; /* So that the vmkernel can check it is compatible */ dp->driverData->magic = VMXNET2_MAGIC; dp->driverData->length = driverDataSize; /* * Alloc rx/tx buffers, init ring, register with hardware etc. */ if (Vxn_AllocInitBuffers(dp) != SOLVMXNET_SUCCESS) { Vxn_FreeDmaMem(&dp->driverDataDmaMem); return SOLVMXNET_FAILURE; } DPRINTF(3, (CE_CONT, "%s%d: numRxBufs=(%d*%"FMT64"d) numTxBufs=(%d*%"FMT64"d)" " driverDataSize=%d driverDataPhy=0x%p\n", dp->drvName, dp->unit, dp->vxnNumRxBufs, (uint64_t)sizeof(Vmxnet2_RxRingEntry), dp->vxnNumTxBufs, (uint64_t)sizeof(Vmxnet2_TxRingEntry), driverDataSize, dp->driverDataPhy)); return SOLVMXNET_SUCCESS; } /* *----------------------------------------------------------------------------- * Vxn_Attach -- * Probe and attach driver to stack * * Results: * DDI_SUCCESS * DDI_FAILURE * * Side effects: * None *----------------------------------------------------------------------------- */ static int Vxn_Attach(dev_info_t *dip, ddi_attach_cmd_t cmd) { int i, ret, len, unit; const char *drvName; ddi_acc_handle_t confHdl; uint16_t vid, did; uint8_t revid; struct pci_phys_spec *regs; caddr_t vxnIOp; ddi_acc_handle_t vxnIOHdl; uint32_t vLow, vHigh; gld_mac_info_t *macInfo; vxn_softc_t *dp; boolean_t morphed = FALSE; uint_t regSpaceSize; uint_t chip; uint_t vxnIOSize; if (cmd != DDI_ATTACH) { return DDI_FAILURE; } unit = ddi_get_instance(dip); drvName = ddi_driver_name(dip); /* * Check if chip is supported. */ if (pci_config_setup(dip, &confHdl) != DDI_SUCCESS) { cmn_err(CE_WARN, "%s%d: pci_config_setup() failed", drvName, unit); return DDI_FAILURE; } vid = pci_config_get16(confHdl, PCI_CONF_VENID); did = pci_config_get16(confHdl, PCI_CONF_DEVID); revid = pci_config_get8(confHdl, PCI_CONF_REVID); if (vid == PCI_VENDOR_ID_VMWARE && did == PCI_DEVICE_ID_VMWARE_NET) { /* Found vmxnet */ chip = VMXNET_CHIP; } else if (vid == PCI_VENDOR_ID_AMD && did == PCI_DEVICE_ID_AMD_VLANCE) { /* Found vlance (maybe a vmxnet disguise) */ chip = LANCE_CHIP; } else { /* Not Found */ DPRINTF(3, (CE_WARN, "%s: Vxn_Attach: wrong PCI venid/devid (0x%x, 0x%x)", drvName, vid, did)); goto err; } DPRINTF(3, (CE_CONT, "%s%d: (vid: 0x%04x, did: 0x%04x, revid: 0x%02x)\n", drvName, unit, vid, did, revid)); /* * Get device properties */ regs = NULL; len = 0; if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "reg", (caddr_t)®s, &len) != DDI_PROP_SUCCESS) { cmn_err(CE_WARN, "%s%d: Vxn_Attach: failed to get reg property", drvName, unit); goto err; } ASSERT(regs != NULL && len > 0); /* * Search device properties for IO-space */ for (i = 0; i regSpaceSize) { cmn_err(CE_WARN, "%s%d: Vxn_Attach: " "vlance device is not supported by this driver", drvName, unit); goto err_free_regs_map; } /* * Morph, if we found a vlance adapter */ if (chip == LANCE_CHIP) { uint16_t magic; /* Read morph port to verify that we can morph the adapter */ magic = ddi_get16(vxnIOHdl, (uint16_t *)(vxnIOp - MORPH_PORT_SIZE)); if (magic != LANCE_CHIP && magic != VMXNET_CHIP) { cmn_err(CE_WARN, "%s%d: Vxn_Attach: Invalid magic, read: 0x%08X", drvName, unit, magic); goto err_free_regs_map; } /* Morph */ ddi_put16(vxnIOHdl, (uint16_t *)(vxnIOp - MORPH_PORT_SIZE), VMXNET_CHIP); morphed = TRUE; /* Verify that we morphed correctly */ magic = ddi_get16(vxnIOHdl, (uint16_t *)(vxnIOp - MORPH_PORT_SIZE)); if (magic != VMXNET_CHIP) { cmn_err(CE_WARN, "%s%d: Vxn_Attach: Couldn't morph adapter." " Invalid magic, read:: 0x%08X", drvName, unit, magic); goto err_morph_back; } } /* * Check the version number of the device implementation */ vLow = (uint32_t)ddi_get32(vxnIOHdl, (uint32_t *)(vxnIOp+VMXNET_LOW_VERSION)); vHigh = (uint32_t)ddi_get32(vxnIOHdl, (uint32_t *)(vxnIOp+VMXNET_HIGH_VERSION)); if ((vLow & 0xffff0000) != (VMXNET2_MAGIC & 0xffff0000) || ((VMXNET2_MAGIC < vLow) || (VMXNET2_MAGIC > vHigh))) { cmn_err(CE_WARN, "%s%d: Vxn_Attach: driver version 0x%08X doesn't " "match device 0x%08X:0x%08X", drvName, unit, VMXNET2_MAGIC, vLow, vHigh); goto err_version_mismatch; } /* * Alloc soft state */ macInfo = gld_mac_alloc(dip); if (!macInfo) { cmn_err(CE_WARN, "%s%d: Vxn_Attach: gld_mac_alloc failed", drvName, unit); goto err_gld_mac_alloc; } dp = (vxn_softc_t *) kmem_zalloc(sizeof(vxn_softc_t), KM_SLEEP); ASSERT(dp); /* * Get interrupt cookie */ if (ddi_get_iblock_cookie(dip, 0, &dp->iblockCookie) != DDI_SUCCESS) { cmn_err(CE_WARN, "%s%d: Vxn_Attach: ddi_get_iblock_cookie failed", drvName, unit); goto err_get_iblock_cookie; } strncpy(dp->drvName, drvName, SOLVMXNET_MAXNAME); dp->unit = unit; dp->dip = dip; dp->macInfo = macInfo; dp->confHdl = confHdl; dp->vxnIOHdl = vxnIOHdl; dp->vxnIOp = vxnIOp; dp->morphed = morphed; dp->nicActive = FALSE; dp->txPending = 0; dp->maxTxFrags = 1; /* * Initialize mutexes */ mutex_init(&dp->intrlock, NULL, MUTEX_DRIVER, (void *)dp->iblockCookie); mutex_init(&dp->xmitlock, NULL, MUTEX_DRIVER, (void *)dp->iblockCookie); mutex_init(&dp->rxlistlock, NULL, MUTEX_DRIVER, (void *)dp->iblockCookie); /* * Allocate and initialize our private and shared data structures */ if (Vxn_AllocDriverData(dp) != SOLVMXNET_SUCCESS) { goto err_alloc_driverdata; } /* * Read the MAC address from the device */ for (i = 0; i < 6; i++) { dp->devAddr.ether_addr_octet[i] = (uint8_t)ddi_get8(vxnIOHdl, (uint8_t *)(vxnIOp + VMXNET_MAC_ADDR + i)); } macInfo->gldm_vendor_addr = dp->devAddr.ether_addr_octet; macInfo->gldm_broadcast_addr = etherbroadcastaddr.ether_addr_octet; DPRINTF(3, (CE_CONT, "MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", dp->devAddr.ether_addr_octet[0], dp->devAddr.ether_addr_octet[1], dp->devAddr.ether_addr_octet[2], dp->devAddr.ether_addr_octet[3], dp->devAddr.ether_addr_octet[4], dp->devAddr.ether_addr_octet[5])); /* * Configure GLD entry points */ macInfo->gldm_devinfo = dip; macInfo->gldm_private = (caddr_t)dp; macInfo->gldm_cookie = dp->iblockCookie; macInfo->gldm_reset = Vxn_Reset; macInfo->gldm_start = Vxn_Start; macInfo->gldm_stop = Vxn_Stop; macInfo->gldm_set_mac_addr = Vxn_SetMacAddress; macInfo->gldm_send = Vxn_Send; macInfo->gldm_set_promiscuous = Vxn_SetPromiscuous; macInfo->gldm_get_stats = Vxn_GetStats; macInfo->gldm_ioctl = NULL; macInfo->gldm_set_multicast= Vxn_SetMulticast; macInfo->gldm_intr = Vxn_Interrupt; macInfo->gldm_mctl = NULL; macInfo->gldm_ident = (char *)ddi_driver_name(dip); macInfo->gldm_type = DL_ETHER; macInfo->gldm_minpkt = 0; macInfo->gldm_maxpkt = ETHERMTU; macInfo->gldm_addrlen = ETHERADDRL; macInfo->gldm_saplen = -2; macInfo->gldm_ppa = unit; /* * Register with GLD (Generic Lan Driver) framework */ if (gld_register(dip, (char *)ddi_driver_name(dip), macInfo) != DDI_SUCCESS) { goto err_gld_register; } /* * Add interrupt to system. */ if (ddi_add_intr(dip, 0, NULL, NULL, gld_intr, (caddr_t)macInfo) != DDI_SUCCESS) { cmn_err(CE_WARN, "%s%d: ddi_add_intr failed", drvName, unit); goto err_ddi_add_intr; } /* * Add to list of interfaces. */ mutex_enter(&vxnListLock); dp->next = &vxnList; dp->prev = vxnList.prev; vxnList.prev->next = dp; vxnList.prev = dp; mutex_exit(&vxnListLock); /* * Success */ return DDI_SUCCESS; err_ddi_add_intr: gld_unregister(macInfo); err_gld_register: Vxn_FreeDriverData(dp); err_alloc_driverdata: mutex_destroy(&dp->intrlock); mutex_destroy(&dp->xmitlock); err_get_iblock_cookie: kmem_free(dp, sizeof(*dp)); gld_mac_free(macInfo); err_gld_mac_alloc: err_version_mismatch: err_morph_back: if (morphed) { ddi_put16(vxnIOHdl, (uint16_t *)(vxnIOp - MORPH_PORT_SIZE), LANCE_CHIP); } err_free_regs_map: ddi_regs_map_free(&vxnIOHdl); err: pci_config_teardown(&confHdl); return DDI_FAILURE; } /* *----------------------------------------------------------------------------- * Vxn_Detach -- * Called on module unload * * Results: * DDI_SUCCESS * DDI_FAILURE * * Side effects: * None *----------------------------------------------------------------------------- */ static int Vxn_Detach(dev_info_t *dip, ddi_detach_cmd_t cmd) { gld_mac_info_t *macInfo; vxn_softc_t *dp; macInfo = (gld_mac_info_t *)ddi_get_driver_private(dip); dp = (vxn_softc_t *)macInfo->gldm_private; if (cmd == DDI_DETACH) { /* * Tear down interrupt */ ddi_remove_intr(dip, 0, macInfo->gldm_cookie); gld_unregister(macInfo); /* * Quiesce hardware */ Vxn_Stop(macInfo); /* * Free driver-data, tx/rx buffers etc */ Vxn_FreeDriverData(dp); /* * Destroy locks */ mutex_destroy(&dp->intrlock); mutex_destroy(&dp->xmitlock); /* * Unmorph */ if (dp->morphed) { uint16_t magic; /* Verify that we had morphed earlier */ magic = ddi_get16(dp->vxnIOHdl, (uint16_t *)(dp->vxnIOp - MORPH_PORT_SIZE)); if (magic != VMXNET_CHIP) { cmn_err(CE_WARN, "%s%d: Vxn_Detach: Adapter not morphed" " magic=0x%08X", dp->drvName, dp->unit, magic); } else { /* Unmorph */ ddi_put16(dp->vxnIOHdl, (uint16_t *)(dp->vxnIOp - MORPH_PORT_SIZE), LANCE_CHIP); /* Verify */ magic = ddi_get16(dp->vxnIOHdl, (uint16_t *)(dp->vxnIOp - MORPH_PORT_SIZE)); if (magic != LANCE_CHIP) { cmn_err(CE_WARN, "%s%d: Vxn_Detach: Unable to unmorph adapter" " magic=0x%08X", dp->drvName, dp->unit, magic); } } } /* * Release resister mappings */ ddi_regs_map_free(&dp->vxnIOHdl); pci_config_teardown(&dp->confHdl); /* * Remove from list of interfaces. */ mutex_enter(&vxnListLock); ASSERT(dp != &vxnList); dp->prev->next = dp->next; dp->next->prev = dp->prev; mutex_exit(&vxnListLock); /* * Release memory */ kmem_free(dp, sizeof(*dp)); gld_mac_free(macInfo); return DDI_SUCCESS; } else { return DDI_FAILURE; } } static struct module_info vxnminfo = { 0, /* mi_idnum */ "vmxnet", /* mi_idname */ 0, /* mi_minpsz */ ETHERMTU, /* mi_maxpsz */ QHIWATER, /* mi_hiwat */ 1, /* mi_lowat */ }; static struct qinit vxnrinit = { NULL, /* qi_putp */ gld_rsrv, /* qi_srvp */ gld_open, /* qi_qopen */ gld_close, /* qi_qclose */ NULL, /* qi_qadmin */ &vxnminfo, /* qi_minfo */ NULL /* qi_mstat */ }; static struct qinit vxnwinit = { gld_wput, /* qi_putp */ gld_wsrv, /* qi_srvp */ NULL, /* qi_qopen */ NULL, /* qi_qclose */ NULL, /* qi_qadmin */ &vxnminfo, /* qi_minfo */ NULL /* qi_mstat */ }; static struct streamtab vxn_info = { &vxnrinit, /* st_rdinit */ &vxnwinit, /* st_wrinit */ NULL, /* st_muxrinit */ NULL /* st_muxwrinit */ }; static struct cb_ops cb_vxn_ops = { nulldev, /* cb_open */ nulldev, /* cb_close */ nodev, /* cb_strategy */ nodev, /* cb_print */ nodev, /* cb_dump */ nodev, /* cb_read */ nodev, /* cb_write */ nodev, /* cb_ioctl */ nodev, /* cb_devmap */ nodev, /* cb_mmap */ nodev, /* cb_segmap */ nochpoll, /* cb_chpoll */ ddi_prop_op, /* cb_prop_op */ &vxn_info, /* cb_stream */ D_NEW|D_MP /* cb_flag */ }; static struct dev_ops vxn_ops = { DEVO_REV, /* devo_rev */ 0, /* devo_refcnt */ gld_getinfo, /* devo_getinfo */ nulldev, /* devo_identify */ nulldev, /* devo_probe */ Vxn_Attach, /* devo_attach */ Vxn_Detach, /* devo_detach */ nodev, /* devo_reset */ &cb_vxn_ops, /* devo_cb_ops */ NULL, /* devo_bus_ops */ #ifdef SOL11 NULL, #else ddi_power /* devo_power */ #endif }; static struct modldrv modldrv = { &mod_driverops, ident, &vxn_ops, }; static struct modlinkage modlinkage = { MODREV_1, {&modldrv, NULL,} }; /* * Module load entry point */ int _init(void) { int err; DPRINTF(5, (CE_CONT, "vxn: _init:\n")); /* Initialize interface list */ vxnList.next = vxnList.prev = &vxnList; mutex_init(&vxnListLock, NULL, MUTEX_DRIVER, NULL); if ((err = mod_install(&modlinkage)) != 0) { mutex_destroy(&vxnListLock); } return err; } /* * Module unload entry point */ int _fini(void) { int err; DPRINTF(5, (CE_CONT, "vxn: _fini:\n")); if ((err = mod_remove(&modlinkage)) == 0) { mutex_destroy(&vxnListLock); } return err; } /* * Module info entry point */ int _info(struct modinfo *modinfop) { return (mod_info(&modlinkage, modinfop)); } open-vm-tools-9.4.0-1280544/modules/solaris/vmblock/0000755765153500003110000000000012220061556020220 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/solaris/vmblock/module.h0000644765153500003110000000627212220061556021665 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * module.h -- * * Defnitions for entire vmblock module. */ #ifndef __MODULE_H_ #define __MODULE_H_ #include #include #include #include #include #include #if SOL11 #include /* fs_operation_def_t, ... */ #endif #include "vm_basic_types.h" /* * Macros */ #define VMBLOCK_FS_NAME "vmblock" #define VMBLOCK_VFS_FLAGS 0 #define VMBLOCK_VFSSW_FLAGS 0 #define VFSPTOMIP(vfsp) ((VMBlockMountInfo *)(vfsp)->vfs_data) #define VPTOMIP(vp) VFSPTOMIP((vp)->v_vfsp) #define VPTOVIP(vp) ((VMBlockVnodeInfo *)(vp)->v_data) /* * Debug logging */ #define VMBLOCK_DEBUG CE_WARN #define VMBLOCK_ERROR CE_WARN #define VMBLOCK_ENTRY_LOGLEVEL 7 #undef ASSERT #ifdef VMX86_DEVEL # define Debug(level, fmt, args...) level > LOGLEVEL ? \ 0 : \ cmn_err(VMBLOCK_DEBUG, fmt, ##args) # define LOG(level, fmt, args...) Debug(level, fmt, ##args) # define ASSERT(expr) (expr) ? \ 0 : \ cmn_err(CE_PANIC, "ASSERT: %s:%d\n", \ __FILE__, __LINE__) #else # define Debug(level, fmt, args...) # define LOG(level, fmt, args...) # define ASSERT(expr) #endif #define Warning(fmt, args...) cmn_err(VMBLOCK_ERROR, fmt, ##args) #if defined(SOL9) # define OS_VFS_VERSION 2 #elif defined(SOL10) # define OS_VFS_VERSION 3 #elif defined(SOL11) # define OS_VFS_VERSION 5 #else # error "Unknown Solaris version, can't set OS_VFS_VERSION" #endif #if OS_VFS_VERSION <= 3 # define VMBLOCK_VOP(vopName, vopFn, vmblkFn) { vopName, vmblkFn } #else # define VMBLOCK_VOP(vopName, vopFn, vmblkFn) { vopName, { .vopFn = vmblkFn } } #endif /* * Types */ typedef struct VMBlockMountInfo { struct vnode *root; struct vnode *redirectVnode; struct pathname redirectPath; } VMBlockMountInfo; typedef struct VMBlockVnodeInfo { struct vnode *realVnode; char name[MAXNAMELEN]; size_t nameLen; } VMBlockVnodeInfo; /* * Externs */ /* Filesystem initialization routine (see vnops.c) */ EXTERN int VMBlockInit(int, char *); /* Needed in struct modlfs */ EXTERN struct mod_ops mod_fsops; EXTERN const fs_operation_def_t vnodeOpsArr[]; EXTERN vnodeops_t *vmblockVnodeOps; EXTERN int vmblockType; EXTERN int LOGLEVEL; #endif /* __MODULE_H_ */ open-vm-tools-9.4.0-1280544/modules/solaris/vmblock/module.c0000644765153500003110000000765212220061556021663 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * module.c -- * * Main loading and unloading of kernel module. */ #include #include "module.h" #include "block.h" static vfsdef_t VMBlockVfsDef = { VFSDEF_VERSION, /* Structure version: defined in */ VMBLOCK_FS_NAME, /* Name of file system */ VMBlockInit, /* File system initialization routine */ VMBLOCK_VFSSW_FLAGS, /* File system flags */ NULL /* No mount options */ }; /* Filesystem module structure */ static struct modlfs VMBlockModlfs = { &mod_fsops, /* Module operation structure: for * auto loading/unloading */ "VMBlock File system", /* Name */ &VMBlockVfsDef /* Filesystem type definition record */ }; static struct modlinkage VMBlockModlinkage = { MODREV_1, /* Module revision: must be MODREV_1 */ { &VMBlockModlfs, /* FS module structure */ NULL, } }; #ifdef VMX86_DEBUG /* XXX: Figure out how to pass this in at module load time. */ int LOGLEVEL = 4; #else int LOGLEVEL = 0; #endif int vmblockType; vnodeops_t *vmblockVnodeOps; /* * Module loading/unloading/info functions. */ /* *---------------------------------------------------------------------------- * * _init -- * Invoked when module is being loaded into kernel, and is called before * any function in the module. Any state that spans all instances of the * driver should be allocated and initialized here. * * Results: * Returns the result of mod_install(9F), which is zero on success and a * non-zero value on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int _init(void) { int error; error = mod_install(&VMBlockModlinkage); if (error) { Warning("Could not install vmblock module.\n"); return error; } error = BlockInit(); if (error) { Warning("Could not initialize blocking.\n"); mod_remove(&VMBlockModlinkage); return error; } return 0; } /* *---------------------------------------------------------------------------- * * _fini -- * Invoked when a module is being removed from the kernel. * * Results: * Returns the result of mod_remove(9F), which is zero on success, and a * non-zero value on failure. * * Side effects: * The module will be removed from the kernel. * *---------------------------------------------------------------------------- */ int _fini(void) { int error; error = mod_remove(&VMBlockModlinkage); if (error) { Warning("Could not remove vmblock module.\n"); return error; } BlockCleanup(); vfs_freevfsops_by_type(vmblockType); vn_freevnodeops(vmblockVnodeOps); return 0; } /* *---------------------------------------------------------------------------- * * _info -- * * Invoked when the modinfo(1M) command is executed. mod_info(9F) handles * this for us. * * Results: * Returns mod_info(9F)'s results, which are a non-zero value on success, and * zero on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int _info(struct modinfo *modinfop) // OUT: Filled in with module's information { return mod_info(&VMBlockModlinkage, modinfop); } open-vm-tools-9.4.0-1280544/modules/solaris/vmblock/vnops.c0000644765153500003110000003672712220061556021550 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * vnops.c -- * * vnode operations for vmblock file system. * */ #include #include #include #include /* FREAD, FWRITE, etc flags */ #include /* fs_fab_acl */ #include /* S_IRWXU and friends */ #include /* Directory name lookup cache */ #include /* k_sigset_t and signal macros */ #include /* practive (the active process) */ #include /* u macro for current user area */ #include /* curthread and curproc macros */ #include /* segment vnode mapping for mmap() */ #include /* VM address mapping functions */ #include /* strlen() */ #include "vmblock.h" #include "module.h" #include "block.h" extern int VMBlockVnodePut(struct vnode *vp); extern int VMBlockVnodeGet(struct vnode **vpp, struct vnode *realVp, const char *name, size_t nameLen, struct vnode *dvp, struct vfs *vfsp, Bool isRoot); /* * Vnode Entry Points */ /* *---------------------------------------------------------------------------- * * VMBlockOpen -- * * Invoked when open(2) is called on a file in our filesystem. * * "Opens a file referenced by the supplied vnode. The open() system call * has already done a vop_lookup() on the path name, which returned a vnode * pointer and then calls to vop_open(). This function typically does very * little since most of the real work was performed by vop_lookup()." * (Solaris Internals, p537) * * Results: * Zero on success, error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VMBlockOpen(struct vnode **vpp, // IN: Vnode for file to open int flag, // IN: Open flags struct cred *cr // IN: Credentials of caller #if OS_VFS_VERSION >= 5 , caller_context_t *ctx // IN: Caller's context #endif ) { VMBlockMountInfo *mip; Bool isRoot = TRUE; Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockOpen: entry\n"); /* * The opened vnode is held for us, so we don't need to do anything here * except make sure only root opens the mount point. */ mip = VPTOMIP(*vpp); if (mip->root == *vpp) { isRoot = crgetuid(cr) == 0; } return isRoot ? 0 : EACCES; } /* *---------------------------------------------------------------------------- * * VMBlockClose -- * * Invoked when a user calls close(2) on a file in our filesystem. * * "Closes the file given by the supplied vnode. When this is the last * close, some filesystems use vop_close() to initiate a writeback of * outstanding dirty pages by checking the reference cound in the vnode." * (Solaris Internals, p536) * * Results: * Zero on success, error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VMBlockClose(struct vnode *vp, // IN: Vnode of file that is being closed int flag, // IN: Flags file was opened with int count, // IN: Reference count on this vnode offset_t offset, // IN: File offset struct cred *cr // IN :Credentials of caller #if OS_VFS_VERSION >= 5 , caller_context_t *ctx // IN: Caller's context #endif ) { VMBlockMountInfo *mip; Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockClose: entry\n"); /* * If someone is closing the root of our file system (the mount point), then * we need to remove all blocks that were added by this thread. Note that * Solaris calls close with counts greater than one, but we only want to * actually close the file when the count reaches one. */ mip = VPTOMIP(vp); if (count == 1 && vp == mip->root) { BlockRemoveAllBlocks(curthread); } return 0; } /* *---------------------------------------------------------------------------- * * VMBlockIoctl -- * * Invoked when a user calls ioctl(2) on a file in our filesystem. * Performs a specified operation on the file. * * Results: * Zero on success, error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VMBlockIoctl(struct vnode *vp, // IN: Vnode of file to operate on int cmd, // IN: Requested command from user intptr_t arg, // IN: Arguments for command int flag, // IN: File pointer flags and data model struct cred *cr, // IN: Credentials of caller int *rvalp // OUT: Return value on success #if OS_VFS_VERSION >= 5 , caller_context_t *ctx // IN: Caller's context #endif ) { VMBlockMountInfo *mip; int ret; Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockIoctl: entry\n"); mip = VPTOMIP(vp); if (vp != mip->root) { return ENOTSUP; } if (rvalp) { *rvalp = 0; } switch (cmd) { case VMBLOCK_ADD_FILEBLOCK: case VMBLOCK_DEL_FILEBLOCK: { struct pathname pn; ret = pn_get((char *)arg, UIO_USERSPACE, &pn); if (ret) { goto out; } /* Remove all trailing path separators. */ while (pn.pn_pathlen > 0 && pn.pn_path[pn.pn_pathlen - 1] == '/') { pn.pn_path[pn.pn_pathlen - 1] = '\0'; pn.pn_pathlen--; } ret = cmd == VMBLOCK_ADD_FILEBLOCK ? BlockAddFileBlock(pn.pn_path, curthread) : BlockRemoveFileBlock(pn.pn_path, curthread); pn_free(&pn); break; } #ifdef VMX86_DEVEL case VMBLOCK_LIST_FILEBLOCKS: BlockListFileBlocks(); ret = 0; break; #endif default: Warning("VMBlockIoctl: unknown command (%d) received.\n", cmd); return ENOTSUP; } out: return ret; } /* *---------------------------------------------------------------------------- * * VMBlockGetattr -- * * "Gets the attributes for the supplied vnode." (Solaris Internals, p536) * * Results: * Zero on success, error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VMBlockGetattr(struct vnode *vp, // IN: Vnode of file to get attributes for struct vattr *vap, // OUT: Filled in with attributes of file int flags, // IN: Getattr flags (see ATTR_ in vnode.h) struct cred *cr // IN: Credentials of caller #if OS_VFS_VERSION >= 5 , caller_context_t *ctx // IN: Caller's context #endif ) { VMBlockMountInfo *mip; VMBlockVnodeInfo *vip; int ret; Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockGetattr: entry\n"); mip = VPTOMIP(vp); vip = VPTOVIP(vp); ASSERT(mip); ASSERT(vip); ret = VOP_GETATTR(vip->realVnode, vap, flags, cr #if OS_VFS_VERSION >= 5 , ctx #endif ); if (ret) { return ret; } if (vp == mip->root) { vap->va_type = VDIR; } else { vap->va_type = VLNK; } return 0; } /* *---------------------------------------------------------------------------- * * VMBlockAccess -- * * This function is invoked when the user calls access(2) on a file in our * filesystem. It checks to ensure the user has the specified type of * access to the file. * * Results: * Zero if access is allowed, error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VMBlockAccess(struct vnode *vp, // IN: Vnode of file to check access for int mode, // IN: Mode of access int flags, // IN: Flags struct cred *cr // IN: Credentials of caller #if OS_VFS_VERSION >= 5 , caller_context_t *ctx // IN: Caller's context #endif ) { Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockAccess: entry\n"); /* Success */ return 0; } /* *---------------------------------------------------------------------------- * * VMBlockLookup -- * * Looks in the provided directory for the specified filename. Only * succeeds and creates a vmblock vnode if nm exists in the redirect path. * * "Looks up the path name for the supplied vnode. The vop_lookup() does * file-name translation for the open, stat system calls." (Solaris * Internals, p537) * * Results: * Returns zero on success and ENOENT if the file cannot be found * If file is found, a vnode representing the file is returned in vpp. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VMBlockLookup(struct vnode *dvp, // IN: Directory to look in char *nm, // IN: Name of component to lookup in directory struct vnode **vpp, // OUT: Pointer to vnode representing found file struct pathname *pnp,// IN: Full pathname being looked up int flags, // IN: Lookup flags (see vnode.h) struct vnode *rdir, // IN: Vnode of root device struct cred *cr // IN: Credentials of caller #if OS_VFS_VERSION >= 5 , caller_context_t *ctx // IN: Caller's context , int *direntflags // IN: , struct pathname *rpnp // IN: #endif ) { struct vnode *realVp; VMBlockMountInfo *mip; int ret; Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMblockLookup: entry\n"); /* First ensure that we are looking in a directory. */ if (dvp->v_type != VDIR) { return ENOTDIR; } /* Don't invoke lookup for ourself. */ if (nm[0] == '\0' || (nm[0] == '.' && nm[1] == '\0')) { VN_HOLD(dvp); *vpp = dvp; return 0; } *vpp = NULL; /* Make sure nm exists before creating our link to it. */ mip = VPTOMIP(dvp); ret = VOP_LOOKUP(mip->redirectVnode, nm, &realVp, pnp, flags, rdir, cr #if OS_VFS_VERSION >= 5 , ctx, direntflags, rpnp #endif ); if (ret) { return ret; } ret = VMBlockVnodeGet(vpp, realVp, nm, strlen(nm), dvp, dvp->v_vfsp, FALSE); if (ret) { VN_RELE(realVp); return ret; } return 0; } /* *---------------------------------------------------------------------------- * * VMBlockReaddir -- * * Reads as many entries from the directory as will fit in to the provided * buffer. * * "The vop_readdir() method reads chunks of the directory into a uio * structure. Each chunk can contain as many entries as will fit within * the size supplied by the uio structure. The uio_resid structure member * shows the size of the getdents request in bytes, which is divided by the * size of the directory entry made by the vop_readdir() method to * calculate how many directory entries to return." (Solaris Internals, * p555) * * Results: * Zero on success, error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VMBlockReaddir(struct vnode *vp, // IN: Vnode of directory to read struct uio *uiop, // IN: User's read request struct cred *cr, // IN: Credentials of caller int *eofp // OUT: Indicates we are done #if OS_VFS_VERSION >= 5 , caller_context_t *ctx // IN: Caller's context , int flags // IN: flags #endif ) { VMBlockMountInfo *mip; Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockReaddir: entry\n"); mip = (VMBlockMountInfo *)vp->v_vfsp->vfs_data; return VOP_READDIR(mip->redirectVnode, uiop, cr, eofp #if OS_VFS_VERSION >= 5 , ctx, flags #endif ); } /* *---------------------------------------------------------------------------- * * VMBlockReadlink -- * * "Follows the symlink in the supplied vnode." (Solaris Internals, p537) * * Results: * Zero on success, error code on failure. * * Side effects: * Blocks if a block has been placed on this file. * *---------------------------------------------------------------------------- */ static int VMBlockReadlink(struct vnode *vp, // IN: Vnode for the symlink struct uio *uiop, // IN: IO request structure struct cred *cr // IN: Credentials of caller #if OS_VFS_VERSION >= 5 , caller_context_t *ctx // IN: Caller's context #endif ) { VMBlockMountInfo *mip; VMBlockVnodeInfo *vip; int ret; Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockReadlink: entry\n"); mip = VPTOMIP(vp); vip = VPTOVIP(vp); if (vip->nameLen + 1 >= uiop->uio_resid) { Warning("VMBlockReadlink: name is too long for provided buffer\n"); return ENAMETOOLONG; } BlockWaitOnFile(vip->name, NULL); /* Copy path to user space. */ ASSERT(vip->name[vip->nameLen] == '\0'); ret = uiomove(vip->name, vip->nameLen + 1, UIO_READ, uiop); if (ret) { return ret; } return 0; } /* *---------------------------------------------------------------------------- * * VMBlockInactive -- * * Frees a vnode that is no longer referenced. * * "Free resources and releases the supplied vnode. The file system can * choose to destroy the vnode or put it onto an inactive list, which is * managed by the file system implementation." (Solaris Internals, p536) * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VMBlockInactive(struct vnode *vp, // IN: Vnode to operate on struct cred *cr // IN: Credentials of the caller #if OS_VFS_VERSION >= 5 , caller_context_t *ctx // IN: Caller's context #endif ) { Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockInactive: entry\n"); VMBlockVnodePut(vp); } const fs_operation_def_t vnodeOpsArr[] = { VMBLOCK_VOP(VOPNAME_OPEN, vop_open, VMBlockOpen), VMBLOCK_VOP(VOPNAME_CLOSE, vop_close, VMBlockClose), VMBLOCK_VOP(VOPNAME_IOCTL, vop_ioctl, VMBlockIoctl), VMBLOCK_VOP(VOPNAME_GETATTR, vop_getattr, VMBlockGetattr), VMBLOCK_VOP(VOPNAME_ACCESS, vop_access, VMBlockAccess), VMBLOCK_VOP(VOPNAME_LOOKUP, vop_lookup, VMBlockLookup), VMBLOCK_VOP(VOPNAME_READDIR, vop_readdir, VMBlockReaddir), VMBLOCK_VOP(VOPNAME_READLINK, vop_readlink, VMBlockReadlink), #if OS_VFS_VERSION <=3 VMBLOCK_VOP(VOPNAME_INACTIVE, vop_inactive, (fs_generic_func_p)VMBlockInactive), #else VMBLOCK_VOP(VOPNAME_INACTIVE, vop_inactive, VMBlockInactive), #endif { NULL } }; open-vm-tools-9.4.0-1280544/modules/solaris/vmblock/COPYING0000644765153500003110000004331212220061556021256 0ustar dtormts COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 1. Definitions. 1.1. "Contributor" means each individual or entity that creates or contributes to the creation of Modifications. 1.2. "Contributor Version" means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor. 1.3. "Covered Software" means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof. 1.4. "Executable" means the Covered Software in any form other than Source Code. 1.5. "Initial Developer" means the individual or entity that first makes Original Software available under this License. 1.6. "Larger Work" means a work which combines Covered Software or portions thereof with code not governed by the terms of this License. 1.7. "License" means this document. 1.8. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. 1.9. "Modifications" means the Source Code and Executable form of any of the following: A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications; B. Any new file that contains any part of the Original Software or previous Modifications; or C. Any new file that is contributed or otherwise made available under the terms of this License. 1.10. "Original Software" means the Source Code and Executable form of computer software code that is originally released under this License. 1.11. "Patent Claims" means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. 1.12. "Source Code" means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code. 1.13. "You" (or "Your") means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants. 2.1. The Initial Developer Grant. Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license: (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof). (c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License. (d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices. 2.2. Contributor Grant. Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes or otherwise makes the Modifications available to a third party. (d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Contributor. 3. Distribution Obligations. 3.1. Availability of Source Code. Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used for software exchange. 3.2. Modifications. The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License. 3.3. Required Notices. You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer. 3.4. Application of Additional Terms. You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients' rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. 3.5. Distribution of Executable Versions. You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipient's rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable form under a different license, You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. 3.6. Larger Works. You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software. 4. Versions of the License. 4.1. New Versions. Sun Microsystems, Inc. is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License. 4.2. Effect of New Versions. You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. Otherwise, You may also choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version of the License published by the license steward. 4.3. Modified Versions. When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License. 5. DISCLAIMER OF WARRANTY. COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. 6. TERMINATION. 6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. 6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as "Participant") alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant, the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement with Participant. 6.3. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination. 7. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. 8. U.S. GOVERNMENT END USERS. The Covered Software is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" (as that term is defined at 48 C.F.R. 252.227-7014(a)(1)) and "commercial computer software documentation" as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License. 9. MISCELLANEOUS. This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdiction's conflict-of-law provisions. Any litigation relating to this License shall be subject to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the losing party responsible for costs, including, without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use, distribute or otherwise make available any Covered Software. 10. RESPONSIBILITY FOR CLAIMS. As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. open-vm-tools-9.4.0-1280544/modules/solaris/vmblock/Makefile0000644765153500003110000000617212220061556021666 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 2009 VMware, Inc. All rights reserved. # # The contents of this file are subject to the terms of the Common # Development and Distribution License (the "License") version 1.0 # and no later version. You may not use this file except in # compliance with the License. # # You can obtain a copy of the License at # http://www.opensource.org/licenses/cddl1.php # # See the License for the specific language governing permissions # and limitations under the License. # ########################################################## ## ## General build locations and variables ## MODULE := vmblock CFLAGS := LDFLAGS := # Solaris version defines for in-code #ifdefs (default to Solaris 9) ifeq ($(shell echo "$(VM_UNAME)" | cut -c-4),5.11) CFLAGS += -DSOL11 else ifeq ($(shell echo "$(VM_UNAME)" | cut -c-4),5.10) CFLAGS += -DSOL10 else CFLAGS += -DSOL9 # we don't support Solaris 9 (we could but we use memcpy/memset # and we'd need stubs to get the module to load into the kernel). $(error "This makefile is only used for Solaris 10 and 11") endif endif CFLAGS += -ffreestanding CFLAGS += -nodefaultlibs CFLAGS += -O2 CFLAGS += -Wall -Werror CFLAGS += -I. ## ## Objects needed to build vmblock kernel module ## VMBLOCK_OBJS := block.o VMBLOCK_OBJS += module.o VMBLOCK_OBJS += stubs.o VMBLOCK_OBJS += vfsops.o VMBLOCK_OBJS += vnops.o VMBLOCK_32_OBJS := $(addprefix i386/, $(VMBLOCK_OBJS)) VMBLOCK_64_OBJS := $(addprefix amd64/, $(VMBLOCK_OBJS)) MODULE_32 := i386/$(MODULE) MODULE_64 := amd64/$(MODULE) ifdef OVT_SOURCE_DIR CFLAGS += -I$(OVT_SOURCE_DIR)/lib/include CFLAGS += -I$(OVT_SOURCE_DIR)/modules/shared/vmblock CFLAGS += -I$(OVT_SOURCE_DIR)/modules/solaris/vmblock VPATH := $(OVT_SOURCE_DIR)/modules/shared/vmblock endif CFLAGS_32 := $(CFLAGS) CFLAGS_32 += -m32 LDFLAGS_32 := $(LDFLAGS) CFLAGS_64 := $(CFLAGS) CFLAGS_64 += -m64 CFLAGS_64 += -mcmodel=kernel CFLAGS_64 += -mno-red-zone LDFLAGS_64 := $(LDFLAGS) ifdef HAVE_GNU_LD LDFLAGS_64 += -m elf_x86_64 else LDFLAGS_64 += -64 endif ## ## Building targets ## .PHONY: all prepare_dirs clean install all: prepare_dirs $(MODULE_32) $(MODULE_64) prepare_dirs: @echo "Creating build directories" mkdir -p i386 mkdir -p amd64 # Build just the module for 32 bits kernel $(MODULE_32): $(VMBLOCK_32_OBJS) @echo "Linking $(MODULE_32)" $(LD) $(LDFLAGS_32) -r -o $(MODULE_32) $(VMBLOCK_32_OBJS) $(VMBLOCK_32_OBJS): i386/%.o: %.c @echo "Compiling $( #include /* kmem_zalloc() */ #include /* error codes */ #include /* MS_OVERLAY */ #include /* makedevice macro */ #include /* cmpldev() */ #include /* secpolicy_fs_mount() */ #include "module.h" /* * Variables */ vfsops_t *vmblockVfsOps; static major_t vmblockMajor; static minor_t vmblockMinor; static kmutex_t vmblockMutex; /* * Prototypes */ int VMBlockVnodeGet(struct vnode **vpp, struct vnode *realVp, const char *name, size_t nameLen, struct vnode *dvp, struct vfs *vfsp, Bool isRoot); int VMBlockVnodePut(struct vnode *vp); static int VMBlockMount(struct vfs *vfsp, struct vnode *vnodep, struct mounta *mntp, struct cred *credp); static int VMBlockUnmount(struct vfs *vfsp, int mflag, struct cred *credp); static int VMBlockRoot(struct vfs *vfsp, struct vnode **vnodepp); static int VMBlockStatvfs(struct vfs *vfsp, struct statvfs64 *stats); /* *---------------------------------------------------------------------------- * * VMBlockVnodeGet -- * * Creates a vnode. * * Note that realVp is assumed to be held (see the comment in the function * for further explanation). * * Results: * Returns zero on success and a non-zero error code on failure. On * success, vpp is filled in with a new, held vnode. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VMBlockVnodeGet(struct vnode **vpp, // OUT: Filled with address of new vnode struct vnode *realVp, // IN: Real vnode (assumed held) const char *name, // IN: Relative name of the file size_t nameLen, // IN: Size of name struct vnode *dvp, // IN: Parent directory's vnode struct vfs *vfsp, // IN: Filesystem structure Bool isRoot) // IN: If is root directory of fs { VMBlockVnodeInfo *vip; struct vnode *vp; char *curr; int ret; Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockVnodeGet: entry\n"); ASSERT(vpp); ASSERT(realVp); ASSERT(vfsp); ASSERT(name); ASSERT(dvp || isRoot); vp = vn_alloc(KM_SLEEP); if (!vp) { return ENOMEM; } vip = kmem_zalloc(sizeof *vip, KM_SLEEP); vp->v_data = (void *)vip; /* * Store the path that this file redirects to. For the root vnode we just * store the provided path, but for all others we first copy in the parent * directory's path. */ curr = vip->name; if (!isRoot) { VMBlockVnodeInfo *dvip = VPTOVIP(dvp); if (dvip->nameLen + 1 + nameLen + 1 >= sizeof vip->name) { ret = ENAMETOOLONG; goto error; } memcpy(vip->name, dvip->name, dvip->nameLen); vip->name[dvip->nameLen] = '/'; curr = vip->name + dvip->nameLen + 1; } if (nameLen + 1 > (sizeof vip->name - (curr - vip->name))) { ret = ENAMETOOLONG; goto error; } memcpy(curr, name, nameLen); curr[nameLen] = '\0'; vip->nameLen = nameLen + (curr - vip->name); /* * We require the caller to have held realVp so we don't need VN_HOLD() it * here here even though we VN_RELE() this vnode in VMBlockVnodePut(). * Despite seeming awkward, this is more natural since the function that our * caller obtained realVp from provided a held vnode. */ vip->realVnode = realVp; /* * Now we'll initialize the vnode. We need to set the file type, vnode * operations, flags, filesystem pointer, reference count, and device. */ /* The root directory is our only directory; the rest are symlinks. */ vp->v_type = isRoot ? VDIR : VLNK; vn_setops(vp, vmblockVnodeOps); vp->v_flag = VNOMAP | VNOMOUNT | VNOSWAP | isRoot ? VROOT : 0; vp->v_vfsp = vfsp; vp->v_rdev = NODEV; /* Fill in the provided address with the new vnode. */ *vpp = vp; return 0; error: kmem_free(vip, sizeof *vip); vn_free(vp); return ret; } /* *---------------------------------------------------------------------------- * * VMBlockVnodePut -- * * Frees state associated with provided vnode. * * Results: * Zero on success, non-zero error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VMBlockVnodePut(struct vnode *vp) { VMBlockVnodeInfo *vip; struct vnode *realVnode; Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockVnodePut: entry (%p)\n", vp); mutex_enter(&vp->v_lock); if (vp->v_count > 1) { vp->v_count--; mutex_exit(&vp->v_lock); return 0; } mutex_exit(&vp->v_lock); vip = (VMBlockVnodeInfo *)vp->v_data; realVnode = vip->realVnode; kmem_free(vip, sizeof *vip); vn_free(vp); /* * VMBlockVnodeGet() doesn't VN_HOLD() the real vnode, but all callers of it * will have the vnode held, so we need to VN_RELE() here. */ VN_RELE(realVnode); return 0; } /* *---------------------------------------------------------------------------- * * VMBlockInit -- * * This is the file system initialization routine. It creates an array of * fs_operation_def_t for all the vfs operations, then calls vfs_makefsops() * and vfs_setfsops() to assign them to the file system properly. * * Results: * Returns zero on success and a non-zero error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VMBlockInit(int fstype, // IN: file system type char *name) // IN: Name of the file system { int ret; static const fs_operation_def_t vfsOpsArr[] = { VMBLOCK_VOP(VFSNAME_MOUNT, vfs_mount, VMBlockMount), VMBLOCK_VOP(VFSNAME_UNMOUNT, vfs_unmount, VMBlockUnmount), VMBLOCK_VOP(VFSNAME_ROOT, vfs_root, VMBlockRoot), VMBLOCK_VOP(VFSNAME_STATVFS, vfs_statvfs, VMBlockStatvfs), { NULL } }; if (!name) { Warning("VMBlockInit: received NULL input from kernel.\n"); return EINVAL; } Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockInit: fstype=%d, name=\"%s\"\n", fstype, name); /* * Set our file system type and the vfs operations in the kernel's VFS * switch table. */ vmblockType = fstype; ret = vfs_setfsops(vmblockType, vfsOpsArr, &vmblockVfsOps); if (ret) { Warning("VMBlockInit: could not set vfs operations.\n"); return ret; } ret = vn_make_ops(name, vnodeOpsArr, &vmblockVnodeOps); if (ret) { Warning("VMBlockInit: could not create vnode operations.\n"); /* * It's important not to call vfs_freevfsops() here; that's only for * freeing ops created with vfs_makefsops(). */ vfs_freevfsops_by_type(vmblockType); return ret; } /* * We need to find a unique device number for this instance of the module; * it will be used at each mount to secure a unique device number and file * system identifier. If one cannot be located, we'll just use zero like * other Solaris file systems. */ if ((vmblockMajor = getudev()) == (major_t)-1) { Warning("VMBlockInit: could not obtain unique device.\n"); vmblockMajor = 0; } vmblockMinor = 0; mutex_init(&vmblockMutex, NULL, MUTEX_DEFAULT, NULL); return 0; } /* * VFS Entry Points */ /* *---------------------------------------------------------------------------- * * VMBlockMount -- * * This function is invoked when mount(2) is called on our file system. * The file system is mounted on the supplied vnode. * * Results: * Returns zero on success and an appropriate error code on error. * * Side effects: * The file system is mounted on top of vnodep. * *---------------------------------------------------------------------------- */ static int VMBlockMount(struct vfs *vfsp, // IN: file system to mount struct vnode *vnodep, // IN: Vnode that we are mounting on struct mounta *mntp, // IN: Arguments to mount(2) from user struct cred *credp) // IN: Credentials of caller { VMBlockMountInfo *mip; int ret; Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockMount: entry\n"); /* * These next few checks are done by all other Solaris file systems, so * let's follow their lead. */ ret = secpolicy_fs_mount(credp, vnodep, vfsp); if (ret) { Warning("VMBlockMount: mounting security check failed.\n"); return ret; } if (vnodep->v_type != VDIR) { Warning("VMBlockMount: not mounting on a directory.\n"); return ENOTDIR; } mutex_enter(&vnodep->v_lock); if ((mntp->flags & MS_OVERLAY) == 0 && (vnodep->v_count != 1 || (vnodep->v_flag & VROOT))) { mutex_exit(&vnodep->v_lock); Warning("VMBlockMount: cannot allow unrequested overlay mount.\n"); return EBUSY; } mutex_exit(&vnodep->v_lock); /* * The directory we are redirecting to is specified as the special file * since we have no actual device to mount on. We store that path in the * mount information structure (note that there's another allocation inside * pn_get() so we must pn_free() that path at unmount time). KM_SLEEP * guarantees our memory allocation will succeed (pn_get() uses this flag * too). */ mip = kmem_zalloc(sizeof *mip, KM_SLEEP); ret = pn_get(mntp->spec, (mntp->flags & MS_SYSSPACE) ? UIO_SYSSPACE : UIO_USERSPACE, &mip->redirectPath); if (ret) { Warning("VMBlockMount: could not obtain redirecting directory.\n"); kmem_free(mip, sizeof *mip); return ret; } /* Do a lookup on the specified path. */ ret = lookupname(mntp->spec, (mntp->flags & MS_SYSSPACE) ? UIO_SYSSPACE : UIO_USERSPACE, FOLLOW, NULLVPP, &mip->redirectVnode); if (ret) { Warning("VMBlockMount: could not obtain redirecting directory.\n"); goto error_lookup; } if (mip->redirectVnode->v_type != VDIR) { Warning("VMBlockMount: not redirecting to a directory.\n"); ret = ENOTDIR; goto error; } /* * Initialize our vfs structure. */ vfsp->vfs_vnodecovered = vnodep; vfsp->vfs_flag &= ~VFS_UNMOUNTED; vfsp->vfs_flag |= VMBLOCK_VFS_FLAGS; vfsp->vfs_bsize = PAGESIZE; vfsp->vfs_fstype = vmblockType; vfsp->vfs_bcount = 0; /* If we had mount options, we'd call vfs_setmntopt with vfsp->vfs_mntopts */ /* Locate a unique device minor number for this mount. */ mutex_enter(&vmblockMutex); do { vfsp->vfs_dev = makedevice(vmblockMajor, vmblockMinor); vmblockMinor = (vmblockMinor + 1) & L_MAXMIN32; } while (vfs_devismounted(vfsp->vfs_dev)); mutex_exit(&vmblockMutex); vfs_make_fsid(&vfsp->vfs_fsid, vfsp->vfs_dev, vmblockType); vfsp->vfs_data = (caddr_t)mip; /* * Now create the root vnode of the file system. */ ret = VMBlockVnodeGet(&mip->root, mip->redirectVnode, mip->redirectPath.pn_path, mip->redirectPath.pn_pathlen, NULL, vfsp, TRUE); if (ret) { Warning("VMBlockMount: couldn't create root vnode.\n"); ret = EFAULT; goto error; } VN_HOLD(vfsp->vfs_vnodecovered); return 0; error: /* lookupname() provides a held vnode. */ VN_RELE(mip->redirectVnode); error_lookup: pn_free(&mip->redirectPath); kmem_free(mip, sizeof *mip); return ret; } /* *---------------------------------------------------------------------------- * * VMBlockUnmount -- * * This function is invoked when umount(2) is called on our file system. * * Results: * Returns zero on success and an error code on error. * * Side effects: * The root vnode will be freed. * *---------------------------------------------------------------------------- */ static int VMBlockUnmount(struct vfs *vfsp, // IN: This file system int flag, // IN: Unmount flags struct cred *credp) // IN: Credentials of caller { VMBlockMountInfo *mip; int ret; Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockUnmount: entry\n"); ret = secpolicy_fs_unmount(credp, vfsp); if (ret) { return ret; } mip = (VMBlockMountInfo *)vfsp->vfs_data; mutex_enter(&mip->root->v_lock); if (mip->root->v_count > 1) { mutex_exit(&mip->root->v_lock); return EBUSY; } mutex_exit(&mip->root->v_lock); VN_RELE(vfsp->vfs_vnodecovered); /* * We don't need to VN_RELE() mip->redirectVnode since it's the realVnode * for mip->root. That means when we VN_RELE() mip->root and * VMBlockInactive() is called, VMBlockVnodePut() will VN_RELE() * mip->redirectVnode for us. It's like magic, but better. */ VN_RELE(mip->root); pn_free(&mip->redirectPath); kmem_free(mip, sizeof *mip); vfsp->vfs_flag |= VFS_UNMOUNTED; return 0; } /* *---------------------------------------------------------------------------- * * VMBlockRoot -- * * This supplies the root vnode for the file system. * * Results: * Returns zero on success and an error code on error. On success vnodepp * is set to the pointer of the root vnode. * * Side effects: * The root vnode's reference count is incremented by one. * *---------------------------------------------------------------------------- */ static int VMBlockRoot(struct vfs *vfsp, // IN: file system to find root vnode of struct vnode **vnodepp) // OUT: Set to pointer to root vnode of this fs { VMBlockMountInfo *mip; Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockRoot: entry\n"); mip = (VMBlockMountInfo *)vfsp->vfs_data; VN_HOLD(mip->root); *vnodepp = mip->root; return 0; } /* *---------------------------------------------------------------------------- * * VMBlockStatvfs -- * * Provides statistics for the provided file system. The values provided * by this function are fake. * * Results: * Returns zero on success and a non-zero error code on exit. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VMBlockStatvfs(struct vfs *vfsp, // IN: file system to get statistics for struct statvfs64 *stats) // OUT: Statistics are placed into this struct { dev32_t dev32; Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockStatvfs: entry\n"); /* Clear stats struct, then fill it in with our values. */ memset(stats, 0, sizeof *stats); /* * Macros in case we need these elsewhere later. * * Since vmblock does not provide any actual storage, we use zero so that * the output of df(1) is pleasant for users. */ #define VMBLOCK_BLOCKSIZE PAGESIZE #define VMBLOCK_BLOCKS_TOTAL 0 #define VMBLOCK_BLOCKS_FREE 0 #define VMBLOCK_BLOCKS_AVAIL 0 #define VMBLOCK_FILES_TOTAL 0 #define VMBLOCK_FILES_FREE 0 #define VMBLOCK_FILES_AVAIL 0 /* Compress the device number to 32-bits for consistency on 64-bit systems. */ cmpldev(&dev32, vfsp->vfs_dev); stats->f_bsize = VMBLOCK_BLOCKSIZE; /* Preferred fs block size */ stats->f_frsize = VMBLOCK_BLOCKSIZE; /* Fundamental fs block size */ /* Next six are u_longlong_t */ stats->f_blocks = VMBLOCK_BLOCKS_TOTAL; /* Total blocks on fs */ stats->f_bfree = VMBLOCK_BLOCKS_FREE; /* Total free blocks */ stats->f_bavail = VMBLOCK_BLOCKS_AVAIL; /* Total blocks avail to non-root */ stats->f_files = VMBLOCK_FILES_TOTAL; /* Total files (inodes) */ stats->f_ffree = VMBLOCK_FILES_FREE; /* Total files free */ stats->f_favail = VMBLOCK_FILES_AVAIL; /* Total files avail to non-root */ stats->f_fsid = dev32; /* file system id */ stats->f_flag &= ST_NOSUID; /* Flags: we don't support setuid. */ stats->f_namemax = MAXNAMELEN; /* Max filename; use Solaris default. */ /* Memset above and -1 of array size as n below ensure NUL termination. */ strncpy(stats->f_basetype, VMBLOCK_FS_NAME, sizeof stats->f_basetype - 1); strncpy(stats->f_fstr, VMBLOCK_FS_NAME, sizeof stats->f_fstr - 1); return 0; } open-vm-tools-9.4.0-1280544/modules/solaris/vmblock/os.h0000644765153500003110000001163512220061556021020 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * os.h -- * * OS-specific definitions. */ #ifndef __OS_H__ #define __OS_H__ #include #include #include #include #include #include #include #include #include #include "vm_basic_types.h" typedef krwlock_t os_rwlock_t; typedef kmem_cache_t os_kmem_cache_t; typedef struct os_completion_t { Bool completed; kmutex_t mutex; kcondvar_t cv; } os_completion_t; /* * Changing the os_atomic_t type requires that the os_atomic_* macros below be * changed as well. */ typedef uint_t os_atomic_t; typedef kthread_t * os_blocker_id_t; #define OS_UNKNOWN_BLOCKER NULL #define OS_ENOMEM ENOMEM #define OS_ENOENT ENOENT #define OS_EEXIST EEXIST #define OS_PATH_MAX MAXPATHLEN #define OS_KMEM_CACHE_FLAG_HWALIGN 0 #define OS_FMTTID "lu" #define os_threadid (uintptr_t)curthread #define os_panic(fmt, args) vcmn_err(CE_PANIC, fmt, args) #define os_rwlock_init(lock) rw_init(lock, NULL, RW_DRIVER, NULL) #define os_rwlock_destroy(lock) rw_destroy(lock) /* * rw_lock_held() returns 1 if the lock is read locked, and rw_owner() returns * the current lock owner if it's write locked. In the read locked case, we * just have to assume we're one of the readers. */ #define os_rwlock_held(lock) (rw_lock_held(lock) || \ rw_owner(lock) == curthread) #define os_read_lock(lock) rw_enter(lock, RW_READER) #define os_write_lock(lock) rw_enter(lock, RW_WRITER) #define os_read_unlock(lock) rw_exit(lock) #define os_write_unlock(lock) rw_exit(lock) #define os_kmem_cache_create(name, size, align, ctor) \ kmem_cache_create(name, size, align, ctor, NULL, NULL, NULL, NULL, 0) #define os_kmem_cache_destroy(cache) kmem_cache_destroy(cache) #define os_kmem_cache_alloc(cache) kmem_cache_alloc(cache, KM_SLEEP) #define os_kmem_cache_free(cache, elem) kmem_cache_free(cache, elem) #define os_completion_init(comp) \ do { \ (comp)->completed = FALSE; \ mutex_init(&(comp)->mutex, NULL, MUTEX_DRIVER, NULL); \ cv_init(&(comp)->cv, NULL, CV_DRIVER, NULL); \ } while (0) #define os_completion_destroy(comp) \ do { \ mutex_destroy(&(comp)->mutex); \ cv_destroy(&(comp)->cv); \ } while (0) /* * XXX The following should be made interruptible such as via * cv_wait_sig, and returning that function's return value. In * the meantime, fake "success" by evaluating to 0. */ #define os_wait_for_completion(comp) \ ({ \ mutex_enter(&(comp)->mutex); \ while (!(comp)->completed) { \ cv_wait(&(comp)->cv, &(comp)->mutex); \ } \ mutex_exit(&(comp)->mutex); \ 0; \ }) #define os_complete_all(comp) \ do { \ mutex_enter(&(comp)->mutex); \ (comp)->completed = TRUE; \ mutex_exit(&(comp)->mutex); \ cv_broadcast(&(comp)->cv); \ } while (0) /* These will need to change if os_atomic_t is changed from uint_t. */ #define os_atomic_dec_and_test(atomic) (atomic_dec_uint_nv(atomic) == 0) #define os_atomic_dec(atomic) atomic_dec_uint(atomic) #define os_atomic_set(atomic, val) atomic_swap_uint(atomic, val) #define os_atomic_inc(atomic) atomic_inc_uint(atomic) #define os_atomic_read(atomic) atomic_add_int_nv(atomic, 0) #endif /* __OS_H__ */ open-vm-tools-9.4.0-1280544/modules/solaris/vmmemctl/0000755765153500003110000000000012220061556020407 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/solaris/vmmemctl/vmballoon_kstats.c0000644765153500003110000001347712220061556024151 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * vmballoon_kstats.c -- * * Functions reporting status for vmballoon driver in the form of * kstats. */ /* * Compile-Time Options */ #include #include #include #include "os.h" #include "vmballoon.h" #include "vmballoon_kstats.h" /* * Information to be reported to user level through kstats. This * table should be kept in sync with the corresponding info reported * through procfs by the linux driver. To display this information * on a Solaris system with the driver loaded, run "kstat -m vmmemctl". */ typedef struct { kstat_named_t nPagesTarget; kstat_named_t nPages; kstat_named_t rateAlloc; kstat_named_t rateFree; kstat_named_t timer; kstat_named_t start; kstat_named_t startFail; kstat_named_t guestType; kstat_named_t guestTypeFail; kstat_named_t lock; kstat_named_t lockFail; kstat_named_t unlock; kstat_named_t unlockFail; kstat_named_t target; kstat_named_t targetFail; kstat_named_t primAlloc[BALLOON_PAGE_ALLOC_TYPES_NR]; kstat_named_t primAllocFail[BALLOON_PAGE_ALLOC_TYPES_NR]; kstat_named_t primFree; kstat_named_t primErrorPageAlloc; kstat_named_t primErrorPageFree; } BalloonKstats; /* *---------------------------------------------------------------------- * * BalloonKstatUpdate -- * * Ballon driver status reporting routine. * * Results: * Copies current driver status and statistics into kstat structure * for reporting to user level. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int BalloonKstatUpdate(kstat_t *ksp, int rw) { int i; const BalloonStats *stats; BalloonKstats *bkp = ksp->ks_data; if (rw == KSTAT_WRITE) return (EACCES); stats = Balloon_GetStats(); /* size info */ bkp->nPagesTarget.value.ui32 = stats->nPagesTarget; bkp->nPages.value.ui32 = stats->nPages; /* rate info */ bkp->rateAlloc.value.ui32 = stats->rateAlloc; bkp->rateFree.value.ui32 = stats->rateFree; /* statistics */ bkp->timer.value.ui32 = stats->timer; bkp->start.value.ui32 = stats->start; bkp->startFail.value.ui32 = stats->startFail; bkp->guestType.value.ui32 = stats->guestType; bkp->guestTypeFail.value.ui32 = stats->guestTypeFail; bkp->lock.value.ui32 = stats->lock; bkp->lockFail.value.ui32 = stats->lockFail; bkp->unlock.value.ui32 = stats->unlock; bkp->unlockFail.value.ui32 = stats->unlockFail; bkp->target.value.ui32 = stats->target; bkp->targetFail.value.ui32 = stats->targetFail; for (i = 0; i < BALLOON_PAGE_ALLOC_TYPES_NR; i++) { bkp->primAlloc[i].value.ui32 = stats->primAlloc[i]; bkp->primAllocFail[i].value.ui32 = stats->primAllocFail[i]; } bkp->primFree.value.ui32 = stats->primFree; bkp->primErrorPageAlloc.value.ui32 = stats->primErrorPageAlloc; bkp->primErrorPageFree.value.ui32 = stats->primErrorPageFree; return 0; } /* * Set up statistics for the balloon driver. Creates and initializes * the kstats structure. */ kstat_t * BalloonKstatCreate(void) { kstat_t *ksp; BalloonKstats *bkp; ksp = kstat_create("vmmemctl", 0, "vmmemctl", "vm", KSTAT_TYPE_NAMED, sizeof (BalloonKstats) / sizeof (kstat_named_t), 0); if (ksp == NULL) return (NULL); /* can't allocate space, give up (no kstats) */ bkp = ksp->ks_data; kstat_named_init(&bkp->nPagesTarget, "targetPages", KSTAT_DATA_UINT32); kstat_named_init(&bkp->nPages, "currentPages", KSTAT_DATA_UINT32); kstat_named_init(&bkp->rateAlloc, "rateAlloc", KSTAT_DATA_UINT32); kstat_named_init(&bkp->rateFree, "rateFree", KSTAT_DATA_UINT32); kstat_named_init(&bkp->timer, "timer", KSTAT_DATA_UINT32); kstat_named_init(&bkp->start, "start", KSTAT_DATA_UINT32); kstat_named_init(&bkp->startFail, "startFail", KSTAT_DATA_UINT32); kstat_named_init(&bkp->guestType, "guestType", KSTAT_DATA_UINT32); kstat_named_init(&bkp->guestTypeFail, "guestTypeFail", KSTAT_DATA_UINT32); kstat_named_init(&bkp->lock, "lock", KSTAT_DATA_UINT32); kstat_named_init(&bkp->lockFail, "lockFail", KSTAT_DATA_UINT32); kstat_named_init(&bkp->unlock, "unlock", KSTAT_DATA_UINT32); kstat_named_init(&bkp->unlockFail, "unlockFail", KSTAT_DATA_UINT32); kstat_named_init(&bkp->target, "target", KSTAT_DATA_UINT32); kstat_named_init(&bkp->targetFail, "targetFail", KSTAT_DATA_UINT32); kstat_named_init(&bkp->primAlloc[BALLOON_PAGE_ALLOC_NOSLEEP], "primAllocNoSleep", KSTAT_DATA_UINT32); kstat_named_init(&bkp->primAlloc[BALLOON_PAGE_ALLOC_CANSLEEP], "primAllocCanSleep", KSTAT_DATA_UINT32); kstat_named_init(&bkp->primAllocFail[BALLOON_PAGE_ALLOC_NOSLEEP], "primAllocNoSleepFail", KSTAT_DATA_UINT32); kstat_named_init(&bkp->primAllocFail[BALLOON_PAGE_ALLOC_CANSLEEP], "primAllocCanSleepFail", KSTAT_DATA_UINT32); kstat_named_init(&bkp->primFree, "primFree", KSTAT_DATA_UINT32); kstat_named_init(&bkp->primErrorPageAlloc, "errAlloc", KSTAT_DATA_UINT32); kstat_named_init(&bkp->primErrorPageFree, "errFree", KSTAT_DATA_UINT32); /* set update function to be run when kstats are read */ ksp->ks_update = BalloonKstatUpdate; kstat_install(ksp); return ksp; } void BalloonKstatDelete(kstat_t *ksp) { if (ksp != NULL) kstat_delete(ksp); } open-vm-tools-9.4.0-1280544/modules/solaris/vmmemctl/kernelStubsSolaris.c0000644765153500003110000002071112220061556024412 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * kernelStubsSolaris.c * * This file contains implementations of common userspace functions in terms * that the Solaris kernel can understand. */ #include "kernelStubs.h" #include #include #include #ifdef SOL9 # define compat_va_start(arg, fmt) arg = ((char *)__builtin_next_arg(fmt)) # define compat_va_end(arg) # define compat_va_copy(arg1, arg2) va_copy(arg1, arg2) #else # define compat_va_start(arg, fmt) va_start(arg, fmt) # define compat_va_end(arg) va_end(arg) # define compat_va_copy(arg1, arg2) va_copy(arg1, arg2) #endif /* *----------------------------------------------------------------------------- * * Panic -- * * Prints the debug message and stops the system. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void Panic(const char *fmt, ...) // IN { va_list args; char *result; compat_va_start(args, fmt); result = Str_Vasprintf(NULL, fmt, args); compat_va_end(args); cmn_err(CE_PANIC, "%s", result ? result : "Unable to format PANIC message"); } /* *---------------------------------------------------------------------- * * Str_Strcpy -- * * Wrapper for strcpy that checks for buffer overruns. * * Results: * Same as strcpy. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * Str_Strcpy(char *buf, // OUT const char *src, // IN size_t maxSize) // IN { size_t len; len = strlen(src); if (len >= maxSize) { Panic("%s:%d Buffer too small %p\n", __FILE__, __LINE__, buf); } bcopy(src, buf, len + 1); return buf; } /* *---------------------------------------------------------------------- * * Str_Vsnprintf -- * * Compatability wrapper b/w different libc versions * * Results: * int - number of bytes written (not including NULL terminator), * -1 on overflow (insufficient space for NULL terminator * is considered overflow). * * NB: on overflow the buffer WILL be null terminated. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Str_Vsnprintf(char *str, // OUT size_t size, // IN const char *format, // IN va_list arguments) // IN { int retval = vsnprintf(str, size, format, arguments); /* * Linux glibc 2.0.x returns -1 and null terminates (which we shouldn't * be linking against), but glibc 2.1.x follows c99 and returns * characters that would have been written. */ if (retval >= size) { return -1; } return retval; } /* *----------------------------------------------------------------------------- * * Str_Vasprintf -- * * Allocate and format a string, using the GNU libc way to specify the * format (i.e. optionally allow the use of positional parameters). * * Results: * The allocated string on success (if 'length' is not NULL, *length * is set to the length of the allocated string), NULL on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ char * Str_Vasprintf(size_t *length, // OUT const char *format, // IN va_list arguments) // IN { /* * Simple implementation of Str_Vasprintf when userlevel libraries are not * available (e.g. for use in drivers). We just fallback to vsnprintf, * doubling if we didn't have enough space. */ unsigned int bufSize; char *buf; int retval; bufSize = strlen(format); buf = NULL; do { /* * Initial allocation of strlen(format) * 2. Should this be tunable? * XXX Yes, this could overflow and spin forever when you get near 2GB * allocations. I don't care. --rrdharan */ va_list args2; bufSize *= 2; buf = realloc(buf, bufSize); if (!buf) { return NULL; } compat_va_copy(args2, arguments); retval = Str_Vsnprintf(buf, bufSize, format, args2); compat_va_end(args2); } while (retval == -1); if (length) { *length = retval; } /* * Try to trim the buffer here to save memory? */ return buf; } /* *----------------------------------------------------------------------------- * * Str_Asprintf -- * * Same as Str_Vasprintf(), but parameters are passed inline --hpreg * * Results: * Same as Str_Vasprintf() * * Side effects: * Same as Str_Vasprintf() * *----------------------------------------------------------------------------- */ char * Str_Asprintf(size_t *length, // OUT const char *format, // IN ...) // IN { va_list arguments; char *result; compat_va_start(arguments, format); result = Str_Vasprintf(length, format, arguments); compat_va_end(arguments); return result; } /* *---------------------------------------------------------------------------- * * malloc -- * * Allocate memory using kmalloc. There is no realloc * equivalent, so we roll our own by padding each allocation with * 4 (or 8 for 64 bit guests) extra bytes to store the block length. * * Results: * Pointer to driver heap memory, offset by 4 (or 8) * bytes from the real block pointer. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void * malloc(size_t size) // IN { size_t *ptr = kmem_alloc(size + sizeof(size), KM_SLEEP); if (ptr) { *ptr++ = size; } return ptr; } /* *--------------------------------------------------------------------------- * * free -- * * Free memory allocated by a previous call to malloc, calloc or realloc. * * Results: * None. * * Side effects: * Calls kmem_free to free the real (base) pointer. * *--------------------------------------------------------------------------- */ void free(void *mem) // IN { size_t *dataPtr = mem; if (mem) { --dataPtr; kmem_free(dataPtr, *dataPtr + sizeof(*dataPtr)); } } /* *---------------------------------------------------------------------------- * * calloc -- * * Malloc and zero. * * Results: * Pointer to driver heap memory (see malloc, above). * * Side effects: * None. * *---------------------------------------------------------------------------- */ void * calloc(size_t num, // IN size_t len) // IN { size_t size; void *ptr; size = num * len; ptr = malloc(size); if (ptr) { memset(ptr, 0, size); } return ptr; } /* *---------------------------------------------------------------------------- * * realloc -- * * Since the driver heap has no realloc equivalent, we have to roll our * own. Fortunately, we can retrieve the block size of every block we * hand out since we stashed it at allocation time (see malloc above). * * Results: * Pointer to memory block valid for 'newSize' bytes, or NULL if * allocation failed. * * Side effects: * Could copy memory around. * *---------------------------------------------------------------------------- */ void * realloc(void *ptr, // IN size_t newSize) // IN { void *newPtr; size_t *dataPtr; size_t length, lenUsed; dataPtr = (size_t *)ptr; length = ptr ? dataPtr[-1] : 0; if (newSize == 0) { if (ptr) { free(ptr); newPtr = NULL; } else { newPtr = malloc(newSize); } } else if (newSize == length) { newPtr = ptr; } else if ((newPtr = malloc(newSize))) { if (length < newSize) { lenUsed = length; } else { lenUsed = newSize; } memcpy(newPtr, ptr, lenUsed); free(ptr); } return newPtr; } open-vm-tools-9.4.0-1280544/modules/solaris/vmmemctl/os.c0000644765153500003110000003524712220061556021207 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * os.c -- * * Wrappers for Solaris system functions required by "vmmemctl". */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "os.h" #include "vmballoon.h" #include "balloon_def.h" #include "vm_assert.h" #include "vmballoon_kstats.h" #include "buildNumber.h" extern void memscrub_disable(void); /* * Constants */ #define ONE_SECOND_IN_MICROSECONDS 1000000 /* * Types */ typedef struct { timeout_id_t id; /* Worker thread ID */ kt_did_t thread_id; /* termination flag */ volatile int stop; /* synchronization with worker thread */ kmutex_t lock; kcondvar_t cv; /* registered state */ void *data; int period; } os_timer; /* * Keep track of offset here rather than peeking inside the page_t to * avoid dependencies on the page structure layout (which changes from * release to release). */ typedef struct { page_t *pp; u_offset_t offset; } os_page; typedef struct { os_timer timer; kstat_t *kstats; id_space_t *id_space; vnode_t vnode; } os_state; /* * Globals */ static os_state global_state; /* *----------------------------------------------------------------------------- * * OS_Malloc -- * * Allocates kernel memory. * * Results: * On success: Pointer to allocated memory * On failure: NULL * * Side effects: * None * *----------------------------------------------------------------------------- */ void * OS_Malloc(size_t size) // IN { return (kmem_alloc(size, KM_NOSLEEP)); } /* *----------------------------------------------------------------------------- * * OS_Free -- * * Free allocated kernel memory. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void OS_Free(void *ptr, // IN size_t size) // IN { kmem_free(ptr, size); } /* *----------------------------------------------------------------------------- * * OS_MemZero -- * * Fill a memory location with 0s. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void OS_MemZero(void *ptr, // OUT size_t size) // IN { bzero(ptr, size); } /* *----------------------------------------------------------------------------- * * OS_MemCopy -- * * Copy a memory portion into another location. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void OS_MemCopy(void *dest, // OUT const void *src, // IN size_t size) // IN { bcopy(src, dest, size); } /* *----------------------------------------------------------------------------- * * OS_ReservedPageGetLimit -- * * Predict the maximum achievable balloon size. * * Results: * Currently we just return the total memory pages. * * Side effects: * None * *----------------------------------------------------------------------------- */ unsigned long OS_ReservedPageGetLimit(void) { return maxmem; } /* *----------------------------------------------------------------------------- * * OS_ReservedPageGetPA -- * * Convert a page handle (of a physical page previously reserved with * OS_ReservedPageAlloc()) to a pa. * * Results: * The pa. * * Side effects: * None. * *----------------------------------------------------------------------------- */ PA64 OS_ReservedPageGetPA(PageHandle handle) // IN: A valid page handle { return ptob(page_pptonum(((os_page *)handle)->pp)); } /* *----------------------------------------------------------------------------- * * OS_ReservedPageGetHandle -- * * Convert a pa (of a physical page previously reserved with * OS_ReservedPageAlloc()) to a page handle. * * Results: * The page handle. * * Side effects: * None. * * Note: * Currently not implemented on Solaris. * *----------------------------------------------------------------------------- */ PageHandle OS_ReservedPageGetHandle(PA64 pa) // IN { // Solaris does not use batched commands. NOT_IMPLEMENTED(); } /* *----------------------------------------------------------------------------- * * OS_MapPageHandle -- * * Map a page handle into kernel address space, and return the * mapping to that page handle. * * Results: * The mapping. * * Side effects: * None. * * Note: * Currently not implemented on Solaris. * *----------------------------------------------------------------------------- */ Mapping OS_MapPageHandle(PageHandle handle) // IN { // Solaris does not use batched commands. NOT_IMPLEMENTED(); } /* *----------------------------------------------------------------------------- * * OS_Mapping2Addr -- * * Return the address of a previously mapped page handle (with * OS_MapPageHandle). * * Results: * The mapping address. * * Side effects: * None. * * Note: * Currently not implemented on Solaris. * *----------------------------------------------------------------------------- */ void * OS_Mapping2Addr(Mapping mapping) // IN { // Solaris does not use batched commands. NOT_IMPLEMENTED(); } /* *----------------------------------------------------------------------------- * * OS_UnmapPage -- * * Unmap a previously mapped page handle. * * Results: * None. * * Side effects: * None. * * Note: * Currently not implemented on Solaris. * *----------------------------------------------------------------------------- */ void OS_UnmapPage(Mapping mapping) // IN { // Solaris does not use protocol v3. NOT_IMPLEMENTED(); } /* * NOTE: cast id before shifting to avoid overflow (id_t is 32 bits, * u_offset_t is 64 bits). Also, can't use ptob because it will * overflow in a 32-bit kernel (since ptob returns a ulong_t, and the * physical address may be larger than 2^32). */ #define idtooff(id) ((u_offset_t)(id) << PAGESHIFT) #define offtoid(off) ((id_t)((off) >> PAGESHIFT)) /* *----------------------------------------------------------------------------- * * OS_ReservedPageAlloc -- * * Reserve a physical page for the exclusive use of this driver. * * This is a bit ugly. In order to allocate a page, we need a vnode to * hang it from and a unique offset within that vnode. We do this by * using our own vnode (used only to hang pages from) and allocating * offsets by use of the id space allocator. The id allocator hands * us back unique integers between 0 and INT_MAX; we can then use those * as page indices into our fake vnode space. * * Future versions of Solaris will have a devmap_pmem_alloc/free * interface for allocating physical pages that may allow us to * eliminate some of this. * * Results: * On success: A valid page handle that can be passed to OS_ReservedPageGetPA() * or OS_ReservedPageFree(). * On failure: PAGE_HANDLE_INVALID * * Side effects: * None. * *----------------------------------------------------------------------------- */ PageHandle OS_ReservedPageAlloc(int canSleep) // IN { os_state *state = &global_state; page_t *pp; u_offset_t off; struct seg kseg; os_page *page; id_space_t *idp = state->id_space; vnode_t *vp = &state->vnode; uint_t flags; /* * Reserve space for the page. */ flags = canSleep ? KM_SLEEP : KM_NOSLEEP; if (!page_resv(1, flags)) return PAGE_HANDLE_INVALID; /* no space! */ /* * Allocating space for os_page early simplifies error handling. */ if ((page = kmem_alloc(sizeof (os_page), flags)) == NULL) { page_unresv(1); return PAGE_HANDLE_INVALID; } /* * Construct an offset for page_create. */ off = idtooff(id_alloc(idp)); /* * Allocate the page itself. Note that this can fail. */ kseg.s_as = &kas; flags = canSleep ? PG_EXCL | PG_WAIT : PG_EXCL; pp = page_create_va(vp, off, PAGESIZE, flags, &kseg, (caddr_t)(ulong_t)off); if (pp != NULL) { /* * We got a page. We keep the PG_EXCL lock to prohibit * anyone (swrand, memscrubber) touching the page. Return the * pointer to structure describing page. */ page_io_unlock(pp); page_hashout(pp, NULL); page->pp = pp; page->offset = off; } else { /* * Oops, didn't get a page. Undo everything and return. */ id_free(idp, offtoid(off)); kmem_free(page, sizeof (os_page)); page_unresv(1); page = NULL; } return (PageHandle)page; } /* *----------------------------------------------------------------------------- * * OS_ReservedPageFree -- * * Unreserve a physical page previously reserved with OS_ReservedPageAlloc(). * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void OS_ReservedPageFree(PageHandle handle) // IN: A valid page handle { os_state *state = &global_state; os_page *page = (os_page *)handle; page_t *pp = page->pp; u_offset_t off = page->offset; id_space_t *idp = state->id_space; page_free(pp, 1); page_unresv(1); id_free(idp, offtoid(off)); kmem_free(page, sizeof (os_page)); } /* *----------------------------------------------------------------------------- * * vmememctl_poll_worker -- * * Worker thread that periodically calls the timer handler. This is * executed by a user context thread so that it can block waiting for * memory without fear of deadlock. * * Results: * On success: 0 * On failure: error code * * Side effects: * None * *----------------------------------------------------------------------------- */ static void vmmemctl_poll_worker(os_timer *t) // IN { clock_t timeout; mutex_enter(&t->lock); while (!t->stop) { mutex_exit(&t->lock); Balloon_QueryAndExecute(); mutex_enter(&t->lock); /* check again whether we should stop */ if (t->stop) break; /* wait for timeout */ (void) drv_getparm(LBOLT, &timeout); timeout += t->period; cv_timedwait_sig(&t->cv, &t->lock, timeout); } mutex_exit(&t->lock); thread_exit(); } /* *----------------------------------------------------------------------------- * * OS_TimerStart -- * * Setup the timer callback function, then start it. * * Results: * Always TRUE, cannot fail. * * Side effects: * None * *----------------------------------------------------------------------------- */ static int vmmemctl_poll_start(void) { os_timer *t = &global_state.timer; kthread_t *tp; /* setup the timer structure */ t->id = 0; t->stop = 0; t->period = drv_usectohz(BALLOON_POLL_PERIOD * ONE_SECOND_IN_MICROSECONDS); mutex_init(&t->lock, NULL, MUTEX_DRIVER, NULL); cv_init(&t->cv, NULL, CV_DRIVER, NULL); /* * All Solaris drivers that I checked assume that thread_create() will * succeed, let's follow the suit. */ tp = thread_create(NULL, 0, vmmemctl_poll_worker, (void *)t, 0, &p0, TS_RUN, minclsyspri); t->thread_id = tp->t_did; return 0; } /* *----------------------------------------------------------------------------- * * vmmemctl_poll_stop -- * * Signal polling thread to stop and wait till it exists. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static void vmmemctl_poll_stop(void) { os_timer *t = &global_state.timer; mutex_enter(&t->lock); /* Set termination flag. */ t->stop = 1; /* Wake up worker thread so it can exit. */ cv_signal(&t->cv); mutex_exit(&t->lock); /* Wait for the worker thread to complete. */ if (t->thread_id != 0) { thread_join(t->thread_id); t->thread_id = 0; } mutex_destroy(&t->lock); cv_destroy(&t->cv); } /* *----------------------------------------------------------------------------- * * OS_Yield -- * * Yield the CPU, if needed. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void OS_Yield(void) { /* Do nothing. */ } /* * Module linkage */ static struct modldrv vmmodldrv = { &mod_miscops, "VMware Memory Control b" BUILD_NUMBER_NUMERIC_STRING, }; static struct modlinkage vmmodlinkage = { MODREV_1, { &vmmodldrv, NULL } }; int _init(void) { os_state *state = &global_state; int error; if (!Balloon_Init(BALLOON_GUEST_SOLARIS)) { return EIO; } state->kstats = BalloonKstatCreate(); state->id_space = id_space_create(BALLOON_NAME, 0, INT_MAX); /* disable memscrubber */ memscrub_disable(); error = vmmemctl_poll_start(); if (error) { goto err_do_cleanup; } error = mod_install(&vmmodlinkage); if (error) { goto err_stop_poll; } cmn_err(CE_CONT, "!%s initialized\n", BALLOON_NAME_VERBOSE); return 0; err_stop_poll: vmmemctl_poll_stop(); err_do_cleanup: Balloon_Cleanup(); id_space_destroy(state->id_space); BalloonKstatDelete(state->kstats); return error; } int _info(struct modinfo *modinfop) // IN { return mod_info(&vmmodlinkage, modinfop); } int _fini(void) { os_state *state = &global_state; int error; /* * Check if the module is busy before cleaning up. */ error = mod_remove(&vmmodlinkage); if (error) { return error; } vmmemctl_poll_stop(); Balloon_Cleanup(); id_space_destroy(state->id_space); BalloonKstatDelete(state->kstats); cmn_err(CE_CONT, "!%s unloaded\n", BALLOON_NAME_VERBOSE); return 0; } open-vm-tools-9.4.0-1280544/modules/solaris/vmmemctl/vmballoon_kstats.h0000644765153500003110000000164212220061556024145 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * vmballoon_kstats.h -- * * External definitions associated with the functions providing * kstats for the vmmemctl driver. */ #ifndef VMBALLOON_KSTATS_H #define VMBALLOON_KSTATS_H extern kstat_t *BalloonKstatCreate(void); extern void BalloonKstatDelete(kstat_t *); #endif /* VMBALLOON_KSTATS_H */ open-vm-tools-9.4.0-1280544/modules/solaris/vmmemctl/README0000644765153500003110000000042612220061556021271 0ustar dtormtsThe files in this directory are components of the VMware Memory Control driver. This version of the driver will only work on an x86 system running Solaris 9 or later with a 32-bit kernel. This driver will be installed by the installer of the VMware Tools for Solaris package. open-vm-tools-9.4.0-1280544/modules/solaris/vmmemctl/COPYING0000644765153500003110000004331212220061556021445 0ustar dtormts COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 1. Definitions. 1.1. "Contributor" means each individual or entity that creates or contributes to the creation of Modifications. 1.2. "Contributor Version" means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor. 1.3. "Covered Software" means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof. 1.4. "Executable" means the Covered Software in any form other than Source Code. 1.5. "Initial Developer" means the individual or entity that first makes Original Software available under this License. 1.6. "Larger Work" means a work which combines Covered Software or portions thereof with code not governed by the terms of this License. 1.7. "License" means this document. 1.8. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. 1.9. "Modifications" means the Source Code and Executable form of any of the following: A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications; B. Any new file that contains any part of the Original Software or previous Modifications; or C. Any new file that is contributed or otherwise made available under the terms of this License. 1.10. "Original Software" means the Source Code and Executable form of computer software code that is originally released under this License. 1.11. "Patent Claims" means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. 1.12. "Source Code" means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code. 1.13. "You" (or "Your") means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants. 2.1. The Initial Developer Grant. Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license: (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof). (c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License. (d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices. 2.2. Contributor Grant. Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes or otherwise makes the Modifications available to a third party. (d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Contributor. 3. Distribution Obligations. 3.1. Availability of Source Code. Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used for software exchange. 3.2. Modifications. The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License. 3.3. Required Notices. You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer. 3.4. Application of Additional Terms. You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients' rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. 3.5. Distribution of Executable Versions. You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipient's rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable form under a different license, You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. 3.6. Larger Works. You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software. 4. Versions of the License. 4.1. New Versions. Sun Microsystems, Inc. is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License. 4.2. Effect of New Versions. You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. Otherwise, You may also choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version of the License published by the license steward. 4.3. Modified Versions. When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License. 5. DISCLAIMER OF WARRANTY. COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. 6. TERMINATION. 6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. 6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as "Participant") alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant, the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement with Participant. 6.3. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination. 7. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. 8. U.S. GOVERNMENT END USERS. The Covered Software is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" (as that term is defined at 48 C.F.R. 252.227-7014(a)(1)) and "commercial computer software documentation" as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License. 9. MISCELLANEOUS. This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdiction's conflict-of-law provisions. Any litigation relating to this License shall be subject to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the losing party responsible for costs, including, without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use, distribute or otherwise make available any Covered Software. 10. RESPONSIBILITY FOR CLAIMS. As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. open-vm-tools-9.4.0-1280544/modules/solaris/vmmemctl/Makefile0000644765153500003110000000641112220061556022051 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 2009 VMware, Inc. All rights reserved. # # The contents of this file are subject to the terms of the Common # Development and Distribution License (the "License") version 1.0 # and no later version. You may not use this file except in # compliance with the License. # # You can obtain a copy of the License at # http://www.opensource.org/licenses/cddl1.php # # See the License for the specific language governing permissions # and limitations under the License. # ########################################################## ## ## General build locations and variables ## MODULE := vmmemctl MODULE_32 := i386/$(MODULE) MODULE_64 := amd64/$(MODULE) CFLAGS := KFLAGS := LDFLAGS := CFLAGS += -O CFLAGS += -Wall -Wno-unknown-pragmas -Werror CFLAGS += -I../../../lib/include # for buildNumber.h KFLAGS += -D_KERNEL ## ## Objects needed to build the vmmemctl kernel module ## VMMCTL_OBJS := vmballoon.o VMMCTL_OBJS += vmballoon_kstats.o VMMCTL_OBJS += os.o VMMCTL_OBJS += backdoor_balloon.o VMMCTL_OBJS += kernelStubsSolaris.o VMMCTL_32_OBJS := $(addprefix i386/, $(VMMCTL_OBJS)) VMMCTL_32_OBJS += i386/backdoorGcc32.o VMMCTL_64_OBJS := $(addprefix amd64/, $(VMMCTL_OBJS)) VMMCTL_64_OBJS += amd64/backdoorGcc64.o ifeq ($(shell echo "$(VM_UNAME)" | cut -c-4),5.10) # Solaris 10 SUPPORTED := 1 MODULES := $(MODULE_32) $(MODULE_64) INSTALL := install32 install64 CFLAGS += -DSOL10 KFLAGS += -ffreestanding KFLAGS += -nodefaultlibs endif ifeq ($(shell echo "$(VM_UNAME)" | cut -c-4),5.11) # Solaris 11 SUPPORTED := 1 MODULES := $(MODULE_32) $(MODULE_64) INSTALL := install32 install64 CFLAGS += -DSOL11 KFLAGS += -ffreestanding KFLAGS += -nodefaultlibs endif $(if $(SUPPORTED),,$(error "Unsupported Solaris version: $(VM_UNAME)")) ifdef OVT_SOURCE_DIR CFLAGS += -I$(OVT_SOURCE_DIR)/lib/include CFLAGS += -I$(OVT_SOURCE_DIR)/lib/backdoor CFLAGS += -I$(OVT_SOURCE_DIR)/modules/shared/vmmemctl VPATH := $(OVT_SOURCE_DIR)/lib/backdoor VPATH := $(VPATH):$(OVT_SOURCE_DIR)/modules/shared/vmmemctl endif CFLAGS_32 := $(CFLAGS) CFLAGS_32 += -m32 LDFLAGS_32 := $(LDFLAGS) CFLAGS_64 := $(CFLAGS) CFLAGS_64 += -m64 KFLAGS_32 := $(KFLAGS) KFLAGS_64 := $(KFLAGS) KFLAGS_64 += -mcmodel=kernel KFLAGS_64 += -mno-red-zone LDFLAGS_64 := $(LDFLAGS) ifdef HAVE_GNU_LD LDFLAGS_64 += -m elf_x86_64 else LDFLAGS_64 += -64 endif all: prepare_dirs $(MODULES) prepare_dirs: @echo "Creating build directories" mkdir -p i386 mkdir -p amd64 $(MODULE_32): $(VMMCTL_32_OBJS) @echo "Linking $@" $(LD) $(LDFLAGS_32) -r $(VMMCTL_32_OBJS) -o $@ $(VMMCTL_32_OBJS): i386/%.o: %.c @echo "Compiling $(devEnabled); for (i = 0; i < txq->cmdRing.size; i++) { mblk_t *mp = txq->metaRing[i].mp; if (mp) { freemsg(mp); } } } /* *--------------------------------------------------------------------------- * * vmxnet3_tx_prepare_offload -- * * Build the offload context of a msg. * * Results: * 0 if everything went well. * +n if n bytes need to be pulled up. * -1 in case of error (not used). * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int vmxnet3_tx_prepare_offload(vmxnet3_softc_t *dp, vmxnet3_offload_t *ol, mblk_t *mp) { int ret = 0; uint32_t start, stuff, value, flags; ol->om = VMXNET3_OM_NONE; ol->hlen = 0; ol->msscof = 0; hcksum_retrieve(mp, NULL, NULL, &start, &stuff, NULL, &value, &flags); if (flags) { struct ether_vlan_header *eth = (void *) mp->b_rptr; uint8_t ethLen; if (eth->ether_tpid == htons(ETHERTYPE_VLAN)) { ethLen = sizeof(struct ether_vlan_header); } else { ethLen = sizeof(struct ether_header); } VMXNET3_DEBUG(dp, 4, "flags=0x%x, ethLen=%u, start=%u, stuff=%u, value=%u\n", flags, ethLen, start, stuff, value); if (flags & HCK_PARTIALCKSUM) { ol->om = VMXNET3_OM_CSUM; ol->hlen = start + ethLen; ol->msscof = stuff + ethLen; } if (flags & HW_LSO) { mblk_t *mblk = mp; uint8_t *ip, *tcp; uint8_t ipLen, tcpLen; /* * Copy e1000g's behavior: * - Do not assume all the headers are in the same mblk. * - Assume each header is always within one mblk. * - Assume the ethernet header is in the first mblk. */ ip = mblk->b_rptr + ethLen; if (ip >= mblk->b_wptr) { mblk = mblk->b_cont; ip = mblk->b_rptr; } ipLen = IPH_HDR_LENGTH((ipha_t *) ip); tcp = ip + ipLen; if (tcp >= mblk->b_wptr) { mblk = mblk->b_cont; tcp = mblk->b_rptr; } tcpLen = TCP_HDR_LENGTH((tcph_t *) tcp); if (tcp + tcpLen > mblk->b_wptr) { // careful, '>' instead of '>=' here mblk = mblk->b_cont; } ol->om = VMXNET3_OM_TSO; ol->hlen = ethLen + ipLen + tcpLen; /* OpenSolaris fills 'value' with the MSS but Solaris doesn't. */ ol->msscof = DB_LSOMSS(mp); if (mblk != mp) { ret = ol->hlen; } } } return ret; } /* *--------------------------------------------------------------------------- * * vmxnet3_tx_one -- * * Map a msg into the Tx command ring of a vmxnet3 device. * * Results: * VMXNET3_TX_OK if everything went well. * VMXNET3_TX_RINGFULL if the ring is nearly full. * VMXNET3_TX_PULLUP if the msg is overfragmented. * VMXNET3_TX_FAILURE if there was a DMA or offload error. * * Side effects: * The ring is filled if VMXNET3_TX_OK is returned. * *--------------------------------------------------------------------------- */ static vmxnet3_txstatus vmxnet3_tx_one(vmxnet3_softc_t *dp, vmxnet3_txqueue_t *txq, vmxnet3_offload_t *ol, mblk_t *mp, boolean_t retry) { int ret = VMXNET3_TX_OK; unsigned int frags = 0, totLen = 0; vmxnet3_cmdring_t *cmdRing = &txq->cmdRing; Vmxnet3_TxQueueCtrl *txqCtrl = txq->sharedCtrl; Vmxnet3_GenericDesc *txDesc; uint16_t sopIdx, eopIdx; uint8_t sopGen, curGen; mblk_t *mblk; mutex_enter(&dp->txLock); sopIdx = eopIdx = cmdRing->next2fill; sopGen = cmdRing->gen; curGen = !cmdRing->gen; for (mblk = mp; mblk != NULL; mblk = mblk->b_cont) { unsigned int len = MBLKL(mblk); ddi_dma_cookie_t cookie; uint_t cookieCount; if (len) { totLen += len; } else { continue; } if (ddi_dma_addr_bind_handle(dp->txDmaHandle, NULL, (caddr_t) mblk->b_rptr, len, DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, NULL, &cookie, &cookieCount) != DDI_DMA_MAPPED) { VMXNET3_WARN(dp, "ddi_dma_addr_bind_handle() failed\n"); ret = VMXNET3_TX_FAILURE; goto error; } ASSERT(cookieCount); do { uint64_t addr = cookie.dmac_laddress; size_t len = cookie.dmac_size; do { uint32_t dw2, dw3; size_t chunkLen; ASSERT(!txq->metaRing[eopIdx].mp); ASSERT(cmdRing->avail - frags); if (frags >= cmdRing->size - 1 || (ol->om != VMXNET3_OM_TSO && frags >= VMXNET3_MAX_TXD_PER_PKT)) { if (retry) { VMXNET3_DEBUG(dp, 2, "overfragmented, frags=%u ring=%hu om=%hu\n", frags, cmdRing->size, ol->om); } ddi_dma_unbind_handle(dp->txDmaHandle); ret = VMXNET3_TX_PULLUP; goto error; } if (cmdRing->avail - frags <= 1) { dp->txMustResched = B_TRUE; ddi_dma_unbind_handle(dp->txDmaHandle); ret = VMXNET3_TX_RINGFULL; goto error; } if (len > VMXNET3_MAX_TX_BUF_SIZE) { chunkLen = VMXNET3_MAX_TX_BUF_SIZE; } else { chunkLen = len; } frags++; eopIdx = cmdRing->next2fill; txDesc = VMXNET3_GET_DESC(cmdRing, eopIdx); ASSERT(txDesc->txd.gen != cmdRing->gen); // txd.addr txDesc->txd.addr = addr; // txd.dw2 dw2 = chunkLen == VMXNET3_MAX_TX_BUF_SIZE ? 0 : chunkLen; dw2 |= curGen << VMXNET3_TXD_GEN_SHIFT; txDesc->dword[2] = dw2; ASSERT(txDesc->txd.len == len || txDesc->txd.len == 0); // txd.dw3 dw3 = 0; txDesc->dword[3] = dw3; VMXNET3_INC_RING_IDX(cmdRing, cmdRing->next2fill); curGen = cmdRing->gen; addr += chunkLen; len -= chunkLen; } while (len); if (--cookieCount) { ddi_dma_nextcookie(dp->txDmaHandle, &cookie); } } while (cookieCount); ddi_dma_unbind_handle(dp->txDmaHandle); } /* Update the EOP descriptor */ txDesc = VMXNET3_GET_DESC(cmdRing, eopIdx); txDesc->dword[3] |= VMXNET3_TXD_CQ | VMXNET3_TXD_EOP; /* Update the SOP descriptor. Must be done last */ txDesc = VMXNET3_GET_DESC(cmdRing, sopIdx); if (ol->om == VMXNET3_OM_TSO && txDesc->txd.len != 0 && txDesc->txd.len < ol->hlen) { ret = VMXNET3_TX_FAILURE; goto error; } txDesc->txd.om = ol->om; txDesc->txd.hlen = ol->hlen; txDesc->txd.msscof = ol->msscof; membar_producer(); txDesc->txd.gen = sopGen; /* Update the meta ring & metadata */ txq->metaRing[sopIdx].mp = mp; txq->metaRing[eopIdx].sopIdx = sopIdx; txq->metaRing[eopIdx].frags = frags; cmdRing->avail -= frags; if (ol->om == VMXNET3_OM_TSO) { txqCtrl->txNumDeferred += (totLen - ol->hlen + ol->msscof - 1) / ol->msscof; } else { txqCtrl->txNumDeferred++; } VMXNET3_DEBUG(dp, 3, "tx 0x%p on [%u;%u]\n", mp, sopIdx, eopIdx); goto done; error: /* Reverse the generation bits */ while (sopIdx != cmdRing->next2fill) { VMXNET3_DEC_RING_IDX(cmdRing, cmdRing->next2fill); txDesc = VMXNET3_GET_DESC(cmdRing, cmdRing->next2fill); txDesc->txd.gen = !cmdRing->gen; } done: mutex_exit(&dp->txLock); return ret; } /* *--------------------------------------------------------------------------- * * vmxnet3_tx -- * * Send packets on a vmxnet3 device. * * Results: * NULL in case of success or failure. * The mps to be retransmitted later if the ring is full. * * Side effects: * None. * *--------------------------------------------------------------------------- */ mblk_t * vmxnet3_tx(void *data, mblk_t *mps) { vmxnet3_softc_t *dp = data; vmxnet3_txqueue_t *txq = &dp->txQueue; vmxnet3_cmdring_t *cmdRing = &txq->cmdRing; Vmxnet3_TxQueueCtrl *txqCtrl = txq->sharedCtrl; vmxnet3_txstatus status = VMXNET3_TX_OK; mblk_t *mp; ASSERT(mps != NULL); do { vmxnet3_offload_t ol; int pullup; mp = mps; mps = mp->b_next; mp->b_next = NULL; if (DB_TYPE(mp) != M_DATA) { /* * PR #315560: Solaris might pass M_PROTO mblks for some reason. * Drop them because we don't understand them and because their * contents are not Ethernet frames anyway. */ ASSERT(B_FALSE); freemsg(mp); continue; } /* * Prepare the offload while we're still handling the original * message -- msgpullup() discards the metadata afterwards. */ pullup = vmxnet3_tx_prepare_offload(dp, &ol, mp); if (pullup) { mblk_t *new_mp = msgpullup(mp, pullup); freemsg(mp); if (new_mp) { mp = new_mp; } else { continue; } } /* * Try to map the message in the Tx ring. * This call might fail for non-fatal reasons. */ status = vmxnet3_tx_one(dp, txq, &ol, mp, B_FALSE); if (status == VMXNET3_TX_PULLUP) { /* * Try one more time after flattening * the message with msgpullup(). */ if (mp->b_cont != NULL) { mblk_t *new_mp = msgpullup(mp, -1); freemsg(mp); if (new_mp) { mp = new_mp; status = vmxnet3_tx_one(dp, txq, &ol, mp, B_TRUE); } else { continue; } } } if (status != VMXNET3_TX_OK && status != VMXNET3_TX_RINGFULL) { /* Fatal failure, drop it */ freemsg(mp); } } while (mps && status != VMXNET3_TX_RINGFULL); if (status == VMXNET3_TX_RINGFULL) { mp->b_next = mps; mps = mp; } else { ASSERT(!mps); } /* Notify the device */ mutex_enter(&dp->txLock); if (txqCtrl->txNumDeferred >= txqCtrl->txThreshold) { txqCtrl->txNumDeferred = 0; VMXNET3_BAR0_PUT32(dp, VMXNET3_REG_TXPROD, cmdRing->next2fill); } mutex_exit(&dp->txLock); return mps; } /* *--------------------------------------------------------------------------- * * vmxnet3_tx_complete -- * * Parse a transmit queue and complete packets. * * Results: * B_TRUE if Tx must be updated or B_FALSE if no action is required. * * Side effects: * None. * *--------------------------------------------------------------------------- */ boolean_t vmxnet3_tx_complete(vmxnet3_softc_t *dp, vmxnet3_txqueue_t *txq) { vmxnet3_cmdring_t *cmdRing = &txq->cmdRing; vmxnet3_compring_t *compRing = &txq->compRing; Vmxnet3_GenericDesc *compDesc; boolean_t completedTx = B_FALSE; boolean_t ret = B_FALSE; mutex_enter(&dp->txLock); compDesc = VMXNET3_GET_DESC(compRing, compRing->next2comp); while (compDesc->tcd.gen == compRing->gen) { vmxnet3_metatx_t *sopMetaDesc, *eopMetaDesc; uint16_t sopIdx, eopIdx; mblk_t *mp; eopIdx = compDesc->tcd.txdIdx; eopMetaDesc = &txq->metaRing[eopIdx]; sopIdx = eopMetaDesc->sopIdx; sopMetaDesc = &txq->metaRing[sopIdx]; ASSERT(eopMetaDesc->frags); cmdRing->avail += eopMetaDesc->frags; ASSERT(sopMetaDesc->mp); mp = sopMetaDesc->mp; freemsg(mp); eopMetaDesc->sopIdx = 0; eopMetaDesc->frags = 0; sopMetaDesc->mp = NULL; completedTx = B_TRUE; VMXNET3_DEBUG(dp, 3, "cp 0x%p on [%u;%u]\n", mp, sopIdx, eopIdx); VMXNET3_INC_RING_IDX(compRing, compRing->next2comp); compDesc = VMXNET3_GET_DESC(compRing, compRing->next2comp); } if (dp->txMustResched && completedTx) { dp->txMustResched = B_FALSE; ret = B_TRUE; } mutex_exit(&dp->txLock); return ret; } open-vm-tools-9.4.0-1280544/modules/solaris/vmxnet3/vmxnet3_main.c0000644765153500003110000013116112220061556022746 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ #include "vmxnet3_solaris.h" /* * TODO: * - Tx data ring * - MAC_CAPAB_POLL support * - JF support * - Dynamic RX pool */ /* * Forward declarations */ static int vmxnet3_getstat(void *, uint_t, uint64_t *); static int vmxnet3_start(void *); static void vmxnet3_stop(void *); static int vmxnet3_setpromisc(void *, boolean_t); static void vmxnet3_ioctl(void *arg, queue_t *wq, mblk_t *mp); static int vmxnet3_multicst(void *, boolean_t, const uint8_t *); static int vmxnet3_unicst(void *, const uint8_t *); static boolean_t vmxnet3_getcapab(void *, mac_capab_t, void *); /* MAC callbacks */ static mac_callbacks_t vmxnet3_mac_callbacks = { .mc_callbacks = MC_GETCAPAB | MC_IOCTL, .mc_getstat = vmxnet3_getstat, .mc_start = vmxnet3_start, .mc_stop = vmxnet3_stop, .mc_setpromisc = vmxnet3_setpromisc, .mc_multicst = vmxnet3_multicst, .mc_unicst = vmxnet3_unicst, .mc_tx = vmxnet3_tx, #ifndef OPEN_SOLARIS #ifndef SOL11 .mc_resources = NULL, #endif #endif .mc_ioctl = vmxnet3_ioctl, .mc_getcapab = *vmxnet3_getcapab, }; /* Tx DMA engine description */ static ddi_dma_attr_t vmxnet3_dma_attrs_tx = { DMA_ATTR_V0, /* dma_attr_version */ 0x0000000000000000ull, /* dma_attr_addr_lo */ 0xFFFFFFFFFFFFFFFFull, /* dma_attr_addr_hi */ 0xFFFFFFFFFFFFFFFFull, /* dma_attr_count_max */ 0x0000000000000001ull, /* dma_attr_align */ 0x0000000000000001ull, /* dma_attr_burstsizes */ 0x00000001, /* dma_attr_minxfer */ 0x000000000000FFFFull, /* dma_attr_maxxfer */ 0xFFFFFFFFFFFFFFFFull, /* dma_attr_seg */ -1, /* dma_attr_sgllen */ 0x00000001, /* dma_attr_granular */ 0 /* dma_attr_flags */ }; /* --- */ /* *--------------------------------------------------------------------------- * * vmxnet3_getstat -- * * Fetch the statistics of a vmxnet3 device. * * Results: * DDI_FAILURE. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int vmxnet3_getstat(void *data, uint_t stat, uint64_t *val) { vmxnet3_softc_t *dp = data; UPT1_TxStats *txStats; UPT1_RxStats *rxStats; VMXNET3_DEBUG(dp, 3, "getstat(%u)\n", stat); if (!dp->devEnabled) { return DDI_FAILURE; } txStats = &VMXNET3_TQDESC(dp)->stats; rxStats = &VMXNET3_RQDESC(dp)->stats; /* * First touch the related register */ switch (stat) { case MAC_STAT_MULTIRCV: case MAC_STAT_BRDCSTRCV: case MAC_STAT_MULTIXMT: case MAC_STAT_BRDCSTXMT: case MAC_STAT_NORCVBUF: case MAC_STAT_IERRORS: case MAC_STAT_NOXMTBUF: case MAC_STAT_OERRORS: case MAC_STAT_RBYTES: case MAC_STAT_IPACKETS: case MAC_STAT_OBYTES: case MAC_STAT_OPACKETS: VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS); break; case MAC_STAT_IFSPEED: case MAC_STAT_COLLISIONS: case ETHER_STAT_LINK_DUPLEX: /* nothing */ break; default: return DDI_FAILURE; } /* * Then fetch the corresponding stat */ switch (stat) { case MAC_STAT_IFSPEED: *val = dp->linkSpeed; break; case MAC_STAT_MULTIRCV: *val = rxStats->mcastPktsRxOK; break; case MAC_STAT_BRDCSTRCV: *val = rxStats->bcastPktsRxOK; break; case MAC_STAT_MULTIXMT: *val = txStats->mcastPktsTxOK; break; case MAC_STAT_BRDCSTXMT: *val = txStats->bcastPktsTxOK; break; case MAC_STAT_NORCVBUF: *val = rxStats->pktsRxOutOfBuf; break; case MAC_STAT_IERRORS: *val = rxStats->pktsRxError; break; case MAC_STAT_NOXMTBUF: *val = txStats->pktsTxDiscard; break; case MAC_STAT_OERRORS: *val = txStats->pktsTxError; break; case MAC_STAT_COLLISIONS: *val = 0; break; case MAC_STAT_RBYTES: *val = rxStats->LROBytesRxOK + rxStats->ucastBytesRxOK + rxStats->mcastBytesRxOK + rxStats->bcastBytesRxOK; break; case MAC_STAT_IPACKETS: *val = rxStats->LROPktsRxOK + rxStats->ucastPktsRxOK + rxStats->mcastPktsRxOK + rxStats->bcastPktsRxOK; break; case MAC_STAT_OBYTES: *val = txStats->TSOBytesTxOK + txStats->ucastBytesTxOK + txStats->mcastBytesTxOK + txStats->bcastBytesTxOK; break; case MAC_STAT_OPACKETS: *val = txStats->TSOPktsTxOK + txStats->ucastPktsTxOK + txStats->mcastPktsTxOK + txStats->bcastPktsTxOK; break; case ETHER_STAT_LINK_DUPLEX: *val = LINK_DUPLEX_FULL; break; default: ASSERT(B_FALSE); } return DDI_SUCCESS; } /* *--------------------------------------------------------------------------- * * vmxnet3_prepare_drivershared -- * * Allocate and initialize the shared data structures * of a vmxnet3 device. * * Results: * DDI_SUCCESS or DDI_FAILURE. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int vmxnet3_prepare_drivershared(vmxnet3_softc_t *dp) { Vmxnet3_DriverShared *ds; size_t allocSize = sizeof(Vmxnet3_DriverShared); if (vmxnet3_alloc_dma_mem_1(dp, &dp->sharedData, allocSize, B_TRUE) != DDI_SUCCESS) { return DDI_FAILURE; } ds = VMXNET3_DS(dp); memset(ds, 0, allocSize); allocSize = sizeof(Vmxnet3_TxQueueDesc) + sizeof(Vmxnet3_RxQueueDesc); if (vmxnet3_alloc_dma_mem_128(dp, &dp->queueDescs, allocSize, B_TRUE) != DDI_SUCCESS) { vmxnet3_free_dma_mem(&dp->sharedData); return DDI_FAILURE; } memset(dp->queueDescs.buf, 0, allocSize); ds->magic = VMXNET3_REV1_MAGIC; /* Take care of most of devRead */ ds->devRead.misc.driverInfo.version = BUILD_NUMBER_NUMERIC; if (sizeof(void *) == 4) { ds->devRead.misc.driverInfo.gos.gosBits = VMXNET3_GOS_BITS_32; } else if (sizeof(void *) == 8) { ds->devRead.misc.driverInfo.gos.gosBits = VMXNET3_GOS_BITS_64; } else { ASSERT(B_FALSE); } ds->devRead.misc.driverInfo.gos.gosType = VMXNET3_GOS_TYPE_SOLARIS; ds->devRead.misc.driverInfo.gos.gosVer = 10; ds->devRead.misc.driverInfo.vmxnet3RevSpt = 1; ds->devRead.misc.driverInfo.uptVerSpt = 1; ds->devRead.misc.uptFeatures = UPT1_F_RXCSUM; ds->devRead.misc.mtu = dp->cur_mtu; // XXX: ds->devRead.misc.maxNumRxSG ds->devRead.misc.numTxQueues = 1; ds->devRead.misc.numRxQueues = 1; ds->devRead.misc.queueDescPA = dp->queueDescs.bufPA; ds->devRead.misc.queueDescLen = allocSize; /* TxQueue and RxQueue information is filled in other functions */ ds->devRead.intrConf.autoMask = (dp->intrMaskMode == VMXNET3_IMM_AUTO); ds->devRead.intrConf.numIntrs = 1; // XXX: ds->intr.modLevels ds->devRead.intrConf.eventIntrIdx = 0; VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_DSAL, VMXNET3_ADDR_LO(dp->sharedData.bufPA)); VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_DSAH, VMXNET3_ADDR_HI(dp->sharedData.bufPA)); return DDI_SUCCESS; } /* *--------------------------------------------------------------------------- * * vmxnet3_destroy_drivershared -- * * Destroy the shared data structures of a vmxnet3 device. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static void vmxnet3_destroy_drivershared(vmxnet3_softc_t *dp) { VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_DSAL, 0); VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_DSAH, 0); vmxnet3_free_dma_mem(&dp->queueDescs); vmxnet3_free_dma_mem(&dp->sharedData); } /* *--------------------------------------------------------------------------- * * vmxnet3_alloc_cmdring -- * * Allocate and initialize the command ring of a queue. * * Results: * DDI_SUCCESS or DDI_FAILURE. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int vmxnet3_alloc_cmdring(vmxnet3_softc_t *dp, vmxnet3_cmdring_t *cmdRing) { size_t ringSize = cmdRing->size * sizeof(Vmxnet3_TxDesc); if (vmxnet3_alloc_dma_mem_512(dp, &cmdRing->dma, ringSize, B_TRUE) != DDI_SUCCESS) { return DDI_FAILURE; } memset(cmdRing->dma.buf, 0, ringSize); cmdRing->avail = cmdRing->size; cmdRing->next2fill = 0; cmdRing->gen = VMXNET3_INIT_GEN; return DDI_SUCCESS; } /* *--------------------------------------------------------------------------- * * vmxnet3_alloc_compring -- * * Allocate and initialize the completion ring of a queue. * * Results: * DDI_SUCCESS or DDI_FAILURE. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int vmxnet3_alloc_compring(vmxnet3_softc_t *dp, vmxnet3_compring_t *compRing) { size_t ringSize = compRing->size * sizeof(Vmxnet3_TxCompDesc); if (vmxnet3_alloc_dma_mem_512(dp, &compRing->dma, ringSize, B_TRUE) != DDI_SUCCESS) { return DDI_FAILURE; } memset(compRing->dma.buf, 0, ringSize); compRing->next2comp = 0; compRing->gen = VMXNET3_INIT_GEN; return DDI_SUCCESS; } /* *--------------------------------------------------------------------------- * * vmxnet3_prepare_txqueue -- * * Initialize the tx queue of a vmxnet3 device. * * Results: * DDI_SUCCESS or DDI_FAILURE. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int vmxnet3_prepare_txqueue(vmxnet3_softc_t *dp) { Vmxnet3_TxQueueDesc *tqdesc = VMXNET3_TQDESC(dp); vmxnet3_txqueue_t *txq = &dp->txQueue; ASSERT(!(txq->cmdRing.size & VMXNET3_RING_SIZE_MASK)); ASSERT(!(txq->compRing.size & VMXNET3_RING_SIZE_MASK)); ASSERT(!txq->cmdRing.dma.buf && !txq->compRing.dma.buf); if (vmxnet3_alloc_cmdring(dp, &txq->cmdRing) != DDI_SUCCESS) { goto error; } tqdesc->conf.txRingBasePA = txq->cmdRing.dma.bufPA; tqdesc->conf.txRingSize = txq->cmdRing.size; tqdesc->conf.dataRingBasePA = 0; tqdesc->conf.dataRingSize = 0; if (vmxnet3_alloc_compring(dp, &txq->compRing) != DDI_SUCCESS) { goto error_cmdring; } tqdesc->conf.compRingBasePA = txq->compRing.dma.bufPA; tqdesc->conf.compRingSize = txq->compRing.size; txq->metaRing = kmem_zalloc(txq->cmdRing.size*sizeof(vmxnet3_metatx_t), KM_SLEEP); ASSERT(txq->metaRing); if (vmxnet3_txqueue_init(dp, txq) != DDI_SUCCESS) { goto error_mpring; } return DDI_SUCCESS; error_mpring: kmem_free(txq->metaRing, txq->cmdRing.size*sizeof(vmxnet3_metatx_t)); vmxnet3_free_dma_mem(&txq->compRing.dma); error_cmdring: vmxnet3_free_dma_mem(&txq->cmdRing.dma); error: return DDI_FAILURE; } /* *--------------------------------------------------------------------------- * * vmxnet3_prepare_rxqueue -- * * Initialize the rx queue of a vmxnet3 device. * * Results: * DDI_SUCCESS or DDI_FAILURE. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int vmxnet3_prepare_rxqueue(vmxnet3_softc_t *dp) { Vmxnet3_RxQueueDesc *rqdesc = VMXNET3_RQDESC(dp); vmxnet3_rxqueue_t *rxq = &dp->rxQueue; ASSERT(!(rxq->cmdRing.size & VMXNET3_RING_SIZE_MASK)); ASSERT(!(rxq->compRing.size & VMXNET3_RING_SIZE_MASK)); ASSERT(!rxq->cmdRing.dma.buf && !rxq->compRing.dma.buf); if (vmxnet3_alloc_cmdring(dp, &rxq->cmdRing) != DDI_SUCCESS) { goto error; } rqdesc->conf.rxRingBasePA[0] = rxq->cmdRing.dma.bufPA; rqdesc->conf.rxRingSize[0] = rxq->cmdRing.size; rqdesc->conf.rxRingBasePA[1] = 0; rqdesc->conf.rxRingSize[1] = 0; if (vmxnet3_alloc_compring(dp, &rxq->compRing) != DDI_SUCCESS) { goto error_cmdring; } rqdesc->conf.compRingBasePA = rxq->compRing.dma.bufPA; rqdesc->conf.compRingSize = rxq->compRing.size; rxq->bufRing = kmem_zalloc(rxq->cmdRing.size*sizeof(vmxnet3_bufdesc_t), KM_SLEEP); ASSERT(rxq->bufRing); if (vmxnet3_rxqueue_init(dp, rxq) != DDI_SUCCESS) { goto error_bufring; } return DDI_SUCCESS; error_bufring: kmem_free(rxq->bufRing, rxq->cmdRing.size*sizeof(vmxnet3_bufdesc_t)); vmxnet3_free_dma_mem(&rxq->compRing.dma); error_cmdring: vmxnet3_free_dma_mem(&rxq->cmdRing.dma); error: return DDI_FAILURE; } /* *--------------------------------------------------------------------------- * * vmxnet3_destroy_txqueue -- * * Destroy the tx queue of a vmxnet3 device. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static void vmxnet3_destroy_txqueue(vmxnet3_softc_t *dp) { vmxnet3_txqueue_t *txq = &dp->txQueue; ASSERT(txq->metaRing); ASSERT(txq->cmdRing.dma.buf && txq->compRing.dma.buf); vmxnet3_txqueue_fini(dp, txq); kmem_free(txq->metaRing, txq->cmdRing.size*sizeof(vmxnet3_metatx_t)); vmxnet3_free_dma_mem(&txq->cmdRing.dma); vmxnet3_free_dma_mem(&txq->compRing.dma); } /* *--------------------------------------------------------------------------- * * vmxnet3_destroy_rxqueue -- * * Destroy the rx queue of a vmxnet3 device. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static void vmxnet3_destroy_rxqueue(vmxnet3_softc_t *dp) { vmxnet3_rxqueue_t *rxq = &dp->rxQueue; ASSERT(rxq->bufRing); ASSERT(rxq->cmdRing.dma.buf && rxq->compRing.dma.buf); vmxnet3_rxqueue_fini(dp, rxq); kmem_free(rxq->bufRing, rxq->cmdRing.size*sizeof(vmxnet3_bufdesc_t)); vmxnet3_free_dma_mem(&rxq->cmdRing.dma); vmxnet3_free_dma_mem(&rxq->compRing.dma); } /* *--------------------------------------------------------------------------- * * vmxnet3_refresh_rxfilter -- * * Apply new RX filters settings to a vmxnet3 device. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static void vmxnet3_refresh_rxfilter(vmxnet3_softc_t *dp) { Vmxnet3_DriverShared *ds = VMXNET3_DS(dp); ds->devRead.rxFilterConf.rxMode = dp->rxMode; VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_CMD, VMXNET3_CMD_UPDATE_RX_MODE); } /* *--------------------------------------------------------------------------- * * vmxnet3_refresh_linkstate -- * * Fetch the link state of a vmxnet3 device. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static void vmxnet3_refresh_linkstate(vmxnet3_softc_t *dp) { uint32_t ret32; VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK); ret32 = VMXNET3_BAR1_GET32(dp, VMXNET3_REG_CMD); if (ret32 & 1) { dp->linkState = LINK_STATE_UP; dp->linkSpeed = (ret32 >> 16) * 1000000ULL; } else { dp->linkState = LINK_STATE_DOWN; dp->linkSpeed = 0; } } /* *--------------------------------------------------------------------------- * * vmxnet3_start -- * * Start a vmxnet3 device: allocate and initialize the shared data * structures and send a start command to the device. * * Results: * DDI_SUCCESS or DDI_FAILURE. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int vmxnet3_start(void *data) { vmxnet3_softc_t *dp = data; Vmxnet3_TxQueueDesc *tqdesc; Vmxnet3_RxQueueDesc *rqdesc; int txQueueSize, rxQueueSize; uint32_t ret32; VMXNET3_DEBUG(dp, 1, "start()\n"); /* * Allocate vmxnet3's shared data and advertise its PA */ if (vmxnet3_prepare_drivershared(dp) != DDI_SUCCESS) { VMXNET3_WARN(dp, "vmxnet3_prepare_drivershared() failed\n"); goto error; } tqdesc = VMXNET3_TQDESC(dp); rqdesc = VMXNET3_RQDESC(dp); /* * Create and initialize the tx queue */ txQueueSize = vmxnet3_getprop(dp, "TxRingSize", 32, 4096, VMXNET3_DEF_TX_RING_SIZE); if (!(txQueueSize & VMXNET3_RING_SIZE_MASK)) { dp->txQueue.cmdRing.size = txQueueSize; dp->txQueue.compRing.size = txQueueSize; dp->txQueue.sharedCtrl = &tqdesc->ctrl; if (vmxnet3_prepare_txqueue(dp) != DDI_SUCCESS) { VMXNET3_WARN(dp, "vmxnet3_prepare_txqueue() failed\n"); goto error_shared_data; } } else { VMXNET3_WARN(dp, "invalid tx ring size (%d)\n", txQueueSize); goto error_shared_data; } /* * Create and initialize the rx queue */ rxQueueSize = vmxnet3_getprop(dp, "RxRingSize", 32, 4096, VMXNET3_DEF_RX_RING_SIZE); if (!(rxQueueSize & VMXNET3_RING_SIZE_MASK)) { dp->rxQueue.cmdRing.size = rxQueueSize; dp->rxQueue.compRing.size = rxQueueSize; dp->rxQueue.sharedCtrl = &rqdesc->ctrl; if (vmxnet3_prepare_rxqueue(dp) != DDI_SUCCESS) { VMXNET3_WARN(dp, "vmxnet3_prepare_rxqueue() failed\n"); goto error_tx_queue; } } else { VMXNET3_WARN(dp, "invalid rx ring size (%d)\n", rxQueueSize); goto error_tx_queue; } /* * Allocate the Tx DMA handle */ if (ddi_dma_alloc_handle(dp->dip, &vmxnet3_dma_attrs_tx, DDI_DMA_SLEEP, NULL, &dp->txDmaHandle) != DDI_SUCCESS) { VMXNET3_WARN(dp, "ddi_dma_alloc_handle() failed\n"); goto error_rx_queue; } /* * Activate the device */ VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_CMD, VMXNET3_CMD_ACTIVATE_DEV); ret32 = VMXNET3_BAR1_GET32(dp, VMXNET3_REG_CMD); if (ret32) { VMXNET3_WARN(dp, "ACTIVATE_DEV failed: 0x%x\n", ret32); goto error_txhandle; } dp->devEnabled = B_TRUE; VMXNET3_BAR0_PUT32(dp, VMXNET3_REG_RXPROD, dp->txQueue.cmdRing.size - 1); /* * Update the RX filters, must be done after ACTIVATE_DEV */ dp->rxMode = VMXNET3_RXM_UCAST | VMXNET3_RXM_BCAST; vmxnet3_refresh_rxfilter(dp); /* * Get the link state now because no events will be generated */ vmxnet3_refresh_linkstate(dp); mac_link_update(dp->mac, dp->linkState); /* * Finally, unmask the interrupt */ VMXNET3_BAR0_PUT32(dp, VMXNET3_REG_IMR, 0); return DDI_SUCCESS; error_txhandle: ddi_dma_free_handle(&dp->txDmaHandle); error_rx_queue: vmxnet3_destroy_rxqueue(dp); error_tx_queue: vmxnet3_destroy_txqueue(dp); error_shared_data: vmxnet3_destroy_drivershared(dp); error: return DDI_FAILURE; } /* *--------------------------------------------------------------------------- * * vmxnet3_stop -- * * Stop a vmxnet3 device: send a stop command to the device and * de-allocate the shared data structures. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static void vmxnet3_stop(void *data) { vmxnet3_softc_t *dp = data; VMXNET3_DEBUG(dp, 1, "stop()\n"); /* * Take the 2 locks related to asynchronous events. * These events should always check dp->devEnabled before poking dp. */ mutex_enter(&dp->intrLock); mutex_enter(&dp->rxPoolLock); VMXNET3_BAR0_PUT32(dp, VMXNET3_REG_IMR, 1); dp->devEnabled = B_FALSE; VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_CMD, VMXNET3_CMD_QUIESCE_DEV); mutex_exit(&dp->rxPoolLock); mutex_exit(&dp->intrLock); ddi_dma_free_handle(&dp->txDmaHandle); vmxnet3_destroy_rxqueue(dp); vmxnet3_destroy_txqueue(dp); vmxnet3_destroy_drivershared(dp); } /* *--------------------------------------------------------------------------- * * vmxnet3_setpromisc -- * * Set or unset promiscuous mode on a vmxnet3 device. * * Results: * DDI_SUCCESS. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int vmxnet3_setpromisc(void *data, boolean_t promisc) { vmxnet3_softc_t *dp = data; VMXNET3_DEBUG(dp, 2, "setpromisc(%s)\n", promisc ? "TRUE" : "FALSE"); if (promisc) { dp->rxMode |= VMXNET3_RXM_PROMISC; } else { dp->rxMode &= ~VMXNET3_RXM_PROMISC; } vmxnet3_refresh_rxfilter(dp); return DDI_SUCCESS; } /* *--------------------------------------------------------------------------- * * vmxnet3_multicst -- * * Add or remove a multicast address from/to a vmxnet3 device. * * Results: * DDI_FAILURE. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int vmxnet3_multicst(void *data, boolean_t add, const uint8_t *macaddr) { vmxnet3_softc_t *dp = data; vmxnet3_dmabuf_t newMfTable; int ret = DDI_SUCCESS; uint16_t macIdx; VMXNET3_DEBUG(dp, 2, "multicst(%s, "MACADDR_FMT")\n", add ? "add" : "remove", MACADDR_FMT_ARGS(macaddr)); /* * First lookup the position of the given MAC to check if it is * present in the existing MF table. */ for (macIdx = 0; macIdx < dp->mfTable.bufLen; macIdx += 6) { if (memcmp(&dp->mfTable.buf[macIdx], macaddr, 6) == 0) { break; } } /* * Check for 2 situations we can handle gracefully by bailing out: * Adding an already existing filter or removing a non-existing one. */ if (add && macIdx < dp->mfTable.bufLen) { VMXNET3_WARN(dp, MACADDR_FMT " already in MC filter list @ %u\n", MACADDR_FMT_ARGS(macaddr), macIdx / 6); ASSERT(B_FALSE); goto done; } if (!add && macIdx == dp->mfTable.bufLen) { VMXNET3_WARN(dp, MACADDR_FMT " not in MC filter list @ %u\n", MACADDR_FMT_ARGS(macaddr), macIdx / 6); ASSERT(B_FALSE); goto done; } /* * Create the new MF table */ { size_t allocSize = dp->mfTable.bufLen + (add ? 6 : -6); if (allocSize) { ret = vmxnet3_alloc_dma_mem_1(dp, &newMfTable, allocSize, B_TRUE); ASSERT(ret == DDI_SUCCESS); if (add) { memcpy(newMfTable.buf, dp->mfTable.buf, dp->mfTable.bufLen); memcpy(newMfTable.buf + dp->mfTable.bufLen, macaddr, 6); } else { memcpy(newMfTable.buf, dp->mfTable.buf, macIdx); memcpy(newMfTable.buf + macIdx, dp->mfTable.buf + macIdx + 6, dp->mfTable.bufLen - macIdx - 6); } } else { newMfTable.buf = NULL; newMfTable.bufPA = 0; newMfTable.bufLen = 0; } } /* * Now handle 2 corner cases: if we're creating the first filter or * removing the last one, we have to update rxMode accordingly. */ if (add && newMfTable.bufLen == 6) { ASSERT(!(dp->rxMode & VMXNET3_RXM_MCAST)); dp->rxMode |= VMXNET3_RXM_MCAST; vmxnet3_refresh_rxfilter(dp); } if (!add && dp->mfTable.bufLen == 6) { ASSERT(newMfTable.buf == NULL); ASSERT(dp->rxMode & VMXNET3_RXM_MCAST); dp->rxMode &= ~VMXNET3_RXM_MCAST; vmxnet3_refresh_rxfilter(dp); } /* * Now replace the old MF table with the new one */ if (dp->mfTable.buf) { vmxnet3_free_dma_mem(&dp->mfTable); } dp->mfTable = newMfTable; VMXNET3_DS(dp)->devRead.rxFilterConf.mfTablePA = newMfTable.bufPA; VMXNET3_DS(dp)->devRead.rxFilterConf.mfTableLen = newMfTable.bufLen; done: /* Always update the filters */ VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_CMD, VMXNET3_CMD_UPDATE_MAC_FILTERS); return ret; } /* *--------------------------------------------------------------------------- * * vmxnet3_unicst -- * * Set the mac address of a vmxnet3 device. * * Results: * DDI_FAILURE. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int vmxnet3_unicst(void *data, const uint8_t *macaddr) { vmxnet3_softc_t *dp = data; uint32_t val32; VMXNET3_DEBUG(dp, 2, "unicst("MACADDR_FMT")\n", MACADDR_FMT_ARGS(macaddr)); val32 = *((uint32_t *) (macaddr + 0)); VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_MACL, val32); val32 = *((uint16_t *) (macaddr + 4)); VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_MACH, val32); memcpy(dp->macaddr, macaddr, 6); return DDI_SUCCESS; } /* *--------------------------------------------------------------------------- * * vmxnet3_change_mtu -- * * Change the MTU as seen by the driver. Reset the device and tx/rx queues * so that buffers of right size are posted in rx queues. * * Results: * EINVAL for invalid MTUs or other failures. 0 for success. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int vmxnet3_change_mtu(vmxnet3_softc_t *dp, uint32_t new_mtu) { int ret = 0, do_reset = 0; ASSERT(dp); VMXNET3_DEBUG(dp, 2, "New MTU: %d current MTU: %d\n", new_mtu, dp->cur_mtu); if (new_mtu == dp->cur_mtu) { VMXNET3_WARN(dp, "New MTU is same as old mtu : %d.\n", new_mtu); return 0; } if (new_mtu < VMXNET3_MIN_MTU || new_mtu > VMXNET3_MAX_MTU) { VMXNET3_WARN(dp, "New MTU not in valid range [%d, %d].\n", VMXNET3_MIN_MTU, VMXNET3_MAX_MTU); return EINVAL; } else if (new_mtu > ETHERMTU && !dp->allow_jumbo) { VMXNET3_WARN(dp, "MTU cannot be greater than %d because accept-jumbo " "is not enabled.\n", ETHERMTU); return EINVAL; } if (dp->devEnabled) { do_reset = 1; vmxnet3_stop(dp); VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV); } dp->cur_mtu = new_mtu; #if defined (SOL11) || defined (OPEN_SOLARIS) mac_maxsdu_update(dp->mac, new_mtu); #endif if (do_reset) ret = vmxnet3_start(dp); return ret; } /* *--------------------------------------------------------------------------- * * vmxnet3_ioctl -- * * DDI/DDK callback to handle IOCTL in driver. Currently it only handles * ND_SET ioctl. Rest all are ignored. The ND_SET is used to set/reset * accept-jumbo ndd parameter for the interface. * * Results: * Nothing is returned directly. An ACK or NACK is conveyed to the calling * function from the mblk which was used to call this function. * * Side effects: * MTU can be changed and device can be reset. * *--------------------------------------------------------------------------- */ static void vmxnet3_ioctl(void *arg, queue_t *wq, mblk_t *mp) { vmxnet3_softc_t *dp = arg; int ret = EINVAL; IOCP iocp; mblk_t *mp1; char *valp, *param; int data; iocp = (void *)mp->b_rptr; iocp->ioc_error = 0; switch (iocp->ioc_cmd) { case ND_SET: /* the mblk in continuation would contain the ndd parameter name * and data value to be set */ mp1 = mp->b_cont; if (!mp1) { VMXNET3_WARN(dp, "Error locating parameter name.\n"); ret = EINVAL; break; } mp1->b_datap->db_lim[-1] = '\0'; /* Force null termination */ /* * From /usr/src/uts/common/inet/nd.c : nd_getset() * "logic throughout nd_xxx assumes single data block for ioctl. * However, existing code sends in some big buffers." */ if (mp1->b_cont) { freemsg(mp1->b_cont); mp1->b_cont = NULL; } valp = (char *)mp1->b_rptr; /* Points to param name*/ ASSERT(valp); param = valp; VMXNET3_DEBUG(dp, 3, "ND Set ioctl for %s\n", param); /* Go past the end of this null terminated string to get the data value.*/ while (*valp && valp <= (char *)mp1->b_wptr) valp++; if (valp > (char *)mp1->b_wptr) { /* We are already beyond the readable area of mblk and still havent * found the end of param string. */ VMXNET3_WARN(dp, "No data value found to be set to param.\n"); data = -1; } else { valp++; /* Now this points to data string */ data = (int)*valp - (int)'0'; /* Get numeric value of first letter */ } if (strcmp("accept-jumbo", param) == 0) { if (data == 1) { VMXNET3_DEBUG(dp, 1, "Accepting jumbo frames\n"); dp->allow_jumbo = 1; vmxnet3_change_mtu(dp, VMXNET3_MAX_MTU); ret = 0; } else if (data == 0) { dp->allow_jumbo = 0; vmxnet3_change_mtu(dp, ETHERMTU); VMXNET3_DEBUG(dp, 1, "Rejecting jumbo frames\n"); ret = 0; } else { VMXNET3_WARN(dp, "Invalid data value to be set, use 1 or 0.\n"); ret = -1; } } freemsg(mp1); mp->b_cont = NULL; break; default: if (mp->b_cont) { freemsg(mp->b_cont); mp->b_cont = NULL; } ret = -1; break; } if (ret == 0) miocack(wq, mp, 0, 0); else miocnak(wq, mp, 0, EINVAL); } /* *--------------------------------------------------------------------------- * * vmxnet3_getcapab -- * * Get the capabilities of a vmxnet3 device. * * Results: * B_TRUE or B_FALSE. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static boolean_t vmxnet3_getcapab(void *data, mac_capab_t capab, void *arg) { vmxnet3_softc_t *dp = data; boolean_t ret; switch (capab) { case MAC_CAPAB_HCKSUM: { uint32_t *txflags = arg; *txflags = HCKSUM_INET_PARTIAL; ret = B_TRUE; break; } case MAC_CAPAB_LSO: { mac_capab_lso_t *lso = arg; lso->lso_flags = LSO_TX_BASIC_TCP_IPV4; lso->lso_basic_tcp_ipv4.lso_max = IP_MAXPACKET; ret = vmxnet3_getprop(dp, "EnableLSO", 0, 1, 1); break; } default: ret = B_FALSE; } VMXNET3_DEBUG(dp, 3, "getcapab(0x%x) -> %s\n", capab, ret ? "yes" : "no"); return ret; } /* *--------------------------------------------------------------------------- * * vmxnet3_reset -- * * Reset a vmxnet3 device. Only to be used when the device is wedged. * * Results: * None. * * Side effects: * The device is reset. * *--------------------------------------------------------------------------- */ static void vmxnet3_reset(void *data) { vmxnet3_softc_t *dp = data; VMXNET3_DEBUG(dp, 1, "vmxnet3_reset()\n"); vmxnet3_stop(dp); VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV); vmxnet3_start(dp); } /* *--------------------------------------------------------------------------- * * vmxnet3_intr_events -- * * Process pending events on a vmxnet3 device. * * Results: * B_TRUE if the link state changed, B_FALSE otherwise. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static boolean_t vmxnet3_intr_events(vmxnet3_softc_t *dp) { Vmxnet3_DriverShared *ds = VMXNET3_DS(dp); boolean_t linkStateChanged = B_FALSE; uint32_t events = ds->ecr; if (events) { VMXNET3_DEBUG(dp, 2, "events(0x%x)\n", events); if (events & (VMXNET3_ECR_RQERR | VMXNET3_ECR_TQERR)) { Vmxnet3_TxQueueDesc *tqdesc = VMXNET3_TQDESC(dp); Vmxnet3_RxQueueDesc *rqdesc = VMXNET3_RQDESC(dp); VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_CMD, VMXNET3_CMD_GET_QUEUE_STATUS); if (tqdesc->status.stopped) { VMXNET3_WARN(dp, "tq error 0x%x\n", tqdesc->status.error); } if (rqdesc->status.stopped) { VMXNET3_WARN(dp, "rq error 0x%x\n", rqdesc->status.error); } if (ddi_taskq_dispatch(dp->resetTask, vmxnet3_reset, dp, DDI_NOSLEEP) == DDI_SUCCESS) { VMXNET3_WARN(dp, "reset scheduled\n"); } else { VMXNET3_WARN(dp, "ddi_taskq_dispatch() failed()\n"); } } if (events & VMXNET3_ECR_LINK) { vmxnet3_refresh_linkstate(dp); linkStateChanged = B_TRUE; } if (events & VMXNET3_ECR_DIC) { VMXNET3_DEBUG(dp, 1, "device implementation change\n"); } VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_ECR, events); } return linkStateChanged; } /* *--------------------------------------------------------------------------- * * vmxnet3_intr -- * * Interrupt handler of a vmxnet3 device. * * Results: * DDI_INTR_CLAIMED or DDI_INTR_UNCLAIMED. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static u_int vmxnet3_intr(caddr_t data1, caddr_t data2) { vmxnet3_softc_t *dp = (void *) data1; VMXNET3_DEBUG(dp, 3, "intr()\n"); mutex_enter(&dp->intrLock); if (dp->devEnabled) { boolean_t linkStateChanged; boolean_t mustUpdateTx; mblk_t *mps; if (dp->intrType == DDI_INTR_TYPE_FIXED && !VMXNET3_BAR1_GET32(dp, VMXNET3_REG_ICR)) { goto intr_unclaimed; } if (dp->intrMaskMode == VMXNET3_IMM_ACTIVE) { VMXNET3_BAR0_PUT32(dp, VMXNET3_REG_IMR, 1); } linkStateChanged = vmxnet3_intr_events(dp); mustUpdateTx = vmxnet3_tx_complete(dp, &dp->txQueue); mps = vmxnet3_rx_intr(dp, &dp->rxQueue); mutex_exit(&dp->intrLock); VMXNET3_BAR0_PUT32(dp, VMXNET3_REG_IMR, 0); if (linkStateChanged) { mac_link_update(dp->mac, dp->linkState); } if (mustUpdateTx) { mac_tx_update(dp->mac); } if (mps) { mac_rx(dp->mac, NULL, mps); } return DDI_INTR_CLAIMED; } intr_unclaimed: mutex_exit(&dp->intrLock); return DDI_INTR_UNCLAIMED; } /* *--------------------------------------------------------------------------- * * vmxnet3_attach -- * * Probe and attach a vmxnet3 instance to the stack. * * Results: * DDI_SUCCESS or DDI_FAILURE. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int vmxnet3_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) { vmxnet3_softc_t *dp; mac_register_t *macr; uint16_t vendorId, devId, ret16; uint32_t ret32; int ret, err; uint_t uret; if (cmd != DDI_ATTACH) { goto error; } /* * Allocate the soft state */ dp = kmem_zalloc(sizeof(vmxnet3_softc_t), KM_SLEEP); ASSERT(dp); dp->dip = dip; dp->instance = ddi_get_instance(dip); dp->cur_mtu = ETHERMTU; VMXNET3_DEBUG(dp, 1, "attach()\n"); ddi_set_driver_private(dip, dp); /* * Get access to the PCI bus configuration space */ if (pci_config_setup(dip, &dp->pciHandle) != DDI_SUCCESS) { VMXNET3_WARN(dp, "pci_config_setup() failed\n"); goto error_soft_state; } /* * Make sure the chip is a vmxnet3 device */ vendorId = pci_config_get16(dp->pciHandle, PCI_CONF_VENID); devId = pci_config_get16(dp->pciHandle, PCI_CONF_DEVID); if (vendorId != PCI_VENDOR_ID_VMWARE || devId != PCI_DEVICE_ID_VMWARE_VMXNET3) { VMXNET3_WARN(dp, "wrong PCI venid/devid (0x%x, 0x%x)\n", vendorId, devId); goto error_pci_config; } /* * Make sure we can access the registers through the I/O space */ ret16 = pci_config_get16(dp->pciHandle, PCI_CONF_COMM); ret16 |= PCI_COMM_IO | PCI_COMM_ME; pci_config_put16(dp->pciHandle, PCI_CONF_COMM, ret16); /* * Map the I/O space in memory */ if (ddi_regs_map_setup(dip, 1, &dp->bar0, 0, 0, &vmxnet3_dev_attr, &dp->bar0Handle) != DDI_SUCCESS) { VMXNET3_WARN(dp, "ddi_regs_map_setup() for BAR0 failed\n"); goto error_pci_config; } if (ddi_regs_map_setup(dip, 2, &dp->bar1, 0, 0, &vmxnet3_dev_attr, &dp->bar1Handle) != DDI_SUCCESS) { VMXNET3_WARN(dp, "ddi_regs_map_setup() for BAR1 failed\n"); goto error_regs_map_0; } /* * Check the version number of the virtual device */ if (VMXNET3_BAR1_GET32(dp, VMXNET3_REG_VRRS) & 1) { VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_VRRS, 1); } else { VMXNET3_WARN(dp, "incompatible h/w version\n"); goto error_regs_map_1; } if (VMXNET3_BAR1_GET32(dp, VMXNET3_REG_UVRS) & 1) { VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_UVRS, 1); } else { VMXNET3_WARN(dp, "incompatible upt version\n"); goto error_regs_map_1; } /* * Read the MAC address from the device */ ret32 = VMXNET3_BAR1_GET32(dp, VMXNET3_REG_MACL); *((uint32_t *) (dp->macaddr + 0)) = ret32; ret32 = VMXNET3_BAR1_GET32(dp, VMXNET3_REG_MACH); *((uint16_t *) (dp->macaddr + 4)) = ret32; /* * Register with the MAC framework */ if (!(macr = mac_alloc(MAC_VERSION))) { VMXNET3_WARN(dp, "mac_alloc() failed.\n"); goto error_regs_map_1; } macr->m_type_ident = MAC_PLUGIN_IDENT_ETHER; macr->m_driver = dp; macr->m_dip = dip; macr->m_instance = 0; macr->m_src_addr = dp->macaddr; macr->m_dst_addr = NULL; macr->m_callbacks = &vmxnet3_mac_callbacks; macr->m_min_sdu = VMXNET3_MIN_MTU; #if defined(SOL9) || defined (SOL10) macr->m_max_sdu = vmxnet3_getprop(dp, "MTU", VMXNET3_MIN_MTU, VMXNET3_MAX_MTU, ETHERMTU); #else macr->m_max_sdu = ETHERMTU; #endif macr->m_pdata = NULL; macr->m_pdata_size = 0; ret = mac_register(macr, &dp->mac); mac_free(macr); if (ret != DDI_SUCCESS) { VMXNET3_WARN(dp, "mac_register() failed\n"); goto error_regs_map_1; } /* * Register the interrupt(s) in this order of preference: * MSI-X, MSI, INTx */ VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_CMD, VMXNET3_CMD_GET_CONF_INTR); ret32 = VMXNET3_BAR1_GET32(dp, VMXNET3_REG_CMD); switch (ret32 & 0x3) { case VMXNET3_IT_AUTO: case VMXNET3_IT_MSIX: dp->intrType = DDI_INTR_TYPE_MSIX; err = ddi_intr_alloc(dip, &dp->intrHandle, dp->intrType, 0, 1, &ret, DDI_INTR_ALLOC_STRICT); if (err == DDI_SUCCESS) break; VMXNET3_DEBUG(dp, 2, "DDI_INTR_TYPE_MSIX failed, err:%d\n", err); case VMXNET3_IT_MSI: dp->intrType = DDI_INTR_TYPE_MSI; if (ddi_intr_alloc(dip, &dp->intrHandle, dp->intrType, 0, 1, &ret, DDI_INTR_ALLOC_STRICT) == DDI_SUCCESS) break; VMXNET3_DEBUG(dp, 2, "DDI_INTR_TYPE_MSI failed\n"); case VMXNET3_IT_INTX: dp->intrType = DDI_INTR_TYPE_FIXED; if (ddi_intr_alloc(dip, &dp->intrHandle, dp->intrType, 0, 1, &ret, DDI_INTR_ALLOC_STRICT) == DDI_SUCCESS) { break; } VMXNET3_DEBUG(dp, 2, "DDI_INTR_TYPE_INTX failed\n"); default: VMXNET3_WARN(dp, "ddi_intr_alloc() failed\n"); goto error_mac; } dp->intrMaskMode = (ret32 >> 2) & 0x3; if (dp->intrMaskMode == VMXNET3_IMM_LAZY) { VMXNET3_WARN(dp, "Lazy masking is not supported\n"); goto error_intr; } if (ddi_intr_get_pri(dp->intrHandle, &uret) != DDI_SUCCESS) { VMXNET3_WARN(dp, "ddi_intr_get_pri() failed\n"); goto error_intr; } VMXNET3_DEBUG(dp, 2, "intrType=0x%x, intrMaskMode=0x%x, intrPrio=%u\n", dp->intrType, dp->intrMaskMode, uret); /* * Create a task queue to reset the device if it wedges. */ dp->resetTask = ddi_taskq_create(dip, "vmxnet3_reset_task", 1, TASKQ_DEFAULTPRI, 0); if (!dp->resetTask) { VMXNET3_WARN(dp, "ddi_taskq_create() failed()\n"); goto error_intr; } /* * Initialize our mutexes now that we know the interrupt priority * This _must_ be done before ddi_intr_enable() */ mutex_init(&dp->intrLock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(uret)); mutex_init(&dp->txLock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(uret)); mutex_init(&dp->rxPoolLock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(uret)); if (ddi_intr_add_handler(dp->intrHandle, vmxnet3_intr, dp, NULL) != DDI_SUCCESS) { VMXNET3_WARN(dp, "ddi_intr_add_handler() failed\n"); goto error_mutexes; } err = ddi_intr_get_cap(dp->intrHandle, &dp->intrCap); if (err != DDI_SUCCESS) { VMXNET3_WARN(dp, "ddi_intr_get_cap() failed %d", err); goto error_intr_handler; } if (dp->intrCap & DDI_INTR_FLAG_BLOCK) { err = ddi_intr_block_enable(&dp->intrHandle, 1); if (err != DDI_SUCCESS) { VMXNET3_WARN(dp, "ddi_intr_block_enable() failed, err:%d\n", err); goto error_intr_handler; } } else { err = ddi_intr_enable(dp->intrHandle); if ((err != DDI_SUCCESS)) { VMXNET3_WARN(dp, "ddi_intr_enable() failed, err:%d\n", err); goto error_intr_handler; } } return DDI_SUCCESS; error_intr_handler: ddi_intr_remove_handler(dp->intrHandle); error_mutexes: mutex_destroy(&dp->rxPoolLock); mutex_destroy(&dp->txLock); mutex_destroy(&dp->intrLock); ddi_taskq_destroy(dp->resetTask); error_intr: ddi_intr_free(dp->intrHandle); error_mac: mac_unregister(dp->mac); error_regs_map_1: ddi_regs_map_free(&dp->bar1Handle); error_regs_map_0: ddi_regs_map_free(&dp->bar0Handle); error_pci_config: pci_config_teardown(&dp->pciHandle); error_soft_state: kmem_free(dp, sizeof(vmxnet3_softc_t)); error: return DDI_FAILURE; } /* *--------------------------------------------------------------------------- * * vmxnet3_detach -- * * Detach a vmxnet3 instance from the stack. * * Results: * DDI_SUCCESS or DDI_FAILURE. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int vmxnet3_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) { vmxnet3_softc_t *dp = ddi_get_driver_private(dip); unsigned int retries = 0; VMXNET3_DEBUG(dp, 1, "detach()\n"); if (cmd != DDI_DETACH) { return DDI_FAILURE; } while (dp->rxNumBufs) { if (retries++ < 10) { VMXNET3_WARN(dp, "rx pending (%u), waiting 1 second...\n", dp->rxNumBufs); delay(drv_usectohz(1000000)); } else { VMXNET3_WARN(dp, "giving up...\n"); return DDI_FAILURE; } } if (dp->intrCap & DDI_INTR_FLAG_BLOCK) { ddi_intr_block_disable(&dp->intrHandle, 1); } else { ddi_intr_disable(dp->intrHandle); } ddi_intr_remove_handler(dp->intrHandle); ddi_intr_free(dp->intrHandle); mac_unregister(dp->mac); if (dp->mfTable.buf) { vmxnet3_free_dma_mem(&dp->mfTable); } mutex_destroy(&dp->rxPoolLock); mutex_destroy(&dp->txLock); mutex_destroy(&dp->intrLock); ddi_taskq_destroy(dp->resetTask); ddi_regs_map_free(&dp->bar1Handle); ddi_regs_map_free(&dp->bar0Handle); pci_config_teardown(&dp->pciHandle); kmem_free(dp, sizeof(vmxnet3_softc_t)); return DDI_SUCCESS; } /* --- */ /* * Structures used by the Solaris module loader */ #define VMXNET3_IDENT "VMware EtherAdapter v3 b" BUILD_NUMBER_NUMERIC_STRING COMPAT_DDI_DEFINE_STREAM_OPS(vmxnet3_dev_ops, nulldev, nulldev, vmxnet3_attach, vmxnet3_detach, nodev, NULL, D_NEW | D_MP, NULL); static struct modldrv vmxnet3_modldrv = { &mod_driverops, /* drv_modops */ VMXNET3_IDENT, /* drv_linkinfo */ &vmxnet3_dev_ops /* drv_dev_ops */ }; static struct modlinkage vmxnet3_modlinkage = { MODREV_1, /* ml_rev */ { &vmxnet3_modldrv, NULL } /* ml_linkage */ }; /* Module load entry point */ int _init(void) { int ret; #ifdef DEBUG cmn_err(CE_CONT, "_init()\n"); #endif mac_init_ops(&vmxnet3_dev_ops, VMXNET3_MODNAME); ret = mod_install(&vmxnet3_modlinkage); if (ret != DDI_SUCCESS) { mac_fini_ops(&vmxnet3_dev_ops); } return ret; } /* Module unload entry point */ int _fini(void) { int ret; #ifdef DEBUG cmn_err(CE_CONT, "_fini()\n"); #endif ret = mod_remove(&vmxnet3_modlinkage); if (ret == DDI_SUCCESS) { mac_fini_ops(&vmxnet3_dev_ops); } return ret; } /* Module info entry point */ int _info(struct modinfo *modinfop) { #ifdef DEBUG cmn_err(CE_CONT, "_info()\n"); #endif return mod_info(&vmxnet3_modlinkage, modinfop); } open-vm-tools-9.4.0-1280544/modules/solaris/vmxnet3/vmxnet3_rx.c0000644765153500003110000003030112220061556022445 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ #include "vmxnet3_solaris.h" static void vmxnet3_put_rxbuf(vmxnet3_rxbuf_t *rxBuf); /* *--------------------------------------------------------------------------- * * vmxnet3_alloc_rxbuf -- * * Allocate a new rxBuf from memory. All its fields are set except * for its associated mblk which has to be allocated later. * * Results: * A new rxBuf or NULL. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static vmxnet3_rxbuf_t * vmxnet3_alloc_rxbuf(vmxnet3_softc_t *dp, boolean_t canSleep) { vmxnet3_rxbuf_t *rxBuf; int flag = canSleep ? KM_SLEEP : KM_NOSLEEP; int err; rxBuf = kmem_zalloc(sizeof(vmxnet3_rxbuf_t), flag); if (!rxBuf) { return NULL; } if ((err = vmxnet3_alloc_dma_mem_1(dp, &rxBuf->dma, (dp->cur_mtu + 18), canSleep)) != DDI_SUCCESS) { VMXNET3_DEBUG(dp, 0, "Failed to allocate %d bytes for rx buf, err:%d.\n", (dp->cur_mtu + 18), err); kmem_free(rxBuf, sizeof(vmxnet3_rxbuf_t)); return NULL; } rxBuf->freeCB.free_func = vmxnet3_put_rxbuf; rxBuf->freeCB.free_arg = (caddr_t) rxBuf; rxBuf->dp = dp; atomic_inc_32(&dp->rxNumBufs); return rxBuf; } /* *--------------------------------------------------------------------------- * * vmxnet3_free_rxbuf -- * * Free a rxBuf. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static void vmxnet3_free_rxbuf(vmxnet3_softc_t *dp, vmxnet3_rxbuf_t *rxBuf) { vmxnet3_free_dma_mem(&rxBuf->dma); kmem_free(rxBuf, sizeof(vmxnet3_rxbuf_t)); #ifndef DEBUG atomic_dec_32(&dp->rxNumBufs); #else { uint32_t nv = atomic_dec_32_nv(&dp->rxNumBufs); ASSERT(nv != -1); } #endif } /* *--------------------------------------------------------------------------- * * vmxnet3_put_rxbuf -- * * Return a rxBuf to the pool or free it. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static void vmxnet3_put_rxbuf(vmxnet3_rxbuf_t *rxBuf) { vmxnet3_softc_t *dp = rxBuf->dp; vmxnet3_rxpool_t *rxPool = &dp->rxPool; VMXNET3_DEBUG(dp, 5, "free 0x%p\n", rxBuf); mutex_enter(&dp->rxPoolLock); if (dp->devEnabled && rxPool->nBufs < rxPool->nBufsLimit) { rxBuf->next = rxPool->listHead; rxPool->listHead = rxBuf; mutex_exit(&dp->rxPoolLock); } else { mutex_exit(&dp->rxPoolLock); vmxnet3_free_rxbuf(dp, rxBuf); } } /* *--------------------------------------------------------------------------- * * vmxnet3_get_rxbuf -- * * Get an unused rxBuf from either the pool or from memory. * The returned rxBuf has a mblk associated with it. * * Results: * A rxBuf or NULL. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static vmxnet3_rxbuf_t * vmxnet3_get_rxbuf(vmxnet3_softc_t *dp, boolean_t canSleep) { vmxnet3_rxbuf_t *rxBuf; vmxnet3_rxpool_t *rxPool = &dp->rxPool; mutex_enter(&dp->rxPoolLock); if (rxPool->listHead) { rxBuf = rxPool->listHead; rxPool->listHead = rxBuf->next; mutex_exit(&dp->rxPoolLock); VMXNET3_DEBUG(dp, 5, "alloc 0x%p from pool\n", rxBuf); } else { mutex_exit(&dp->rxPoolLock); rxBuf = vmxnet3_alloc_rxbuf(dp, canSleep); if (!rxBuf) { goto done; } VMXNET3_DEBUG(dp, 5, "alloc 0x%p from mem\n", rxBuf); } ASSERT(rxBuf); rxBuf->mblk = desballoc((uchar_t *) rxBuf->dma.buf, rxBuf->dma.bufLen, BPRI_MED, &rxBuf->freeCB); if (!rxBuf->mblk) { vmxnet3_put_rxbuf(rxBuf); rxBuf = NULL; } done: return rxBuf; } /* *--------------------------------------------------------------------------- * * vmxnet3_rx_populate -- * * Populate a Rx descriptor with a new rxBuf. * * Results: * DDI_SUCCESS or DDI_FAILURE. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int vmxnet3_rx_populate(vmxnet3_softc_t *dp, vmxnet3_rxqueue_t *rxq, uint16_t idx, boolean_t canSleep) { int ret = DDI_SUCCESS; vmxnet3_rxbuf_t *rxBuf = vmxnet3_get_rxbuf(dp, canSleep); if (rxBuf) { vmxnet3_cmdring_t *cmdRing = &rxq->cmdRing; Vmxnet3_GenericDesc *rxDesc = VMXNET3_GET_DESC(cmdRing, idx);; rxq->bufRing[idx].rxBuf = rxBuf; rxDesc->rxd.addr = rxBuf->dma.bufPA; rxDesc->rxd.len = rxBuf->dma.bufLen; // rxDesc->rxd.btype = 0; membar_producer(); rxDesc->rxd.gen = cmdRing->gen; } else { ret = DDI_FAILURE; } return ret; } /* *--------------------------------------------------------------------------- * * vmxnet3_rxqueue_init -- * * Initialize a RxQueue by populating the whole Rx ring with rxBufs. * * Results: * DDI_SUCCESS or DDI_FAILURE. * * Side effects: * None. * *--------------------------------------------------------------------------- */ int vmxnet3_rxqueue_init(vmxnet3_softc_t *dp, vmxnet3_rxqueue_t *rxq) { vmxnet3_cmdring_t *cmdRing = &rxq->cmdRing; do { if (vmxnet3_rx_populate(dp, rxq, cmdRing->next2fill, B_TRUE) != DDI_SUCCESS) { goto error; } VMXNET3_INC_RING_IDX(cmdRing, cmdRing->next2fill); } while (cmdRing->next2fill); dp->rxPool.nBufsLimit = vmxnet3_getprop(dp, "RxBufPoolLimit", 0, cmdRing->size * 10, cmdRing->size * 2); return DDI_SUCCESS; error: while (cmdRing->next2fill) { VMXNET3_DEC_RING_IDX(cmdRing, cmdRing->next2fill); vmxnet3_free_rxbuf(dp, rxq->bufRing[cmdRing->next2fill].rxBuf); } return DDI_FAILURE; } /* *--------------------------------------------------------------------------- * * vmxnet3_rxqueue_fini -- * * Finish a RxQueue by freeing all the related rxBufs. * * Results: * DDI_SUCCESS. * * Side effects: * None. * *--------------------------------------------------------------------------- */ void vmxnet3_rxqueue_fini(vmxnet3_softc_t *dp, vmxnet3_rxqueue_t *rxq) { vmxnet3_rxpool_t *rxPool = &dp->rxPool; vmxnet3_rxbuf_t *rxBuf; unsigned int i; ASSERT(!dp->devEnabled); /* First the rxPool */ while (rxPool->listHead) { rxBuf = rxPool->listHead; rxPool->listHead = rxBuf->next; vmxnet3_free_rxbuf(dp, rxBuf); } /* Then the ring */ for (i = 0; i < rxq->cmdRing.size; i++) { rxBuf = rxq->bufRing[i].rxBuf; ASSERT(rxBuf); ASSERT(rxBuf->mblk); /* * Here, freemsg() will trigger a call to vmxnet3_put_rxbuf() which * will then call vmxnet3_free_rxbuf() because the underlying * device is disabled. */ freemsg(rxBuf->mblk); } } /* *--------------------------------------------------------------------------- * * vmxnet3_rx_hwcksum -- * * Determine if a received packet was checksummed by the Vmxnet3 * device and tag the mp appropriately. * * Results: * None. * * Side effects: * The mp may get tagged. * *--------------------------------------------------------------------------- */ static void vmxnet3_rx_hwcksum(vmxnet3_softc_t *dp, mblk_t *mp, Vmxnet3_GenericDesc *compDesc) { uint32_t flags = 0; if (!compDesc->rcd.cnc) { if (compDesc->rcd.v4 && compDesc->rcd.ipc) { flags |= HCK_IPV4_HDRCKSUM; if ((compDesc->rcd.tcp || compDesc->rcd.udp) && compDesc->rcd.tuc) { flags |= HCK_FULLCKSUM | HCK_FULLCKSUM_OK; } } VMXNET3_DEBUG(dp, 3, "rx cksum flags = 0x%x\n", flags); hcksum_assoc(mp, NULL, NULL, 0, 0, 0, 0, flags, 0); } } /* *--------------------------------------------------------------------------- * * vmxnet3_rx_intr -- * * Interrupt handler for Rx. Look if there are any pending Rx and * put them in mplist. * * Results: * A list of messages to pass to the MAC subystem. * * Side effects: * None. * *--------------------------------------------------------------------------- */ mblk_t * vmxnet3_rx_intr(vmxnet3_softc_t *dp, vmxnet3_rxqueue_t *rxq) { vmxnet3_compring_t *compRing = &rxq->compRing; vmxnet3_cmdring_t *cmdRing = &rxq->cmdRing; Vmxnet3_RxQueueCtrl *rxqCtrl = rxq->sharedCtrl; Vmxnet3_GenericDesc *compDesc; mblk_t *mplist = NULL, **mplistTail = &mplist; ASSERT(mutex_owned(&dp->intrLock)); compDesc = VMXNET3_GET_DESC(compRing, compRing->next2comp); while (compDesc->rcd.gen == compRing->gen) { mblk_t *mp = NULL, **mpTail = ∓ boolean_t mpValid = B_TRUE; boolean_t eop; ASSERT(compDesc->rcd.sop); do { uint16_t rxdIdx = compDesc->rcd.rxdIdx; vmxnet3_rxbuf_t *rxBuf = rxq->bufRing[rxdIdx].rxBuf; mblk_t *mblk = rxBuf->mblk; Vmxnet3_GenericDesc *rxDesc; while (compDesc->rcd.gen != compRing->gen) { /* * H/W may be still be in the middle of generating this entry, * so hold on until the gen bit is flipped. */ membar_consumer(); } ASSERT(compDesc->rcd.gen == compRing->gen); ASSERT(rxBuf); ASSERT(mblk); /* Some Rx descriptors may have been skipped */ while (cmdRing->next2fill != rxdIdx) { rxDesc = VMXNET3_GET_DESC(cmdRing, cmdRing->next2fill); rxDesc->rxd.gen = cmdRing->gen; VMXNET3_INC_RING_IDX(cmdRing, cmdRing->next2fill); } eop = compDesc->rcd.eop; /* * Now we have a piece of the packet in the rxdIdx descriptor. * Grab it only if we achieve to replace it with a fresh buffer. */ if (vmxnet3_rx_populate(dp, rxq, rxdIdx, B_FALSE) == DDI_SUCCESS) { /* Success, we can chain the mblk with the mp */ mblk->b_wptr = mblk->b_rptr + compDesc->rcd.len; *mpTail = mblk; mpTail = &mblk->b_cont; ASSERT(*mpTail == NULL); VMXNET3_DEBUG(dp, 3, "rx 0x%p on [%u]\n", mblk, rxdIdx); if (eop) { if (!compDesc->rcd.err) { /* Tag the mp if it was checksummed by the H/W */ vmxnet3_rx_hwcksum(dp, mp, compDesc); } else { mpValid = B_FALSE; } } } else { /* Keep the same buffer, we still need to flip the gen bit */ rxDesc = VMXNET3_GET_DESC(cmdRing, rxdIdx); rxDesc->rxd.gen = cmdRing->gen; mpValid = B_FALSE; } VMXNET3_INC_RING_IDX(compRing, compRing->next2comp); VMXNET3_INC_RING_IDX(cmdRing, cmdRing->next2fill); compDesc = VMXNET3_GET_DESC(compRing, compRing->next2comp); } while (!eop); if (mp) { if (mpValid) { *mplistTail = mp; mplistTail = &mp->b_next; ASSERT(*mplistTail == NULL); } else { /* This message got holes, drop it */ freemsg(mp); } } } if (rxqCtrl->updateRxProd) { uint32_t rxprod; /* * All buffers are actually available, but we can't tell that to * the device because it may interpret that as an empty ring. * So skip one buffer. */ if (cmdRing->next2fill) { rxprod = cmdRing->next2fill - 1; } else { rxprod = cmdRing->size - 1; } VMXNET3_BAR0_PUT32(dp, VMXNET3_REG_RXPROD, rxprod); } return mplist; } open-vm-tools-9.4.0-1280544/modules/solaris/vmxnet3/vmxnet3_solaris_compat.h0000644765153500003110000000304312220061556025043 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ #ifndef _VMXNET3_SOLARIS_COMPAT_H_ #define _VMXNET3_SOLARIS_COMPAT_H_ /* * In this file are stored all the definitions/helpers that the * DDI/DDK provides but that our toolchain currently lacks. * Nuke them the day the toolchain is refreshed. */ #define DDI_INTR_PRI(pri) (void *)((uintptr_t)(pri)) /* OPEN_SOLARIS and SOLARIS 11 */ #if defined(OPEN_SOLARIS) || defined(SOL11) #define COMPAT_DDI_DEFINE_STREAM_OPS(XXname, XXidentify, XXprobe, XXattach, XXdetach, XXreset, XXgetinfo, XXflag, XXstream_tab) \ DDI_DEFINE_STREAM_OPS(XXname, XXidentify, XXprobe, XXattach, XXdetach, \ XXreset, XXgetinfo, XXflag, XXstream_tab, ddi_quiesce_not_supported) #else /* All other Solari */ #define LSO_TX_BASIC_TCP_IPV4 0x02 #define COMPAT_DDI_DEFINE_STREAM_OPS DDI_DEFINE_STREAM_OPS #endif #define HW_LSO 0x10 #define DB_LSOMSS(mp) ((mp)->b_datap->db_struioun.cksum.pad) #define ETHERTYPE_VLAN (0x8100) #endif /* _VMXNET3_SOLARIS_COMPAT_H_ */ open-vm-tools-9.4.0-1280544/modules/solaris/vmxnet3/COPYING0000644765153500003110000004331212220061556021225 0ustar dtormts COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 1. Definitions. 1.1. "Contributor" means each individual or entity that creates or contributes to the creation of Modifications. 1.2. "Contributor Version" means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor. 1.3. "Covered Software" means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof. 1.4. "Executable" means the Covered Software in any form other than Source Code. 1.5. "Initial Developer" means the individual or entity that first makes Original Software available under this License. 1.6. "Larger Work" means a work which combines Covered Software or portions thereof with code not governed by the terms of this License. 1.7. "License" means this document. 1.8. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. 1.9. "Modifications" means the Source Code and Executable form of any of the following: A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications; B. Any new file that contains any part of the Original Software or previous Modifications; or C. Any new file that is contributed or otherwise made available under the terms of this License. 1.10. "Original Software" means the Source Code and Executable form of computer software code that is originally released under this License. 1.11. "Patent Claims" means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. 1.12. "Source Code" means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code. 1.13. "You" (or "Your") means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants. 2.1. The Initial Developer Grant. Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license: (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof). (c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License. (d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices. 2.2. Contributor Grant. Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes or otherwise makes the Modifications available to a third party. (d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Contributor. 3. Distribution Obligations. 3.1. Availability of Source Code. Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used for software exchange. 3.2. Modifications. The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License. 3.3. Required Notices. You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer. 3.4. Application of Additional Terms. You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients' rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. 3.5. Distribution of Executable Versions. You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipient's rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable form under a different license, You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. 3.6. Larger Works. You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software. 4. Versions of the License. 4.1. New Versions. Sun Microsystems, Inc. is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License. 4.2. Effect of New Versions. You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. Otherwise, You may also choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version of the License published by the license steward. 4.3. Modified Versions. When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License. 5. DISCLAIMER OF WARRANTY. COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. 6. TERMINATION. 6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. 6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as "Participant") alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant, the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement with Participant. 6.3. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination. 7. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. 8. U.S. GOVERNMENT END USERS. The Covered Software is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" (as that term is defined at 48 C.F.R. 252.227-7014(a)(1)) and "commercial computer software documentation" as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License. 9. MISCELLANEOUS. This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdiction's conflict-of-law provisions. Any litigation relating to this License shall be subject to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the losing party responsible for costs, including, without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use, distribute or otherwise make available any Covered Software. 10. RESPONSIBILITY FOR CLAIMS. As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. open-vm-tools-9.4.0-1280544/modules/solaris/vmxnet3/vmxnet3_solaris.h0000644765153500003110000001765212220061556023513 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ #ifndef _VMXNET3_SOLARIS_H_ #define _VMXNET3_SOLARIS_H_ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(OPEN_SOLARIS) || defined(SOL11) # include #endif #include #include #include #include #include "vm_basic_types.h" #include "vm_device_version.h" #include "buildNumber.h" #include "vmxnet3_defs.h" #include "vmxnet3_solaris_compat.h" typedef struct vmxnet3_dmabuf_t { caddr_t buf; uint64_t bufPA; size_t bufLen; ddi_dma_handle_t dmaHandle; ddi_acc_handle_t dataHandle; } vmxnet3_dmabuf_t; typedef struct vmxnet3_cmdring_t { vmxnet3_dmabuf_t dma; uint16_t size; uint16_t next2fill; uint16_t avail; uint8_t gen; } vmxnet3_cmdring_t; typedef struct vmxnet3_compring_t { vmxnet3_dmabuf_t dma; uint16_t size; uint16_t next2comp; uint8_t gen; } vmxnet3_compring_t; typedef struct vmxnet3_metatx_t { mblk_t *mp; uint16_t sopIdx; uint16_t frags; } vmxnet3_metatx_t; typedef struct vmxnet3_txqueue_t { vmxnet3_cmdring_t cmdRing; vmxnet3_compring_t compRing; vmxnet3_metatx_t *metaRing; Vmxnet3_TxQueueCtrl *sharedCtrl; } vmxnet3_txqueue_t; typedef struct vmxnet3_rxbuf_t { vmxnet3_dmabuf_t dma; mblk_t *mblk; frtn_t freeCB; struct vmxnet3_softc_t *dp; struct vmxnet3_rxbuf_t *next; } vmxnet3_rxbuf_t; typedef struct vmxnet3_bufdesc_t { vmxnet3_rxbuf_t *rxBuf; } vmxnet3_bufdesc_t; typedef struct vmxnet3_rxpool_t { vmxnet3_rxbuf_t *listHead; unsigned int nBufs; unsigned int nBufsLimit; } vmxnet3_rxpool_t; typedef struct vmxnet3_rxqueue_t { vmxnet3_cmdring_t cmdRing; vmxnet3_compring_t compRing; vmxnet3_bufdesc_t *bufRing; Vmxnet3_RxQueueCtrl *sharedCtrl; } vmxnet3_rxqueue_t; typedef struct vmxnet3_softc_t { dev_info_t *dip; int instance; mac_handle_t mac; ddi_acc_handle_t pciHandle; ddi_acc_handle_t bar0Handle, bar1Handle; caddr_t bar0, bar1; boolean_t devEnabled; uint8_t macaddr[6]; uint32_t cur_mtu; uint8_t allow_jumbo; link_state_t linkState; uint64_t linkSpeed; vmxnet3_dmabuf_t sharedData; vmxnet3_dmabuf_t queueDescs; kmutex_t intrLock; int intrType; int intrMaskMode; int intrCap; ddi_intr_handle_t intrHandle; ddi_taskq_t *resetTask; kmutex_t txLock; vmxnet3_txqueue_t txQueue; ddi_dma_handle_t txDmaHandle; boolean_t txMustResched; vmxnet3_rxqueue_t rxQueue; kmutex_t rxPoolLock; vmxnet3_rxpool_t rxPool; volatile uint32_t rxNumBufs; uint32_t rxMode; vmxnet3_dmabuf_t mfTable; } vmxnet3_softc_t; int vmxnet3_alloc_dma_mem_1(vmxnet3_softc_t *dp, vmxnet3_dmabuf_t *dma, size_t size, boolean_t canSleep); int vmxnet3_alloc_dma_mem_128(vmxnet3_softc_t *dp, vmxnet3_dmabuf_t *dma, size_t size, boolean_t canSleep); int vmxnet3_alloc_dma_mem_512(vmxnet3_softc_t *dp, vmxnet3_dmabuf_t *dma, size_t size, boolean_t canSleep); void vmxnet3_free_dma_mem(vmxnet3_dmabuf_t *dma); int vmxnet3_getprop(vmxnet3_softc_t *dp, char *name, int min, int max, int def); int vmxnet3_txqueue_init(vmxnet3_softc_t *dp, vmxnet3_txqueue_t *txq); mblk_t *vmxnet3_tx(void *data, mblk_t *mps); boolean_t vmxnet3_tx_complete(vmxnet3_softc_t *dp, vmxnet3_txqueue_t *txq); void vmxnet3_txqueue_fini(vmxnet3_softc_t *dp, vmxnet3_txqueue_t *txq); int vmxnet3_rxqueue_init(vmxnet3_softc_t *dp, vmxnet3_rxqueue_t *rxq); mblk_t *vmxnet3_rx_intr(vmxnet3_softc_t *dp, vmxnet3_rxqueue_t *rxq); void vmxnet3_rxqueue_fini(vmxnet3_softc_t *dp, vmxnet3_rxqueue_t *rxq); extern ddi_device_acc_attr_t vmxnet3_dev_attr; #define VMXNET3_MODNAME "vmxnet3s" /* Logging stuff */ #define VMXNET3_LOG(Level, Device, Format, Args...) \ cmn_err(Level, VMXNET3_MODNAME ":%d: " Format, \ Device->instance, ##Args); #define VMXNET3_WARN(Device, Format, Args...) \ VMXNET3_LOG(CE_WARN, Device, Format, ##Args) #define VMXNET3_DEBUG_LEVEL 2 #ifdef VMXNET3_DEBUG_LEVEL #define VMXNET3_DEBUG(Device, Level, Format, Args...) \ do { \ if (Level <= VMXNET3_DEBUG_LEVEL) { \ VMXNET3_LOG(CE_CONT, Device, Format, ##Args) \ } \ } while (0) #else #define VMXNET3_DEBUG(Device, Level, Format, Args...) #endif #define MACADDR_FMT "%02x:%02x:%02x:%02x:%02x:%02x" #define MACADDR_FMT_ARGS(mac) \ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] /* Default ring size */ #define VMXNET3_DEF_TX_RING_SIZE 256 #define VMXNET3_DEF_RX_RING_SIZE 256 /* Register access helpers */ #define VMXNET3_BAR0_GET32(Device, Reg) \ ddi_get32((Device)->bar0Handle, (uint32_t *) ((Device)->bar0 + (Reg))) #define VMXNET3_BAR0_PUT32(Device, Reg, Value) \ ddi_put32((Device)->bar0Handle, (uint32_t *) ((Device)->bar0 + (Reg)), (Value)) #define VMXNET3_BAR1_GET32(Device, Reg) \ ddi_get32((Device)->bar1Handle, (uint32_t *) ((Device)->bar1 + (Reg))) #define VMXNET3_BAR1_PUT32(Device, Reg, Value) \ ddi_put32((Device)->bar1Handle, (uint32_t *) ((Device)->bar1 + (Reg)), (Value)) /* Misc helpers */ #define VMXNET3_DS(Device) \ ((Vmxnet3_DriverShared *) (Device)->sharedData.buf) #define VMXNET3_TQDESC(Device) \ ((Vmxnet3_TxQueueDesc *) (Device)->queueDescs.buf) #define VMXNET3_RQDESC(Device) \ ((Vmxnet3_RxQueueDesc *) ((Device)->queueDescs.buf + sizeof(Vmxnet3_TxQueueDesc))) #define VMXNET3_ADDR_LO(addr) ((uint32_t) (addr)) #define VMXNET3_ADDR_HI(addr) ((uint32_t) (((uint64_t) (addr)) >> 32)) #define VMXNET3_GET_DESC(Ring, Idx) \ (((Vmxnet3_GenericDesc *) (Ring)->dma.buf) + Idx) /* Rings handling */ #define VMXNET3_INC_RING_IDX(Ring, Idx) \ do { \ (Idx)++; \ if ((Idx) == (Ring)->size) { \ (Idx) = 0; \ (Ring)->gen ^= 1; \ } \ } while (0) #define VMXNET3_DEC_RING_IDX(Ring, Idx) \ do { \ if ((Idx) == 0) { \ (Idx) = (Ring)->size; \ (Ring)->gen ^= 1; \ } \ (Idx)--; \ } while (0) #endif /* _VMXNET3_SOLARIS_H_ */ open-vm-tools-9.4.0-1280544/modules/solaris/vmxnet3/Makefile0000644765153500003110000000545412220061556021637 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 2009 VMware, Inc. All rights reserved. # # The contents of this file are subject to the terms of the Common # Development and Distribution License (the "License") version 1.0 # and no later version. You may not use this file except in # compliance with the License. # # You can obtain a copy of the License at # http://www.opensource.org/licenses/cddl1.php # # See the License for the specific language governing permissions # and limitations under the License. # ########################################################## ifneq ($(shell echo "$(VM_UNAME)" | cut -c-4),5.10) SUPPORTED := 1 endif ifneq ($(shell echo "$(VM_UNAME)" | cut -c-4),5.11) SUPPORTED := 1 endif $(if $(SUPPORTED),,$(error "Unsupported Solaris version: $(VM_UNAME)")) ## ## General build locations and variables ## MODULE := vmxnet3 CFLAGS := LDFLAGS := CFLAGS += -O2 CFLAGS += -Wall -Werror -Wno-unknown-pragmas CFLAGS += -U_NO_LONGLONG CFLAGS += -D_KERNEL CFLAGS += -I../../../lib/include # for buildNumber.h CFLAGS += -ffreestanding CFLAGS += -nodefaultlibs ifdef OVT_SOURCE_DIR CFLAGS += -I$(OVT_SOURCE_DIR)/lib/include CFLAGS += -I$(OVT_SOURCE_DIR)/modules/shared/vmxnet endif CFLAGS_32 := $(CFLAGS) CFLAGS_32 += -m32 LDFLAGS_32 := $(LDFLAGS) CFLAGS_64 := $(CFLAGS) CFLAGS_64 += -m64 CFLAGS_64 += -mcmodel=kernel CFLAGS_64 += -mno-red-zone LDFLAGS_64 := $(LDFLAGS) ifdef HAVE_GNU_LD LDFLAGS_64 += -m elf_x86_64 else LDFLAGS_64 += -64 endif ## ## Objects needed to build the HGFS kernel module ## VMXNET3_OBJS := vmxnet3_main.o VMXNET3_OBJS += vmxnet3_utils.o VMXNET3_OBJS += vmxnet3_tx.o VMXNET3_OBJS += vmxnet3_rx.o VMXNET3_32_OBJS := $(addprefix i386/, $(VMXNET3_OBJS)) VMXNET3_64_OBJS := $(addprefix amd64/, $(VMXNET3_OBJS)) MODULE_32 := i386/$(MODULE) MODULE_64 := amd64/$(MODULE) all: prepare_dirs $(MODULE_32) $(MODULE_64) prepare_dirs: @echo "Creating build directories" mkdir -p i386 mkdir -p amd64 $(MODULE_32): $(VMXNET3_32_OBJS) @echo "Linking $@" $(LD) $(LDFLAGS_32) -r $(VMXNET3_32_OBJS) -o $@ $(VMXNET3_32_OBJS): i386/%.o: %.c @echo "Compiling $(dip, dma_attrs, cb, NULL, &dma->dmaHandle) != DDI_SUCCESS) { VMXNET3_WARN(dp, "ddi_dma_alloc_handle() failed\n"); goto error; } /* * Allocate memory */ if (ddi_dma_mem_alloc(dma->dmaHandle, size, &vmxnet3_dev_attr, DDI_DMA_CONSISTENT, cb, NULL, &dma->buf, &dma->bufLen, &dma->dataHandle) != DDI_SUCCESS) { VMXNET3_WARN(dp, "ddi_dma_mem_alloc() failed\n"); goto error_dma_handle; } /* * Map the memory */ if (ddi_dma_addr_bind_handle(dma->dmaHandle, NULL, dma->buf, dma->bufLen, DDI_DMA_RDWR | DDI_DMA_STREAMING, cb, NULL, &cookie, &cookieCount) != DDI_DMA_MAPPED) { VMXNET3_WARN(dp, "ddi_dma_addr_bind_handle() failed\n"); goto error_dma_mem; } ASSERT(cookieCount == 1); dma->bufPA = cookie.dmac_laddress; return DDI_SUCCESS; error_dma_mem: ddi_dma_mem_free(&dma->dataHandle); error_dma_handle: ddi_dma_free_handle(&dma->dmaHandle); error: dma->buf = NULL; dma->bufPA = NULL; dma->bufLen = 0; return DDI_FAILURE; } int vmxnet3_alloc_dma_mem_1(vmxnet3_softc_t *dp, vmxnet3_dmabuf_t *dma, size_t size, boolean_t canSleep) { return vmxnet3_alloc_dma_mem(dp, dma, size, canSleep, &vmxnet3_dma_attrs_1); } int vmxnet3_alloc_dma_mem_512(vmxnet3_softc_t *dp, vmxnet3_dmabuf_t *dma, size_t size, boolean_t canSleep) { return vmxnet3_alloc_dma_mem(dp, dma, size, canSleep, &vmxnet3_dma_attrs_512); } int vmxnet3_alloc_dma_mem_128(vmxnet3_softc_t *dp, vmxnet3_dmabuf_t *dma, size_t size, boolean_t canSleep) { return vmxnet3_alloc_dma_mem(dp, dma, size, canSleep, &vmxnet3_dma_attrs_128); } /* *--------------------------------------------------------------------------- * * vmxnet3_free_dma_mem -- * * Free DMA-ble memory. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ void vmxnet3_free_dma_mem(vmxnet3_dmabuf_t *dma) { ddi_dma_unbind_handle(dma->dmaHandle); ddi_dma_mem_free(&dma->dataHandle); ddi_dma_free_handle(&dma->dmaHandle); dma->buf = NULL; dma->bufPA = NULL; dma->bufLen = 0; } /* *--------------------------------------------------------------------------- * * vmxnet3_getprop -- * * Get the numeric value of the property "name" in vmxnet3s.conf for * the corresponding device instance. * If the property isn't found or if it doesn't satisfy the conditions, * "def" is returned. * * Results: * The value of the property or "def". * * Side effects: * None. * *--------------------------------------------------------------------------- */ int vmxnet3_getprop(vmxnet3_softc_t *dp, char *name, int min, int max, int def) { int ret = def; int *props; uint_t nprops; if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dp->dip, DDI_PROP_DONTPASS, name, &props, &nprops) == DDI_PROP_SUCCESS) { if (dp->instance < nprops) { ret = props[dp->instance]; } else { VMXNET3_WARN(dp, "property %s not available for this device\n", name); } ddi_prop_free(props); } if (ret < min || ret > max) { ASSERT(def >= min && def <= max); VMXNET3_WARN(dp, "property %s invalid (%d <= %d <= %d)\n", name, min, ret, max); ret = def; } VMXNET3_DEBUG(dp, 2, "getprop(%s) -> %d\n", name, ret); return ret; } open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/0000755765153500003110000000000012220061556020055 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/hgfsBdGlue.h0000644765153500003110000000162712220061556022246 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * bdhandler.h -- * * Glue for backdoor library. */ #ifndef _HGFS_BD_GLUE_H_ #define _HGFS_BD_GLUE_H_ int HgfsBackdoorSendRequest(HgfsReq *req); void HgfsBackdoorCancelRequest(HgfsReq *req); Bool HgfsBackdoorInit(void); void HgfsBackdoorCleanup(void); #endif // _HGFS_DRIVER_BDHANDLER_H_ open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/module.h0000644765153500003110000000342412220061556021516 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * module.h -- * * EXTERNs needed by structures in module.c */ #ifndef __MODULE_H_ #define __MODULE_H_ #include "filesystem.h" /* * Filesystem EXTERNs */ /* Filesystem initialization routine (see filesystem.c) */ #if HGFS_VFS_VERSION == 2 EXTERN int HgfsInit(struct vfssw *vfsswp, int fstype); #else EXTERN int HgfsInit(int, char *); #endif /* Functions for the vfsops structure (see filesystem.c) */ EXTERN int HgfsMount(struct vfs *vfsp, struct vnode *vnodep, struct mounta *mntp, struct cred *credp); EXTERN int HgfsUnmount(struct vfs *vfsp, int mflag, struct cred *credp); EXTERN int HgfsRoot(struct vfs *vfsp, struct vnode **vnodepp); EXTERN int HgfsStatvfs(struct vfs *vfsp, struct statvfs64 *stats); EXTERN int HgfsSync(struct vfs* vfsp, short flags, struct cred *credp); EXTERN int HgfsVget(struct vfs *vfsp, struct vnode **vnodepp, struct fid *fidp); EXTERN int HgfsMountroot(struct vfs *vfsp, enum whymountroot reason); EXTERN int HgfsReserved(struct vfs *vfsp, struct vnode **vnodepp, char * /* ?? */); EXTERN void HgfsFreevfs(struct vfs *vfsp); /* Struct needed in struct modlfs */ EXTERN struct mod_ops mod_fsops; #endif /* __MODULE_H_ */ open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/hgfsState.h0000644765153500003110000001433012220061556022157 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * hgfsState.h -- * * Public functions, types, and macros for Hgfs state that is attached to * vnodes. */ #ifndef __HGFS_STATE_H_ #define __HGFS_STATE_H_ /* * Includes */ #include /* MAXPATHLEN */ #include /* krwlock_t */ #include /* kmutex_t */ #include /* struct vnode */ #include "hgfsProto.h" #include "dbllnklst.h" /* * Macros */ /* Number of buckets for the HgfsInode hash table */ #define HGFS_HT_NR_BUCKETS 5 /* Conversion between different state structures */ #define HGFS_VP_TO_OFP(vp) ((HgfsOpenFile *)(vp)->v_data) #define HGFS_VP_TO_FP(vp) ((HgfsFile *)(HGFS_VP_TO_OFP(vp))->hgfsFile) #define HGFS_OFP_TO_VP(ofp) (ofp)->vnodep #define HGFS_VP_TO_FILENAME(vp) \ HGFS_VP_TO_FP(vp)->fileName #define HGFS_VP_TO_FILENAME_LENGTH(vp) \ HGFS_VP_TO_FP(vp)->fileNameLength #define HGFS_VP_TO_NODEID(vp) \ HGFS_VP_TO_FP(vp)->nodeId #define HGFS_VP_TO_RWLOCK(vp) \ HGFS_VP_TO_FP(vp)->rwlock #define HGFS_VP_TO_RWLOCKP(vp) &(HGFS_VP_TO_RWLOCK(vp)) #define HGFS_VP_TO_HGFSFILETYPE(vp) \ HGFS_VP_TO_FP(vp)->fileType /* * This macro is used for sanity checking the fact that Solaris won't ever call * one of our vnode operations without first calling lookup(), which is the * place where we acquire the filename. I have never seen a function fail * because of this, so it is likely that we can kill this macro and the checks * on it throughout vnode.c. */ #define HGFS_KNOW_FILENAME(vp) \ ( \ vp && \ HGFS_VP_TO_FP(vp) && \ HGFS_VP_TO_FP(vp)->fileName[0] != '\0' \ ) /* * Types */ typedef uint32_t HgfsMode; /* * State kept per shared file from the host. * * All fields are read-only after initialization except reference count, which * is protected by the mutex. */ typedef struct HgfsFile { /* Link to place this state on the file state hash table */ DblLnkLst_Links listNode; /* * Full path of file within the filesystem (that is, taking /mnt/hgfs as /). * These are built from / in HgfsMount() and appending names as provided to * HgfsLookup(). Saving the length in HgfsIget() saves having to calculate * it in each HgfsMakeFullName(). */ char fileName[MAXPATHLEN + 1]; uint32_t fileNameLength; ino64_t nodeId; /* * The file type is saved so additional per-open-file vnodes can be * recreated from a Hgfs file without sending a request to the Hgfs server. */ HgfsFileType fileType; /* * Readers/writers lock for this file. Needed by rwlock() and rwunlock() * entry points. */ krwlock_t rwlock; /* Lock to protect the reference count of this file state. */ kmutex_t mutex; uint32_t refCount; } HgfsFile; /* * State kept per vnode, which implies per open file within a process. * * Once created, the hgfsFile and vnode/vnodep values are read-only. The * handle and mode will change throughout this structure's existence, and are * both protected by their own mutex. */ typedef struct HgfsOpenFile { /* Handle provided by reply to a request */ HgfsHandle handle; Bool handleIsSet; kmutex_t handleMutex; /* * Mode specified for this file to be created with. This is necessary * because create is called with the mode then open is called without it. * We save this value in create and access it in open. */ HgfsMode mode; Bool modeIsSet; kmutex_t modeMutex; /* * Pointer to the single Hgfs file state structure shared amongst all open * instances of this file. */ HgfsFile *hgfsFile; /* * A pointer back to the vnode this open-file state is for. */ struct vnode *vnodep; } HgfsOpenFile; /* The hash table for file state. */ typedef struct HgfsFileHashTable { kmutex_t mutex; DblLnkLst_Links hashTable[HGFS_HT_NR_BUCKETS]; } HgfsFileHashTable; /* Forward declaration to prevent circular dependency between this and hgfs.h. */ struct HgfsSuperInfo; /* * Functions */ int HgfsVnodeGet(struct vnode **vpp, struct HgfsSuperInfo *sip, struct vfs *vfsp, const char *fileName, HgfsFileType fileType, HgfsFileHashTable *htp); int HgfsVnodePut(struct vnode *vp, HgfsFileHashTable *ht); int HgfsVnodeDup(struct vnode **newVpp, struct vnode *origVp, struct HgfsSuperInfo *sip, HgfsFileHashTable *htp); int HgfsFileNameToVnode(const char *fileName, struct vnode **vpp, struct HgfsSuperInfo *sip, struct vfs *vfsp, HgfsFileHashTable *htp); void HgfsNodeIdGet(HgfsFileHashTable *ht, const char *fileName, uint32_t fileNameLength, ino64_t *outNodeId); void HgfsInitFileHashTable(HgfsFileHashTable *htp); Bool HgfsFileHashTableIsEmpty(struct HgfsSuperInfo *sip, HgfsFileHashTable *htp); /* Handle get/set/clear functions */ int HgfsSetOpenFileHandle(struct vnode *vp, HgfsHandle handle); int HgfsGetOpenFileHandle(struct vnode *vp, HgfsHandle *outHandle); int HgfsClearOpenFileHandle(struct vnode *vp); Bool HgfsHandleIsSet(struct vnode *vp); /* Mode get/set/clear functions */ int HgfsSetOpenFileMode(struct vnode *vp, HgfsMode mode); int HgfsGetOpenFileMode(struct vnode *vp, HgfsMode *outMode); int HgfsClearOpenFileMode(struct vnode *vp); /* Debugging function */ void HgfsDebugPrintFileHashTable(HgfsFileHashTable *htp, int level); #endif /* __HGFS_STATE_H_ */ open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/kernelStubsSolaris.c0000644765153500003110000002071112220061556024060 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * kernelStubsSolaris.c * * This file contains implementations of common userspace functions in terms * that the Solaris kernel can understand. */ #include "kernelStubs.h" #include #include #include #ifdef SOL9 # define compat_va_start(arg, fmt) arg = ((char *)__builtin_next_arg(fmt)) # define compat_va_end(arg) # define compat_va_copy(arg1, arg2) va_copy(arg1, arg2) #else # define compat_va_start(arg, fmt) va_start(arg, fmt) # define compat_va_end(arg) va_end(arg) # define compat_va_copy(arg1, arg2) va_copy(arg1, arg2) #endif /* *----------------------------------------------------------------------------- * * Panic -- * * Prints the debug message and stops the system. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void Panic(const char *fmt, ...) // IN { va_list args; char *result; compat_va_start(args, fmt); result = Str_Vasprintf(NULL, fmt, args); compat_va_end(args); cmn_err(CE_PANIC, "%s", result ? result : "Unable to format PANIC message"); } /* *---------------------------------------------------------------------- * * Str_Strcpy -- * * Wrapper for strcpy that checks for buffer overruns. * * Results: * Same as strcpy. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * Str_Strcpy(char *buf, // OUT const char *src, // IN size_t maxSize) // IN { size_t len; len = strlen(src); if (len >= maxSize) { Panic("%s:%d Buffer too small %p\n", __FILE__, __LINE__, buf); } bcopy(src, buf, len + 1); return buf; } /* *---------------------------------------------------------------------- * * Str_Vsnprintf -- * * Compatability wrapper b/w different libc versions * * Results: * int - number of bytes written (not including NULL terminator), * -1 on overflow (insufficient space for NULL terminator * is considered overflow). * * NB: on overflow the buffer WILL be null terminated. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Str_Vsnprintf(char *str, // OUT size_t size, // IN const char *format, // IN va_list arguments) // IN { int retval = vsnprintf(str, size, format, arguments); /* * Linux glibc 2.0.x returns -1 and null terminates (which we shouldn't * be linking against), but glibc 2.1.x follows c99 and returns * characters that would have been written. */ if (retval >= size) { return -1; } return retval; } /* *----------------------------------------------------------------------------- * * Str_Vasprintf -- * * Allocate and format a string, using the GNU libc way to specify the * format (i.e. optionally allow the use of positional parameters). * * Results: * The allocated string on success (if 'length' is not NULL, *length * is set to the length of the allocated string), NULL on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ char * Str_Vasprintf(size_t *length, // OUT const char *format, // IN va_list arguments) // IN { /* * Simple implementation of Str_Vasprintf when userlevel libraries are not * available (e.g. for use in drivers). We just fallback to vsnprintf, * doubling if we didn't have enough space. */ unsigned int bufSize; char *buf; int retval; bufSize = strlen(format); buf = NULL; do { /* * Initial allocation of strlen(format) * 2. Should this be tunable? * XXX Yes, this could overflow and spin forever when you get near 2GB * allocations. I don't care. --rrdharan */ va_list args2; bufSize *= 2; buf = realloc(buf, bufSize); if (!buf) { return NULL; } compat_va_copy(args2, arguments); retval = Str_Vsnprintf(buf, bufSize, format, args2); compat_va_end(args2); } while (retval == -1); if (length) { *length = retval; } /* * Try to trim the buffer here to save memory? */ return buf; } /* *----------------------------------------------------------------------------- * * Str_Asprintf -- * * Same as Str_Vasprintf(), but parameters are passed inline --hpreg * * Results: * Same as Str_Vasprintf() * * Side effects: * Same as Str_Vasprintf() * *----------------------------------------------------------------------------- */ char * Str_Asprintf(size_t *length, // OUT const char *format, // IN ...) // IN { va_list arguments; char *result; compat_va_start(arguments, format); result = Str_Vasprintf(length, format, arguments); compat_va_end(arguments); return result; } /* *---------------------------------------------------------------------------- * * malloc -- * * Allocate memory using kmalloc. There is no realloc * equivalent, so we roll our own by padding each allocation with * 4 (or 8 for 64 bit guests) extra bytes to store the block length. * * Results: * Pointer to driver heap memory, offset by 4 (or 8) * bytes from the real block pointer. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void * malloc(size_t size) // IN { size_t *ptr = kmem_alloc(size + sizeof(size), KM_SLEEP); if (ptr) { *ptr++ = size; } return ptr; } /* *--------------------------------------------------------------------------- * * free -- * * Free memory allocated by a previous call to malloc, calloc or realloc. * * Results: * None. * * Side effects: * Calls kmem_free to free the real (base) pointer. * *--------------------------------------------------------------------------- */ void free(void *mem) // IN { size_t *dataPtr = mem; if (mem) { --dataPtr; kmem_free(dataPtr, *dataPtr + sizeof(*dataPtr)); } } /* *---------------------------------------------------------------------------- * * calloc -- * * Malloc and zero. * * Results: * Pointer to driver heap memory (see malloc, above). * * Side effects: * None. * *---------------------------------------------------------------------------- */ void * calloc(size_t num, // IN size_t len) // IN { size_t size; void *ptr; size = num * len; ptr = malloc(size); if (ptr) { memset(ptr, 0, size); } return ptr; } /* *---------------------------------------------------------------------------- * * realloc -- * * Since the driver heap has no realloc equivalent, we have to roll our * own. Fortunately, we can retrieve the block size of every block we * hand out since we stashed it at allocation time (see malloc above). * * Results: * Pointer to memory block valid for 'newSize' bytes, or NULL if * allocation failed. * * Side effects: * Could copy memory around. * *---------------------------------------------------------------------------- */ void * realloc(void *ptr, // IN size_t newSize) // IN { void *newPtr; size_t *dataPtr; size_t length, lenUsed; dataPtr = (size_t *)ptr; length = ptr ? dataPtr[-1] : 0; if (newSize == 0) { if (ptr) { free(ptr); newPtr = NULL; } else { newPtr = malloc(newSize); } } else if (newSize == length) { newPtr = ptr; } else if ((newPtr = malloc(newSize))) { if (length < newSize) { lenUsed = length; } else { lenUsed = newSize; } memcpy(newPtr, ptr, lenUsed); free(ptr); } return newPtr; } open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/module.c0000644765153500003110000001704212220061556021512 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * module.c -- * * Structures and modules for loading and unloading of the HGFS module. * */ /* * For reference: Solaris Structures * ================================= * * VFS module struct hierarchy: * ---------------------------- * * (Solaris 9) * * modlinkage --> modlfs --> mod_ops * \ * -> vfssw --> vfsops * \ * -> (*fs_init_routine)() * * * modlfs: - points to module loading/unloading operations structure (mod_ops) * - points to VFS Switch strucutre (vfssw) * - contains extended name of filesystem * * mod_ops: - contains pointers to _init(), _fini(), and _info(), which handle * loading/unloading module into kernel and providing information * * vfssw: - points to filesystem initialization routine that is called once at * module load time (not mount time) * - points to vfsops struct that points to fs-specific operations * - contains name of fs (what you would put in /etc/vfstab) * - also contains fs mount options, flags, and mutex * * vfsops: - points to fs-level functions (mount(), umount(), etc.) * * (Solaris 10) * * modlinkage --> modlfs --> mod_ops * \ * -> vfsdef_v2 --> (*init)() * * vfsdef_v2: - this contains a pointer to an initialization routine for the * filesystem that takes different arguments * - we no longer provide an address to a vfsops; now we need to * call vfs_makevfsops() with a preconstructed array of * fs_operation_t that defines each vfs op. This needs to occur * in the initialization routine. * * (Build 58 contains the same structure named vfsdev_v3) * */ #include "hgfsSolaris.h" #include "module.h" #include "vnode.h" #include "filesystem.h" #include "debug.h" /* * Macros */ #define HGFS_VFSSW_FLAGS 0 /* * Filesystem structures */ #if HGFS_VFS_VERSION == 2 /* VFS Operations Structure */ struct vfsops HgfsVfsOps = { HgfsMount, /* vfs_mount() */ HgfsUnmount, /* vfs_unmount() */ HgfsRoot, /* vfs_root() */ HgfsStatvfs, /* vfs_statvfs() */ HgfsSync, /* vfs_sync() */ HgfsVget, /* vfs_vget() */ HgfsMountroot, /* vfs_mountroot() */ HgfsReserved, /* vfs_reserved() */ HgfsFreevfs /* vfs_freevfs() */ }; /* VFS Switch structure */ static struct vfssw HgfsVfsSw = { HGFS_FS_NAME, /* Name of filesystem */ HgfsInit, /* Initialization routine */ &HgfsVfsOps, /* VFS Operations struct */ HGFS_VFSSW_FLAGS, /* Flags: see */ NULL, /* Mount options table prototype */ 1, /* Count of references */ { { 0 } } /* Lock to protect count */ }; #else /* * Different beta builds of Solaris have different versions of this structure. * We currently don't support v4 which was out in intermediate beta builds of * Solaris 11. Instead we choose to update to the latest revision. But if needed, * v4 could be added without significant effort. */ #if HGFS_VFS_VERSION == 2 static struct vfsdef_v2 HgfsVfsDef = { #elif HGFS_VFS_VERSION == 3 static struct vfsdef_v3 HgfsVfsDef = { #else static struct vfsdef_v5 HgfsVfsDef = { #endif VFSDEF_VERSION, /* Structure version: defined in */ HGFS_FS_NAME, /* Name of filesystem */ HgfsInit, /* Initialization routine: note this is a different * routine than the one used in 9 */ HGFS_VFSSW_FLAGS, /* Filesystem flags */ NULL /* No mount options */ }; #endif /* Solaris version */ /* Filesystem module structure */ static struct modlfs HgfsModlfs = { &mod_fsops, /* Module operation structure: for auto loading/unloading */ "Host/Guest Filesystem", /* Name */ #if HGFS_VFS_VERSION== 2 &HgfsVfsSw /* VFS Switch structure */ #else &HgfsVfsDef /* Filesystem type definition record */ #endif }; /* * Modlinkage containing filesystem. */ static struct modlinkage HgfsModlinkage = { MODREV_1, /* Module revision: must be MODREV_1 */ { &HgfsModlfs, /* FS module structure */ NULL, /* NULL terminator */ } }; /* * Driver autoload functions */ /* *---------------------------------------------------------------------------- * * _init -- * Invoked when module is being loaded into kernel, and is called before * any function in the module. Any state that spans all instances of the * driver should be allocated and initialized here. * * Results: * Returns the result of mod_install(9F), which is zero on success and a * non-zero value on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int _init(void) { int ret; DEBUG(VM_DEBUG_ENTRY, "_init() for HGFS.\n"); ret = mod_install(&HgfsModlinkage); if (ret) { cmn_err(HGFS_ERROR, "could not install HGFS module.\n"); return ret; } DEBUG(VM_DEBUG_DONE, "_init() done.\n"); return 0; } /* *---------------------------------------------------------------------------- * * _fini -- * Invoked when a module is being removed from the kernel. * * Results: * Returns the result of mod_remove(9F), which is zero on success, and a * non-zero value on failure. * * Side effects: * The module will be removed from the kernel. * *---------------------------------------------------------------------------- */ int _fini(void) { int error; DEBUG(VM_DEBUG_ENTRY, "_fini() for HGFS.\n"); /* * Make sure that the fs is not mounted. */ if (HgfsGetSuperInfo()) { DEBUG(VM_DEBUG_FAIL, "Cannot unload module because file system is mounted\n"); return EBUSY; } error = mod_remove(&HgfsModlinkage); if (error) { cmn_err(HGFS_ERROR, "could not remove HGFS module.\n"); return error; } HgfsFreeVnodeOps(); HgfsFreeVfsOps(); DEBUG(VM_DEBUG_DONE, "_fini() done.\n"); return 0; } /* *---------------------------------------------------------------------------- * * _info -- * * Invoked when the modinfo(1M) command is executed. mod_info(9F) handles * this for us. * * Results: * Returns mod_info(9F)'s results, which are a non-zero value on success, and * zero on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int _info(struct modinfo *modinfop) // OUT: Filled in with module's information by { DEBUG(VM_DEBUG_ENTRY, "_info().\n"); ASSERT(modinfop); if (!modinfop) { cmn_err(HGFS_ERROR, "NULL input in _info\n"); return EINVAL; } return mod_info(&HgfsModlinkage, modinfop); } open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/filesystem.h0000644765153500003110000000477712220061556022431 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * filesystem.h -- * * Includes and definitions for filesystem code. * */ #ifndef __FILESYSTEM_H_ #define __FILESYSTEM_H_ /* * Solaris includes */ #include /* mount flags */ #include /* * Kernel only includes */ #ifdef _KERNEL #include /* mod_fsops, ... */ #include /* cmn_err() */ #include /* cmn_err() */ #include /* cmn_err() */ #include /* struct vfs, ... */ #include /* struct vnode, ... */ #if SOL11 #include /* fs_operation_def_t, ... */ #endif #endif /* _KERNEL */ #include "hgfsSolaris.h" /* * Macros */ #define HGFS_MAGIC (0xbacbacbc) #define HGFS_FSTYPE HGFS_FS_NAME /* * Struct passed from mount program to kernel (fs module) */ typedef struct HgfsMountData { uint32_t magic; uint32_t version; uint32_t fd; } HgfsMountData; #ifdef _KERNEL /* * Macros */ #ifdef SOL9 #define HGFS_VFS_FLAGS VFS_NOSUID #else #define HGFS_VFS_FLAGS VFS_NOSETUID #endif #ifdef SOL9 #define HGFS_VFS_VERSION 2 #elif defined SOL10 #define HGFS_VFS_VERSION 3 #else #define HGFS_VFS_VERSION 5 #endif #define HGFS_VFS_BSIZE HGFS_PACKET_MAX #define HGFS_COPYIN_FLAGS (0) #define HGFS_VFS_TO_SI(vfsp) ((HgfsSuperInfo *)vfsp->vfs_data) /* This macro is used for both vnode ops and vfs ops. */ #if defined SOL9 || defined SOL10 #define HGFS_VOP(vopName, vopFn, hgfsFn) { vopName, hgfsFn } #else #define HGFS_VOP(vopName, vopFn, hgfsFn) { vopName, { .vopFn = hgfsFn } } #endif /* * Functions */ /* To abstract Solaris 9 and 10 differences in suser() calls */ int HgfsSuser(struct cred *cr); void HgfsFreeVfsOps(void); /* * Extern variables */ #ifdef SOL9 EXTERN struct vfsops HgfsVfsOps; #endif #endif /* _KERNEL */ #endif /* __FILESYSTEM_H_ */ open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/request.c0000644765153500003110000002342512220061556021717 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * request.c -- * * Implementation of routines used to initialize, allocate, and move requests * between lists. * */ /* * Includes */ #include "hgfsSolaris.h" #include "request.h" /* *---------------------------------------------------------------------------- * * HgfsInitRequestList -- * * Initializes the request list related members of the HgfsSuperInfo for * this instance of the driver state. * * Results: * The pending request list, free request list, and associated * synchronization primitives are initialized. * * Side effects: * Each request is now in the free list and is set to UNUSED. * *---------------------------------------------------------------------------- */ void HgfsInitRequestList(HgfsSuperInfo *sip) // IN: Pointer to superinfo structure { int i; DEBUG(VM_DEBUG_REQUEST, "HgfsInitRequestList().\n"); ASSERT(sip); mutex_init(&sip->reqMutex, NULL, MUTEX_DRIVER, NULL); /* Initialize free request list */ DblLnkLst_Init(&sip->reqFreeList); mutex_init(&sip->reqFreeMutex, NULL, MUTEX_DRIVER, NULL); cv_init(&sip->reqFreeCondVar, NULL, CV_DRIVER, NULL); /* * Initialize pool of requests * * Here we are setting each request's id to its index into the requestPool * so this can be used as an identifier in reply packets. Each request's * state is also set to UNUSED and is added to the free list. */ for (i = 0; i < ARRAYSIZE(requestPool); i++) { requestPool[i].id = i; requestPool[i].state = HGFS_REQ_UNUSED; DblLnkLst_Init(&requestPool[i].listNode); DblLnkLst_LinkLast(&sip->reqFreeList, &requestPool[i].listNode); } //HgfsDebugPrintReqList(&sip->reqFreeList); DEBUG(VM_DEBUG_REQUEST, "HgfsInitRequestList() done.\n"); } /* *---------------------------------------------------------------------------- * * HgfsCancelAllRequests -- * * Cancels all pending (SUBMITTED) requests by signalling the transport * code that they should be aborted. * * Results: * None. * * Side effects: * Threads waiting on requests are woken up with error conditions. * *---------------------------------------------------------------------------- */ void HgfsCancelAllRequests(HgfsSuperInfo *sip) // IN: Superinfo containing // request list { int i; DEBUG(VM_DEBUG_REQUEST, "HgfsCancelAllRequests().\n"); ASSERT(sip); ASSERT(mutex_owned(&sip->reqMutex)); for (i = 0; i < ARRAYSIZE(requestPool); i++) { /* * Signal that all submitted requests need to be cancelled. * We expect that transport implementation wakes up processes * waiting on requests */ if (requestPool[i].state == HGFS_REQ_SUBMITTED) sip->cancelRequest(&requestPool[i]); } DEBUG(VM_DEBUG_REQUEST, "HgfsCancelAllRequests() done.\n"); } /* *---------------------------------------------------------------------------- * * HgfsListIsEmpty -- * * Determines whether the provided list is empty. * * Note: this assumes it is called with the list lock held because often * callers will need this function to be atomic with other operations. * * Results: * Returns zero if list is not empty, a positive integer if it is empty. * * Side effects: * None. * *---------------------------------------------------------------------------- */ INLINE Bool HgfsListIsEmpty(DblLnkLst_Links *listAnchor) // IN: Anchor of list to check { ASSERT(listAnchor); return (listAnchor == listAnchor->next); } /* *---------------------------------------------------------------------------- * * HgfsGetNewReq -- * * Allocates and initializes a new request structure from the request pool. * This function blocks until a request is available or it has been * interrupted by a signal. * * Results: * Returns pointer to allocated HgfsReq on success, and NULL if interrupted * while waiting to be allocated a request structure. * * Side effects: * Request's state is set to HGFS_REQ_ALLOCATED. * Request is removed from the free list. * *---------------------------------------------------------------------------- */ HgfsReq * HgfsGetNewReq(HgfsSuperInfo *sip) // IN: Superinfo containing free list { HgfsReq *newReq; DEBUG(VM_DEBUG_REQUEST, "HgfsGetNewReq().\n"); ASSERT(sip); /* * Here we atomically get the next free request from the free list and set * that request's state to ALLOCATED. */ mutex_enter(&sip->reqFreeMutex); /* Wait for a request structure if there aren't any free */ while (HgfsListIsEmpty(&sip->reqFreeList)) { /* * If the list is empty, we wait on the condition variable which is * unconditionally signaled whenever a request is destroyed. */ if (cv_wait_sig(&sip->reqFreeCondVar, &sip->reqFreeMutex) == 0) { /* * We were interrupted while waiting for a request, so we must return * NULL and release the mutex. */ newReq = NULL; goto out; } } newReq = HGFS_FREE_REQ_LIST_HEAD(sip); HgfsDebugPrintReq("HgfsGetNewReq", newReq); /* Failure of these indicates error in program's logic */ ASSERT(newReq && newReq->state == HGFS_REQ_UNUSED); /* Take request off the free list and indicate it has been ALLOCATED */ DblLnkLst_Unlink1(&newReq->listNode); newReq->state = HGFS_REQ_ALLOCATED; /* Clear packet of request before allocating to clients. */ bzero(newReq->packet, sizeof newReq->packet); DEBUG(VM_DEBUG_LIST, "Dequeued from free list: %s", newReq->packet); HgfsDebugPrintReqList(&sip->reqFreeList); out: mutex_exit(&sip->reqFreeMutex); DEBUG(VM_DEBUG_REQUEST, "HgfsGetNewReq() done.\n"); return newReq; } /* *---------------------------------------------------------------------------- * * HgfsDestroyReq -- * * Deallocates a request structure. * * Results: * Returns void. * * Side effects: * Request's state is set to HGFS_REQ_UNUSED. * Request is placed on the free list. * *---------------------------------------------------------------------------- */ void HgfsDestroyReq(HgfsSuperInfo *sip, // IN: Superinfo containing free list HgfsReq *oldReq) // IN: Request to destroy { DEBUG(VM_DEBUG_ENTRY, "HgfsDestroyReq().\n"); /* XXX This should go away later, just for testing */ if (oldReq->state != HGFS_REQ_COMPLETED) { DEBUG(VM_DEBUG_ALWAYS, "HgfsDestroyReq() (oldReq state=%d).\n", oldReq->state); } ASSERT(sip); ASSERT(oldReq); /* Failure of this check indicates an error in program logic */ ASSERT(oldReq->state == HGFS_REQ_COMPLETED || oldReq->state == HGFS_REQ_ABANDONED || oldReq->state == HGFS_REQ_ERROR); /* * To make the request available for other clients we change its state to * UNUSED and place it back on the free list. */ mutex_enter(&sip->reqFreeMutex); oldReq->state = HGFS_REQ_UNUSED; DblLnkLst_LinkLast(&sip->reqFreeList, &oldReq->listNode); /* Wake up clients waiting for a request structure */ cv_signal(&sip->reqFreeCondVar); mutex_exit(&sip->reqFreeMutex); HgfsDebugPrintReqList(&sip->reqFreeList); DEBUG(VM_DEBUG_REQUEST, "HgfsDestroyReq() done.\n"); } /* *---------------------------------------------------------------------------- * * HgfsSendRequest -- * * Sends request for execution. The exact details depend on transport used * to communicate with the host. * * Note: this assumes it is called with the list lock held because often * callers will need this function to be atomic with other operations. * * Results: * Returns void. * * Side effects: * Request's state is set to HGFS_REQ_SUBMITTED. * Request is added to the pending request list. * *---------------------------------------------------------------------------- */ int HgfsSendRequest(HgfsSuperInfo *sip, // IN: Superinfo sructure with methods HgfsReq *req) // IN/OUT: Request to be sent { int ret; ASSERT(sip); ASSERT(req); /* Failure of this check indicates error in program logic */ ASSERT(req->state == HGFS_REQ_ALLOCATED); req->state = HGFS_REQ_SUBMITTED; ret = sip->sendRequest(req); if (ret) { req->state = HGFS_REQ_ERROR; } return ret; } /* *---------------------------------------------------------------------------- * * HgfsWakeWaitingClient -- * * Wakes up the client waiting on the specified request. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ INLINE void HgfsWakeWaitingClient(HgfsSuperInfo *sip, // IN: Superinfo with request mutex HgfsReq *req) // IN: Request to wake client for { // DEBUG(VM_DEBUG_REQUEST, "HgfsWakeWaitingClient().\n"); ASSERT(sip); ASSERT(req); /* * We need to acquire the mutex before signaling the request's condition * variable since it was acquired before sleeping in HgfsSubmitRequest(). */ mutex_enter(&sip->reqMutex); cv_signal(&req->condVar); mutex_exit(&sip->reqMutex); // DEBUG(VM_DEBUG_REQUEST, "HgfsWakeWaitingClient() done.\n"); } open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/hgfsSolaris.h0000644765153500003110000001342012220061556022512 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * hgfsSolaris.h -- * * Contains declarations needed in entire Solaris HGFS module. * */ /* XXX: Split the non-kernel parts off into another header */ #ifndef __HGFS_H_ #define __HGFS_H_ /* * System includes */ /* * Kernel system includes */ #ifdef _KERNEL /* * These must be in this order, so we include them here, and only here, so * that this ordering is guaranteed. * * defines min and max macros (that shouldn't be used because * they're broken) and includes which defines * functions named min and max. The function definitions must come first. */ #include /* D_NEW flag and other includes */ #include /* various typedefs */ #endif /* _KERNEL */ /* * VMware includes */ #include "hgfsProto.h" #include "hgfsState.h" #include "filesystem.h" /* * Kernel VMware includes */ #ifdef _KERNEL #include "dbllnklst.h" #include "vm_assert.h" #endif /* _KERNEL */ /* * Macros */ #define HGFS_PAYLOAD_MAX(reply) (HGFS_PACKET_MAX - sizeof *reply) #define HGFS_FS_NAME "vmhgfs" #define HGFS_BLOCKSIZE 1024 /* * Kernel only macros */ #ifdef _KERNEL /* Determines size of request pool */ #define HGFS_MAX_OUTSTANDING_REQS 4 /* HGFS cmn_err() levels */ #define HGFS_ERROR (CE_WARN) /* Internal error code(s) */ #define HGFS_ERR (-1) #define HGFS_ERR_NULL_INPUT (-50) #define HGFS_ERR_NODEV (-51) #define HGFS_ERR_INVAL (-52) /* * Don't change this to KM_NOSLEEP without first making sure that we handle * the possibility of kmem_zalloc() failing: KM_SLEEP guarantees it won't fail */ #define HGFS_ALLOC_FLAG (KM_SLEEP) /* Accessing root inode and vnode */ #define HGFS_ROOT_VNODE(sip) (sip->rootVnode) #endif /* _KERNEL */ /* * Structures */ /* We call them *Header in the Solaris code for clarity. */ typedef HgfsReply HgfsReplyHeader; typedef HgfsRequest HgfsRequestHeader; /* * Kernel only structures and variables */ #ifdef _KERNEL /* * Each request will traverse through this set of states. See * docs/request-lifecycle.txt for an explanation of these and the API for * interacting with requests. */ typedef enum { HGFS_REQ_UNUSED = 1, HGFS_REQ_ALLOCATED, HGFS_REQ_SUBMITTED, HGFS_REQ_ABANDONED, HGFS_REQ_ERROR, HGFS_REQ_COMPLETED } HgfsReqState; /* * General request structure. Specific requests and replies are placed in the * packet of this structure. */ typedef struct HgfsReq { DblLnkLst_Links listNode; /* Node to connect the request to one of * the lists (free or pending) */ kcondvar_t condVar; /* Condition variable to wait for and signal presence of reply. Used with the reqMutex in HgfsSuperInfo. */ HgfsReqState state; /* Indicates state of request */ uint32_t id; /* The unique identifier of this request */ uint32_t packetSize; /* Total size of packet */ char packet[HGFS_PACKET_MAX]; /* Contains both requests and replies */ } HgfsReq; /* * The global state structure for the entire module. This is allocated in * HgfsDevAttach() and deallocated in HgfsDevDetach(). * * Note that reqMutex and reqFreeList are also used for synchronization between * the filesystem and driver. See docs/synchronization.txt for details. */ typedef struct HgfsSuperInfo { kmutex_t reqMutex; /* Serializes sending of requests */ /* Free request list */ DblLnkLst_Links reqFreeList; /* Anchor for free request list */ kmutex_t reqFreeMutex; /* For protection of reqFreeList */ kcondvar_t reqFreeCondVar; /* For waiting on free request list */ /* For filesystem */ struct vfs *vfsp; /* Our filesystem structure */ struct vnode *rootVnode; /* Root vnode of the filesystem */ HgfsFileHashTable fileHashTable; /* File hash table */ int (*sendRequest)(HgfsReq *req); /* Current transport's sent method */ void (*cancelRequest)(HgfsReq *req); /* Current transport's cancel method */ Bool (*transportInit)(void); void (*transportCleanup)(void); } HgfsSuperInfo; /* * Global Variables */ /* Pool of request structures */ HgfsReq requestPool[HGFS_MAX_OUTSTANDING_REQS]; /* * Used to access shared state of driver and filesystem. superInfoHead is * a pointer to state managed by Solaris, hgfsInstance is the index into this state * list, and is set in HgfsDevAttach(). * * Note that both the driver and filesystem use ddi_get_soft_state() to get * a pointer to the superinfo. Both use superInfoHead, but the device uses the * instance number derived from passed in arguments and the filesystem uses * hgfsInstance. This is not a problem as long as the instance number cannot * change, which /should/ be guaranteed, and there is only a single instance, * which cannot happen. */ void *superInfoHead; int hgfsInstance; #endif /* _KERNEL */ #endif /* __HGFS_H_ */ open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/hgfsBdGlue.c0000644765153500003110000001077412220061556022244 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * hgfsBdGlue.c -- * * Glue to communicate directly with backdoor code instead of offloading * it to guestd */ #include "hgfsSolaris.h" #include "request.h" #include "hgfsBdGlue.h" #include "hgfsBd.h" #include "vm_assert.h" #include "debug.h" static RpcOut *hgfsRpcOut; static void *packetBuffer; /* * Public function implementations. */ /* *----------------------------------------------------------------------------- * * HgfsBackdoorSendRequest -- * * Send one request through backdoor and wait for the result. * * Results: * 0 on success, standard UNIX error code upon failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int HgfsBackdoorSendRequest(HgfsReq *req) // IN/OUT: Request to be sent { char const *replyPacket; size_t packetSize; ASSERT(req->state == HGFS_REQ_SUBMITTED); ASSERT(req->packetSize <= HGFS_PACKET_MAX); bcopy(req->packet, packetBuffer, req->packetSize); packetSize = req->packetSize; DEBUG(VM_DEBUG_COMM, "HgfsBackdoorSendRequest: Sending packet over backdoor\n"); /* * We should attempt to reopen the backdoor channel with every request, * because the HGFS server in the host can be enabled or disabled at any * time. */ if (!HgfsBd_OpenBackdoor(&hgfsRpcOut)) { DEBUG(VM_DEBUG_COMM, "HgfsBackdoorSendRequest: HGFS is disabled in the host\n"); req->state = HGFS_REQ_ERROR; return ENOSYS; } else if (HgfsBd_Dispatch(hgfsRpcOut, packetBuffer, &packetSize, &replyPacket) == 0) { DEBUG(VM_DEBUG_COMM, "HgfsBackdoorSendRequest: backdoor reply received\n"); /* Request was sent successfully. Copy the reply and return to the client. */ ASSERT(packetSize <= HGFS_PACKET_MAX); bcopy(replyPacket, req->packet, packetSize); req->packetSize = packetSize; req->state = HGFS_REQ_COMPLETED; } else { DEBUG(VM_DEBUG_COMM, "HgfsBackdoorSendRequest: backdoor error\n"); /* Pass the error into the request. */ req->state = HGFS_REQ_ERROR; /* * If the channel was previously open, make sure it's dead and gone * now. We do this because subsequent requests deserve a chance to * reopen it. */ HgfsBd_CloseBackdoor(&hgfsRpcOut); } return 0; } /* *----------------------------------------------------------------------------- * * HgfsBackdoorCancelRequest -- * * Cancel request stub. Since backdoor is synchronous transport this * function should never be called in practice. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void HgfsBackdoorCancelRequest(HgfsReq *req) // IN: Request to be cancelled { DEBUG(VM_DEBUG_COMM, "HgfsBackdoorCancelRequest: %p\n", req); } /* *---------------------------------------------------------------------- * * HgfsBackdoorInit -- * * This function initializes backdoor transport by allocating transfer * buffer. * * Results: * TRUE if buffer was allocated succsessfully, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool HgfsBackdoorInit(void) { packetBuffer = HgfsBd_GetBuf(); return packetBuffer != NULL; } /* *---------------------------------------------------------------------- * * HgfsBackdoorCleanup -- * * This function closes backdoor channel. It is supposed to be * called when we unmount the filesystem. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void HgfsBackdoorCleanup(void) { DEBUG(VM_DEBUG_COMM, "HgfsBackdoorCleanup: Closing backdoor\n"); HgfsBd_CloseBackdoor(&hgfsRpcOut); HgfsBd_PutBuf(packetBuffer); } open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/request.h0000644765153500003110000000357312220061556021726 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * request.h -- * * Prototypes for request initialization, allocation, and list manipulation * functions. * */ #ifndef __REQUEST_H_ #define __REQUEST_H_ #include /* mutexes and condition variables */ #include "hgfsSolaris.h" #include "debug.h" #include "dbllnklst.h" /* Double link list types */ /* * Macros */ /* Since the DblLnkLst_Links in the superinfo is just an anchor, we want to * skip it (e.g., get the container for the next element) */ #define HGFS_REQ_LIST_HEAD(si) \ (DblLnkLst_Container(si->reqList.next, HgfsReq, listNode)) #define HGFS_REQ_LIST_HEAD_NODE(si) \ (si->reqList.next) #define HGFS_FREE_REQ_LIST_HEAD(si) \ (DblLnkLst_Container(si->reqFreeList.next, HgfsReq, listNode)) #define HGFS_FREE_REQ_LIST_HEAD_NODE(si) \ (si->reqFreeList.next) /* * Functions */ void HgfsInitRequestList(HgfsSuperInfo *sip); void HgfsCancelAllRequests(HgfsSuperInfo *sip); INLINE Bool HgfsListIsEmpty(DblLnkLst_Links *listAnchor); HgfsReq *HgfsGetNewReq(HgfsSuperInfo *sip); void HgfsDestroyReq(HgfsSuperInfo *sip, HgfsReq *oldReq); int HgfsSendRequest(HgfsSuperInfo *sip, HgfsReq *req); INLINE void HgfsWakeWaitingClient(HgfsSuperInfo *sip, HgfsReq *req); #endif /* __REQUEST_H_ */ open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/debug.c0000644765153500003110000003267212220061556021321 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * debug.c -- * * Routines for debugging Solaris kernel module. * */ #include "debug.h" #include "filesystem.h" #ifndef SOL9 #include #endif /* * Functions */ /* *---------------------------------------------------------------------------- * * HgfsDebugPrintVfssw -- * * Prints the provided VFS Switch structure. * * Results: * None. * * Side effects: * None. * * *---------------------------------------------------------------------------- */ INLINE void HgfsDebugPrintVfssw(char *str, struct vfssw *vfsswp) { ASSERT(str); ASSERT(vfsswp); DEBUG(VM_DEBUG_STRUCT, "struct vfssw from %s\n", str); DEBUG(VM_DEBUG_STRUCT, " vsw_name : %s\n", (vfsswp->vsw_name) ? vfsswp->vsw_name : "NULL"); DEBUG(VM_DEBUG_STRUCT, " vsw_init : %p\n", vfsswp->vsw_init); DEBUG(VM_DEBUG_STRUCT, " vsw_flag : %x\n", vfsswp->vsw_flag); # ifdef SOL9 DEBUG(VM_DEBUG_STRUCT, " vsw_vfsops : %x\n", vfsswp->vsw_vfsops); DEBUG(VM_DEBUG_STRUCT, " vsw_optproto: %x\n", vfsswp->vsw_optproto); # endif DEBUG(VM_DEBUG_STRUCT, " vsw_count : %d\n", vfsswp->vsw_count); } /* *---------------------------------------------------------------------------- * * HgfsDebugPrintVfs -- * * Prints the provided VFS structure. * * Results: * None. * * Side effects: * None. * * *---------------------------------------------------------------------------- */ INLINE void HgfsDebugPrintVfs(char *str, struct vfs *vfsp) { ASSERT(str); ASSERT(vfsp); DEBUG(VM_DEBUG_STRUCT, "struct vfs from %s\n", str); DEBUG(VM_DEBUG_STRUCT, " vfs_next : %p\n", vfsp->vfs_next); DEBUG(VM_DEBUG_STRUCT, " vfs_op : %p\n", vfsp->vfs_op); DEBUG(VM_DEBUG_STRUCT, " vfs_vnodecovered: %p\n", vfsp->vfs_vnodecovered); DEBUG(VM_DEBUG_STRUCT, " vfs_flag : %d\n", vfsp->vfs_flag); DEBUG(VM_DEBUG_STRUCT, " vfs_bsize : %d\n", vfsp->vfs_bsize); DEBUG(VM_DEBUG_STRUCT, " vfs_fstype : %d\n", vfsp->vfs_fstype); # ifdef SOL9 DEBUG(VM_DEBUG_STRUCT, " vfs_fsid : %d\n", vfsp->vfs_fsid); # else DEBUG(VM_DEBUG_STRUCT, " vfs_fsid.val[0] : %d\n", vfsp->vfs_fsid.val[0]); DEBUG(VM_DEBUG_STRUCT, " vfs_fsid.val[1] : %d\n", vfsp->vfs_fsid.val[1]); # endif DEBUG(VM_DEBUG_STRUCT, " vfs_vadata : %p\n", vfsp->vfs_data); DEBUG(VM_DEBUG_STRUCT, " vfs_dev : %lu\n", vfsp->vfs_dev); DEBUG(VM_DEBUG_STRUCT, " vfs_bcount : %lu\n", vfsp->vfs_bcount); # ifdef SOL9 DEBUG(VM_DEBUG_STRUCT, " vfs_nsubmounts : %d\n", vfsp->vfs_nsubmounts); # endif DEBUG(VM_DEBUG_STRUCT, " vfs_list : %p\n", vfsp->vfs_list); DEBUG(VM_DEBUG_STRUCT, " vfs_hash : %p\n", vfsp->vfs_hash); DEBUG(VM_DEBUG_STRUCT, " vfs_reflock : %p\n", &vfsp->vfs_reflock); DEBUG(VM_DEBUG_STRUCT, " vfs_count : %d\n", vfsp->vfs_count); # ifdef SOL9 DEBUG(VM_DEBUG_STRUCT, " vfs_mntopts : %x\n", vfsp->vfs_mntopts); DEBUG(VM_DEBUG_STRUCT, " vfs_resource : %s\n", (vfsp->vfs_resource) ? vfsp->vfs_resource : "NULL"); # endif DEBUG(VM_DEBUG_STRUCT, " vfs_mtime : %ld\n", vfsp->vfs_mtime); } /* *---------------------------------------------------------------------------- * * HgfsDebugPrintVnode -- * * Prints the provided vnode structure. * * Results: * None. * * Side effects: * None. * * *---------------------------------------------------------------------------- */ INLINE void HgfsDebugPrintVnode(uint32 level, char *str, struct vnode *vnodep, Bool printFileName) { ASSERT(str); ASSERT(vnodep); DEBUG(level, "struct vnode from %s located at %p\n", str, vnodep); DEBUG(level, " v_lock : %p\n", &vnodep->v_lock); DEBUG(level, " v_flag : %d\n", vnodep->v_flag); DEBUG(level, " v_count : %d\n", vnodep->v_count); DEBUG(level, " v_vfsmountedhere: %p\n", vnodep->v_vfsmountedhere); DEBUG(level, " v_op : %p\n", vnodep->v_op); DEBUG(level, " v_vfsp : %p\n", vnodep->v_vfsp); DEBUG(level, " v_stream : %p\n", vnodep->v_stream); DEBUG(level, " v_pages : %p\n", vnodep->v_pages); # ifdef SOL9 DEBUG(level, " v_next : %p\n", vnodep->v_next); DEBUG(level, " v_prev : %p\n", vnodep->v_prev); # endif DEBUG(level, " v_type : %d\n", vnodep->v_type); DEBUG(level, " v_rdev : %lu\n", vnodep->v_rdev); DEBUG(level, " v_data : %p\n", vnodep->v_data); DEBUG(level, " v_filocks : %p\n", vnodep->v_filocks); DEBUG(level, " v_shrlocks : %p\n", vnodep->v_shrlocks); DEBUG(level, " v_cv : %p\n", &vnodep->v_cv); DEBUG(level, " v_locality : %p\n", vnodep->v_locality); DEBUG(level, " v_nbllock : %p\n", &vnodep->v_nbllock); if (printFileName && HGFS_VP_TO_OFP(vnodep) && HGFS_VP_TO_FP(vnodep)) { DEBUG(level, " filename : %s\n", HGFS_VP_TO_FILENAME(vnodep)); } } /* *---------------------------------------------------------------------------- * * HgfsDebugPrintCred -- * * Prints the provided cred structure the describes the credentials of the * caller. * * Results: * None. * * Side effects: * None. * * *---------------------------------------------------------------------------- */ INLINE void HgfsDebugPrintCred(char *str, struct cred *credp) { DEBUG(VM_DEBUG_STRUCT, "struct cred from %s\n", str); DEBUG(VM_DEBUG_STRUCT, " cr_ref : %d\n", credp->cr_ref); DEBUG(VM_DEBUG_STRUCT, " cr_uid : %d\n", credp->cr_uid); DEBUG(VM_DEBUG_STRUCT, " cr_gid : %d\n", credp->cr_gid); DEBUG(VM_DEBUG_STRUCT, " cr_ruid : %d\n", credp->cr_ruid); DEBUG(VM_DEBUG_STRUCT, " cr_rgid : %d\n", credp->cr_rgid); DEBUG(VM_DEBUG_STRUCT, " cr_suid : %d\n", credp->cr_suid); DEBUG(VM_DEBUG_STRUCT, " cr_sgid : %d\n", credp->cr_sgid); DEBUG(VM_DEBUG_STRUCT, " cr_ngroups: %d\n", credp->cr_ngroups); DEBUG(VM_DEBUG_STRUCT, " cr_groups : %p\n", credp->cr_groups); } /* *---------------------------------------------------------------------------- * * HgfsDebugMounta -- * * Prints the provided mounta structure that describes the arguments * provided to users. * * Results: * None. * * Side effects: * None. * * *---------------------------------------------------------------------------- */ INLINE void HgfsDebugPrintMounta(char *str, struct mounta *mntp) { ASSERT(str); ASSERT(mntp); DEBUG(VM_DEBUG_STRUCT, "struct mounta from %s\n", str); DEBUG(VM_DEBUG_STRUCT, " spec : %s\n", (mntp->spec) ? mntp->spec : "NULL"); DEBUG(VM_DEBUG_STRUCT, " dir : %s\n", (mntp->dir) ? mntp->dir : "NULL"); DEBUG(VM_DEBUG_STRUCT, " flags : %x\n", mntp->flags); DEBUG(VM_DEBUG_STRUCT, " fstype : %s\n", (mntp->fstype) ? mntp->fstype : "NULL"); DEBUG(VM_DEBUG_STRUCT, " dataptr : %p\n", mntp->dataptr); DEBUG(VM_DEBUG_STRUCT, " datalen : %d\n", mntp->datalen); DEBUG(VM_DEBUG_STRUCT, " optptr : %p\n", mntp->optptr); DEBUG(VM_DEBUG_STRUCT, " optlen : %d\n", mntp->optlen); } /* *---------------------------------------------------------------------------- * * HgfsDebugPrintVattr -- * * Prints the contents of an attributes structure. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ INLINE void HgfsDebugPrintVattr(const struct vattr *vap) { DEBUG(VM_DEBUG_STRUCT, " va_mask: %x\n", vap->va_mask); DEBUG(VM_DEBUG_STRUCT, " va_type: %d\n", vap->va_type); DEBUG(VM_DEBUG_STRUCT, " va_mode: %x\n", vap->va_mode); DEBUG(VM_DEBUG_STRUCT, " va_uid: %u\n", vap->va_uid); DEBUG(VM_DEBUG_STRUCT, " va_gid: %u\n", vap->va_gid); DEBUG(VM_DEBUG_STRUCT, " va_fsid: %lu\n", vap->va_fsid); DEBUG(VM_DEBUG_STRUCT, " va_nodeid: %llu\n", vap->va_nodeid); DEBUG(VM_DEBUG_STRUCT, " va_nlink: %x\n", vap->va_nlink); DEBUG(VM_DEBUG_STRUCT, " va_size: %llu\n", vap->va_size); DEBUG(VM_DEBUG_STRUCT, " va_atime.tv_sec: %ld\n", vap->va_atime.tv_sec); DEBUG(VM_DEBUG_STRUCT, " va_atime.tv_nsec: %ld\n", vap->va_atime.tv_nsec); DEBUG(VM_DEBUG_STRUCT, " va_mtime.tv_sec: %ld\n", vap->va_mtime.tv_sec); DEBUG(VM_DEBUG_STRUCT, " va_mtime.tv_nsec: %ld\n", vap->va_mtime.tv_nsec); DEBUG(VM_DEBUG_STRUCT, " va_ctime.tv_sec: %ld\n", vap->va_ctime.tv_sec); DEBUG(VM_DEBUG_STRUCT, " va_ctime.tv_nsec: %ld\n", vap->va_ctime.tv_nsec); DEBUG(VM_DEBUG_STRUCT, " va_rdev: %lu\n", vap->va_rdev); DEBUG(VM_DEBUG_STRUCT, " va_blksize: %u\n", vap->va_blksize); DEBUG(VM_DEBUG_STRUCT, " va_nblocks: %llu\n", vap->va_nblocks); #ifdef SOL9 DEBUG(VM_DEBUG_STRUCT, " va_vcode: %u\n", vap->va_vcode); #else DEBUG(VM_DEBUG_STRUCT, " va_seq: %u\n", vap->va_seq); #endif } /* *---------------------------------------------------------------------------- * * HgfsDebugPrintReqList -- * * For debugging. Prints out the request list for the provided list * anchor. * Note: Assumes called with the list lock held. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsDebugPrintReqList(DblLnkLst_Links *listAnchor) // IN: Anchor of list to print { DblLnkLst_Links *currNode; HgfsReq *currReq; ASSERT(listAnchor); DEBUG(VM_DEBUG_STRUCT, "Request List:\n"); DEBUG(VM_DEBUG_STRUCT, " anchor: %p\n", listAnchor); for (currNode = listAnchor->next; currNode != listAnchor; currNode = currNode->next) { currReq = DblLnkLst_Container(currNode, HgfsReq, listNode); DEBUG(VM_DEBUG_STRUCT, " address: %p (id=%d)\n", currReq, currReq->id); } DEBUG(VM_DEBUG_STRUCT, "--DONE--\n"); } /* *---------------------------------------------------------------------------- * * HgfsDebugPrintReq -- * * Prints the relevant portions of the provided HgfsReq structure. * * Results: * None. * * Side effects: * None. * * *---------------------------------------------------------------------------- */ void HgfsDebugPrintReq(const char *str, HgfsReq *req) { ASSERT(str); ASSERT(req); DEBUG(VM_DEBUG_STRUCT, "struct HgfsReq from %s\n", str); DEBUG(VM_DEBUG_STRUCT, " id: %d\n", req->id); DEBUG(VM_DEBUG_STRUCT, " listNode: %p\n", &req->listNode); DEBUG(VM_DEBUG_STRUCT, " next=%p\n", req->listNode.next); DEBUG(VM_DEBUG_STRUCT, " prev=%p\n", req->listNode.prev); DEBUG(VM_DEBUG_STRUCT, " packetSize: %d\n", req->packetSize); DEBUG(VM_DEBUG_STRUCT, " state: %d (see hgfsSolaris.h)\n", req->state); } /* *---------------------------------------------------------------------------- * * HgfsDebugPrintReqPool -- * * Prints the contents if the request pool. * * Results: * None. * * Side effects: * None. * * *---------------------------------------------------------------------------- */ void HgfsDebugPrintReqPool(const char *str) { int i; ASSERT(str); DEBUG(VM_DEBUG_STRUCT, "Request pool from %s\n", str); for (i = 0; i < ARRAYSIZE(requestPool); i++) { DEBUG(VM_DEBUG_STRUCT, " Index: %d, ID: %d\n", i, requestPool[i].id); DEBUG(VM_DEBUG_STRUCT, " listNode: %p\n", &requestPool[i].listNode); DEBUG(VM_DEBUG_STRUCT, " next=%p\n", requestPool[i].listNode.next); DEBUG(VM_DEBUG_STRUCT, " prev=%p\n", requestPool[i].listNode.prev); DEBUG(VM_DEBUG_STRUCT, " packetSize: %d\n", requestPool[i].packetSize); DEBUG(VM_DEBUG_STRUCT, " state: %d (see hgfsSolaris.h)\n", requestPool[i].state); } DEBUG(VM_DEBUG_STRUCT, "--request pool done--\n"); } /* * There is a problem in Solaris 9's header files when using the va_start * and va_end macros, so we manually do what the preprocessor would have * done here. * * Note, the line using __builtin_next_arg is equivalent to: * args = ((char *)(&fmt) + sizeof (char *)); * * That is, it just provides a pointer to the unnamed first variable * argument. */ #ifdef SOL9 # define compat_va_start(arg, fmt) arg = ((char *)__builtin_next_arg(fmt)) # define compat_va_end(arg) #else # define compat_va_start(arg, fmt) va_start(arg, fmt) # define compat_va_end(arg) va_end(arg) #endif static void vLog(const char *fmt, va_list args) { #ifdef VM_DEBUG_LEV char buffer[1024]; /* * We check this here to avoid unnecessarily manipulating buffer if we * aren't even going to print the log. */ if (VM_DEBUG_LOG & VM_DEBUG_LEV) { vsprintf(buffer, fmt, args); cmn_err(HGFS_DEBUG, "%s", buffer); } #endif } /* * For compatibility with existing code. */ void Log(const char *fmt, ...) // IN: format string, etc { va_list args; compat_va_start(args, fmt); vLog(fmt, args); compat_va_end(args); } /* * For compatibility with existing code. */ void Debug(const char *fmt, ...) // IN: format string, etc. { va_list args; compat_va_start(args, fmt); vLog(fmt, args); compat_va_end(args); } #undef compat_va_list #undef compat_va_start #undef compat_va_end open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/COPYING0000644765153500003110000004331212220061556021113 0ustar dtormts COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 1. Definitions. 1.1. "Contributor" means each individual or entity that creates or contributes to the creation of Modifications. 1.2. "Contributor Version" means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor. 1.3. "Covered Software" means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof. 1.4. "Executable" means the Covered Software in any form other than Source Code. 1.5. "Initial Developer" means the individual or entity that first makes Original Software available under this License. 1.6. "Larger Work" means a work which combines Covered Software or portions thereof with code not governed by the terms of this License. 1.7. "License" means this document. 1.8. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. 1.9. "Modifications" means the Source Code and Executable form of any of the following: A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications; B. Any new file that contains any part of the Original Software or previous Modifications; or C. Any new file that is contributed or otherwise made available under the terms of this License. 1.10. "Original Software" means the Source Code and Executable form of computer software code that is originally released under this License. 1.11. "Patent Claims" means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. 1.12. "Source Code" means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code. 1.13. "You" (or "Your") means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants. 2.1. The Initial Developer Grant. Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license: (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof). (c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License. (d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices. 2.2. Contributor Grant. Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes or otherwise makes the Modifications available to a third party. (d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Contributor. 3. Distribution Obligations. 3.1. Availability of Source Code. Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used for software exchange. 3.2. Modifications. The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License. 3.3. Required Notices. You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer. 3.4. Application of Additional Terms. You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients' rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. 3.5. Distribution of Executable Versions. You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipient's rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable form under a different license, You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. 3.6. Larger Works. You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software. 4. Versions of the License. 4.1. New Versions. Sun Microsystems, Inc. is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License. 4.2. Effect of New Versions. You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. Otherwise, You may also choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version of the License published by the license steward. 4.3. Modified Versions. When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License. 5. DISCLAIMER OF WARRANTY. COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. 6. TERMINATION. 6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. 6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as "Participant") alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant, the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement with Participant. 6.3. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination. 7. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. 8. U.S. GOVERNMENT END USERS. The Covered Software is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" (as that term is defined at 48 C.F.R. 252.227-7014(a)(1)) and "commercial computer software documentation" as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License. 9. MISCELLANEOUS. This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdiction's conflict-of-law provisions. Any litigation relating to this License shall be subject to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the losing party responsible for costs, including, without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use, distribute or otherwise make available any Covered Software. 10. RESPONSIBILITY FOR CLAIMS. As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/vnode.h0000644765153500003110000000171012220061556021340 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * vnode.h -- * * Functions exported by vnode.c */ #ifndef __VNODE_H_ #define __VNODE_H_ #include "hgfsSolaris.h" int HgfsSetVnodeOps(struct vnode *vp); inline HgfsSuperInfo *HgfsGetSuperInfo(void); void HgfsInitSuperInfo(struct vfs *vfsp); void HgfsClearSuperInfo(void); int HgfsMakeVnodeOps(void); void HgfsFreeVnodeOps(void); #endif open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/Makefile0000644765153500003110000001113212220061556021513 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 2008 VMware, Inc. All rights reserved. # # The contents of this file are subject to the terms of the Common # Development and Distribution License (the "License") version 1.0 # and no later version. You may not use this file except in # compliance with the License. # # You can obtain a copy of the License at # http://www.opensource.org/licenses/cddl1.php # # See the License for the specific language governing permissions # and limitations under the License. # ########################################################## ## ## General build locations and variables ## MODULE := vmhgfs CFLAGS := LDFLAGS := # Solaris version defines for in-code #ifdefs (default to Solaris 9) ifeq ($(shell echo "$(VM_UNAME)" | cut -c-4),5.11) CFLAGS += -DSOL11 else ifeq ($(shell echo "$(VM_UNAME)" | cut -c-4),5.10) CFLAGS += -DSOL10 else CFLAGS += -DSOL9 # we don't support Solaris 9 (we could but we use memcpy/memset # and we'd need stubs to get the module to load into the kernel). $(error "This makefile is only used for Solaris 10 and 11") endif endif CFLAGS += -ffreestanding CFLAGS += -nodefaultlibs CFLAGS += -O2 CFLAGS += -Wall -Werror CFLAGS += $(GLOBAL_DEFS) CFLAGS += $(CC_WARNINGS) CFLAGS += -DVMX86_TOOLS CFLAGS += -I. ifdef VMX86_DEVEL CFLAGS += -DVMX86_DEVEL endif ifdef VMX86_DEBUG # For assertions CFLAGS += -DVMX86_DEBUG endif ifdef VMX86_LOG # For debug logging CFLAGS += -DVM_DEBUGGING_ON endif ## ## Objects needed to build the HGFS kernel module ## SOLHGFS_KRN_OBJS := debug.o SOLHGFS_KRN_OBJS += filesystem.o SOLHGFS_KRN_OBJS += hgfsBdGlue.o SOLHGFS_KRN_OBJS += hgfsState.o SOLHGFS_KRN_OBJS += kernelStubsSolaris.o SOLHGFS_KRN_OBJS += module.o SOLHGFS_KRN_OBJS += request.o SOLHGFS_KRN_OBJS += vnode.o SOLHGFS_32_KRN_OBJS := $(addprefix i386/, $(SOLHGFS_KRN_OBJS)) SOLHGFS_64_KRN_OBJS := $(addprefix amd64/, $(SOLHGFS_KRN_OBJS)) SOLHGFS_LIB_OBJS := backdoor.o SOLHGFS_LIB_OBJS += cpName.o SOLHGFS_LIB_OBJS += cpNameLinux.o SOLHGFS_LIB_OBJS += hgfsBd.o SOLHGFS_LIB_OBJS += hgfsEscape.o SOLHGFS_LIB_OBJS += hgfsUtil.o SOLHGFS_LIB_OBJS += message.o SOLHGFS_LIB_OBJS += rpcout.o SOLHGFS_LIB_OBJS += sha1.o SOLHGFS_32_LIB_OBJS := $(addprefix i386/, $(SOLHGFS_LIB_OBJS)) SOLHGFS_32_LIB_OBJS += i386/backdoorGcc32.o SOLHGFS_64_LIB_OBJS := $(addprefix amd64/, $(SOLHGFS_LIB_OBJS)) SOLHGFS_64_LIB_OBJS += amd64/backdoorGcc64.o SOLHGFS_32_OBJS := $(SOLHGFS_32_KRN_OBJS) $(SOLHGFS_32_LIB_OBJS) SOLHGFS_64_OBJS := $(SOLHGFS_64_KRN_OBJS) $(SOLHGFS_64_LIB_OBJS) MODULE_32 := i386/$(MODULE) MODULE_64 := amd64/$(MODULE) ifdef OVT_SOURCE_DIR CFLAGS += -I$(OVT_SOURCE_DIR)/lib/include CFLAGS += -I$(OVT_SOURCE_DIR)/lib/backdoor CFLAGS += -I$(OVT_SOURCE_DIR)/lib/hgfs VPATH := $(OVT_SOURCE_DIR)/lib/backdoor VPATH := $(VPATH):$(OVT_SOURCE_DIR)/lib/hgfs VPATH := $(VPATH):$(OVT_SOURCE_DIR)/lib/hgfsBd VPATH := $(VPATH):$(OVT_SOURCE_DIR)/lib/message VPATH := $(VPATH):$(OVT_SOURCE_DIR)/lib/misc VPATH := $(VPATH):$(OVT_SOURCE_DIR)/lib/rpcOut endif CFLAGS_32 := $(CFLAGS) CFLAGS_32 += -m32 LDFLAGS_32 := $(LDFLAGS) CFLAGS_64 := $(CFLAGS) CFLAGS_64 += -m64 CFLAGS_64 += -mcmodel=kernel CFLAGS_64 += -mno-red-zone LDFLAGS_64 := $(LDFLAGS) ifdef HAVE_GNU_LD LDFLAGS_64 += -m elf_x86_64 else LDFLAGS_64 += -64 endif ## ## Building targets ## .PHONY: all prepare_dirs clean install all: prepare_dirs $(MODULE_32) $(MODULE_64) prepare_dirs: @echo "Creating build directories" mkdir -p i386 mkdir -p amd64 # Build just the module for 32 bits kernel $(MODULE_32): $(SOLHGFS_32_OBJS) @echo "Linking $(MODULE_32)" $(LD) $(LDFLAGS_32) -r -o $(MODULE_32) $(SOLHGFS_32_OBJS) $(SOLHGFS_32_KRN_OBJS): i386/%.o: %.c @echo "Compiling $(hashTable[index]).next #define HGFS_FILE_HT_BUCKET(ht, index) (&ht->hashTable[index]) #define HGFS_IS_ROOT_FILE(sip, file) (HGFS_VP_TO_FP(sip->rootVnode) == file) /* * Prototypes for internal functions */ /* Allocation/initialization/free of open file state */ static HgfsOpenFile *HgfsAllocOpenFile(const char *fileName, HgfsFileType fileType, HgfsFileHashTable *htp); static void HgfsFreeOpenFile(HgfsOpenFile *ofp, HgfsFileHashTable *htp); /* Acquiring/releasing file state */ static HgfsFile *HgfsGetFile(const char *fileName, HgfsFileType fileType, HgfsFileHashTable *htp); static void HgfsReleaseFile(HgfsFile *fp, HgfsFileHashTable *htp); static int HgfsInitFile(HgfsFile *fp, const char *fileName, HgfsFileType fileType); /* Adding/finding/removing file state from hash table */ static inline void HgfsAddFile(HgfsFile *fp, HgfsFileHashTable *htp); static inline void HgfsRemoveFile(HgfsFile *fp, HgfsFileHashTable *htp); static HgfsFile *HgfsFindFile(const char *fileName, HgfsFileHashTable *htp); /* Other utility functions */ static unsigned int HgfsFileNameHash(const char *fileName); static void HgfsNodeIdHash(const char *fileName, uint32_t fileNameLength, ino64_t *outHash); /* * Public functions */ /* *---------------------------------------------------------------------------- * * HgfsVnodeGet -- * * Creates a vnode for the provided filename. * * This will always allocate a vnode and HgfsOpenFile. If a HgfsFile * already exists for this filename then that is used, if a HgfsFile doesn't * exist, one is created. * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * If the HgfsFile already exists, its reference count is incremented; * otherwise a HgfsFile is created. * *---------------------------------------------------------------------------- */ int HgfsVnodeGet(struct vnode **vpp, // OUT: Filled with address of created vnode HgfsSuperInfo *sip, // IN: Superinfo struct vfs *vfsp, // IN: Filesystem structure const char *fileName, // IN: Name of this file HgfsFileType fileType, // IN: Type of file HgfsFileHashTable *htp) // IN: File hash table { struct vnode *vp; ASSERT(vpp); ASSERT(sip); ASSERT(vfsp); ASSERT(fileName); ASSERT(htp); /* * Here we need to construct the vnode for the kernel as well as our * internal file system state. Our internal state consists of * a HgfsOpenFile and a HgfsFile. The HgfsOpenFile is state kept per-open * file; the HgfsFile state is kept per-file. We have a one-to-one mapping * between vnodes and HgfsOpenFiles, and a many-to-one mapping from each of * those to a HgfsFile. * * Note that it appears the vnode is intended to be used as a per-file * structure, but we are using it as a per-open-file. The sole exception * for this is the root vnode because it is returned by HgfsRoot(). This * also means that reference counts for all vnodes except the root should * be one; the reference count in our HgfsFile takes on the role of the * vnode reference count. */ /* * Note that we no longer embed the vnode in our private structure in * Solaris 9. This was done to simplify this code path and decrease the * differences between Solaris 9 and 10. */ # ifdef SOL9 vp = kmem_zalloc(sizeof *vp, HGFS_ALLOC_FLAG); # else vp = vn_alloc(HGFS_ALLOC_FLAG); # endif if (!vp) { return HGFS_ERR; } /* * Now we'll initialize the vnode. We need to set the file type, vnode * operations, flags, filesystem pointer, reference count, and device. * After that we'll create our private structures and hang them from the * vnode's v_data pointer. */ switch (fileType) { case HGFS_FILE_TYPE_REGULAR: vp->v_type = VREG; break; case HGFS_FILE_TYPE_DIRECTORY: vp->v_type = VDIR; break; default: /* Hgfs only supports directories and regular files */ goto vnode_error; } /* * Now set the vnode operations. This is handled differently on Solaris * 9 and 10, and we call HgfsSetVnodeOps() to take care of this for us. */ if (HgfsSetVnodeOps(vp) != 0) { goto vnode_error; } /* * The vnode cache constructor will have initialized the mutex for us on * Solaris 10, so we only do it ourselves on Solaris 9. */ # ifdef SOL9 mutex_init(&vp->v_lock, NULL, MUTEX_DRIVER, NULL); # endif vp->v_flag = HGFS_VNODE_INIT_FLAG; vp->v_count = HGFS_VNODE_INIT_COUNT; vp->v_vfsp = vfsp; vp->v_rdev = HGFS_VNODE_INIT_RDEV; /* * We now allocate our private open file structure. This will correctly * initialize the per-open-file state, as well as locate (or create if * necessary) the per-file state. */ vp->v_data = (void *)HgfsAllocOpenFile(fileName, fileType, htp); if (!vp->v_data) { goto openfile_error; } /* Fill in the provided address with the new vnode. */ *vpp = vp; /* Return success */ return 0; /* Cleanup points for errors. */ openfile_error: # ifdef SOL9 mutex_destroy(&vp->v_lock); # endif vnode_error: # ifdef SOL9 kmem_free(vp, sizeof *vp); # else vn_free(vp); # endif return HGFS_ERR; } /* *---------------------------------------------------------------------------- * * HgfsVnodePut -- * * Releases the provided vnode. * * This will always free both the vnode and its associated HgfsOpenFile. * The HgfsFile's reference count is decremented and, if 0, freed. * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * * *---------------------------------------------------------------------------- */ int HgfsVnodePut(struct vnode *vp, // IN: Vnode to release HgfsFileHashTable *htp) // IN: Hash table pointer { HgfsOpenFile *ofp; ASSERT(vp); ASSERT(htp); /* Get our private open-file state. */ ofp = HGFS_VP_TO_OFP(vp); if (!ofp) { // XXX Maybe ASSERT() this? return HGFS_ERR; } /* * We need to free the open file structure. This takes care of releasing * our reference on the underlying file structure (and freeing it if * necessary). */ HgfsFreeOpenFile(ofp, htp); /* * Now we clean up the vnode. */ # ifdef SOL9 mutex_destroy(&vp->v_lock); # endif # ifdef SOL9 kmem_free(vp, sizeof *vp); # else vn_free(vp); # endif return 0; } /* *---------------------------------------------------------------------------- * * HgfsVnodeDup -- * * Duplicates the vnode and HgfsOpenFile (per-open state) of a file and * increments the reference count of the underlying HgfsFile. This function * just calls HgfsVnodeGet with the right arguments. * * Results: * Returns 0 on success and a non-zero error code on failure. On success * the address of the duplicated vnode is written to newVpp. * * Side effects: * The HgfsFile for origVp will have an additional reference. * *---------------------------------------------------------------------------- */ int HgfsVnodeDup(struct vnode **newVpp, // OUT: Given address of new vnode struct vnode *origVp, // IN: Vnode to duplicate struct HgfsSuperInfo *sip, // IN: Superinfo pointer HgfsFileHashTable *htp) // IN: File hash table { ASSERT(newVpp); ASSERT(origVp); ASSERT(sip); ASSERT(htp); DEBUG(VM_DEBUG_ALWAYS, "HgfsVnodeDup: duping %s\n", HGFS_VP_TO_FILENAME(origVp)); return HgfsVnodeGet(newVpp, sip, origVp->v_vfsp, HGFS_VP_TO_FILENAME(origVp), HGFS_VP_TO_HGFSFILETYPE(origVp), &sip->fileHashTable); } /* *---------------------------------------------------------------------------- * * HgfsFileNameToVnode -- * * Allocates new per-open-file state if a HgfsFile for fileName exists in * the provided file hash table. * * Results: * Returns 0 on success or a non-zero error code on failure. On success, * vpp is filled with the address of the new per-open state. * * Side effects: * The reference count of the HgfsFile for fileName is incremented if it * exists. * *---------------------------------------------------------------------------- */ int HgfsFileNameToVnode(const char *fileName, struct vnode **vpp, struct HgfsSuperInfo *sip, struct vfs *vfsp, HgfsFileHashTable *htp) { HgfsFile *fp; HgfsFileType fileType; ASSERT(vpp); ASSERT(sip); ASSERT(vfsp); ASSERT(fileName); ASSERT(htp); /* * XXX: This locking here is not totally correct. Because we are calling * HgfsVnodeGet(), which does its own locking on the hash table, we must * make finding out the file is in the hash table and then creating our * internal state that increments that file's reference count non-atomic. * * Because of this, it is possible for the file to be in the hash table when * we look, then be removed by the time we look for it again. As * a consquence, we will add the file to the hash table then. This is * partially correct in the fact that the file was in the hash table when we * looked, but it is partially incorrect since it wasn't in the hash table * when we looked again. In practice this shouldn't cause any problems, but * it is possible for a file that is deleted on the host to remain in our * hash table longer than it should. * * A more correct locking scheme was not used because the complexity of * doing so outweighed the problems that can occur from this more simple * approach. This approach was also left as is because it provides an * optimization to the filesystem by decreasing the number of requests that * must be sent significantly. This optimization can be easily turned off * by commenting out the single call to this function in HgfsLookup() in * vnode.c. * * Possible solutions to this are: 1) adding new locks to the top-level * public functions (HgfsVnodeGet(), FileNameToVnode(), and NodeIdGet()), 2) * bringing the hash table locking up to those same functions, or 3) * reimplementing much of the call sequence down to the calls to FindFile() * and AddFile() in HgfsGetFile() that is specific to this function. 1 is * likely the best option as 2 uses hash table locks for an incorrect * purpose and 3 will create a significant amount of repeated code. */ DEBUG(VM_DEBUG_ALWAYS, "HgfsFileNameToVnode: looking for %s\n", fileName); mutex_enter(&htp->mutex); fp = HgfsFindFile(fileName, htp); if (!fp) { mutex_exit(&htp->mutex); return HGFS_ERR; } /* Guaranteed by HgfsFindFile(). */ ASSERT(strcmp(fileName, fp->fileName) == 0); /* * We save the type of this file with the lock held in case it goes away: * see the above comment about locking. */ fileType = fp->fileType; mutex_exit(&htp->mutex); DEBUG(VM_DEBUG_ALWAYS, "HgfsFileNameToVnode: found %s\n", fileName); return HgfsVnodeGet(vpp, sip, vfsp, fileName, fileType, htp); } /* *---------------------------------------------------------------------------- * * HgfsNodeIdGet -- * * Gets the node id for the provided file. This will only calculate the * node id again if a per-file state structure doesn't yet exist for this * file. (This situation exists on a readdir since dentries are filled in * rather than creating vnodes.) * * In Solaris, node ids are provided in vnodes and inode numbers are * provided in dentries. For applications to work correctly, we must make * sure that the inode number of a file's dentry and the node id in a file's * vnode match one another. This poses a problem since vnodes typically do * not exist when dentries need to be created, and once a dentry is created * we have no reference to it since it is copied to the user and freed from * kernel space. An example of a program that breaks when these values * don't match is /usr/bin/pwd. This program first acquires the node id of * "." from its vnode, then traverses backwards to ".." and looks for the * dentry in that directory with the inode number matching the node id. * (This is how it obtains the name of the directory it was just in.) * /usr/bin/pwd repeats this until it reaches the root directory, at which * point it concatenates the filenames it acquired along the way and * displays them to the user. When inode numbers don't match the node id, * /usr/bin/pwd displays an error saying it cannot determine the directory. * * The Hgfs protocol does not provide us with unique identifiers for files * since it must support filesystems that do not have the concept of inode * numbers. Therefore, we must maintain a mapping from filename to node id/ * inode numbers. This is done in a stateless manner by calculating the * SHA-1 hash of the filename. All points in the Hgfs code that need a node * id/inode number obtain it by either calling this function or directly * referencing the saved node id value in the vnode, if one is available. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsNodeIdGet(HgfsFileHashTable *htp, // IN: File hash table const char *fileName, // IN: Filename to get node id for uint32_t fileNameLength, // IN: Length of filename ino64_t *outNodeId) // OUT: Destination for nodeid { HgfsFile *fp; ASSERT(htp); ASSERT(fileName); ASSERT(outNodeId); mutex_enter(&htp->mutex); fp = HgfsFindFile(fileName, htp); if (fp) { *outNodeId = fp->nodeId; } else { HgfsNodeIdHash(fileName, fileNameLength, outNodeId); } mutex_exit(&htp->mutex); } /* *---------------------------------------------------------------------------- * * HgfsInitFileHashTable -- * * Initializes the hash table used to track per-file state. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsInitFileHashTable(HgfsFileHashTable *htp) // IN: Hash table to initialize { int i; ASSERT(htp); mutex_init(&htp->mutex, NULL, MUTEX_DRIVER, NULL); for (i = 0; i < ARRAYSIZE(htp->hashTable); i++) { DblLnkLst_Init(&htp->hashTable[i]); } } /* *---------------------------------------------------------------------------- * * HgfsFileHashTableIsEmpty -- * * Determines whether the hash table is in an acceptable state to unmount * the file system. * * Note that this is not strictly empty: if the only file in the table is * the root of the filesystem and its reference count is 1, this is * considered empty since this is part of the operation of unmounting the * filesystem. * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * None. * * *---------------------------------------------------------------------------- */ Bool HgfsFileHashTableIsEmpty(HgfsSuperInfo *sip, // IN: Superinfo HgfsFileHashTable *htp) // IN: File hash table { int i; ASSERT(sip); ASSERT(htp); mutex_enter(&htp->mutex); /* Traverse each bucket. */ for (i = 0; i < ARRAYSIZE(htp->hashTable); i++) { DblLnkLst_Links *currNode = HGFS_FILE_HT_HEAD(htp, i); /* Visit each file in this bucket */ while (currNode != HGFS_FILE_HT_BUCKET(htp, i)) { HgfsFile *currFile = DblLnkLst_Container(currNode, HgfsFile, listNode); /* * Here we special case the root of our filesystem. In a correct * unmount, the root vnode of the filesystem will have an entry in the * hash table and will have a reference count of 1. We check if the * current entry is the root file, and if so, make sure its vnode's * reference count is not > 1. Note that we are not mapping from file * to vnode here (which is not possible), we are using the root vnode * stored in the superinfo structure. This is the only vnode that * should have multiple references associated with it because whenever * someone calls HgfsRoot(), we return that vnode. */ if (HGFS_IS_ROOT_FILE(sip, currFile)) { mutex_enter(&HGFS_ROOT_VNODE(sip)->v_lock); if (HGFS_ROOT_VNODE(sip)->v_count <= 1) { mutex_exit(&HGFS_ROOT_VNODE(sip)->v_lock); /* This file is okay; skip to the next one. */ currNode = currNode->next; continue; } DEBUG(VM_DEBUG_FAIL, "HgfsFileHashTableIsEmpty: %s has count of %d.\n", currFile->fileName, HGFS_ROOT_VNODE(sip)->v_count); mutex_exit(&HGFS_ROOT_VNODE(sip)->v_lock); /* Fall through to failure case */ } /* Fail if a file is found. */ mutex_exit(&htp->mutex); DEBUG(VM_DEBUG_FAIL, "HgfsFileHashTableIsEmpty: %s " "still in use (file count=%d).\n", currFile->fileName, currFile->refCount); return FALSE; } } mutex_exit(&htp->mutex); return TRUE; } /* *---------------------------------------------------------------------------- * * HgfsDebugPrintFileHashTable -- * * This will print out all the HgfsFiles that we have in the hash table, as * well as the HgfsFile reference count. This should help finding places * where there may be loose references on files that prevent an unmount * (EBUSY) when it should be allowed. * * Results: * Void. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsDebugPrintFileHashTable(HgfsFileHashTable *htp, // IN: Hash table to print int level) // IN: Debugging level { int bucket; ASSERT(htp); mutex_enter(&htp->mutex); for (bucket = 0; bucket < ARRAYSIZE(htp->hashTable); bucket++) { DblLnkLst_Links *currNode = HGFS_FILE_HT_HEAD(htp, bucket); while (currNode != HGFS_FILE_HT_BUCKET(htp, bucket)) { HgfsFile *currFile = DblLnkLst_Container(currNode, HgfsFile, listNode); mutex_enter(&currFile->mutex); DEBUG(level, "HgfsDebugPrintFileHashTable: " "file: %s, count: %d (bucket %d)\n", currFile->fileName, currFile->refCount, bucket); mutex_exit(&currFile->mutex); currNode = currNode->next; } } mutex_exit(&htp->mutex); } /* *---------------------------------------------------------------------------- * * HgfsHandleIsSet -- * * Determines whether handle of the vnode's open file is currently set. * * Results: * Returns TRUE if the handle is set, FALSE if the handle is not set. * HGFS_ERR is returned on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool HgfsHandleIsSet(struct vnode *vp) // IN: Vnode to check handle of { HgfsOpenFile *ofp; Bool isSet; ASSERT(vp); ofp = HGFS_VP_TO_OFP(vp); if (!ofp) { return HGFS_ERR; } mutex_enter(&ofp->handleMutex); isSet = ofp->handleIsSet; mutex_exit(&ofp->handleMutex); return isSet; } /* *---------------------------------------------------------------------------- * * HgfsSetOpenFileHandle -- * * Sets the open file handle for the provided vnode. * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * The handle may not be set again until it is cleared. * *---------------------------------------------------------------------------- */ int HgfsSetOpenFileHandle(struct vnode *vp, // IN: Vnode to set handle for HgfsHandle handle) // IN: Value of handle { HgfsOpenFile *ofp; ASSERT(vp); ofp = HGFS_VP_TO_OFP(vp); if (!ofp) { return HGFS_ERR; } mutex_enter(&ofp->handleMutex); if (ofp->handleIsSet) { DEBUG(VM_DEBUG_FAIL, "**HgfsSetOpenFileHandle: handle for %s already set to %d; " "cannot set to %d\n", HGFS_VP_TO_FILENAME(vp), ofp->handle, handle); mutex_exit(&ofp->handleMutex); return HGFS_ERR; } ofp->handle = handle; ofp->handleIsSet = TRUE; DEBUG(VM_DEBUG_STATE, "HgfsSetOpenFileHandle: set handle for %s to %d\n", HGFS_VP_TO_FILENAME(vp), ofp->handle); mutex_exit(&ofp->handleMutex); return 0; } /* *---------------------------------------------------------------------------- * * HgfsGetOpenFileHandle -- * * Gets the open file handle for the provided vnode. * * Results: * Returns 0 on success and a non-zero error code on failure. On success, * the value of the vnode's handle is placed in outHandle. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsGetOpenFileHandle(struct vnode *vp, // IN: Vnode to get handle for HgfsHandle *outHandle) // OUT: Filled with value of handle { HgfsOpenFile *ofp; ASSERT(vp); ASSERT(outHandle); ofp = HGFS_VP_TO_OFP(vp); if (!ofp) { return HGFS_ERR; } mutex_enter(&ofp->handleMutex); if (!ofp->handleIsSet) { DEBUG(VM_DEBUG_FAIL, "**HgfsGetOpenFileHandle: handle for %s is not set.\n", HGFS_VP_TO_FILENAME(vp)); mutex_exit(&ofp->handleMutex); return HGFS_ERR; } *outHandle = ofp->handle; mutex_exit(&ofp->handleMutex); return 0; } /* *---------------------------------------------------------------------------- * * HgfsClearOpenFileHandle -- * * Clears the open file handle for the provided vnode. * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * The handle may be set. * *---------------------------------------------------------------------------- */ int HgfsClearOpenFileHandle(struct vnode *vp) // IN: Vnode to clear handle for { HgfsOpenFile *ofp; ASSERT(vp); ofp = HGFS_VP_TO_OFP(vp); if (!ofp) { return HGFS_ERR; } mutex_enter(&ofp->handleMutex); ofp->handle = 0; ofp->handleIsSet = FALSE; DEBUG(VM_DEBUG_STATE, "HgfsClearOpenFileHandle: cleared %s's handle\n", HGFS_VP_TO_FILENAME(vp)); mutex_exit(&ofp->handleMutex); return 0; } /* *---------------------------------------------------------------------------- * * HgfsSetOpenFileMode -- * * Sets the mode of the open file for the provided vnode. * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * The mode may not be set again until cleared. * *---------------------------------------------------------------------------- */ int HgfsSetOpenFileMode(struct vnode *vp, // IN: Vnode to set mode for HgfsMode mode) // IN: Mode to set to { HgfsOpenFile *ofp; ASSERT(vp); ofp = HGFS_VP_TO_OFP(vp); if (!ofp) { return HGFS_ERR; } mutex_enter(&ofp->modeMutex); if (ofp->modeIsSet) { DEBUG(VM_DEBUG_FAIL, "**HgfsSetOpenFileMode: mode for %s already set to %d; " "cannot set to %d\n", HGFS_VP_TO_FILENAME(vp), ofp->mode, mode); mutex_exit(&ofp->modeMutex); return HGFS_ERR; } ofp->mode = mode; ofp->modeIsSet = TRUE; DEBUG(VM_DEBUG_STATE, "HgfsSetOpenFileMode: set mode for %s to %d\n", HGFS_VP_TO_FILENAME(vp), ofp->mode); mutex_exit(&ofp->modeMutex); return 0; } /* *---------------------------------------------------------------------------- * * HgfsGetOpenFileMode -- * * Gets the mode of the open file for the provided vnode. * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsGetOpenFileMode(struct vnode *vp, // IN: Vnode to get mode for HgfsMode *outMode) // OUT: Filled with mode { HgfsOpenFile *ofp; ASSERT(vp); ASSERT(outMode); ofp = HGFS_VP_TO_OFP(vp); if (!ofp) { return HGFS_ERR; } mutex_enter(&ofp->modeMutex); if (!ofp->modeIsSet) { // DEBUG(VM_DEBUG_FAIL, "**HgfsGetOpenFileMode: mode for %s is not set.\n", // HGFS_VP_TO_FILENAME(vp)); mutex_exit(&ofp->modeMutex); return HGFS_ERR; } *outMode = ofp->mode; mutex_exit(&ofp->modeMutex); return 0; } /* *---------------------------------------------------------------------------- * * HgfsClearOpenFileMode -- * * Clears the mode of the open file for the provided vnode. * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * The mode may be set again. * *---------------------------------------------------------------------------- */ int HgfsClearOpenFileMode(struct vnode *vp) // IN: Vnode to clear mode for { HgfsOpenFile *ofp; ASSERT(vp); ofp = HGFS_VP_TO_OFP(vp); if (!ofp) { return HGFS_ERR; } mutex_enter(&ofp->modeMutex); ofp->mode = 0; ofp->modeIsSet = FALSE; DEBUG(VM_DEBUG_STATE, "HgfsClearOpenFileMode: cleared %s's mode\n", HGFS_VP_TO_FILENAME(vp)); mutex_exit(&ofp->modeMutex); return 0; } /* * Internal functions */ /* Allocation/initialization/free of open file state */ /* *---------------------------------------------------------------------------- * * HgfsAllocOpenFile -- * * Allocates and initializes an open file structure. Also finds or, if * necessary, creates the underlying HgfsFile per-file state. * * Results: * Returns a pointer to the open file on success, NULL on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static HgfsOpenFile * HgfsAllocOpenFile(const char *fileName, // IN: Name of file HgfsFileType fileType, // IN: Type of file HgfsFileHashTable *htp) // IN: Hash table { HgfsOpenFile *ofp; ASSERT(fileName); ASSERT(htp); /* * We allocate and initialize our open-file state. */ ofp = (HgfsOpenFile *)kmem_zalloc(sizeof *ofp, HGFS_ALLOC_FLAG); /* kmem_zalloc() cannot fail if given KM_SLEEP; check otherwise */ # if HGFS_ALLOC_FLAG != KM_SLEEP if (!ofp) { return NULL; } # endif /* Manually set these since the public functions need the lock. */ ofp->handle = 0; ofp->handleIsSet = FALSE; ofp->mode = 0; ofp->modeIsSet = FALSE; mutex_init(&ofp->handleMutex, NULL, MUTEX_DRIVER, NULL); mutex_init(&ofp->handleMutex, NULL, MUTEX_DRIVER, NULL); /* * Now we get a reference to the underlying per-file state. */ ofp->hgfsFile = HgfsGetFile(fileName, fileType, htp); if (!ofp->hgfsFile) { kmem_free(ofp, sizeof *ofp); return NULL; } return ofp; } /* *---------------------------------------------------------------------------- * * HgfsFreeOpenFile -- * * Frees the provided open file. * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void HgfsFreeOpenFile(HgfsOpenFile *ofp, // IN: Open file to free HgfsFileHashTable *htp) // IN: File hash table { ASSERT(ofp); ASSERT(htp); /* * First we release our reference to the underlying per-file state. */ HgfsReleaseFile(ofp->hgfsFile, htp); /* * Then we destroy anything initialized and free the open file. */ mutex_destroy(&ofp->handleMutex); mutex_destroy(&ofp->modeMutex); kmem_free(ofp, sizeof *ofp); } /* Acquiring/releasing file state */ /* *---------------------------------------------------------------------------- * * HgfsGetFile -- * * Gets the file for the provided filename. * * If no file structure exists for this filename, one is created and added * to the hash table. * * Results: * Returns a pointer to the file on success, NULL on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static HgfsFile * HgfsGetFile(const char *fileName, // IN: Filename to get file for HgfsFileType fileType, // IN: Type of file HgfsFileHashTable *htp) // IN: Hash table to look in { HgfsFile *fp; int err; ASSERT(fileName); ASSERT(htp); /* * We try to find the file in the hash table. If it exists we increment its * reference count and return it. */ mutex_enter(&htp->mutex); fp = HgfsFindFile(fileName, htp); if (fp) { /* Signify our reference to this file. */ mutex_enter(&fp->mutex); fp->refCount++; mutex_exit(&fp->mutex); mutex_exit(&htp->mutex); return fp; } DEBUG(VM_DEBUG_ALWAYS, "HgfsGetFile: allocated HgfsFile for %s.\n", fileName); /* * If it doesn't exist we create one, initialize it, and add it to the hash * table. */ fp = (HgfsFile *)kmem_zalloc(sizeof *fp, HGFS_ALLOC_FLAG); # if HGFS_ALLOC_FLAG != KM_SLEEP if (!fp) { /* fp is NULL already */ goto out; } # endif err = HgfsInitFile(fp, fileName, fileType); if (err) { kmem_free(fp, sizeof *fp); fp = NULL; goto out; } /* * This is guaranteed to not add a duplicate since we checked above and have * held the lock until now. */ HgfsAddFile(fp, htp); out: mutex_exit(&htp->mutex); DEBUG(VM_DEBUG_DONE, "HgfsGetFile: done\n"); return fp; } /* *---------------------------------------------------------------------------- * * HgfsReleaseFile -- * * Releases a reference to the provided file. If the reference count of * this file becomes zero, the file structure is removed from the hash table * and freed. * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void HgfsReleaseFile(HgfsFile *fp, // IN: File to release HgfsFileHashTable *htp) // IN: Hash table to look in/remove from { ASSERT(fp); ASSERT(htp); /* * Decrement this file's reference count. If it becomes zero, then we * remove it from the hash table and free it. */ mutex_enter(&fp->mutex); if ( !(--fp->refCount) ) { mutex_exit(&fp->mutex); /* Remove file from hash table, then clean up. */ HgfsRemoveFile(fp, htp); DEBUG(VM_DEBUG_ALWAYS, "HgfsReleaseFile: freeing HgfsFile for %s.\n", fp->fileName); rw_destroy(&fp->rwlock); mutex_destroy(&fp->mutex); kmem_free(fp, sizeof *fp); return; } DEBUG(VM_DEBUG_ALWAYS, "HgfsReleaseFile: %s has %d references.\n", fp->fileName, fp->refCount); mutex_exit(&fp->mutex); } /* Allocation/initialization/free of file state */ /* *---------------------------------------------------------------------------- * * HgfsInitFile -- * * Initializes a file structure. * * This sets the filename of the file and initializes other structure * elements. * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsInitFile(HgfsFile *fp, // IN: File to initialize const char *fileName, // IN: Name of file HgfsFileType fileType) // IN: Type of file { int len; ASSERT(fp); ASSERT(fileName); /* Make sure the filename will fit. */ len = strlen(fileName); if (len > sizeof fp->fileName - 1) { return HGFS_ERR; } fp->fileNameLength = len; memcpy(fp->fileName, fileName, len + 1); fp->fileName[fp->fileNameLength] = '\0'; /* * We save the file type so we can recreate a vnode for the HgfsFile without * sending a request to the Hgfs Server. */ fp->fileType = fileType; /* Initialize the links to place this file in our hash table. */ DblLnkLst_Init(&fp->listNode); /* * Fill in the node id. This serves as the inode number in directory * entries and the node id in vnode attributes. */ HgfsNodeIdHash(fp->fileName, fp->fileNameLength, &fp->nodeId); /* * The reader/write lock is for the rwlock/rwunlock vnode entry points and * the mutex is to protect the reference count on this structure. */ rw_init(&fp->rwlock, NULL, RW_DRIVER, NULL); mutex_init(&fp->mutex, NULL, MUTEX_DRIVER, NULL); /* The caller is the single reference. */ fp->refCount = 1; return 0; } /* Adding/finding/removing file state from hash table */ /* *---------------------------------------------------------------------------- * * HgfsAddFile -- * * Adds the file to the hash table. * * This function must be called with the hash table lock held. This is done * so adding the file in the hash table can be made with any other * operations (such as previously finding out that this file wasn't in the * hash table). * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static inline void HgfsAddFile(HgfsFile *fp, // IN: File to add HgfsFileHashTable *htp) // IN: Hash table to add to { unsigned int index; ASSERT(fp); ASSERT(htp); index = HgfsFileNameHash(fp->fileName); /* Add this file to the end of the bucket's list */ DblLnkLst_LinkLast(HGFS_FILE_HT_HEAD(htp, index), &fp->listNode); } /* *---------------------------------------------------------------------------- * * HgfsRemoveFile -- * * Removes file from the hash table. * * Note that unlike the other two hash functions, this one performs its own * locking since the removal doesn't need to be atomic with other * operations. (This could change in the future if the functions that use * this one are reorganized.) * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static inline void HgfsRemoveFile(HgfsFile *fp, // IN: File to remove HgfsFileHashTable *htp) // IN: Hash table to remove from { ASSERT(fp); ASSERT(htp); mutex_enter(&htp->mutex); /* Take this file off its list */ DblLnkLst_Unlink1(&fp->listNode); mutex_exit(&htp->mutex); } /* *---------------------------------------------------------------------------- * * HgfsFindFile -- * * Looks for a filename in the hash table. * * This function must be called with the hash table lock held. This is done * so finding the file in the hash table and using it (after this function * returns) can be atomic. * * Results: * Returns a pointer to the file if found, NULL otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static HgfsFile * HgfsFindFile(const char *fileName, // IN: Filename to look for HgfsFileHashTable *htp) // IN: Hash table to look in { HgfsFile *found = NULL; DblLnkLst_Links *currNode; unsigned int index; ASSERT(fileName); ASSERT(htp); /* Determine which bucket. */ index = HgfsFileNameHash(fileName); /* Traverse the bucket's list. */ for (currNode = HGFS_FILE_HT_HEAD(htp, index); currNode != HGFS_FILE_HT_BUCKET(htp, index); currNode = currNode->next) { HgfsFile *curr; curr = DblLnkLst_Container(currNode, HgfsFile, listNode); if (strcmp(curr->fileName, fileName) == 0) { /* We found the file we want. */ found = curr; break; } } /* Return file if found. */ return found; } /* Other utility functions */ /* *---------------------------------------------------------------------------- * * HgfsFileNameHash -- * * Hashes the filename to get an index into the hash table. This is known * as the PJW string hash function and it was taken from "Mastering * Algorithms in C". * * Results: * Returns an index between 0 and HGFS_HT_NR_BUCKETS. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static unsigned int HgfsFileNameHash(const char *fileName) // IN: Filename to hash { unsigned int val = 0; ASSERT(fileName); while (*fileName != '\0') { unsigned int tmp; val = (val << 4) + (*fileName); if ((tmp = (val & 0xf0000000))) { val = val ^ (tmp >> 24); val = val ^ tmp; } fileName++; } return val % HGFS_HT_NR_BUCKETS; } /* *---------------------------------------------------------------------------- * * HgfsNodeIdHash -- * * Hashes the provided filename to generate a node id. * * Results: * None. The value of the hash is filled into outHash. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void HgfsNodeIdHash(const char *fileName, // IN: Filename to hash uint32_t fileNameLength, // IN: Length of the filename ino64_t *outHash) // OUT: Location to write hash to { SHA1_CTX hashContext; unsigned char digest[SHA1_HASH_LEN]; int i; ASSERT(fileName); ASSERT(outHash); /* Make sure we start at a consistent state. */ memset(&hashContext, 0, sizeof hashContext); memset(digest, 0, sizeof digest); memset(outHash, 0, sizeof *outHash); /* Generate a SHA1 hash of the filename */ SHA1Init(&hashContext); SHA1Update(&hashContext, (unsigned char *)fileName, fileNameLength); SHA1Final(digest, &hashContext); /* * Fold the digest into the allowable size of our hash. * * For each group of bytes the same size as our output hash, xor the * contents of the digest together. If there are less than that many bytes * left in the digest, xor each byte that's left. */ for(i = 0; i < sizeof digest; i += sizeof *outHash) { int bytesLeft = sizeof digest - i; /* Do a byte-by-byte xor if there aren't enough bytes left in the digest */ if (bytesLeft < sizeof *outHash) { int j; for (j = 0; j < bytesLeft; j++) { uint8 *outByte = (uint8 *)outHash + j; uint8 *inByte = (uint8 *)((u_longlong_t *)(digest + i)) + j; *outByte ^= *inByte; } break; } /* Block xor */ *outHash ^= *((u_longlong_t *)(digest + i)); } /* * Clear the most significant byte so that user space apps depending on * a node id/inode number that's only 32 bits won't break. (For example, * gedit's call to stat(2) returns EOVERFLOW if we don't do this.) */ # ifndef HGFS_BREAK_32BIT_USER_APPS *((uint32_t *)outHash) ^= *((uint32_t *)outHash + 1); *((uint32_t *)outHash + 1) = 0; # endif DEBUG(VM_DEBUG_INFO, "Hash of: %s (%d) is %"FMT64"u\n", fileName, fileNameLength, *outHash); return; } open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/kernelStubs.h0000644765153500003110000001077312220061556022537 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * kernelStubs.h * * KernelStubs implements some userspace library functions in terms * of kernel functions to allow library userspace code to be used in a * kernel. */ #ifndef __KERNELSTUBS_H__ #define __KERNELSTUBS_H__ #ifdef linux # ifndef __KERNEL__ # error "__KERNEL__ is not defined" # endif # include "driver-config.h" // Must be included before any other header files # include "vm_basic_types.h" # include # include #elif defined(_WIN32) # include "vm_basic_types.h" # include /* kernel memory APIs */ # include /* for _vsnprintf, vsprintf */ # include /* for va_start stuff */ # include /* for min macro. */ # include "vm_assert.h" /* Our assert macros */ #elif defined(__FreeBSD__) # include "vm_basic_types.h" # ifndef _KERNEL # error "_KERNEL is not defined" # endif # include # include # include # include # include # include #elif defined(__APPLE__) # include "vm_basic_types.h" # ifndef KERNEL # error "KERNEL is not defined" # endif # include # include # elif defined(sun) # include "vm_basic_types.h" # include # include #endif /* * Function Prototypes */ #if defined(linux) || defined(__APPLE__) || defined (sun) # ifdef linux /* if (linux) { */ char *strdup(const char *source); # endif /* Shared between Linux and Apple kernel stubs. */ void *malloc(size_t size); void free(void *mem); void *calloc(size_t num, size_t len); void *realloc(void *ptr, size_t newSize); #elif defined(_WIN32) /* } else if (_WIN32) { */ #if (_WIN32_WINNT == 0x0400) /* The following declarations are missing on NT4. */ typedef unsigned int UINT_PTR; typedef unsigned int SIZE_T; /* No free with tag availaible on NT4 kernel! */ #define KRNL_STUBS_FREE(P,T) ExFreePool((P)) #else /* _WIN32_WINNT */ #define KRNL_STUBS_FREE(P,T) ExFreePoolWithTag((P),(T)) /* Win 2K and later useful kernel function, documented but not declared! */ NTKERNELAPI VOID ExFreePoolWithTag(IN PVOID P, IN ULONG Tag); #endif /* _WIN32_WINNT */ #elif defined(__FreeBSD__) /* } else if (FreeBSD) { */ /* Kernel memory on FreeBSD is tagged for statistics and sanity checking. */ MALLOC_DECLARE(M_VMWARE_TEMP); /* * On FreeBSD, the general memory allocator for both userland and the kernel is named * malloc, but the kernel malloc() takes more arguments. The following alias & macros * work around this, to provide the standard malloc() API for userspace code that is * being used in the kernel. */ # undef malloc static INLINE void * __compat_malloc(unsigned long size, struct malloc_type *type, int flags) { return malloc(size, type, flags); } # define malloc(size) __compat_malloc(size, M_VMWARE_TEMP, M_NOWAIT) # define calloc(count, size) __compat_malloc((count) * (size), \ M_VMWARE_TEMP, M_NOWAIT|M_ZERO) # define realloc(buf, size) realloc(buf, size, M_VMWARE_TEMP, M_NOWAIT) # define free(buf) free(buf, M_VMWARE_TEMP) # define strchr(s,c) index(s,c) # define strrchr(s,c) rindex(s,c) #endif /* } */ /* * Stub functions we provide. */ void Panic(const char *fmt, ...); char *Str_Strcpy(char *buf, const char *src, size_t maxSize); int Str_Vsnprintf(char *str, size_t size, const char *format, va_list arguments); char *Str_Vasprintf(size_t *length, const char *format, va_list arguments); char *Str_Asprintf(size_t *length, const char *Format, ...); /* * Functions the driver must implement for the stubs. */ EXTERN void Debug(const char *fmt, ...); #endif /* __KERNELSTUBS_H__ */ open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/filesystem.c0000644765153500003110000005621312220061556022414 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * filesystem.c -- * * Implementation of the filesystem level routines. These include functions * that intialize, mount, unmount, and provide other various filesystem * information. */ #include /* MAXNAMELEN */ #include /* FKIOCTL */ #include "hgfsSolaris.h" #include "hgfsState.h" #include "filesystem.h" #include "vnode.h" #include "request.h" #include "debug.h" /* * Prototypes * * These are only needed because Solaris 10 requires that we create the vfsops * structure through their provided interface (vfs_setfsops()). */ #if HGFS_VFS_VERSION > 2 int HgfsMount(struct vfs *vfsp, struct vnode *vnodep, struct mounta *mntp, struct cred *credp); int HgfsUnmount(struct vfs *vfsp, int mflag, struct cred *credp); int HgfsRoot(struct vfs *vfsp, struct vnode **vnodepp); int HgfsStatvfs(struct vfs *vfsp, struct statvfs64 *stats); int HgfsSync(struct vfs *vfsp, short flags, struct cred *credp); int HgfsVget(struct vfs *vfsp, struct vnode **vnodepp, struct fid *fidp); int HgfsMountroot(struct vfs *vfsp, enum whymountroot reason); int HgfsVnstate(vfs_t *vfsp, vnode_t *vp, vntrans_t trans); #if HGFS_VFS_VERSION == 3 int HgfsFreevfs(struct vfs *vfsp); #else void HgfsFreevfs(struct vfs *vfsp); #endif #endif #if HGFS_VFS_VERSION > 2 static vfsops_t *hgfsVfsOpsP; #endif /* * Fileystem type number given to us upon initialization. */ static int hgfsType; #if HGFS_VFS_VERSION == 2 /* *---------------------------------------------------------------------------- * * HgfsInit -- * * This is the filesystem initialization routine which is run when the * filesystem is placed in the VFS switch table. * * Results: * Returns zero on success. * * Side effects: * The filesystem type (index number) is set to the provided value. * *---------------------------------------------------------------------------- */ int HgfsInit(struct vfssw *vfsswp, // IN: VFS Switch table struct int fstype) // IN: Index into the vfssw table for this filesystem { if (!vfsswp) { cmn_err(HGFS_ERROR, "HgfsInit: received NULL input from Kernel.\n"); return EINVAL; } DEBUG(VM_DEBUG_ENTRY, "HgfsInit().\n"); /* * Hook VFS operations into switch table and save * filesystem type number and pointer to vfsswp. */ vfsswp->vsw_vfsops = &HgfsVfsOps; hgfsType = fstype; mutex_init(&vfsswp->vsw_lock, NULL, MUTEX_DRIVER, NULL); DEBUG(VM_DEBUG_LOAD, "fstype: %d\n", hgfsType); HgfsDebugPrintVfssw("HgfsInit()", vfsswp); DEBUG(VM_DEBUG_DONE, "HgfsInit() done.\n"); return 0; } #else /* Implies Solaris > 9 */ /* *---------------------------------------------------------------------------- * * HgfsInit -- * * This is the filesystem initialization routine for Solaris 10. It creates * an array of fs_operation_def_t for all the vfs operations, then calls * vfs_setfsops() to assign them to the filesystem properly. * * Results: * Returns 0 on success and a non-zero error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsInit(int fstype, // IN: Filesystem type char *name) // IN: Name of the filesystem { int ret; /* Construct the VFS operations array to give to vfs_setfsops() */ static fs_operation_def_t vfsOpsArr[] = { HGFS_VOP(VFSNAME_MOUNT, vfs_mount, HgfsMount), HGFS_VOP(VFSNAME_UNMOUNT, vfs_unmount, HgfsUnmount), HGFS_VOP(VFSNAME_ROOT, vfs_root, HgfsRoot), HGFS_VOP(VFSNAME_STATVFS, vfs_statvfs, HgfsStatvfs), HGFS_VOP(VFSNAME_VGET, vfs_vget, HgfsVget), HGFS_VOP(VFSNAME_MOUNTROOT, vfs_mountroot, HgfsMountroot), HGFS_VOP(VFSNAME_FREEVFS, vfs_freevfs, HgfsFreevfs), HGFS_VOP(VFSNAME_VNSTATE, vfs_vnstate, HgfsVnstate), #if HGFS_VFS_VERSION <= 3 HGFS_VOP(VFSNAME_SYNC, vfs_vnstate, (fs_generic_func_p)HgfsSync), { NULL, NULL } #else HGFS_VOP(VFSNAME_SYNC, vfs_sync, HgfsSync), { NULL, { NULL }}, #endif }; if (!name) { cmn_err(HGFS_ERROR, "HgfsInit: received NULL input from Kernel.\n"); return EINVAL; } DEBUG(VM_DEBUG_ENTRY, "HgfsInit: fstype=%d, name=\"%s\"\n", fstype, name); /* Assign VFS operations to our filesystem. */ ret = vfs_setfsops(fstype, vfsOpsArr, &hgfsVfsOpsP); if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsInit: vfs_setfsops returned %d\n", ret); return ret; } ret = HgfsMakeVnodeOps(); if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsInit: could not register HGFS Vnode Ops.\n"); vfs_freevfsops_by_type(fstype); ret = EIO; return ret; } /* Set our filesystem type. */ hgfsType = fstype; DEBUG(VM_DEBUG_DONE, "HgfsInit: done. (fstype=%d)\n", hgfsType); return 0; } #endif /* *---------------------------------------------------------------------------- * * HgfsFreeVfsOps -- * * Free VFS Ops created when we initialized the filesystem. * * Results: * None. * * Side effects: * Resets hgfsVfsOpsP back to NULL. * *---------------------------------------------------------------------------- */ void HgfsFreeVfsOps(void) { #if HGFS_VFS_VERSION > 2 if (hgfsVfsOpsP) { vfs_freevfsops_by_type(hgfsType); } #endif } /* * VFS Entry Points */ /* *---------------------------------------------------------------------------- * * HgfsMount -- * * This function is invoked when mount(2) is called on our filesystem. * The filesystem is mounted on the supplied vnode. * * Results: * Returns zero on success and an appropriate error code on error. * * Side effects: * The filesystem is mounted on top of vnodep. * *---------------------------------------------------------------------------- */ int HgfsMount(struct vfs *vfsp, // IN: Filesystem to mount struct vnode *vnodep, // IN: Vnode that we are mounting on struct mounta *mntp, // IN: Arguments to mount(2) from user struct cred *credp) // IN: Credentials of caller { HgfsSuperInfo *sip; HgfsMountData *mountData; int ret; dev_t dev; if (!vfsp || !vnodep || !mntp || !credp) { cmn_err(HGFS_ERROR, "HgfsMount: NULL input from Kernel.\n"); return EINVAL; } DEBUG(VM_DEBUG_ENTRY, "HgfsMount().\n"); //HgfsDebugPrintVfs("HgfsMount", vfsp); //HgfsDebugPrintVnode(VM_DEBUG_STRUCT, "HgfsMount", vnodep, FALSE); //HgfsDebugPrintMounta("HgfsMount", mntp); //HgfsDebugPrintCred("HgfsMount", credp); if (!HgfsSuser(credp)) { return EPERM; } if (mntp->datalen != sizeof *mountData) { DEBUG(VM_DEBUG_FAIL, "HgfsMount: bad data size (%lu vs %lu).\n", (unsigned long) mntp->datalen, (unsigned long) sizeof *mountData); return EINVAL; } mountData = kmem_zalloc(sizeof *mountData, HGFS_ALLOC_FLAG); if (!mountData) { return ENOMEM; } if (ddi_copyin(mntp->dataptr, mountData, sizeof *mountData, mntp->flags & MS_SYSSPACE ? FKIOCTL : 0) == -1) { DEBUG(VM_DEBUG_FAIL, "HgfsMount: couldn't copy mount data.\n"); ret = EFAULT; goto out; } /* * Make sure mount data matches what mount program will send us. */ if (mountData->magic != HGFS_MAGIC) { DEBUG(VM_DEBUG_FAIL, "HgfsMount: received invalid magic value: %x\n", mountData->magic); ret = EINVAL; goto out; } /* We support only one instance of hgfs, at least for now */ if (HgfsGetSuperInfo()) { DEBUG(VM_DEBUG_FAIL, "HgfsMount: HGFS is already mounted somewhere\n"); ret = EBUSY; goto out; } /* * We need to find a unique device number for this VFS that will be used to * construct the filesystem id. */ if ((dev = getudev()) == -1) { DEBUG(VM_DEBUG_FAIL, "HgfsMount(): getudev() failed.\n"); ret = ENXIO; goto out; } DEBUG(VM_DEBUG_LOAD, "HgfsMount: dev=%lu\n", dev); if (vfs_devismounted(dev)) { DEBUG(VM_DEBUG_FAIL, "HgfsMount(): dev is not unique. We should loop on this.\n"); ret = ENXIO; goto out; } /* * Fill in values of the VFS structure for the kernel. * * There are several important values that must be set. In particular, we * need to create a chain of pointers so the Kernel can easily move between * the various filesystems mounted on the system. * * o Each filesystem must set its vfs_vnodecovered to the vnode of the * directory it is mounted upon. * o Each directory that is a mount point must set v_vfsmountedhere to * point to the vfs struct of the filesystem mounted there. * o The root vnode of each filesystem must have the VROOT flag set in its * vnode's v_flag so that the Kernel knows to consult the two previously * mentioned pointers. */ vfsp->vfs_vnodecovered = vnodep; vfsp->vfs_flag &= ~VFS_UNMOUNTED; vfsp->vfs_flag |= HGFS_VFS_FLAGS; vfsp->vfs_bsize = HGFS_VFS_BSIZE; vfsp->vfs_fstype = hgfsType; vfsp->vfs_bcount = 0; /* If we had mount options, we'd call vfs_setmntopt with vfsp->vfs_mntopts */ vfsp->vfs_dev = dev; vfs_make_fsid(&vfsp->vfs_fsid, vfsp->vfs_dev, hgfsType); /* * Fill in value(s) of the vnode structure we are mounted on top of. We * aren't allowed to modify this ourselves in Solaris 10. */ # if HGFS_VFS_VERSION == 2 vnodep->v_vfsmountedhere = vfsp; # endif HgfsInitSuperInfo(vfsp); sip = HgfsGetSuperInfo(); vfsp->vfs_data = (caddr_t)sip; if (!sip->transportInit()) { DEBUG(VM_DEBUG_FAIL, "HgfsMount: failed to start transport.\n"); HgfsClearSuperInfo(); ret = EIO; goto out; } /* * Now create the root vnode of the filesystem. * * Note: do not change the name from "/" here without first checking that * HgfsMakeFullName() in vnode.c will still do the right thing. (See the * comment for the ".." special case.) */ ret = HgfsVnodeGet(&sip->rootVnode, // vnode to fill in sip, // Superinfo vfsp, // This filesystem "/", // File name HGFS_FILE_TYPE_DIRECTORY, // File type &sip->fileHashTable); // File hash table if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsMount: couldn't get root vnode.\n"); sip->transportCleanup(); HgfsClearSuperInfo(); ret = EIO; goto out; } /* We must signify that this is the root of our filesystem. */ mutex_enter(&sip->rootVnode->v_lock); sip->rootVnode->v_flag |= VROOT; mutex_exit(&sip->rootVnode->v_lock); /* XXX do this? */ VN_HOLD(vnodep); DEBUG(VM_DEBUG_DONE, "HgfsMount() done.\n"); ret = 0; /* Return success */ out: kmem_free(mountData, sizeof *mountData); return ret; } /* *---------------------------------------------------------------------------- * * HgfsUnmount -- * * This function is invoked when umount(2) is called on our filesystem. * * Results: * Returns 0 on success and an error code on error. * * Side effects: * The root vnode will be freed. * *---------------------------------------------------------------------------- */ int HgfsUnmount(struct vfs *vfsp, // IN: This filesystem int mflag, // IN: Unmount flags struct cred *credp) // IN: Credentials of caller { HgfsSuperInfo *sip; int ret; DEBUG(VM_DEBUG_ENTRY, "HgfsUnmount().\n"); if (!vfsp || !credp) { cmn_err(HGFS_ERROR, "HgfsUnmount: NULL input from Kernel.\n"); return EINVAL; } /* * Initial check to ensure caller is root. */ if (!HgfsSuser(credp)) { return EPERM; } sip = HgfsGetSuperInfo(); if (!sip) { return EINVAL; } if (vfsp != sip->vfsp) { DEBUG(VM_DEBUG_ALWAYS, "HgfsUnmount: vfsp != sip->vfsp.\n"); } HgfsDebugPrintVnode(VM_DEBUG_STRUCT, "HgfsUnmount", vfsp->vfs_vnodecovered, FALSE); /* Take the request lock to prevent submitting new requests */ mutex_enter(&sip->reqMutex); /* * Make sure there are no active files (besides the root vnode which we * release at the end of the function). */ HgfsDebugPrintFileHashTable(&sip->fileHashTable, VM_DEBUG_STATE); if (!HgfsFileHashTableIsEmpty(sip, &sip->fileHashTable) && !(mflag & MS_FORCE)) { DEBUG(VM_DEBUG_FAIL, "HgfsUnmount: there are still active files.\n"); ret = EBUSY; goto out; } HgfsCancelAllRequests(sip); /* * Set unmounted flag in vfs structure. */ vfsp->vfs_flag |= VFS_UNMOUNTED; /* * Close transport channel, we should not be gettign any more requests. */ sip->transportCleanup(); /* * Clean up fields in vnode structure of mount point and release hold on * vnodes for mount. */ # if HGFS_VFS_VERSION == 2 vfsp->vfs_vnodecovered->v_vfsmountedhere = NULL; # endif VN_RELE(vfsp->vfs_vnodecovered); VN_RELE(HGFS_ROOT_VNODE(sip)); /* * Signify to the device half that the filesystem has been unmounted. */ HGFS_ROOT_VNODE(sip) = NULL; HgfsClearSuperInfo(); ret = 0; out: mutex_exit(&sip->reqMutex); DEBUG(VM_DEBUG_DONE, "HgfsUnmount() done.\n"); return ret; } /* *---------------------------------------------------------------------------- * * HgfsRoot -- * * This supplies the root vnode for the filesystem. * * Results: * Returns zero on success and an error code on error. On success vnodepp * is set to the pointer of the root vnode. * * Side effects: * The root vnode's reference count is incremented by one. * *---------------------------------------------------------------------------- */ int HgfsRoot(struct vfs *vfsp, // IN: Filesystem to find root vnode of struct vnode **vnodepp) // OUT: Set to pointer to root vnode of this fs { HgfsSuperInfo *sip; if (!vfsp || !vnodepp) { cmn_err(HGFS_ERROR, "HgfsRoot: NULL input from Kernel.\n"); return EINVAL; } DEBUG(VM_DEBUG_ENTRY, "HgfsRoot().\n"); /* * Get the root vnode from the superinfo structure. */ sip = HgfsGetSuperInfo(); if (!sip) { DEBUG(VM_DEBUG_FAIL, "HgfsRoot() failed to find superinfo.\n"); return EIO; } if (vfsp != sip->vfsp) { DEBUG(VM_DEBUG_ALWAYS, "HgfsRoot: vfsp != sip->vfsp.\n"); } VN_HOLD( HGFS_ROOT_VNODE(sip) ); *vnodepp = HGFS_ROOT_VNODE(sip); DEBUG(VM_DEBUG_LOAD, " rootvnode=%p", HGFS_ROOT_VNODE(sip)); DEBUG(VM_DEBUG_DONE, "HgfsRoot() done.\n"); return 0; } /* *---------------------------------------------------------------------------- * * HgfsStatvfs -- * * Provides statistics for the provided filesystem. The values provided * by this function are fake. * * Results: * Returns 0 on success and a non-zero error code on exit. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsStatvfs(struct vfs *vfsp, // IN: Filesystem to get statistics for struct statvfs64 *stats) // OUT: Statistics are placed into this struct { dev32_t dev32; DEBUG(VM_DEBUG_ENTRY, "HgfsStatvfs().\n"); if (!stats) { cmn_err(HGFS_ERROR, "HgfsStatvfs: NULL input from Kernel.\n"); return EINVAL; } /* Clear stats struct, then fill it in with our values. */ memset(stats, 0, sizeof *stats); /* * Macros in case we need these elsewhere later. * * These were selected pretty randomly: the numbers should be large enough * so a user can attempt to create any reasonably sized file, but small * enough to be so the Kernel doesn't give callers who are using statvfs32 * an EOVERFLOW. */ #define HGFS_BLOCKS_TOTAL 0x00ffffff #define HGFS_BLOCKS_FREE 0x00ffefff #define HGFS_BLOCKS_AVAIL 0x00ffef00 #define HGFS_FILES_TOTAL 0x00ffffff #define HGFS_FILES_FREE 0x00ffefff #define HGFS_FILES_AVAIL 0x00ffef00 /* Compress the device number to 32-bits for consistency on 64-bit systems. */ cmpldev(&dev32, vfsp->vfs_dev); stats->f_bsize = HGFS_BLOCKSIZE; /* Preferred fs block size */ stats->f_frsize = HGFS_BLOCKSIZE; /* Fundamental fs block size */ /* Next six are u_longlong_t */ stats->f_blocks = HGFS_BLOCKS_TOTAL; /* Total blocks on fs */ stats->f_bfree = HGFS_BLOCKS_FREE; /* Total free blocks */ stats->f_bavail = HGFS_BLOCKS_AVAIL; /* Total blocks avail to non-root */ stats->f_files = HGFS_FILES_TOTAL; /* Total files (inodes) */ stats->f_ffree = HGFS_FILES_FREE; /* Total files free */ stats->f_favail = HGFS_FILES_AVAIL; /* Total files avail to non-root */ stats->f_fsid = dev32; /* Filesystem id */ stats->f_flag &= ST_NOSUID; /* Flags: we don't support setuid. */ stats->f_namemax = MAXNAMELEN; /* Max filename; use Solaris default. */ /* Memset above and -1 of array size as n below ensure NUL termination. */ strncpy(stats->f_basetype, HGFS_FS_NAME, sizeof stats->f_basetype - 1); strncpy(stats->f_fstr, HGFS_FS_NAME, sizeof stats->f_fstr - 1); return 0; } /* *---------------------------------------------------------------------------- * * HgfsSync -- * * Flushes the filesystem cache. * * Results: * Returns zero on success and an error code on failure. Currently this * always succeeds. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsSync(struct vfs *vfsp, // IN: Filesystem to flush short flags, // XXX: ? struct cred *credp) // IN: Credentials of caller { //DEBUG(VM_DEBUG_ENTRY, "HgfsSync().\n"); /* * We just return success and hope the host OS calls its filesystem sync * operation periodically as well. */ return 0; } /* *---------------------------------------------------------------------------- * * HgfsVget -- * * Finds the vnode that matches the unique file identifier. * * XXX: Come back to this when figure out how/if to store fidp to vnode * mappings. * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ int HgfsVget(struct vfs *vfsp, // IN: Filesystem to operate on struct vnode **vnodepp, // OUT: Set to pointer of found vnode struct fid *fidp) // IN: Unique file identifier for vnode { DEBUG(VM_DEBUG_NOTSUP, "HgfsVget() NOTSUP.\n"); return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsMountroot -- * * Mounts the file system on the root directory. * * XXX: Still need to figure out when this is invoked. * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ int HgfsMountroot(struct vfs *vfsp, // IN: Filesystem to mount enum whymountroot reason) // IN: Reason why mounting on root { DEBUG(VM_DEBUG_NOTSUP, "HgfsMountroot() NOTSUP.\n"); return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsReserved -- * * XXX: Is this a placeholder function in the struct? * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ int HgfsReserved(struct vfs *vfsp, struct vnode **vnodepp, char *charp) { DEBUG(VM_DEBUG_NOTSUP, "HgfsReserved() NOTSUP.\n"); return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsFreevfs -- * * Called when a filesystem is unmounted to free the resources held by the * filesystem. * * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION == 3 int HgfsFreevfs(vfs_t *vfsp) #else void HgfsFreevfs(vfs_t *vfsp) #endif { DEBUG(VM_DEBUG_ENTRY, "HgfsFreevfs().\n"); /* * The only allocation to undo here is call mutex_destroy() on the vsw_lock * for our filesystem's struct vfssw. Doing this causes a system crash, * from a call to a mutex free function within the Kernel (that is, not from * our code), so we are assured that the Kernel cleans this up for us. * * In Solaris 10 it seemed that we needed to free the vnode and vfs * operations we had made earlier (vn_freevnodeops() and * vfs_freevfsops_by_type()), but this is not so. Freeing these prevents * 1) multiple mounts without first reloading the module, and 2) unloading * the module from the Kernel. The combination of these two meant that * the guest would have to be rebooted to remount the filesystem. Because * of all this, the assumption is made that the Kernel takes care of * removing these structures for us. */ #if HGFS_VFS_VERSION == 3 return 0; #endif } #if HGFS_VFS_VERSION > 2 /* *---------------------------------------------------------------------------- * * HgfsVnstate -- * * Performs the necessary operations on the provided vnode given the state * transfer that has occurred. * * The possible transfers are VNTRANS_EXISTS, VNTRANS_IDLED, * VNTRANS_RECLAIMED, and VNTRANS_DESTROYED (see ). * * Results: * Returns 0 on success and a non-zero error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsVnstate(vfs_t *vfsp, // IN: Pointer to our filesystem vnode_t *vp, // IN: Vnode to change state of vntrans_t trans) // IN: Type of state transfer { DEBUG(VM_DEBUG_NOTSUP, "HgfsVnstate: entry.\n"); return ENOTSUP; } #endif /* *---------------------------------------------------------------------------- * * HgfsSuser -- * * Correctly implements the superuser check depending on the version of * Solaris. * * Results: * Returns zero if this user is not superuser, returns non-zero otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsSuser(struct cred *cr) // IN: Credentials of the caller { ASSERT(cr); #if HGFS_VFS_VERSION == 2 return suser(cr); #else /* * I am assuming the crgetuid() is the effective uid, since the other two * related functions are crgetruid() and crgetsuid(). */ return (crgetuid(cr) == 0); #endif } open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/debug.h0000644765153500003110000000613212220061556021316 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * debug.h -- * * Macros and includes for debugging. * */ #ifndef __DEBUG_H_ #define __DEBUG_H_ #ifdef _KERNEL #include #include #include "hgfsSolaris.h" #include "filesystem.h" #endif /* * Debugging */ #define HGFS_DEBUG (CE_NOTE) #define VM_DEBUG_ALWAYS (1) #define VM_DEBUG_FAIL VM_DEBUG_ALWAYS #define VM_DEBUG_NOTSUP VM_DEBUG_ALWAYS #define VM_DEBUG_ENTRY (1 << 1) #define VM_DEBUG_DONE (1 << 2) #define VM_DEBUG_LOAD (1 << 3) #define VM_DEBUG_INFO (1 << 4) #define VM_DEBUG_STRUCT (1 << 5) #define VM_DEBUG_LIST (1 << 6) #define VM_DEBUG_CHPOLL (1 << 7) #define VM_DEBUG_RARE (1 << 8) #define VM_DEBUG_COMM (1 << 9) #define VM_DEBUG_REQUEST (1 << 10) #define VM_DEBUG_LOG (1 << 11) #define VM_DEBUG_ATTR (1 << 12) #define VM_DEBUG_DEVENTRY (1 << 13) #define VM_DEBUG_DEVDONE (1 << 14) #define VM_DEBUG_SIG (1 << 15) #define VM_DEBUG_ERROR (1 << 16) #define VM_DEBUG_HSHTBL (1 << 17) #define VM_DEBUG_HANDLE (1 << 18) #define VM_DEBUG_STATE (1 << 19) #ifdef VM_DEBUGGING_ON /*#define VM_DEBUG_LEV (VM_DEBUG_ALWAYS | VM_DEBUG_ENTRY | VM_DEBUG_DONE | \ VM_DEBUG_LOAD | VM_DEBUG_COMM | \ VM_DEBUG_LOG | VM_DEBUG_ATTR) */ /*#define VM_DEBUG_LEV (VM_DEBUG_ALWAYS | VM_DEBUG_FAIL | VM_DEBUG_ERROR | \ VM_DEBUG_COMM | VM_DEBUG_DONE) */ #define VM_DEBUG_LEV (VM_DEBUG_ALWAYS | VM_DEBUG_FAIL) #endif #ifdef VM_DEBUG_LEV #define DEBUG(type, args...) \ ((type & VM_DEBUG_LEV) ? (cmn_err(HGFS_DEBUG, args)) : 0) #else #define DEBUG(type, args...) #endif /* * Prototypes */ #ifdef _KERNEL INLINE void HgfsDebugPrintVfssw(char *str, struct vfssw *vfsswp); INLINE void HgfsDebugPrintVfs(char *str, struct vfs *vfsp); INLINE void HgfsDebugPrintVnode(uint32 level, char *str, struct vnode *vnodep, Bool printFileName); INLINE void HgfsDebugPrintCred(char *str, struct cred *credp); INLINE void HgfsDebugPrintMounta(char *str, struct mounta *mntp); INLINE void HgfsDebugPrintVattr(const struct vattr *vap); void HgfsDebugPrintReqList(DblLnkLst_Links *listAnchor); void HgfsDebugPrintReq(const char *str, HgfsReq *req); void HgfsDebugPrintReqPool(const char *str); #endif void Log(const char *fmt, ...); void Debug(const char *fmt, ...); #endif /* __DEBUG_H_ */ open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/vnode.c0000644765153500003110000054034012220061556021342 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * vnode.c -- * * Implementaiton of entry points for operations on files (vnodes) and * definition of the vnodeops structure. */ #include #include #include #include /* FREAD, FWRITE, etc flags */ #include /* fs_fab_acl */ #include /* S_IRWXU and friends */ #include /* Directory name lookup cache */ #include /* k_sigset_t and signal macros */ #include /* practive (the active process) */ #include /* u macro for current user area */ #include /* curthread and curproc macros */ #include /* segment vnode mapping for mmap() */ #include /* VM address mapping functions */ #include "hgfsSolaris.h" #include "hgfsState.h" #include "hgfsBdGlue.h" #include "vnode.h" #include "filesystem.h" #include "request.h" #include "debug.h" #include "hgfsEscape.h" /* Escaping/unescaping buffers */ #include "cpName.h" /* Cross-platform name conversion */ #include "hgfsUtil.h" /* Cross-platform time conversion */ #include "sha1.h" /* SHA-1 for Node ID calculation */ /* * Macros */ #define HGFS_ATTR_MODE_SHIFT 6 /* Sets the values of request headers properly */ #define HGFS_INIT_REQUEST_HDR(request, req, _op) \ do { \ request->header.id = req->id; \ request->header.op = _op; \ } while(0) /* Solaris times support nsecs, so only use these functions directly */ #define HGFS_SET_TIME(unixtm, nttime) \ HgfsConvertFromNtTimeNsec(&unixtm, nttime) #define HGFS_GET_TIME(unixtm) \ HgfsConvertTimeSpecToNtTime(&unixtm) /* Determine if this is the root vnode. */ #define HGFS_IS_ROOT_VNODE(sip, vp) \ (sip->rootVnode == vp) // ((vp->v_flag & VROOT) && (vp->v_vfsp == sip->vfsp)) /* * Prototypes */ /* Local vnode functions */ static int HgfsDirOpen(HgfsSuperInfo *sip, struct vnode *vp); static int HgfsFileOpen(HgfsSuperInfo *sip, struct vnode *vp, int flag, int permissions); static int HgfsDirClose(HgfsSuperInfo *sip, struct vnode *vp); static int HgfsFileClose(HgfsSuperInfo *sip, struct vnode *vp); static int HgfsGetNextDirEntry(HgfsSuperInfo *sip, HgfsHandle handle, uint32_t offset, char *nameOut, Bool *done); static int HgfsDoRead(HgfsSuperInfo *sip, HgfsHandle handle, uint64_t offset, uint32_t size, uio_t *uiop, uint32_t *count); static int HgfsDoWrite(HgfsSuperInfo *sip, HgfsHandle handle, int ioflag, uint64_t offset, uint32_t size, uio_t *uiop, uint32_t *count); static int HgfsDelete(HgfsSuperInfo *sip, char *filename, HgfsOp op); static int HgfsSubmitRequest(HgfsSuperInfo *sip, HgfsReq *req); static int HgfsValidateReply(HgfsReq *req, uint32_t minSize); static int HgfsStatusConvertToSolaris(HgfsStatus hgfsStatus); static void HgfsAttrToSolaris(struct vnode *vp, const HgfsAttr *hgfsAttr, struct vattr *solAttr); static Bool HgfsSetattrCopy(struct vattr *solAttr, int flags, HgfsAttr *hgfsAttr, HgfsAttrChanges *update); static int HgfsMakeFullName(const char *path, uint32_t pathLen, const char *file, char *outBuf, ssize_t bufSize); static int HgfsGetOpenMode(uint32 flags); static int HgfsGetOpenFlags(uint32 flags); INLINE static void HgfsDisableSignals(k_sigset_t *oldIgnoreSet); INLINE static void HgfsRestoreSignals(k_sigset_t *oldIgnoreSet); /* vnode Operation prototypes */ #if HGFS_VFS_VERSION <= 3 static int HgfsOpen(struct vnode **vpp, int flag, struct cred *cr); static int HgfsClose(struct vnode *vp, int flag, int count, offset_t offset, struct cred *cr); #else static int HgfsOpen(struct vnode **vpp, int flag, struct cred *cr, caller_context_t *ctx); static int HgfsClose(struct vnode *vp, int flag, int count, offset_t offset, struct cred *cr, caller_context_t *ctx); #endif #if HGFS_VFS_VERSION == 2 static int HgfsRead(struct vnode *vp, struct uio *uiop, int ioflag, struct cred *cr); static int HgfsWrite(struct vnode *vp, struct uio *uiop, int ioflag, struct cred *cr); #else static int HgfsRead(struct vnode *vp, struct uio *uiop, int ioflag, struct cred *cr, caller_context_t *ctx); static int HgfsWrite(struct vnode *vp, struct uio *uiop, int ioflag, struct cred *cr, caller_context_t *ctx); #endif #if HGFS_VFS_VERSION <= 3 static int HgfsIoctl(struct vnode *vp, int cmd, intptr_t arg, int flag, struct cred *cr, int *rvalp); static int HgfsGetattr(struct vnode *vp, struct vattr *vap, int flags, struct cred *cr); #else static int HgfsIoctl(struct vnode *vp, int cmd, intptr_t arg, int flag, struct cred *cr, int *rvalp, caller_context_t *ctx); static int HgfsGetattr(struct vnode *vp, struct vattr *vap, int flags, struct cred *cr, caller_context_t *ctx); #endif #if HGFS_VFS_VERSION == 2 static int HgfsSetattr(struct vnode *vp, struct vattr *vap, int flags, struct cred *cr); #else static int HgfsSetattr(struct vnode *vp, struct vattr *vap, int flags, struct cred *cr, caller_context_t *ctx); #endif #if HGFS_VFS_VERSION <= 3 static int HgfsAccess(struct vnode *vp, int mode, int flags, struct cred *cr); static int HgfsLookup(struct vnode *dvp, char *nm, struct vnode **vpp, struct pathname *pnp, int flags, struct vnode *rdir, struct cred *cr); static int HgfsCreate(struct vnode *dvp, char *name, struct vattr *vap, vcexcl_t excl, int mode, struct vnode **vpp, struct cred *cr, int flag); static int HgfsRemove(struct vnode *vp, char *nm, struct cred *cr); static int HgfsLink(struct vnode *tdvp, struct vnode *svp, char *tnm, struct cred *cr); static int HgfsRename(struct vnode *sdvp, char *snm, struct vnode *tdvp, char *tnm, struct cred *cr); static int HgfsMkdir(struct vnode *dvp, char *dirname, struct vattr *vap, struct vnode **vpp, struct cred *cr); static int HgfsRmdir(struct vnode *vp, char *nm, struct vnode *cdir, struct cred *cr); static int HgfsReaddir(struct vnode *vp, struct uio *uiop, struct cred *cr, int *eofp); static int HgfsSymlink(struct vnode *dvp, char *linkname, struct vattr *vap, char *target, struct cred *cr); static int HgfsReadlink(struct vnode *vp, struct uio *uiop, struct cred *cr); static int HgfsFsync(struct vnode *vp, int syncflag, struct cred *cr); static void HgfsInactive(struct vnode *vp, struct cred *cr); static int HgfsFid(struct vnode *vp, struct fid *fidp); #else static int HgfsAccess(struct vnode *vp, int mode, int flags, struct cred *cr, caller_context_t *ctx); static int HgfsLookup(struct vnode *dvp, char *nm, struct vnode **vpp, struct pathname *pnp, int flags, struct vnode *rdir, struct cred *cr, caller_context_t *ctx, int *direntflags, pathname_t *realpnp); static int HgfsCreate(struct vnode *dvp, char *name, struct vattr *vap, vcexcl_t excl, int mode, struct vnode **vpp, struct cred *cr, int flag, caller_context_t *ctx, vsecattr_t *vsecp); static int HgfsRemove(struct vnode *vp, char *nm, struct cred *cr, caller_context_t *ctx, int flags); static int HgfsLink(struct vnode *tdvp, struct vnode *svp, char *tnm, struct cred *cr, caller_context_t *ctx, int flags); static int HgfsRename(struct vnode *sdvp, char *snm, struct vnode *tdvp, char *tnm, struct cred *cr, caller_context_t *ctx, int flags); static int HgfsMkdir(struct vnode *dvp, char *dirname, struct vattr *vap, struct vnode **vpp, struct cred *cr, caller_context_t *ctx, int flags, vsecattr_t *vsecp); static int HgfsRmdir(struct vnode *vp, char *nm, struct vnode *cdir, struct cred *cr, caller_context_t *ctx, int flags); static int HgfsReaddir(struct vnode *vp, struct uio *uiop, struct cred *cr, int *eofp, caller_context_t *ctx, int flags); static int HgfsSymlink(struct vnode *dvp, char *linkname, struct vattr *vap, char *target, struct cred *cr, caller_context_t *ctx, int flags); static int HgfsReadlink(struct vnode *vp, struct uio *uiop, struct cred *cr, caller_context_t *ctx); static int HgfsFsync(struct vnode *vp, int syncflag, struct cred *cr, caller_context_t *ctx); static void HgfsInactive(struct vnode *vp, struct cred *cr, caller_context_t *ctx); static int HgfsFid(struct vnode *vp, struct fid *fidp, caller_context_t *ctx); #endif #if HGFS_VFS_VERSION == 2 static void HgfsRwlock(struct vnode *vp, int write_lock); #elif HGFS_VFS_VERSION == 3 static void HgfsRwlock(struct vnode *vp, int write_lock, caller_context_t *ctx); #else static int HgfsRwlock(struct vnode *vp, int write_lock, caller_context_t *ctx); #endif #if HGFS_VFS_VERSION == 2 static void HgfsRwunlock(struct vnode *vp, int write_lock); #else static void HgfsRwunlock(struct vnode *vp, int write_lock, caller_context_t *ctx); #endif #if HGFS_VFS_VERSION <= 3 static int HgfsSeek(struct vnode *vp, offset_t ooff, offset_t *noffp); static int HgfsCmp(struct vnode *vp1, struct vnode *vp2); static int HgfsFrlock(struct vnode *vp, int cmd, struct flock64 *bfp, int flag, offset_t offset, struct flk_callback *, struct cred *cr); #else static int HgfsSeek(struct vnode *vp, offset_t ooff, offset_t *noffp, caller_context_t *ctx); static int HgfsCmp(struct vnode *vp1, struct vnode *vp2, caller_context_t *ctx); static int HgfsFrlock(struct vnode *vp, int cmd, struct flock64 *bfp, int flag, offset_t offset, struct flk_callback *, struct cred *cr, caller_context_t *ctx); #endif #if HGFS_VFS_VERSION == 2 static int HgfsSpace(struct vnode *vp, int cmd, struct flock64 *bfp, int flag, offset_t offset, struct cred *cr); #else static int HgfsSpace(struct vnode *vp, int cmd, struct flock64 *bfp, int flag, offset_t offset, struct cred *cr, caller_context_t *ctx); #endif #if HGFS_VFS_VERSION <= 3 static int HgfsRealvp(struct vnode *vp, struct vnode **vpp); static int HgfsGetpage(struct vnode *vp, offset_t off, size_t len, uint_t *protp, struct page **plarr, size_t plsz, struct seg *seg, caddr_t addr, enum seg_rw rw, struct cred *cr); static int HgfsPutpage(struct vnode *vp, offset_t off, size_t len, int flags, struct cred *cr); static int HgfsMap(struct vnode *vp, offset_t off, struct as *as, caddr_t *addrp, size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, struct cred *cr); static int HgfsAddmap(struct vnode *vp, offset_t off, struct as *as, caddr_t addr, size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, struct cred *cr); static int HgfsDelmap(struct vnode *vp, offset_t off, struct as *as, caddr_t addr, size_t len, uint_t prot, uint_t maxprot, uint_t flags, struct cred *cr); static int HgfsDump(struct vnode *vp, caddr_t addr, int lbdn, int dblks); static int HgfsPathconf(struct vnode *vp, int cmd, ulong_t *valp, struct cred *cr); static int HgfsPageio(struct vnode *vp, struct page *pp, u_offset_t io_off, size_t io_len, int flags, struct cred *cr); static int HgfsDumpctl(struct vnode *vp, int action, int *blkp); static void HgfsDispose(struct vnode *vp, struct page *pp, int flag, int dn, struct cred *cr); static int HgfsSetsecattr(struct vnode *vp, vsecattr_t *vsap, int flag, struct cred *cr); #else static int HgfsRealvp(struct vnode *vp, struct vnode **vpp, caller_context_t *ctx); static int HgfsGetpage(struct vnode *vp, offset_t off, size_t len, uint_t *protp, struct page **plarr, size_t plsz, struct seg *seg, caddr_t addr, enum seg_rw rw, struct cred *cr, caller_context_t *ctx); static int HgfsPutpage(struct vnode *vp, offset_t off, size_t len, int flags, struct cred *cr, caller_context_t *ctx); static int HgfsMap(struct vnode *vp, offset_t off, struct as *as, caddr_t *addrp, size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, struct cred *cr, caller_context_t *ctx); static int HgfsAddmap(struct vnode *vp, offset_t off, struct as *as, caddr_t addr, size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, struct cred *cr, caller_context_t *ctx); static int HgfsDelmap(struct vnode *vp, offset_t off, struct as *as, caddr_t addr, size_t len, uint_t prot, uint_t maxprot, uint_t flags, struct cred *cr, caller_context_t *ctx); static int HgfsDump(struct vnode *vp, caddr_t addr, offset_t lbdn, offset_t dblks, caller_context_t *ctx); static int HgfsPathconf(struct vnode *vp, int cmd, ulong_t *valp, struct cred *cr, caller_context_t *ctx); static int HgfsPageio(struct vnode *vp, struct page *pp, u_offset_t io_off, size_t io_len, int flags, struct cred *cr, caller_context_t *ctx); static int HgfsDumpctl(struct vnode *vp, int action, offset_t *blkp, caller_context_t *ctx); static void HgfsDispose(struct vnode *vp, struct page *pp, int flag, int dn, struct cred *cr, caller_context_t *ctx); static int HgfsSetsecattr(struct vnode *vp, vsecattr_t *vsap, int flag, struct cred *cr, caller_context_t *ctx); #endif #if HGFS_VFS_VERSION == 2 static int HgfsShrlock(struct vnode *vp, int cmd, struct shrlock *chr, int flag); #elif HGFS_VFS_VERSION == 3 static int HgfsShrlock(struct vnode *vp, int cmd, struct shrlock *chr, int flag, cred_t *cr); #else /* SOL11 */ static int HgfsShrlock(struct vnode *vp, int cmd, struct shrlock *chr, int flag, cred_t *cr, caller_context_t *ctx); #endif #if HGFS_VFS_VERSION == 3 static int HgfsVnevent(struct vnode *vp, vnevent_t event); #elif HGFS_VFS_VERSION == 5 static int HgfsVnevent(struct vnode *vp, vnevent_t event, vnode_t *dvp, char *fnm, caller_context_t *ctx); #endif #if HGFS_VFS_VERSION == 2 /* vnode Operations Structure */ struct vnodeops hgfsVnodeOps = { HgfsOpen, /* vop_open() */ HgfsClose, /* vop_close() */ HgfsRead, /* vop_read() */ HgfsWrite, /* vop_write() */ HgfsIoctl, /* vop_ioctl() */ fs_setfl, /* vop_setfl() */ HgfsGetattr, /* vop_getattr() */ HgfsSetattr, /* vop_setattr() */ HgfsAccess, /* vop_access() */ HgfsLookup, /* vop_lookup() */ HgfsCreate, /* vop_create() */ HgfsRemove, /* vop_remove() */ HgfsLink, /* vop_link() */ HgfsRename, /* vop_rename() */ HgfsMkdir, /* vop_mkdir() */ HgfsRmdir, /* vop_rmdir() */ HgfsReaddir, /* vop_readdir() */ HgfsSymlink, /* vop_symlink() */ HgfsReadlink, /* vop_readlink() */ HgfsFsync, /* vop_fsync() */ HgfsInactive, /* vop_inactive() */ HgfsFid, /* vop_fid() */ HgfsRwlock, /* vop_rwlock() */ HgfsRwunlock, /* vop_rwunlock() */ HgfsSeek, /* vop_seek() */ HgfsCmp, /* vop_cmp() */ HgfsFrlock, /* vop_frlock() */ HgfsSpace, /* vop_space() */ HgfsRealvp, /* vop_realvp() */ HgfsGetpage, /* vop_getpage() */ HgfsPutpage, /* vop_putpage() */ HgfsMap, /* vop_map() */ HgfsAddmap, /* vop_addmap() */ HgfsDelmap, /* vop_delmap() */ fs_poll, /* vop_poll() */ HgfsDump, /* vop_dump() */ HgfsPathconf, /* vop_pathconf() */ HgfsPageio, /* vop_pageio() */ HgfsDumpctl, /* vop_dumpctl() */ HgfsDispose, /* vop_dispose() */ HgfsSetsecattr, /* vop_setsecattr() */ fs_fab_acl, /* vop_getsecattr() */ HgfsShrlock /* vop_shrlock() */ }; #else /* Will be set up during HGFS initialization (see HgfsInit) */ static struct vnodeops *hgfsVnodeOpsP; #endif static HgfsSuperInfo hgfsSuperInfo; /* * Vnode Entry Points */ /* *---------------------------------------------------------------------------- * * HgfsOpen -- * * Invoked when open(2) is called on a file in our filesystem. Sends an * OPEN request to the Hgfs server with the filename of this vnode. * * "Opens a file referenced by the supplied vnode. The open() system call * has already done a vop_lookup() on the path name, which returned a vnode * pointer and then calls to vop_open(). This function typically does very * little since most of the real work was performed by vop_lookup()." * (Solaris Internals, p537) * * Results: * Returns 0 on success and an error code on error. * * Side effects: * The HgfsOpenFile for this file is given a handle that can be used on * future read and write requests. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsOpen(struct vnode **vpp, // IN: Vnode for file to open int flag, // IN: Open flags struct cred *cr) // IN: Credentials of caller #else static int HgfsOpen(struct vnode **vpp, // IN: Vnode for file to open int flag, // IN: Open flags struct cred *cr, // IN: Credentials of caller caller_context_t *ctx) // IN: Context of caller #endif { HgfsSuperInfo *sip; if (!vpp || !cr) { cmn_err(HGFS_ERROR, "HgfsOpen: NULL input from Kernel.\n"); return EINVAL; } DEBUG(VM_DEBUG_ENTRY, "HgfsOpen().\n"); sip = HgfsGetSuperInfo(); if (!sip) { return EIO; } /* Make sure we know the filename. */ ASSERT(HGFS_KNOW_FILENAME(*vpp)); /* * Make sure the handle is not already set. If it is, this means the file * has already been opened so we'll need to create a new vnode since we keep * a vnode for each open instance of a file. This ensures that the handle * we'll create now won't clobber the other one's open-file state. */ if (HgfsHandleIsSet(*vpp)) { int ret; struct vnode *origVp = *vpp; ret = HgfsVnodeDup(vpp, origVp, sip, &sip->fileHashTable); if (ret) { return EIO; } } switch((*vpp)->v_type) { case VDIR: DEBUG(VM_DEBUG_COMM, "HgfsOpen: opening a directory\n"); return HgfsDirOpen(sip, *vpp); case VREG: { HgfsMode mode = 0; /* * If HgfsCreate() was called prior to this, this fills in the mode we * saved there. It's okay if this fails since often HgfsCreate() * won't have been called. */ HgfsGetOpenFileMode(*vpp, &mode); DEBUG(VM_DEBUG_COMM, "HgfsOpen: opening a file with flag %x\n", flag); return HgfsFileOpen(sip, *vpp, flag, mode); } default: DEBUG(VM_DEBUG_FAIL, "HgfsOpen: unrecognized file of type %d.\n", (*vpp)->v_type); return EINVAL; } } /* *---------------------------------------------------------------------------- * * HgfsClose -- * * Invoked when a user calls close(2) on a file in our filesystem. Sends * a CLOSE request to the Hgfs server with the filename of this vnode. * * "Closes the file given by the supplied vnode. When this is the last * close, some filesystems use vop_close() to initiate a writeback of * outstanding dirty pages by checking the reference cound in the vnode." * (Solaris Internals, p536) * * Results: * Returns 0 on success and an error code on error. * * Side effects: * * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsClose(struct vnode *vp, // IN: Vnode of file that is being closed int flag, // IN: Flags file was opened with int count, // IN: Reference count on this vnode offset_t offset, // IN: XXX struct cred *cr) // IN: Credentials of caller #else static int HgfsClose(struct vnode *vp, // IN: Vnode of file that is being closed int flag, // IN: Flags file was opened with int count, // IN: Reference count on this vnode offset_t offset, // IN: XXX struct cred *cr, // IN: Credentials of caller caller_context_t *ctx) // IN: Context of caller #endif { HgfsSuperInfo *sip; if (!vp) { cmn_err(HGFS_ERROR, "HgfsClose: NULL input from Kernel.\n"); return EINVAL; } DEBUG(VM_DEBUG_ENTRY, "HgfsClose(). (vp=%p)\n", vp); DEBUG(VM_DEBUG_INFO, "HgfsClose: flag=%x, count=%x, offset=%lld\n", flag, count, offset); /* * Solaris calls this function with a count greater than one at certain * times. We only want to actually close it on the last close. */ if (count > 1) { return 0; } sip = HgfsGetSuperInfo(); if (!sip) { return EIO; } if ( !HGFS_KNOW_FILENAME(vp) ) { DEBUG(VM_DEBUG_FAIL, "HgfsClose: we don't know the filename of:\n"); HgfsDebugPrintVnode(VM_DEBUG_STRUCT, "HgfsClose", vp, TRUE); return EINVAL; } /* * If we are closing a directory we need to send a SEARCH_CLOSE request, * but if we are closing a regular file we need to send a CLOSE request. * Other file types are not supported by the Hgfs protocol. */ switch (vp->v_type) { case VDIR: return HgfsDirClose(sip, vp); case VREG: return HgfsFileClose(sip, vp); default: DEBUG(VM_DEBUG_FAIL, "HgfsClose: unsupported filetype %d.\n", vp->v_type); return EINVAL; } } /* *---------------------------------------------------------------------------- * * HgfsRead -- * * Invoked when a user calls read(2) on a file in our filesystem. * * We call HgfsDoRead() to fill the user's buffer until the request is met * or the file has no more data. This is done since we can only transfer * HGFS_IO_MAX bytes in any one request. * * "Reads the range supplied for the given vnode. vop_read() typically * maps the requested range of a file into kernel memory and then uses * vop_getpage() to do the real work." (Solaris Internals, p537) * * Results: * Returns zero on success and an error code on failure. * * Side effects: * None. * * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION == 2 static int HgfsRead(struct vnode *vp, // IN: Vnode of file to read struct uio *uiop, // IN: User's read request int ioflag, // IN: XXX struct cred *cr) // IN: Credentials of caller #else static int HgfsRead(struct vnode *vp, // IN: Vnode of file to read struct uio *uiop, // IN: User's read request int ioflag, // IN: XXX struct cred *cr, // IN: Credentials of caller caller_context_t *ctx) // IN: Context of caller #endif { HgfsSuperInfo *sip; HgfsHandle handle; uint64_t offset; int ret; if (!vp || !uiop) { cmn_err(HGFS_ERROR, "HgfsRead: NULL input from Kernel.\n"); return EINVAL; } DEBUG(VM_DEBUG_ENTRY, "HgfsRead: entry.\n"); /* We can't read from directories, that's what readdir() is for. */ if (vp->v_type == VDIR) { DEBUG(VM_DEBUG_FAIL, "HgfsRead: cannot read directories.\n"); return EISDIR; } sip = HgfsGetSuperInfo(); if (!sip) { return EIO; } /* This is where the user wants to start reading from in the file. */ offset = uiop->uio_loffset; /* * We need to get the handle for the requests sent to the Hgfs server. Note * that this is guaranteed to not change until a close(2) is called on this * vnode, so it's safe and correct to acquire it outside the loop below. */ ret = HgfsGetOpenFileHandle(vp, &handle); if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsRead: could not get handle.\n"); return EINVAL; } /* * Here we loop around HgfsDoRead with requests less than or equal to * HGFS_IO_MAX until one of the following conditions is met: * (1) All the requested data has been read * (2) The file has no more data * (3) An error occurred * * Since HgfsDoRead() calls uiomove(9F), we know condition (1) is met when * the uio structure's uio_resid is decremented to zero. If HgfsDoRead() * returns 0 we know condition (2) was met, and if it returns less than 0 we * know condtion (3) was met. */ do { uint32_t size; uint32_t count; DEBUG(VM_DEBUG_INFO, "%s: offset=%"FMT64"d, uio_loffset=%lld\n", __func__, offset, uiop->uio_loffset); DEBUG(VM_DEBUG_HANDLE, "%s: ** handle=%d, file=%s\n", __func__, handle, HGFS_VP_TO_FILENAME(vp)); /* Request at most HGFS_IO_MAX bytes */ size = (uiop->uio_resid > HGFS_IO_MAX) ? HGFS_IO_MAX : uiop->uio_resid; /* Send one read request. */ ret = HgfsDoRead(sip, handle, offset, size, uiop, &count); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: HgfsDoRead() failed.\n", __func__); return ret; } if (count == 0) { /* On end of file we return success */ DEBUG(VM_DEBUG_DONE, "%s: end of file reached.\n", __func__); return 0; } /* Bump the offset past where we have already read. */ offset += count; } while (uiop->uio_resid); /* We fulfilled the user's read request, so return success. */ DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__); return 0; } /* *---------------------------------------------------------------------------- * * HgfsWrite -- * * This is invoked when a user calls write(2) on a file in our filesystem. * * We call HgfsDoWrite() once with requests less than or equal to * HGFS_IO_MAX bytes until the user's write request has completed. * * "Writes the range supplied for the given vnode. The write system call * typically maps the requested range of a file into kernel memory and then * uses vop_putpage() to do the real work." (Solaris Internals, p538) * * Results: * Returns 0 on success and error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION < 3 static int HgfsWrite(struct vnode *vp, // IN: Vnode of file to write to struct uio *uiop, // IN: User's write request int ioflag, // IN: XXX struct cred *cr) // IN: Credentials of caller #else static int HgfsWrite(struct vnode *vp, // IN: Vnode of file to write to struct uio *uiop, // IN: User's write request int ioflag, // IN: XXX struct cred *cr, // IN: Credentials of caller caller_context_t *ctx) // IN: Context of caller #endif { HgfsSuperInfo *sip; HgfsHandle handle; uint64_t offset; int ret; if (!vp || !uiop) { cmn_err(HGFS_ERROR, "HgfsWrite: NULL input from Kernel.\n"); return EINVAL; } DEBUG(VM_DEBUG_ENTRY, "HgfsWrite: entry. (vp=%p)\n", vp); DEBUG(VM_DEBUG_INFO, "HgfsWrite: ***ioflag=%x, uio_resid=%ld\n", ioflag, uiop->uio_resid); /* Skip write requests for 0 bytes. */ if (uiop->uio_resid == 0) { DEBUG(VM_DEBUG_INFO, "HgfsWrite: write of 0 bytes requested.\n"); return 0; } sip = HgfsGetSuperInfo(); if (!sip) { return EIO; } DEBUG(VM_DEBUG_INFO, "HgfsWrite: file is %s\n", HGFS_VP_TO_FILENAME(vp)); /* This is where the user will begin writing into the file. */ offset = uiop->uio_loffset; /* Get the handle we need to supply the Hgfs server. */ ret = HgfsGetOpenFileHandle(vp, &handle); if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsWrite: could not get handle.\n"); return EINVAL; } /* * We loop around calls to HgfsDoWrite() until either (1) we have written all * of our data or (2) an error has occurred. uiop->uio_resid is decremented * by uiomove(9F) inside HgfsDoWrite(), so condition (1) is met when it * reaches zero. Condition (2) occurs when HgfsDoWrite() returns less than * zero. */ do { uint32_t size; uint32_t count; DEBUG(VM_DEBUG_INFO, "HgfsWrite: ** offset=%"FMT64"d, uio_loffset=%lld\n", offset, uiop->uio_loffset); DEBUG(VM_DEBUG_HANDLE, "HgfsWrite: ** handle=%d, file=%s\n", handle, HGFS_VP_TO_FILENAME(vp)); /* Write at most HGFS_IO_MAX bytes. */ size = (uiop->uio_resid > HGFS_IO_MAX) ? HGFS_IO_MAX : uiop->uio_resid; /* Send one write request. */ ret = HgfsDoWrite(sip, handle, ioflag, offset, size, uiop, &count); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: HgfsDoRead() failed.\n", __func__); return ret; } /* Increment the offest by the amount already written. */ offset += count; } while (uiop->uio_resid); /* We have completed the user's write request, so return success. */ DEBUG(VM_DEBUG_DONE, "HgfsWrite: done.\n"); return 0; } /* *---------------------------------------------------------------------------- * * HgfsIoctl -- * * Invoked when a user calls ioctl(2) on a file in our filesystem. * Performs a specified operation on the file. * * Results: * ENOTSUP * * Side effects: * None. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsIoctl(struct vnode *vp, // IN: Vnode of file to operate on int cmd, // IN: Requested command from user intptr_t arg, // IN: Arguments for command int flag, // IN: XXX struct cred *cr, // IN: Credentials of caller int *rvalp) //XXX #else static int HgfsIoctl(struct vnode *vp, // IN: Vnode of file to operate on int cmd, // IN: Requested command from user intptr_t arg, // IN: Arguments for command int flag, // IN: XXX struct cred *cr, // IN: Credentials of caller int *rvalp, //XXX caller_context_t *ctx) // IN: Context of caller #endif { DEBUG(VM_DEBUG_NOTSUP, "HgfsIoctl() NOTSUP.\n"); return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsSetfl -- * * "Sets file locks on the supplied vnode." (Solaris Internals, p538) * * Use fs_setfl from ? Do we need this? * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ /* int HgfsSetfl(struct vnode *vp, int oflags, int nflags, struct cred *cr) { DEBUG(VM_DEBUG_NOTSUP, "HgfsSetfl() NOTSUP.\n"); return ENOTSUP; }*/ /* *---------------------------------------------------------------------------- * * HgfsGetattr -- * * "Gets the attributes for the supplied vnode." (Solaris Internals, p536) * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsGetattr(struct vnode *vp, // IN: Vnode of file to get attributes for struct vattr *vap, // OUT: Filled in with attributes of file int flags, // IN: XXX struct cred *cr) // IN: Credentials of caller #else static int HgfsGetattr(struct vnode *vp, // IN: Vnode of file to get attributes for struct vattr *vap, // OUT: Filled in with attributes of file int flags, // IN: XXX struct cred *cr, // IN: Credentials of caller caller_context_t *ctx) // IN: Context of caller #endif { HgfsSuperInfo *sip; HgfsReq *req; HgfsRequestGetattr *request; HgfsReplyGetattr *reply; int ret; if (!vp || !vap) { cmn_err(HGFS_ERROR, "HgfsGetattr: NULL input from Kernel.\n"); return EINVAL; } DEBUG(VM_DEBUG_ENTRY, "HgfsGetattr().\n"); /* * Here we should send a Getattr request then examine vap->va_mask to * retun the values the user asked for. HgfsAttrToSolaris() handles filling * in the Solaris structure with the correct values based on the Hgfs type. */ sip = HgfsGetSuperInfo(); if (!sip) { DEBUG(VM_DEBUG_FAIL, "HgfsGetattr() couldn't get superinfo.\n"); return EIO; } ASSERT(HGFS_KNOW_FILENAME(vp)); req = HgfsGetNewReq(sip); if (!req) { return EIO; } request = (HgfsRequestGetattr *)req->packet; HGFS_INIT_REQUEST_HDR(request, req, HGFS_OP_GETATTR); /* * Now we need to convert the filename to cross-platform and unescaped * format. */ ret = CPName_ConvertTo(HGFS_VP_TO_FILENAME(vp), MAXPATHLEN, request->fileName.name); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "HgfsGetattr: CPName_ConvertTo failed.\n"); ret = ENAMETOOLONG; /* We need to set the request's state to error before destroying. */ req->state = HGFS_REQ_ERROR; goto out; } request->fileName.length = ret; req->packetSize = sizeof *request + request->fileName.length; /* * Now submit request and wait for reply. The request's state will be * properly set to COMPLETED, ERROR, or ABANDONED after calling * HgfsSubmitRequest() */ ret = HgfsSubmitRequest(sip, req); if (ret) { goto out; } reply = (HgfsReplyGetattr *)req->packet; if (HgfsValidateReply(req, sizeof reply->header) != 0) { DEBUG(VM_DEBUG_FAIL, "HgfsGetattr: reply not valid.\n"); ret = EPROTO; goto out; } ret = HgfsStatusConvertToSolaris(reply->header.status); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n", __func__, ret); } else { /* Make sure we got all of the attributes */ if (req->packetSize != sizeof *reply) { DEBUG(VM_DEBUG_FAIL, "%s: packet too small.\n", __func__); ret = EIO; } else { DEBUG(VM_DEBUG_COMM, "%s: received reply for ID %d\n", __func__, reply->header.id); DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n", reply->header.status); DEBUG(VM_DEBUG_COMM, " file type: %d\n", reply->attr.type); DEBUG(VM_DEBUG_COMM, " file size: %"FMT64"u\n", reply->attr.size); DEBUG(VM_DEBUG_COMM, " permissions: %o\n", reply->attr.permissions); DEBUG(VM_DEBUG_COMM, "%s: filename %s\n", __func__, HGFS_VP_TO_FILENAME(vp)); /* Map the Hgfs attributes into the Solaris attributes */ HgfsAttrToSolaris(vp, &reply->attr, vap); DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__); } } out: HgfsDestroyReq(sip, req); return ret; } /* *---------------------------------------------------------------------------- * * HgfsSetattr -- * * Maps the Solaris attributes to Hgfs attributes (by calling * HgfsSetattrCopy()) and sends a set attribute request to the Hgfs server. * * "Sets the attributes for the supplied vnode." (Solaris Internals, p537) * * Results: * Returns 0 on success and a non-zero error code on error. * * Side effects: * The file on the host will have new attributes. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION == 2 static int HgfsSetattr(struct vnode *vp, // IN: Vnode of file to get attributes for struct vattr *vap, // IN: New attributes for the file int flags, // IN: Flags for this call (from sys/vnode.h) struct cred *cr) // IN: Credentials of caller #else static int HgfsSetattr(struct vnode *vp, // IN: Vnode of file to get attributes for struct vattr *vap, // IN: New attributes for the file int flags, // IN: Flags for this call (from sys/vnode.h) struct cred *cr, // IN: Credentials of caller caller_context_t *ctx) // IN: Context of caller #endif { HgfsSuperInfo *sip; HgfsReq *req; HgfsRequestSetattr *request; HgfsReplySetattr *reply; int ret; DEBUG(VM_DEBUG_ENTRY, "HgfsSetattr().\n"); if (!vp || !vap) { cmn_err(HGFS_ERROR, "HgfsSetattr: NULL input from Kernel.\n"); return EINVAL; } if ( !HGFS_KNOW_FILENAME(vp) ) { DEBUG(VM_DEBUG_FAIL, "HgfsSetattr: we don't know filename to set attributes for.\n"); return EINVAL; } sip = HgfsGetSuperInfo(); if (!sip) { return EIO; } req = HgfsGetNewReq(sip); if (!req) { return EIO; } request = (HgfsRequestSetattr *)req->packet; HGFS_INIT_REQUEST_HDR(request, req, HGFS_OP_SETATTR); /* * Fill the attributes and update fields of the request. If no updates are * needed then we will just return success without sending the request. */ if (HgfsSetattrCopy(vap, flags, &request->attr, &request->update) == FALSE) { DEBUG(VM_DEBUG_DONE, "HgfsSetattr: don't need to update attributes.\n"); ret = 0; /* We need to set the request state to completed before destroying. */ req->state = HGFS_REQ_COMPLETED; goto out; } /* Convert the filename to cross platform and escape its buffer. */ ret = CPName_ConvertTo(HGFS_VP_TO_FILENAME(vp), MAXPATHLEN, request->fileName.name); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "HgfsSetattr: CPName_ConvertTo failed.\n"); ret = ENAMETOOLONG; /* We need to set the request state to error before destroying. */ req->state = HGFS_REQ_ERROR; goto out; } request->fileName.length = ret; /* The request's size includes the request and filename. */ req->packetSize = sizeof *request + request->fileName.length; ret = HgfsSubmitRequest(sip, req); if (ret) { goto out; } reply = (HgfsReplySetattr *)req->packet; if (HgfsValidateReply(req, sizeof *reply) != 0) { DEBUG(VM_DEBUG_FAIL, "HgfsSetattr: invalid reply received.\n"); ret = EPROTO; goto out; } ret = HgfsStatusConvertToSolaris(reply->header.status); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n", __func__, ret); } else { DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__); } out: HgfsDestroyReq(sip, req); return ret; } /* *---------------------------------------------------------------------------- * * HgfsAccess -- * * This function is invoked when the user calls access(2) on a file in our * filesystem. It checks to ensure the user has the specified type of * access to the file. * * We send a GET_ATTRIBUTE request by calling HgfsGetattr() to get the mode * (permissions) for the provided vnode. * * Results: * Returns 0 if access is allowed and a non-zero error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsAccess(struct vnode *vp, // IN: Vnode of file to check access for int mode, // IN: Mode of access int flags, // IN: XXX struct cred *cr) // IN: Credentials of caller #else static int HgfsAccess(struct vnode *vp, // IN: Vnode of file to check access for int mode, // IN: Mode of access int flags, // IN: XXX struct cred *cr, // IN: Credentials of caller caller_context_t *ctx) // IN: Context of caller #endif { int ret; struct vattr vap; if (!vp | !cr) { cmn_err(HGFS_ERROR, "HgfsAccess: NULL input from Kernel.\n"); return EINVAL; } DEBUG(VM_DEBUG_ENTRY, "HgfsAccess(). (vp=%p, mode=%o, flags=%x)\n", vp, mode, flags); /* We only care about the file's mode (permissions). That is, not the owner */ vap.va_mask = AT_MODE; /* Get the attributes for this file from the Hgfs server. */ #if HGFS_VFS_VERSION <= 3 ret = HgfsGetattr(vp, &vap, flags, cr); #else ret = HgfsGetattr(vp, &vap, flags, cr, NULL); #endif if (ret) { return ret; } DEBUG(VM_DEBUG_INFO, "HgfsAccess: vp's mode: %o\n", vap.va_mode); /* * mode is the desired access from the caller, and is composed of S_IREAD, * S_IWRITE, and S_IEXEC from . Since the mode of the file is * guaranteed to only contain owner permissions (by the Hgfs server), we * don't need to shift any bits. */ if ((mode & S_IREAD) && !(vap.va_mode & S_IREAD)) { DEBUG(VM_DEBUG_FAIL, "HgfsAccess: read access not allowed (%s).\n", HGFS_VP_TO_FILENAME(vp)); return EPERM; } if ((mode & S_IWRITE) && !(vap.va_mode & S_IWRITE)) { DEBUG(VM_DEBUG_FAIL, "HgfsAccess: write access not allowed (%s).\n", HGFS_VP_TO_FILENAME(vp)); return EPERM; } if ((mode & S_IEXEC) && !(vap.va_mode & S_IEXEC)) { DEBUG(VM_DEBUG_FAIL, "HgfsAccess: execute access not allowed (%s).\n", HGFS_VP_TO_FILENAME(vp)); return EPERM; } /* Success */ return 0; } /* *---------------------------------------------------------------------------- * * HgfsLookup -- * * Looks in the provided directory for the specified filename. If we cannot * determine the vnode locally (i.e, the vnode is not the root vnode of the * filesystem or the provided dvp), we send a getattr request to the server * and allocate a vnode and internal filesystem state for this file. * * "Looks up the path name for the supplied vnode. The vop_lookup() does * file-name translation for the open, stat system calls." (Solaris * Internals, p537) * * Results: * Returns zero on success and ENOENT if the file cannot be found * If file is found, a vnode representing the file is returned in vpp. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsLookup(struct vnode *dvp, // IN: Directory to look in char *nm, // IN: Name to lookup in directory struct vnode **vpp, // OUT: Pointer to vnode representing found file struct pathname *pnp,// IN: XXX int flags, // IN: XXX struct vnode *rdir, // IN: XXX struct cred *cr) // IN: Credentials of caller #else static int HgfsLookup(struct vnode *dvp, // IN: Directory to look in char *nm, // IN: Name to lookup in directory struct vnode **vpp, // OUT: Pointer to vnode representing found file struct pathname *pnp, // IN: XXX int flags, // IN: XXX struct vnode *rdir, // IN: XXX struct cred *cr, // IN: Credentials of caller caller_context_t *ctx, // IN: Context of caller int *direntflags, // IN: XXX pathname_t *realpnp) // IN: XXX #endif { int ret; HgfsReq *req; HgfsRequestGetattr *request; HgfsReplyGetattr *reply; HgfsSuperInfo *sip; char path[MAXPATHLEN + 1]; /* Temporary buffer for full path */ if (!dvp || !nm || !vpp || !cr) { cmn_err(HGFS_ERROR, "HgfsLookup: NULL input from Kernel.\n"); return EINVAL; } DEBUG(VM_DEBUG_ENTRY, "HgfsLookup(). (nm=%s)\n", nm); //DEBUG(VM_DEBUG_ENTRY, "HgfsLookup: pnp=%x, rdir=%x\n", pnp, rdir); /* First ensure that we are looking in a directory. */ if (dvp->v_type != VDIR) { return ENOTDIR; } DEBUG(VM_DEBUG_COMM, " looking up \"%s\"\n", nm); /* * Get pointer to the superinfo. If the device is not attached, * hgfsInstance will not be valid and we immediately return an error. */ sip = HgfsGetSuperInfo(); if (!sip) { DEBUG(VM_DEBUG_FAIL, "HgfsLookup: couldn't acquire superinfo " "(hgfsInstance=%x).\n", hgfsInstance); return EIO; } /* Construct the full path for this lookup. */ ret = HgfsMakeFullName(HGFS_VP_TO_FILENAME(dvp), // Path to this file HGFS_VP_TO_FILENAME_LENGTH(dvp), // Length of path nm, // File's name path, // Destination buffer sizeof path); // Size of dest buffer if (ret < 0) { return EINVAL; } DEBUG(VM_DEBUG_LOAD, "HgfsLookup: full path is \"%s\"\n", path); /* See if the lookup is really for the root vnode. */ if (strcmp(path, "/") == 0) { DEBUG(VM_DEBUG_INFO, "HgfsLookup: returning the root vnode.\n"); *vpp = HGFS_ROOT_VNODE(sip); /* * Note that this is the only vnode we maintain a reference count on; all * others are per-open-file and should only be given to the Kernel once. */ VN_HOLD(*vpp); return 0; } /* * Now that we know the full filename, we can check our hash table for this * file to prevent having to send a request to the Hgfs Server. If we do * find this file in the hash table, this function will correctly create * a vnode and other per-open state for us. * * On an 'ls -l', this saves sending two requests for each file in the * directory. * * XXX * Note that this optimization leaves open the possibility that a file that * has been removed on the host will not be noticed as promptly by the * filesystem. This shouldn't cause any problems, though, because as far * as we can tell this function is invoked internally by the kernel before * other operations. That is, this function is called implicitly for path * traversal when user applications issue other system calls. The operation * next performed on the vnode we create here should happen prior to * returning to the user application, so if that next operation fails * because the file has been deleted, the user won't see different behavior * than if this optimization was not included. Nonetheless, the #if 1 below * is provided to make it easy to turn off. */ #if 1 ret = HgfsFileNameToVnode(path, vpp, sip, sip->vfsp, &sip->fileHashTable); if (ret == 0) { /* * The filename was in our hash table and we successfully created new * per-open state for it. */ DEBUG(VM_DEBUG_DONE, "HgfsLookup: created per-open state from filename.\n"); return 0; } #endif /* * We don't have any reference to this vnode, so we must send a get * attribute request to see if the file exists and create one. */ req = HgfsGetNewReq(sip); if (!req) { return EIO; } /* Fill in the header of this request. */ request = (HgfsRequestGetattr *)req->packet; HGFS_INIT_REQUEST_HDR(request, req, HGFS_OP_GETATTR); /* Fill in the filename portion of the request. */ ret = CPName_ConvertTo(path, MAXPATHLEN, request->fileName.name); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "HgfsLookup: CPName_ConvertTo failed.\n"); ret = ENAMETOOLONG; /* We need to set the request state to error before destroying. */ req->state = HGFS_REQ_ERROR; goto out; } request->fileName.length = ret; /* Packet size includes the request and its payload. */ req->packetSize = request->fileName.length + sizeof *request; DEBUG(VM_DEBUG_COMM, "HgfsLookup: sending getattr request for ID %d\n", request->header.id); DEBUG(VM_DEBUG_COMM, " fileName.length: %d\n", request->fileName.length); DEBUG(VM_DEBUG_COMM, " fileName.name: \"%s\"\n", request->fileName.name); /* * Submit the request and wait for the reply. */ ret = HgfsSubmitRequest(sip, req); if (ret) { goto out; } /* The reply is in the request's packet */ reply = (HgfsReplyGetattr *)req->packet; /* Validate the reply was COMPLETED and at least contains a header */ if (HgfsValidateReply(req, sizeof reply->header) != 0) { DEBUG(VM_DEBUG_FAIL, "HgfsLookup(): invalid reply received for ID %d " "with status %d.\n", reply->header.id, reply->header.status); ret = EPROTO; goto out; } DEBUG(VM_DEBUG_COMM, "HgfsLookup: received reply for ID %d\n", reply->header.id); DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n", reply->header.status); DEBUG(VM_DEBUG_COMM, " file type: %d\n", reply->attr.type); DEBUG(VM_DEBUG_COMM, " file size: %"FMT64"u\n", reply->attr.size); DEBUG(VM_DEBUG_COMM, " permissions: %o\n", reply->attr.permissions); ret = HgfsStatusConvertToSolaris(reply->header.status); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: failed for [%s] with error %d.\n", __func__, nm, ret); goto out; } /* Ensure packet contains correct amount of data */ if (req->packetSize != sizeof *reply) { DEBUG(VM_DEBUG_COMM, "%s: invalid packet size received for [%s].\n", __func__, nm); ret = EIO; goto out; } /* * We need to create a vnode for this found file to give back to the Kernel. * Note that v_vfsp of the filesystem's root vnode was set properly in * HgfsMount(), so that value (dvp->v_vfsp) propagates down to each vnode. * */ ret = HgfsVnodeGet(vpp, // Location to write vnode's address sip, // Superinfo dvp->v_vfsp, // VFS for our filesystem path, // Full name of the file reply->attr.type, // Type of file &sip->fileHashTable); // File hash table if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsLookup: couldn't create vnode for \"%s\".\n", path); ret = EIO; goto out; } /* HgfsVnodeGet guarantees this. */ ASSERT(*vpp); DEBUG(VM_DEBUG_LOAD, "HgfsLookup: assigned vnode %p to %s\n", *vpp, path); ret = 0; /* Return success */ out: HgfsDestroyReq(sip, req); return ret; } /* *---------------------------------------------------------------------------- * * HgfsCreate -- * * This entry point is invoked when a user calls open(2) with the O_CREAT * flag specified. The kernel calls our open entry point (HgfsOpen()) after * calling this function, so here all we do is consruct the vnode and * save the filename and permission bits for the file to be created within * our filesystem internal state. * * "Creates the supplied pathname." (Solaris Internals, p536) * * Results: * Returns zero on success and an appropriate error code on error. * * Side effects: * If the file exists, the vnode is duplicated since they are kepy per-open. * If the file doesn't exist, a vnode will be created. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsCreate(struct vnode *dvp, // IN: Directory to create file in char *name, // IN: Name of file to create struct vattr *vap, // IN: Attributes for file vcexcl_t excl, // IN: Exclusive creation flag: either NONEXCL or EXCL int mode, // IN: Permissions to create with struct vnode **vpp, // OUT: Vnode of file to create struct cred *cr, // IN: Credentials of caller int flag) // IN: XXX #else static int HgfsCreate(struct vnode *dvp, // IN: Directory to create file in char *name, // IN: Name of file to create struct vattr *vap, // IN: Attributes for file vcexcl_t excl, // IN: Exclusive creation flag: either NONEXCL or EXCL int mode, // IN: Permissions to create with struct vnode **vpp, // OUT: Vnode of file to create struct cred *cr, // IN: Credentials of caller int flag, // IN: XXX caller_context_t *ctx, // IN: Context of caller vsecattr_t *vsecp) // IN: XXX #endif { HgfsSuperInfo *sip; int ret = 0; DEBUG(VM_DEBUG_ENTRY, "HgfsCreate(): entry for \"%s\"\n", name); if (!dvp || !name || !vap || !vpp || !cr) { cmn_err(HGFS_ERROR, "HgfsCreate: NULL input from Kernel.\n"); return EINVAL; } sip = HgfsGetSuperInfo(); if (!sip) { return EIO; } if (dvp->v_type != VDIR) { DEBUG(VM_DEBUG_FAIL, "HgfsCreate: files must be created in directories.\n"); return ENOTDIR; } /* * There are two cases: either the file already exists or it doesn't. If * the file exists already then *vpp points to its vnode that was allocated * in HgfsLookup(). In both cases we need to create a new vnode (since our * vnodes are per-open-file, not per-file), but we don't need to construct * the full name again if we already have it in the existing vnode. */ if ( !(*vpp) ) { char fullname[MAXPATHLEN + 1]; ret = HgfsMakeFullName(HGFS_VP_TO_FILENAME(dvp), // Name of directory to create in HGFS_VP_TO_FILENAME_LENGTH(dvp), // Length of name name, // Name of file to create fullname, // Buffer to write full name sizeof fullname); // Size of this buffer if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "HgfsCreate: couldn't create full path name.\n"); return ENAMETOOLONG; } /* Create the vnode for this file. */ ret = HgfsVnodeGet(vpp, sip, dvp->v_vfsp, fullname, HGFS_FILE_TYPE_REGULAR, &sip->fileHashTable); if (ret) { return EIO; } } else { struct vnode *origVp = *vpp; ASSERT(origVp->v_type != VDIR); /* HgfsMkdir() should have been invoked */ ret = HgfsVnodeDup(vpp, origVp, sip, &sip->fileHashTable); if (ret) { return EIO; } /* These cannot be the same. */ ASSERT(*vpp != origVp); } /* HgfsVnodeGet() guarantees this. */ ASSERT(*vpp); /* Save the mode so when open is called we can reference it. */ HgfsSetOpenFileMode(*vpp, vap->va_mode); /* Solaris automatically calls open after this, so our work is done. */ return 0; } /* *---------------------------------------------------------------------------- * * HgfsRemove -- * * Composes the full pathname of this file and sends a DELETE_FILE request * by calling HgfsDelete(). * * "Removes the file for the supplied vnode." (Solaris Internals, p537) * * Results: * Returns 0 on success or a non-zero error code on error. * * Side effects: * If successful, the file specified will be deleted from the host's * filesystem. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsRemove(struct vnode *vp, // IN: Directory containing file to remove char *nm, // IN: Name of file to remove struct cred *cr) // IN: Credentials of caller #else static int HgfsRemove(struct vnode *vp, // IN: Directory containing file to remove char *nm, // IN: Name of file to remove struct cred *cr, // IN: Credentials of caller caller_context_t *ctx, // IN: Context of caller int flags) // IN: XXX #endif { HgfsSuperInfo *sip; char fullpath[MAXPATHLEN + 1]; int ret; DEBUG(VM_DEBUG_ENTRY, "HgfsRemove().\n"); if (!vp || !nm) { cmn_err(HGFS_ERROR, "HgfsRemove: NULL input from Kernel.\n"); return EINVAL; } /* Ensure parent is a directory. */ if (vp->v_type != VDIR) { DEBUG(VM_DEBUG_FAIL, "HgfsRemove: provided parent is a file, not a directory.\n"); return ENOTDIR; } /* Ensure we know the name of the parent. */ ASSERT(HGFS_KNOW_FILENAME(vp)); sip = HgfsGetSuperInfo(); if (!sip) { return EIO; } /* * We must construct the full name of the file to remove then call * HgfsDelete() to send the deletion request. */ ret = HgfsMakeFullName(HGFS_VP_TO_FILENAME(vp), // Name of directory to create in HGFS_VP_TO_FILENAME_LENGTH(vp), // Length of name nm, // Name of file to create fullpath, // Buffer to write full name sizeof fullpath); // Size of this buffer if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "HgfsRemove: could not construct full name.\n"); return ENAMETOOLONG; } DEBUG(VM_DEBUG_COMM, "HgfsRemove: removing \"%s\".\n", fullpath); /* We can now send the delete request. */ return HgfsDelete(sip, fullpath, HGFS_OP_DELETE_FILE); } /* *---------------------------------------------------------------------------- * * HgfsLink -- * * "Creates a hard link to the supplied vnode." (Solaris Internals, p537) * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsLink(struct vnode *tdvp, //XXX: Vnode of directory to create link in struct vnode *svp, //XXX: Vnode of file to link to char *tnm, //XXX: Name of link in directory struct cred *cr) // IN: Credentials of caller #else static int HgfsLink(struct vnode *tdvp, //XXX: Vnode of directory to create link in struct vnode *svp, //XXX: Vnode of file to link to char *tnm, //XXX: Name of link in directory struct cred *cr, // IN: Credentials of caller caller_context_t *ctx, // IN: Context of caller int flags) // IN: XXX #endif { DEBUG(VM_DEBUG_NOTSUP, "HgfsLink() NOTSUP.\n"); return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsRename -- * * Renames the provided source name in the source directory with the * destination name in the destination directory. A RENAME request is sent * to the Hgfs server. * * Results: * Returns 0 on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsRename(struct vnode *sdvp, // IN: Source directory that contains file to move char *snm, // IN: File to move struct vnode *tdvp, // IN: Destination directory of file char *tnm, // IN: Destination name of file struct cred *cr) // IN: Credentials of caller #else static int HgfsRename(struct vnode *sdvp, // IN: Source directory that contains file to move char *snm, // IN: File to move struct vnode *tdvp, // IN: Destination directory of file char *tnm, // IN: Destination name of file struct cred *cr, // IN: Credentials of caller caller_context_t *ctx, // IN: Context of caller int flags) // IN: XXX #endif { HgfsSuperInfo *sip; HgfsReq *req; HgfsRequestRename *request; HgfsReplyRename *reply; HgfsFileName *newNameP; char srcFullPath[MAXPATHLEN + 1]; char dstFullPath[MAXPATHLEN + 1]; int ret; if (!sdvp || !snm || !tdvp || !tnm) { cmn_err(HGFS_ERROR, "HgfsRename: NULL input from Kernel.\n"); return EINVAL; } DEBUG(VM_DEBUG_ENTRY, "HgfsRename().\n"); sip = HgfsGetSuperInfo(); if (!sip) { return EIO; } /* Make sure we know the names of both parent directories. */ ASSERT(HGFS_KNOW_FILENAME(sdvp) && HGFS_KNOW_FILENAME(tdvp)); /* Make the full path of the source. */ ret = HgfsMakeFullName(HGFS_VP_TO_FILENAME(sdvp), HGFS_VP_TO_FILENAME_LENGTH(sdvp), snm, srcFullPath, sizeof srcFullPath); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "HgfsRename: could not construct full path of source.\n"); return ENAMETOOLONG; } /* Make the full path of the destination. */ ret = HgfsMakeFullName(HGFS_VP_TO_FILENAME(tdvp), HGFS_VP_TO_FILENAME_LENGTH(tdvp), tnm, dstFullPath, sizeof dstFullPath); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "HgfsRename: could not construct full path of dest.\n"); return ENAMETOOLONG; } /* Ensure both names will fit in one request. */ if ((sizeof *request + strlen(srcFullPath) + strlen(dstFullPath)) > HGFS_PACKET_MAX) { DEBUG(VM_DEBUG_FAIL, "HgfsRename: names too big for one request.\n"); return EPROTO; } /* * Now we can prepare and send the request. */ req = HgfsGetNewReq(sip); if (!req) { return EIO; } request = (HgfsRequestRename *)req->packet; HGFS_INIT_REQUEST_HDR(request, req, HGFS_OP_RENAME); /* Convert the source to cross platform and unescape its buffer. */ ret = CPName_ConvertTo(srcFullPath, MAXPATHLEN, request->oldName.name); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "HgfsRename: couldn't convert source to cross platform name.\n"); ret = ENAMETOOLONG; /* We need to set the request state to error before destroying. */ req->state = HGFS_REQ_ERROR; goto out; } request->oldName.length = ret; /* * The new name is placed directly after the old name in the packet and we * access it through this pointer. */ newNameP = (HgfsFileName *)((char *)&request->oldName + sizeof request->oldName + request->oldName.length); /* Convert the destination to cross platform and unescape its buffer. */ ret = CPName_ConvertTo(dstFullPath, MAXPATHLEN, newNameP->name); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "HgfsRename: couldn't convert destination to cross platform name.\n"); ret = ENAMETOOLONG; /* We need to set the request state to error before destroying. */ req->state = HGFS_REQ_ERROR; goto out; } newNameP->length = ret; /* The request's size includes the request and both filenames. */ req->packetSize = sizeof *request + request->oldName.length + newNameP->length; ret = HgfsSubmitRequest(sip, req); if (ret) { goto out; } reply = (HgfsReplyRename *)req->packet; /* Validate the reply's state and size. */ if (HgfsValidateReply(req, sizeof *reply) != 0) { DEBUG(VM_DEBUG_FAIL, "HgfsRename: invalid reply received.\n"); ret = EPROTO; goto out; } /* Return appropriate value. */ ret = HgfsStatusConvertToSolaris(reply->header.status); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n", __func__, ret); } else { DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__); } out: HgfsDestroyReq(sip, req); return ret; } /* *---------------------------------------------------------------------------- * * HgfsMkdir -- * * Makes a directory named dirname in the directory specified by the dvp * vnode by sending a CREATE_DIR request, then allocates a vnode for this * new directory and writes its address into vpp. * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * If successful, a directory is created on the host's filesystem. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsMkdir(struct vnode *dvp, // IN: Vnode of directory to create directory in char *dirname, // IN: Name of directory to create struct vattr *vap, // IN: Attributes of new directory struct vnode **vpp, // OUT: Set to point to vnode for new directory struct cred *cr) // IN: Credentials of caller #else static int HgfsMkdir(struct vnode *dvp, // IN: Vnode of directory to create directory in char *dirname, // IN: Name of directory to create struct vattr *vap, // IN: Attributes of new directory struct vnode **vpp, // OUT: Set to point to vnode for new directory struct cred *cr, // IN: Credentials of caller caller_context_t *ctx, // IN: Context of caller int flags, // IN: XXX vsecattr_t *vsecp) // IN: XXX #endif { HgfsSuperInfo *sip; HgfsReq *req; HgfsRequestCreateDir *request; HgfsReplyCreateDir *reply; char fullname[MAXPATHLEN + 1]; int ret; if (!dvp || !dirname || !vap || !vpp) { cmn_err(HGFS_ERROR, "HgfsMkdir: NULL input from Kernel.\n"); } DEBUG(VM_DEBUG_ENTRY, "HgfsMkdir: dvp=%p (%s), dirname=%s, vap=%p, vpp=%p\n", dvp, HGFS_VP_TO_FILENAME(dvp), dirname, vap, *vpp); /* * We need to construct the full path of the directory to create then send * a CREATE_DIR request. If successful we will create a vnode and fill in * vpp with a pointer to it. * * Note that unlike in HgfsCreate(), *vpp is always NULL. */ if (dvp->v_type != VDIR) { DEBUG(VM_DEBUG_FAIL, "HgfsMkdir: must create directory in directory.\n"); return ENOTDIR; } /* Construct the complete path of the directory to create. */ ret = HgfsMakeFullName(HGFS_VP_TO_FILENAME(dvp),// Name of directory to create in HGFS_VP_TO_FILENAME_LENGTH(dvp), // Length of name dirname, // Name of file to create fullname, // Buffer to write full name sizeof fullname); // Size of this buffer if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "HgfsCreate: couldn't create full path name.\n"); return ENAMETOOLONG; } /* Get pointer to our Superinfo */ sip = HgfsGetSuperInfo(); if (!sip) { return EIO; } req = HgfsGetNewReq(sip); if (!req) { return EIO; } /* Initialize the request's contents. */ request = (HgfsRequestCreateDir *)req->packet; HGFS_INIT_REQUEST_HDR(request, req, HGFS_OP_CREATE_DIR); request->permissions = (vap->va_mode & S_IRWXU) >> HGFS_ATTR_MODE_SHIFT; ret = CPName_ConvertTo(fullname, MAXPATHLEN, request->fileName.name); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "HgfsMkdir: cross-platform name is too long.\n"); ret = ENAMETOOLONG; /* We need to set the request state to error before destroying. */ req->state = HGFS_REQ_ERROR; goto out; } request->fileName.length = ret; /* Set the size of this request. */ req->packetSize = sizeof *request + request->fileName.length; /* Send the request. */ ret = HgfsSubmitRequest(sip, req); if (ret) { goto out; } reply = (HgfsReplyCreateDir *)req->packet; if (HgfsValidateReply(req, sizeof *reply) != 0) { DEBUG(VM_DEBUG_FAIL, "HgfsMkdir: invalid reply received.\n"); ret = EPROTO; goto out; } ret = HgfsStatusConvertToSolaris(reply->header.status); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n", __func__, ret); goto out; } /* We now create the vnode for the new directory. */ ret = HgfsVnodeGet(vpp, sip, dvp->v_vfsp, fullname, HGFS_FILE_TYPE_DIRECTORY, &sip->fileHashTable); if (ret) { ret = EIO; goto out; } ASSERT(*vpp); /* HgfsIget guarantees this. */ ret = 0; out: HgfsDestroyReq(sip, req); return ret; } /* *---------------------------------------------------------------------------- * * HgfsRmdir -- * * Removes the specified name from the provided vnode. Sends a DELETE * request by calling HgfsDelete() with the filename and correct opcode to * indicate deletion of a directory. * * "Removes the directory pointed to by the supplied vnode." (Solaris * Internals, p537) * * Results: * Returns 0 on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsRmdir(struct vnode *vp, // IN: Dir containing dir to remove char *nm, // IN: Name of directory to remove struct vnode *cdir, // XXX? struct cred *cr) // IN: Credentials of caller #else static int HgfsRmdir(struct vnode *vp, // IN: Dir containing dir to remove char *nm, // IN: Name of directory to remove struct vnode *cdir, // XXX? struct cred *cr, // IN: Credentials of caller caller_context_t *ctx, // IN: Context of caller int flags) // IN: XXX #endif { HgfsSuperInfo *sip; char fullpath[MAXPATHLEN + 1]; int ret; DEBUG(VM_DEBUG_ENTRY, "HgfsRmdir().\n"); if (!vp || !nm) { cmn_err(HGFS_ERROR, "HgfsRmdir: NULL input from Kernel.\n"); return EINVAL; } DEBUG(VM_DEBUG_ENTRY, "HgfsRmdir: vp=%p (%s), nm=%s, cdir=%p (%s)\n", vp, (HGFS_VP_TO_FP(vp)) ? HGFS_VP_TO_FILENAME(vp) : "vp->v_data null", nm, cdir, (HGFS_VP_TO_FP(cdir)) ? HGFS_VP_TO_FILENAME(cdir) : "cdir->v_data null"); /* A few checks to ensure we can remove the directory. */ if (vp->v_type != VDIR) { DEBUG(VM_DEBUG_FAIL, "HgfsRmdir: provided parent is a file, not a directory.\n"); return ENOTDIR; } ASSERT(HGFS_KNOW_FILENAME(vp)); sip = HgfsGetSuperInfo(); if (!sip) { return EIO; } /* * We need to construct the full name of the directory to remove then call * HgfsDelete with the proper opcode. */ ret = HgfsMakeFullName(HGFS_VP_TO_FILENAME(vp), // Name of directory to create in HGFS_VP_TO_FILENAME_LENGTH(vp), // Length of name nm, // Name of file to create fullpath, // Buffer to write full name sizeof fullpath); // Size of this buffer if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "HgfsRmdir: could not construct full name.\n"); return ENAMETOOLONG; } DEBUG(VM_DEBUG_COMM, "HgfsRmdir: removing \"%s\".\n", fullpath); /* We can now send the delete request. */ return HgfsDelete(sip, fullpath, HGFS_OP_DELETE_DIR); } /* *---------------------------------------------------------------------------- * * HgfsReaddir -- * * Reads as many entries from the directory as will fit in to the provided * buffer. Each directory entry is read by calling HgfsGetNextDirEntry(). * * "The vop_readdir() method reads chunks of the directory into a uio * structure. Each chunk can contain as many entries as will fit within * the size supplied by the uio structure. The uio_resid structure member * shows the size of the getdents request in bytes, which is divided by the * size of the directory entry made by the vop_readdir() method to * calculate how many directory entries to return." (Solaris Internals, * p555) * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsReaddir(struct vnode *vp, // IN: Vnode of directory to read struct uio *uiop, // IN: User's read request struct cred *cr, // IN: Credentials of caller int *eofp) // OUT: Indicates we are done #else static int HgfsReaddir(struct vnode *vp, // IN: Vnode of directory to read struct uio *uiop, // IN: User's read request struct cred *cr, // IN: Credentials of caller int *eofp, // OUT: Indicates we are done caller_context_t *ctx, // IN: Context of caller int flags) // IN: XXX #endif { HgfsSuperInfo *sip; HgfsHandle handle; struct dirent64 *dirp, *origdirp; ssize_t readSize; uint64_t offset; Bool done; int ret; DEBUG(VM_DEBUG_ENTRY, "HgfsReaddir().\n"); if (!vp || !uiop || !cr || !eofp) { cmn_err(HGFS_ERROR, "HgfsReaddir: NULL input from Kernel.\n"); return EINVAL; } DEBUG(VM_DEBUG_ENTRY, "HgfsReaddir: uiop->uio_resid=%ld, " "uiop->uio_loffset=%lld\n", uiop->uio_resid, uiop->uio_loffset); /* * XXX: If would be nice if we could perform some sort of sanity check on * the handle here. Perhaps make sure handle <= NUM_SEARCHES in * hgfsServer.c since the handle is the index number in searchArray. */ if ( !HGFS_KNOW_FILENAME(vp) ) { DEBUG(VM_DEBUG_FAIL, "HgfsReaddir: we don't know the filename.\n"); return EBADF; } sip = HgfsGetSuperInfo(); if (!sip) { DEBUG(VM_DEBUG_FAIL, "HgfsReaddir: we can't get the superinfo.\n"); return EIO; } /* * In order to fill the user's buffer with directory entries, we must * iterate on HGFS_OP_SEARCH_READ requests until either the user's buffer is * full or there are no more entries. Each call to HgfsGetNextDirEntry() * fills in the name and attribute structure for the next entry. We then * escape that name and place it in a kernel buffer that's the same size as * the user's buffer. Once there are no more entries or no more room in the * buffer, we copy it to user space. */ /* * XXX * Note that I allocate a large buffer in kernel space so I can do only one * copy to user space, otherwise we would need to do a copy for each * directory entry. This approach is potentially bad since readSize is * as big as the buffer the user called us with, and therefore in their * control. (Actually, it's likely that the user can just say it has a * huge buffer without really having it.) For this reason, I call * kmem_zalloc() with the KM_NOSLEEP flag which fails if it cannot allocate * memory rather than sleeping until it can (as KM_SLEEP does). * * This approach may want to be changed in the future. */ readSize = uiop->uio_resid; origdirp = dirp = (struct dirent64 *)kmem_zalloc(readSize, KM_NOSLEEP); if (!origdirp) { DEBUG(VM_DEBUG_FAIL, "HgfsReaddir: couldn't allocate memory.\n"); return ENOMEM; } /* * We need to get the handle for this open directory to send to the Hgfs * server in our requests. */ ret = HgfsGetOpenFileHandle(vp, &handle); if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsReaddir: could not get handle.\n"); return EINVAL; } /* * Loop until one of the following conditions is met: * o An error occurs while reading a directory entry * o There are no more directory entries to read * o The buffer is full and cannot hold the next entry * * We request dentries from the Hgfs server based on their index in the * directory. The offset value is initialized to the value specified in * the user's io request and is incremented each time through the loop. * * dirp is incremented by the record length each time through the loop and * is used to determine where in the kernel buffer we write to. */ for (offset = uiop->uio_loffset, done = 0; /* Nothing */ ; offset++) { char nameBuf[MAXNAMELEN + 1]; char escName[MAXNAMELEN + 1]; char fullName[MAXPATHLEN + 1]; DEBUG(VM_DEBUG_COMM, "HgfsReaddir: getting directory entry at offset %"FMT64"u.\n", offset); DEBUG(VM_DEBUG_HANDLE, "HgfsReaddir: ** handle=%d, file=%s\n", handle, HGFS_VP_TO_FILENAME(vp)); ret = HgfsGetNextDirEntry(sip, handle, offset, nameBuf, &done); /* If the filename was too long, we skip to the next entry ... */ if (ret == EOVERFLOW) { continue; /* ... but if another error occurred, we return that error code ... */ } else if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsReaddir: failure occurred in HgfsGetNextDirEntry\n"); goto out; /* * ... and if there are no more entries, we set the end of file pointer * and break out of the loop. */ } else if (done == TRUE) { DEBUG(VM_DEBUG_COMM, "HgfsReaddir: Done reading directory entries.\n"); *eofp = TRUE; break; } /* * We now have the directory entry, so we sanitize the name and try to * put it in our buffer. */ DEBUG(VM_DEBUG_COMM, "HgfsReaddir: received filename \"%s\"\n", nameBuf); ret = HgfsEscape_Do(nameBuf, strlen(nameBuf), sizeof escName, escName); /* If the escaped name didn't fit in the buffer, skip to the next entry. */ if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "HgfsReaddir: HgfsEscape_Do failed.\n"); continue; } /* * Make sure there is enough room in the buffer for the entire directory * entry. If not, we just break out of the loop and copy what we have. */ if (DIRENT64_RECLEN(ret) > (readSize - ((uintptr_t)dirp - (uintptr_t)origdirp))) { DEBUG(VM_DEBUG_INFO, "HgfsReaddir: ran out of room in the buffer.\n"); break; } /* Fill in the directory entry. */ dirp->d_reclen = DIRENT64_RECLEN(ret); dirp->d_off = offset; memcpy(dirp->d_name, escName, ret); dirp->d_name[ret] = '\0'; ret = HgfsMakeFullName(HGFS_VP_TO_FILENAME(vp), // Directorie's name HGFS_VP_TO_FILENAME_LENGTH(vp), // Length dirp->d_name, // Name of file fullName, // Destination buffer sizeof fullName); // Size of this buffer /* Skip this entry if the full path was too long. */ if (ret < 0) { continue; } /* * Place the node id, which serves the purpose of inode number, for this * filename directory entry. As long as we are using a dirent64, this is * okay since ino_t is also a u_longlong_t. */ HgfsNodeIdGet(&sip->fileHashTable, fullName, (uint32_t)ret, &dirp->d_ino); /* Advance to the location for the next directory entry */ dirp = (struct dirent64 *)((intptr_t)dirp + dirp->d_reclen); } /* * Now that we've filled our buffer with as many dentries as fit, we copy it * into the user's buffer. */ ret = uiomove(origdirp, // Source buffer ((uintptr_t)dirp - (uintptr_t)origdirp), // Size of this buffer UIO_READ, // Read flag uiop); // User's request struct /* * uiomove(9F) will have incremented the uio offset by the number of bytes * written. We reset it here to the fs-specific offset in our directory so * the next time we are called it is correct. (Note, this does not break * anything and /is/ how this field is intended to be used.) */ uiop->uio_loffset = offset; DEBUG(VM_DEBUG_DONE, "HgfsReaddir: done (ret=%d, *eofp=%d).\n", ret, *eofp); out: kmem_free(origdirp, readSize); DEBUG(VM_DEBUG_ENTRY, "HgfsReaddir: exiting.\n"); return ret; } /* *---------------------------------------------------------------------------- * * HgfsSymlink -- * * "Creates a symbolic link between the two pathnames" (Solaris Internals, * p538) * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <=3 static int HgfsSymlink(struct vnode *dvp, // IN: Directory to create link in char *linkname, // IN: Name of link struct vattr *vap, // IN: Attributes for the symlink char *target, // IN: Name of target for symlink struct cred *cr) // IN: Credentials of caller #else static int HgfsSymlink(struct vnode *dvp, // IN: Directory to create link in char *linkname, // IN: Name of link struct vattr *vap, // IN: Attributes for the symlink char *target, // IN: Name of target for symlink struct cred *cr, // IN: Credentials of caller caller_context_t *ctx, // IN: Context of caller int flags) // IN: XXX #endif { DEBUG(VM_DEBUG_NOTSUP, "HgfsSymlink() NOTSUP.\n"); /* * Hgfs doesn't support links. */ return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsReadlink -- * * "Follows the symlink in the supplied vnode." (Solaris Internals, p537) * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsReadlink(struct vnode *vp, // IN: Vnode for the symlink struct uio *uiop, // IN: XXX User's request? struct cred *cr) // IN: Credentials of caller #else static int HgfsReadlink(struct vnode *vp, // IN: Vnode for the symlink struct uio *uiop, // IN: XXX User's request? struct cred *cr, // IN: Credentials of caller caller_context_t *ctx) // IN: Context of caller #endif { DEBUG(VM_DEBUG_NOTSUP, "HgfsReadlink() NOTSUP.\n"); /* * Hgfs doesn't support links */ return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsFsync -- * * We don't map any memory so we can safely return success. * * "Flushes out any dirty pages for the supplied vnode." (Solaris * Internals, p536) * * Results: * Returns 0 on success and non-zero on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsFsync(struct vnode *vp, // IN: Vnode for the file to sync int syncflag, // IN: XXX? struct cred *cr) // IN: Credentials of the caller #else static int HgfsFsync(struct vnode *vp, // IN: Vnode for the file to sync int syncflag, // IN: XXX? struct cred *cr, // IN: Credentials of the caller caller_context_t *ctx) // IN: Context of caller #endif { DEBUG(VM_DEBUG_ENTRY, "HgfsFsync().\n"); return 0; } /* *---------------------------------------------------------------------------- * * HgfsInactive -- * * Frees a vnode that is no longer referenced. This is done by calling * HgfsVnodePut() from hgfsState.c, which also cleans up our internal * filesystem state. * * "Free resources and releases the supplied vnode. The file system can * choose to destroy the vnode or put it onto an inactive list, which is * managed by the file system implementation." (Solaris Internals, p536) * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static void HgfsInactive(struct vnode *vp, // IN: Vnode to operate on struct cred *cr) // IN: Credentials of the caller #else static void HgfsInactive(struct vnode *vp, // IN: Vnode to operate on struct cred *cr, // IN: Credentials of the caller caller_context_t *ctx) // IN: Context of caller #endif { HgfsSuperInfo *sip; if (!vp) { cmn_err(HGFS_ERROR, "HgfsInactive: NULL input from Kernel.\n"); return; } DEBUG(VM_DEBUG_ENTRY, "HgfsInactive().\n"); sip = HgfsGetSuperInfo(); if (!sip) { return; } /* We need the check and decrement of v_count to be atomic */ mutex_enter(&vp->v_lock); if (vp->v_count > 1) { vp->v_count--; mutex_exit(&vp->v_lock); DEBUG(VM_DEBUG_LOAD, "--> decremented count of vnode %p to %d\n", vp, vp->v_count); /* * XXX This should only ever happen for the root vnode with our new state * organization. */ if (vp != sip->rootVnode) { DEBUG(VM_DEBUG_ALWAYS, "HgfsInactive: v_count of vnode for %s too high!\n", HGFS_VP_TO_FILENAME(vp)); } ASSERT(vp == sip->rootVnode); } else { mutex_exit(&vp->v_lock); DEBUG(VM_DEBUG_LOAD, "--> freeing vnode %p - \"%s\"\n", vp, HGFS_VP_TO_FILENAME(vp)); /* Deallocate this vnode. */ HgfsVnodePut(vp, &sip->fileHashTable); } } /* *---------------------------------------------------------------------------- * * HgfsFid -- * * Provide a unique file identifier for this vnode. Note that I have never * seen this function called by the Kernel. * * Results: * Returns 0 on success and a non-zero error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsFid(struct vnode *vp, // IN: File to generate file identifier for struct fid *fidp) // XXX: IN/OUT?: File identifier #else static int HgfsFid(struct vnode *vp, // IN: File to generate file identifier for struct fid *fidp, // XXX: IN/OUT?: File identifier caller_context_t *ctx) // IN: Context of caller #endif { DEBUG(VM_DEBUG_ENTRY, "HgfsFid().\n"); if (!vp || !fidp) { cmn_err(HGFS_ERROR, "HgfsFid: NULL input from Kernel.\n"); } /* * Make sure we can fit our node id in the provided structure. This allows * us to call memcpy() with the sizeof the source below. */ if (sizeof fidp->fid_data < sizeof HGFS_VP_TO_NODEID(vp)) { return EOVERFLOW; } memset(fidp, 0, sizeof *fidp); memcpy(&fidp->fid_data, &HGFS_VP_TO_NODEID(vp), sizeof HGFS_VP_TO_NODEID(vp)); fidp->fid_len = sizeof HGFS_VP_TO_NODEID(vp); return 0; } /* *---------------------------------------------------------------------------- * * HgfsRwlock -- * * Acquires either a readers or writers lock. * * "Holds the reader/writer lock for the supplied vnode. This method is * called for each vnode, with the rwflag set to 0 inside a read() system * call and the rwflag set to 1 inside a write() at a time. Some file * system implementations have opetions to ignore the writer lock inside * vop_rwlock()." (Solaris Internals, p537) * * Results: * None. * * Side effects: * The file's readers/writers lock is held after this function. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION == 2 static void HgfsRwlock(struct vnode *vp, // IN: Vnode to get lock for int write_lock) // IN: Set if wants a write lock, cleared for read lock #elif HGFS_VFS_VERSION == 3 static void HgfsRwlock(struct vnode *vp, // IN: Vnode to get lock for int write_lock, // IN: Set for write lock, cleared for read lock caller_context_t *context) // IN: Context of caller #else /* SOL11 */ static int HgfsRwlock(struct vnode *vp, // IN: Vnode to get lock for int write_lock, // IN: Set for write lock, cleared for read lock caller_context_t *context) // IN: Context of caller #endif { if (write_lock) { rw_enter(HGFS_VP_TO_RWLOCKP(vp), RW_WRITER); } else { rw_enter(HGFS_VP_TO_RWLOCKP(vp), RW_READER); } #if HGFS_VFS_VERSION == 5 return write_lock ? V_WRITELOCK_TRUE : V_WRITELOCK_FALSE; #endif } /* *---------------------------------------------------------------------------- * * HgfsRwunlock -- * * "Releases the reader/writer lock for the supplied vnode." (Solaris * Internals, p537) * * Results: * Void. * * Side effects: * This file's readers/writer lock is unlocked. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION == 2 static void HgfsRwunlock(struct vnode *vp, // IN: Vnode to release lock for int write_lock) // IN: Set for write lock, cleared for read lock #else static void HgfsRwunlock(struct vnode *vp, // IN: Vnode to release lock for int write_lock, // IN: Set for write lock, cleared for read lock caller_context_t *context) // IN: Context of caller #endif { //DEBUG(VM_DEBUG_ENTRY, "HgfsRwunlock().\n"); if (!vp) { cmn_err(HGFS_ERROR, "HgfsRwunlock: NULL input from Kernel.\n"); return; } rw_exit(HGFS_VP_TO_RWLOCKP(vp)); } /* *---------------------------------------------------------------------------- * * HgfsSeek -- * * Checks to ensure that the specified offset is valid. Actual manipulation * of the file position is handled by the Kernel. * * "Seeks within the supplied vnode." (Solaris Internals, p537) * * Results: * Returns zero if this offset is valid and EINVAL if it isn't. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsSeek(struct vnode *vp, // IN: Vnode to seek within offset_t ooff, // IN: Current offset in this vnode offset_t *noffp) // IN/OUT: Requested new offset within file #else static int HgfsSeek(struct vnode *vp, // IN: Vnode to seek within offset_t ooff, // IN: Current offset in this vnode offset_t *noffp, // IN/OUT: Requested new offset within file caller_context_t *ctx) // IN: Context of caller #endif { DEBUG(VM_DEBUG_ENTRY, "HgfsSeek().\n"); if (!noffp) { DEBUG(VM_DEBUG_FAIL, "HgfsSeek: noffp is NULL\n"); return EINVAL; } if (*noffp < 0) { return EINVAL; } DEBUG(VM_DEBUG_INFO, "HgfsSeek: file %s\n", HGFS_VP_TO_FILENAME(vp)); DEBUG(VM_DEBUG_INFO, "HgfsSeek: ooff %llu\n", ooff); DEBUG(VM_DEBUG_INFO, "HgfsSeek: *noffp %llu\n", *noffp); return 0; } /* *---------------------------------------------------------------------------- * * HgfsCmp -- * * Compares two vnodes to see if they are for the same file. Our * filesystem-specific check is to compare the filenames, file type, and * file flags. Since we keep vnodes per-open-file, rather than per-file, * this function has significance. * * This function is invoked by the VN_CMP macro only if the two given * pointers are different and each has the same operations (v_op). * * Results: * TRUE if vnodes are the same, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsCmp(struct vnode *vp1, // IN: First vnode struct vnode *vp2) // IN: Second vnode #else static int HgfsCmp(struct vnode *vp1, // IN: First vnode struct vnode *vp2, // IN: Second vnode caller_context_t *ctx) // IN: Context of caller #endif { DEBUG(VM_DEBUG_ENTRY, "HgfsCmp: vp1=%p, vp2=%p.\n", vp1, vp2); /* * This function is only called if: * ((vp1 != vp2) && (vp1->v_op == vp2->v_op)) * * We also care if the filenames are the same. */ if (vp1->v_type != vp2->v_type) { DEBUG(VM_DEBUG_FAIL, "HgfsCmp: %s != %s", (vp1->v_type == VDIR) ? "VDIR" : "VREG", (vp2->v_type == VDIR) ? "VDIR" : "VREG"); return FALSE; } if (vp1->v_flag != vp2->v_flag) { DEBUG(VM_DEBUG_FAIL, "HgfsCmp: flags: %x != %x\n", vp1->v_flag, vp2->v_flag); return FALSE; } if (strcmp(HGFS_VP_TO_FILENAME(vp1), HGFS_VP_TO_FILENAME(vp2)) != 0) { return FALSE; } DEBUG(VM_DEBUG_DONE, "HgfsCmp: for \"%s\", vp1 == vp2\n", HGFS_VP_TO_FILENAME(vp1)); return TRUE; } /* *---------------------------------------------------------------------------- * * HgfsFrlock -- * * "Does file and record locking for the supplied vnode." (Solaris * Internals, p536) * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsFrlock(struct vnode *vp, // XXX int cmd, // IN: Command to carry out struct flock64 *bfp, // XXX int flag, // XXX offset_t offset, // XXX struct flk_callback *flk_callbackp, // XXX struct cred *cr) // IN: Credentials of caller #else static int HgfsFrlock(struct vnode *vp, // XXX int cmd, // IN: Command to carry out struct flock64 *bfp, // XXX int flag, // XXX offset_t offset, // XXX struct flk_callback *flk_callbackp, // XXX struct cred *cr, // IN: Credentials of caller caller_context_t *ctx) // IN: Context of caller #endif { DEBUG(VM_DEBUG_NOTSUP, "HgfsFrlock() NOTSUP.\n"); return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsSpace -- * * "Frees space for the supplied vnode." (Solaris Internals, p538) * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION == 2 static int HgfsSpace(struct vnode *vp, // IN: Vnode to free space for int cmd, // IN: XXX Command struct flock64 *bfp, // IN: XXX int flag, // IN: XXX offset_t offset, // IN: XXX struct cred *cr) // IN: Credentials of caller #else static int HgfsSpace(struct vnode *vp, // IN: Vnode to free space for int cmd, // IN: XXX Command struct flock64 *bfp, // IN: XXX int flag, // IN: XXX offset_t offset, // IN: XXX struct cred *cr, // IN: Credentials of caller caller_context_t *ctx) // IN: Context of caller #endif { DEBUG(VM_DEBUG_NOTSUP, "HgfsSpace() NOTSUP.\n"); return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsRealvp -- * * "Gets the real vnode from the supplied vnode." (Solaris Internals, p537) * * Results: * Returns 0 on success and a non-zero error code on error. On success, vpp * is given the value of the real vnode. Currently this always returns * success. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsRealvp(struct vnode *vp, // IN: Vnode to find real vnode for struct vnode **vpp) // OUT: Set to point to real vnode #else static int HgfsRealvp(struct vnode *vp, // IN: Vnode to find real vnode for struct vnode **vpp, // OUT: Set to point to real vnode caller_context_t *ctx) #endif { DEBUG(VM_DEBUG_ENTRY, "HgfsRealvp().\n"); DEBUG(VM_DEBUG_ENTRY, "HgfsRealvp: vp=%p\n", vp); DEBUG(VM_DEBUG_ENTRY, "HgfsRealvp: vp's name=%s\n", HGFS_VP_TO_FILENAME(vp)); /* * Here we just supply the vnode we were provided. This behavior is correct * since we maintain vnodes per-open-file rather than per-file. The "real" * vnode /is/ the provided one since any other one belongs to a different * "open" file. */ *vpp = vp; return 0; } /* *---------------------------------------------------------------------------- * * HgfsGetpage -- * * HgfsRead() does not map file data into the Kernel's address space, so we * shouldn't need to support this (that is, page faults will never occur). * * "Gets pages in the range offset and length for the vnode from the * backing store of the file system. Does the real work of reading a * vnode. This method is often called as a result of read(), which causes * a page fault in seg_map, which calls vop_getpage()." (Solaris Internals, * p536) * * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsGetpage(struct vnode *vp, // IN: Vnode of file to get page for offset_t off, // IN: Offset in file/page to retrieve size_t len, // IN: Length of range to retrieve uint_t *protp, // XXX struct page **plarr, // XXX size_t plsz, // IN: XXX struct seg *seg, // XXX: Segment caddr_t addr, // IN: Address of XXX enum seg_rw rw, // IN: XXX struct cred *cr) //IN Credentials of caller #else static int HgfsGetpage(struct vnode *vp, // IN: Vnode of file to get page for offset_t off, // IN: Offset in file/page to retrieve size_t len, // IN: Length of range to retrieve uint_t *protp, // XXX struct page **plarr, // XXX size_t plsz, // IN: XXX struct seg *seg, // XXX: Segment caddr_t addr, // IN: Address of XXX enum seg_rw rw, // IN: XXX struct cred *cr, //IN Credentials of caller caller_context_t *ctx) #endif { DEBUG(VM_DEBUG_NOTSUP, "HgfsGetpage() NOTSUP.\n"); /* We don't currently need this; see the comment above. */ return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsPutpage -- * * HgfsWrite() does not map file data into the Kernel's address space, so we * shouldn't need to support this (that is, page faults will never occur). * * "Writes pages in the range offset and length for the vnode to the * backing store of the file system. Does the real work of reading a * vnode." (Solaris Internals, p537) * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsPutpage(struct vnode *vp, // IN: Vnode of file to put page for offset_t off, // IN: Offset to begin writing size_t len, // IN: Amount of data to write int flags, // IN: XXX struct cred *cr) // IN: Credentials of caller #else static int HgfsPutpage(struct vnode *vp, // IN: Vnode of file to put page for offset_t off, // IN: Offset to begin writing size_t len, // IN: Amount of data to write int flags, // IN: XXX struct cred *cr, // IN: Credentials of caller caller_context_t *ctx) // IN: Context of caller #endif { DEBUG(VM_DEBUG_NOTSUP, "HgfsPutpage() NOTSUP.\n"); /* We don't currently need this; see the comment above. */ return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsMap -- * * Each file has its VNOMAP flag set so this shouldn't be invoked. Most * applications seem to handle this so, if this becomes a problem this * function will need to be implemented. * * "Maps a range of pages into an address space by doing the appropriate * checks and calline as_map()" (Solaris Internals, p537) * * * Results: * Returns 0 on success and a non-zero error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsMap(struct vnode *vp, // IN: Vnode of file to map page for offset_t off, // IN: XXX struct as *as, // IN: Address space caddr_t *addrp, // IN: XXX: Address in this space? size_t len, // IN: XXX:Length of area to map? uchar_t prot, // IN: XXX uchar_t maxprot, // IN: XXX uint_t flags, // IN: XXX struct cred *cr) // IN: Credentials of caller #else static int HgfsMap(struct vnode *vp, // IN: Vnode of file to map page for offset_t off, // IN: XXX struct as *as, // IN: Address space caddr_t *addrp, // IN: XXX: Address in this space? size_t len, // IN: XXX:Length of area to map? uchar_t prot, // IN: XXX uchar_t maxprot, // IN: XXX uint_t flags, // IN: XXX struct cred *cr, // IN: Credentials of caller caller_context_t *ctx) // IN: Context of caller #endif { /* We specify VNOMAP for each file, so this shouldn't be called. */ DEBUG(VM_DEBUG_NOTSUP, "HgfsMap() NOTSUP.\n"); return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsAddmap -- * * Since HgfsMap() above is ENOTSUP, this is not needed. * * "Increments the map count." (Solaris Internals, p536) * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsAddmap(struct vnode *vp, // IN: Vnode to increment map count for offset_t off, //XXX struct as *as, // IN: Address space caddr_t addrp, // IN: XXX: Address in this space? size_t len, // IN: XXX: Length of this mapping? uchar_t prot, // IN: XXX uchar_t maxprot, // IN: XXX uint_t flags, // IN: XXX struct cred *cr) // IN: Credentials of caller #else static int HgfsAddmap(struct vnode *vp, // IN: Vnode to increment map count for offset_t off, //XXX struct as *as, // IN: Address space caddr_t addrp, // IN: XXX: Address in this space? size_t len, // IN: XXX: Length of this mapping? uchar_t prot, // IN: XXX uchar_t maxprot, // IN: XXX uint_t flags, // IN: XXX struct cred *cr, // IN: Credentials of caller caller_context_t *ctx) // IN: Context of caller #endif { DEBUG(VM_DEBUG_NOTSUP, "HgfsAddmap() NOTSUP.\n"); return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsDelmap -- * * Since HgfsMap() above is ENOTSUP, this is not needed. * * "Decrements the map count." (Solaris Internals, p536) * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsDelmap(struct vnode *vp, // IN: Vnode of file to decrement map count for offset_t off, // XXX struct as *as, // IN: Address space caddr_t addr, // IN: XXX: Address in this space? size_t len, // IN: XXX: Length of this mapping? uint_t prot, // IN: XXX uint_t maxprot, // IN: XXX uint_t flags, // IN: XXX struct cred *cr) // IN: Credentials of caller #else static int HgfsDelmap(struct vnode *vp, // IN: Vnode of file to decrement map count for offset_t off, // XXX struct as *as, // IN: Address space caddr_t addr, // IN: XXX: Address in this space? size_t len, // IN: XXX: Length of this mapping? uint_t prot, // IN: XXX uint_t maxprot, // IN: XXX uint_t flags, // IN: XXX struct cred *cr, // IN: Credentials of caller caller_context_t *ctx) #endif { DEBUG(VM_DEBUG_NOTSUP, "HgfsDelmap() NOTSUP.\n"); return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsPoll -- * * We are using fs_poll() instead of this, which seems acceptable so far. * * Invoked when user calls poll(2) on a file in our filesystem. * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ /* int HgfsPoll(struct vnode *vp, // IN: Vnode of file to poll short ev, // IN: Requested events int any, // IN: Whether other file descriptors have had events short *revp, // OUT: Filled in with events that have occurred struct pollhead **phpp)// OUT: Set to a pollhead if necessary { DEBUG(VM_DEBUG_NOTSUP, "HgfsPoll() NOTSUP.\n"); return ENOTSUP; }*/ /* *---------------------------------------------------------------------------- * * HgfsDump -- * * "Dumps data when the kernel is in a frozen state." (Solaris Internals, * p536) * * Results: * * Side effects: * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsDump(struct vnode *vp, // IN: Vnode of XXX caddr_t addr, // IN: XXX: Location to dump to? int lbdn, // IN: XXX int dblks) // IN: XXX #else static int HgfsDump(struct vnode *vp, // IN: Vnode of XXX caddr_t addr, // IN: XXX: Location to dump to? offset_t lbdn, // IN: XXX offset_t dblks, // IN: XXX caller_context_t *ctx) // IN: Context of caller #endif { DEBUG(VM_DEBUG_NOTSUP, "HgfsDump() NOTSUP.\n"); return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsPathconf -- * * "Establishes file system parameters with the pathconf system call." * (Solaris Internals, p537) * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsPathconf(struct vnode *vp, // IN: Vnode of file to establish parameters for int cmd, // IN: Command ulong_t *valp, // OUT: XXX: Returned value? struct cred *cr) // IN: Credentials of caller #else static int HgfsPathconf(struct vnode *vp, // IN: Vnode of file to establish parameters for int cmd, // IN: Command ulong_t *valp, // OUT: XXX: Returned value? struct cred *cr, // IN: Credentials of caller caller_context_t *ctx) // IN: Context of caller #endif { DEBUG(VM_DEBUG_NOTSUP, "HgfsPathconf() NOTSUP.\n"); return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsPageio -- * * "Paged I/O supprt for file system swap files." (Solaris Internals, p537) * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsPageio(struct vnode *vp, struct page *pp, u_offset_t io_off, size_t io_len, int flags, struct cred *cr) #else static int HgfsPageio(struct vnode *vp, struct page *pp, u_offset_t io_off, size_t io_len, int flags, struct cred *cr, caller_context_t *ctx) #endif { DEBUG(VM_DEBUG_NOTSUP, "HgfsPageio() NOTSUP.\n"); return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsDumpctl -- * * "Prepares the file system before and after a dump" (Solaris Internals, * p536) * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsDumpctl(struct vnode *vp, int action, int *blkp) #else static int HgfsDumpctl(struct vnode *vp, int action, offset_t *blkp, caller_context_t *ctx) #endif { DEBUG(VM_DEBUG_NOTSUP, "HgfsDumpctl() NOTSUP.\n"); return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsDispose -- * * Since we don't map any parts of files to pages, this isn't needed. * * "Frees the given page from the vnode." (Solaris Internals, p536) * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static void HgfsDispose(struct vnode *vp, // IN: Vnode to free page for struct page *pp, // IN: Page to free int flag, // IN: XXX int dn, // IN: XXX struct cred *cr) // IN: Credentials of caller #else static void HgfsDispose(struct vnode *vp, // IN: Vnode to free page for struct page *pp, // IN: Page to free int flag, // IN: XXX int dn, // IN: XXX struct cred *cr, // IN: Credentials of caller caller_context_t *ctx) // IN: Context of caller #endif { DEBUG(VM_DEBUG_ENTRY, "HgfsDispose().\n"); } /* *---------------------------------------------------------------------------- * * HgfsSetsecattr -- * * "Sets security access control list attributes." (Solaris Internals, * p538) * * We almost certainly won't support this. * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION <= 3 static int HgfsSetsecattr(struct vnode *vp, vsecattr_t *vsap, int flag, struct cred *cr) #else static int HgfsSetsecattr(struct vnode *vp, vsecattr_t *vsap, int flag, struct cred *cr, caller_context_t *ctx) #endif { DEBUG(VM_DEBUG_NOTSUP, "HgfsSetsecattr() NOTSUP.\n"); return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsGetsecattr -- * * We are using fs_fab_acl() instead of this, which seems to do the right * thing. * * "Gets security access control list attributes" (Solaris Internals, p536) * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ /* int HgfsGetsecattr(struct vnode *vp, vsecattr_t *vsap, int flag, struct cred *cr) { DEBUG(VM_DEBUG_NOTSUP, "HgfsGetsecattr() NOTSUP.\n"); return ENOTSUP; }*/ /* *---------------------------------------------------------------------------- * * HgfsShrlock -- * * "ONC shared lock support." (Solaris Internals, p538) * * Results: * * Side effects: * * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION == 2 static int HgfsShrlock(struct vnode *vp, // IN: Vnode of file to lock int cmd, // IN: Command struct shrlock *chr, // IN: Lock int flag) // IN: Flags for XXX #elif HGFS_VFS_VERSION == 3 static int HgfsShrlock(struct vnode *vp, // IN: Vnode of file to lock int cmd, // IN: Command struct shrlock *chr, // IN: Lock int flag, // IN: Flags for XXX cred_t *cr) // IN: Credentials of caller #else static int HgfsShrlock(struct vnode *vp, // IN: Vnode of file to lock int cmd, // IN: Command struct shrlock *chr, // IN: Lock int flag, // IN: Flags for XXX cred_t *cr, // IN: Credentials of caller caller_context_t *ctx) // IN: Context of caller #endif { DEBUG(VM_DEBUG_NOTSUP, "HgfsShrlock() NOTSUP.\n"); return ENOTSUP; } /* *---------------------------------------------------------------------------- * * HgfsVnevent -- * * Handles an event for the provided vnode. * * Events can be VE_SUPPORT, VE_RENAME_SRC, VE_RENAME_DEST, VE_REMOVE, * VE_RMDIR. * * Note that this function showed up at some point after Build 52 (02/2004) * of Solaris 10 but before (or at) Build 58 (06/2004). We only compile * this in if the driver is being built for Builds greater than 52. * XXX We should find out what build this function first showed up on. * * Results: * Returns zero on success and a non-zero error code on error. * * Side effects: * None. * * *---------------------------------------------------------------------------- */ #if HGFS_VFS_VERSION > 2 #if HGFS_VFS_VERSION == 3 static int HgfsVnevent(struct vnode *vp, // IN: Vnode the event is occuring to vnevent_t event) // IN: Event that has occurred #else static int HgfsVnevent(struct vnode *vp, // IN: Vnode the event is occuring to vnevent_t event, // IN: Event that has occurred vnode_t *dvp, // IN: XXX char *fnm, // IN: XXX caller_context_t *ctx) // IN: Context of caller #endif { DEBUG(VM_DEBUG_NOTSUP, "HgfsVnevent: ENOTSUP\n"); return ENOTSUP; } #endif /* * Local vnode functions. * * (The rest of the functions in this file are only invoked by our code so they * ASSERT() their pointer arguments.) */ /* *---------------------------------------------------------------------------- * * HgfsDirOpen -- * * Invoked when HgfsOpen() is called with a vnode of type VDIR. * * Sends a SEARCH_OPEN request to the Hgfs server. * * Results: * Returns zero on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsDirOpen(HgfsSuperInfo *sip, // IN: Superinfo pointer struct vnode *vp) // IN: Vnode of directory to open { int ret; HgfsReq *req; HgfsRequestSearchOpen *request; HgfsReplySearchOpen *reply; ASSERT(sip); ASSERT(vp); DEBUG(VM_DEBUG_ENTRY, "HgfsDirOpen: opening \"%s\"\n", HGFS_VP_TO_FILENAME(vp)); req = HgfsGetNewReq(sip); if (!req) { return EIO; } /* Set the correct header values */ request = (HgfsRequestSearchOpen *)req->packet; HGFS_INIT_REQUEST_HDR(request, req, HGFS_OP_SEARCH_OPEN); /* * Convert name to cross-platform and unescape. If the vnode is the root of * our filesystem the Hgfs server expects an empty string. */ ret = CPName_ConvertTo((HGFS_IS_ROOT_VNODE(sip, vp)) ? "" : HGFS_VP_TO_FILENAME(vp), MAXPATHLEN, request->dirName.name); if (ret < 0) { ret = ENAMETOOLONG; /* We need to set the request state to error before destroying. */ req->state = HGFS_REQ_ERROR; goto out; } request->dirName.length = ret; req->packetSize = request->dirName.length + sizeof *request; /* Submit the request to the Hgfs server */ ret = HgfsSubmitRequest(sip, req); if (ret) { goto out; } /* Our reply is in the request packet */ reply = (HgfsReplySearchOpen *)req->packet; /* Perform basic validation of packet transfer */ if (HgfsValidateReply(req, sizeof reply->header) != 0) { DEBUG(VM_DEBUG_FAIL, "HgfsDirOpen(): invalid reply received.\n"); ret = EPROTO; goto out; } DEBUG(VM_DEBUG_COMM, "HgfsDirOpen: received reply for ID %d\n", reply->header.id); DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n", reply->header.status); DEBUG(VM_DEBUG_COMM, " handle: %d\n", reply->search); ret = HgfsStatusConvertToSolaris(reply->header.status); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: failed for [%s] with error %d.\n", __func__, HGFS_VP_TO_FILENAME(vp), ret); goto out; } if (req->packetSize != sizeof *reply) { DEBUG(VM_DEBUG_FAIL, "HgfsDirOpen: incorrect packet size.\n"); ret = EIO; goto out; } /* Set the search open handle for use in HgfsReaddir() */ ret = HgfsSetOpenFileHandle(vp, reply->search); if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsDirOpen: couldn't assign handle=%d to %s\n", reply->search, HGFS_VP_TO_FILENAME(vp)); req->state = HGFS_REQ_ERROR; ret = EINVAL; goto out; } DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__); out: /* Make sure we put the request back on the list */ HgfsDestroyReq(sip, req); return ret; } /* *---------------------------------------------------------------------------- * * HgfsFileOpen -- * * Invoked when HgfsOpen() is called with a vnode of type VREG. Sends * a OPEN request to the Hgfs server. * * Note that this function doesn't need to handle creations since the * HgfsCreate() entry point is called by the kernel for that. * * Results: * Returns zero on success and an error code on error. * * Side effects: * None. * * *---------------------------------------------------------------------------- */ static int HgfsFileOpen(HgfsSuperInfo *sip, // IN: Superinfo pointer struct vnode *vp, // IN: Vnode of file to open int flag, // IN: Flags of open int permissions) // IN: Permissions of open (only when creating) { HgfsReq *req; HgfsRequestOpen *request; HgfsReplyOpen *reply; int ret; ASSERT(sip); ASSERT(vp); DEBUG(VM_DEBUG_ENTRY, "HgfsFileOpen: opening \"%s\"\n", HGFS_VP_TO_FILENAME(vp)); req = HgfsGetNewReq(sip); if (!req) { DEBUG(VM_DEBUG_FAIL, "HgfsFileOpen: HgfsGetNewReq failed.\n"); return EIO; } request = (HgfsRequestOpen *)req->packet; HGFS_INIT_REQUEST_HDR(request, req, HGFS_OP_OPEN); /* Convert Solaris modes to Hgfs modes */ ret = HgfsGetOpenMode((uint32_t)flag); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "HgfsFileOpen: HgfsGetOpenMode failed.\n"); ret = EINVAL; /* We need to set the request state to error before destroying. */ req->state = HGFS_REQ_ERROR; goto out; } request->mode = ret; DEBUG(VM_DEBUG_COMM, "HgfsFileOpen: open mode is %x\n", request->mode); /* Convert Solaris flags to Hgfs flags */ ret = HgfsGetOpenFlags((uint32_t)flag); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "HgfsFileOpen: HgfsGetOpenFlags failed.\n"); ret = EINVAL; /* We need to set the request state to error before destroying. */ req->state = HGFS_REQ_ERROR; goto out; } request->flags = ret; DEBUG(VM_DEBUG_COMM, "HgfsFileOpen: open flags are %x\n", request->flags); request->permissions = (permissions & S_IRWXU) >> HGFS_ATTR_MODE_SHIFT; DEBUG(VM_DEBUG_COMM, "HgfsFileOpen: permissions are %o\n", request->permissions); /* Convert the file name to cross platform format. */ ret = CPName_ConvertTo(HGFS_VP_TO_FILENAME(vp), MAXPATHLEN, request->fileName.name); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "HgfsFileOpen: CPName_ConvertTo failed.\n"); ret = ENAMETOOLONG; /* We need to set the request state to error before destroying. */ req->state = HGFS_REQ_ERROR; goto out; } request->fileName.length = ret; /* Packet size includes the request and its payload. */ req->packetSize = request->fileName.length + sizeof *request; ret = HgfsSubmitRequest(sip, req); if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsFileOpen: could not submit request.\n"); goto out; } reply = (HgfsReplyOpen *)req->packet; if (HgfsValidateReply(req, sizeof reply->header) != 0) { DEBUG(VM_DEBUG_FAIL, "HgfsFileOpen: request not valid.\n"); ret = EPROTO; goto out; } ret = HgfsStatusConvertToSolaris(reply->header.status); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: failed for [%s] with error %d.\n", __func__, HGFS_VP_TO_FILENAME(vp), ret); goto out; } if (req->packetSize != sizeof *reply) { DEBUG(VM_DEBUG_FAIL, "%s: size of reply is incorrect.\n", __func__); ret = EIO; goto out; } /* * We successfully received a reply, so we need to save the handle in * this file's HgfsOpenFile and return success. */ ret = HgfsSetOpenFileHandle(vp, reply->file); if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsFileOpen: couldn't assign handle %d (%s)\n", reply->file, HGFS_VP_TO_FILENAME(vp)); req->state = HGFS_REQ_ERROR; ret = EINVAL; goto out; } DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__); out: HgfsDestroyReq(sip, req); return ret; } /* *---------------------------------------------------------------------------- * * HgfsDirClose -- * * Invoked when HgfsClose() is called with a vnode of type VDIR. * * Sends an SEARCH_CLOSE request to the Hgfs server. * * Results: * Returns zero on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsDirClose(HgfsSuperInfo *sip, // IN: Superinfo pointer struct vnode *vp) // IN: Vnode of directory to close { HgfsReq *req; HgfsRequestSearchClose *request; HgfsReplySearchClose *reply; int ret; ASSERT(sip); ASSERT(vp); req = HgfsGetNewReq(sip); if (!sip) { return EIO; } /* * Prepare the request structure. Of note here is that the request is * always the same size so we just set the packetSize to that. */ request = (HgfsRequestSearchClose *)req->packet; HGFS_INIT_REQUEST_HDR(request, req, HGFS_OP_SEARCH_CLOSE); /* Get this open file's handle, since that is what we want to close. */ ret = HgfsGetOpenFileHandle(vp, &request->search); if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsDirClose: couldn't get handle for %s\n", HGFS_VP_TO_FILENAME(vp)); ret = EINVAL; /* We need to set the request state to error before destroying. */ req->state = HGFS_REQ_ERROR; goto out; } req->packetSize = sizeof *request; /* Submit the request to the Hgfs server */ ret = HgfsSubmitRequest(sip, req); if (ret) { goto out; } reply = (HgfsReplySearchClose *)req->packet; /* Ensure reply was received correctly and is necessary size. */ if (HgfsValidateReply(req, sizeof reply->header) != 0) { DEBUG(VM_DEBUG_FAIL, "HgfsDirClose: invalid reply received.\n"); ret = EPROTO; goto out; } DEBUG(VM_DEBUG_COMM, "HgfsDirClose: received reply for ID %d\n", reply->header.id); DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n", reply->header.status); /* Ensure server was able to close directory. */ ret = HgfsStatusConvertToSolaris(reply->header.status); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n", __func__, ret); goto out; } /* Now clear this open file's handle for future use. */ ret = HgfsClearOpenFileHandle(vp); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: couldn't clear handle.\n", __func__); ret = EINVAL; req->state = HGFS_REQ_ERROR; goto out; } /* The directory was closed successfully so we return success. */ DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__); out: HgfsDestroyReq(sip, req); return ret; } /* *---------------------------------------------------------------------------- * * HgfsFileClose -- * * Invoked when HgfsClose() is called with a vnode of type VREG. * * Sends a CLOSE request to the Hgfs server. * * Results: * Returns zero on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsFileClose(HgfsSuperInfo *sip, // IN: Superinfo pointer struct vnode *vp) // IN: Vnode of file to close { HgfsReq *req; HgfsRequestClose *request; HgfsReplyClose *reply; int ret; ASSERT(sip); ASSERT(vp); req = HgfsGetNewReq(sip); if (!req) { ret = EIO; goto out; } request = (HgfsRequestClose *)req->packet; HGFS_INIT_REQUEST_HDR(request, req, HGFS_OP_CLOSE); /* Tell the Hgfs server which handle to close */ ret = HgfsGetOpenFileHandle(vp, &request->file); if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsFileClose: couldn't get handle.\n"); ret = EINVAL; /* We need to set the request state to error before destroying. */ req->state = HGFS_REQ_ERROR; goto out; } req->packetSize = sizeof *request; ret = HgfsSubmitRequest(sip, req); if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsFileClose: submit request failed.\n"); goto out; } if (HgfsValidateReply(req, sizeof *reply) != 0) { DEBUG(VM_DEBUG_FAIL, "HgfsFileClose: reply was invalid.\n"); ret = EPROTO; goto out; } reply = (HgfsReplyClose *)req->packet; ret = HgfsStatusConvertToSolaris(reply->header.status); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n", __func__, ret); goto out; } /* * We already verified the size of the reply above since this reply type * only contains a header, so we just clear the handle and return success. */ ret = HgfsClearOpenFileHandle(vp); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: couldn't clear handle.\n", __func__); ret = EINVAL; req->state = HGFS_REQ_ERROR; goto out; } DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__); out: HgfsDestroyReq(sip, req); DEBUG(VM_DEBUG_DONE, "HgfsFileClose: returning %d\n", ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsGetNextDirEntry -- * * Writes the name of the directory entry matching the handle and offset to * nameOut. This requires sending a SEARCH_READ request. * * Results: * Returns zero on success and an error code on error. The done value is * set if there are no more directory entries. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsGetNextDirEntry(HgfsSuperInfo *sip, // IN: Superinfo pointer HgfsHandle handle, // IN: Handle for request uint32_t offset, // IN: Offset char *nameOut, // OUT: Location to write name Bool *done) // OUT: Whether there are any more { HgfsReq *req; HgfsRequestSearchRead *request; HgfsReplySearchRead *reply; int ret; DEBUG(VM_DEBUG_ENTRY, "HgfsGetNextDirEntry: handle=%d, offset=%d.\n", handle, offset); ASSERT(sip); ASSERT(nameOut); ASSERT(done); req = HgfsGetNewReq(sip); if (!req) { DEBUG(VM_DEBUG_FAIL, "HgfsGetNextDirEntry: couldn't get req.\n"); return EIO; } /* * Fill out the search read request that will return a single directory * entry for the provided handle at the given offset. */ request = (HgfsRequestSearchRead *)req->packet; HGFS_INIT_REQUEST_HDR(request, req, HGFS_OP_SEARCH_READ); request->search = handle; request->offset = offset; req->packetSize = sizeof *request; ret = HgfsSubmitRequest(sip, req); if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsGetNextDirEntry: HgfsSubmitRequest failed.\n"); goto out; } reply = (HgfsReplySearchRead *)req->packet; /* Validate the request state and ensure we have at least a header */ if (HgfsValidateReply(req, sizeof reply->header) != 0) { DEBUG(VM_DEBUG_FAIL, "HgfsGetNextDirEntry: reply not valid.\n"); ret = EPROTO; goto out; } DEBUG(VM_DEBUG_COMM, "HgfsGetNextDirEntry: received reply for ID %d\n", reply->header.id); DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n", reply->header.status); /* Now ensure the server didn't have an error */ ret = HgfsStatusConvertToSolaris(reply->header.status); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n", __func__, ret); goto out; } /* Make sure we got an entire reply (excluding filename) */ if (req->packetSize < sizeof *reply) { DEBUG(VM_DEBUG_FAIL, "%s: server didn't provide entire reply.\n", __func__); ret = EIO; goto out; } /* See if there are no more filenames to read */ if (reply->fileName.length <= 0) { DEBUG(VM_DEBUG_DONE, "%s: no more directory entries.\n", __func__); *done = TRUE; ret = 0; /* return success */ goto out; } /* Make sure filename isn't too long */ if ((reply->fileName.length > MAXNAMELEN) || (reply->fileName.length > HGFS_PAYLOAD_MAX(reply)) ) { DEBUG(VM_DEBUG_FAIL, "%s: filename is too long.\n", __func__); ret = EOVERFLOW; goto out; } /* * Everything is all right, copy filename to caller's buffer. Note that * Solaris directory entries don't need the attribute information in the * reply. */ memcpy(nameOut, reply->fileName.name, reply->fileName.length); nameOut[reply->fileName.length] = '\0'; ret = 0; DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__); out: HgfsDestroyReq(sip, req); return ret; } /* *---------------------------------------------------------------------------- * * HgfsDoRead -- * * Sends a single READ request to the Hgfs server and writes the contents * into the user's buffer if successful. * * This function is called repeatedly by HgfsRead() with requests of size * less than or equal to HGFS_IO_MAX. * * Results: * Returns 0 on success and a positive value on error. * * Side effects: * On success, up to 'size' bytes are written into the user's buffer. * Actual number of bytes written passed back in 'count' argument. * *---------------------------------------------------------------------------- */ static int HgfsDoRead(HgfsSuperInfo *sip, // IN: Superinfo pointer HgfsHandle handle, // IN: Server's handle to read from uint64_t offset, // IN: File offset to read at uint32_t size, // IN: Number of bytes to read uio_t *uiop, // IN: Defines user's read request uint32_t *count) // OUT: Number of bytes read { HgfsReq *req; HgfsRequestRead *request; HgfsReplyRead *reply; int ret; ASSERT(sip); ASSERT(uiop); ASSERT(size <= HGFS_IO_MAX); // HgfsRead() should guarantee this ASSERT(count); DEBUG(VM_DEBUG_ENTRY, "%s: entry.\n", __func__); req = HgfsGetNewReq(sip); if (!req) { return EIO; } request = (HgfsRequestRead *)req->packet; HGFS_INIT_REQUEST_HDR(request, req, HGFS_OP_READ); /* Indicate which file, where in the file, and how much to read. */ request->file = handle; request->offset = offset; request->requiredSize = size; req->packetSize = sizeof *request; ret = HgfsSubmitRequest(sip, req); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: HgfsSubmitRequest failed.\n", __func__); goto out; } reply = (HgfsReplyRead *)req->packet; /* Ensure we got an entire header. */ if (HgfsValidateReply(req, sizeof reply->header) != 0) { DEBUG(VM_DEBUG_FAIL, "%s: invalid reply received.\n", __func__); ret = EPROTO; goto out; } ret = HgfsStatusConvertToSolaris(reply->header.status); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n", __func__, ret); goto out; } /* * Now perform checks on the actualSize. There are three cases: * o actualSize is less than or equal to size, which indicates success * o actualSize is zero, which indicates the end of the file (and success) * o actualSize is greater than size, which indicates a server error */ if (reply->actualSize > size) { /* We got too much data: server error. */ DEBUG(VM_DEBUG_FAIL, "%s: received too much data in payload.\n", __func__); ret = EPROTO; goto out; } /* Perform the copy to the user if we have something to copy */ if (reply->actualSize > 0) { ret = uiomove(reply->payload, reply->actualSize, UIO_READ, uiop); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: uiomove failed, rc: %d\n.", __func__, ret); goto out; } } *count = reply->actualSize; DEBUG(VM_DEBUG_DONE, "%s: successfully read %d bytes to user.\n", __func__, *count); out: HgfsDestroyReq(sip, req); return ret; } /* *---------------------------------------------------------------------------- * * HgfsDoWrite -- * * Sends a single WRITE request to the Hgfs server with the contents of * the user's buffer. * * This function is called repeatedly by HgfsWrite() with requests of size * less than or equal to HGFS_IO_MAX. * * Results: * Returns number 0 on success and a positive value on error. * * Side effects: * On success, up to 'size' bytes are written to the file specified by the * handle. Actual number of bytes written passed back in 'count' argument. * *---------------------------------------------------------------------------- */ static int HgfsDoWrite(HgfsSuperInfo *sip, // IN: Superinfo pointer HgfsHandle handle, // IN: Handle representing file to write to int ioflag, // IN: Flags for write uint64_t offset, // IN: Where in the file to begin writing uint32_t size, // IN: How much data to write uio_t *uiop, // IN: Describes user's write request uint32_t *count) // OUT: number of bytes written { HgfsReq *req; HgfsRequestWrite *request; HgfsReplyWrite *reply; int ret; ASSERT(sip); ASSERT(uiop); ASSERT(size <= HGFS_IO_MAX); // HgfsWrite() guarantees this ASSERT(count); DEBUG(VM_DEBUG_ENTRY, "%s: entry.\n", __func__); req = HgfsGetNewReq(sip); if (!req) { return EIO; } request = (HgfsRequestWrite *)req->packet; HGFS_INIT_REQUEST_HDR(request, req, HGFS_OP_WRITE); request->file = handle; request->flags = 0; request->offset = offset; request->requiredSize = size; if (ioflag & FAPPEND) { DEBUG(VM_DEBUG_COMM, "%s: writing in append mode.\n", __func__); request->flags |= HGFS_WRITE_APPEND; } DEBUG(VM_DEBUG_COMM, "%s: requesting write of %d bytes.\n", __func__, size); /* Copy the data the user wants to write into the payload. */ ret = uiomove(request->payload, request->requiredSize, UIO_WRITE, uiop); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: uiomove(9F) failed copying data from user.\n", __func__); /* We need to set the request state to error before destroying. */ req->state = HGFS_REQ_ERROR; goto out; } /* We subtract one so request's 'char payload[1]' member isn't double counted. */ req->packetSize = sizeof *request + request->requiredSize - 1; ret = HgfsSubmitRequest(sip, req); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: HgfsSubmitRequest failed.\n", __func__); goto out; } reply = (HgfsReplyWrite *)req->packet; if (HgfsValidateReply(req, sizeof reply->header) != 0) { DEBUG(VM_DEBUG_FAIL, "%s: invalid reply received.\n", __func__); ret = EPROTO; goto out; } ret = HgfsStatusConvertToSolaris(reply->header.status); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n", __func__, ret); goto out; } if (req->packetSize != sizeof *reply) { DEBUG(VM_DEBUG_FAIL, "%s: invalid size of reply on successful reply.\n", __func__); ret = EPROTO; goto out; } /* The write was completed successfully, so return the amount written. */ *count = reply->actualSize; DEBUG(VM_DEBUG_DONE, "%s: wrote %d bytes.\n", __func__, *count); out: HgfsDestroyReq(sip, req); return ret; } /* *---------------------------------------------------------------------------- * * HgfsDelete -- * * Sends a request to delete a file or directory. * * Results: * Returns 0 on success or an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsDelete(HgfsSuperInfo *sip, // IN: Superinfo char *filename, // IN: Full name of file to remove HgfsOp op) // IN: Hgfs operation this delete is for { HgfsReq *req; HgfsRequestDelete *request; HgfsReplyDelete *reply; int ret; ASSERT(sip); ASSERT(filename); ASSERT((op == HGFS_OP_DELETE_FILE) || (op == HGFS_OP_DELETE_DIR)); DEBUG(VM_DEBUG_ENTRY, "HgfsDelete().\n"); req = HgfsGetNewReq(sip); if (!req) { return EIO; } /* Initialize the request's contents. */ request = (HgfsRequestDelete *)req->packet; HGFS_INIT_REQUEST_HDR(request, req, op); /* Convert filename to cross platform and unescape. */ ret = CPName_ConvertTo(filename, MAXPATHLEN, request->fileName.name); if (ret < 0) { ret = ENAMETOOLONG; /* We need to set the request state to error before destroying. */ req->state = HGFS_REQ_ERROR; goto out; } request->fileName.length = ret; /* Set the size of our request. (XXX should this be - 1 for char[1]?) */ req->packetSize = sizeof *request + request->fileName.length; DEBUG(VM_DEBUG_COMM, "HgfsDelete: deleting \"%s\"\n", filename); /* Submit our request. */ ret = HgfsSubmitRequest(sip, req); if (ret) { goto out; } reply = (HgfsReplyDelete *)req->packet; /* Check the request status and size of reply. */ if (HgfsValidateReply(req, sizeof *reply) != 0) { DEBUG(VM_DEBUG_FAIL, "HgfsDelete: invalid reply received.\n"); ret = EPROTO; goto out; } /* Return the appropriate value. */ ret = HgfsStatusConvertToSolaris(reply->header.status); if (ret) { DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n", __func__, ret); } else { DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__); } out: HgfsDestroyReq(sip, req); return ret; } /* * Function(s) exported to Solaris Hgfs code */ /* *---------------------------------------------------------------------------- * * HgfsGetSuperInfo -- * * Provides a pointer to the superinfo structure as long as the filesystem * is mounted. * * Results: * Pointer to the superinfo on success, NULL on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ inline HgfsSuperInfo * HgfsGetSuperInfo(void) { return hgfsSuperInfo.vfsp ? &hgfsSuperInfo : NULL; } /* *---------------------------------------------------------------------------- * * HgfsInitSuperInfo -- * * Initializes superinfo structure to indicate that filesystem has been * mounted and can be used now. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsInitSuperInfo(struct vfs *vfsp) // IN: pointer to vfs being mounted { hgfsSuperInfo.vfsp = vfsp; /* For now we are only using the backdoor transport. */ hgfsSuperInfo.sendRequest = HgfsBackdoorSendRequest; hgfsSuperInfo.cancelRequest = HgfsBackdoorCancelRequest; hgfsSuperInfo.transportInit = HgfsBackdoorInit; hgfsSuperInfo.transportCleanup = HgfsBackdoorCleanup; HgfsInitRequestList(&hgfsSuperInfo); HgfsInitFileHashTable(&hgfsSuperInfo.fileHashTable); } /* *---------------------------------------------------------------------------- * * HgfsClearSuperInfo -- * * Clears superinfo structure to indicate that filesystem has been * unmounted. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsClearSuperInfo(void) { hgfsSuperInfo.vfsp = NULL; } /* *---------------------------------------------------------------------------- * * HgfsSetVnodeOps -- * * Sets the vnode operations for the provided vnode. * * Results: * Returns zero on success and a non-zero error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsSetVnodeOps(struct vnode *vp) // IN: vnode for this file { ASSERT(vp); #if HGFS_VFS_VERSION == 2 vp->v_op = &hgfsVnodeOps; #else /* hgfsVnodeOpsP is set up when we mounted HGFS volume. */ if (vn_getops(vp) == hgfsVnodeOpsP) { DEBUG(VM_DEBUG_INFO, "HgfsSetVnodeOps: vnode ops already set.\n"); } else { DEBUG(VM_DEBUG_INFO, "HgfsSetVnodeOps: we had to set the vnode ops.\n"); /* Set the operations for this vnode. */ vn_setops(vp, hgfsVnodeOpsP); } #endif return 0; } /* *---------------------------------------------------------------------------- * * HgfsMakeVnodeOps -- * * Registers our vnode operations with the kernel. After this function * completes, all calls to vn_alloc() for our filesystem should return vnodes * with the correct operations. * * Results: * Return 0 on success and non-zero on failure. * * Side effects: * The kernel allocates memory for our operations structure. * *---------------------------------------------------------------------------- */ int HgfsMakeVnodeOps(void) { #if HGFS_VFS_VERSION > 2 int ret; static fs_operation_def_t vnodeOpsArr[] = { HGFS_VOP(VOPNAME_OPEN, vop_open, HgfsOpen), HGFS_VOP(VOPNAME_CLOSE, vop_close, HgfsClose), HGFS_VOP(VOPNAME_READ, vop_read, HgfsRead), HGFS_VOP(VOPNAME_WRITE, vop_write, HgfsWrite), HGFS_VOP(VOPNAME_IOCTL, vop_ioctl, HgfsIoctl), HGFS_VOP(VOPNAME_SETFL, vop_setfl, fs_setfl), HGFS_VOP(VOPNAME_GETATTR, vop_getattr, HgfsGetattr), HGFS_VOP(VOPNAME_SETATTR, vop_setattr, HgfsSetattr), HGFS_VOP(VOPNAME_ACCESS, vop_access, HgfsAccess), HGFS_VOP(VOPNAME_LOOKUP, vop_lookup, HgfsLookup), HGFS_VOP(VOPNAME_CREATE, vop_create, HgfsCreate), HGFS_VOP(VOPNAME_REMOVE, vop_remove, HgfsRemove), HGFS_VOP(VOPNAME_LINK, vop_link, HgfsLink), HGFS_VOP(VOPNAME_RENAME, vop_rename, HgfsRename), HGFS_VOP(VOPNAME_MKDIR, vop_mkdir, HgfsMkdir), HGFS_VOP(VOPNAME_RMDIR, vop_rmdir, HgfsRmdir), HGFS_VOP(VOPNAME_READDIR, vop_readdir, HgfsReaddir), HGFS_VOP(VOPNAME_SYMLINK, vop_symlink, HgfsSymlink), HGFS_VOP(VOPNAME_READLINK, vop_readlink, HgfsReadlink), HGFS_VOP(VOPNAME_FSYNC, vop_fsync, HgfsFsync), #if HGFS_VFS_VERSION <= 3 HGFS_VOP(VOPNAME_INACTIVE, vop_inactive, (fs_generic_func_p)HgfsInactive), HGFS_VOP(VOPNAME_RWLOCK, vop_rwlock, (fs_generic_func_p)HgfsRwlock), HGFS_VOP(VOPNAME_RWUNLOCK, vop_rwunlock, (fs_generic_func_p)HgfsRwunlock), HGFS_VOP(VOPNAME_MAP, vop_map, (fs_generic_func_p)HgfsMap), HGFS_VOP(VOPNAME_ADDMAP, vop_addmap, (fs_generic_func_p)HgfsAddmap), HGFS_VOP(VOPNAME_POLL, vop_poll, (fs_generic_func_p)fs_poll), HGFS_VOP(VOPNAME_DISPOSE, vop_dispose, (fs_generic_func_p)HgfsDispose), #else HGFS_VOP(VOPNAME_INACTIVE, vop_inactive, HgfsInactive), HGFS_VOP(VOPNAME_RWLOCK, vop_rwlock, HgfsRwlock), HGFS_VOP(VOPNAME_RWUNLOCK, vop_rwunlock, HgfsRwunlock), HGFS_VOP(VOPNAME_MAP, vop_map, HgfsMap), HGFS_VOP(VOPNAME_ADDMAP, vop_addmap, HgfsAddmap), HGFS_VOP(VOPNAME_POLL, vop_poll, fs_poll), HGFS_VOP(VOPNAME_DISPOSE, vop_dispose, HgfsDispose), #endif HGFS_VOP(VOPNAME_FID, vop_fid, HgfsFid), HGFS_VOP(VOPNAME_SEEK, vop_seek, HgfsSeek), HGFS_VOP(VOPNAME_CMP, vop_cmp, HgfsCmp), HGFS_VOP(VOPNAME_FRLOCK, vop_frlock, HgfsFrlock), HGFS_VOP(VOPNAME_SPACE, vop_space, HgfsSpace), HGFS_VOP(VOPNAME_REALVP, vop_realvp, HgfsRealvp), HGFS_VOP(VOPNAME_GETPAGE, vop_getpage, HgfsGetpage), HGFS_VOP(VOPNAME_PUTPAGE, vop_putpage, HgfsPutpage), HGFS_VOP(VOPNAME_DELMAP, vop_delmap, HgfsDelmap), HGFS_VOP(VOPNAME_DUMP, vop_dump, HgfsDump), HGFS_VOP(VOPNAME_PATHCONF, vop_pathconf, HgfsPathconf), HGFS_VOP(VOPNAME_PAGEIO, vop_pageio, HgfsPageio), HGFS_VOP(VOPNAME_DUMPCTL, vop_dumpctl, HgfsDumpctl), HGFS_VOP(VOPNAME_GETSECATTR, vop_getsecattr, fs_fab_acl), HGFS_VOP(VOPNAME_SETSECATTR, vop_setsecattr, HgfsSetsecattr), HGFS_VOP(VOPNAME_SHRLOCK, vop_shrlock, HgfsShrlock), HGFS_VOP(VOPNAME_VNEVENT, vop_vnevent, HgfsVnevent), #if HGFS_VFS_VERSION <= 3 { NULL, NULL } #else { NULL, { NULL } } #endif }; DEBUG(VM_DEBUG_ENTRY, "HgfsMakeVnodeOps: making vnode ops.\n"); /* * Create a vnodeops structure and register it with the kernel. * We save the operations structure so it can be assigned in the * future. */ ret = vn_make_ops(HGFS_FS_NAME, vnodeOpsArr, &hgfsVnodeOpsP); if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsMakeVnodeOps: vn_make_ops returned %d\n", ret); return ret; } DEBUG(VM_DEBUG_DONE, "HgfsMakeVnodeOps: hgfsVnodeOpsP=%p\n", hgfsVnodeOpsP); #endif return 0; } /* *---------------------------------------------------------------------------- * * HgfsFreeVnodeOps -- * * Unregisters vnode operations from the kernel. * * Results: * None. * * Side effects: * The kernel frees memory allocated for our operations structure. * *---------------------------------------------------------------------------- */ void HgfsFreeVnodeOps(void) { #if HGFS_VFS_VERSION > 2 if (hgfsVnodeOpsP) vn_freevnodeops(hgfsVnodeOpsP); #endif } /* * Local utility functions. */ /* *---------------------------------------------------------------------------- * * HgfsSubmitRequest -- * * Sends request through the transport channel, then waits for * the response. * * Both submitting request and waiting for reply are in this function * because the signaling of the request list's condition variable and * waiting on the request's condition variable must be atomic. * * Results: * Returns zero on success, and an appropriate error code on error. * Note: EINTR is returned if cv_wait_sig() is interrupted. * * Side effects: * The request list's condition variable is signaled. * *---------------------------------------------------------------------------- */ static int HgfsSubmitRequest(HgfsSuperInfo *sip, // IN: Superinfo containing request list, // condition variable, and mutex HgfsReq *req) // IN: Request to submit { int ret = 0; ASSERT(sip); ASSERT(req); mutex_enter(&sip->reqMutex); if (sip->vfsp->vfs_flag & VFS_UNMOUNTED) { DEBUG(VM_DEBUG_REQUEST, "HgfsSubmitRequest(): filesystem not mounted.\n"); ret = ENODEV; goto out; } ret = HgfsSendRequest(sip, req); if (ret) { DEBUG(VM_DEBUG_REQUEST, "HgfsSubmitRequest(): transport failed.\n"); goto out; } /* * If we are using synchronous transport we should have the result right * here and status will not be equal HGFS_REQ_SUBMITTED. If we are using * async transport we'll sleep till somebody wakes us up. */ while (req->state == HGFS_REQ_SUBMITTED) { k_sigset_t oldIgnoreSet; //DEBUG(VM_DEBUG_SIG, "HgfsSubmitRequest: currproc is %s.\n", u.u_comm); HgfsDisableSignals(&oldIgnoreSet); if (cv_wait_sig(&req->condVar, &sip->reqMutex) == 0) { /* * We received a system signal (e.g., SIGKILL) while waiting for the * reply. * * Since we gave up the mutex while waiting on the condition * variable, we must make sure the reply didn't come /after/ we were * signaled but /before/ we reacquired the mutex. We do this by * checking the state to make sure it is still SUBMITTED. (Note that * this case should be quite rare, but is possible.) * * If the reply has come, we ignore it (since we were interrupted) and * clean up the request. Otherwise we set the state to ABANDONED so * the device half knows we are no longer waiting for the reply and it * can clean up for us. */ HgfsRestoreSignals(&oldIgnoreSet); DEBUG(VM_DEBUG_SIG, "HgfsSubmitRequest(): interrupted while waiting for reply.\n"); if (req->state != HGFS_REQ_SUBMITTED) { /* It it's not SUBMITTED, it must be COMPLETED or ERROR */ ASSERT(req->state == HGFS_REQ_COMPLETED || req->state == HGFS_REQ_ERROR); DEBUG(VM_DEBUG_REQUEST, "HgfsSubmitRequest(): request not in submitted status.\n"); } else { DEBUG(VM_DEBUG_REQUEST, "HgfsSubmitRequest(): setting request state to abandoned.\n"); req->state = HGFS_REQ_ABANDONED; } ret = EINTR; goto out; } HgfsRestoreSignals(&oldIgnoreSet); } /* The reply should now be in req->packet. */ DEBUG(VM_DEBUG_SIG, "HgfsSubmitRequest(): awoken because reply received.\n"); out: mutex_exit(&sip->reqMutex); return ret; } /* *---------------------------------------------------------------------------- * * HgfsValidateReply -- * * Validates a reply to ensure that its state is set appropriately and the * reply is at least the minimum expected size and not greater than the * maximum allowed packet size. * * Results: * Returns zero on success, and a non-zero on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsValidateReply(HgfsReq *req, // IN: Request that contains reply data uint32_t minSize) // IN: Minimum size expected for the reply { ASSERT(req); ASSERT(minSize <= HGFS_PACKET_MAX); /* we want to know if this fails */ switch (req->state) { case HGFS_REQ_ERROR: DEBUG(VM_DEBUG_FAIL, "HgfsValidateReply(): received reply with error.\n"); return -1; case HGFS_REQ_COMPLETED: if ((req->packetSize < minSize) || (req->packetSize > HGFS_PACKET_MAX)) { DEBUG(VM_DEBUG_FAIL, "HgfsValidateReply(): successfully " "completed reply is too small/big: !(%d < %d < %d).\n", minSize, req->packetSize, HGFS_PACKET_MAX); return -1; } else { return 0; } /* * If we get here then there is a programming error in this module: * HGFS_REQ_UNUSED should be for requests in the free list * HGFS_REQ_SUBMITTED should be for requests only that are awaiting * a response * HGFS_REQ_ABANDONED should have returned an error to the client */ default: NOT_REACHED(); return -1; /* avoid compiler warning */ } } /* *----------------------------------------------------------------------------- * * HgfsStatusConvertToSolaris -- * * Convert a cross-platform HGFS status code to its kernel specific * counterpart. * * Rather than encapsulate the status codes within an array indexed by the * various HGFS status codes, we explicitly enumerate them in a switch * statement, saving the reader some time when matching HGFS status codes * against Solaris status codes. * * Results: * Zero if the converted status code represents success, positive error * otherwise. Unknown status codes are converted to EPROTO. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int HgfsStatusConvertToSolaris(HgfsStatus hgfsStatus) // IN: Status code to convert { switch (hgfsStatus) { case HGFS_STATUS_SUCCESS: return 0; case HGFS_STATUS_NO_SUCH_FILE_OR_DIR: case HGFS_STATUS_INVALID_NAME: return ENOENT; case HGFS_STATUS_INVALID_HANDLE: return EBADF; case HGFS_STATUS_OPERATION_NOT_PERMITTED: return EPERM; case HGFS_STATUS_FILE_EXISTS: return EEXIST; case HGFS_STATUS_NOT_DIRECTORY: return ENOTDIR; case HGFS_STATUS_DIR_NOT_EMPTY: return ENOTEMPTY; case HGFS_STATUS_PROTOCOL_ERROR: return EPROTO; case HGFS_STATUS_ACCESS_DENIED: case HGFS_STATUS_SHARING_VIOLATION: return EACCES; case HGFS_STATUS_NO_SPACE: return ENOSPC; case HGFS_STATUS_OPERATION_NOT_SUPPORTED: return EOPNOTSUPP; case HGFS_STATUS_NAME_TOO_LONG: return ENAMETOOLONG; case HGFS_STATUS_GENERIC_ERROR: return EIO; default: DEBUG(VM_DEBUG_LOG, "VMware hgfs: %s: unknown error: %u\n", __func__, hgfsStatus); return EPROTO; } } /* * XXX * These were taken and slightly modified from hgfs/driver/linux/driver.c. * Should we move them into a hgfs/driver/posix/driver.c? */ /* *---------------------------------------------------------------------- * * HgfsGetOpenMode -- * * Based on the flags requested by the process making the open() * syscall, determine which open mode (access type) to request from * the server. * * Results: * Returns the correct HgfsOpenMode enumeration to send to the * server, or -1 on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsGetOpenMode(uint32 flags) // IN: Open flags { #ifdef sun /* * Sun uses different values in the kernel. These are defined in * . */ #undef O_RDONLY #undef O_WRONLY #undef O_RDWR #define O_RDONLY FREAD #define O_WRONLY FWRITE #define O_RDWR (FREAD | FWRITE) #endif uint32 mask = O_RDONLY|O_WRONLY|O_RDWR; int result = -1; #ifndef sun LOG(4, (KERN_DEBUG "VMware hgfs: HgfsGetOpenMode: entered\n")); #else DEBUG(VM_DEBUG_LOG, "HgfsGetOpenMode: entered\n"); #endif /* * Mask the flags to only look at the access type. */ flags &= mask; /* Pick the correct HgfsOpenMode. */ switch (flags) { case O_RDONLY: DEBUG(VM_DEBUG_COMM, "HgfsGetOpenMode: O_RDONLY\n"); result = HGFS_OPEN_MODE_READ_ONLY; break; case O_WRONLY: DEBUG(VM_DEBUG_COMM, "HgfsGetOpenMode: O_WRONLY\n"); result = HGFS_OPEN_MODE_WRITE_ONLY; break; case O_RDWR: DEBUG(VM_DEBUG_COMM, "HgfsGetOpenMode: O_RDWR\n"); result = HGFS_OPEN_MODE_READ_WRITE; break; default: /* This should never happen. */ NOT_REACHED(); #ifndef sun LOG(4, (KERN_DEBUG "VMware hgfs: HgfsGetOpenMode: invalid open flags %o\n", flags)); #else DEBUG(VM_DEBUG_LOG, "HgfsGetOpenMode: invalid open flags %o\n", flags); #endif result = -1; break; } return result; } /* *---------------------------------------------------------------------- * * HgfsGetOpenFlags -- * * Based on the flags requested by the process making the open() * syscall, determine which flags to send to the server to open the * file. * * Results: * Returns the correct HgfsOpenFlags enumeration to send to the * server, or -1 on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsGetOpenFlags(uint32 flags) // IN: Open flags { #ifdef sun /* * Sun uses different values inside the kernel. These are defined in * . */ #undef O_CREAT // Must undef b/c included #undef O_TRUNC #undef O_EXCL #define O_CREAT FCREAT #define O_TRUNC FTRUNC #define O_EXCL FEXCL #endif uint32 mask = O_CREAT | O_TRUNC | O_EXCL; int result = -1; #ifndef sun LOG(4, (KERN_DEBUG "VMware hgfs: HgfsGetOpenFlags: entered\n")); #else DEBUG(VM_DEBUG_INFO, "HgfsGetOpenFlags: entered\n"); #endif /* * Mask the flags to only look at O_CREAT, O_EXCL, and O_TRUNC. */ flags &= mask; /* O_EXCL has no meaning if O_CREAT is not set. */ if (!(flags & O_CREAT)) { flags &= ~O_EXCL; } /* Pick the right HgfsOpenFlags. */ switch (flags) { case 0: /* Regular open; fails if file nonexistant. */ DEBUG(VM_DEBUG_COMM, "HgfsGetOpenFlags: 0\n"); result = HGFS_OPEN; break; case O_CREAT: /* Create file; if it exists already just open it. */ DEBUG(VM_DEBUG_COMM, "HgfsGetOpenFlags: O_CREAT\n"); result = HGFS_OPEN_CREATE; break; case O_TRUNC: /* Truncate existing file; fails if nonexistant. */ DEBUG(VM_DEBUG_COMM, "HgfsGetOpenFlags: O_TRUNC\n"); result = HGFS_OPEN_EMPTY; break; case (O_CREAT | O_EXCL): /* Create file; fail if it exists already. */ DEBUG(VM_DEBUG_COMM, "HgfsGetOpenFlags: O_CREAT | O_EXCL\n"); result = HGFS_OPEN_CREATE_SAFE; break; case (O_CREAT | O_TRUNC): /* Create file; if it exists already, truncate it. */ DEBUG(VM_DEBUG_COMM, "HgfsGetOpenFlags: O_CREAT | O_TRUNC\n"); result = HGFS_OPEN_CREATE_EMPTY; break; default: /* * This can only happen if all three flags are set, which * conceptually makes no sense because O_EXCL and O_TRUNC are * mutually exclusive if O_CREAT is set. * * However, the open(2) man page doesn't say you can't set all * three flags, and certain apps (*cough* Nautilus *cough*) do * so. To be friendly to those apps, we just silenty drop the * O_TRUNC flag on the assumption that it's safer to honor * O_EXCL. */ #ifndef sun LOG(4, (KERN_DEBUG "VMware hgfs: HgfsGetOpenFlags: invalid open " "flags %o. Ignoring the O_TRUNC flag.\n", flags)); #else DEBUG(VM_DEBUG_INFO, "HgfsGetOpenFlags: invalid open flags %o. " "Ignoring the O_TRUNC flag.\n", flags); #endif result = HGFS_OPEN_CREATE_SAFE; break; } return result; } /* *---------------------------------------------------------------------------- * * HgfsAttrToSolaris -- * * Maps Hgfs attributes to Solaris attributes, filling the provided Solaris * attribute structure appropriately. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void HgfsAttrToSolaris(struct vnode *vp, // IN: The vnode for this file const HgfsAttr *hgfsAttr, // IN: Hgfs attributes to copy from struct vattr *solAttr) // OUT: Solaris attributes to fill { ASSERT(vp); ASSERT(hgfsAttr); ASSERT(solAttr); DEBUG(VM_DEBUG_ENTRY, "HgfsAttrToSolaris: %p -> %p", hgfsAttr, solAttr); /* * We only fill in those fields that va_mask tells us to. */ if (solAttr->va_mask & AT_TYPE) { /* Set the file type. */ switch (hgfsAttr->type) { case HGFS_FILE_TYPE_REGULAR: solAttr->va_type = VREG; DEBUG(VM_DEBUG_ATTR, " Type: VREG\n"); break; case HGFS_FILE_TYPE_DIRECTORY: solAttr->va_type = VDIR; DEBUG(VM_DEBUG_ATTR, " Type: VDIR\n"); break; default: /* * There are only the above two filetypes. If there is an error * elsewhere that provides another value, we set the Solaris type to * none and ASSERT in devel builds. */ solAttr->va_type = VNON; DEBUG(VM_DEBUG_FAIL, "HgfsAttrToSolaris: invalid HgfsFileType provided.\n"); ASSERT(0); } } if (solAttr->va_mask & AT_MODE) { /* We only have permissions for owners. */ solAttr->va_mode = (hgfsAttr->permissions << HGFS_ATTR_MODE_SHIFT); DEBUG(VM_DEBUG_ATTR, " Owner's permissions: %o\n", solAttr->va_mode >> HGFS_ATTR_MODE_SHIFT); } if (solAttr->va_mask & AT_UID) { DEBUG(VM_DEBUG_ATTR, " Setting uid\n"); solAttr->va_uid = 0; /* XXX root? */ } if (solAttr->va_mask & AT_GID) { DEBUG(VM_DEBUG_ATTR, " Setting gid\n"); solAttr->va_gid = 0; /* XXX root? */ } if (solAttr->va_mask & AT_FSID) { DEBUG(VM_DEBUG_ATTR, " Setting fsid\n"); solAttr->va_fsid = vp->v_vfsp->vfs_dev; } if (solAttr->va_mask & AT_NODEID) { /* Get the node id calculated for this file in HgfsVnodeGet() */ solAttr->va_nodeid = HGFS_VP_TO_NODEID(vp); DEBUG(VM_DEBUG_ATTR, "*HgfsAttrToSolaris: fileName %s\n", HGFS_VP_TO_FILENAME(vp)); DEBUG(VM_DEBUG_ATTR, " Node ID: %llu\n", solAttr->va_nodeid); } if (solAttr->va_mask & AT_NLINK) { DEBUG(VM_DEBUG_ATTR, " Setting nlink\n"); solAttr->va_nlink = 1; /* fake */ } if (solAttr->va_mask & AT_SIZE) { DEBUG(VM_DEBUG_ATTR, " Setting size\n"); solAttr->va_size = hgfsAttr->size; } if (solAttr->va_mask & AT_ATIME) { DEBUG(VM_DEBUG_ATTR, " Setting atime\n"); HGFS_SET_TIME(solAttr->va_atime, hgfsAttr->accessTime); } if (solAttr->va_mask & AT_MTIME) { DEBUG(VM_DEBUG_ATTR, " Setting mtime\n"); HGFS_SET_TIME(solAttr->va_mtime, hgfsAttr->writeTime); } if (solAttr->va_mask & AT_CTIME) { DEBUG(VM_DEBUG_ATTR, " Setting ctime\n"); /* Since Windows doesn't keep ctime, we may need to use mtime instead. */ if (HGFS_SET_TIME(solAttr->va_ctime, hgfsAttr->attrChangeTime)) { solAttr->va_ctime = solAttr->va_mtime; } } if (solAttr->va_mask & AT_RDEV) { DEBUG(VM_DEBUG_ATTR, " Setting rdev\n"); /* Since Windows doesn't keep ctime, we may need to use mtime instead. */ solAttr->va_rdev = 0; /* devices aren't allowed in Hgfs */ } if (solAttr->va_mask & AT_BLKSIZE) { DEBUG(VM_DEBUG_ATTR, " Setting blksize\n"); /* Since Windows doesn't keep ctime, we may need to use mtime instead. */ solAttr->va_blksize = HGFS_BLOCKSIZE; } if (solAttr->va_mask & AT_NBLOCKS) { DEBUG(VM_DEBUG_ATTR, " Setting nblocks\n"); solAttr->va_nblocks = (solAttr->va_size / HGFS_BLOCKSIZE) + 1; } #if HGFS_VFS_VERSION == 2 if (solAttr->va_mask & AT_VCODE) { DEBUG(VM_DEBUG_ATTR, " Setting vcode\n"); solAttr->va_vcode = 0; /* fake */ } #else if (solAttr->va_mask & AT_SEQ) { DEBUG(VM_DEBUG_ATTR, " Setting seq\n"); solAttr->va_seq = 0; /* fake */ } #endif HgfsDebugPrintVattr(solAttr); } /* *---------------------------------------------------------------------------- * * HgfsSetattrCopy -- * * Sets the Hgfs attributes that need to be modified based on the provided * Solaris attribute structure. * * Results: * Returns TRUE if changes need to be made, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static Bool HgfsSetattrCopy(struct vattr *solAttr, // IN: Attributes to change to int flags, // IN: Context of HgfsSetattr call HgfsAttr *hgfsAttr, // OUT: Hgfs attributes to fill in HgfsAttrChanges *update) // OUT: Hgfs attribute changes to make { uint32_t mask; Bool ret = FALSE; ASSERT(solAttr); ASSERT(hgfsAttr); ASSERT(update); memset(hgfsAttr, 0, sizeof *hgfsAttr); memset(update, 0, sizeof *update); /* This is the mask of attributes to change. */ mask = solAttr->va_mask; /* * Hgfs supports changing these attributes: * o mode bits (permissions) * o size * o access/write times */ if (mask & AT_MODE) { DEBUG(VM_DEBUG_COMM, "HgfsSetattrCopy: updating permissions.\n"); *update |= HGFS_ATTR_PERMISSIONS; hgfsAttr->permissions = (solAttr->va_mode & S_IRWXU) >> HGFS_ATTR_MODE_SHIFT; ret = TRUE; } if (mask & AT_SIZE) { DEBUG(VM_DEBUG_COMM, "HgfsSetattrCopy: updating size.\n"); *update |= HGFS_ATTR_SIZE; hgfsAttr->size = solAttr->va_size; ret = TRUE; } if (mask & AT_ATIME) { DEBUG(VM_DEBUG_COMM, "HgfsSetattrCopy: updating access time.\n"); *update |= HGFS_ATTR_ACCESS_TIME | ((flags & ATTR_UTIME) ? HGFS_ATTR_ACCESS_TIME_SET : 0); hgfsAttr->accessTime = HGFS_GET_TIME(solAttr->va_atime); ret = TRUE; } if (mask & AT_MTIME) { DEBUG(VM_DEBUG_COMM, "HgfsSetattrCopy: updating write time.\n"); *update |= HGFS_ATTR_WRITE_TIME | ((flags & ATTR_UTIME) ? HGFS_ATTR_WRITE_TIME_SET : 0); hgfsAttr->writeTime = HGFS_GET_TIME(solAttr->va_mtime); ret = TRUE; } return ret; } /* *---------------------------------------------------------------------------- * * HgfsMakeFullName -- * * Concatenates the path and filename to construct the full path. This * handles the special cases of . and .. filenames so the Hgfs server * doesn't return an error. * * Results: * Returns the length of the full path on success, and a negative value on * error. The full pathname is placed in outBuf. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsMakeFullName(const char *path, // IN: Path of directory containing file uint32_t pathLen, // IN: Length of path const char *file, // IN: Name of file char *outBuf, // OUT: Location to write full path ssize_t bufSize) // IN: Size of the out buffer { ASSERT(path); ASSERT(file); ASSERT(outBuf); DEBUG(VM_DEBUG_INFO, "HgfsMakeFullName:\n" " path: \"%s\" (%d)\n" " file: \"%s\" (%ld)\n", path, pathLen, file, (long) strlen(file)); /* * Here there are three possibilities: * o file is ".", in which case we just place path in outBuf * o file is "..", in which case we strip the last component from path and * put that in outBuf * o for all other cases, we concatenate path, a path separator, file, and * a NUL terminator and place it in outBuf */ /* Make sure that the path and a NUL terminator will fit. */ if (bufSize < pathLen + 1) { return HGFS_ERR_INVAL; } /* Copy path for this file into the caller's buffer. */ memset(outBuf, 0, bufSize); memcpy(outBuf, path, pathLen); /* Handle three cases. */ if (strcmp(file, ".") == 0) { /* NUL terminate and return provided length. */ outBuf[pathLen] = '\0'; return pathLen; } else if (strcmp(file, "..") == 0) { /* * Replace the last path separator with a NUL terminator, then return the * size of the buffer. */ char *newEnd = strrchr(outBuf, '/'); if (!newEnd) { /* * We should never get here since we name the root vnode "/" in * HgfsMount(). */ return HGFS_ERR_INVAL; } *newEnd = '\0'; return ((uintptr_t)newEnd - (uintptr_t)outBuf); } else { /* * The full path consists of path, the path separator, file, plus a NUL * terminator. Make sure it will all fit. */ int fileLen = strlen(file); if (bufSize < pathLen + 1 + fileLen + 1) { return HGFS_ERR_INVAL; } /* * The CPName_ConvertTo function handles multiple path separators * at the beginning of the filename, so we skip the checks to limit * them to one. This also enables clobbering newEnd above to work * properly on base shares (named "//sharename") that need to turn into * "/". */ outBuf[pathLen] = '/'; /* Now append the filename and NUL terminator. */ memcpy(outBuf + pathLen + 1, file, fileLen); outBuf[pathLen + 1 + fileLen] = '\0'; return pathLen + 1 + fileLen; } } /* * Process signal mask manipulation */ /* *---------------------------------------------------------------------------- * * HgfsDisableSignals -- * * Disables signals of current thread by calling sigintr(). * * Results: * Returns the old set of signals this process ignores. * * Side effects: * This process is now only delivered SIGKILL sinals. * *---------------------------------------------------------------------------- */ INLINE static void HgfsDisableSignals(k_sigset_t *oldIgnoreSet) // OUT: Current thread's ignore set { ASSERT(oldIgnoreSet); /* * Passing sigintr() a 1 ensures that SIGINT will not be blocked. */ sigintr(oldIgnoreSet, 1); /* * Note that the following alone works for Netscape ... * sigaddset(&curthread->t_hold, SIGALRM); */ } /* *---------------------------------------------------------------------------- * * HgfsRestoreSignals -- * * Restores the current process' set of signals to ignore to the provided * signal set. * * Results: * None. * * Side effects: * The process will now be delivered signals as dictated by the oldSigSet. * *---------------------------------------------------------------------------- */ INLINE static void HgfsRestoreSignals(k_sigset_t *oldIgnoreSet) { ASSERT(oldIgnoreSet); /* * sigunintr() will replace the current thread's blocked signals with the * provided signal set. */ sigunintr(oldIgnoreSet); /* * Note that the following alone works for Netscape ... * sigdelset(&curthread->t_hold, SIGALRM); */ } /* * This is a less-tested, alternate implementation of HgfsReaddir(). The * difference is that this one copies each entry individually so it doesn't * have to a malloc() a buffer of size readSize (see the XXX comment in the * HgfsReaddir() implementation above). The thinking is that this approach is * likely safer, but has the potential to be slower. Initial tests show that * this implementation "feels" the same speed as the other one. */ #if 0 static int HgfsReaddir(struct vnode *vp, // IN: Vnode of directory to read struct uio *uiop, // IN: User's read request struct cred *cr, // IN: Credentials of caller int *eofp) // OUT: Indicates we are done { HgfsSuperInfo *sip; HgfsHandle handle; struct dirent64 *dirp; char buf[sizeof *dirp + MAXNAMELEN]; ssize_t readSize; uint64_t offset; Bool done; int ret; DEBUG(VM_DEBUG_ENTRY, "HgfsReaddir().\n"); if (!vp || !uiop || !cr || !eofp) { cmn_err(HGFS_ERROR, "HgfsReaddir: NULL input from Kernel.\n"); return EINVAL; } DEBUG(VM_DEBUG_ENTRY, "HgfsReaddir: uiop->uio_resid=%d, uiop->uio_loffset=%d\n", uiop->uio_resid, uiop->uio_loffset); /* * XXX: If would be nice if we could perform some sort of sanity check on * the handle here. Perhaps make sure handle <= NUM_SEARCHES in * hgfsServer.c since the handle is the index number in searchArray. */ if ( !HGFS_KNOW_FILENAME(vp) ) { DEBUG(VM_DEBUG_FAIL, "HgfsReaddir: we don't know the filename.\n"); return EBADF; } sip = HgfsGetSuperInfo(); if (!sip) { DEBUG(VM_DEBUG_FAIL, "HgfsReaddir: we can't get the superinfo.\n"); return EIO; } /* * In order to fill the user's buffer with directory entries, we must * iterate on HGFS_OP_SEARCH_READ requests until either the user's buffer is * full or there are no more entries. Each call to HgfsGetNextDirEntry() * fills in the name and attribute structure for the next entry. We then * escape the name, create the directory entry in our temporary buf, and * copy the entry to the user's buffer. */ readSize = uiop->uio_resid; dirp = (struct dirent64 *)buf; /* * We need to get the handle for this open directory to send to the Hgfs * server in our requests. */ ret = HgfsGetOpenFileHandle(vp, &handle); if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsReaddir: could not get handle.\n"); return EINVAL; } /* * Loop until one of the following conditions is met: * o An error occurs while reading a directory entry * o There are no more directory entries to read * o The buffer is full and cannot hold the next entry * * We request dentries from the Hgfs server based on their index in the * directory. The offset value is initialized to the value specified in * the user's io request and is incremented each time through the loop. * * We decrement readSize by the size of the directory entry each time we * successfully copy one into the user's buffer. */ for (offset = uiop->uio_loffset, done = 0; /* Nothing */ ; offset++) { char nameBuf[MAXNAMELEN + 1]; char escName[MAXNAMELEN + 1]; char fullName[MAXPATHLEN + 1]; DEBUG(VM_DEBUG_COMM, "HgfsReaddir: getting directory entry at offset %d.\n", offset); memset(nameBuf, 0, sizeof nameBuf); memset(buf, 0, sizeof buf); ret = HgfsGetNextDirEntry(sip, handle, offset, nameBuf, &done); /* If the filename was too long, we skip to the next entry ... */ if (ret == EOVERFLOW) { continue; /* ... but if another error occurred, we return that error code ... */ } else if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsReaddir: failure occurred in HgfsGetNextDirEntry\n"); goto out; /* * ... and if there are no more entries, we set the end of file pointer * and break out of the loop. */ } else if (done == TRUE) { DEBUG(VM_DEBUG_COMM, "HgfsReaddir: Done reading directory entries.\n"); *eofp = TRUE; break; } /* * We now have the directory entry, so we sanitize the name and try to * put it in our buffer. */ DEBUG(VM_DEBUG_COMM, "HgfsReaddir: received filename \"%s\"\n", nameBuf); memset(escName, 0, sizeof escName); ret = HgfsEscape_Do(nameBuf, strlen(nameBuf), MAXNAMELEN, escName); /* If the escaped name didn't fit in the buffer, skip to the next entry. */ if (ret < 0 || ret > MAXNAMELEN) { DEBUG(VM_DEBUG_FAIL, "HgfsReaddir: HgfsEscape_Do failed.\n"); continue; } /* * Make sure there is enough room in the buffer for the entire directory * entry. If not, we just break out of the loop and copy what we have. */ if (DIRENT64_RECLEN(ret) > readSize) { DEBUG(VM_DEBUG_INFO, "HgfsReaddir: ran out of room in the buffer.\n"); break; } /* Fill in the directory entry. */ dirp->d_reclen = DIRENT64_RECLEN(ret); dirp->d_off = offset; memcpy(dirp->d_name, escName, ret); dirp->d_name[ret] = '\0'; ret = HgfsMakeFullName(HGFS_VP_TO_FILENAME(vp), // Directorie's name HGFS_VP_TO_FILENAME_LENGTH(vp), // Length dirp->d_name, // Name of file fullName, // Destination buffer sizeof fullName); // Size of this buffer /* Skip this entry if the full path was too long. */ if (ret < 0) { continue; } /* * Place the node id, which serves the purpose of inode number, for this * filename directory entry. As long as we are using a dirent64, this is * okay since ino_t is also a u_longlong_t. */ HgfsNodeIdGet(&sip->fileHashTable, fullName, (uint32_t)ret, (u_longlong_t *)&dirp->d_ino); /* * Now that we've filled our buffer with as many dentries as fit, we copy it * into the user's buffer. */ ret = uiomove(dirp, // Source buffer dirp->d_reclen, // Size of this buffer UIO_READ, // Read flag uiop); // User's request struct /* Break the loop if we can't copy this dentry into the user's buffer. */ if (ret) { goto out; } /* Decrement the number of bytes copied on success */ readSize -= dirp->d_reclen; } /* Return success */ ret = 0; out: /* * uiomove(9F) will have incremented the uio offset by the number of bytes * written. We reset it here to the fs-specific offset in our directory so * the next time we are called it is correct. (Note, this does not break * anything and /is/ how this field is intended to be used.) */ uiop->uio_loffset = offset; // XXX ok to do this on error too? DEBUG(VM_DEBUG_DONE, "HgfsReaddir: done (ret=%d, *eofp=%d).\n", ret, *eofp); DEBUG(VM_DEBUG_ENTRY, "HgfsReaddir: exiting.\n"); return ret; } #endif open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/docs/0000755765153500003110000000000012220061556021005 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/docs/hgfs-9-to-10.txt0000644765153500003110000001252712220061556023510 0ustar dtormtsNotes for porting Hgfs from Solaris 9 to 10 =========================================== Note that Solaris 10 is a beta and still in development, so these notes may become outdated. They are based on the headers in build 52. vnode.h ------- o Now use vn_make_ops() to create vnodeops int vn_make_ops(const char *, const fs_operation_def_t *, vnodeops_t **); void vn_freevnodeops(vnodeops_t *); o Now use vfs_makefsops()/vfs_setfsops() to create vfsops (see vfs.h notes) o There is a new structure struct fs_operation_def_t: typedef int (*fs_generic_func_p) (); typedef struct fs_operation_def { char *name; /* name of operation (NUL terminated) */ fs_generic_func_p func; /* function implementing operation */ } fs_operation_def_t; The name is likely one of the VOPNAME_* macros. o vnodes should only be created by calls to vn_alloc(); they may not be embedded in fs-specific structures; vnodes may change size. Definitions for related vnode allocation/freeing functions are: vnode_t *vn_alloc(int); void vn_reinit(vnode_t *); void vn_free(vnode_t *); Note that the vn_free() function destroys the vnode's mutex so doing so yourself will crash the system. o There are a quite a few new vnode manipulation functions; see vnode.h. o v_vfsmountedhere member of struct vnode is private, perhaps we shouldn't touch it; it is also protected by vn_vfswlock in vnode.c o A number of private members were added to struct vnode -- shouldn't affect us o New structure struct caller_context contains PID of caller, system ID, and a caller identifier. This structure is now passed in as the last argument to: o vop_read o vop_write o vop_setattr o vop_rwlock o vop_rwunlock o vop_space o vop_shrlock now takes an additional cred_t * argument as its last argument o A new vnodeop was added: int (*vop_vnevent)(vnode_t *, vnevent_t); This likely has to do "something" to the vnode depending on the value of vnevent_t. It is likely that this is required since the vnode now stores the cached path of the file in its private char *v_path member. Can we use vnevent_*() for help, or do these call us? How about the new vn_setpath*(), vn_path(), and vn_copypath() functions? (We should use the VN_SETPATH() macro instead of calling vn_setpath() directly.) o vnevent_t is a new enum with the following definition: typedef enum vnevent { VE_SUPPORT = 0, /* Query */ VE_RENAME_SRC = 1, /* Rename, with vnode as source */ VE_RENAME_DEST = 2, /* Rename, with vnode as target/dest */ VE_REMOVE = 3, /* Remove of vnode's name */ VE_RMDIR = 4 /* Remove of directory vnode's name */ } vnevent_t; o A new macro VN_SET_VFS_TYPE_DEV(vp, vfsp, type, dev) was created, but it is trivial. o VN_CMP() now calls vn_getops() rather than dereferencing the vnode's vn_ops member. (We should use this to access that variable too, it seems.) o There is no more VN_INIT() macro, but it was trivial anyhow. vfs.h ----- o Filesystems now must supply their list of vfs operations using: int vfs_setfsops(int, const fs_operation_def_t *, vfsops_t **); o There are also functions for filesystems to make, free, etc vfs operation structures: int vfs_makefsops(const fs_operation_def_t *, vfsops_t **); void vfs_freevfsops(vfsops_t *); int vfs_freevfsops_by_type(int); void vfs_setops(vfs_t *, vfsops_t *); vfsops_t *vfs_getops(vfs_t *vfsp); The names placed in fs_operation_def_t->name are likely one of the VFSNAME_* macros. o This isn't relevant to our layer, but the vfs now keeps filesystems in a double linked circular list rather than a singly linked list. There are also issues with zones: each zone has a list of its own mounts. o The vfs_op member of struct vfs should never be directly accessed; use the accessor functions described above. o There is a new function in struct vfsops: int (*vfs_vnstate)(vfs_t *, vnode_t *, vntrans_t); o vntrans_t is a new enum that is either VNTRANS_EXISTS, VNTRANS_IDLED, VNTRANS_RECLAIMED, or VNTRANS_DESTROYED. o The function pointer vsw_init member of struct vfssw now has the definition: int (*vsw_init)(int, char *) Also, the vsw_optproto and vsw_vfsops members are no longer pointers. Since we will not be directly including this structure in our modlfs anymore (see modctl.h notes), these differences probably don't matter. o There is a new structure (that will be used in our modlfs now instead of struct vfssw). typedef struct vfsdef_v2 { int def_version; /* structure version, must be first */ char *name; /* filesystem type name */ int (*init) (int, char *); /* init routine */ int flags; /* fs flags */ mntopts_t *optproto; /* mount options table prototype */ } vfsdef_v2; Note that build 58 contains the same structure but it is called vfsdef_v3. o There are a few other additional macros and functions that likely won't matter to us. modctl.h -------- o struct modlfs now has a struct vfsdef_v3 instead of a struct vfssw o other changes don't seem relevant devops.h -------- o There are no changes to struct cb_ops, struct dev_ops, or any of the command enums taken by these functions. open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/docs/kadb.txt0000644765153500003110000000417312220061556022454 0ustar dtormtsSolaris kadb cheat sheet ========================= Setting up ---------- See Chapter 18 of Solaris' 9 "Writing Device Drivers" (http://docs.sun.com/db/doc/806-5222) If using a tip connection, boot with 'b kadb -d' and at the break for __start, create a deferred breakpoint with this command: hgfs# HgfsDevAttach:b Breakpoints ----------- Deferred: # :b Regular : :b - Regular will complain if symbol isn't found. Examples: hgfs# HgfsDevAttach:b --> deferred breakpoint for HgfsDevAttach takes effect when hgfs module is loaded HgfsGetNewReq:b --> breakpoint for HgfsGetNewReq Commands at breakpoints: :c : continue :s : single step :e : single step over function calls :u : stop after return to caller of current function :d : delete breakpoint :z : delete allbreakpoints Viewing ------- ,/ : symbol name, as in HgfsDevAttach, or address : number of items to show : see pg. 348 "Writing Device Drivers" for complete list Common: d,D : 2,4-byte decimal x,X : 2,4-byte hex K : 4-byte hex for 32 bit progs (use this for pointers) u,U : 2,4-byte unsigned decimal c,C : character, without or with ^escape notation s,S : string, without or with ^escape notation i : instructions a : prints address in symbolic form w,W : 2,4-byte write Examples: HgfsGetNewReq,24/ai --> see first 24 instructions of HgfsGetNewReq 0x01234567,24/X --> see 24 4-byte words at that address in hex *0x1234567,24/X --> see the 24 4-byte words at memory address specified in 0x1234567 Macros ------ $r : view registers $c : stack trace $b : display breakpoints Pager (pause after lines) ----- 0t::more Registers --------- Display a single register: <(register)=K Set value of a register : (value)>(register) Examples: eip Set the value of eip to 0xdf78b1f8 open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/docs/hgfs.conf0000644765153500003110000000013412220061556022601 0ustar dtormts# name= parent="pseudo" instance=0; name="vmhgfs" parent="pseudo" instance=0; open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/docs/append-to-devlink.tab0000644765153500003110000000007112220061556025014 0ustar dtormtstype=ddi_pseudo;name=vmhgfs;addr=0;minor=vmware-hgfs \M0 open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/docs/BUILD0000644765153500003110000002114112220061556021566 0ustar dtormtsSolaris Hgfs Build Instructions =============================== Last Updated: 11/22/2005 (biggadike@vmware.com) Hgfs Kernel Module ------------------ 0. One-time Guest Operations 1. Building with the Linux cross-compiler (Solaris 9) 2. Building from the Guest (Solaris 10) Tools ----- 0. Building guestd and the toolbox 1. Running guestd 2. Running the toolbox Hgfs Kernel Module ------------------ 0. One-time Guest Operations ------------------------- Requirements: just a Solaris 9 or 10 guest o First, to build you'll need to make sure gmake, gcc, and binutils are installed. The easiest way to install these is to use the pkg-get script from http://www.blastwave.org/pkg-get.php. Follow the instructions there then do: # pkg-get -U # pkg-get -i gmake gcc2 binutils # export PATH=$PATH:/opt/csw/bin (for Bash) # alias make='gmake' (for Bash) o You'll need to add an entry to the device link table so that when the driver is loaded a symlink called /dev/vmware-hgfs is created that points to the entry in the Kernel's device tree (/devices). # cat docs/append-to-devlink.tab >> /etc/devlink.tab o You'll also need a copy of the driver's configuration file where the kernel looks for it. # cp docs/hgfs.conf /usr/kernel/drv o You also need to create the directory where guestd will mount the filesystem: # mkdir -p /mnt/hgfs These only need to be done once. 1. Building with the Linux cross-compiler (Solaris 9) ----------------------------------------------------- Note that the cross-compiler is currently only for Solaris 9. o From top of bora-vmsoft: # make tools-for-solaris o Respected build variables: VMX86_DEVEL : gets passed on to code VMX86_DEBUG : enables assertion checking VMX86_LOG : enables logging SOL_VERSION : defaults to 9 because the Solaris 10 cross-compiler doesn't exist yet o Installing Targets (run these from the guest): rem : removes the driver from the system install : installs the driver and driver config file to the proper directories add : adds the driver to the system rotate : invokes rem, install, then add. Note that most of the time rotate will take care of everything for you, but if guestd is running this may cause problems because the driver will be added even if the module cannot be removed. Just kill guestd then make rotate. 2. Building from the Guest (Solaris 10) --------------------------------------- Note that this is currently the only way to build in Solaris 10. o Make sure the BORA, BUILD, and BUILDROOT variables are set properly in the Makefile.guest. It's likely all you need know is: make -f Makefile.guest module make -f Makefile.guest install add If you want to disable debugging, use: make -f Makefile.guest module DEBUG=OFF If you get a "module already loaded" error, try: make -f Makefile.guest rotate o Building targets: module : builds only the Kernel module (current default) clean : cleans build files o Building variables: DEBUG=OFF : turns off all debugging output from the module (faster!) ASSERT=OFF : turns off ASSERT()s SOL_VERSION : defaults to 10 and automatically determines which build number this is with uname -v (52 and 58 are the only builds tested) o Installing Targets (run these from the guest): rem : removes the driver from the system install : installs the driver and driver config file to the proper directories add : adds the driver to the system rotate : invokes rem, install, then add. once : appends necessary lines to /etc/devlink.tab (only needed once) initbuilddir: creates the build directory Tools ----- 0. Building guestd and the toolbox ------------------------------ o guestd has been ported to Solaris and is built using the Solaris 9 cross compiler mentioned above. The toolbox has not been ported to Solaris and is run using lxrun. Building both is handled by the Makefiles in bora-vmsoft: # cd /path/to/bora-vmsoft # make tools-for-solaris The binaries will be located at $(BUILD)/obj/ws/tools-for-solaris/guestd/guestd and $(BUILD)/obj/ws/tools-for-solaris/toolbox/toolbox. 1. Running guestd ----------------- o guestd runs natively on Solaris 9. It will mount Hgfs at /mnt/hgfs and your "Shared Folders" will be visible there. o I have not been able to use the bora-vmsoft Makefile infrastructure from within a Solaris 10 guest, so it is not currently possible to build guestd for Solaris 10. Porting the Makefiles to run inside the guest should not be too difficult and a Solaris 10 cross compiler would allow guestd to be built for Solaris 10. 2. Running the toolbox ---------------------- o It is first necessary to set up lxrun on the guestd Setting up lxrun ---------------- o lxrun enables you to run Linux binaries in Solaris by catching and translating all of their system calls. This works relatively well for running guestd and toolbox, but you must install lxrun and build versions of the programs that have been "ported" to lxrun. o Install lxrun on the guest: The easiest way is to see if ~biggadike/public_html/lxrun/lxrun-environ.tgz exists. If so, extract this to the root of your guest's filesystem: # cd / # gunzip /path/to/lxrun-environ.tgz # tar xvf /path/to/lxrun-environ.tar This will create two directories: /lx and /usr/local/lxrun. /lx contains a linux environment (circa Red Hat 6.2) and the lxrun executable. /usr/local/lxrun contains a file called PATHMAP which tells lxrun where to get its environment files from (/lx). If the precompiled environment doesn't work, you'll need to get lxrun 0.9.6pre1, compile it, and then use a Red Hat 6.2 Installation CD with the INSTALL-RH6 script in the lxrun directory. o Try ~biggadike/public_html/lxrun/lxrun-0.9.6pre1.tar.gz or http://www.ugcs.caltech.edu/~steven/lxrun/ for the lxrun source o Try exit15:/home/ISO-Images/vol1/redhat/RedHat6.2.iso for the Red Hat disc **Note that it is not necessary to patch lxrun for the toolbox. The patch in the directory mentioned above is to enable lxrun to run guestd, which is no longer necessary since it has been ported. The lxrun binary in the lxrun-environ.tgz file is a patched version, but this does also work for running the toolbox. o Set necessary environment variables: You will also need a few environment variables set. For bash, add these lines to your .bashrc: export LXRUN_ROOT=/lx export PATH=$PATH:/lx o The following steps outline running the toolbox with lxrun Running the toolbox ------------------- o Just copy (or make available) the above binaries on your guest and invoke them with lxrun: # lxrun /path/to/toolbox & (It is usually best to background this process.) o lxrun can also log the system calls it translates using its trace feature: # lxrun -t all /path/to/toolbox This will trace all the system calls guestd makes. The output file is always placed in /tmp/lxrun.. You can also restrict the system calls that are traced to a particular subset, run lxrun without any options to see the usage. It also appears possible to chroot the running process with -r, to specify the linux root directory with -R, and specify the uname of the emulated Linux system with -U. I haven't ever needed to use these options. o Mouse grab/ungrab and device connection/disconnection are both known to work. Notes from the old BUILD file that may still be helpful ------------------------------------------------------- o You can verify the module is installed with: # modinfo | grep hgfs This should output text of this format: hgfs (HGFS Device Interface) hgfs (Host/Guest Filesystem) There are two entries for the same ID number because we've placed both the device driver and the filesystem in a single loadable kernel module. o You can load the driver into the Kernel by hand with: # /usr/sbin/add_drv -v -m '* 0644 root sys' hgfs This should output something similar to: devfsadm[1032]: verbose: mknod /devices/pseudo/hgfs@0:vmware-hgfs 0l/3l/20644 devfsadm[1032]: verbose: symlink /dev/vmware-hgfs -> ../devices/pseudo/hgfs@0:vmware-hgfs o You can remove the driver from the system by hand with: # /usr/sbin/rem_drv hgfs open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/docs/FILES0000644765153500003110000000255612220061556021602 0ustar dtormtsFiles ===== Driver (hgfs/solaris/) ---------------------------------- hgfsSolaris.h - definitions global to all parts of module module.{c,h} - module initialization routines (_init(), _fini()) and structures (struct modlinkage, struct modlfs, ...) filesystem.{c,h} - filesystem level functions (mount(), unmount()) hgfsState.{c,h} - maintains internal state of filesystem (HgfsOpenFile, HgfsFile) vnode.c - file level functions (open(), read(), close()) device.{c,h} - device interface (attach(), detach(), open(), read(), close()) request.{c,h} - functions that initialize, allocate, and manipulate requests and the lists that they are on debug.{c,h} - debugging routines and macros Misc (hgfs/solaris/docs) ------------------------------------ hgfs.conf - must be place in /usr/kernel/drv/ append-to-devlink.tab - must append this text to /etc/devlink.tab to generate symlink /dev/vmware-hgfs Docs (hgfs/solaris/docs) ------------------------------------ BUILD - build instructions synchronization.txt - outline of how components are synchronized request-lifecycle.txt - outline of how requests travel through driver kadb.txt - cheat sheet for Solaris' kernel debugger hgfs-9-to-10.txt - notes for porting from Solaris 9 to 10 open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/docs/request-lifecycle.txt0000644765153500003110000001102612220061556025173 0ustar dtormtsThe lifecycle of a request in the Solaris HGFS code =================================================== Note that this design is based almost entirely on the Linux HGFS code. Data Structures --------------- - A preallocated request pool array. (requestPool[]) - A list of the current free requests. (reqFreeList) - A list of the currently pending requests (reqList) Request States -------------- - Unused: This is a request's initial state and it guarantees that the request is on the free request list. Requests are placed back in this state after the Abandoned, Error, or Completed states. - Allocated: The request has been allocated to a client and is not on any of the lists. - Submitted: The request has been filled out and has been placed on the pending request list. The request may leave the pending request list while still in this state. - Abandoned: The client was interrupted while waiting for the reply and has left the request to be cleaned up when a reply comes. The request is either still on the pending list or is not on any list, and will be accessed by its index into the requestPool array. - Error: An error occurred while submitting the request or awaiting the reply. The request is not on any lists. - Completed: The reply for this request has been received correctly. The request is not on any lists. State Transition ----------------- Each request starts as Unused and is then Allocated and Submitted. After the request is submitted, the request can be Abandoned, can have an Error occur, or can Complete successfully. Each of these states transitions back to the Unused state. --> Unused --> Allocated --> Submitted ---> Abandoned ------> Unused \ / --> Error --------> \ / -> Completed --> Functions --------- These functions will affect the state of requests and their locations on the lists. - HgfsInitRequestList(): This will initialize each request's state to UNUSED and ID to its index into the requestPool array. Each request will also be added to the free request list (reqFreeList). - HgfsCancelAllRequests(): Iterates over the pending request list and the request pool and cancels each request. If a request is abandoned it must clean up for the interrupted process; if the requester is waiting, set the request state to error and wake up the client. - HgfsGetNewReq(): Takes an UNUSED request off the free list (reqFreeList) and sets its state to ALLOCATED. The request will not be on any lists after this function is completed. - HgfsEnqueueRequest(): Puts an ALLOCATED request on to the pending request list (reqList) and sets its state to SUBMITTED. The request should not be on any of the lists when this function is called. This function will also assume that the list lock is held since most callers of this function will need to enqueue and do other operations atomically. - HgfsDequeueRequest(): Takes a SUBMITTED or ERROR request from the pending request list (reqList). The request will not be on any lists after this function is completed. For the reason noted above, this function also assumes the list lock is held by the caller. - HgfsDestroyReq(): Puts a COMPLETED, ERROR, or ABANDONED request on to the free list (reqFreeList) and sets its state to UNUSED. The request should not be on any lists when this function is called. - HgfsReqSetState(): Will set the state of the specified request to the specified value. This abstraction is to help prevent forgetting to lock the state's mutex. - HgfsReqGetState(): Will return the state of the specified request. This abstraction is to help prevent forgetting to lock the state's mutex. Submitting a request -------------------- { request = HgfsGetNewReq(superinfo); if (request is NULL) { return error } Fill in specific request information in request->packet - header.id and header.op of specific request struct should be set - request specific information should be filled in - request->packetSize should be set if (HgfsSubmitRequest(superinfo, request) fails) { return error } if (HgfsValidateReply(request, minimum size) fails) { HgfsDestroyReq(superinfo, request); return error } Process reply and give to client HgfsDestroyReq(superinfo, request); } open-vm-tools-9.4.0-1280544/modules/solaris/vmhgfs/docs/synchronization.txt0000644765153500003110000000634012220061556025012 0ustar dtormtsSolaris HGFS Synchronization ============================ The Solaris synchronization primitives that will be used are mutexes and condition variables. Mutexes will protect access to shared resources and condition variables will synchronize the order of the operations by those accessing these resources. Synchronization must be achieved in two directions. First, a client that requests an operation on a HGFS file must wait for the reply from the HGFS server. Second, guestd must wait for requests to be made when it queries the HGFS device and there are no pending requests. To enable this synchronization, the superinfo structure will contain these elements: - a list of outgoing requests (reqList) - a condition variable for waiting until and signaling when requests are put on an empty list (reqCondVar) - a flag which indicates whether guestd is waiting for a request (guestdWaiting) - a mutex to protect access to these components (reqMutex) Additionally, each request structure should contain: - a condition variable for waiting for and signaling of replies to /this/ request (condVar) - a flag indicating whether the requesting thread has been interrupted and is no longer waiting for the reply (abandoned) The filesystem half of the driver will place requests onto reqList with the following pseudocode: { Acquire and initialize request structure from free request list mutex_enter(superinfo's reqMutex) HgfsEnqueueRequest(request list, request) if (superinfo's guestdWaiting is set) { cv_signal(superinfo's reqCondVar) } cv_wait_sig(request's condVar, superinfo's reqMutex) if (cv_wait_sig() was interrupted) { request's abandoned = TRUE release mutex and return EINTR } mutex_exit(superinfo's reqMutex) Read reply in request's packet When done, put request structure back on free list } Note that the calls to cv_signal() and cv_wait_sig() above must be atomic, otherwise a reply could come and incur a signal before cv_wait_sig() is called. Therefore, the superinfo's reqMutex must also be passed to the cv_wait_sig() on the request structure's condition variable. The device half of the driver will check for and take requests of the request list with the following pseudocode (HgfsDevRead()): { mutex_enter(superinfo's reqMutex) if (request list is empty) { superinfo's guestdWaiting = TRUE cv_wait_sig(superinfo's reqCondVar, superinfo's reqMutex) if (cv_wait_sig() was interrupted) { superinfo's guestdWaiting = FALSE release mutex and return EINTR } superinfo's guestdWaiting = FALSE } Take next request off request list mutex_exit(superinfo's reqMutex) Submit request to guestd } When a reply is received, the device half of the driver will handle it with the following pseudocode (HgfsDevWrite()): { Read in and verify the reply from guestd Get pointer to the request structure from the handle in reply Copy reply payload to the request packet mutex_enter(superinfo's reqMutex) if (request's abandoned is set) { Clean up on behalf of interrupted thread - place request back on free list return } cv_signal(request's condVar) mutex_exit(superinfo's reqMutex) } open-vm-tools-9.4.0-1280544/modules/linux/0000755765153500003110000000000012220061556016246 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/linux/dkms.conf0000644765153500003110000000304012220061556020050 0ustar dtormtsPACKAGE_NAME=open-vm-tools PACKAGE_VERSION=9.4.0 MAKE_CMD_TMPL="make VM_UNAME=\$kernelver \ MODULEBUILDDIR=$dkms_tree/$PACKAGE_NAME/$PACKAGE_VERSION/build" # The vsock module depends on symbols exported by the vmci module, so it # needs to be built afterwards; the MODULEBUILDDIR variable tells the makefiles # where to store / retrive those symbol files. MAKE[0]="$MAKE_CMD_TMPL -C vmblock; \ $MAKE_CMD_TMPL -C vmci; \ $MAKE_CMD_TMPL -C vmhgfs; \ $MAKE_CMD_TMPL -C vmsync; \ $MAKE_CMD_TMPL -C vmxnet; \ $MAKE_CMD_TMPL -C vsock" CLEAN[0]="$MAKE_CMD_TMPL -C vmblock clean; \ $MAKE_CMD_TMPL -C vmci clean; \ $MAKE_CMD_TMPL -C vmhgfs clean; \ $MAKE_CMD_TMPL -C vmsync clean"; \ $MAKE_CMD_TMPL -C vmxnet clean; \ $MAKE_CMD_TMPL -C vsock clean BUILT_MODULE_NAME[0]="vmblock" BUILT_MODULE_NAME[1]="vmci" BUILT_MODULE_NAME[2]="vmhgfs" BUILT_MODULE_NAME[3]="vmsync" BUILT_MODULE_NAME[4]="vmxnet" BUILT_MODULE_NAME[5]="vsock" BUILT_MODULE_LOCATION[0]="vmblock/" BUILT_MODULE_LOCATION[1]="vmci/" BUILT_MODULE_LOCATION[2]="vmhgfs/" BUILT_MODULE_LOCATION[3]="vmsync/" BUILT_MODULE_LOCATION[4]="vmxnet/" BUILT_MODULE_LOCATION[5]="vsock/" DEST_MODULE_LOCATION[0]="/kernel/fs/vmblock" DEST_MODULE_LOCATION[1]="/kernel/drivers/misc" DEST_MODULE_LOCATION[2]="/kernel/fs/vmhgfs" DEST_MODULE_LOCATION[3]="/kernel/drivers/misc" DEST_MODULE_LOCATION[4]="/kernel/drivers/net" DEST_MODULE_LOCATION[5]="/kernel/net/vsock" AUTOINSTALL="YES" open-vm-tools-9.4.0-1280544/modules/linux/dkms.sh0000644765153500003110000000744412220061556017551 0ustar dtormts#!/bin/sh ################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### Script for creating a dmks-compliant source tree from an open-vm-tools ### distribution. ### ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ if test -z "$1" -o -z "$2" then echo "usage: $0 src dst" echo echo "Where:" echo " src: root of unpacked open-vm-tools package" echo " dst: where to create the dkms tree" echo echo "The script will create an 'open-vm-tools' module with version 9.4.0." exit 1 fi src=$1 dst=$2/open-vm-tools-9.4.0 SHARED_HEADERS="backdoor_def.h" SHARED_HEADERS="$SHARED_HEADERS backdoor_types.h" SHARED_HEADERS="$SHARED_HEADERS circList.h" SHARED_HEADERS="$SHARED_HEADERS community_source.h" SHARED_HEADERS="$SHARED_HEADERS dbllnklst.h" SHARED_HEADERS="$SHARED_HEADERS guest_msg_def.h" SHARED_HEADERS="$SHARED_HEADERS includeCheck.h" SHARED_HEADERS="$SHARED_HEADERS vm_assert.h" SHARED_HEADERS="$SHARED_HEADERS vm_atomic.h" SHARED_HEADERS="$SHARED_HEADERS vm_basic_asm.h" SHARED_HEADERS="$SHARED_HEADERS vm_basic_asm_x86.h" SHARED_HEADERS="$SHARED_HEADERS vm_basic_asm_x86_64.h" SHARED_HEADERS="$SHARED_HEADERS vm_basic_defs.h" SHARED_HEADERS="$SHARED_HEADERS vm_basic_math.h" SHARED_HEADERS="$SHARED_HEADERS vm_basic_types.h" SHARED_HEADERS="$SHARED_HEADERS vm_device_version.h" SHARED_HEADERS="$SHARED_HEADERS vmci_sockets.h" SHARED_HEADERS="$SHARED_HEADERS vmware.h" SHARED_HEADERS="$SHARED_HEADERS vmware_pack_begin.h" SHARED_HEADERS="$SHARED_HEADERS vmware_pack_end.h" SHARED_HEADERS="$SHARED_HEADERS vmware_pack_init.h" SHARED_HEADERS="$SHARED_HEADERS x86cpuid.h" SHARED_HEADERS="$SHARED_HEADERS x86vendor.h" SHARED_HEADERS="$SHARED_HEADERS x86cpuid_asm.h" rm -rf $dst mkdir -p $dst cp -f `dirname $0`/dkms.conf $dst for m in vmblock vmci vmhgfs vmsync vmxnet vsock do mdst="$dst/$m" cp -rf $src/modules/linux/$m $mdst cp -rf $src/modules/linux/shared $mdst for h in $SHARED_HEADERS do cp -f $src/lib/include/$h $mdst/shared done # Shared vmblock code. if test $m = vmblock then cp -f $src/lib/include/vmblock.h $mdst/linux cp -rf $src/modules/shared/vmblock/* $mdst/linux fi # Backdoor library (for vmhgfs and vmmemctl). if test $m = vmhgfs -o $m = vmmemctl then cp -f $src/lib/include/backdoor.h $mdst cp -f $src/lib/backdoor/*.c $src/lib/backdoor/*.h $mdst fi # Other libraries used by vmhgfs if test $m = vmhgfs then cp -f $src/lib/include/cpName*.h $mdst cp -f $src/lib/include/escBitvector.h $mdst cp -f $src/lib/include/hgfs*.h $mdst cp -f $src/lib/include/message.h $mdst cp -f $src/lib/include/rpcout.h $mdst cp -f $src/lib/hgfs/*.c $src/lib/hgfs/*.h $mdst cp -f $src/lib/hgfsBd/*.c $mdst cp -f $src/lib/message/*.c $mdst cp -f $src/lib/rpcOut/*.c $mdst fi # Extra header file for vmsync. if test $m = vmsync then cp -f $src/lib/include/syncDriverIoc.h $mdst fi # Shared vmxnet headers. if test $m = vmxnet then cp -f $src/modules/shared/vmxnet/* $mdst/shared fi done open-vm-tools-9.4.0-1280544/modules/linux/vmxnet/0000755765153500003110000000000012220061556017567 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/linux/vmxnet/vmxnet_version.h0000644765153500003110000000222312220061556023025 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmxnet_version.h -- * * Version definitions for the Linux vmxnet driver. */ #ifndef _VMXNET_VERSION_H_ #define _VMXNET_VERSION_H_ #define VMXNET_DRIVER_VERSION 2.0.15.0 #define VMXNET_DRIVER_VERSION_COMMAS 2,0,15,0 #define VMXNET_DRIVER_VERSION_STRING "2.0.15.0" #endif /* _VMXNET_VERSION_H_ */ open-vm-tools-9.4.0-1280544/modules/linux/vmxnet/Makefile.kernel0000644765153500003110000000255112220061556022511 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 1998 VMware, Inc. All rights reserved. # # 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 version 2 and no later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ########################################################## #### #### VMware vmxnet Makefile to be distributed externally #### INCLUDE += -I. ifdef OVT_SOURCE_DIR INCLUDE += -I$(OVT_SOURCE_DIR)/modules/shared/vmxnet endif EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE) EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/skblin.c, -DVMW_SKB_LINEARIZE_2618, ) obj-m += $(DRIVER).o clean: rm -rf $(wildcard $(DRIVER).mod.c $(DRIVER).ko .tmp_versions \ Module.symvers Modules.symvers Module.markers modules.order \ $(foreach dir,./,$(addprefix $(dir),.*.cmd .*.o.flags *.o))) open-vm-tools-9.4.0-1280544/modules/linux/vmxnet/README0000644765153500003110000000071412220061556020451 0ustar dtormtsThe files in this directory are the source files for the VMware Virtual Ethernet Adapter driver. In order to build, make certain the Makefile is correct, especially about whether or not your system is multi-processor or not, and then just type: make from this directory. A copy of the module will be left in 'vmxnet.o', which can then be installed in /lib/modules//net. If you have any problems or questions, send mail to support@vmware.com open-vm-tools-9.4.0-1280544/modules/linux/vmxnet/COPYING0000644765153500003110000004310312220061556020623 0ustar dtormts GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. open-vm-tools-9.4.0-1280544/modules/linux/vmxnet/Makefile0000644765153500003110000001054112220061556021230 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 1998 VMware, Inc. All rights reserved. # # 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 version 2 and no later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ########################################################## #### #### VMware kernel module Makefile to be distributed externally #### #### #### SRCROOT _must_ be a relative path. #### SRCROOT = . # # open-vm-tools doesn't replicate shared source files for different modules; # instead, files are kept in shared locations. So define a few useful macros # to be able to handle both cases cleanly. # INCLUDE := ifdef OVT_SOURCE_DIR AUTOCONF_DIR := $(OVT_SOURCE_DIR)/modules/linux/shared/autoconf VMLIB_PATH = $(OVT_SOURCE_DIR)/lib/$(1) INCLUDE += -I$(OVT_SOURCE_DIR)/modules/linux/shared INCLUDE += -I$(OVT_SOURCE_DIR)/lib/include else AUTOCONF_DIR := $(SRCROOT)/shared/autoconf INCLUDE += -I$(SRCROOT)/shared endif VM_UNAME = $(shell uname -r) # Header directory for the running kernel ifdef LINUXINCLUDE HEADER_DIR = $(LINUXINCLUDE) else HEADER_DIR = /lib/modules/$(VM_UNAME)/build/include endif BUILD_DIR = $(HEADER_DIR)/.. DRIVER := vmxnet PRODUCT := tools-source # Grep program GREP = /bin/grep vm_check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null \ > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) vm_check_file = $(shell if test -f $(1); then echo "yes"; else echo "no"; fi) ifndef VM_KBUILD VM_KBUILD := no ifeq ($(call vm_check_file,$(BUILD_DIR)/Makefile), yes) ifneq ($(call vm_check_file,$(BUILD_DIR)/Rules.make), yes) VM_KBUILD := 26 endif endif export VM_KBUILD endif ifndef VM_KBUILD_SHOWN ifeq ($(VM_KBUILD), no) VM_DUMMY := $(shell echo >&2 "Using standalone build system.") else ifeq ($(VM_KBUILD), 24) VM_DUMMY := $(shell echo >&2 "Using 2.4.x kernel build system.") else VM_DUMMY := $(shell echo >&2 "Using 2.6.x kernel build system.") endif endif VM_KBUILD_SHOWN := yes export VM_KBUILD_SHOWN endif ifneq ($(VM_KBUILD), no) VMCCVER := $(shell $(CC) -dumpversion) # If there is no version defined, we are in toplevel pass, not yet in kernel makefiles... ifeq ($(VERSION),) ifeq ($(VM_KBUILD), 24) DRIVER_KO := $(DRIVER).o else DRIVER_KO := $(DRIVER).ko endif .PHONY: $(DRIVER_KO) auto-build: $(DRIVER_KO) cp -f $< $(SRCROOT)/../$(DRIVER).o # $(DRIVER_KO) is a phony target, so compare file times explicitly $(DRIVER): $(DRIVER_KO) if [ $< -nt $@ ] || [ ! -e $@ ] ; then cp -f $< $@; fi # Pass gcc version down the chain, so we can detect if kernel attempts to use unapproved compiler VM_CCVER := $(VMCCVER) export VM_CCVER VM_CC := $(CC) export VM_CC MAKEOVERRIDES := $(filter-out CC=%,$(MAKEOVERRIDES)) # # Define a setup target that gets built before the actual driver. # This target may not be used at all, but if it is then it will be defined # in Makefile.kernel # prebuild:: ; postbuild:: ; $(DRIVER_KO): prebuild $(MAKE) -C $(BUILD_DIR) SUBDIRS=$$PWD SRCROOT=$$PWD/$(SRCROOT) \ MODULEBUILDDIR=$(MODULEBUILDDIR) modules $(MAKE) -C $$PWD SRCROOT=$$PWD/$(SRCROOT) \ MODULEBUILDDIR=$(MODULEBUILDDIR) postbuild endif vm_check_build = $(shell if $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ $(CPPFLAGS) $(CFLAGS) $(CFLAGS_KERNEL) $(LINUXINCLUDE) \ $(EXTRA_CFLAGS) -Iinclude2/asm/mach-default \ -DKBUILD_BASENAME=\"$(DRIVER)\" \ -Werror -S -o /dev/null -xc $(1) \ > /dev/null 2>&1; then echo "$(2)"; else echo "$(3)"; fi) CC_WARNINGS := -Wall -Wstrict-prototypes CC_OPTS := $(GLOBAL_DEFS) $(CC_WARNINGS) -DVMW_USING_KBUILD ifdef VMX86_DEVEL CC_OPTS += -DVMX86_DEVEL endif ifdef VMX86_DEBUG CC_OPTS += -DVMX86_DEBUG endif include $(SRCROOT)/Makefile.kernel ifdef TOPDIR ifeq ($(VM_KBUILD), 24) O_TARGET := $(DRIVER).o obj-y := $($(DRIVER)-y) include $(TOPDIR)/Rules.make endif endif else include $(SRCROOT)/Makefile.normal endif #.SILENT: open-vm-tools-9.4.0-1280544/modules/linux/vmxnet/vmxnetInt.h0000644765153500003110000000725412220061556021744 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __VMXNETINT_H__ #define __VMXNETINT_H__ #define INCLUDE_ALLOW_MODULE #include "includeCheck.h" #define VMXNET_CHIP_NAME "vmxnet ether" #define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */ #define PKT_BUF_SZ 1536 #define VMXNET_MIN_MTU (ETH_MIN_FRAME_LEN - 14) #define VMXNET_MAX_MTU (16 * 1024 - 18) typedef enum Vmxnet_TxStatus { VMXNET_CALL_TRANSMIT, VMXNET_DEFER_TRANSMIT, VMXNET_STOP_TRANSMIT } Vmxnet_TxStatus; #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)) # define MODULE_PARM(var, type) # define net_device_stats enet_statistics #endif #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0)) # define le16_to_cpu(x) ((__u16)(x)) # define le32_to_cpu(x) ((__u32)(x)) #endif #if defined(BUG_ON) #define VMXNET_ASSERT(cond) BUG_ON(!(cond)) #else #define VMXNET_ASSERT(cond) #endif #define ASSERT(cond) VMXNET_ASSERT(cond) struct Vmxnet2_TxBuf { struct sk_buff *skb; char sgForLinear; /* the sg entry mapping the linear part * of the skb, -1 means this tx entry only * mapps the frags of the skb */ char firstSgForFrag; /* the first sg entry mapping the frags */ Bool eop; }; /* * Private data area, pointed to by priv field of our struct net_device. * dd field is shared with the lower layer. */ typedef struct Vmxnet_Private { Vmxnet2_DriverData *dd; dma_addr_t ddPA; size_t ddSize; const char *name; struct net_device_stats stats; struct sk_buff *rxSkbuff[ENHANCED_VMXNET2_MAX_NUM_RX_BUFFERS]; struct page *rxPages[VMXNET2_MAX_NUM_RX_BUFFERS2]; struct Vmxnet2_TxBuf txBufInfo[VMXNET2_MAX_NUM_TX_BUFFERS_TSO]; spinlock_t txLock; int numTxPending; unsigned int numRxBuffers; unsigned int numRxBuffers2; unsigned int numTxBuffers; Vmxnet2_RxRingEntry *rxRing; Vmxnet2_RxRingEntry *rxRing2; Vmxnet2_TxRingEntry *txRing; Bool devOpen; uint32 portID; uint32 capabilities; uint32 features; Bool zeroCopyTx; Bool partialHeaderCopyEnabled; Bool tso; Bool chainTx; Bool chainRx; Bool jumboFrame; Bool lpd; Bool morphed; // Indicates whether adapter is morphed size_t txBufferSize; char *txBufferStart; dma_addr_t txBufferPA; struct pci_dev *pdev; struct timer_list linkCheckTimer; } Vmxnet_Private; #endif /* __VMXNETINT_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/vmxnet/vmxnet.c0000644765153500003110000025334412220061556021267 0ustar dtormts/********************************************************* * Copyright (C) 1999 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmxnet.c: A virtual network driver for VMware. */ #include "driver-config.h" #include "compat_module.h" #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9) #include #endif #include "compat_slab.h" #include "compat_spinlock.h" #include "compat_pci.h" #include "compat_pci_mapping.h" #include "compat_timer.h" #include "compat_ethtool.h" #include "compat_netdevice.h" #include "compat_skbuff.h" #include #include "compat_ioport.h" #ifndef KERNEL_2_1 #include #endif #include "compat_interrupt.h" #include #include #include #include #include "vm_basic_types.h" #include "vmnet_def.h" #include "vmxnet_def.h" #include "vmxnet2_def.h" #include "vm_device_version.h" #include "vmxnetInt.h" #include "net.h" #include "eth_public.h" #include "vmxnet_version.h" static int vmxnet_debug = 1; #define VMXNET_WATCHDOG_TIMEOUT (5 * HZ) #if defined(CONFIG_NET_POLL_CONTROLLER) || defined(HAVE_POLL_CONTROLLER) #define VMW_HAVE_POLL_CONTROLLER #endif static int vmxnet_open(struct net_device *dev); static int vmxnet_start_tx(struct sk_buff *skb, struct net_device *dev); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) static compat_irqreturn_t vmxnet_interrupt(int irq, void *dev_id, struct pt_regs * regs); #else static compat_irqreturn_t vmxnet_interrupt(int irq, void *dev_id); #endif #ifdef VMW_HAVE_POLL_CONTROLLER static void vmxnet_netpoll(struct net_device *dev); #endif static int vmxnet_close(struct net_device *dev); static void vmxnet_set_multicast_list(struct net_device *dev); static int vmxnet_set_mac_address(struct net_device *dev, void *addr); static struct net_device_stats *vmxnet_get_stats(struct net_device *dev); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) static int vmxnet_set_features(struct net_device *netdev, compat_netdev_features_t features); #endif #if defined(HAVE_CHANGE_MTU) || defined(HAVE_NET_DEVICE_OPS) static int vmxnet_change_mtu(struct net_device *dev, int new_mtu); #endif static Bool vmxnet_check_version(unsigned int ioaddr); static Bool vmxnet_probe_features(struct net_device *dev, Bool morphed, Bool probeFromResume); static void vmxnet_release_private_data(Vmxnet_Private *lp, struct pci_dev *pdev); static int vmxnet_probe_device(struct pci_dev *pdev, const struct pci_device_id *id); static void vmxnet_remove_device(struct pci_dev *pdev); static Bool vmxnet_alloc_shared_mem(struct pci_dev *pdev, size_t size, void **vaOut, dma_addr_t *paOut); #ifdef CONFIG_PM /* * Prototype of suspend and resume handlers are different depending on the * version of Linux kernel. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) # define VMXNET_SUSPEND_DEVICE(pdev, state) \ static int vmxnet_suspend_device(struct pci_dev *pdev, pm_message_t state) # define VMXNET_RESUME_DEVICE(pdev) \ static int vmxnet_resume_device(struct pci_dev *pdev) # define VMXNET_SET_POWER_STATE_D0(pdev) pci_set_power_state(pdev, PCI_D0) # define VMXNET_SET_POWER_STATE(pdev, state) \ pci_set_power_state(pdev, pci_choose_state(pdev, state)) # define VMXNET_PM_RETURN(ret) return ret #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 6) # define VMXNET_SUSPEND_DEVICE(pdev, state) \ static int vmxnet_suspend_device(struct pci_dev *pdev, u32 state) # define VMXNET_RESUME_DEVICE(pdev) \ static int vmxnet_resume_device(struct pci_dev *pdev) # define VMXNET_SET_POWER_STATE_D0(pdev) (pdev)->current_state = 0 # define VMXNET_SET_POWER_STATE(pdev, state) \ do { \ (pdev)->current_state = state; \ } while (0) # define VMXNET_PM_RETURN(ret) return ret #else # define VMXNET_SUSPEND_DEVICE(pdev, state) \ static void vmxnet_suspend_device(struct pci_dev *pdev) # define VMXNET_RESUME_DEVICE(pdev) \ static void vmxnet_resume_device(struct pci_dev *pdev) # define VMXNET_SET_POWER_STATE_D0(pdev) # define VMXNET_SET_POWER_STATE(pdev, state) # define VMXNET_PM_RETURN(ret) #endif VMXNET_SUSPEND_DEVICE(pdev, state); VMXNET_RESUME_DEVICE(pdev); #endif /* CONFIG_PM */ #ifdef MODULE static int debug = -1; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9) module_param(debug, int, 0444); #else MODULE_PARM(debug, "i"); #endif #endif #ifdef VMXNET_DO_ZERO_COPY #undef VMXNET_DO_ZERO_COPY #endif #if defined(MAX_SKB_FRAGS) && \ ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,18) ) && \ ( LINUX_VERSION_CODE != KERNEL_VERSION(2, 6, 0) ) #define VMXNET_DO_ZERO_COPY #endif #define VMXNET_GET_LO_ADDR(dma) ((uint32)(dma)) #define VMXNET_GET_HI_ADDR(dma) ((uint16)(((uint64)(dma)) >> 32)) #define VMXNET_GET_DMA_ADDR(sge) ((dma_addr_t)((((uint64)(sge).addrHi) << 32) | \ (sge).addrLow)) #define VMXNET_FILL_SG(sg, dma, size)\ do{\ (sg).addrLow = VMXNET_GET_LO_ADDR(dma);\ (sg).addrHi = VMXNET_GET_HI_ADDR(dma);\ (sg).length = size;\ } while (0) #ifdef VMXNET_DO_ZERO_COPY #include #include #include #include /* * Tx buffer size that we need for copying header * max header is: 14(ip) + 4(vlan) + ip (60) + tcp(60) = 138 * round it up to the power of 2 */ #define TX_PKT_HEADER_SIZE 256 /* Constants used for Zero Copy Tx */ #define ETHERNET_HEADER_SIZE 14 #define VLAN_TAG_LENGTH 4 #define ETH_FRAME_TYPE_LOCATION 12 #define ETH_TYPE_VLAN_TAG 0x0081 /* in NBO */ #define ETH_TYPE_IP 0x0008 /* in NBO */ #define PKT_OF_PROTO(skb, type) \ (*(uint16*)(skb->data + ETH_FRAME_TYPE_LOCATION) == (type) || \ (*(uint16*)(skb->data + ETH_FRAME_TYPE_LOCATION) == ETH_TYPE_VLAN_TAG && \ *(uint16*)(skb->data + ETH_FRAME_TYPE_LOCATION + VLAN_TAG_LENGTH) == (type))) #define PKT_OF_IPV4(skb) PKT_OF_PROTO(skb, ETH_TYPE_IP) #if defined(NETIF_F_TSO) #define VMXNET_DO_TSO #if defined(NETIF_F_GSO) /* 2.6.18 and upwards */ #define VMXNET_SKB_MSS(skb) skb_shinfo(skb)->gso_size #else #define VMXNET_SKB_MSS(skb) skb_shinfo(skb)->tso_size #endif #endif #endif // VMXNET_DO_ZERO_COPY #ifdef VMXNET_DO_TSO static int disable_lro = 0; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9) module_param(disable_lro, int, 0); #else MODULE_PARM(disable_lro, "i"); #endif #endif #ifdef VMXNET_DEBUG #define VMXNET_LOG(msg...) printk(KERN_ERR msg) #else #define VMXNET_LOG(msg...) #endif // VMXNET_DEBUG /* Data structure used when determining what hardware the driver supports. */ static const struct pci_device_id vmxnet_chips[] = { { PCI_DEVICE(PCI_VENDOR_ID_VMWARE, PCI_DEVICE_ID_VMWARE_NET), .driver_data = VMXNET_CHIP, }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE), .driver_data = LANCE_CHIP, }, { 0, }, }; static struct pci_driver vmxnet_driver = { .name = "vmxnet", .id_table = vmxnet_chips, .probe = vmxnet_probe_device, .remove = vmxnet_remove_device, #ifdef CONFIG_PM .suspend = vmxnet_suspend_device, .resume = vmxnet_resume_device, #endif }; #if defined(HAVE_CHANGE_MTU) || defined(HAVE_NET_DEVICE_OPS) static int vmxnet_change_mtu(struct net_device *dev, int new_mtu) { struct Vmxnet_Private *lp = netdev_priv(dev); if (new_mtu < VMXNET_MIN_MTU || new_mtu > VMXNET_MAX_MTU) { return -EINVAL; } if (new_mtu > 1500 && !lp->jumboFrame) { return -EINVAL; } dev->mtu = new_mtu; return 0; } #endif #ifdef SET_ETHTOOL_OPS /* *---------------------------------------------------------------------------- * * vmxnet_get_settings -- * * Get device-specific settings. * * Results: * 0 on success, errno on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int vmxnet_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { ecmd->supported = SUPPORTED_1000baseT_Full | SUPPORTED_TP; ecmd->advertising = ADVERTISED_TP; ecmd->port = PORT_TP; ecmd->transceiver = XCVR_INTERNAL; if (netif_carrier_ok(dev)) { ecmd->speed = 1000; ecmd->duplex = DUPLEX_FULL; } else { ecmd->speed = -1; ecmd->duplex = -1; } return 0; } /* *---------------------------------------------------------------------------- * * vmxnet_get_drvinfo -- * * Ethtool callback to return driver information * * Results: * None. * * Side effects: * Updates *drvinfo * *---------------------------------------------------------------------------- */ static void vmxnet_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) { struct Vmxnet_Private *lp = netdev_priv(dev); strncpy(drvinfo->driver, vmxnet_driver.name, sizeof(drvinfo->driver)); drvinfo->driver[sizeof(drvinfo->driver) - 1] = '\0'; strncpy(drvinfo->version, VMXNET_DRIVER_VERSION_STRING, sizeof(drvinfo->version)); drvinfo->driver[sizeof(drvinfo->version) - 1] = '\0'; strncpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); drvinfo->fw_version[sizeof(drvinfo->fw_version) - 1] = '\0'; strncpy(drvinfo->bus_info, pci_name(lp->pdev), ETHTOOL_BUSINFO_LEN); } #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39) /* *---------------------------------------------------------------------------- * * vmxnet_get_tx_csum -- * * Ethtool op to check whether or not hw csum offload is enabled. * * Result: * 1 if csum offload is currently used and 0 otherwise. * * Side-effects: * None * *---------------------------------------------------------------------------- */ static uint32 vmxnet_get_tx_csum(struct net_device *netdev) { return (netdev->features & NETIF_F_HW_CSUM) != 0; } /* *---------------------------------------------------------------------------- * * vmxnet_get_rx_csum -- * * Ethtool op to check whether or not rx csum offload is enabled. * * Result: * Always return 1 to indicate that rx csum is enabled. * * Side-effects: * None * *---------------------------------------------------------------------------- */ static uint32 vmxnet_get_rx_csum(struct net_device *netdev) { return 1; } /* *---------------------------------------------------------------------------- * * vmxnet_set_tx_csum -- * * Ethtool op to change if hw csum offloading should be used or not. * If the device supports hardware checksum capability netdev features bit * is set/reset. This bit is referred to while setting hw checksum required * flag (VMXNET2_TX_HW_XSUM) in xmit ring entry. * * Result: * 0 on success. -EOPNOTSUPP if ethtool asks to set hw checksum and device * does not support it. * * Side-effects: * None * *---------------------------------------------------------------------------- */ static int vmxnet_set_tx_csum(struct net_device *netdev, uint32 val) { if (val) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) struct Vmxnet_Private *lp = netdev_priv(netdev); if (lp->capabilities & (VMNET_CAP_IP4_CSUM | VMNET_CAP_HW_CSUM)) { netdev->features |= NETIF_F_HW_CSUM; return 0; } #endif return -EOPNOTSUPP; } else { netdev->features &= ~NETIF_F_HW_CSUM; } return 0; } /* *---------------------------------------------------------------------------- * * vmxnet_set_rx_csum -- * * Ethtool op to change if hw csum offloading should be used or not for * received packets. Hardware checksum on received packets cannot be turned * off. Hence we fail the ethtool op which turns h/w csum off. * * Result: * 0 when rx csum is set. -EOPNOTSUPP when ethtool tries to reset rx csum. * * Side-effects: * None * *---------------------------------------------------------------------------- */ static int vmxnet_set_rx_csum(struct net_device *netdev, uint32 val) { if (val) { return 0; } else { return -EOPNOTSUPP; } } /* *---------------------------------------------------------------------------- * * vmxnet_set_tso -- * * Ethtool handler to set TSO. If the data is non-zero, TSO is * enabled. Othewrise, it is disabled. * * Results: * 0 if successful, error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ # ifdef VMXNET_DO_TSO static int vmxnet_set_tso(struct net_device *dev, u32 data) { if (data) { struct Vmxnet_Private *lp = netdev_priv(dev); if (!lp->tso) { return -EINVAL; } dev->features |= NETIF_F_TSO; } else { dev->features &= ~NETIF_F_TSO; } return 0; } # endif #endif static struct ethtool_ops vmxnet_ethtool_ops = { .get_settings = vmxnet_get_settings, .get_drvinfo = vmxnet_get_drvinfo, .get_link = ethtool_op_get_link, #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39) .get_rx_csum = vmxnet_get_rx_csum, .set_rx_csum = vmxnet_set_rx_csum, .get_tx_csum = vmxnet_get_tx_csum, .set_tx_csum = vmxnet_set_tx_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, # ifdef VMXNET_DO_TSO .get_tso = ethtool_op_get_tso, .set_tso = vmxnet_set_tso, # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) .get_ufo = ethtool_op_get_ufo, # endif # endif #endif }; #else /* !defined(SET_ETHTOOL_OPS) */ /* *---------------------------------------------------------------------------- * * vmxnet_get_settings -- * * Ethtool handler to get device settings. * * Results: * 0 if successful, error code otherwise. Settings are copied to addr. * * Side effects: * None. * * *---------------------------------------------------------------------------- */ #ifdef ETHTOOL_GSET static int vmxnet_get_settings(struct net_device *dev, void *addr) { struct ethtool_cmd cmd; memset(&cmd, 0, sizeof(cmd)); cmd.speed = 1000; // 1 Gb cmd.duplex = 1; // full-duplex cmd.maxtxpkt = 1; // no tx coalescing cmd.maxrxpkt = 1; // no rx coalescing cmd.autoneg = 0; // no autoneg cmd.advertising = 0; // advertise nothing return copy_to_user(addr, &cmd, sizeof(cmd)); } #endif /* *---------------------------------------------------------------------------- * * vmxnet_get_link -- * * Ethtool handler to get the link state. * * Results: * 0 if successful, error code otherwise. The link status is copied to * addr. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #ifdef ETHTOOL_GLINK static int vmxnet_get_link(struct net_device *dev, void *addr) { compat_ethtool_value value = {ETHTOOL_GLINK}; value.data = netif_carrier_ok(dev) ? 1 : 0; return copy_to_user(addr, &value, sizeof(value)); } #endif /* *---------------------------------------------------------------------------- * * vmxnet_get_tso -- * * Ethtool handler to get the TSO setting. * * Results: * 0 if successful, error code otherwise. The TSO setting is copied to * addr. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #ifdef VMXNET_DO_TSO static int vmxnet_get_tso(struct net_device *dev, void *addr) { compat_ethtool_value value = { ETHTOOL_GTSO }; value.data = (dev->features & NETIF_F_TSO) ? 1 : 0; if (copy_to_user(addr, &value, sizeof(value))) { return -EFAULT; } return 0; } #endif /* *---------------------------------------------------------------------------- * * vmxnet_set_tso -- * * Ethtool handler to set TSO. If the data in addr is non-zero, TSO is * enabled. Othewrise, it is disabled. * * Results: * 0 if successful, error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #ifdef VMXNET_DO_TSO static int vmxnet_set_tso(struct net_device *dev, void *addr) { compat_ethtool_value value; if (copy_from_user(&value, addr, sizeof(value))) { return -EFAULT; } if (value.data) { struct Vmxnet_Private *lp = netdev_priv(dev); if (!lp->tso) { return -EINVAL; } dev->features |= NETIF_F_TSO; } else { dev->features &= ~NETIF_F_TSO; } return 0; } #endif /* *---------------------------------------------------------------------------- * * vmxnet_ethtool_ioctl -- * * Handler for ethtool ioctl calls. * * Results: * If ethtool op is supported, the outcome of the op. Otherwise, * -EOPNOTSUPP. * * Side effects: * * *---------------------------------------------------------------------------- */ #ifdef SIOCETHTOOL static int vmxnet_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr) { uint32_t cmd; if (copy_from_user(&cmd, ifr->ifr_data, sizeof(cmd))) { return -EFAULT; } switch (cmd) { #ifdef ETHTOOL_GSET case ETHTOOL_GSET: return vmxnet_get_settings(dev, ifr->ifr_data); #endif #ifdef ETHTOOL_GLINK case ETHTOOL_GLINK: return vmxnet_get_link(dev, ifr->ifr_data); #endif #ifdef VMXNET_DO_TSO case ETHTOOL_GTSO: return vmxnet_get_tso(dev, ifr->ifr_data); case ETHTOOL_STSO: return vmxnet_set_tso(dev, ifr->ifr_data); #endif default: return -EOPNOTSUPP; } } #endif /* *---------------------------------------------------------------------------- * * vmxnet_ioctl -- * * Handler for ioctl calls. * * Results: * If ioctl is supported, the result of that operation. Otherwise, * -EOPNOTSUPP. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int vmxnet_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { switch (cmd) { #ifdef SIOCETHTOOL case SIOCETHTOOL: return vmxnet_ethtool_ioctl(dev, ifr); #endif } return -EOPNOTSUPP; } #endif /* SET_ETHTOOL_OPS */ /* *----------------------------------------------------------------------------- * * vmxnet_init -- * * Initialization, called by Linux when the module is loaded. * * Results: * Returns 0 for success, negative errno value otherwise. * * Side effects: * See vmxnet_probe_device, which does all the work. * *----------------------------------------------------------------------------- */ static int vmxnet_init(void) { int err; if (vmxnet_debug > 0) { vmxnet_debug = debug; } printk(KERN_INFO "VMware vmxnet virtual NIC driver\n"); err = pci_register_driver(&vmxnet_driver); if (err < 0) { return err; } return 0; } /* *----------------------------------------------------------------------------- * * vmxnet_exit -- * * Cleanup, called by Linux when the module is unloaded. * * Results: * None. * * Side effects: * Unregisters all vmxnet devices with Linux and frees memory. * *----------------------------------------------------------------------------- */ static void vmxnet_exit(void) { pci_unregister_driver(&vmxnet_driver); } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,43) /* *----------------------------------------------------------------------------- * * vmxnet_tx_timeout -- * * Network device tx_timeout routine. Called by Linux when the tx * queue has been stopped for more than dev->watchdog_timeo jiffies. * * Results: * None. * * Side effects: * Tries to restart the transmit queue. * *----------------------------------------------------------------------------- */ static void vmxnet_tx_timeout(struct net_device *dev) { netif_wake_queue(dev); } #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,43) */ /* *----------------------------------------------------------------------------- * * vmxnet_link_check -- * * Propagate device link status to netdev. * * Results: * None. * * Side effects: * Rearms timer for next check. * *----------------------------------------------------------------------------- */ static void vmxnet_link_check(unsigned long data) // IN: netdevice pointer { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,43) struct net_device *dev = (struct net_device *)data; struct Vmxnet_Private *lp = netdev_priv(dev); uint32 status; int ok; status = inl(dev->base_addr + VMXNET_STATUS_ADDR); ok = (status & VMXNET_STATUS_CONNECTED) != 0; if (ok != netif_carrier_ok(dev)) { if (ok) { netif_carrier_on(dev); } else { netif_carrier_off(dev); } } /* * It would be great if vmxnet2 could generate interrupt when link * state changes. Maybe next time. Let's just poll media every * two seconds (2 seconds is same interval pcnet32 uses). */ mod_timer(&lp->linkCheckTimer, jiffies + 2 * HZ); #else /* * Nothing to do on kernels before 2.3.43. They do not have * netif_carrier_*, and as we've lived without link state for * years, let's live without it forever on these kernels. */ #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,43) */ } /* *----------------------------------------------------------------------------- * * vmxnet_morph_device -- * * Morph a lance device into vmxnet device. * * Results: * Returns 0 on success, -1 on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int vmxnet_morph_device(unsigned int morphAddr) // IN { uint16 magic; /* Read morph port to verify that we can morph the adapter. */ magic = inw(morphAddr); if (magic != LANCE_CHIP && magic != VMXNET_CHIP) { printk(KERN_ERR "Invalid magic, read: 0x%08X\n", magic); return -1; } /* Morph adapter. */ outw(VMXNET_CHIP, morphAddr); /* Verify that we morphed correctly. */ magic = inw(morphAddr); if (magic != VMXNET_CHIP) { printk(KERN_ERR "Couldn't morph adapter. Invalid magic, read: 0x%08X\n", magic); goto morph_back; } return 0; morph_back: /* Morph back to LANCE hw. */ outw(LANCE_CHIP, morphAddr); return -1; } /* *----------------------------------------------------------------------------- * * vmxnet_unmorph_device -- * * Morph a vmxnet adapter back to vlance. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void vmxnet_unmorph_device(unsigned int morphAddr) // IN { uint16 magic; /* Read morph port to verify that we can morph the adapter. */ magic = inw(morphAddr); if (magic != VMXNET_CHIP) { printk(KERN_ERR "Adapter not morphed, magic: 0x%08X\n", magic); return; } /* Unmorph adapter. */ outw(LANCE_CHIP, morphAddr); /* Verify that we morphed correctly. */ magic = inw(morphAddr); if (magic != LANCE_CHIP) { printk(KERN_ERR "Couldn't unmorph adapter. Invalid magic, read: 0x%08X\n", magic); } } /* *----------------------------------------------------------------------------- * * vmxnet_probe_device -- * * Most of the initialization at module load time is done here. * * Results: * Returns 0 for success, an error otherwise. * * Side effects: * Switches device from vlance to vmxnet mode, creates ethernet * structure for device, and registers device with network stack. * *----------------------------------------------------------------------------- */ static int vmxnet_probe_device(struct pci_dev *pdev, // IN: vmxnet PCI device const struct pci_device_id *id) // IN: matching device ID { #ifdef HAVE_NET_DEVICE_OPS static const struct net_device_ops vmxnet_netdev_ops = { .ndo_open = &vmxnet_open, .ndo_start_xmit = &vmxnet_start_tx, .ndo_stop = &vmxnet_close, .ndo_get_stats = &vmxnet_get_stats, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) .ndo_set_features = vmxnet_set_features, #endif #if COMPAT_LINUX_VERSION_CHECK_LT(3, 2, 0) .ndo_set_multicast_list = &vmxnet_set_multicast_list, #else .ndo_set_rx_mode = &vmxnet_set_multicast_list, #endif .ndo_change_mtu = &vmxnet_change_mtu, # ifdef VMW_HAVE_POLL_CONTROLLER .ndo_poll_controller = vmxnet_netpoll, # endif .ndo_set_mac_address = &vmxnet_set_mac_address, .ndo_tx_timeout = &vmxnet_tx_timeout, }; #endif /* HAVE_NET_DEVICE_OPS */ struct Vmxnet_Private *lp; struct net_device *dev; unsigned int ioaddr, reqIOAddr, reqIOSize; unsigned int irq_line; Bool morphed = FALSE; int i; i = pci_enable_device(pdev); if (i) { printk(KERN_ERR "Cannot enable vmxnet adapter %s: error %d\n", pci_name(pdev), i); return i; } pci_set_master(pdev); irq_line = pdev->irq; ioaddr = pci_resource_start(pdev, 0); reqIOAddr = ioaddr; /* Found adapter, adjust ioaddr to match the adapter we found. */ if (id->driver_data == VMXNET_CHIP) { reqIOSize = VMXNET_CHIP_IO_RESV_SIZE; } else { /* * Since this is a vlance adapter we can only use it if * its I/0 space is big enough for the adapter to be * capable of morphing. This is the first requirement * for this adapter to potentially be morphable. The * layout of a morphable LANCE adapter is * * I/O space: * * |------------------| * | LANCE IO PORTS | * |------------------| * | MORPH PORT | * |------------------| * | VMXNET IO PORTS | * |------------------| * * VLance has 8 ports of size 4 bytes, the morph port is 4 bytes, and * Vmxnet has 10 ports of size 4 bytes. * * We shift up the ioaddr with the size of the LANCE I/O space since * we want to access the vmxnet ports. We also shift the ioaddr up by * the MORPH_PORT_SIZE so other port access can be independent of * whether we are Vmxnet or a morphed VLance. This means that when * we want to access the MORPH port we need to subtract the size * from ioaddr to get to it. */ ioaddr += LANCE_CHIP_IO_RESV_SIZE + MORPH_PORT_SIZE; reqIOSize = LANCE_CHIP_IO_RESV_SIZE + MORPH_PORT_SIZE + VMXNET_CHIP_IO_RESV_SIZE; } /* Do not attempt to morph non-morphable AMD PCnet */ if (reqIOSize > pci_resource_len(pdev, 0)) { printk(KERN_INFO "vmxnet: Device in slot %s is not supported by this driver.\n", pci_name(pdev)); goto pci_disable; } /* * Request I/O region with adjusted base address and size. The adjusted * values are needed and used if we release the region in case of failure. */ if (!compat_request_region(reqIOAddr, reqIOSize, VMXNET_CHIP_NAME)) { printk(KERN_INFO "vmxnet: Another driver already loaded for device in slot %s.\n", pci_name(pdev)); goto pci_disable; } /* Morph the underlying hardware if we found a VLance adapter. */ if (id->driver_data == LANCE_CHIP) { if (vmxnet_morph_device(ioaddr - MORPH_PORT_SIZE) == 0) { morphed = TRUE; } else { goto release_reg; } } printk(KERN_INFO "Found vmxnet/PCI at %#x, irq %u.\n", ioaddr, irq_line); if (!vmxnet_check_version(ioaddr)) { goto morph_back; } dev = alloc_etherdev(sizeof *lp); if (!dev) { printk(KERN_ERR "Unable to allocate ethernet device\n"); goto morph_back; } lp = netdev_priv(dev); lp->pdev = pdev; dev->base_addr = ioaddr; if (!vmxnet_probe_features(dev, morphed, FALSE)) { goto free_dev; } dev->irq = irq_line; #ifdef HAVE_NET_DEVICE_OPS dev->netdev_ops = &vmxnet_netdev_ops; #else dev->open = &vmxnet_open; dev->hard_start_xmit = &vmxnet_start_tx; dev->stop = &vmxnet_close; dev->get_stats = &vmxnet_get_stats; dev->set_multicast_list = &vmxnet_set_multicast_list; #ifdef HAVE_CHANGE_MTU dev->change_mtu = &vmxnet_change_mtu; #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,43) dev->tx_timeout = &vmxnet_tx_timeout; #endif #ifdef VMW_HAVE_POLL_CONTROLLER dev->poll_controller = vmxnet_netpoll; #endif /* Do this after ether_setup(), which sets the default value. */ dev->set_mac_address = &vmxnet_set_mac_address; #endif /* HAVE_NET_DEVICE_OPS */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,43) dev->watchdog_timeo = VMXNET_WATCHDOG_TIMEOUT; #endif #ifdef SET_ETHTOOL_OPS SET_ETHTOOL_OPS(dev, &vmxnet_ethtool_ops); #else dev->do_ioctl = vmxnet_ioctl; #endif COMPAT_SET_MODULE_OWNER(dev); COMPAT_SET_NETDEV_DEV(dev, &pdev->dev); if (register_netdev(dev)) { printk(KERN_ERR "Unable to register device\n"); goto free_dev_dd; } /* * Use deferrable timer - we want 2s interval, but if it will * be 2 seconds or 10 seconds, we do not care. */ compat_init_timer_deferrable(&lp->linkCheckTimer); lp->linkCheckTimer.data = (unsigned long)dev; lp->linkCheckTimer.function = vmxnet_link_check; vmxnet_link_check(lp->linkCheckTimer.data); /* Do this after register_netdev(), which sets device name */ VMXNET_LOG("%s: %s at %#3lx assigned IRQ %d.\n", dev->name, lp->name, dev->base_addr, dev->irq); pci_set_drvdata(pdev, dev); #ifdef CONFIG_PM /* * Initialize pci_dev's current_state for .suspend to work properly. */ VMXNET_SET_POWER_STATE_D0(pdev); #endif return 0; free_dev_dd: vmxnet_release_private_data(lp, pdev); free_dev: free_netdev(dev); morph_back: if (morphed) { vmxnet_unmorph_device(ioaddr - MORPH_PORT_SIZE); } release_reg: release_region(reqIOAddr, reqIOSize); pci_disable: pci_disable_device(pdev); return -EBUSY; } /* *----------------------------------------------------------------------------- * * vmxnet_check_version -- * * Helper to check version of the device backend to see if it is * compatible with the driver. Called from .probe or .resume. * * Results: * TRUE/FALSE on success/failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool vmxnet_check_version(unsigned int ioaddr) // IN: { /* VMware's version of the magic number */ unsigned int low_vmware_version; low_vmware_version = inl(ioaddr + VMXNET_LOW_VERSION); if ((low_vmware_version & 0xffff0000) != (VMXNET2_MAGIC & 0xffff0000)) { printk(KERN_ERR "Driver version 0x%08X doesn't match version 0x%08X\n", VMXNET2_MAGIC, low_vmware_version); return FALSE; } else { /* * The low version looked OK so get the high version and make sure that * our version is supported. */ unsigned int high_vmware_version = inl(ioaddr + VMXNET_HIGH_VERSION); if ((VMXNET2_MAGIC < low_vmware_version) || (VMXNET2_MAGIC > high_vmware_version)) { printk(KERN_ERR "Driver version 0x%08X doesn't match version 0x%08X, 0x%08X\n", VMXNET2_MAGIC, low_vmware_version, high_vmware_version); return FALSE; } } return TRUE; } /* *----------------------------------------------------------------------------- * * vmxnet_probe_features -- * * Helper to probe device features and capabilities and initialize various * driver state. Called from the .probe and .resume handlers. During * .resume phase this function validates that compatible * feature/capabilities (or other state) is obtained from the device as * during the .probe phase prior to guest suspend or hibernate. * * Results: * Boolean indicating success/failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool vmxnet_probe_features(struct net_device *dev, // IN: Bool morphed, // IN: Bool probeFromResume) // IN: { struct Vmxnet_Private *lp = netdev_priv(dev); unsigned int numRxBuffers, numRxBuffers2, maxNumRxBuffers, defNumRxBuffers; unsigned int numTxBuffers, maxNumTxBuffers, defNumTxBuffers; Bool enhanced = FALSE; int i; unsigned int ioaddr = dev->base_addr; VMXNET_ASSERT(lp); outl(VMXNET_CMD_GET_FEATURES, dev->base_addr + VMXNET_COMMAND_ADDR); if (probeFromResume) { if ((lp->features & inl(dev->base_addr + VMXNET_COMMAND_ADDR)) != lp->features) { return FALSE; } } else { lp->features = inl(dev->base_addr + VMXNET_COMMAND_ADDR); } outl(VMXNET_CMD_GET_CAPABILITIES, dev->base_addr + VMXNET_COMMAND_ADDR); if (probeFromResume) { if ((lp->capabilities & inl(dev->base_addr + VMXNET_COMMAND_ADDR)) != lp->capabilities) { return FALSE; } } else { lp->capabilities = inl(dev->base_addr + VMXNET_COMMAND_ADDR); } /* determine the features supported */ lp->zeroCopyTx = FALSE; lp->partialHeaderCopyEnabled = FALSE; lp->tso = FALSE; lp->chainTx = FALSE; lp->chainRx = FALSE; lp->jumboFrame = FALSE; lp->lpd = FALSE; printk(KERN_INFO "features:"); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) if (lp->capabilities & VMNET_CAP_IP4_CSUM) { dev->features |= NETIF_F_HW_CSUM; printk(" ipCsum"); } if (lp->capabilities & VMNET_CAP_HW_CSUM) { dev->features |= NETIF_F_HW_CSUM; printk(" hwCsum"); } #endif #ifdef VMXNET_DO_ZERO_COPY if (lp->capabilities & VMNET_CAP_SG && lp->features & VMXNET_FEATURE_ZERO_COPY_TX){ dev->features |= NETIF_F_SG; lp->zeroCopyTx = TRUE; printk(" zeroCopy"); if (lp->capabilities & VMNET_CAP_ENABLE_HEADER_COPY) { lp->partialHeaderCopyEnabled = TRUE; printk(" partialHeaderCopy"); } if (lp->capabilities & VMNET_CAP_TX_CHAIN) { lp->chainTx = TRUE; } if (lp->capabilities & VMNET_CAP_RX_CHAIN) { lp->chainRx = TRUE; } if (lp->chainRx && lp->chainTx && (lp->features & VMXNET_FEATURE_JUMBO_FRAME)) { lp->jumboFrame = TRUE; printk(" jumboFrame"); } } #ifdef VMXNET_DO_TSO if ((lp->capabilities & VMNET_CAP_TSO) && (lp->capabilities & (VMNET_CAP_IP4_CSUM | VMNET_CAP_HW_CSUM)) && // tso only makes sense if we have hw csum offload lp->chainTx && lp->zeroCopyTx && lp->features & VMXNET_FEATURE_TSO) { dev->features |= NETIF_F_TSO; lp->tso = TRUE; printk(" tso"); } if ((lp->capabilities & VMNET_CAP_LPD) && (lp->features & VMXNET_FEATURE_LPD) && !disable_lro) { lp->lpd = TRUE; printk(" lpd"); } #endif #endif printk("\n"); /* check if this is enhanced vmxnet device */ if ((lp->features & VMXNET_FEATURE_TSO) && (lp->features & VMXNET_FEATURE_JUMBO_FRAME)) { enhanced = TRUE; } /* determine rx/tx ring sizes */ if (enhanced) { maxNumRxBuffers = ENHANCED_VMXNET2_MAX_NUM_RX_BUFFERS; defNumRxBuffers = ENHANCED_VMXNET2_DEFAULT_NUM_RX_BUFFERS; } else { maxNumRxBuffers = VMXNET2_MAX_NUM_RX_BUFFERS; defNumRxBuffers = VMXNET2_DEFAULT_NUM_RX_BUFFERS; } outl(VMXNET_CMD_GET_NUM_RX_BUFFERS, dev->base_addr + VMXNET_COMMAND_ADDR); numRxBuffers = inl(dev->base_addr + VMXNET_COMMAND_ADDR); if (numRxBuffers == 0 || numRxBuffers > maxNumRxBuffers) { numRxBuffers = defNumRxBuffers; } if (lp->jumboFrame || lp->lpd) { numRxBuffers2 = numRxBuffers * 4; if (numRxBuffers2 > VMXNET2_MAX_NUM_RX_BUFFERS2) { numRxBuffers2 = VMXNET2_MAX_NUM_RX_BUFFERS2; } } else { numRxBuffers2 = 1; } printk(KERN_INFO "numRxBuffers = %d, numRxBuffers2 = %d\n", numRxBuffers, numRxBuffers2); if (lp->tso || lp->jumboFrame) { maxNumTxBuffers = VMXNET2_MAX_NUM_TX_BUFFERS_TSO; defNumTxBuffers = VMXNET2_DEFAULT_NUM_TX_BUFFERS_TSO; } else { maxNumTxBuffers = VMXNET2_MAX_NUM_TX_BUFFERS; defNumTxBuffers = VMXNET2_DEFAULT_NUM_TX_BUFFERS; } outl(VMXNET_CMD_GET_NUM_TX_BUFFERS, dev->base_addr + VMXNET_COMMAND_ADDR); numTxBuffers = inl(dev->base_addr + VMXNET_COMMAND_ADDR); if (numTxBuffers == 0 || numTxBuffers > maxNumTxBuffers) { numTxBuffers = defNumTxBuffers; } lp->ddSize = sizeof(Vmxnet2_DriverData) + (numRxBuffers + numRxBuffers2) * sizeof(Vmxnet2_RxRingEntry) + numTxBuffers * sizeof(Vmxnet2_TxRingEntry); VMXNET_LOG("vmxnet: numRxBuffers=((%d+%d)*%d) numTxBuffers=(%d*%d) ddSize=%d\n", numRxBuffers, numRxBuffers2, (uint32)sizeof(Vmxnet2_RxRingEntry), numTxBuffers, (uint32)sizeof(Vmxnet2_TxRingEntry), (int)lp->ddSize); if (!vmxnet_alloc_shared_mem(lp->pdev, lp->ddSize, (void **)&lp->dd, &lp->ddPA)) { printk(KERN_ERR "Unable to allocate memory for driver data\n"); return FALSE; } memset(lp->dd, 0, lp->ddSize); spin_lock_init(&lp->txLock); lp->numRxBuffers = numRxBuffers; lp->numRxBuffers2 = numRxBuffers2; lp->numTxBuffers = numTxBuffers; /* So that the vmkernel can check it is compatible */ lp->dd->magic = VMXNET2_MAGIC; lp->dd->length = lp->ddSize; lp->name = VMXNET_CHIP_NAME; /* * Store whether we are morphed so we can figure out how to * clean up when we unload. */ lp->morphed = morphed; if (lp->capabilities & VMNET_CAP_VMXNET_APROM) { for (i = 0; i < ETH_ALEN; i++) { dev->dev_addr[i] = inb(ioaddr + VMXNET_APROM_ADDR + i); } for (i = 0; i < ETH_ALEN; i++) { outb(dev->dev_addr[i], ioaddr + VMXNET_MAC_ADDR + i); } } else { /* * Be backwards compatible and use the MAC address register to * get MAC address. */ for (i = 0; i < ETH_ALEN; i++) { dev->dev_addr[i] = inb(ioaddr + VMXNET_MAC_ADDR + i); } } #ifdef VMXNET_DO_ZERO_COPY lp->txBufferStart = NULL; lp->dd->txBufferPhysStart = 0; lp->dd->txBufferPhysLength = 0; if (lp->partialHeaderCopyEnabled) { lp->txBufferSize = numTxBuffers * TX_PKT_HEADER_SIZE; if (vmxnet_alloc_shared_mem(lp->pdev, lp->txBufferSize, (void **)&lp->txBufferStart, &lp->txBufferPA)) { lp->dd->txBufferPhysStart = (uint32)lp->txBufferPA; lp->dd->txBufferPhysLength = (uint32)lp->txBufferSize; lp->dd->txPktMaxSize = TX_PKT_HEADER_SIZE; } else { lp->partialHeaderCopyEnabled = FALSE; printk(KERN_INFO "failed to allocate tx buffer, disable partialHeaderCopy\n"); } } #endif return TRUE; } /* *----------------------------------------------------------------------------- * * vmxnet_alloc_shared_mem -- * * Attempts to allocate dma-able memory that uses a 32-bit PA. * * Results: * TRUE on success, otherwise FALSE. * * Side effects: * None. * *----------------------------------------------------------------------------- */ #define FITS_IN_32_BITS(_x) ((_x) == ((_x) & 0xFFFFFFFF)) static Bool vmxnet_alloc_shared_mem(struct pci_dev *pdev, // IN: size_t size, // IN: void **vaOut, // OUT: dma_addr_t *paOut) // OUT: { void *va = NULL; dma_addr_t pa = 0; /* DMA-mapping.txt says 32-bit DMA by default */ va = compat_pci_alloc_consistent(pdev, size, &pa); if (!va) { *vaOut = NULL; *paOut = 0; return FALSE; } VMXNET_ASSERT(FITS_IN_32_BITS(pa) && FITS_IN_32_BITS((uint64)pa + (size - 1))); *vaOut = va; *paOut = pa; return TRUE; } /* *----------------------------------------------------------------------------- * * vmxnet_remove_device -- * * Cleanup, called for each device on unload. * * Results: * None. * * Side effects: * Unregisters vmxnet device with Linux and frees memory. * *----------------------------------------------------------------------------- */ static void vmxnet_remove_device(struct pci_dev* pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct Vmxnet_Private *lp = netdev_priv(dev); /* * Do this before device is gone so we never call netif_carrier_* after * unregistering netdevice. */ compat_del_timer_sync(&lp->linkCheckTimer); unregister_netdev(dev); /* Unmorph adapter if it was morphed. */ if (lp->morphed) { vmxnet_unmorph_device(dev->base_addr - MORPH_PORT_SIZE); release_region(dev->base_addr - (LANCE_CHIP_IO_RESV_SIZE + MORPH_PORT_SIZE), VMXNET_CHIP_IO_RESV_SIZE + (LANCE_CHIP_IO_RESV_SIZE + MORPH_PORT_SIZE)); } else { release_region(dev->base_addr, VMXNET_CHIP_IO_RESV_SIZE); } vmxnet_release_private_data(lp, pdev); free_netdev(dev); pci_disable_device(pdev); } /* *----------------------------------------------------------------------------- * * vmxnet_release_private_data -- * * Helper to release/free some private driver data. Called from the * .remove handler and the .suspend handler. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void vmxnet_release_private_data(Vmxnet_Private *lp, // IN: struct pci_dev *pdev) // IN: { #ifdef VMXNET_DO_ZERO_COPY if (lp->partialHeaderCopyEnabled && lp->txBufferStart) { compat_pci_free_consistent(pdev, lp->txBufferSize, lp->txBufferStart, lp->txBufferPA); lp->txBufferStart = NULL; } #endif if (lp->dd) { compat_pci_free_consistent(pdev, lp->ddSize, lp->dd, lp->ddPA); lp->dd = NULL; } } #ifdef CONFIG_PM /* *----------------------------------------------------------------------------- * * vmxnet_suspend_device -- * * Suspend PM handler. * * Results: * Returns 0 for success. * * Side effects: * Morphs device back to lance mode. * *----------------------------------------------------------------------------- */ VMXNET_SUSPEND_DEVICE(/* struct pci_dev * */ pdev, // IN: pci device /* pm_message_t */ state) // IN: state { /* * Suspend needs to: * 1. Disable IRQ. * 2. Morph back to vlance. * 3. Disable bus-mastering. * 4. Put device to low power state. * 5. Enable wake up. * * TODO: implement 5. */ struct net_device *dev = pci_get_drvdata(pdev); struct Vmxnet_Private *lp = netdev_priv(dev); if (lp->devOpen) { /* * Close the device first (and unmap rings, frees skbs, etc) * since morphing will reset the device. However, still * keep the device marked as "opened" so we can reopen it at * resume time. */ vmxnet_close(dev); lp->devOpen = TRUE; } if (lp->morphed) { /* Morph back to vlance. */ vmxnet_unmorph_device(dev->base_addr - MORPH_PORT_SIZE); } pci_disable_device(pdev); /* Disables bus-mastering. */ vmxnet_release_private_data(lp, pdev); VMXNET_SET_POWER_STATE(pdev, state); VMXNET_PM_RETURN(0); } /* *----------------------------------------------------------------------------- * * vmxnet_resume_device -- * * Resume PM handler. * TODO: check capability of the device on resume. * * Results: * Returns 0 for success, an error otherwise. * * Side effects: * Morphs device to vxmnet mode. * *----------------------------------------------------------------------------- */ VMXNET_RESUME_DEVICE(/* struct pci_dev* */ pdev) // IN: pci device { struct net_device *dev = pci_get_drvdata(pdev); struct Vmxnet_Private *lp = netdev_priv(dev); int ret; ret = pci_enable_device(pdev); /* Does not enable bus-mastering. */ if (ret) { printk(KERN_ERR "Cannot resume vmxnet adapter %s: error %d\n", pci_name(pdev), ret); VMXNET_PM_RETURN(ret); } pci_set_master(pdev); if (lp->morphed) { if (vmxnet_morph_device(dev->base_addr - MORPH_PORT_SIZE) != 0) { ret = -ENODEV; goto disable_pci; } } if (!vmxnet_check_version(dev->base_addr) || !vmxnet_probe_features(dev, lp->morphed, TRUE)) { ret = -ENODEV; goto disable_pci; } if (lp->devOpen) { /* * The adapter was closed at suspend time. So mark it as closed, then * try to reopen it. */ lp->devOpen = FALSE; ret = vmxnet_open(dev); if (ret) { /* * We do not unmorph the device here since that would be handled in * the .remove handler. */ printk(KERN_ERR "Could not open vmxnet adapter %s: error %d\n", pci_name(pdev), ret); goto disable_pci; } } VMXNET_SET_POWER_STATE_D0(pdev); VMXNET_PM_RETURN(0); disable_pci: pci_disable_device(pdev); /* Disables bus-mastering. */ VMXNET_PM_RETURN(ret); } #endif /* *----------------------------------------------------------------------------- * * vmxnet_init_ring -- * * Initializes buffer rings in Vmxnet_Private structure. Allocates skbs * to receive into. Called by vmxnet_open. * * Results: * 0 on success; -1 on failure to allocate skbs. * * Side effects: * *----------------------------------------------------------------------------- */ static int vmxnet_init_ring(struct net_device *dev) { struct Vmxnet_Private *lp = netdev_priv(dev); Vmxnet2_DriverData *dd = lp->dd; unsigned int i; size_t offset; offset = sizeof(*dd); dd->rxRingLength = lp->numRxBuffers; dd->rxRingOffset = offset; lp->rxRing = (Vmxnet2_RxRingEntry *)((uintptr_t)dd + offset); offset += lp->numRxBuffers * sizeof(Vmxnet2_RxRingEntry); dd->rxRingLength2 = lp->numRxBuffers2; dd->rxRingOffset2 = offset; lp->rxRing2 = (Vmxnet2_RxRingEntry *)((uintptr_t)dd + offset); offset += lp->numRxBuffers2 * sizeof(Vmxnet2_RxRingEntry); dd->txRingLength = lp->numTxBuffers; dd->txRingOffset = offset; lp->txRing = (Vmxnet2_TxRingEntry *)((uintptr_t)dd + offset); offset += lp->numTxBuffers * sizeof(Vmxnet2_TxRingEntry); VMXNET_LOG("vmxnet_init_ring: offset=%"FMT64"d length=%d\n", (uint64)offset, dd->length); for (i = 0; i < lp->numRxBuffers; i++) { lp->rxSkbuff[i] = dev_alloc_skb(PKT_BUF_SZ + COMPAT_NET_IP_ALIGN); if (lp->rxSkbuff[i] == NULL) { unsigned int j; printk (KERN_ERR "%s: vmxnet_init_ring dev_alloc_skb failed.\n", dev->name); for (j = 0; j < i; j++) { compat_dev_kfree_skb(lp->rxSkbuff[j], FREE_WRITE); lp->rxSkbuff[j] = NULL; } return -ENOMEM; } skb_reserve(lp->rxSkbuff[i], COMPAT_NET_IP_ALIGN); lp->rxRing[i].paddr = compat_pci_map_single(lp->pdev, lp->rxSkbuff[i]->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); lp->rxRing[i].bufferLength = PKT_BUF_SZ; lp->rxRing[i].actualLength = 0; lp->rxRing[i].ownership = VMXNET2_OWNERSHIP_NIC; } #ifdef VMXNET_DO_ZERO_COPY if (lp->jumboFrame || lp->lpd) { struct pci_dev *pdev = lp->pdev; dd->maxFrags = MAX_SKB_FRAGS; for (i = 0; i < lp->numRxBuffers2; i++) { lp->rxPages[i] = alloc_page(GFP_KERNEL); if (lp->rxPages[i] == NULL) { unsigned int j; printk (KERN_ERR "%s: vmxnet_init_ring alloc_page failed.\n", dev->name); for (j = 0; j < i; j++) { put_page(lp->rxPages[j]); lp->rxPages[j] = NULL; } for (j = 0; j < lp->numRxBuffers; j++) { compat_dev_kfree_skb(lp->rxSkbuff[j], FREE_WRITE); lp->rxSkbuff[j] = NULL; } return -ENOMEM; } lp->rxRing2[i].paddr = pci_map_page(pdev, lp->rxPages[i], 0, PAGE_SIZE, PCI_DMA_FROMDEVICE); lp->rxRing2[i].bufferLength = PAGE_SIZE; lp->rxRing2[i].actualLength = 0; lp->rxRing2[i].ownership = VMXNET2_OWNERSHIP_NIC_FRAG; } } else #endif { // dummy rxRing2 tacked on to the end, with a single unusable entry lp->rxRing2[0].paddr = 0; lp->rxRing2[0].bufferLength = 0; lp->rxRing2[0].actualLength = 0; lp->rxRing2[0].ownership = VMXNET2_OWNERSHIP_DRIVER; } dd->rxDriverNext = 0; dd->rxDriverNext2 = 0; for (i = 0; i < lp->numTxBuffers; i++) { lp->txRing[i].ownership = VMXNET2_OWNERSHIP_DRIVER; lp->txBufInfo[i].skb = NULL; lp->txBufInfo[i].eop = 0; lp->txRing[i].sg.sg[0].addrHi = 0; lp->txRing[i].sg.addrType = NET_SG_PHYS_ADDR; } dd->txDriverCur = dd->txDriverNext = 0; dd->savedRxNICNext = dd->savedRxNICNext2 = dd->savedTxNICNext = 0; dd->txStopped = FALSE; if (lp->lpd) { dd->featureCtl |= VMXNET_FEATURE_LPD; } return 0; } /* *----------------------------------------------------------------------------- * * vmxnet_open -- * * Network device open routine. Called by Linux when the interface is * brought up. * * Results: * 0 on success; else negative errno value. * * Side effects: * Allocates an IRQ if not already allocated. Sets our Vmxnet_Private * structure to be the shared area with the lower layer. * *----------------------------------------------------------------------------- */ static int vmxnet_open(struct net_device *dev) { struct Vmxnet_Private *lp = netdev_priv(dev); unsigned int ioaddr = dev->base_addr; uint32 ddPA; /* * The .suspend handler frees driver data, so we need this check. */ if (UNLIKELY(!lp->dd)) { return -ENOMEM; } if (dev->irq == 0 || request_irq(dev->irq, &vmxnet_interrupt, COMPAT_IRQF_SHARED, dev->name, (void *)dev)) { return -EAGAIN; } if (vmxnet_debug > 1) { printk(KERN_DEBUG "%s: vmxnet_open() irq %d lp %p.\n", dev->name, dev->irq, lp); } if (vmxnet_init_ring(dev)) { return -ENOMEM; } ddPA = VMXNET_GET_LO_ADDR(lp->ddPA); outl(ddPA, ioaddr + VMXNET_INIT_ADDR); outl(lp->dd->length, ioaddr + VMXNET_INIT_LENGTH); #ifdef VMXNET_DO_ZERO_COPY if (lp->partialHeaderCopyEnabled) { outl(VMXNET_CMD_PIN_TX_BUFFERS, ioaddr + VMXNET_COMMAND_ADDR); } // Pin the Tx buffers if partial header copy is enabled #endif lp->dd->txStopped = FALSE; netif_start_queue(dev); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) dev->interrupt = 0; dev->start = 1; #endif lp->devOpen = TRUE; COMPAT_NETDEV_MOD_INC_USE_COUNT; return 0; } #ifdef VMXNET_DO_ZERO_COPY /* *----------------------------------------------------------------------------- * * vmxnet_unmap_buf -- * * Unmap the PAs of the tx entry that we pinned for DMA. * * Results: * None. * * Side effects: * None *----------------------------------------------------------------------------- */ void vmxnet_unmap_buf(struct sk_buff *skb, struct Vmxnet2_TxBuf *tb, Vmxnet2_TxRingEntry *xre, struct pci_dev *pdev) { int sgIdx; // unmap the mapping for skb->data if needed if (tb->sgForLinear >= 0) { pci_unmap_single(pdev, VMXNET_GET_DMA_ADDR(xre->sg.sg[(int)tb->sgForLinear]), xre->sg.sg[(int)tb->sgForLinear].length, PCI_DMA_TODEVICE); VMXNET_LOG("vmxnet_unmap_buf: sg[%d] (%uB)\n", (int)tb->sgForLinear, xre->sg.sg[(int)tb->sgForLinear].length); } // unmap the mapping for skb->frags[] for (sgIdx = tb->firstSgForFrag; sgIdx < xre->sg.length; sgIdx++) { pci_unmap_page(pdev, VMXNET_GET_DMA_ADDR(xre->sg.sg[sgIdx]), xre->sg.sg[sgIdx].length, PCI_DMA_TODEVICE); VMXNET_LOG("vmxnet_unmap_buf: sg[%d] (%uB)\n", sgIdx, xre->sg.sg[sgIdx].length); } } /* *----------------------------------------------------------------------------- * * vmxnet_map_pkt -- * * Map the buffers/pages that we need for DMA and populate the SG. * * "offset" indicates the position inside the pkt where mapping should start. * "startSgIdx" indicates the first free sg slot of the first tx entry * (pointed to by txDriverNext). * * The caller should guarantee the first tx has at least one sg slot * available. The caller should also ensure that enough tx entries are * available for this pkt. * * Results: * None. * * Side effects: * 1. Ownership of all tx entries used (EXCEPT the 1st one) are updated. * The only flag set is VMXNET2_TX_MORE if needed. caller is * responsible to set up other flags after this call returns. * 2. lp->dd->numTxPending is updated * 3. txBufInfo corresponding to used tx entries (including the 1st one) * are updated * 4. txDriverNext is advanced accordingly * *----------------------------------------------------------------------------- */ void vmxnet_map_pkt(struct sk_buff *skb, int offset, struct Vmxnet_Private *lp, int startSgIdx) { int nextFrag = 0, nextSg = startSgIdx; struct skb_frag_struct *frag; Vmxnet2_DriverData *dd = lp->dd; Vmxnet2_TxRingEntry *xre; struct Vmxnet2_TxBuf *tb; dma_addr_t dma; VMXNET_ASSERT(startSgIdx < VMXNET2_SG_DEFAULT_LENGTH); lp->numTxPending++; tb = &lp->txBufInfo[dd->txDriverNext]; xre = &lp->txRing[dd->txDriverNext]; if (offset == skb_headlen(skb)) { tb->sgForLinear = -1; tb->firstSgForFrag = nextSg; } else if (offset < skb_headlen(skb)) { /* we need to map some of the non-frag data. */ dma = pci_map_single(lp->pdev, skb->data + offset, skb_headlen(skb) - offset, PCI_DMA_TODEVICE); VMXNET_FILL_SG(xre->sg.sg[nextSg], dma, skb_headlen(skb) - offset); VMXNET_LOG("vmxnet_map_pkt: txRing[%u].sg[%d] -> data %p offset %u size %u\n", dd->txDriverNext, nextSg, skb->data, offset, skb_headlen(skb) - offset); tb->sgForLinear = nextSg++; tb->firstSgForFrag = nextSg; } else { // all non-frag data is copied, skip it tb->sgForLinear = -1; tb->firstSgForFrag = nextSg; offset -= skb_headlen(skb); for ( ; nextFrag < skb_shinfo(skb)->nr_frags; nextFrag++){ int fragSize; frag = &skb_shinfo(skb)->frags[nextFrag]; #if COMPAT_LINUX_VERSION_CHECK_LT(3, 2, 0) fragSize = frag->size; #else fragSize = skb_frag_size(frag); #endif // skip those frags that are completely copied if (offset >= fragSize){ offset -= fragSize; } else { // map the part of the frag that is not copied dma = pci_map_page(lp->pdev, #if COMPAT_LINUX_VERSION_CHECK_LT(3, 2, 0) frag->page, #else frag->page.p, #endif frag->page_offset + offset, fragSize - offset, PCI_DMA_TODEVICE); VMXNET_FILL_SG(xre->sg.sg[nextSg], dma, fragSize - offset); VMXNET_LOG("vmxnet_map_tx: txRing[%u].sg[%d] -> frag[%d]+%u (%uB)\n", dd->txDriverNext, nextSg, nextFrag, offset, fragSize - offset); nextSg++; nextFrag++; break; } } } // map the remaining frags, we might need to use additional tx entries for ( ; nextFrag < skb_shinfo(skb)->nr_frags; nextFrag++) { int fragSize; frag = &skb_shinfo(skb)->frags[nextFrag]; #if COMPAT_LINUX_VERSION_CHECK_LT(3, 2, 0) fragSize = frag->size; #else fragSize = skb_frag_size(frag); #endif dma = pci_map_page(lp->pdev, #if COMPAT_LINUX_VERSION_CHECK_LT(3, 2, 0) frag->page, #else frag->page.p, #endif frag->page_offset, fragSize, PCI_DMA_TODEVICE); if (nextSg == VMXNET2_SG_DEFAULT_LENGTH) { xre->flags = VMXNET2_TX_MORE; xre->sg.length = VMXNET2_SG_DEFAULT_LENGTH; tb->skb = skb; tb->eop = 0; // move to the next tx entry VMXNET_INC(dd->txDriverNext, dd->txRingLength); xre = &lp->txRing[dd->txDriverNext]; tb = &lp->txBufInfo[dd->txDriverNext]; // the new tx entry must be available VMXNET_ASSERT(xre->ownership == VMXNET2_OWNERSHIP_DRIVER && tb->skb == NULL); /* * we change it even before the sg are populated but this is * fine, because the first tx entry's ownership is not * changed yet */ xre->ownership = VMXNET2_OWNERSHIP_NIC; tb->sgForLinear = -1; tb->firstSgForFrag = 0; lp->numTxPending ++; nextSg = 0; } VMXNET_FILL_SG(xre->sg.sg[nextSg], dma, fragSize); VMXNET_LOG("vmxnet_map_tx: txRing[%u].sg[%d] -> frag[%d] (%uB)\n", dd->txDriverNext, nextSg, nextFrag, fragSize); nextSg++; } // setup the last tx entry xre->flags = 0; xre->sg.length = nextSg; tb->skb = skb; tb->eop = 1; VMXNET_ASSERT(nextSg <= VMXNET2_SG_DEFAULT_LENGTH); VMXNET_INC(dd->txDriverNext, dd->txRingLength); } #endif /* *----------------------------------------------------------------------------- * * check_tx_queue -- * * Loop through the tx ring looking for completed transmits. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void check_tx_queue(struct net_device *dev) { struct Vmxnet_Private *lp = netdev_priv(dev); Vmxnet2_DriverData *dd = lp->dd; int completed = 0; /* * The .suspend handler frees driver data, so we need this check. */ while (dd) { Vmxnet2_TxRingEntry *xre = &lp->txRing[dd->txDriverCur]; struct sk_buff *skb = lp->txBufInfo[dd->txDriverCur].skb; if (xre->ownership != VMXNET2_OWNERSHIP_DRIVER || skb == NULL) { break; } #ifdef VMXNET_DO_ZERO_COPY if (lp->zeroCopyTx) { VMXNET_LOG("unmap txRing[%u]\n", dd->txDriverCur); vmxnet_unmap_buf(skb, &lp->txBufInfo[dd->txDriverCur], xre, lp->pdev); } else #endif { compat_pci_unmap_single(lp->pdev, xre->sg.sg[0].addrLow, xre->sg.sg[0].length, PCI_DMA_TODEVICE); } if (lp->txBufInfo[dd->txDriverCur].eop) { compat_dev_kfree_skb_irq(skb, FREE_WRITE); } lp->txBufInfo[dd->txDriverCur].skb = NULL; completed ++; VMXNET_INC(dd->txDriverCur, dd->txRingLength); } if (completed){ lp->numTxPending -= completed; // XXX conditionally wake up the queue based on the # of freed entries if (netif_queue_stopped(dev)) { netif_wake_queue(dev); dd->txStopped = FALSE; } } } /* *----------------------------------------------------------------------------- * * vmxnet_tx -- * * Network device hard_start_xmit helper routine. This is called by * the drivers hard_start_xmit routine when it wants to send a packet. * * Results: * VMXNET_CALL_TRANSMIT: The driver should ask the virtual NIC to * transmit a packet. * VMXNET_DEFER_TRANSMIT: This transmit is deferred because of * transmit clustering. * VMXNET_STOP_TRANSMIT: We ran out of queue space so the caller * should stop transmitting. * * Side effects: * The drivers tx ring may get modified. * *----------------------------------------------------------------------------- */ Vmxnet_TxStatus vmxnet_tx(struct sk_buff *skb, struct net_device *dev) { Vmxnet_TxStatus status = VMXNET_DEFER_TRANSMIT; struct Vmxnet_Private *lp = netdev_priv(dev); Vmxnet2_DriverData *dd = lp->dd; unsigned long flags; Vmxnet2_TxRingEntry *xre; #ifdef VMXNET_DO_TSO int mss; #endif /* * The .suspend handler frees driver data, so we need this check. */ if (UNLIKELY(!dd)) { return VMXNET_STOP_TRANSMIT; } xre = &lp->txRing[dd->txDriverNext]; #ifdef VMXNET_DO_ZERO_COPY if (lp->zeroCopyTx) { int txEntries, sgCount; unsigned int headerSize; /* conservatively estimate the # of tx entries needed in the worse case */ sgCount = (lp->partialHeaderCopyEnabled ? 2 : 1) + skb_shinfo(skb)->nr_frags; txEntries = (sgCount + VMXNET2_SG_DEFAULT_LENGTH - 1) / VMXNET2_SG_DEFAULT_LENGTH; if (UNLIKELY(!lp->chainTx && txEntries > 1)) { /* * rare case, no tx desc chaining support but the pkt need more than 1 * tx entry, linearize it */ if (compat_skb_linearize(skb) != 0) { VMXNET_LOG("vmxnet_tx: skb_linearize failed\n"); compat_dev_kfree_skb(skb, FREE_WRITE); return VMXNET_DEFER_TRANSMIT; } txEntries = 1; } VMXNET_LOG("\n%d(%d) bytes, %d frags, %d tx entries\n", skb->len, skb_headlen(skb), skb_shinfo(skb)->nr_frags, txEntries); spin_lock_irqsave(&lp->txLock, flags); /* check for the availability of tx ring entries */ if (dd->txRingLength - lp->numTxPending < txEntries) { dd->txStopped = TRUE; netif_stop_queue(dev); check_tx_queue(dev); spin_unlock_irqrestore(&lp->txLock, flags); VMXNET_LOG("queue stopped\n"); return VMXNET_STOP_TRANSMIT; } /* copy protocol headers if needed */ if (LIKELY(lp->partialHeaderCopyEnabled)) { unsigned int pos = dd->txDriverNext * dd->txPktMaxSize; char *header = lp->txBufferStart + pos; /* figure out the protocol and header sizes */ /* PR 171928 * compat_skb_ip_header isn't updated in rhel5 for * vlan tagging. using these macros causes incorrect * computation of the headerSize */ headerSize = ETHERNET_HEADER_SIZE; if (UNLIKELY((skb_headlen(skb) < headerSize))) { if (skb_is_nonlinear(skb)) { compat_skb_linearize(skb); } /* * drop here if we don't have a complete ETH header for delivery */ if (skb_headlen(skb) < headerSize) { compat_dev_kfree_skb(skb, FREE_WRITE); spin_unlock_irqrestore(&lp->txLock, flags); return VMXNET_DEFER_TRANSMIT; } } if (UNLIKELY(*(uint16*)(skb->data + ETH_FRAME_TYPE_LOCATION) == ETH_TYPE_VLAN_TAG)) { headerSize += VLAN_TAG_LENGTH; if (UNLIKELY(skb_headlen(skb) < headerSize)) { if (skb_is_nonlinear(skb)) { compat_skb_linearize(skb); } /* * drop here if we don't have a ETH header and a complete VLAN tag */ if (skb_headlen(skb) < headerSize) { compat_dev_kfree_skb(skb, FREE_WRITE); spin_unlock_irqrestore(&lp->txLock, flags); return VMXNET_DEFER_TRANSMIT; } } } if (LIKELY(PKT_OF_IPV4(skb))){ // PR 171928 -- compat_skb_ip_header broken with vconfig // please do not rewrite using compat_skb_ip_header struct iphdr *ipHdr = (struct iphdr *)(skb->data + headerSize); if (UNLIKELY(skb_headlen(skb) < headerSize + sizeof(*ipHdr))) { if (skb_is_nonlinear(skb)) { compat_skb_linearize(skb); } } if (LIKELY(skb_headlen(skb) > headerSize + sizeof(*ipHdr)) && (LIKELY(ipHdr->version == 4))) { headerSize += ipHdr->ihl << 2; if (LIKELY(ipHdr->protocol == IPPROTO_TCP)) { /* * tcp traffic, copy all protocol headers * refrain from using compat_skb macros PR 171928 */ struct tcphdr *tcpHdr = (struct tcphdr *) (skb->data + headerSize); /* * tcp->doff is near the end of the tcpHdr, use the * entire struct as the required size */ if (skb->len < headerSize + sizeof(*tcpHdr)) { compat_dev_kfree_skb(skb, FREE_WRITE); spin_unlock_irqrestore(&lp->txLock, flags); return VMXNET_DEFER_TRANSMIT; } if (skb_headlen(skb) < (headerSize + sizeof(*tcpHdr))) { /* * linearized portion of the skb doesn't have a tcp header */ compat_skb_linearize(skb); } headerSize += tcpHdr->doff << 2; } } } if (skb_copy_bits(skb, 0, header, headerSize) != 0) { compat_dev_kfree_skb(skb, FREE_WRITE); spin_unlock_irqrestore(&lp->txLock, flags); return VMXNET_DEFER_TRANSMIT; } xre->sg.sg[0].addrLow = dd->txBufferPhysStart + pos; xre->sg.sg[0].addrHi = 0; xre->sg.sg[0].length = headerSize; vmxnet_map_pkt(skb, headerSize, lp, 1); } else { headerSize = 0; vmxnet_map_pkt(skb, 0, lp, 0); } #ifdef VMXNET_DO_TSO mss = VMXNET_SKB_MSS(skb); if (mss) { xre->flags |= VMXNET2_TX_TSO; xre->tsoMss = mss; dd->txNumDeferred += ((skb->len - headerSize) + mss - 1) / mss; } else #endif { dd->txNumDeferred++; } } else /* zero copy not enabled */ #endif { struct Vmxnet2_TxBuf *tb; dma_addr_t dmaAddr; spin_lock_irqsave(&lp->txLock, flags); if (lp->txBufInfo[dd->txDriverNext].skb != NULL) { dd->txStopped = TRUE; netif_stop_queue(dev); check_tx_queue(dev); spin_unlock_irqrestore(&lp->txLock, flags); return VMXNET_STOP_TRANSMIT; } lp->numTxPending ++; dmaAddr = compat_pci_map_single(lp->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); VMXNET_FILL_SG(xre->sg.sg[0], dmaAddr, skb->len); xre->sg.length = 1; xre->flags = 0; tb = &lp->txBufInfo[dd->txDriverNext]; tb->skb = skb; tb->sgForLinear = -1; tb->firstSgForFrag = -1; tb->eop = 1; VMXNET_INC(dd->txDriverNext, dd->txRingLength); dd->txNumDeferred++; dd->stats.copyTransmits++; } /* at this point, xre must point to the 1st tx entry for the pkt */ if (skb->ip_summed == VM_TX_CHECKSUM_PARTIAL && ((dev->features & NETIF_F_HW_CSUM) != 0)) { xre->flags |= VMXNET2_TX_HW_XSUM | VMXNET2_TX_CAN_KEEP; } else { xre->flags |= VMXNET2_TX_CAN_KEEP; } if (lp->numTxPending > dd->txRingLength - 5) { xre->flags |= VMXNET2_TX_RING_LOW; status = VMXNET_CALL_TRANSMIT; } wmb(); xre->ownership = VMXNET2_OWNERSHIP_NIC; if (dd->txNumDeferred >= dd->txClusterLength) { dd->txNumDeferred = 0; status = VMXNET_CALL_TRANSMIT; } dev->trans_start = jiffies; lp->stats.tx_packets++; dd->stats.pktsTransmitted++; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) lp->stats.tx_bytes += skb->len; #endif if (lp->numTxPending > dd->stats.maxTxsPending) { dd->stats.maxTxsPending = lp->numTxPending; } check_tx_queue(dev); spin_unlock_irqrestore(&lp->txLock, flags); return status; } /* *----------------------------------------------------------------------------- * * vmxnet_start_tx -- * * Network device hard_start_xmit routine. Called by Linux when it has * a packet for us to transmit. * * Results: * 0 on success; 1 if no resources. * * Side effects: * *----------------------------------------------------------------------------- */ static int vmxnet_start_tx(struct sk_buff *skb, struct net_device *dev) { int retVal = 0; Vmxnet_TxStatus xs = vmxnet_tx(skb, dev); switch (xs) { case VMXNET_CALL_TRANSMIT: inl(dev->base_addr + VMXNET_TX_ADDR); break; case VMXNET_DEFER_TRANSMIT: break; case VMXNET_STOP_TRANSMIT: retVal = 1; break; } return retVal; } #ifdef VMXNET_DO_ZERO_COPY /* *---------------------------------------------------------------------------- * * vmxnet_drop_frags -- * * return the entries in the 2nd ring to the hw. The entries returned are * from rxDriverNext2 to the entry with VMXNET2_RX_FRAG_EOP set. * * Result: * None * * Side-effects: * None * *---------------------------------------------------------------------------- */ static void vmxnet_drop_frags(Vmxnet_Private *lp) { Vmxnet2_DriverData *dd = lp->dd; Vmxnet2_RxRingEntry *rre2; uint16 flags; do { rre2 = &lp->rxRing2[dd->rxDriverNext2]; flags = rre2->flags; VMXNET_ASSERT(rre2->ownership == VMXNET2_OWNERSHIP_DRIVER_FRAG); rre2->ownership = VMXNET2_OWNERSHIP_NIC_FRAG; VMXNET_INC(dd->rxDriverNext2, dd->rxRingLength2); } while(!(flags & VMXNET2_RX_FRAG_EOP)); } /* *---------------------------------------------------------------------------- * * vmxnet_rx_frags -- * * get data from the 2nd rx ring and append the frags to the skb. Multiple * rx entries in the 2nd rx ring are processed until the one with * VMXNET2_RX_FRAG_EOP set. * * Result: * 0 on success * -1 on error * * Side-effects: * frags are appended to skb. related fields in skb are updated * *---------------------------------------------------------------------------- */ static int vmxnet_rx_frags(Vmxnet_Private *lp, struct sk_buff *skb) { Vmxnet2_DriverData *dd = lp->dd; struct pci_dev *pdev = lp->pdev; struct page *newPage; int numFrags = 0; Vmxnet2_RxRingEntry *rre2; uint16 flags; #ifdef VMXNET_DEBUG uint32 firstFrag = dd->rxDriverNext2; #endif do { rre2 = &lp->rxRing2[dd->rxDriverNext2]; flags = rre2->flags; VMXNET_ASSERT(rre2->ownership == VMXNET2_OWNERSHIP_DRIVER_FRAG); if (rre2->actualLength > 0) { newPage = alloc_page(GFP_ATOMIC); if (UNLIKELY(newPage == NULL)) { skb_shinfo(skb)->nr_frags = numFrags; skb->len += skb->data_len; skb->truesize += PAGE_SIZE; compat_dev_kfree_skb(skb, FREE_WRITE); vmxnet_drop_frags(lp); return -1; } pci_unmap_page(pdev, rre2->paddr, PAGE_SIZE, PCI_DMA_FROMDEVICE); #if COMPAT_LINUX_VERSION_CHECK_LT(3, 2, 0) skb_shinfo(skb)->frags[numFrags].page = lp->rxPages[dd->rxDriverNext2]; #else __skb_frag_set_page(&skb_shinfo(skb)->frags[numFrags], lp->rxPages[dd->rxDriverNext2]); #endif skb_shinfo(skb)->frags[numFrags].page_offset = 0; skb_shinfo(skb)->frags[numFrags].size = rre2->actualLength; skb->data_len += rre2->actualLength; skb->truesize += PAGE_SIZE; numFrags++; /* refill the buffer */ lp->rxPages[dd->rxDriverNext2] = newPage; rre2->paddr = pci_map_page(pdev, newPage, 0, PAGE_SIZE, PCI_DMA_FROMDEVICE); rre2->bufferLength = PAGE_SIZE; rre2->actualLength = 0; wmb(); } rre2->ownership = VMXNET2_OWNERSHIP_NIC_FRAG; VMXNET_INC(dd->rxDriverNext2, dd->rxRingLength2); } while (!(flags & VMXNET2_RX_FRAG_EOP)); VMXNET_ASSERT(numFrags > 0); skb_shinfo(skb)->nr_frags = numFrags; skb->len += skb->data_len; skb->truesize += PAGE_SIZE; VMXNET_LOG("vmxnet_rx: %dB from rxRing[%d](%dB)+rxRing2[%d, %d)(%dB)\n", skb->len, dd->rxDriverNext, skb_headlen(skb), firstFrag, dd->rxDriverNext2, skb->data_len); return 0; } #endif /* *----------------------------------------------------------------------------- * * vmxnet_rx -- * * Receive a packet. * * Results: * 0 * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int vmxnet_rx(struct net_device *dev) { struct Vmxnet_Private *lp = netdev_priv(dev); Vmxnet2_DriverData *dd = lp->dd; if (!lp->devOpen || !dd) { return 0; } while (1) { struct sk_buff *skb, *newSkb; Vmxnet2_RxRingEntry *rre; rre = &lp->rxRing[dd->rxDriverNext]; if (rre->ownership != VMXNET2_OWNERSHIP_DRIVER) { break; } if (UNLIKELY(rre->actualLength == 0)) { #ifdef VMXNET_DO_ZERO_COPY if (rre->flags & VMXNET2_RX_WITH_FRAG) { vmxnet_drop_frags(lp); } #endif lp->stats.rx_errors++; goto next_pkt; } skb = lp->rxSkbuff[dd->rxDriverNext]; /* refill the rx ring */ newSkb = dev_alloc_skb(PKT_BUF_SZ + COMPAT_NET_IP_ALIGN); if (UNLIKELY(newSkb == NULL)) { printk(KERN_DEBUG "%s: Memory squeeze, dropping packet.\n", dev->name); #ifdef VMXNET_DO_ZERO_COPY if (rre->flags & VMXNET2_RX_WITH_FRAG) { vmxnet_drop_frags(lp); } #endif lp->stats.rx_errors++; goto next_pkt; } skb_reserve(newSkb, COMPAT_NET_IP_ALIGN); compat_pci_unmap_single(lp->pdev, rre->paddr, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); skb_put(skb, rre->actualLength); lp->rxSkbuff[dd->rxDriverNext] = newSkb; rre->paddr = compat_pci_map_single(lp->pdev, newSkb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); rre->bufferLength = PKT_BUF_SZ; #ifdef VMXNET_DO_ZERO_COPY if (rre->flags & VMXNET2_RX_WITH_FRAG) { if (vmxnet_rx_frags(lp, skb) < 0) { lp->stats.rx_errors++; goto next_pkt; } } else #endif { VMXNET_LOG("vmxnet_rx: %dB from rxRing[%d]\n", skb->len, dd->rxDriverNext); } if (skb->len < (ETH_MIN_FRAME_LEN - 4)) { /* * Ethernet header vlan tags are 4 bytes. Some vendors generate * ETH_MIN_FRAME_LEN frames including vlan tags. When vlan tag * is stripped, such frames become ETH_MIN_FRAME_LEN - 4. (PR106153) */ if (skb->len != 0) { printk(KERN_DEBUG "%s: Runt pkt (%d bytes) entry %d!\n", dev->name, skb->len, dd->rxDriverNext); } lp->stats.rx_errors++; } else { if (rre->flags & VMXNET2_RX_HW_XSUM_OK) { skb->ip_summed = CHECKSUM_UNNECESSARY; } skb->dev = dev; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) lp->stats.rx_bytes += skb->len; #endif skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); lp->stats.rx_packets++; dd->stats.pktsReceived++; } next_pkt: rre->ownership = VMXNET2_OWNERSHIP_NIC; VMXNET_INC(dd->rxDriverNext, dd->rxRingLength); } return 0; } /* *----------------------------------------------------------------------------- * * vmxnet_interrupt -- * * Interrupt handler. Calls vmxnet_rx to receive a packet. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) static compat_irqreturn_t vmxnet_interrupt(int irq, void *dev_id, struct pt_regs * regs) #else static compat_irqreturn_t vmxnet_interrupt(int irq, void *dev_id) #endif { struct net_device *dev = (struct net_device *)dev_id; struct Vmxnet_Private *lp; Vmxnet2_DriverData *dd; if (dev == NULL) { printk (KERN_DEBUG "vmxnet_interrupt(): irq %d for unknown device.\n", irq); return COMPAT_IRQ_NONE; } lp = netdev_priv(dev); outl(VMXNET_CMD_INTR_ACK, dev->base_addr + VMXNET_COMMAND_ADDR); dd = lp->dd; if (LIKELY(dd)) { dd->stats.interrupts++; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) if (dev->interrupt) { printk(KERN_DEBUG "%s: Re-entering the interrupt handler.\n", dev->name); } dev->interrupt = 1; #endif vmxnet_rx(dev); if (lp->numTxPending > 0) { spin_lock(&lp->txLock); check_tx_queue(dev); spin_unlock(&lp->txLock); } if (netif_queue_stopped(dev) && dd && !dd->txStopped) { netif_wake_queue(dev); } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) dev->interrupt = 0; #endif return COMPAT_IRQ_HANDLED; } #ifdef VMW_HAVE_POLL_CONTROLLER /* *----------------------------------------------------------------------------- * * vmxnet_netpoll -- * * Poll network controller. We reuse hardware interrupt for this. * * Results: * None. * * Side effects: * Packets received/transmitted/whatever. * *----------------------------------------------------------------------------- */ static void vmxnet_netpoll(struct net_device *dev) { disable_irq(dev->irq); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) vmxnet_interrupt(dev->irq, dev, NULL); #else vmxnet_interrupt(dev->irq, dev); #endif enable_irq(dev->irq); } #endif /* VMW_HAVE_POLL_CONTROLLER */ /* *----------------------------------------------------------------------------- * * vmxnet_close -- * * Network device stop (close) routine. Called by Linux when the * interface is brought down. * * Results: * 0 for success (always). * * Side effects: * Flushes pending transmits. Frees IRQs and shared memory area. * *----------------------------------------------------------------------------- */ static int vmxnet_close(struct net_device *dev) { unsigned int ioaddr = dev->base_addr; struct Vmxnet_Private *lp = netdev_priv(dev); int i; unsigned long flags; if (vmxnet_debug > 1) { printk(KERN_DEBUG "%s: Shutting down ethercard\n", dev->name); } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) dev->start = 0; #endif netif_stop_queue(dev); lp->devOpen = FALSE; spin_lock_irqsave(&lp->txLock, flags); if (lp->numTxPending > 0) { //Wait absurdly long (2sec) for all the pending packets to be returned. printk(KERN_DEBUG "vmxnet_close: Pending tx = %d\n", lp->numTxPending); for (i = 0; i < 200 && lp->numTxPending > 0; i++) { outl(VMXNET_CMD_CHECK_TX_DONE, dev->base_addr + VMXNET_COMMAND_ADDR); udelay(10000); check_tx_queue(dev); } //This can happen when the related vmxnet device is disabled or when //something's wrong with the pNIC, or even both. //Will go ahead and free these skb's anyways (possibly dangerous, //but seems to work in practice) if (lp->numTxPending > 0) { printk(KERN_EMERG "vmxnet_close: %s failed to finish all pending tx (%d).\n" "Is the related vmxnet device disabled?\n" "This virtual machine may be in an inconsistent state.\n", dev->name, lp->numTxPending); lp->numTxPending = 0; } } spin_unlock_irqrestore(&lp->txLock, flags); outl(0, ioaddr + VMXNET_INIT_ADDR); free_irq(dev->irq, dev); for (i = 0; lp->dd && i < lp->dd->txRingLength; i++) { if (lp->txBufInfo[i].skb != NULL && lp->txBufInfo[i].eop) { compat_dev_kfree_skb(lp->txBufInfo[i].skb, FREE_WRITE); lp->txBufInfo[i].skb = NULL; } } for (i = 0; i < lp->numRxBuffers; i++) { if (lp->rxSkbuff[i] != NULL) { compat_pci_unmap_single(lp->pdev, lp->rxRing[i].paddr, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); compat_dev_kfree_skb(lp->rxSkbuff[i], FREE_WRITE); lp->rxSkbuff[i] = NULL; } } #ifdef VMXNET_DO_ZERO_COPY if (lp->jumboFrame || lp->lpd) { for (i = 0; i < lp->numRxBuffers2; i++) { if (lp->rxPages[i] != NULL) { pci_unmap_page(lp->pdev, lp->rxRing2[i].paddr, PAGE_SIZE, PCI_DMA_FROMDEVICE); put_page(lp->rxPages[i]); lp->rxPages[i] = NULL; } } } #endif COMPAT_NETDEV_MOD_DEC_USE_COUNT; return 0; } /* *----------------------------------------------------------------------------- * * vmxnet_load_multicast -- * * Load the multicast filter. * * Results: * return number of entries used to compute LADRF * * Side effects: * *----------------------------------------------------------------------------- */ static int vmxnet_load_multicast (struct net_device *dev) { struct Vmxnet_Private *lp = netdev_priv(dev); volatile u16 *mcast_table = (u16 *)lp->dd->LADRF; #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34) struct netdev_hw_addr *dmi; #else int i=0; struct dev_mc_list *dmi = dev->mc_list; #endif u8 *addrs; int j, bit, byte; u32 crc, poly = CRC_POLYNOMIAL_LE; /* clear the multicast filter */ lp->dd->LADRF[0] = 0; lp->dd->LADRF[1] = 0; /* Add addresses */ #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34) netdev_for_each_mc_addr(dmi, dev) { addrs = dmi->addr; #else for (i = 0; i < dev->mc_count; i++){ addrs = dmi->dmi_addr; dmi = dmi->next; #endif /* multicast address? */ if (!(*addrs & 1)) continue; crc = 0xffffffff; for (byte = 0; byte < 6; byte++) { for (bit = *addrs++, j = 0; j < 8; j++, bit >>= 1) { int test; test = ((bit ^ crc) & 0x01); crc >>= 1; if (test) { crc = crc ^ poly; } } } crc = crc >> 26; mcast_table [crc >> 4] |= 1 << (crc & 0xf); } #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34) return netdev_mc_count(dev); #else return i; #endif } /* *----------------------------------------------------------------------------- * * vmxnet_set_multicast_list -- * * Network device set_multicast_list routine. Called by Linux when the * set of addresses to listen to changes, including both the multicast * list and the broadcast, promiscuous, multicast, and allmulti flags. * * Results: * None. * * Side effects: * Informs lower layer of the changes. * *----------------------------------------------------------------------------- */ static void vmxnet_set_multicast_list(struct net_device *dev) { unsigned int ioaddr = dev->base_addr; struct Vmxnet_Private *lp = netdev_priv(dev); /* * The .suspend handler frees driver data, so we need this check. */ if (UNLIKELY(!lp->dd)) { return; } lp->dd->ifflags = ~(VMXNET_IFF_PROMISC |VMXNET_IFF_BROADCAST |VMXNET_IFF_MULTICAST); if (dev->flags & IFF_PROMISC) { printk(KERN_DEBUG "%s: Promiscuous mode enabled.\n", dev->name); lp->dd->ifflags |= VMXNET_IFF_PROMISC; } if (dev->flags & IFF_BROADCAST) { lp->dd->ifflags |= VMXNET_IFF_BROADCAST; } if (dev->flags & IFF_ALLMULTI) { lp->dd->LADRF[0] = 0xffffffff; lp->dd->LADRF[1] = 0xffffffff; lp->dd->ifflags |= VMXNET_IFF_MULTICAST; } else { if (vmxnet_load_multicast(dev)) { lp->dd->ifflags |= VMXNET_IFF_MULTICAST; } } outl(VMXNET_CMD_UPDATE_LADRF, ioaddr + VMXNET_COMMAND_ADDR); outl(VMXNET_CMD_UPDATE_IFF, ioaddr + VMXNET_COMMAND_ADDR); } /* *----------------------------------------------------------------------------- * * vmxnet_set_mac_address -- * * Network device set_mac_address routine. Called by Linux when someone * asks to change the interface's MAC address. * * Results: * 0 for success; -EBUSY if interface is up. * * Side effects: * *----------------------------------------------------------------------------- */ static int vmxnet_set_mac_address(struct net_device *dev, void *p) { struct sockaddr *addr=p; unsigned int ioaddr = dev->base_addr; int i; memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); for (i = 0; i < ETH_ALEN; i++) { outb(addr->sa_data[i], ioaddr + VMXNET_MAC_ADDR + i); } return 0; } /* *----------------------------------------------------------------------------- * * vmxnet_get_stats -- * * Network device get_stats routine. Called by Linux when interface * statistics are requested. * * Results: * Returns a pointer to our private stats structure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static struct net_device_stats * vmxnet_get_stats(struct net_device *dev) { Vmxnet_Private *lp = netdev_priv(dev); return &lp->stats; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) static int vmxnet_set_features(struct net_device *netdev, compat_netdev_features_t features) { compat_netdev_features_t changed = features ^ netdev->features; if (changed & (NETIF_F_RXCSUM)) { if (features & NETIF_F_RXCSUM) return 0; } return -1; } #endif module_init(vmxnet_init); module_exit(vmxnet_exit); MODULE_DEVICE_TABLE(pci, vmxnet_chips); /* Module information. */ MODULE_AUTHOR("VMware, Inc."); MODULE_DESCRIPTION("VMware Virtual Ethernet driver"); MODULE_LICENSE("GPL v2"); MODULE_VERSION(VMXNET_DRIVER_VERSION_STRING); /* * Starting with SLE10sp2, Novell requires that IHVs sign a support agreement * with them and mark their kernel modules as externally supported via a * change to the module header. If this isn't done, the module will not load * by default (i.e., neither mkinitrd nor modprobe will accept it). */ MODULE_INFO(supported, "external"); open-vm-tools-9.4.0-1280544/modules/linux/vmblock/0000755765153500003110000000000012220061556017703 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/linux/vmblock/linux/0000755765153500003110000000000012220061556021042 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/linux/vmblock/linux/module.c0000644765153500003110000000651412220061556022501 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * module.c -- * * Module loading/unloading functions. * */ #include "driver-config.h" #include #include #include #include #include "vmblockInt.h" #include "vmblock_version.h" /* Module parameters */ #ifdef VMX86_DEVEL /* { */ int LOGLEVEL_THRESHOLD = 4; module_param(LOGLEVEL_THRESHOLD, int, 0600); MODULE_PARM_DESC(LOGLEVEL_THRESHOLD, "Logging level (0 means no log, " "10 means very verbose, 4 is default)"); #endif /* } */ static char *root = "/tmp/VMwareDnD"; module_param(root, charp, 0600); MODULE_PARM_DESC(root, "The directory the file system redirects to."); /* Module information */ MODULE_AUTHOR("VMware, Inc."); MODULE_DESCRIPTION("VMware Blocking File System"); MODULE_LICENSE("GPL v2"); MODULE_VERSION(VMBLOCK_DRIVER_VERSION_STRING); /* * Starting with SLE10sp2, Novell requires that IHVs sign a support agreement * with them and mark their kernel modules as externally supported via a * change to the module header. If this isn't done, the module will not load * by default (i.e., neither mkinitrd nor modprobe will accept it). */ MODULE_INFO(supported, "external"); /* *---------------------------------------------------------------------------- * * VMBlockInit -- * * Module entry point and initialization. * * Results: * Zero on success, negative value on failure. * * Side effects: * /proc entries are available and file system is registered with kernel and * ready to be mounted. * *---------------------------------------------------------------------------- */ static int VMBlockInit(void) { int ret; ret = VMBlockInitControlOps(); if (ret < 0) { goto error; } ret = VMBlockInitFileSystem(root); if (ret < 0) { VMBlockCleanupControlOps(); goto error; } LOG(4, "module loaded\n"); return 0; error: Warning("VMBlock: could not initialize module\n"); return ret; } module_init(VMBlockInit); /* *---------------------------------------------------------------------------- * * VMBlockExit -- * * Unloads module from kernel and removes associated state. * * Results: * None. * * Side effects: * Opposite of VMBlockInit(): /proc entries go away and file system is * unregistered. * *---------------------------------------------------------------------------- */ static void VMBlockExit(void) { VMBlockCleanupControlOps(); VMBlockCleanupFileSystem(); LOG(4, "module unloaded\n"); } module_exit(VMBlockExit); open-vm-tools-9.4.0-1280544/modules/linux/vmblock/linux/filesystem.h0000644765153500003110000000714012220061556023401 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * filesystem.h -- * * Definitions and prototypes for file system portion of vmblock driver. * * There are currently two classes of files in the blocking file system: the * root directory and symlinks to actual files on the file system. The root * directory provides a way to lookup directory entries in the directory we * are redirecting to; each of these directory entries is presented as * a symlink. These symlinks within the root directory contain the path of * the actual file and will block any time the inode is accessed or dentry is * revalidated (if there is a pending block). This blocking ensures that any * access to the file through the symlink will not proceed until the block is * lifted. * * Operation tables for the root directory and symlinks are are named Root*Ops * and Link*Ops respectively. All operations are preceded by their operation * type (e.g., the file_operation table's open is named FileOpOpen and the * inode_operation table's lookup is named InodeOpLookup). * * The use of symlinks greatly simplifies the driver's implementation but also * limits blocking to a depth of one level within the redirected directory * (since after the symlink is followed all operations are passed on to the * actual file system and are out of our control). This limitation is fine * under the current use of this driver. */ #ifndef __FILESYSTEM_H__ #define __FILESYSTEM_H__ #include "compat_slab.h" #include #include "vm_basic_types.h" #define INODE_TO_IINFO(_inode) container_of(_inode, VMBlockInodeInfo, inode) #define INODE_TO_ACTUALDENTRY(inode) INODE_TO_IINFO(inode)->actualDentry #define INODE_TO_ACTUALINODE(inode) INODE_TO_IINFO(inode)->actualDentry->d_inode #define VMBLOCK_SUPER_MAGIC 0xabababab typedef struct VMBlockInodeInfo { char name[PATH_MAX]; size_t nameLen; struct dentry *actualDentry; /* Embedded inode */ struct inode inode; } VMBlockInodeInfo; ino_t GetNextIno(void); struct inode *Iget(struct super_block *sb, struct inode *dir, struct dentry *dentry, ino_t ino); int MakeFullName(struct inode *dir, struct dentry *dentry, char *bufOut, size_t bufOutSize); void VMBlockReadInode(struct inode *inode); /* Variables */ extern compat_kmem_cache *VMBlockInodeCache; /* File system wide superblock operations */ extern struct super_operations VMBlockSuperOps; /* File operations on fs's root inode to read directory entries. */ extern struct file_operations RootFileOps; /* Inode operations to lookup inodes of directory entries in fs's root inode. */ extern struct inode_operations RootInodeOps; /* Dentry operations for our symlinks to actual files (to enable blocking). */ extern struct dentry_operations LinkDentryOps; #endif /* __FILESYSTEM_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/vmblock/linux/super.c0000644765153500003110000000741312220061556022351 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * super.c -- * * Super operations for the file system portion of the vmblock driver. * */ #include "driver-config.h" #include #include #include "vmblockInt.h" #include "filesystem.h" /* Super block operations */ static struct inode *SuperOpAllocInode(struct super_block *sb); static void SuperOpDestroyInode(struct inode *inode); #ifdef VMW_STATFS_2618 static int SuperOpStatfs(struct dentry *dentry, struct kstatfs *stat); #else static int SuperOpStatfs(struct super_block *sb, struct kstatfs *stat); #endif struct super_operations VMBlockSuperOps = { .alloc_inode = SuperOpAllocInode, .destroy_inode = SuperOpDestroyInode, .statfs = SuperOpStatfs, }; /* *---------------------------------------------------------------------------- * * SuperOpAllocInode -- * * Allocates an inode info from the cache. See function comment for Iget() * for a complete explanation of how inode allocation works. * * Results: * A pointer to the embedded inode on success, NULL on failure. * * Side effects: * iinfo is initialized by InodeCacheCtor(). * *---------------------------------------------------------------------------- */ static struct inode * SuperOpAllocInode(struct super_block *sb) // IN: superblock of file system { VMBlockInodeInfo *iinfo; iinfo = kmem_cache_alloc(VMBlockInodeCache, GFP_KERNEL); if (!iinfo) { Warning("SuperOpAllocInode: could not allocate iinfo\n"); return NULL; } /* The inode we give back to VFS is embedded within our inode info struct. */ return &iinfo->inode; } /* *---------------------------------------------------------------------------- * * SuperOpDestroyInode -- * SuperOpClearInode -- * * Destroys the provided inode by freeing the inode info. In the embedded * inode case, this includes the actual inode itself; in the non-embedded * inode case, the inode is freed by the kernel. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void SuperOpDestroyInode(struct inode *inode) // IN: Inode to free { kmem_cache_free(VMBlockInodeCache, INODE_TO_IINFO(inode)); } /* *---------------------------------------------------------------------------- * * SuperOpStatfs -- * * Implements a null statfs. * * Results: * Zero on success, negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #ifdef VMW_STATFS_2618 static int SuperOpStatfs(struct dentry *dentry, struct kstatfs *stat) #else static int SuperOpStatfs(struct super_block *sb, struct kstatfs *stat) #endif { if (!stat) { return -EINVAL; } stat->f_type = VMBLOCK_SUPER_MAGIC; stat->f_bsize = 0; stat->f_namelen = NAME_MAX; stat->f_blocks = 0; stat->f_bfree = 0; stat->f_bavail = 0; return 0; } open-vm-tools-9.4.0-1280544/modules/linux/vmblock/linux/control.c0000644765153500003110000002257712220061556022703 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * control.c -- * * Control operations for the vmblock driver. * */ #include "driver-config.h" #include #include #include #include #include #include "vmblockInt.h" #include "block.h" /* procfs initialization/cleanup functions */ static int SetupProcDevice(void); static int CleanupProcDevice(void); /* procfs entry file operations */ ssize_t ControlFileOpWrite(struct file *filp, const char __user *buf, size_t cmd, loff_t *ppos); static int ControlFileOpRelease(struct inode *inode, struct file *file); static struct proc_dir_entry *controlProcDirEntry; struct file_operations ControlFileOps = { .owner = THIS_MODULE, .write = ControlFileOpWrite, .release = ControlFileOpRelease, }; /* Public initialization/cleanup routines */ /* *---------------------------------------------------------------------------- * * VMBlockInitControlOps -- * * Sets up state for control operations. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VMBlockInitControlOps(void) { int ret; ret = BlockInit(); if (ret < 0) { Warning("VMBlockInitControlOps: could not initialize blocking ops.\n"); return ret; } ret = SetupProcDevice(); if (ret < 0) { Warning("VMBlockInitControlOps: could not setup proc device.\n"); BlockCleanup(); return ret; } return 0; } /* *---------------------------------------------------------------------------- * * VMBlockCleanupControlOps -- * * Cleans up state for control operations. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VMBlockCleanupControlOps(void) { int ret; ret = CleanupProcDevice(); if (ret < 0) { Warning("VMBlockCleanupControlOps: could not cleanup proc device.\n"); return ret; } BlockCleanup(); return 0; } /* Private initialization/cleanup routines */ /* *---------------------------------------------------------------------------- * * VMBlockSetProcEntryOwner -- * * Sets proc_dir_entry owner if necessary: * * Before version 2.6.24 kernel prints nasty warning when in-use * directory entry is destroyed, which happens when module is unloaded. * We try to prevent this warning in most cases by setting owner to point * to our module, so long operations (like current directory pointing to * directory we created) prevent module from unloading. Since 2.6.24 this * situation is handled without nastygrams, allowing module unload even * when current directory points to directory created by unloaded module, * so we do not have to set owner anymore. And since 2.6.29 we must not * set owner at all, as there is none... * * Results: * None. Always succeeds. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VMBlockSetProcEntryOwner(struct proc_dir_entry *entry) // IN/OUT: directory entry { #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) entry->owner = THIS_MODULE; #endif } /* *---------------------------------------------------------------------------- * * SetupProcDevice -- * * Adds entries to /proc used to control file blocks. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int SetupProcDevice(void) { struct proc_dir_entry *controlProcEntry; struct proc_dir_entry *controlProcMountpoint; /* Create /proc/fs/vmblock */ controlProcDirEntry = proc_mkdir(VMBLOCK_CONTROL_PROC_DIRNAME, NULL); if (!controlProcDirEntry) { Warning("SetupProcDevice: could not create /proc/" VMBLOCK_CONTROL_PROC_DIRNAME "\n"); return -EINVAL; } VMBlockSetProcEntryOwner(controlProcDirEntry); /* Create /proc/fs/vmblock/mountPoint */ controlProcMountpoint = proc_mkdir(VMBLOCK_CONTROL_MOUNTPOINT, controlProcDirEntry); if (!controlProcMountpoint) { Warning("SetupProcDevice: could not create " VMBLOCK_MOUNT_POINT "\n"); remove_proc_entry(VMBLOCK_CONTROL_PROC_DIRNAME, NULL); return -EINVAL; } VMBlockSetProcEntryOwner(controlProcMountpoint); /* Create /proc/fs/vmblock/dev */ controlProcEntry = create_proc_entry(VMBLOCK_CONTROL_DEVNAME, VMBLOCK_CONTROL_MODE, controlProcDirEntry); if (!controlProcEntry) { Warning("SetupProcDevice: could not create " VMBLOCK_DEVICE "\n"); remove_proc_entry(VMBLOCK_CONTROL_MOUNTPOINT, controlProcDirEntry); remove_proc_entry(VMBLOCK_CONTROL_PROC_DIRNAME, NULL); return -EINVAL; } controlProcEntry->proc_fops = &ControlFileOps; return 0; } /* *---------------------------------------------------------------------------- * * CleanupProcDevice -- * * Removes /proc entries for controlling file blocks. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int CleanupProcDevice(void) { if (controlProcDirEntry) { remove_proc_entry(VMBLOCK_CONTROL_MOUNTPOINT, controlProcDirEntry); remove_proc_entry(VMBLOCK_CONTROL_DEVNAME, controlProcDirEntry); remove_proc_entry(VMBLOCK_CONTROL_PROC_DIRNAME, NULL); } return 0; } /* procfs file operations */ /* *---------------------------------------------------------------------------- * * ExecuteBlockOp -- * * Copy block name from user buffer into kernel space, canonicalize it * by removing all trailing path separators, and execute desired block * operation. * * Results: * 0 on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int ExecuteBlockOp(const char __user *buf, // IN: buffer with name const os_blocker_id_t blocker, // IN: blocker ID (file) int (*blockOp)(const char *filename, // IN: block operation const os_blocker_id_t blocker)) { char *name; int i; int retval; name = getname(buf); if (IS_ERR(name)) { return PTR_ERR(name); } for (i = strlen(name) - 1; i >= 0 && name[i] == '/'; i--) { name[i] = '\0'; } retval = i < 0 ? -EINVAL : blockOp(name, blocker); putname(name); return retval; } /* *---------------------------------------------------------------------------- * * ControlFileOpWrite -- * * write implementation for our control file. This accepts either add or * delete commands and the buffer contains the file to block. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ ssize_t ControlFileOpWrite(struct file *file, // IN: Opened file, used for ID const char __user *buf, // IN: NUL-terminated filename size_t cmd, // IN: VMBlock command (usually count) loff_t *ppos) // IN/OUT: File offset (unused) { int ret; switch (cmd) { case VMBLOCK_ADD_FILEBLOCK: ret = ExecuteBlockOp(buf, file, BlockAddFileBlock); break; case VMBLOCK_DEL_FILEBLOCK: ret = ExecuteBlockOp(buf, file, BlockRemoveFileBlock); break; #ifdef VMX86_DEVEL case VMBLOCK_LIST_FILEBLOCKS: BlockListFileBlocks(); ret = 0; break; #endif default: Warning("ControlFileOpWrite: unrecognized command (%u) recieved\n", (unsigned)cmd); ret = -EINVAL; break; } return ret; } /* *---------------------------------------------------------------------------- * * ControlFileOpRelease -- * * Called when the file is closed. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int ControlFileOpRelease(struct inode *inode, // IN struct file *file) // IN { BlockRemoveAllBlocks(file); return 0; } open-vm-tools-9.4.0-1280544/modules/linux/vmblock/linux/dentry.c0000644765153500003110000000663312220061556022523 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * dentry.c -- * * Dentry operations for the file system of the vmblock driver. * */ #include "driver-config.h" #include #include "compat_namei.h" #include "vmblockInt.h" #include "filesystem.h" #include "block.h" static int DentryOpRevalidate(struct dentry *dentry, struct nameidata *nd); struct dentry_operations LinkDentryOps = { .d_revalidate = DentryOpRevalidate, }; /* *---------------------------------------------------------------------------- * * DentryOpRevalidate -- * * This function is invoked every time the dentry is accessed from the cache * to ensure it is still valid. We use it to block since any threads * looking up this dentry after the initial lookup should still block if the * block has not been cleared. * * Results: * 1 if the dentry is valid, 0 if it is not. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int DentryOpRevalidate(struct dentry *dentry, // IN: dentry revalidating struct nameidata *nd) // IN: lookup flags & intent { VMBlockInodeInfo *iinfo; struct nameidata actualNd; struct dentry *actualDentry; int ret; if (!dentry) { Warning("DentryOpRevalidate: invalid args from kernel\n"); return 0; } /* * If a dentry does not have an inode associated with it then * we are dealing with a negative dentry. Always invalidate a negative * dentry which will cause a fresh lookup. */ if (!dentry->d_inode) { return 0; } iinfo = INODE_TO_IINFO(dentry->d_inode); if (!iinfo) { Warning("DentryOpRevalidate: dentry has no fs-specific data\n"); return 0; } /* Block if there is a pending block on this file */ BlockWaitOnFile(iinfo->name, NULL); /* * If the actual dentry has a revalidate function, we'll let it figure out * whether the dentry is still valid. If not, do a path lookup to ensure * that the file still exists. */ actualDentry = iinfo->actualDentry; if (actualDentry && actualDentry->d_op && actualDentry->d_op->d_revalidate) { return actualDentry->d_op->d_revalidate(actualDentry, nd); } if (compat_path_lookup(iinfo->name, 0, &actualNd)) { LOG(4, "DentryOpRevalidate: [%s] no longer exists\n", iinfo->name); return 0; } ret = compat_vmw_nd_to_dentry(actualNd) && compat_vmw_nd_to_dentry(actualNd)->d_inode; compat_path_release(&actualNd); LOG(8, "DentryOpRevalidate: [%s] %s revalidated\n", iinfo->name, ret ? "" : "not"); return ret; } open-vm-tools-9.4.0-1280544/modules/linux/vmblock/linux/file.c0000644765153500003110000001474212220061556022135 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * file.c -- * * File operations for the file system of the vmblock driver. * */ #include "driver-config.h" #include #include #include #include #include "vmblockInt.h" #include "filesystem.h" #if defined(VMW_FILLDIR_2618) typedef u64 inode_num_t; #else typedef ino_t inode_num_t; #endif /* Specifically for our filldir_t callback */ typedef struct FilldirInfo { filldir_t filldir; void *dirent; } FilldirInfo; /* *---------------------------------------------------------------------------- * * Filldir -- * * Callback function for readdir that we use in place of the one provided. * This allows us to specify that each dentry is a symlink, but pass through * everything else to the original filldir function. * * Results: * Original filldir's return value. * * Side effects: * Directory information gets copied to user's buffer. * *---------------------------------------------------------------------------- */ static int Filldir(void *buf, // IN: Dirent buffer passed from FileOpReaddir const char *name, // IN: Dirent name int namelen, // IN: len of dirent's name loff_t offset, // IN: Offset inode_num_t ino, // IN: Inode number of dirent unsigned int d_type) // IN: Type of file { FilldirInfo *info = buf; /* Specify DT_LNK regardless */ return info->filldir(info->dirent, name, namelen, offset, ino, DT_LNK); } /* File operations */ /* *---------------------------------------------------------------------------- * * FileOpOpen -- * * Invoked when open(2) has been called on our root inode. We get an open * file instance of the actual file that we are providing indirect access * to. * * Results: * 0 on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int FileOpOpen(struct inode *inode, // IN struct file *file) // IN { VMBlockInodeInfo *iinfo; struct file *actualFile; if (!inode || !file || !INODE_TO_IINFO(inode)) { Warning("FileOpOpen: invalid args from kernel\n"); return -EINVAL; } iinfo = INODE_TO_IINFO(inode); /* * Get an open file for the directory we are redirecting to. This ensure we * can gracefully handle cases where that directory is removed after we are * mounted. */ actualFile = filp_open(iinfo->name, file->f_flags, file->f_flags); if (IS_ERR(actualFile)) { Warning("FileOpOpen: could not open file [%s]\n", iinfo->name); file->private_data = NULL; return PTR_ERR(actualFile); } /* * If the file opened is the same as the one retrieved for the file then we * shouldn't allow the open to happen. This can only occur if the * redirected root directory specified at mount time is the same as where * the mount is placed. Later in FileOpReaddir() we'd call vfs_readdir() * and that would try to acquire the inode's semaphore; if the two inodes * are the same we'll deadlock. */ if (actualFile->f_dentry && inode == actualFile->f_dentry->d_inode) { Warning("FileOpOpen: identical inode encountered, open cannot succeed.\n"); if (filp_close(actualFile, current->files) < 0) { Warning("FileOpOpen: unable to close opened file.\n"); } return -EINVAL; } file->private_data = actualFile; return 0; } /* *---------------------------------------------------------------------------- * * FileOpReaddir -- * * Invoked when a user invokes getdents(2) or readdir(2) on the root of our * file system. We perform a readdir on the actual underlying file but * interpose the callback by providing our own Filldir() function. This * enables us to change dentry types to symlinks. * * Results: * 0 on success, negative error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int FileOpReaddir(struct file *file, // IN void *dirent, // IN filldir_t filldir) // IN { int ret; FilldirInfo info; struct file *actualFile; if (!file) { Warning("FileOpReaddir: invalid args from kernel\n"); return -EINVAL; } actualFile = file->private_data; if (!actualFile) { Warning("FileOpReaddir: no actual file found\n"); return -EINVAL; } info.filldir = filldir; info.dirent = dirent; actualFile->f_pos = file->f_pos; ret = vfs_readdir(actualFile, Filldir, &info); file->f_pos = actualFile->f_pos; return ret; } /* *---------------------------------------------------------------------------- * * FileOpRelease -- * * Invoked when a user close(2)s the root of our file system. Here we just * close the actual file we opened in FileOpOpen(). * * Results: * 0 on success, negative value on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int FileOpRelease(struct inode *inode, // IN struct file *file) // IN { int ret; struct file *actualFile; if (!inode || !file) { Warning("FileOpRelease: invalid args from kerel\n"); return -EINVAL; } actualFile = file->private_data; if (!actualFile) { Warning("FileOpRelease: no actual file found\n"); return -EINVAL; } ret = filp_close(actualFile, current->files); return ret; } struct file_operations RootFileOps = { .readdir = FileOpReaddir, .open = FileOpOpen, .release = FileOpRelease, }; open-vm-tools-9.4.0-1280544/modules/linux/vmblock/linux/vmblock_version.h0000644765153500003110000000223012220061556024412 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmblock_version.h -- * * Version definitions for the Linux vmblock driver. */ #ifndef _VMBLOCK_VERSION_H_ #define _VMBLOCK_VERSION_H_ #define VMBLOCK_DRIVER_VERSION 1.1.2.0 #define VMBLOCK_DRIVER_VERSION_COMMAS 1,1,2,0 #define VMBLOCK_DRIVER_VERSION_STRING "1.1.2.0" #endif /* _VMBLOCK_VERSION_H_ */ open-vm-tools-9.4.0-1280544/modules/linux/vmblock/linux/vmblockInt.h0000644765153500003110000000614612220061556023332 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmblockInt.h -- * * Definitions and prototypes for entire module. * * The module is split into two halves, a control half and a file system * half, and the halves communicate through the blocking functionality in * block.c. The control half creates a device node for a user space program * (running as root) to add and delete blocks on files in the file system's * namespace. The file system provides links to the contents of the * directory it is redirecting to and blocks according to the file blocks set * through the control half. */ #ifndef __VMBLOCKINT_H__ #define __VMBLOCKINT_H__ #include #include #include "vmblock.h" #include "vm_basic_types.h" #include "vm_assert.h" #ifdef __KERNEL__ #ifdef VMX86_DEVEL extern int LOGLEVEL_THRESHOLD; # define LOG(level, fmt, args...) \ ((void) (LOGLEVEL_THRESHOLD >= (level) ? \ printk(KERN_DEBUG "VMBlock: " fmt, ## args) : \ 0) \ ) #else # define LOG(level, fmt, args...) #endif #define Warning(fmt, args...) \ printk(KERN_WARNING "VMBlock warning: " fmt, ## args) /* * Some kernel versions, bld-2.4.21-32.EL_x86_64-ia32e-RHEL3 and perhaps more, * don't define __user in uaccess.h, so let's do it here so we don't have to * ifdef all the __user annotations. */ #ifndef __user #define __user #endif #endif /* __KERNEL__ */ #define VMBLOCK_CONTROL_MODE S_IRUSR | S_IFREG /* * Our modules may be compatible with kernels built for different processors. * This can cause problems, so we add a reference to the __alloc_pages symbol * below since it is versioned per-processor and will cause modules to only * load on kernels built for the same processor as our module. * * XXX This should go in driver-config.h, but vmmon's hostKernel.h is retarded. */ static const void *forceProcessorCheck __attribute__((unused)) = __alloc_pages; /* * Initialization and cleanup routines for control and file system halves of * vmblock driver */ int VMBlockInitControlOps(void); int VMBlockCleanupControlOps(void); int VMBlockInitFileSystem(char const *root); int VMBlockCleanupFileSystem(void); #endif /* __VMBLOCK_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/vmblock/linux/filesystem.c0000644765153500003110000004275512220061556023407 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * filesystem.c -- * * File system for the vmblock driver. * */ #include "driver-config.h" #include #include #include #include #include "compat_fs.h" #include "compat_namei.h" #include "os.h" #include "vmblockInt.h" #include "filesystem.h" #define VMBLOCK_ROOT_INO 1 #define GetRootInode(sb) Iget(sb, NULL, NULL, VMBLOCK_ROOT_INO) static struct inode *GetInode(struct super_block *sb, ino_t ino); /* File system operations */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) static struct dentry *FsOpMount(struct file_system_type *fsType, int flags, const char *devName, void *rawData); #elif defined(VMW_GETSB_2618) static int FsOpGetSb(struct file_system_type *fsType, int flags, const char *devName, void *rawData, struct vfsmount *mnt); #else static struct super_block *FsOpGetSb(struct file_system_type *fsType, int flags, const char *devName, void *rawData); #endif static int FsOpReadSuper(struct super_block *sb, void *rawData, int flags); /* Utility */ static compat_kmem_cache_ctor InodeCacheCtor; /* Variables */ compat_kmem_cache *VMBlockInodeCache; /* Local variables */ static char const *fsRoot; static size_t fsRootLen; static struct file_system_type fsType = { .owner = THIS_MODULE, .name = VMBLOCK_FS_NAME, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) .mount = FsOpMount, #else .get_sb = FsOpGetSb, #endif .kill_sb = kill_anon_super, }; /* * Public functions (with respect to the module) */ /* *---------------------------------------------------------------------------- * * VMBlockInitFileSystem -- * * Initializes the file system and registers it with the kernel. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VMBlockInitFileSystem(char const *root) // IN: directory redirecting to { int ret; if (!root) { Warning("VMBlockInitFileSystem: root not provided " "(missing module parameter?)\n"); return -EINVAL; } /* * Here we assume that the provided root is valid so the module will load. * The mount operation will fail if that is not the case. */ fsRoot = root; fsRootLen = strlen(fsRoot); if (fsRootLen >= PATH_MAX) { return -ENAMETOOLONG; } /* Initialize our inode slab allocator */ VMBlockInodeCache = os_kmem_cache_create("VMBlockInodeCache", sizeof (VMBlockInodeInfo), 0, InodeCacheCtor); if (!VMBlockInodeCache) { Warning("VMBlockInitFileSystem: could not initialize inode cache\n"); return -ENOMEM; } /* Tell the kernel about our file system */ ret = register_filesystem(&fsType); if (ret < 0) { Warning("VMBlockInitFileSystem: could not initialize file system\n"); kmem_cache_destroy(VMBlockInodeCache); return ret; } LOG(4, "file system registered with root of [%s]\n", fsRoot); return 0; } /* *---------------------------------------------------------------------------- * * VMBlockCleanupFileSystem -- * * Cleans up file system and unregisters it with the kernel. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VMBlockCleanupFileSystem(void) { int ret; ret = unregister_filesystem(&fsType); if (ret < 0) { Warning("VMBlockCleanupFileSystem: could not unregister file system\n"); return ret; } kmem_cache_destroy(VMBlockInodeCache); return 0; } /* *---------------------------------------------------------------------------- * * VMBlockReadInode -- * * A filesystem wide function that is called to initialize a new inode. * This is called from two different places depending on the kernel version. * In older kernels that provide the iget() interface, this function is * called by the kernel as part of inode initialization (from * SuperOpReadInode). In newer kernels that call iget_locked(), this * function is called by filesystem code to initialize the new inode. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void VMBlockReadInode(struct inode *inode) // IN: Inode to initialize { VMBlockInodeInfo *iinfo = INODE_TO_IINFO(inode); iinfo->name[0] = '\0'; iinfo->nameLen = 0; iinfo->actualDentry = NULL; } /* *---------------------------------------------------------------------------- * * GetNextIno -- * * Gets the next available inode number. * * Results: * The next available inode number. * * Side effects: * None. * *---------------------------------------------------------------------------- */ ino_t GetNextIno(void) { static atomic_t nextIno = ATOMIC_INIT(VMBLOCK_ROOT_INO + 1); return (ino_t) atomic_inc_return(&nextIno); } /* *---------------------------------------------------------------------------- * * GetInode -- * * This function replaces iget() and should be called instead of it. In newer * kernels that have removed the iget() interface, GetInode() obtains an inode * and if it is a new one, then initializes the inode by calling * VMBlockReadInode(). In older kernels that support the iget() interface, * VMBlockReadInode() is called by iget() internally by the superblock function * SuperOpReadInode. * * Results: * A new inode object on success, NULL on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static struct inode * GetInode(struct super_block *sb, // IN: file system superblock object ino_t ino) // IN: inode number to assign to new inode { struct inode *inode; inode = iget_locked(sb, ino); if (!inode) { return NULL; } else if (inode->i_state & I_NEW) { VMBlockReadInode(inode); unlock_new_inode(inode); } return inode; } /* *---------------------------------------------------------------------------- * * Iget -- * * Lookup or create a new inode. * * Inode creation in detail: * Throughout the file system, we call the VFS iget() function to get a new * inode. This in turn invokes our file system's SuperOpAllocInode() * function, which allocates an inode info structure (VMBlockInodeInfo) * using the kernel's slab allocator. When a new slab is created, each * object is initialized with the constructor (InodeCacheCtor()), but that * occurs only once per struct (e.g., when a struct from a slab is freed and * reused, the constructor is not invoked again). SuperOpAllocInode() then * returns the address of the inode struct that is embedded within the inode * info we have allocated. iget() also invokes our SuperOpReadInode() * function to do any further file system wide initialization to the inode, * then returns the inode to us (this function). * * Note that in older kernels that don't have the alloc_inode operation * (where VMW_EMBED_INODE is undefined), the allocation is delayed until * this function and is contained within the INODE_TO_IINFO macro. That * allocation is freed in the SuperOpClearInode() function. * * This function then constructs the full path of the actual file name and * does a path_lookup() to see if it exists. If it does, we save a pointer * to the actual dentry within our inode info for future use. If it * doesn't, we still provide an inode but indicate that it doesn't exist by * setting the actual dentry to NULL. Callers that need to handle this case * differently check for the existence of the actual dentry (and actual * inode) to ensure the actual file exists. * * Results: * A new inode object on success, NULL on error. * * Side effects: * A path lookup is done for the actual file. * *---------------------------------------------------------------------------- */ struct inode * Iget(struct super_block *sb, // IN: file system superblock object struct inode *dir, // IN: containing directory struct dentry *dentry, // IN: dentry within directory ino_t ino) // IN: inode number to assign to new inode { VMBlockInodeInfo *iinfo; struct inode *inode; struct nameidata actualNd; ASSERT(sb); inode = GetInode(sb, ino); if (!inode) { return NULL; } iinfo = INODE_TO_IINFO(inode); if (!iinfo) { Warning("Iget: invalid inode provided, or unable to allocate inode info\n"); goto error_inode; } /* Populate iinfo->name with the full path of the target file */ if (MakeFullName(dir, dentry, iinfo->name, sizeof iinfo->name) < 0) { Warning("Iget: could not make full name\n"); goto error_inode; } if (compat_path_lookup(iinfo->name, 0, &actualNd)) { /* * This file does not exist, so we create an inode that doesn't know * about its underlying file. Operations that create files and * directories need an inode to operate on even if there is no actual * file yet. */ iinfo->actualDentry = NULL; return inode; } iinfo->actualDentry = compat_vmw_nd_to_dentry(actualNd); compat_path_release(&actualNd); return inode; error_inode: iput(inode); return NULL; } /* *---------------------------------------------------------------------------- * * InodeCacheCtor -- * * The constructor for inode info structs that occurs once at slab * allocation. That is, this is called once for each piece of memory that * is used to satisfy inode info allocations; it should only be used to * initialized items that will naturally return to their initialized state * before deallocation (such as locks, list_heads). * * We only invoke the inode's initialization routine since all of the inode * info members need to be initialized on each allocation (in * SuperOpReadInode()). * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void InodeCacheCtor(COMPAT_KMEM_CACHE_CTOR_ARGS(slabElem)) // IN: allocated slab item to initialize { VMBlockInodeInfo *iinfo = slabElem; inode_init_once(&iinfo->inode); } /* *---------------------------------------------------------------------------- * * MakeFullName -- * * Constructs the full filename from the provided directory and a dentry * contained within it. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int MakeFullName(struct inode *dir, // IN : directory struct dentry *dentry, // IN : dentry in that directory char *bufOut, // OUT: output buffer size_t bufOutSize) // IN : size of output buffer { ASSERT(bufOut); /* * If dir is supplied, contruct the full path of the actual file, otherwise * it's the root directory. */ if (dir == NULL) { if (fsRootLen >= bufOutSize) { Warning("MakeFullName: root path was too long.\n"); return -ENAMETOOLONG; } memcpy(bufOut, fsRoot, fsRootLen); bufOut[fsRootLen] = '\0'; } else { VMBlockInodeInfo *dirIinfo; int ret; ASSERT(dir); ASSERT(dentry); if (!dentry->d_name.name) { Warning("MakeFullName: dentry name is empty\n"); return -EINVAL; } dirIinfo = INODE_TO_IINFO(dir); /* * If dirIinfo->name[1] is '\0', then it is "/" and we don't need * another '/' between it and the additional name. */ ret = snprintf(bufOut, bufOutSize, dirIinfo->name[1] == '\0' ? "%s%s" : "%s/%s", dirIinfo->name, dentry->d_name.name); if (ret >= bufOutSize) { Warning("MakeFullName: path was too long.\n"); return -ENAMETOOLONG; } } return 0; } /* File system operations */ /* *----------------------------------------------------------------------------- * * FsOpReadSuper -- * * The main entry point of the filesystem side of the driver. Called when * a userland process does a mount(2) of an hgfs filesystem. This makes the * whole driver transition from its initial state to state 1. Fill the * content of the uninitialized superblock provided by the kernel. * * 'rawData' is a pointer (that can be NULL) to a kernel buffer (whose * size is <= PAGE_SIZE) that corresponds to the filesystem-specific 'data' * argument passed to mount(2). * * Results: * zero and initialized superblock on success * negative value on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ static int FsOpReadSuper(struct super_block *sb, // OUT: Superblock object void *rawData, // IN: Fs-specific mount data int flags) // IN: Mount flags { struct inode *rootInode; struct dentry *rootDentry; if (!sb) { Warning("FsOpReadSuper: invalid arg from kernel\n"); return -EINVAL; } sb->s_magic = VMBLOCK_SUPER_MAGIC; sb->s_blocksize = 1024; sb->s_op = &VMBlockSuperOps; /* * Make root inode and dentry. Ensure that the directory we are redirecting * to has an actual dentry and inode, and that it is in fact a directory. */ rootInode = GetRootInode(sb); if (!rootInode) { return -EINVAL; } if (!INODE_TO_IINFO(rootInode) || !INODE_TO_ACTUALDENTRY(rootInode) || !INODE_TO_ACTUALINODE(rootInode) || !S_ISDIR(INODE_TO_ACTUALINODE(rootInode)->i_mode)) { iput(rootInode); return -EINVAL; } rootDentry = d_make_root(rootInode); if (!rootDentry) { return -ENOMEM; } sb->s_root = rootDentry; rootInode->i_op = &RootInodeOps; rootInode->i_fop = &RootFileOps; rootInode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; LOG(4, "%s file system mounted\n", VMBLOCK_FS_NAME); return 0; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) /* *----------------------------------------------------------------------------- * * FsOpMount -- * * Invokes generic kernel code to mount a deviceless filesystem. * * Results: * Mount's root dentry tructure on success * ERR_PTR()-encoded negative error code on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ struct dentry * FsOpMount(struct file_system_type *fs_type, // IN: file system type of mount int flags, // IN: mount flags const char *dev_name, // IN: device mounting on void *rawData) // IN: mount arguments { return mount_nodev(fs_type, flags, rawData, FsOpReadSuper); } #elif defined(VMW_GETSB_2618) /* *----------------------------------------------------------------------------- * * FsOpGetSb -- * * Invokes generic kernel code to prepare superblock for * deviceless filesystem. * * Results: * 0 on success * negative error code on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ static int FsOpGetSb(struct file_system_type *fs_type, // IN: file system type of mount int flags, // IN: mount flags const char *dev_name, // IN: device mounting on void *rawData, // IN: mount arguments struct vfsmount *mnt) // IN: vfs mount { return get_sb_nodev(fs_type, flags, rawData, FsOpReadSuper, mnt); } #else /* *----------------------------------------------------------------------------- * * FsOpGetSb -- * * Invokes generic kernel code to prepare superblock for * deviceless filesystem. * * Results: * The initialized superblock on success * NULL on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ static struct super_block * FsOpGetSb(struct file_system_type *fs_type, // IN: file system type of mount int flags, // IN: mount flags const char *dev_name, // IN: device mounting on void *rawData) // IN: mount arguments { return get_sb_nodev(fs_type, flags, rawData, FsOpReadSuper); } #endif open-vm-tools-9.4.0-1280544/modules/linux/vmblock/linux/inode.c0000644765153500003110000001432312220061556022307 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * inode.c -- * * Inode operations for the file system of the vmblock driver. * */ #include "driver-config.h" #include #include #include #include #include "vmblockInt.h" #include "filesystem.h" #include "block.h" /* Inode operations */ static struct dentry *InodeOpLookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd); static int InodeOpReadlink(struct dentry *dentry, char __user *buffer, int buflen); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) static void *InodeOpFollowlink(struct dentry *dentry, struct nameidata *nd); #else static int InodeOpFollowlink(struct dentry *dentry, struct nameidata *nd); #endif struct inode_operations RootInodeOps = { .lookup = InodeOpLookup, }; static struct inode_operations LinkInodeOps = { .readlink = InodeOpReadlink, .follow_link = InodeOpFollowlink, }; /* *---------------------------------------------------------------------------- * * InodeOpLookup -- * * Looks up a name (dentry) in provided directory. Invoked every time * a directory entry is traversed in path lookups. * * Results: * NULL on success, negative error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static struct dentry * InodeOpLookup(struct inode *dir, // IN: parent directory's inode struct dentry *dentry, // IN: dentry to lookup struct nameidata *nd) // IN: lookup intent and information { char *filename; struct inode *inode; int ret; if (!dir || !dentry) { Warning("InodeOpLookup: invalid args from kernel\n"); return ERR_PTR(-EINVAL); } /* The kernel should only pass us our own inodes, but check just to be safe. */ if (!INODE_TO_IINFO(dir)) { Warning("InodeOpLookup: invalid inode provided\n"); return ERR_PTR(-EINVAL); } /* Get a slab from the kernel's names_cache of PATH_MAX-sized buffers. */ filename = __getname(); if (!filename) { Warning("InodeOpLookup: unable to obtain memory for filename.\n"); return ERR_PTR(-ENOMEM); } ret = MakeFullName(dir, dentry, filename, PATH_MAX); if (ret < 0) { Warning("InodeOpLookup: could not construct full name\n"); __putname(filename); return ERR_PTR(ret); } /* Block if there is a pending block on this file */ BlockWaitOnFile(filename, NULL); __putname(filename); inode = Iget(dir->i_sb, dir, dentry, GetNextIno()); if (!inode) { Warning("InodeOpLookup: failed to get inode\n"); return ERR_PTR(-ENOMEM); } dentry->d_op = &LinkDentryOps; dentry->d_time = jiffies; /* * If the actual file's dentry doesn't have an inode, it means the file we * are redirecting to doesn't exist. Give back the inode that was created * for this and add a NULL dentry->inode entry in the dcache. (The NULL * entry is added so ops to create files/directories are invoked by VFS.) */ if (!INODE_TO_ACTUALDENTRY(inode) || !INODE_TO_ACTUALINODE(inode)) { iput(inode); d_add(dentry, NULL); return NULL; } inode->i_mode = S_IFLNK | S_IRWXUGO; inode->i_size = INODE_TO_IINFO(inode)->nameLen; inode->i_version = 1; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; inode->i_uid = inode->i_gid = 0; inode->i_op = &LinkInodeOps; d_add(dentry, inode); return NULL; } /* *---------------------------------------------------------------------------- * * InodeOpReadlink -- * * Provides the symbolic link's contents to the user. Invoked when * readlink(2) is invoked on our symlinks. * * Results: * 0 on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int InodeOpReadlink(struct dentry *dentry, // IN : dentry of symlink char __user *buffer, // OUT: output buffer (user space) int buflen) // IN : length of output buffer { VMBlockInodeInfo *iinfo; if (!dentry || !buffer) { Warning("InodeOpReadlink: invalid args from kernel\n"); return -EINVAL; } iinfo = INODE_TO_IINFO(dentry->d_inode); if (!iinfo) { return -EINVAL; } return vfs_readlink(dentry, buffer, buflen, iinfo->name); } /* *---------------------------------------------------------------------------- * * InodeOpFollowlink -- * * Provides the inode corresponding to this symlink through the nameidata * structure. * * Results: * 0 on success, negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) static void * #else static int #endif InodeOpFollowlink(struct dentry *dentry, // IN : dentry of symlink struct nameidata *nd) // OUT: stores result { int ret; VMBlockInodeInfo *iinfo; if (!dentry) { Warning("InodeOpReadlink: invalid args from kernel\n"); ret = -EINVAL; goto out; } iinfo = INODE_TO_IINFO(dentry->d_inode); if (!iinfo) { ret = -EINVAL; goto out; } ret = vfs_follow_link(nd, iinfo->name); out: #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) return ERR_PTR(ret); #else return ret; #endif } open-vm-tools-9.4.0-1280544/modules/linux/vmblock/linux/os.h0000644765153500003110000000743112220061556021641 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * os.h -- * * OS-specific definitions. */ #ifndef __OS_H__ #define __OS_H__ #include "driver-config.h" #include #include #include "compat_slab.h" #include #include #include #include typedef rwlock_t os_rwlock_t; typedef compat_kmem_cache os_kmem_cache_t; typedef struct completion os_completion_t; typedef atomic_t os_atomic_t; typedef struct file * os_blocker_id_t; #define OS_UNKNOWN_BLOCKER NULL #define OS_ENOMEM (-ENOMEM) #define OS_ENOENT (-ENOENT) #define OS_EEXIST (-EEXIST) #define OS_PATH_MAX PATH_MAX #define OS_FMTTID "d" #define os_threadid (current->pid) #define os_panic(fmt, args) \ ({ \ vprintk(fmt, args); \ BUG(); \ }) #define os_rwlock_init(lock) rwlock_init(lock) #define os_rwlock_destroy(lock) /* * XXX We'd like to check for kernel version 2.5.34 as the patches indicate, * but SLES10's 2.6.16.21-0.8-i586default doesn't seem to have this defined. */ #if defined(rwlock_is_locked) # define os_rwlock_held(lock) rwlock_is_locked(lock) #else /* XXX Is there something we can come up with for this? */ # define os_rwlock_held(lock) TRUE #endif #define os_read_lock(lock) read_lock(lock) #define os_write_lock(lock) write_lock(lock) #define os_read_unlock(lock) read_unlock(lock) #define os_write_unlock(lock) write_unlock(lock) #define os_kmem_cache_create(name, size, align, ctor) \ compat_kmem_cache_create(name, size, align, SLAB_HWCACHE_ALIGN, ctor) #define os_kmem_cache_destroy(cache) kmem_cache_destroy(cache) #define os_kmem_cache_alloc(cache) kmem_cache_alloc(cache, GFP_KERNEL) #define os_kmem_cache_free(cache, elem) kmem_cache_free(cache, elem) #define os_completion_init(comp) init_completion(comp) #define os_completion_destroy(comp) /* * XXX This should be made interruptible using * wait_for_completion_interruptible(), and return a proper value. Callers * would need to handle interruption, of course. */ #define os_wait_for_completion(comp) \ ({ \ wait_for_completion(comp); \ 0; \ }) #define os_complete_all(comp) complete_all(comp) #define os_atomic_dec_and_test(atomic) atomic_dec_and_test(atomic) #define os_atomic_dec(atomic) atomic_dec(atomic) #define os_atomic_set(atomic, val) atomic_set(atomic, val) #define os_atomic_inc(atomic) atomic_inc(atomic) #define os_atomic_read(atomic) atomic_read(atomic) #endif /* __OS_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/vmblock/Makefile.kernel0000644765153500003110000000452512220061556022630 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 2006 VMware, Inc. All rights reserved. # # 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 version 2 and no later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ########################################################## INCLUDE += -I$(SRCROOT)/include EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE) EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/cachecreate.c, -DVMW_KMEMCR_HAS_DTOR, ) EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/cachector.c, -DVMW_KMEMCR_CTOR_HAS_3_ARGS, ) EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/cachector1.c, -DVMW_KMEMCR_CTOR_HAS_2_ARGS, ) # Note: These tests are inverted. EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/getsb1.c, , -DVMW_GETSB_2618) EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/statfs1.c, , -DVMW_STATFS_2618) EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/filldir1.c, , -DVMW_FILLDIR_2618) obj-m += $(DRIVER).o $(DRIVER)-y := $(subst $(SRCROOT)/, , $(patsubst %.c, %.o, $(wildcard $(SRCROOT)/linux/*.c))) # # In open-vm-tools, need to compile the common sources from the shared directories. # ifdef OVT_SOURCE_DIR VMBLOCK_PATH := $(shell cd $(SRCROOT) && pwd) VMBLOCK_SHARED_PATH := $(OVT_SOURCE_DIR)/modules/shared/vmblock VMBLOCK_SHARED := block.o VMBLOCK_SHARED += stubs.o EXTRA_CFLAGS += -I$(VMBLOCK_PATH)/linux EXTRA_CFLAGS += -I$(VMBLOCK_SHARED_PATH) $(addprefix $(VMBLOCK_PATH)/,$(VMBLOCK_SHARED)): $(VMBLOCK_PATH)/%.o: $(VMBLOCK_SHARED_PATH)/%.c $(Q)$(rule_cc_o_c) $(DRIVER)-y += $(VMBLOCK_SHARED) endif clean: rm -rf $(wildcard $(DRIVER).mod.c $(DRIVER).ko .tmp_versions \ Module.symvers Modules.symvers Module.markers modules.order \ $(foreach dir,./ linux/,$(addprefix $(dir),.*.cmd .*.o.flags *.o))) open-vm-tools-9.4.0-1280544/modules/linux/vmblock/README0000644765153500003110000000074112220061556020565 0ustar dtormtsThis files in this directory and its subdirectories are the kernel module for the VMware Blocking File System. In order to build, make certain the Makefile is correct and then just type make from this directory. A copy of the module will be left in driver-/vmblock.o (e.g. driver-up-2.4.20/vmblock.o) for 2.4 series kernels and in ../vmblock.o for 2.6 series kernels. If you have any problems or questions, send mail to support@vmware.com open-vm-tools-9.4.0-1280544/modules/linux/vmblock/COPYING0000644765153500003110000004310312220061556020737 0ustar dtormts GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. open-vm-tools-9.4.0-1280544/modules/linux/vmblock/Makefile0000644765153500003110000001054212220061556021345 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 1998 VMware, Inc. All rights reserved. # # 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 version 2 and no later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ########################################################## #### #### VMware kernel module Makefile to be distributed externally #### #### #### SRCROOT _must_ be a relative path. #### SRCROOT = . # # open-vm-tools doesn't replicate shared source files for different modules; # instead, files are kept in shared locations. So define a few useful macros # to be able to handle both cases cleanly. # INCLUDE := ifdef OVT_SOURCE_DIR AUTOCONF_DIR := $(OVT_SOURCE_DIR)/modules/linux/shared/autoconf VMLIB_PATH = $(OVT_SOURCE_DIR)/lib/$(1) INCLUDE += -I$(OVT_SOURCE_DIR)/modules/linux/shared INCLUDE += -I$(OVT_SOURCE_DIR)/lib/include else AUTOCONF_DIR := $(SRCROOT)/shared/autoconf INCLUDE += -I$(SRCROOT)/shared endif VM_UNAME = $(shell uname -r) # Header directory for the running kernel ifdef LINUXINCLUDE HEADER_DIR = $(LINUXINCLUDE) else HEADER_DIR = /lib/modules/$(VM_UNAME)/build/include endif BUILD_DIR = $(HEADER_DIR)/.. DRIVER := vmblock PRODUCT := tools-source # Grep program GREP = /bin/grep vm_check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null \ > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) vm_check_file = $(shell if test -f $(1); then echo "yes"; else echo "no"; fi) ifndef VM_KBUILD VM_KBUILD := no ifeq ($(call vm_check_file,$(BUILD_DIR)/Makefile), yes) ifneq ($(call vm_check_file,$(BUILD_DIR)/Rules.make), yes) VM_KBUILD := 26 endif endif export VM_KBUILD endif ifndef VM_KBUILD_SHOWN ifeq ($(VM_KBUILD), no) VM_DUMMY := $(shell echo >&2 "Using standalone build system.") else ifeq ($(VM_KBUILD), 24) VM_DUMMY := $(shell echo >&2 "Using 2.4.x kernel build system.") else VM_DUMMY := $(shell echo >&2 "Using 2.6.x kernel build system.") endif endif VM_KBUILD_SHOWN := yes export VM_KBUILD_SHOWN endif ifneq ($(VM_KBUILD), no) VMCCVER := $(shell $(CC) -dumpversion) # If there is no version defined, we are in toplevel pass, not yet in kernel makefiles... ifeq ($(VERSION),) ifeq ($(VM_KBUILD), 24) DRIVER_KO := $(DRIVER).o else DRIVER_KO := $(DRIVER).ko endif .PHONY: $(DRIVER_KO) auto-build: $(DRIVER_KO) cp -f $< $(SRCROOT)/../$(DRIVER).o # $(DRIVER_KO) is a phony target, so compare file times explicitly $(DRIVER): $(DRIVER_KO) if [ $< -nt $@ ] || [ ! -e $@ ] ; then cp -f $< $@; fi # Pass gcc version down the chain, so we can detect if kernel attempts to use unapproved compiler VM_CCVER := $(VMCCVER) export VM_CCVER VM_CC := $(CC) export VM_CC MAKEOVERRIDES := $(filter-out CC=%,$(MAKEOVERRIDES)) # # Define a setup target that gets built before the actual driver. # This target may not be used at all, but if it is then it will be defined # in Makefile.kernel # prebuild:: ; postbuild:: ; $(DRIVER_KO): prebuild $(MAKE) -C $(BUILD_DIR) SUBDIRS=$$PWD SRCROOT=$$PWD/$(SRCROOT) \ MODULEBUILDDIR=$(MODULEBUILDDIR) modules $(MAKE) -C $$PWD SRCROOT=$$PWD/$(SRCROOT) \ MODULEBUILDDIR=$(MODULEBUILDDIR) postbuild endif vm_check_build = $(shell if $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ $(CPPFLAGS) $(CFLAGS) $(CFLAGS_KERNEL) $(LINUXINCLUDE) \ $(EXTRA_CFLAGS) -Iinclude2/asm/mach-default \ -DKBUILD_BASENAME=\"$(DRIVER)\" \ -Werror -S -o /dev/null -xc $(1) \ > /dev/null 2>&1; then echo "$(2)"; else echo "$(3)"; fi) CC_WARNINGS := -Wall -Wstrict-prototypes CC_OPTS := $(GLOBAL_DEFS) $(CC_WARNINGS) -DVMW_USING_KBUILD ifdef VMX86_DEVEL CC_OPTS += -DVMX86_DEVEL endif ifdef VMX86_DEBUG CC_OPTS += -DVMX86_DEBUG endif include $(SRCROOT)/Makefile.kernel ifdef TOPDIR ifeq ($(VM_KBUILD), 24) O_TARGET := $(DRIVER).o obj-y := $($(DRIVER)-y) include $(TOPDIR)/Rules.make endif endif else include $(SRCROOT)/Makefile.normal endif #.SILENT: open-vm-tools-9.4.0-1280544/modules/linux/vmci/0000755765153500003110000000000012220061556017204 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/linux/vmci/Makefile.normal0000644765153500003110000001062012220061556022132 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 2007 VMware, Inc. All rights reserved. # # 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 version 2 and no later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ########################################################## vm_check_build = $(shell if $(CC) $(CC_OPTS) $(INCLUDE) -Werror -S -o /dev/null -xc $(1) \ > /dev/null 2>&1; then echo "$(2)"; else echo "$(3)"; fi) #### #### DESTDIR is where the module, object files, and dependencies are built #### DESTDIR := driver-$(VM_UNAME) #### #### DRIVERNAME should be untouched unless you have a good reason to change #### it. The form below is how the scripts expect it. #### DRIVERNAME := $(DRIVER)-xxx-$(VM_UNAME) ifneq (,$(filter x86_64%, $(shell $(CC) -dumpmachine))) MACHINE := x86_64 else MACHINE := x386 endif ifdef QUIET ECHO := @true else ECHO := @echo endif #### #### You must compile with at least -O level of optimization #### or the module won't load. #### If desparate, I think that bringing in might #### suffice. #### CC_WARNINGS := -Wall -Wstrict-prototypes # Don't use -pipe or egcs-2.91.66 (shipped with RedHat) will die CC_KFLAGS := -D__KERNEL__ -fno-strength-reduce -fno-omit-frame-pointer \ -fno-common -DKBUILD_MODNAME=\"$(DRIVER)\" CC_KFLAGS += $(call vm_check_gcc,-falign-loops=2 -falign-jumps=2 -falign-functions=2, \ -malign-loops=2 -malign-jumps=2 -malign-functions=2) CC_KFLAGS += $(call vm_check_gcc,-fno-strict-aliasing,) ifeq ($(MACHINE),x86_64) CC_KFLAGS += -mno-red-zone -mcmodel=kernel else # Gcc 3.0 deprecates -m486 --hpreg CC_KFLAGS += -DCPU=586 $(call check_gcc,-march=i586,-m486) endif CC_OPTS := -O2 -DMODULE -DVMCI $(GLOBAL_DEFS) $(CC_KFLAGS) $(CC_WARNINGS) INCLUDE := -I$(SRCROOT)/shared -I$(SRCROOT)/common -I$(SRCROOT)/linux \ -I$(HEADER_DIR) INCLUDE += $(shell $(CC) $(INCLUDE) -E $(SRCROOT)/shared/autoconf/geninclude.c \ | sed -n -e 's!^APATH!-I$(HEADER_DIR)/asm!p') ifdef OVT_SOURCE_PATH DRIVERLOGPATH := $(OVT_SOURCE_DIR)/modules/linux/shared else DRIVERLOGPATH := $(SRCROOT)/shared endif C_TARGETS_LINUX := driver.o vmciKernelIf.o C_TARGETS_COMMON := vmciContext.o vmciDatagram.o vmciDriver.o \ vmciHashtable.o vmciResource.o \ vmciQueuePair.o vmciPageChannel.o \ vmciEvent.o vmciRoute.o C_TARGETS_LINUX_D := ${C_TARGETS_LINUX:.o=.d} C_TARGETS_COMMON_D := ${C_TARGETS_COMMON:.o=.d} C_TARGETS := $(C_TARGETS_LINUX) $(C_TARGETS_COMMON) driverLog.o #### #### Make Targets are beneath here. #### driver: setup deps $(MAKE) -C $(DESTDIR) -f ../Makefile SRCROOT=../$(SRCROOT) $(DRIVER).o \ INCLUDE_DEPS=1 setup: @if [ -d $(DESTDIR) ] ; then true ; else mkdir $(DESTDIR); chmod 755 $(DESTDIR) ; fi $(DRIVER) $(DRIVER).o: $(DRIVERNAME) cp -f $< $@ $(DRIVERNAME): $(C_TARGETS) $(ECHO) "Building $(DRIVERNAME)" ld -r -o $(DRIVERNAME) $(C_TARGETS) auto-build: $(MAKE) driver QUIET=1 cp -f $(DESTDIR)/$(DRIVERNAME) $(SRCROOT)/../$(DRIVER).o $(C_TARGETS_LINUX): %.o: $(SRCROOT)/linux/%.c $(ECHO) "Compiling linux/$( $@ $(C_TARGETS_LINUX_D): %.d: $(SRCROOT)/linux/%.c $(ECHO) "Dependencies for $( $@ driverLog.d: $(DRIVERLOGPATH)/driverLog.c $(ECHO) "Dependencies for $( $@ deps: setup $(MAKE) -C $(DESTDIR) -f ../Makefile SRCROOT=../$(SRCROOT) driver_deps driver_deps: ${C_TARGETS:.o=.d} ifdef INCLUDE_DEPS include ${C_TARGETS:.o=.d} endif .SILENT: open-vm-tools-9.4.0-1280544/modules/linux/vmci/linux/0000755765153500003110000000000012220061556020343 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/linux/vmci/linux/driver.c0000644765153500003110000021277012220061556022013 0ustar dtormts/********************************************************* * Copyright (C) 2011 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* Must come before any kernel header file */ #include "driver-config.h" #define EXPORT_SYMTAB #include #include #include #include #include #if defined(__x86_64__) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12) # include /* Use weak: not all kernels export sys_ioctl for use by modules */ asmlinkage __attribute__((weak)) long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); #endif #include #include #include #include #include "compat_highmem.h" #include "compat_interrupt.h" #include "compat_ioport.h" #include "compat_kernel.h" #include "compat_mm.h" #include "compat_module.h" #include "compat_mutex.h" #include "compat_page.h" #include "compat_pci.h" #include "compat_sched.h" #include "compat_slab.h" #include "compat_uaccess.h" #include "compat_version.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9) # error "Linux kernels before 2.6.9 are not supported." #endif #include "vm_basic_types.h" #include "vm_device_version.h" #include "vmware.h" #include "driverLog.h" #include "pgtbl.h" #include "vmci_defs.h" #include "vmci_handle_array.h" #include "vmci_infrastructure.h" #include "vmci_iocontrols.h" #include "vmci_version.h" #include "vmci_kernel_if.h" #include "vmciCommonInt.h" #include "vmciContext.h" #include "vmciDatagram.h" #include "vmciDoorbell.h" #include "vmciDriver.h" #include "vmciEvent.h" #include "vmciKernelAPI.h" #include "vmciQueuePair.h" #include "vmciResource.h" #define LGPFX "VMCI: " #define VMCI_DEVICE_NAME "vmci" #define VMCI_MODULE_NAME "vmci" /* *---------------------------------------------------------------------- * * PCI Device interface -- * * Declarations of types and functions related to the VMCI PCI * device personality. * * *---------------------------------------------------------------------- */ /* * VMCI PCI driver state */ typedef struct vmci_device { compat_mutex_t lock; unsigned int ioaddr; unsigned int ioaddr_size; unsigned int irq; unsigned int intr_type; Bool exclusive_vectors; struct msix_entry msix_entries[VMCI_MAX_INTRS]; Bool enabled; spinlock_t dev_spinlock; atomic_t datagrams_allowed; } vmci_device; static const struct pci_device_id vmci_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_VMWARE, PCI_DEVICE_ID_VMWARE_VMCI), }, { 0 }, }; static int vmci_probe_device(struct pci_dev *pdev, const struct pci_device_id *id); static void vmci_remove_device(struct pci_dev* pdev); static struct pci_driver vmci_driver = { .name = VMCI_DEVICE_NAME, .id_table = vmci_ids, .probe = vmci_probe_device, .remove = vmci_remove_device, }; #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) static compat_irqreturn_t vmci_interrupt(int irq, void *dev_id, struct pt_regs * regs); static compat_irqreturn_t vmci_interrupt_bm(int irq, void *dev_id, struct pt_regs * regs); #else static compat_irqreturn_t vmci_interrupt(int irq, void *dev_id); static compat_irqreturn_t vmci_interrupt_bm(int irq, void *dev_id); #endif static void dispatch_datagrams(unsigned long data); static void process_bitmap(unsigned long data); /* MSI-X has performance problems in < 2.6.19 */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) # define VMCI_DISABLE_MSIX 0 #else # define VMCI_DISABLE_MSIX 1 #endif /* * Linux kernel < 2.6.31 takes 'int' for 'bool' module parameters. * Linux kernel >= 3.3.0 takes 'bool' for 'bool' module parameters. * Kernels between the two take either. So flip switch at 3.0.0. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) typedef bool compat_bool; #else typedef int compat_bool; #endif static vmci_device vmci_dev; static compat_bool vmci_disable_host = 0; static compat_bool vmci_disable_guest = 0; static compat_bool vmci_disable_msi; static compat_bool vmci_disable_msix = VMCI_DISABLE_MSIX; DECLARE_TASKLET(vmci_dg_tasklet, dispatch_datagrams, (unsigned long)&vmci_dev); DECLARE_TASKLET(vmci_bm_tasklet, process_bitmap, (unsigned long)&vmci_dev); /* * Allocate a buffer for incoming datagrams globally to avoid repeated * allocation in the interrupt handler's atomic context. */ static uint8 *data_buffer = NULL; static uint32 data_buffer_size = VMCI_MAX_DG_SIZE; /* * If the VMCI hardware supports the notification bitmap, we allocate * and register a page with the device. */ static uint8 *notification_bitmap = NULL; /* *---------------------------------------------------------------------- * * Host device node interface -- * * Implements VMCI by implementing open/close/ioctl functions * * *---------------------------------------------------------------------- */ /* * Per-instance host state */ typedef struct VMCILinux { VMCIContext *context; int userVersion; VMCIObjType ctType; #if defined(HAVE_COMPAT_IOCTL) || defined(HAVE_UNLOCKED_IOCTL) compat_mutex_t lock; #endif } VMCILinux; /* * Static driver state. */ #define VM_DEVICE_NAME_SIZE 32 #define LINUXLOG_BUFFER_SIZE 1024 typedef struct VMCILinuxState { struct miscdevice misc; char buf[LINUXLOG_BUFFER_SIZE]; atomic_t activeContexts; } VMCILinuxState; static int VMCISetupNotify(VMCIContext *context, VA notifyUVA); static void VMCIUnsetNotifyInt(VMCIContext *context, Bool useLock); static int LinuxDriver_Open(struct inode *inode, struct file *filp); static int LinuxDriver_Ioctl(struct inode *inode, struct file *filp, u_int iocmd, unsigned long ioarg); #if defined(HAVE_COMPAT_IOCTL) || defined(HAVE_UNLOCKED_IOCTL) static long LinuxDriver_UnlockedIoctl(struct file *filp, u_int iocmd, unsigned long ioarg); #endif static int LinuxDriver_Close(struct inode *inode, struct file *filp); static unsigned int LinuxDriverPoll(struct file *file, poll_table *wait); #if defined(HAVE_COMPAT_IOCTL) || defined(HAVE_UNLOCKED_IOCTL) #define LinuxDriverLockIoctlPerFD(mutex) compat_mutex_lock(mutex) #define LinuxDriverUnlockIoctlPerFD(mutex) compat_mutex_unlock(mutex) #else #define LinuxDriverLockIoctlPerFD(mutex) do {} while (0) #define LinuxDriverUnlockIoctlPerFD(mutex) do {} while (0) #endif /* should be const if not for older kernels support */ static struct file_operations vmuser_fops = { .owner = THIS_MODULE, .open = LinuxDriver_Open, .release = LinuxDriver_Close, .poll = LinuxDriverPoll, #ifdef HAVE_UNLOCKED_IOCTL .unlocked_ioctl = LinuxDriver_UnlockedIoctl, #else .ioctl = LinuxDriver_Ioctl, #endif #ifdef HAVE_COMPAT_IOCTL .compat_ioctl = LinuxDriver_UnlockedIoctl, #endif }; static struct VMCILinuxState linuxState = { .misc = { .name = VMCI_DEVICE_NAME, .minor = MISC_DYNAMIC_MINOR, .fops = &vmuser_fops, }, .activeContexts = ATOMIC_INIT(0), }; /* *---------------------------------------------------------------------- * * Shared VMCI device definitions -- * * Types and variables shared by both host and guest personality * * *---------------------------------------------------------------------- */ static Bool guestDeviceInit; static atomic_t guestDeviceActive; static Bool hostDeviceInit; /* *----------------------------------------------------------------------------- * * Host device support -- * * The following functions implement the support for the VMCI * host driver. * * *----------------------------------------------------------------------------- */ #ifdef VM_X86_64 #ifndef HAVE_COMPAT_IOCTL static int LinuxDriver_Ioctl32_Handler(unsigned int fd, unsigned int iocmd, unsigned long ioarg, struct file * filp) { int ret; ret = -ENOTTY; if (filp && filp->f_op && filp->f_op->ioctl == LinuxDriver_Ioctl) { ret = LinuxDriver_Ioctl(filp->f_dentry->d_inode, filp, iocmd, ioarg); } return ret; } #endif /* !HAVE_COMPAT_IOCTL */ static int register_ioctl32_handlers(void) { #ifndef HAVE_COMPAT_IOCTL { int i; for (i = IOCTL_VMCI_FIRST; i < IOCTL_VMCI_LAST; i++) { int retval = register_ioctl32_conversion(i, LinuxDriver_Ioctl32_Handler); if (retval) { Warning(LGPFX"Failed to register ioctl32 conversion " "(cmd=%d,err=%d).\n", i, retval); return retval; } } for (i = IOCTL_VMCI_FIRST2; i < IOCTL_VMCI_LAST2; i++) { int retval = register_ioctl32_conversion(i, LinuxDriver_Ioctl32_Handler); if (retval) { Warning(LGPFX"Failed to register ioctl32 conversion " "(cmd=%d,err=%d).\n", i, retval); return retval; } } } #endif /* !HAVE_COMPAT_IOCTL */ return 0; } static void unregister_ioctl32_handlers(void) { #ifndef HAVE_COMPAT_IOCTL { int i; for (i = IOCTL_VMCI_FIRST; i < IOCTL_VMCI_LAST; i++) { int retval = unregister_ioctl32_conversion(i); if (retval) { Warning(LGPFX"Failed to unregister ioctl32 conversion " "(cmd=%d,err=%d).\n", i, retval); } } for (i = IOCTL_VMCI_FIRST2; i < IOCTL_VMCI_LAST2; i++) { int retval = unregister_ioctl32_conversion(i); if (retval) { Warning(LGPFX"Failed to unregister ioctl32 conversion " "(cmd=%d,err=%d).\n", i, retval); } } } #endif /* !HAVE_COMPAT_IOCTL */ } #else /* VM_X86_64 */ #define register_ioctl32_handlers() (0) #define unregister_ioctl32_handlers() do { } while (0) #endif /* VM_X86_64 */ /* *----------------------------------------------------------------------------- * * vmci_host_init -- * * Initializes the VMCI host device driver. * * Results: * 0 on success, other error codes on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int vmci_host_init(void) { int error; if (VMCI_HostInit() < VMCI_SUCCESS) { return -ENOMEM; } error = misc_register(&linuxState.misc); if (error) { Warning(LGPFX "Module registration error " "(name=%s, major=%d, minor=%d, err=%d).\n", linuxState.misc.name, MISC_MAJOR, linuxState.misc.minor, error); goto err_host_cleanup; } error = register_ioctl32_handlers(); if (error) { Warning(LGPFX "Failed to register ioctl32 handlers, err: %d\n", error); goto err_misc_unregister; } Log(LGPFX "Module registered (name=%s, major=%d, minor=%d).\n", linuxState.misc.name, MISC_MAJOR, linuxState.misc.minor); return 0; err_misc_unregister: misc_deregister(&linuxState.misc); err_host_cleanup: VMCI_HostCleanup(); return error; } /* *---------------------------------------------------------------------- * * LinuxDriver_Open -- * * Called on open of /dev/vmci. * * Side effects: * Increment use count used to determine eventual deallocation of * the module * *---------------------------------------------------------------------- */ static int LinuxDriver_Open(struct inode *inode, // IN struct file *filp) // IN { VMCILinux *vmciLinux; vmciLinux = kmalloc(sizeof *vmciLinux, GFP_KERNEL); if (vmciLinux == NULL) { return -ENOMEM; } memset(vmciLinux, 0, sizeof *vmciLinux); vmciLinux->ctType = VMCIOBJ_NOT_SET; vmciLinux->userVersion = 0; #if defined(HAVE_COMPAT_IOCTL) || defined(HAVE_UNLOCKED_IOCTL) compat_mutex_init(&vmciLinux->lock); #endif filp->private_data = vmciLinux; return 0; } /* *---------------------------------------------------------------------- * * LinuxDriver_Close -- * * Called on close of /dev/vmci, most often when the process * exits. * *---------------------------------------------------------------------- */ static int LinuxDriver_Close(struct inode *inode, // IN struct file *filp) // IN { VMCILinux *vmciLinux; vmciLinux = (VMCILinux *)filp->private_data; ASSERT(vmciLinux); if (vmciLinux->ctType == VMCIOBJ_CONTEXT) { ASSERT(vmciLinux->context); VMCIContext_ReleaseContext(vmciLinux->context); vmciLinux->context = NULL; /* * The number of active contexts is used to track whether any * VMX'en are using the host personality. It is incremented when * a context is created through the IOCTL_VMCI_INIT_CONTEXT * ioctl. */ atomic_dec(&linuxState.activeContexts); } vmciLinux->ctType = VMCIOBJ_NOT_SET; kfree(vmciLinux); filp->private_data = NULL; return 0; } /* *---------------------------------------------------------------------- * * LinuxDriverPoll -- * * This is used to wake up the VMX when a VMCI call arrives, or * to wake up select() or poll() at the next clock tick. * *---------------------------------------------------------------------- */ static unsigned int LinuxDriverPoll(struct file *filp, poll_table *wait) { VMCILockFlags flags; VMCILinux *vmciLinux = (VMCILinux *) filp->private_data; unsigned int mask = 0; if (vmciLinux->ctType == VMCIOBJ_CONTEXT) { ASSERT(vmciLinux->context != NULL); /* * Check for VMCI calls to this VM context. */ if (wait != NULL) { poll_wait(filp, &vmciLinux->context->hostContext.waitQueue, wait); } VMCI_GrabLock(&vmciLinux->context->lock, &flags); if (vmciLinux->context->pendingDatagrams > 0 || VMCIHandleArray_GetSize(vmciLinux->context->pendingDoorbellArray) > 0) { mask = POLLIN; } VMCI_ReleaseLock(&vmciLinux->context->lock, flags); } return mask; } /* *---------------------------------------------------------------------- * * VMCICopyHandleArrayToUser -- * * Copies the handles of a handle array into a user buffer, and * returns the new length in userBufferSize. If the copy to the * user buffer fails, the functions still returns VMCI_SUCCESS, * but retval != 0. * *---------------------------------------------------------------------- */ static int VMCICopyHandleArrayToUser(void *userBufUVA, // IN uint64 *userBufSize, // IN/OUT VMCIHandleArray *handleArray, // IN int *retval) // IN { uint32 arraySize; VMCIHandle *handles; if (handleArray) { arraySize = VMCIHandleArray_GetSize(handleArray); } else { arraySize = 0; } if (arraySize * sizeof *handles > *userBufSize) { return VMCI_ERROR_MORE_DATA; } *userBufSize = arraySize * sizeof *handles; if (*userBufSize) { *retval = copy_to_user(userBufUVA, VMCIHandleArray_GetHandles(handleArray), *userBufSize); } return VMCI_SUCCESS; } /* *----------------------------------------------------------------------------- * * VMCIDoQPBrokerAlloc -- * * Helper function for creating queue pair and copying the result * to user memory. * * Results: * 0 if result value was copied to user memory, -EFAULT otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int VMCIDoQPBrokerAlloc(VMCIHandle handle, VMCIId peer, uint32 flags, uint64 produceSize, uint64 consumeSize, QueuePairPageStore *pageStore, VMCIContext *context, Bool vmToVm, void *resultUVA) { VMCIId cid; int result; int retval; cid = VMCIContext_GetId(context); result = VMCIQPBroker_Alloc(handle, peer, flags, VMCI_NO_PRIVILEGE_FLAGS, produceSize, consumeSize, pageStore, context); if (result == VMCI_SUCCESS && vmToVm) { result = VMCI_SUCCESS_QUEUEPAIR_CREATE; } retval = copy_to_user(resultUVA, &result, sizeof result); if (retval) { retval = -EFAULT; if (result >= VMCI_SUCCESS) { result = VMCIQPBroker_Detach(handle, context); ASSERT(result >= VMCI_SUCCESS); } } return retval; } /* *----------------------------------------------------------------------------- * * LinuxDriver_Ioctl -- * * Main path for UserRPC * * Results: * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int LinuxDriver_Ioctl(struct inode *inode, struct file *filp, u_int iocmd, unsigned long ioarg) { VMCILinux *vmciLinux = (VMCILinux *) filp->private_data; int retval = 0; switch (iocmd) { case IOCTL_VMCI_VERSION2: { int verFromUser; if (copy_from_user(&verFromUser, (void *)ioarg, sizeof verFromUser)) { retval = -EFAULT; break; } vmciLinux->userVersion = verFromUser; } /* Fall through. */ case IOCTL_VMCI_VERSION: /* * The basic logic here is: * * If the user sends in a version of 0 tell it our version. * If the user didn't send in a version, tell it our version. * If the user sent in an old version, tell it -its- version. * If the user sent in an newer version, tell it our version. * * The rationale behind telling the caller its version is that * Workstation 6.5 required that VMX and VMCI kernel module were * version sync'd. All new VMX users will be programmed to * handle the VMCI kernel module version. */ if (vmciLinux->userVersion > 0 && vmciLinux->userVersion < VMCI_VERSION_HOSTQP) { retval = vmciLinux->userVersion; } else { retval = VMCI_VERSION; } break; case IOCTL_VMCI_INIT_CONTEXT: { VMCIInitBlock initBlock; VMCIHostUser user; retval = copy_from_user(&initBlock, (void *)ioarg, sizeof initBlock); if (retval != 0) { Log(LGPFX"Error reading init block.\n"); retval = -EFAULT; break; } LinuxDriverLockIoctlPerFD(&vmciLinux->lock); if (vmciLinux->ctType != VMCIOBJ_NOT_SET) { Log(LGPFX"Received VMCI init on initialized handle.\n"); retval = -EINVAL; goto init_release; } if (initBlock.flags & ~VMCI_PRIVILEGE_FLAG_RESTRICTED) { Log(LGPFX"Unsupported VMCI restriction flag.\n"); retval = -EINVAL; goto init_release; } user = current_uid(); retval = VMCIContext_InitContext(initBlock.cid, initBlock.flags, 0 /* Unused */, vmciLinux->userVersion, &user, &vmciLinux->context); if (retval < VMCI_SUCCESS) { Log(LGPFX"Error initializing context.\n"); retval = retval == VMCI_ERROR_DUPLICATE_ENTRY ? -EEXIST : -EINVAL; goto init_release; } /* * Copy cid to userlevel, we do this to allow the VMX to enforce its * policy on cid generation. */ initBlock.cid = VMCIContext_GetId(vmciLinux->context); retval = copy_to_user((void *)ioarg, &initBlock, sizeof initBlock); if (retval != 0) { VMCIContext_ReleaseContext(vmciLinux->context); vmciLinux->context = NULL; Log(LGPFX"Error writing init block.\n"); retval = -EFAULT; goto init_release; } ASSERT(initBlock.cid != VMCI_INVALID_ID); vmciLinux->ctType = VMCIOBJ_CONTEXT; atomic_inc(&linuxState.activeContexts); init_release: LinuxDriverUnlockIoctlPerFD(&vmciLinux->lock); break; } case IOCTL_VMCI_DATAGRAM_SEND: { VMCIDatagramSendRecvInfo sendInfo; VMCIDatagram *dg = NULL; VMCIId cid; if (vmciLinux->ctType != VMCIOBJ_CONTEXT) { Warning(LGPFX"Ioctl only valid for context handle (iocmd=%d).\n", iocmd); retval = -EINVAL; break; } retval = copy_from_user(&sendInfo, (void *) ioarg, sizeof sendInfo); if (retval) { Warning(LGPFX"copy_from_user failed.\n"); retval = -EFAULT; break; } if (sendInfo.len > VMCI_MAX_DG_SIZE) { Warning(LGPFX"Datagram too big (size=%d).\n", sendInfo.len); retval = -EINVAL; break; } if (sendInfo.len < sizeof *dg) { Warning(LGPFX"Datagram too small (size=%d).\n", sendInfo.len); retval = -EINVAL; break; } dg = VMCI_AllocKernelMem(sendInfo.len, VMCI_MEMORY_NORMAL); if (dg == NULL) { Log(LGPFX"Cannot allocate memory to dispatch datagram.\n"); retval = -ENOMEM; break; } retval = copy_from_user(dg, (char *)(VA)sendInfo.addr, sendInfo.len); if (retval != 0) { Log(LGPFX"Error getting datagram (err=%d).\n", retval); VMCI_FreeKernelMem(dg, sendInfo.len); retval = -EFAULT; break; } VMCI_DEBUG_LOG(10, (LGPFX"Datagram dst (handle=0x%x:0x%x) src " "(handle=0x%x:0x%x), payload (size=%"FMT64"u " "bytes).\n", dg->dst.context, dg->dst.resource, dg->src.context, dg->src.resource, dg->payloadSize)); /* Get source context id. */ ASSERT(vmciLinux->context); cid = VMCIContext_GetId(vmciLinux->context); ASSERT(cid != VMCI_INVALID_ID); sendInfo.result = VMCIDatagram_Dispatch(cid, dg, TRUE); VMCI_FreeKernelMem(dg, sendInfo.len); retval = copy_to_user((void *)ioarg, &sendInfo, sizeof sendInfo); break; } case IOCTL_VMCI_DATAGRAM_RECEIVE: { VMCIDatagramSendRecvInfo recvInfo; VMCIDatagram *dg = NULL; size_t size; if (vmciLinux->ctType != VMCIOBJ_CONTEXT) { Warning(LGPFX"Ioctl only valid for context handle (iocmd=%d).\n", iocmd); retval = -EINVAL; break; } retval = copy_from_user(&recvInfo, (void *) ioarg, sizeof recvInfo); if (retval) { Warning(LGPFX"copy_from_user failed.\n"); retval = -EFAULT; break; } ASSERT(vmciLinux->ctType == VMCIOBJ_CONTEXT); size = recvInfo.len; ASSERT(vmciLinux->context); recvInfo.result = VMCIContext_DequeueDatagram(vmciLinux->context, &size, &dg); if (recvInfo.result >= VMCI_SUCCESS) { ASSERT(dg); retval = copy_to_user((void *) ((uintptr_t) recvInfo.addr), dg, VMCI_DG_SIZE(dg)); VMCI_FreeKernelMem(dg, VMCI_DG_SIZE(dg)); if (retval != 0) { break; } } retval = copy_to_user((void *)ioarg, &recvInfo, sizeof recvInfo); break; } case IOCTL_VMCI_QUEUEPAIR_ALLOC: { if (vmciLinux->ctType != VMCIOBJ_CONTEXT) { Log(LGPFX"IOCTL_VMCI_QUEUEPAIR_ALLOC only valid for contexts.\n"); retval = -EINVAL; break; } if (vmciLinux->userVersion < VMCI_VERSION_NOVMVM) { VMCIQueuePairAllocInfo_VMToVM queuePairAllocInfo; VMCIQueuePairAllocInfo_VMToVM *info = (VMCIQueuePairAllocInfo_VMToVM *)ioarg; retval = copy_from_user(&queuePairAllocInfo, (void *)ioarg, sizeof queuePairAllocInfo); if (retval) { retval = -EFAULT; break; } retval = VMCIDoQPBrokerAlloc(queuePairAllocInfo.handle, queuePairAllocInfo.peer, queuePairAllocInfo.flags, queuePairAllocInfo.produceSize, queuePairAllocInfo.consumeSize, NULL, vmciLinux->context, TRUE, // VM to VM style create &info->result); } else { VMCIQueuePairAllocInfo queuePairAllocInfo; VMCIQueuePairAllocInfo *info = (VMCIQueuePairAllocInfo *)ioarg; QueuePairPageStore pageStore; retval = copy_from_user(&queuePairAllocInfo, (void *)ioarg, sizeof queuePairAllocInfo); if (retval) { retval = -EFAULT; break; } pageStore.pages = queuePairAllocInfo.ppnVA; pageStore.len = queuePairAllocInfo.numPPNs; retval = VMCIDoQPBrokerAlloc(queuePairAllocInfo.handle, queuePairAllocInfo.peer, queuePairAllocInfo.flags, queuePairAllocInfo.produceSize, queuePairAllocInfo.consumeSize, &pageStore, vmciLinux->context, FALSE, // Not VM to VM style create &info->result); } break; } case IOCTL_VMCI_QUEUEPAIR_SETVA: { VMCIQueuePairSetVAInfo setVAInfo; VMCIQueuePairSetVAInfo *info = (VMCIQueuePairSetVAInfo *)ioarg; int32 result; if (vmciLinux->ctType != VMCIOBJ_CONTEXT) { Log(LGPFX"IOCTL_VMCI_QUEUEPAIR_SETVA only valid for contexts.\n"); retval = -EINVAL; break; } if (vmciLinux->userVersion < VMCI_VERSION_NOVMVM) { Log(LGPFX"IOCTL_VMCI_QUEUEPAIR_SETVA not supported for this VMX version.\n"); retval = -EINVAL; break; } retval = copy_from_user(&setVAInfo, (void *)ioarg, sizeof setVAInfo); if (retval) { retval = -EFAULT; break; } if (setVAInfo.va) { /* * VMX is passing down a new VA for the queue pair mapping. */ result = VMCIQPBroker_Map(setVAInfo.handle, vmciLinux->context, setVAInfo.va); } else { /* * The queue pair is about to be unmapped by the VMX. */ result = VMCIQPBroker_Unmap(setVAInfo.handle, vmciLinux->context, 0); } retval = copy_to_user(&info->result, &result, sizeof result); if (retval) { retval = -EFAULT; } break; } case IOCTL_VMCI_QUEUEPAIR_SETPAGEFILE: { VMCIQueuePairPageFileInfo pageFileInfo; VMCIQueuePairPageFileInfo *info = (VMCIQueuePairPageFileInfo *)ioarg; int32 result; if (vmciLinux->userVersion < VMCI_VERSION_HOSTQP || vmciLinux->userVersion >= VMCI_VERSION_NOVMVM) { Log(LGPFX"IOCTL_VMCI_QUEUEPAIR_SETPAGEFILE not supported this VMX " "(version=%d).\n", vmciLinux->userVersion); retval = -EINVAL; break; } if (vmciLinux->ctType != VMCIOBJ_CONTEXT) { Log(LGPFX"IOCTL_VMCI_QUEUEPAIR_SETPAGEFILE only valid for contexts.\n"); retval = -EINVAL; break; } retval = copy_from_user(&pageFileInfo, (void *)ioarg, sizeof *info); if (retval) { retval = -EFAULT; break; } /* * Communicate success pre-emptively to the caller. Note that * the basic premise is that it is incumbent upon the caller not * to look at the info.result field until after the ioctl() * returns. And then, only if the ioctl() result indicates no * error. We send up the SUCCESS status before calling * SetPageStore() store because failing to copy up the result * code means unwinding the SetPageStore(). * * It turns out the logic to unwind a SetPageStore() opens a can * of worms. For example, if a host had created the QueuePair * and a guest attaches and SetPageStore() is successful but * writing success fails, then ... the host has to be stopped * from writing (anymore) data into the QueuePair. That means * an additional test in the VMCI_Enqueue() code path. Ugh. */ result = VMCI_SUCCESS; retval = copy_to_user(&info->result, &result, sizeof result); if (retval == 0) { result = VMCIQPBroker_SetPageStore(pageFileInfo.handle, pageFileInfo.produceVA, pageFileInfo.consumeVA, vmciLinux->context); if (result < VMCI_SUCCESS) { retval = copy_to_user(&info->result, &result, sizeof result); if (retval != 0) { /* * Note that in this case the SetPageStore() call * failed but we were unable to communicate that to the * caller (because the copy_to_user() call failed). * So, if we simply return an error (in this case * -EFAULT) then the caller will know that the * SetPageStore failed even though we couldn't put the * result code in the result field and indicate exactly * why it failed. * * That says nothing about the issue where we were once * able to write to the caller's info memory and now * can't. Something more serious is probably going on * than the fact that SetPageStore() didn't work. */ retval = -EFAULT; } } } else { /* * In this case, we can't write a result field of the * caller's info block. So, we don't even try to * SetPageStore(). */ retval = -EFAULT; } break; } case IOCTL_VMCI_QUEUEPAIR_DETACH: { VMCIQueuePairDetachInfo detachInfo; VMCIQueuePairDetachInfo *info = (VMCIQueuePairDetachInfo *)ioarg; int32 result; if (vmciLinux->ctType != VMCIOBJ_CONTEXT) { Log(LGPFX"IOCTL_VMCI_QUEUEPAIR_DETACH only valid for contexts.\n"); retval = -EINVAL; break; } retval = copy_from_user(&detachInfo, (void *)ioarg, sizeof detachInfo); if (retval) { retval = -EFAULT; break; } result = VMCIQPBroker_Detach(detachInfo.handle, vmciLinux->context); if (result == VMCI_SUCCESS && vmciLinux->userVersion < VMCI_VERSION_NOVMVM) { result = VMCI_SUCCESS_LAST_DETACH; } retval = copy_to_user(&info->result, &result, sizeof result); if (retval) { retval = -EFAULT; } break; } case IOCTL_VMCI_CTX_ADD_NOTIFICATION: { VMCINotifyAddRemoveInfo arInfo; VMCINotifyAddRemoveInfo *info = (VMCINotifyAddRemoveInfo *)ioarg; int32 result; VMCIId cid; if (vmciLinux->ctType != VMCIOBJ_CONTEXT) { Log(LGPFX"IOCTL_VMCI_CTX_ADD_NOTIFICATION only valid for contexts.\n"); retval = -EINVAL; break; } retval = copy_from_user(&arInfo, (void *)ioarg, sizeof arInfo); if (retval) { retval = -EFAULT; break; } cid = VMCIContext_GetId(vmciLinux->context); result = VMCIContext_AddNotification(cid, arInfo.remoteCID); retval = copy_to_user(&info->result, &result, sizeof result); if (retval) { retval = -EFAULT; break; } break; } case IOCTL_VMCI_CTX_REMOVE_NOTIFICATION: { VMCINotifyAddRemoveInfo arInfo; VMCINotifyAddRemoveInfo *info = (VMCINotifyAddRemoveInfo *)ioarg; int32 result; VMCIId cid; if (vmciLinux->ctType != VMCIOBJ_CONTEXT) { Log(LGPFX"IOCTL_VMCI_CTX_REMOVE_NOTIFICATION only valid for " "contexts.\n"); retval = -EINVAL; break; } retval = copy_from_user(&arInfo, (void *)ioarg, sizeof arInfo); if (retval) { retval = -EFAULT; break; } cid = VMCIContext_GetId(vmciLinux->context); result = VMCIContext_RemoveNotification(cid, arInfo.remoteCID); retval = copy_to_user(&info->result, &result, sizeof result); if (retval) { retval = -EFAULT; break; } break; } case IOCTL_VMCI_CTX_GET_CPT_STATE: { VMCICptBufInfo getInfo; VMCIId cid; char *cptBuf; if (vmciLinux->ctType != VMCIOBJ_CONTEXT) { Log(LGPFX"IOCTL_VMCI_CTX_GET_CPT_STATE only valid for contexts.\n"); retval = -EINVAL; break; } retval = copy_from_user(&getInfo, (void *)ioarg, sizeof getInfo); if (retval) { retval = -EFAULT; break; } cid = VMCIContext_GetId(vmciLinux->context); getInfo.result = VMCIContext_GetCheckpointState(cid, getInfo.cptType, &getInfo.bufSize, &cptBuf); if (getInfo.result == VMCI_SUCCESS && getInfo.bufSize) { retval = copy_to_user((void *)(VA)getInfo.cptBuf, cptBuf, getInfo.bufSize); VMCI_FreeKernelMem(cptBuf, getInfo.bufSize); if (retval) { retval = -EFAULT; break; } } retval = copy_to_user((void *)ioarg, &getInfo, sizeof getInfo); if (retval) { retval = -EFAULT; break; } break; } case IOCTL_VMCI_CTX_SET_CPT_STATE: { VMCICptBufInfo setInfo; VMCIId cid; char *cptBuf; if (vmciLinux->ctType != VMCIOBJ_CONTEXT) { Log(LGPFX"IOCTL_VMCI_CTX_SET_CPT_STATE only valid for contexts.\n"); retval = -EINVAL; break; } retval = copy_from_user(&setInfo, (void *)ioarg, sizeof setInfo); if (retval) { retval = -EFAULT; break; } cptBuf = VMCI_AllocKernelMem(setInfo.bufSize, VMCI_MEMORY_NORMAL); if (cptBuf == NULL) { Log(LGPFX"Cannot allocate memory to set cpt state (type=%d).\n", setInfo.cptType); retval = -ENOMEM; break; } retval = copy_from_user(cptBuf, (void *)(VA)setInfo.cptBuf, setInfo.bufSize); if (retval) { VMCI_FreeKernelMem(cptBuf, setInfo.bufSize); retval = -EFAULT; break; } cid = VMCIContext_GetId(vmciLinux->context); setInfo.result = VMCIContext_SetCheckpointState(cid, setInfo.cptType, setInfo.bufSize, cptBuf); VMCI_FreeKernelMem(cptBuf, setInfo.bufSize); retval = copy_to_user((void *)ioarg, &setInfo, sizeof setInfo); if (retval) { retval = -EFAULT; break; } break; } case IOCTL_VMCI_GET_CONTEXT_ID: { VMCIId cid = VMCI_HOST_CONTEXT_ID; retval = copy_to_user((void *)ioarg, &cid, sizeof cid); break; } case IOCTL_VMCI_SET_NOTIFY: { VMCISetNotifyInfo notifyInfo; if (vmciLinux->ctType != VMCIOBJ_CONTEXT) { Log(LGPFX"IOCTL_VMCI_SET_NOTIFY only valid for contexts.\n"); retval = -EINVAL; break; } retval = copy_from_user(¬ifyInfo, (void *)ioarg, sizeof notifyInfo); if (retval) { retval = -EFAULT; break; } if ((VA)notifyInfo.notifyUVA != (VA)NULL) { notifyInfo.result = VMCISetupNotify(vmciLinux->context, (VA)notifyInfo.notifyUVA); } else { VMCIUnsetNotifyInt(vmciLinux->context, TRUE); notifyInfo.result = VMCI_SUCCESS; } retval = copy_to_user((void *)ioarg, ¬ifyInfo, sizeof notifyInfo); if (retval) { retval = -EFAULT; break; } break; } case IOCTL_VMCI_NOTIFY_RESOURCE: { VMCINotifyResourceInfo info; VMCIId cid; if (vmciLinux->userVersion < VMCI_VERSION_NOTIFY) { Log(LGPFX"IOCTL_VMCI_NOTIFY_RESOURCE is invalid for current" " VMX versions.\n"); retval = -EINVAL; break; } if (vmciLinux->ctType != VMCIOBJ_CONTEXT) { Log(LGPFX"IOCTL_VMCI_NOTIFY_RESOURCE is only valid for contexts.\n"); retval = -EINVAL; break; } retval = copy_from_user(&info, (void *)ioarg, sizeof info); if (retval) { retval = -EFAULT; break; } cid = VMCIContext_GetId(vmciLinux->context); switch (info.action) { case VMCI_NOTIFY_RESOURCE_ACTION_NOTIFY: if (info.resource == VMCI_NOTIFY_RESOURCE_DOOR_BELL) { info.result = VMCIContext_NotifyDoorbell(cid, info.handle, VMCI_NO_PRIVILEGE_FLAGS); } else { info.result = VMCI_ERROR_UNAVAILABLE; } break; case VMCI_NOTIFY_RESOURCE_ACTION_CREATE: info.result = VMCIContext_DoorbellCreate(cid, info.handle); break; case VMCI_NOTIFY_RESOURCE_ACTION_DESTROY: info.result = VMCIContext_DoorbellDestroy(cid, info.handle); break; default: Log(LGPFX"IOCTL_VMCI_NOTIFY_RESOURCE got unknown action (action=%d).\n", info.action); info.result = VMCI_ERROR_INVALID_ARGS; } retval = copy_to_user((void *)ioarg, &info, sizeof info); if (retval) { retval = -EFAULT; break; } break; } case IOCTL_VMCI_NOTIFICATIONS_RECEIVE: { VMCINotificationReceiveInfo info; VMCIHandleArray *dbHandleArray; VMCIHandleArray *qpHandleArray; VMCIId cid; if (vmciLinux->ctType != VMCIOBJ_CONTEXT) { Log(LGPFX"IOCTL_VMCI_NOTIFICATIONS_RECEIVE is only valid for contexts.\n"); retval = -EINVAL; break; } if (vmciLinux->userVersion < VMCI_VERSION_NOTIFY) { Log(LGPFX"IOCTL_VMCI_NOTIFICATIONS_RECEIVE is not supported for the" " current vmx version.\n"); retval = -EINVAL; break; } retval = copy_from_user(&info, (void *)ioarg, sizeof info); if (retval) { retval = -EFAULT; break; } if ((info.dbHandleBufSize && !info.dbHandleBufUVA) || (info.qpHandleBufSize && !info.qpHandleBufUVA)) { retval = -EINVAL; break; } cid = VMCIContext_GetId(vmciLinux->context); info.result = VMCIContext_ReceiveNotificationsGet(cid, &dbHandleArray, &qpHandleArray); if (info.result == VMCI_SUCCESS) { info.result = VMCICopyHandleArrayToUser((void *)(VA)info.dbHandleBufUVA, &info.dbHandleBufSize, dbHandleArray, &retval); if (info.result == VMCI_SUCCESS && !retval) { info.result = VMCICopyHandleArrayToUser((void *)(VA)info.qpHandleBufUVA, &info.qpHandleBufSize, qpHandleArray, &retval); } if (!retval) { retval = copy_to_user((void *)ioarg, &info, sizeof info); } VMCIContext_ReceiveNotificationsRelease(cid, dbHandleArray, qpHandleArray, info.result == VMCI_SUCCESS && !retval); } else { retval = copy_to_user((void *)ioarg, &info, sizeof info); } break; } default: Warning(LGPFX"Unknown ioctl (iocmd=%d).\n", iocmd); retval = -EINVAL; } return retval; } #if defined(HAVE_COMPAT_IOCTL) || defined(HAVE_UNLOCKED_IOCTL) /* *----------------------------------------------------------------------------- * * LinuxDriver_UnlockedIoctl -- * * Wrapper for LinuxDriver_Ioctl supporting the compat_ioctl and * unlocked_ioctl methods that have signatures different from the * old ioctl. Used as compat_ioctl method for 32bit apps running * on 64bit kernel and for unlocked_ioctl on systems supporting * those. LinuxDriver_Ioctl may safely be called without holding * the BKL. * * Results: * Same as LinuxDriver_Ioctl. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static long LinuxDriver_UnlockedIoctl(struct file *filp, u_int iocmd, unsigned long ioarg) { return LinuxDriver_Ioctl(NULL, filp, iocmd, ioarg); } #endif /* *----------------------------------------------------------------------------- * * VMCIUserVAInvalidPointer -- * * Checks if a given user VA is valid or not. Copied from * bora/modules/vmnet/linux/hostif.c:VNetUserIfInvalidPointer(). TODO * libify the common code. * * Results: * TRUE iff invalid. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE Bool VMCIUserVAInvalidPointer(VA uva, // IN: size_t size) // IN: { return !access_ok(VERIFY_WRITE, (void *)uva, size); } /* *----------------------------------------------------------------------------- * * VMCIUserVALockPage -- * * Lock physical page backing a given user VA. Copied from * bora/modules/vmnet/linux/userif.c:UserIfLockPage(). TODO libify the * common code. * * Results: * Pointer to struct page on success, NULL otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE struct page * VMCIUserVALockPage(VA addr) // IN: { struct page *page = NULL; int retval; down_read(¤t->mm->mmap_sem); retval = get_user_pages(current, current->mm, addr, 1, 1, 0, &page, NULL); up_read(¤t->mm->mmap_sem); if (retval != 1) { return NULL; } return page; } /* *----------------------------------------------------------------------------- * * VMCIMapBoolPtr -- * * Lock physical page backing a given user VA and maps it to kernel * address space. The range of the mapped memory should be within a * single page otherwise an error is returned. Copied from * bora/modules/vmnet/linux/userif.c:VNetUserIfMapUint32Ptr(). TODO * libify the common code. * * Results: * 0 on success, negative error code otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE int VMCIMapBoolPtr(VA notifyUVA, // IN: struct page **p, // OUT: Bool **notifyPtr) // OUT: { if (VMCIUserVAInvalidPointer(notifyUVA, sizeof **notifyPtr) || (((notifyUVA + sizeof **notifyPtr - 1) & ~(PAGE_SIZE - 1)) != (notifyUVA & ~(PAGE_SIZE - 1)))) { return -EINVAL; } *p = VMCIUserVALockPage(notifyUVA); if (*p == NULL) { return -EAGAIN; } *notifyPtr = (Bool *)((uint8 *)kmap(*p) + (notifyUVA & (PAGE_SIZE - 1))); return 0; } /* *----------------------------------------------------------------------------- * * VMCISetupNotify -- * * Sets up a given context for notify to work. Calls VMCIMapBoolPtr() * which maps the notify boolean in user VA in kernel space. * * Results: * VMCI_SUCCESS on success, error code otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int VMCISetupNotify(VMCIContext *context, // IN: VA notifyUVA) // IN: { int retval; if (context->notify) { Warning(LGPFX"Notify mechanism is already set up.\n"); return VMCI_ERROR_DUPLICATE_ENTRY; } retval = VMCIMapBoolPtr(notifyUVA, &context->notifyPage, &context->notify) == 0 ? VMCI_SUCCESS : VMCI_ERROR_GENERIC; if (retval == VMCI_SUCCESS) { VMCIContext_CheckAndSignalNotify(context); } return retval; } /* *----------------------------------------------------------------------------- * * VMCIUnsetNotifyInt -- * * Internal version of VMCIUnsetNotify, that allows for locking * the context before unsetting the notify pointer. If useLock is * TRUE, the context lock is grabbed. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VMCIUnsetNotifyInt(VMCIContext *context, // IN Bool useLock) // IN { VMCILockFlags flags; if (useLock) { VMCI_GrabLock(&context->lock, &flags); } if (context->notifyPage) { struct page *notifyPage = context->notifyPage; context->notify = NULL; context->notifyPage = NULL; if (useLock) { VMCI_ReleaseLock(&context->lock, flags); } kunmap(notifyPage); put_page(notifyPage); } else { if (useLock) { VMCI_ReleaseLock(&context->lock, flags); } } } /* *----------------------------------------------------------------------------- * * VMCIUnsetNotify -- * * Reverts actions set up by VMCISetupNotify(). Unmaps and unlocks the * page mapped/locked by VMCISetupNotify(). * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMCIUnsetNotify(VMCIContext *context) // IN: { VMCIUnsetNotifyInt(context, FALSE); } /* *----------------------------------------------------------------------------- * * PCI device support -- * * The following functions implement the support for the VMCI * guest device. This includes initializing the device and * interrupt handling. * *----------------------------------------------------------------------------- */ /* *----------------------------------------------------------------------------- * * vmci_guest_init -- * * Initializes the VMCI PCI device. The initialization might fail * if there is no VMCI PCI device. * * Results: * 0 on success, other error codes on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int vmci_guest_init(void) { int retval; /* Initialize guest device data. */ compat_mutex_init(&vmci_dev.lock); vmci_dev.intr_type = VMCI_INTR_TYPE_INTX; vmci_dev.exclusive_vectors = FALSE; spin_lock_init(&vmci_dev.dev_spinlock); vmci_dev.enabled = FALSE; atomic_set(&vmci_dev.datagrams_allowed, 0); atomic_set(&guestDeviceActive, 0); data_buffer = vmalloc(data_buffer_size); if (!data_buffer) { return -ENOMEM; } /* This should be last to make sure we are done initializing. */ retval = pci_register_driver(&vmci_driver); if (retval < 0) { vfree(data_buffer); data_buffer = NULL; return retval; } return 0; } /* *----------------------------------------------------------------------------- * * vmci_enable_msix -- * * Enable MSI-X. Try exclusive vectors first, then shared vectors. * * Results: * 0 on success, other error codes on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int vmci_enable_msix(struct pci_dev *pdev) // IN { int i; int result; for (i = 0; i < VMCI_MAX_INTRS; ++i) { vmci_dev.msix_entries[i].entry = i; vmci_dev.msix_entries[i].vector = i; } result = pci_enable_msix(pdev, vmci_dev.msix_entries, VMCI_MAX_INTRS); if (!result) { vmci_dev.exclusive_vectors = TRUE; } else if (result > 0) { result = pci_enable_msix(pdev, vmci_dev.msix_entries, 1); } return result; } /* *----------------------------------------------------------------------------- * * vmci_probe_device -- * * Most of the initialization at module load time is done here. * * Results: * Returns 0 for success, an error otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int vmci_probe_device(struct pci_dev *pdev, // IN: vmci PCI device const struct pci_device_id *id) // IN: matching device ID { unsigned int ioaddr; unsigned int ioaddr_size; unsigned int capabilities; int result; printk(KERN_INFO "Probing for vmci/PCI.\n"); result = pci_enable_device(pdev); if (result) { printk(KERN_ERR "Cannot VMCI device %s: error %d\n", pci_name(pdev), result); return result; } pci_set_master(pdev); /* To enable QueuePair functionality. */ ioaddr = pci_resource_start(pdev, 0); ioaddr_size = pci_resource_len(pdev, 0); /* * Request I/O region with adjusted base address and size. The adjusted * values are needed and used if we release the region in case of failure. */ if (!compat_request_region(ioaddr, ioaddr_size, "vmci")) { printk(KERN_INFO "vmci: Another driver already loaded " "for device in slot %s.\n", pci_name(pdev)); goto pci_disable; } printk(KERN_INFO "Found vmci/PCI at %#x, irq %u.\n", ioaddr, pdev->irq); /* * Verify that the VMCI Device supports the capabilities that * we need. If the device is missing capabilities that we would * like to use, check for fallback capabilities and use those * instead (so we can run a new VM on old hosts). Fail the load if * a required capability is missing and there is no fallback. * * Right now, we need datagrams. There are no fallbacks. */ capabilities = inl(ioaddr + VMCI_CAPS_ADDR); if ((capabilities & VMCI_CAPS_DATAGRAM) == 0) { printk(KERN_ERR "VMCI device does not support datagrams.\n"); goto release; } /* * If the hardware supports notifications, we will use that as * well. */ if (capabilities & VMCI_CAPS_NOTIFICATIONS) { capabilities = VMCI_CAPS_DATAGRAM; notification_bitmap = vmalloc(PAGE_SIZE); if (notification_bitmap == NULL) { printk(KERN_ERR "VMCI device unable to allocate notification bitmap.\n"); } else { memset(notification_bitmap, 0, PAGE_SIZE); capabilities |= VMCI_CAPS_NOTIFICATIONS; } } else { capabilities = VMCI_CAPS_DATAGRAM; } printk(KERN_INFO "VMCI: using capabilities 0x%x.\n", capabilities); /* Let the host know which capabilities we intend to use. */ outl(capabilities, ioaddr + VMCI_CAPS_ADDR); /* Device struct initialization. */ compat_mutex_lock(&vmci_dev.lock); if (vmci_dev.enabled) { printk(KERN_ERR "VMCI device already enabled.\n"); goto unlock; } vmci_dev.ioaddr = ioaddr; vmci_dev.ioaddr_size = ioaddr_size; atomic_set(&vmci_dev.datagrams_allowed, 1); /* * Register notification bitmap with device if that capability is * used */ if (capabilities & VMCI_CAPS_NOTIFICATIONS) { unsigned long bitmapPPN; bitmapPPN = page_to_pfn(vmalloc_to_page(notification_bitmap)); if (!VMCI_RegisterNotificationBitmap(bitmapPPN)) { printk(KERN_ERR "VMCI device unable to register notification bitmap " "with PPN 0x%x.\n", (uint32)bitmapPPN); goto datagram_disallow; } } /* Check host capabilities. */ if (!VMCI_CheckHostCapabilities()) { goto remove_bitmap; } /* Enable device. */ vmci_dev.enabled = TRUE; pci_set_drvdata(pdev, &vmci_dev); /* * We do global initialization here because we need datagrams * during VMCIUtil_Init, since it registers for VMCI events. If we * ever support more than one VMCI device we will have to create * seperate LateInit/EarlyExit functions that can be used to do * initialization/cleanup that depends on the device being * accessible. We need to initialize VMCI components before * requesting an irq - the VMCI interrupt handler uses these * components, and it may be invoked once request_irq() has * registered the handler (as the irq line may be shared). */ VMCIUtil_Init(); if (VMCIQPGuestEndpoints_Init() < VMCI_SUCCESS) { goto util_exit; } /* * Enable interrupts. Try MSI-X first, then MSI, and then fallback on * legacy interrupts. */ if (!vmci_disable_msix && !vmci_enable_msix(pdev)) { vmci_dev.intr_type = VMCI_INTR_TYPE_MSIX; vmci_dev.irq = vmci_dev.msix_entries[0].vector; } else if (!vmci_disable_msi && !pci_enable_msi(pdev)) { vmci_dev.intr_type = VMCI_INTR_TYPE_MSI; vmci_dev.irq = pdev->irq; } else { vmci_dev.intr_type = VMCI_INTR_TYPE_INTX; vmci_dev.irq = pdev->irq; } /* Request IRQ for legacy or MSI interrupts, or for first MSI-X vector. */ result = request_irq(vmci_dev.irq, vmci_interrupt, COMPAT_IRQF_SHARED, "vmci", &vmci_dev); if (result) { printk(KERN_ERR "vmci: irq %u in use: %d\n", vmci_dev.irq, result); goto components_exit; } /* * For MSI-X with exclusive vectors we need to request an interrupt for each * vector so that we get a separate interrupt handler routine. This allows * us to distinguish between the vectors. */ if (vmci_dev.exclusive_vectors) { ASSERT(vmci_dev.intr_type == VMCI_INTR_TYPE_MSIX); result = request_irq(vmci_dev.msix_entries[1].vector, vmci_interrupt_bm, 0, "vmci", &vmci_dev); if (result) { printk(KERN_ERR "vmci: irq %u in use: %d\n", vmci_dev.msix_entries[1].vector, result); free_irq(vmci_dev.irq, &vmci_dev); goto components_exit; } } printk(KERN_INFO "Registered vmci device.\n"); atomic_inc(&guestDeviceActive); compat_mutex_unlock(&vmci_dev.lock); /* Enable specific interrupt bits. */ if (capabilities & VMCI_CAPS_NOTIFICATIONS) { outl(VMCI_IMR_DATAGRAM | VMCI_IMR_NOTIFICATION, vmci_dev.ioaddr + VMCI_IMR_ADDR); } else { outl(VMCI_IMR_DATAGRAM, vmci_dev.ioaddr + VMCI_IMR_ADDR); } /* Enable interrupts. */ outl(VMCI_CONTROL_INT_ENABLE, vmci_dev.ioaddr + VMCI_CONTROL_ADDR); return 0; components_exit: VMCIQPGuestEndpoints_Exit(); util_exit: VMCIUtil_Exit(); vmci_dev.enabled = FALSE; if (vmci_dev.intr_type == VMCI_INTR_TYPE_MSIX) { pci_disable_msix(pdev); } else if (vmci_dev.intr_type == VMCI_INTR_TYPE_MSI) { pci_disable_msi(pdev); } remove_bitmap: if (notification_bitmap) { outl(VMCI_CONTROL_RESET, vmci_dev.ioaddr + VMCI_CONTROL_ADDR); } datagram_disallow: atomic_set(&vmci_dev.datagrams_allowed, 0); unlock: compat_mutex_unlock(&vmci_dev.lock); release: if (notification_bitmap) { vfree(notification_bitmap); notification_bitmap = NULL; } release_region(ioaddr, ioaddr_size); pci_disable: pci_disable_device(pdev); return -EBUSY; } /* *----------------------------------------------------------------------------- * * vmci_remove_device -- * * Cleanup, called for each device on unload. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void vmci_remove_device(struct pci_dev* pdev) { struct vmci_device *dev = pci_get_drvdata(pdev); printk(KERN_INFO "Removing vmci device\n"); atomic_dec(&guestDeviceActive); VMCIQPGuestEndpoints_Exit(); VMCIUtil_Exit(); compat_mutex_lock(&dev->lock); atomic_set(&vmci_dev.datagrams_allowed, 0); printk(KERN_INFO "Resetting vmci device\n"); outl(VMCI_CONTROL_RESET, vmci_dev.ioaddr + VMCI_CONTROL_ADDR); /* * Free IRQ and then disable MSI/MSI-X as appropriate. For MSI-X, we might * have multiple vectors, each with their own IRQ, which we must free too. */ free_irq(dev->irq, dev); if (dev->intr_type == VMCI_INTR_TYPE_MSIX) { if (dev->exclusive_vectors) { free_irq(dev->msix_entries[1].vector, dev); } pci_disable_msix(pdev); } else if (dev->intr_type == VMCI_INTR_TYPE_MSI) { pci_disable_msi(pdev); } dev->exclusive_vectors = FALSE; dev->intr_type = VMCI_INTR_TYPE_INTX; release_region(dev->ioaddr, dev->ioaddr_size); dev->enabled = FALSE; if (notification_bitmap) { /* * The device reset above cleared the bitmap state of the * device, so we can safely free it here. */ vfree(notification_bitmap); notification_bitmap = NULL; } printk(KERN_INFO "Unregistered vmci device.\n"); compat_mutex_unlock(&dev->lock); pci_disable_device(pdev); } /* *----------------------------------------------------------------------------- * * vmci_interrupt -- * * Interrupt handler for legacy or MSI interrupt, or for first MSI-X * interrupt (vector VMCI_INTR_DATAGRAM). * * Results: * COMPAT_IRQ_HANDLED if the interrupt is handled, COMPAT_IRQ_NONE if * not an interrupt. * * Side effects: * None. * *----------------------------------------------------------------------------- */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) static compat_irqreturn_t vmci_interrupt(int irq, // IN void *clientdata, // IN struct pt_regs *regs) // IN #else static compat_irqreturn_t vmci_interrupt(int irq, // IN void *clientdata) // IN #endif { vmci_device *dev = clientdata; if (dev == NULL) { printk(KERN_DEBUG "vmci_interrupt(): irq %d for unknown device.\n", irq); return COMPAT_IRQ_NONE; } /* * If we are using MSI-X with exclusive vectors then we simply schedule * the datagram tasklet, since we know the interrupt was meant for us. * Otherwise we must read the ICR to determine what to do. */ if (dev->intr_type == VMCI_INTR_TYPE_MSIX && dev->exclusive_vectors) { tasklet_schedule(&vmci_dg_tasklet); } else { unsigned int icr; ASSERT(dev->intr_type == VMCI_INTR_TYPE_INTX || dev->intr_type == VMCI_INTR_TYPE_MSI); /* Acknowledge interrupt and determine what needs doing. */ icr = inl(dev->ioaddr + VMCI_ICR_ADDR); if (icr == 0 || icr == 0xffffffff) { return COMPAT_IRQ_NONE; } if (icr & VMCI_ICR_DATAGRAM) { tasklet_schedule(&vmci_dg_tasklet); icr &= ~VMCI_ICR_DATAGRAM; } if (icr & VMCI_ICR_NOTIFICATION) { tasklet_schedule(&vmci_bm_tasklet); icr &= ~VMCI_ICR_NOTIFICATION; } if (icr != 0) { printk(KERN_INFO LGPFX"Ignoring unknown interrupt cause (%d).\n", icr); } } return COMPAT_IRQ_HANDLED; } /* *----------------------------------------------------------------------------- * * vmci_interrupt_bm -- * * Interrupt handler for MSI-X interrupt vector VMCI_INTR_NOTIFICATION, * which is for the notification bitmap. Will only get called if we are * using MSI-X with exclusive vectors. * * Results: * COMPAT_IRQ_HANDLED if the interrupt is handled, COMPAT_IRQ_NONE if * not an interrupt. * * Side effects: * None. * *----------------------------------------------------------------------------- */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) static compat_irqreturn_t vmci_interrupt_bm(int irq, // IN void *clientdata, // IN struct pt_regs *regs) // IN #else static compat_irqreturn_t vmci_interrupt_bm(int irq, // IN void *clientdata) // IN #endif { vmci_device *dev = clientdata; if (dev == NULL) { printk(KERN_DEBUG "vmci_interrupt_bm(): irq %d for unknown device.\n", irq); return COMPAT_IRQ_NONE; } /* For MSI-X we can just assume it was meant for us. */ ASSERT(dev->intr_type == VMCI_INTR_TYPE_MSIX && dev->exclusive_vectors); tasklet_schedule(&vmci_bm_tasklet); return COMPAT_IRQ_HANDLED; } /* *----------------------------------------------------------------------------- * * VMCI_DeviceEnabled -- * * Checks whether the VMCI device is enabled. * * Results: * TRUE if device is enabled, FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool VMCI_DeviceEnabled(void) { return VMCI_GuestPersonalityActive() || VMCI_HostPersonalityActive(); } /* *----------------------------------------------------------------------------- * * VMCI_SendDatagram -- * * VM to hypervisor call mechanism. We use the standard VMware naming * convention since shared code is calling this function as well. * * Results: * The result of the hypercall. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int VMCI_SendDatagram(VMCIDatagram *dg) { unsigned long flags; int result; /* Check args. */ if (dg == NULL) { return VMCI_ERROR_INVALID_ARGS; } if (atomic_read(&vmci_dev.datagrams_allowed) == 0) { return VMCI_ERROR_UNAVAILABLE; } /* * Need to acquire spinlock on the device because * the datagram data may be spread over multiple pages and the monitor may * interleave device user rpc calls from multiple VCPUs. Acquiring the * spinlock precludes that possibility. Disabling interrupts to avoid * incoming datagrams during a "rep out" and possibly landing up in this * function. */ spin_lock_irqsave(&vmci_dev.dev_spinlock, flags); /* * Send the datagram and retrieve the return value from the result register. */ __asm__ __volatile__( "cld\n\t" "rep outsb\n\t" : /* No output. */ : "d"(vmci_dev.ioaddr + VMCI_DATA_OUT_ADDR), "c"(VMCI_DG_SIZE(dg)), "S"(dg) ); /* * XXX Should read result high port as well when updating handlers to * return 64bit. */ result = inl(vmci_dev.ioaddr + VMCI_RESULT_LOW_ADDR); spin_unlock_irqrestore(&vmci_dev.dev_spinlock, flags); return result; } /* *----------------------------------------------------------------------------- * * dispatch_datagrams -- * * Reads and dispatches incoming datagrams. * * Results: * None. * * Side effects: * Reads data from the device. * *----------------------------------------------------------------------------- */ void dispatch_datagrams(unsigned long data) { vmci_device *dev = (vmci_device *)data; if (dev == NULL) { printk(KERN_DEBUG "vmci: dispatch_datagrams(): no vmci device" "present.\n"); return; } if (data_buffer == NULL) { printk(KERN_DEBUG "vmci: dispatch_datagrams(): no buffer present.\n"); return; } VMCI_ReadDatagramsFromPort((VMCIIoHandle) 0, dev->ioaddr + VMCI_DATA_IN_ADDR, data_buffer, data_buffer_size); } /* *----------------------------------------------------------------------------- * * process_bitmap -- * * Scans the notification bitmap for raised flags, clears them * and handles the notifications. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void process_bitmap(unsigned long data) { vmci_device *dev = (vmci_device *)data; if (dev == NULL) { printk(KERN_DEBUG "vmci: process_bitmaps(): no vmci device" "present.\n"); return; } if (notification_bitmap == NULL) { printk(KERN_DEBUG "vmci: process_bitmaps(): no bitmap present.\n"); return; } VMCI_ScanNotificationBitmap(notification_bitmap); } /* *---------------------------------------------------------------------- * * Shared functions -- * * Functions shared between host and guest personality. * *---------------------------------------------------------------------- */ /* *----------------------------------------------------------------------------- * * VMCI_GuestPersonalityActive -- * * Determines whether the VMCI PCI device has been successfully * initialized. * * Results: * TRUE, if VMCI guest device is operational, FALSE otherwise. * * Side effects: * Reads data from the device. * *----------------------------------------------------------------------------- */ Bool VMCI_GuestPersonalityActive(void) { return guestDeviceInit && atomic_read(&guestDeviceActive) > 0; } /* *----------------------------------------------------------------------------- * * VMCI_HostPersonalityActive -- * * Determines whether the VMCI host personality is * available. Since the core functionality of the host driver is * always present, all guests could possibly use the host * personality. However, to minimize the deviation from the * pre-unified driver state of affairs, we only consider the host * device active, if there is no active guest device, or if there * are VMX'en with active VMCI contexts using the host device. * * Results: * TRUE, if VMCI host driver is operational, FALSE otherwise. * * Side effects: * Reads data from the device. * *----------------------------------------------------------------------------- */ Bool VMCI_HostPersonalityActive(void) { return hostDeviceInit && (!VMCI_GuestPersonalityActive() || atomic_read(&linuxState.activeContexts) > 0); } /* *---------------------------------------------------------------------- * * Module definitions -- * * Implements support for module load/unload. * *---------------------------------------------------------------------- */ /* *---------------------------------------------------------------------- * * vmci_init -- * * linux module entry point. Called by /sbin/insmod command * * Results: * registers a device driver for a major # that depends * on the uid. Add yourself to that list. List is now in * private/driver-private.c. * *---------------------------------------------------------------------- */ static int __init vmci_init(void) { int retval; retval = VMCI_SharedInit(); if (retval != VMCI_SUCCESS) { Warning(LGPFX"Failed to initialize VMCI common components (err=%d).\n", retval); return -ENOMEM; } if (!vmci_disable_guest) { retval = vmci_guest_init(); if (retval != 0) { Warning(LGPFX"VMCI PCI device not initialized (err=%d).\n", retval); } else { guestDeviceInit = TRUE; if (VMCI_GuestPersonalityActive()) { Log(LGPFX"Using guest personality\n"); } } } if (!vmci_disable_host) { retval = vmci_host_init(); if (retval != 0) { Warning(LGPFX"Unable to initialize host personality (err=%d).\n", retval); } else { hostDeviceInit = TRUE; Log(LGPFX"Using host personality\n"); } } if (!guestDeviceInit && !hostDeviceInit) { VMCI_SharedCleanup(); return -ENODEV; } Log(LGPFX"Module (name=%s) is initialized\n", VMCI_MODULE_NAME); return 0; } /* *---------------------------------------------------------------------- * * vmci_exit -- * * Called by /sbin/rmmod * * *---------------------------------------------------------------------- */ static void __exit vmci_exit(void) { int retval; if (guestDeviceInit) { pci_unregister_driver(&vmci_driver); vfree(data_buffer); guestDeviceInit = FALSE; } if (hostDeviceInit) { unregister_ioctl32_handlers(); VMCI_HostCleanup(); retval = misc_deregister(&linuxState.misc); if (retval) { Warning(LGPFX "Module %s: error unregistering\n", VMCI_MODULE_NAME); } else { Log(LGPFX"Module %s: unloaded\n", VMCI_MODULE_NAME); } hostDeviceInit = FALSE; } VMCI_SharedCleanup(); } module_init(vmci_init); module_exit(vmci_exit); MODULE_DEVICE_TABLE(pci, vmci_ids); module_param_named(disable_host, vmci_disable_host, bool, 0); MODULE_PARM_DESC(disable_host, "Disable driver host personality - (default=0)"); module_param_named(disable_guest, vmci_disable_guest, bool, 0); MODULE_PARM_DESC(disable_guest, "Disable driver guest personality - (default=0)"); module_param_named(disable_msi, vmci_disable_msi, bool, 0); MODULE_PARM_DESC(disable_msi, "Disable MSI use in driver - (default=0)"); module_param_named(disable_msix, vmci_disable_msix, bool, 0); MODULE_PARM_DESC(disable_msix, "Disable MSI-X use in driver - (default=" __stringify(VMCI_DISABLE_MSIX) ")"); MODULE_AUTHOR("VMware, Inc."); MODULE_DESCRIPTION("VMware Virtual Machine Communication Interface (VMCI)."); MODULE_VERSION(VMCI_DRIVER_VERSION_STRING); MODULE_LICENSE("GPL v2"); /* * Starting with SLE10sp2, Novell requires that IHVs sign a support agreement * with them and mark their kernel modules as externally supported via a * change to the module header. If this isn't done, the module will not load * by default (i.e., neither mkinitrd nor modprobe will accept it). */ MODULE_INFO(supported, "external"); open-vm-tools-9.4.0-1280544/modules/linux/vmci/linux/vmciKernelIf.c0000644765153500003110000015360312220061556023075 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciKernelIf.c -- * * This file implements defines and helper functions for VMCI * host _and_ guest kernel code. This is the linux specific * implementation. */ /* Must come before any kernel header file */ #include "driver-config.h" #if !defined(linux) || defined(VMKERNEL) #error "Wrong platform." #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9) # error "Linux kernels before 2.6.9 are not supported." #endif #include /* For vmalloc_to_page() and get_user_pages()*/ #include /* For page_cache_release() */ #include /* For memcpy_{to,from}iovec(). */ #include #include #include "compat_highmem.h" #include "compat_interrupt.h" #include "compat_mm.h" #include "compat_module.h" #include "compat_page.h" #include "compat_pci.h" #include "compat_sched.h" #include "compat_semaphore.h" #include "compat_slab.h" #include "compat_spinlock.h" #include "compat_version.h" #include "compat_workqueue.h" #include "vm_assert.h" #include "vm_basic_types.h" #include "vmci_iocontrols.h" #include "vmci_kernel_if.h" #include "vmciQueue.h" #include "vmciQueuePair.h" /* * The Kernel specific component of the VMCIQueue structure. */ struct VMCIQueueKernelIf { struct page **page; struct page **headerPage; void *va; VMCIMutex __mutex; VMCIMutex *mutex; Bool host; Bool isDataMapped; size_t numPages; }; typedef struct VMCIDelayedWorkInfo { compat_work work; VMCIWorkFn *workFn; void *data; } VMCIDelayedWorkInfo; /* *----------------------------------------------------------------------------- * * VMCI_InitLock * * Initializes the lock. Must be called before use. * * Results: * Always VMCI_SUCCESS. * * Side effects: * Thread can block. * *----------------------------------------------------------------------------- */ int VMCI_InitLock(VMCILock *lock, // IN: char *name, // IN: Unused on Linux VMCILockRank rank) // IN: Unused on Linux { spin_lock_init(lock); return VMCI_SUCCESS; } /* *----------------------------------------------------------------------------- * * VMCI_CleanupLock * * Cleanup the lock. Must be called before deallocating lock. * * Results: * None * * Side effects: * Deletes kernel lock state * *----------------------------------------------------------------------------- */ void VMCI_CleanupLock(VMCILock *lock) { } /* *----------------------------------------------------------------------------- * * VMCI_GrabLock * * Grabs the given lock. XXX Fill in specific lock requirements. XXX Move * locking code into hostif if VMCI stays in vmmon. * * Results: * None * * Side effects: * Thread can block. * *----------------------------------------------------------------------------- */ void VMCI_GrabLock(VMCILock *lock, // IN VMCILockFlags *flags) // OUT: used to restore irql on windows { spin_lock(lock); } /* *----------------------------------------------------------------------------- * * VMCI_ReleaseLock * * Releases the given lock. XXX Move locking code into hostif if VMCI * stays in vmmon. * * Results: * None * * Side effects: * A thread blocked on this lock may wake up. * *----------------------------------------------------------------------------- */ void VMCI_ReleaseLock(VMCILock *lock, // IN VMCILockFlags flags) // IN { spin_unlock(lock); } /* *----------------------------------------------------------------------------- * * VMCI_GrabLock_BH * * Grabs the given lock and for linux kernels disables bottom half execution. * This should be used with locks accessed both from bottom half/tasklet * contexts, ie. guestcall handlers, and from process contexts to avoid * deadlocks where the process has the lock and gets descheduled due to a * bh/tasklet coming in. * * Results: * None * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMCI_GrabLock_BH(VMCILock *lock, // IN VMCILockFlags *flags) // OUT: used to restore { spin_lock_bh(lock); } /* *----------------------------------------------------------------------------- * * VMCI_ReleaseLock_BH * * Releases the given lock and for linux kernels reenables bottom half * execution. * This should be used with locks accessed both from bottom half/tasklet * contexts, ie. guestcall handlers, and from process contexts to avoid * deadlocks where the process has the lock and get descheduled due to a * bh/tasklet coming in. * * Results: * None * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMCI_ReleaseLock_BH(VMCILock *lock, // IN VMCILockFlags flags) // IN { spin_unlock_bh(lock); } /* *---------------------------------------------------------------------- * * VMCIHost_InitContext -- * * Host-specific initialization of VMCI context state. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void VMCIHost_InitContext(VMCIHost *hostContext, // IN uintptr_t eventHnd) // IN: Unused { init_waitqueue_head(&hostContext->waitQueue); } /* *---------------------------------------------------------------------- * * VMCIHost_ReleaseContext -- * * Host-specific release of state allocated by * VMCIHost_InitContext. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void VMCIHost_ReleaseContext(VMCIHost *hostContext) // IN { } /* *---------------------------------------------------------------------- * * VMCIHost_SignalCall -- * * Signal to userlevel that a VMCI call is waiting. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void VMCIHost_SignalCall(VMCIHost *hostContext) // IN { wake_up(&hostContext->waitQueue); } /* *---------------------------------------------------------------------- * * VMCIHost_WaitForCallLocked -- * * Wait until a VMCI call is pending or the waiting thread is * interrupted. It is assumed that a lock is held prior to * calling this function. The lock will be released during the * wait. The correctnes of this funtion depends on that the same * lock is held when the call is signalled. * * Results: * TRUE on success * FALSE if the wait was interrupted. * * Side effects: * The call may block. * *---------------------------------------------------------------------- */ Bool VMCIHost_WaitForCallLocked(VMCIHost *hostContext, // IN VMCILock *lock, // IN VMCILockFlags *flags, // IN Bool useBH) // IN { DECLARE_WAITQUEUE(wait, current); /* * The thread must be added to the wait queue and have its state * changed while holding the lock - otherwise a signal may change * the state in between and have it overwritten causing a loss of * the event. */ add_wait_queue(&hostContext->waitQueue, &wait); current->state = TASK_INTERRUPTIBLE; if (useBH) { VMCI_ReleaseLock_BH(lock, *flags); } else { VMCI_ReleaseLock(lock, *flags); } schedule(); if (useBH) { VMCI_GrabLock_BH(lock, flags); } else { VMCI_GrabLock(lock, flags); } current->state = TASK_RUNNING; remove_wait_queue(&hostContext->waitQueue, &wait); if (signal_pending(current)) { return FALSE; } return TRUE; } /* *---------------------------------------------------------------------- * * VMCIHost_ClearCall -- * * Clear the pending call signal. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void VMCIHost_ClearCall(VMCIHost *hostContext) // IN { } /* *----------------------------------------------------------------------------- * * VMCIHost_CompareUser -- * * Determines whether the two users are the same. * * Results: * VMCI_SUCCESS if equal, error code otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int VMCIHost_CompareUser(VMCIHostUser *user1, VMCIHostUser *user2) { if (!user1 || !user2) { return VMCI_ERROR_INVALID_ARGS; } if (*user1 == *user2) { return VMCI_SUCCESS; } else { return VMCI_ERROR_GENERIC; } } /* *---------------------------------------------------------------------- * * VMCI_AllocKernelMem * * Allocate some kernel memory for the VMCI driver. * * Results: * The address allocated or NULL on error. * * * Side effects: * memory is malloced *---------------------------------------------------------------------- */ void * VMCI_AllocKernelMem(size_t size, int flags) { void *ptr; if ((flags & VMCI_MEMORY_ATOMIC) != 0) { ptr = kmalloc(size, GFP_ATOMIC); } else { ptr = kmalloc(size, GFP_KERNEL); } return ptr; } /* *---------------------------------------------------------------------- * * VMCI_FreeKernelMem * * Free kernel memory allocated for the VMCI driver. * * Results: * None. * * Side effects: * memory is freed. *---------------------------------------------------------------------- */ void VMCI_FreeKernelMem(void *ptr, // IN: size_t size) // IN: Unused on Linux { kfree(ptr); } /* *----------------------------------------------------------------------------- * * VMCI_CopyToUser -- * * Copy memory to the user application from a kernel buffer. This * function may block, so don't call it while holding any kind of * lock. * * Results: * 0 on success. * Nonzero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ int VMCI_CopyToUser(VA64 dst, // OUT: Destination user VA. const void *src, // IN: Source kernel VA. size_t len) // IN: Number of bytes to copy. { return copy_to_user(VMCIVA64ToPtr(dst), src, len) ? -EFAULT : 0; } /* *----------------------------------------------------------------------------- * * VMCI_CopyFromUser -- * * Copy memory from the user application to a kernel buffer. This * function may block, so don't call it while holding any kind of * lock. * * Results: * 0 on success. * Nonzero on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int VMCI_CopyFromUser(void *dst, // OUT: Kernel VA VA64 src, // IN: User VA size_t len) // IN { return copy_from_user(dst, VMCIVA64ToPtr(src), len); } /* *---------------------------------------------------------------------------- * * VMCIDelayedWorkCB * * Called in a worker thread context. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VMCIDelayedWorkCB(compat_work_arg work) // IN { VMCIDelayedWorkInfo *delayedWorkInfo; delayedWorkInfo = COMPAT_WORK_GET_DATA(work, VMCIDelayedWorkInfo, work); ASSERT(delayedWorkInfo); ASSERT(delayedWorkInfo->workFn); delayedWorkInfo->workFn(delayedWorkInfo->data); VMCI_FreeKernelMem(delayedWorkInfo, sizeof *delayedWorkInfo); } /* *---------------------------------------------------------------------------- * * VMCI_CanScheduleDelayedWork -- * * Checks to see if the given platform supports delayed work callbacks. * * Results: * TRUE if it does. FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool VMCI_CanScheduleDelayedWork(void) { return TRUE; } /* *---------------------------------------------------------------------------- * * VMCI_ScheduleDelayedWork -- * * Schedule the specified callback. * * Results: * Zero on success, error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VMCI_ScheduleDelayedWork(VMCIWorkFn *workFn, // IN void *data) // IN { VMCIDelayedWorkInfo *delayedWorkInfo; ASSERT(workFn); delayedWorkInfo = VMCI_AllocKernelMem(sizeof *delayedWorkInfo, VMCI_MEMORY_ATOMIC); if (!delayedWorkInfo) { return VMCI_ERROR_NO_MEM; } delayedWorkInfo->workFn = workFn; delayedWorkInfo->data = data; COMPAT_INIT_WORK(&delayedWorkInfo->work, VMCIDelayedWorkCB, delayedWorkInfo); compat_schedule_work(&delayedWorkInfo->work); return VMCI_SUCCESS; } /* *----------------------------------------------------------------------------- * * VMCI_CreateEvent -- * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMCI_CreateEvent(VMCIEvent *event) // IN: { init_waitqueue_head(event); } /* *----------------------------------------------------------------------------- * * VMCI_DestroyEvent -- * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMCI_DestroyEvent(VMCIEvent *event) // IN: { /* Nothing to do. */ } /* *----------------------------------------------------------------------------- * * VMCI_SignalEvent -- * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMCI_SignalEvent(VMCIEvent *event) // IN: { wake_up(event); } /* *----------------------------------------------------------------------------- * * VMCI_WaitOnEvent -- * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMCI_WaitOnEvent(VMCIEvent *event, // IN: VMCIEventReleaseCB releaseCB, // IN: void *clientData) // IN: { /* * XXX Should this be a TASK_UNINTERRUPTIBLE wait? I'm leaving it * as it was for now. */ VMCI_WaitOnEventInterruptible(event, releaseCB, clientData); } /* *----------------------------------------------------------------------------- * * VMCI_WaitOnEventInterruptible -- * * Results: * True if the wait was interrupted by a signal, false otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool VMCI_WaitOnEventInterruptible(VMCIEvent *event, // IN: VMCIEventReleaseCB releaseCB, // IN: void *clientData) // IN: { DECLARE_WAITQUEUE(wait, current); if (event == NULL || releaseCB == NULL) { return FALSE; } add_wait_queue(event, &wait); current->state = TASK_INTERRUPTIBLE; /* * Release the lock or other primitive that makes it possible for us to * put the current thread on the wait queue without missing the signal. * Ie. on Linux we need to put ourselves on the wait queue and set our * stateto TASK_INTERRUPTIBLE without another thread signalling us. * The releaseCB is used to synchronize this. */ releaseCB(clientData); schedule(); current->state = TASK_RUNNING; remove_wait_queue(event, &wait); return signal_pending(current); } /* *----------------------------------------------------------------------------- * * VMCIMutex_Init -- * * Initializes the mutex. Must be called before use. * * Results: * Success. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int VMCIMutex_Init(VMCIMutex *mutex, // IN char *name, // IN: Unused VMCILockRank rank) // IN: Unused { sema_init(mutex, 1); return VMCI_SUCCESS; } /* *----------------------------------------------------------------------------- * * VMCIMutex_Destroy -- * * Destroys the mutex. Does nothing on Linux. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMCIMutex_Destroy(VMCIMutex *mutex) // IN: Unused { } /* *----------------------------------------------------------------------------- * * VMCIMutex_Acquire -- * * Acquires the mutex. * * Results: * None. * * Side effects: * Thread may block. * *----------------------------------------------------------------------------- */ void VMCIMutex_Acquire(VMCIMutex *mutex) // IN: { down(mutex); } /* *----------------------------------------------------------------------------- * * VMCIMutex_Release -- * * Releases the mutex. * * Results: * None. * * Side effects: * May wake up the thread blocking on this mutex. * *----------------------------------------------------------------------------- */ void VMCIMutex_Release(VMCIMutex *mutex) // IN: { up(mutex); } /* *----------------------------------------------------------------------------- * * VMCI_AllocQueue -- * * Allocates kernel VA space of specified size, plus space for the * queue structure/kernel interface and the queue header. Allocates * physical pages for the queue data pages. * * PAGE m: VMCIQueueHeader (VMCIQueue->qHeader) * PAGE m+1: VMCIQueue * PAGE m+1+q: VMCIQueueKernelIf (VMCIQueue->kernelIf) * PAGE n-size: Data pages (VMCIQueue->kernelIf->page[]) * * Results: * Pointer to the queue on success, NULL otherwise. * * Side effects: * Memory is allocated. * *----------------------------------------------------------------------------- */ void * VMCI_AllocQueue(uint64 size, // IN: size of queue (not including header) uint32 flags) // IN: queuepair flags { uint64 i; VMCIQueue *queue; VMCIQueueHeader *qHeader; const uint64 numDataPages = CEILING(size, PAGE_SIZE); const uint queueSize = PAGE_SIZE + sizeof *queue + sizeof *(queue->kernelIf) + numDataPages * sizeof *(queue->kernelIf->page); /* * Size should be enforced by VMCIQPair_Alloc(), double-check here. * Allocating too much on Linux can cause the system to become * unresponsive, because we allocate page-by-page, and we allow the * system to wait for pages rather than fail. */ if (size > VMCI_MAX_GUEST_QP_MEMORY) { ASSERT(FALSE); return NULL; } /* * If pinning is requested then double-check the size of the queue. * VMCIQPair_Alloc() will do this for the total queuepair size. */ if ((flags & VMCI_QPFLAG_PINNED) && size > VMCI_MAX_PINNED_QP_MEMORY) { return NULL; } qHeader = (VMCIQueueHeader *)vmalloc(queueSize); if (!qHeader) { return NULL; } queue = (VMCIQueue *)((uint8 *)qHeader + PAGE_SIZE); queue->qHeader = qHeader; queue->savedHeader = NULL; queue->kernelIf = (VMCIQueueKernelIf *)((uint8 *)queue + sizeof *queue); queue->kernelIf->headerPage = NULL; // Unused in guest. queue->kernelIf->page = (struct page **)((uint8 *)queue->kernelIf + sizeof *(queue->kernelIf)); queue->kernelIf->va = NULL; queue->kernelIf->host = FALSE; queue->kernelIf->isDataMapped = FALSE; for (i = 0; i < numDataPages; i++) { queue->kernelIf->page[i] = alloc_pages(GFP_KERNEL, 0); if (!queue->kernelIf->page[i]) { VMCI_FreeQueue(queue, i * PAGE_SIZE); return NULL; } } /* * alloc_pages() returns pinned PAs, but we need a permanent mapping to VA * if the caller has requested pinned queuepairs. Map all of them into * kernel VA now, for the lifetime of the queue. The page VAs will be * contiguous. */ if (flags & VMCI_QPFLAG_PINNED) { queue->kernelIf->va = vmap(queue->kernelIf->page, numDataPages, VM_MAP, PAGE_KERNEL); if (NULL == queue->kernelIf->va) { VMCI_FreeQueue(queue, numDataPages * PAGE_SIZE); return NULL; } queue->kernelIf->isDataMapped = TRUE; } return (void *)queue; } /* *----------------------------------------------------------------------------- * * VMCI_FreeQueue -- * * Frees kernel VA space for a given queue and its queue header, and * frees physical data pages. * * Results: * None. * * Side effects: * Memory is freed. * *----------------------------------------------------------------------------- */ void VMCI_FreeQueue(void *q, // IN: uint64 size) // IN: size of queue (not including header) { VMCIQueue *queue = q; if (queue) { uint64 i; if (queue->kernelIf->isDataMapped) { ASSERT(queue->kernelIf->va); vunmap(queue->kernelIf->va); queue->kernelIf->va = NULL; } ASSERT(NULL == queue->kernelIf->va); for (i = 0; i < CEILING(size, PAGE_SIZE); i++) { __free_page(queue->kernelIf->page[i]); } vfree(queue->qHeader); } } /* *----------------------------------------------------------------------------- * * VMCI_AllocPPNSet -- * * Allocates two list of PPNs --- one for the pages in the produce queue, * and the other for the pages in the consume queue. Intializes the list * of PPNs with the page frame numbers of the KVA for the two queues (and * the queue headers). * * Results: * Success or failure. * * Side effects: * Memory may be allocated. * *----------------------------------------------------------------------------- */ int VMCI_AllocPPNSet(void *prodQ, // IN: uint64 numProducePages, // IN: for queue plus header void *consQ, // IN: uint64 numConsumePages, // IN: for queue plus header PPNSet *ppnSet) // OUT: { VMCIPpnList producePPNs; VMCIPpnList consumePPNs; VMCIQueue *produceQ = prodQ; VMCIQueue *consumeQ = consQ; uint64 i; if (!produceQ || !numProducePages || !consumeQ || !numConsumePages || !ppnSet) { return VMCI_ERROR_INVALID_ARGS; } if (ppnSet->initialized) { return VMCI_ERROR_ALREADY_EXISTS; } producePPNs = VMCI_AllocKernelMem(numProducePages * sizeof *producePPNs, VMCI_MEMORY_NORMAL); if (!producePPNs) { return VMCI_ERROR_NO_MEM; } consumePPNs = VMCI_AllocKernelMem(numConsumePages * sizeof *consumePPNs, VMCI_MEMORY_NORMAL); if (!consumePPNs) { VMCI_FreeKernelMem(producePPNs, numProducePages * sizeof *producePPNs); return VMCI_ERROR_NO_MEM; } producePPNs[0] = page_to_pfn(vmalloc_to_page(produceQ->qHeader)); for (i = 1; i < numProducePages; i++) { unsigned long pfn; producePPNs[i] = pfn = page_to_pfn(produceQ->kernelIf->page[i - 1]); /* * Fail allocation if PFN isn't supported by hypervisor. */ if (sizeof pfn > sizeof *producePPNs && pfn != producePPNs[i]) { goto ppnError; } } consumePPNs[0] = page_to_pfn(vmalloc_to_page(consumeQ->qHeader)); for (i = 1; i < numConsumePages; i++) { unsigned long pfn; consumePPNs[i] = pfn = page_to_pfn(consumeQ->kernelIf->page[i - 1]); /* * Fail allocation if PFN isn't supported by hypervisor. */ if (sizeof pfn > sizeof *consumePPNs && pfn != consumePPNs[i]) { goto ppnError; } } ppnSet->numProducePages = numProducePages; ppnSet->numConsumePages = numConsumePages; ppnSet->producePPNs = producePPNs; ppnSet->consumePPNs = consumePPNs; ppnSet->initialized = TRUE; return VMCI_SUCCESS; ppnError: VMCI_FreeKernelMem(producePPNs, numProducePages * sizeof *producePPNs); VMCI_FreeKernelMem(consumePPNs, numConsumePages * sizeof *consumePPNs); return VMCI_ERROR_INVALID_ARGS; } /* *----------------------------------------------------------------------------- * * VMCI_FreePPNSet -- * * Frees the two list of PPNs for a queue pair. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMCI_FreePPNSet(PPNSet *ppnSet) // IN: { ASSERT(ppnSet); if (ppnSet->initialized) { /* Do not call these functions on NULL inputs. */ ASSERT(ppnSet->producePPNs && ppnSet->consumePPNs); VMCI_FreeKernelMem(ppnSet->producePPNs, ppnSet->numProducePages * sizeof *ppnSet->producePPNs); VMCI_FreeKernelMem(ppnSet->consumePPNs, ppnSet->numConsumePages * sizeof *ppnSet->consumePPNs); } memset(ppnSet, 0, sizeof *ppnSet); } /* *----------------------------------------------------------------------------- * * VMCI_PopulatePPNList -- * * Populates the list of PPNs in the hypercall structure with the PPNS * of the produce queue and the consume queue. * * Results: * VMCI_SUCCESS. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int VMCI_PopulatePPNList(uint8 *callBuf, // OUT: const PPNSet *ppnSet) // IN: { ASSERT(callBuf && ppnSet && ppnSet->initialized); memcpy(callBuf, ppnSet->producePPNs, ppnSet->numProducePages * sizeof *ppnSet->producePPNs); memcpy(callBuf + ppnSet->numProducePages * sizeof *ppnSet->producePPNs, ppnSet->consumePPNs, ppnSet->numConsumePages * sizeof *ppnSet->consumePPNs); return VMCI_SUCCESS; } #ifdef __KERNEL__ /* *----------------------------------------------------------------------------- * * __VMCIMemcpyToQueue -- * * Copies from a given buffer or iovector to a VMCI Queue. Uses * kmap()/kunmap() to dynamically map/unmap required portions of the queue * by traversing the offset -> page translation structure for the queue. * Assumes that offset + size does not wrap around in the queue. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int __VMCIMemcpyToQueue(VMCIQueue *queue, // OUT: uint64 queueOffset, // IN: const void *src, // IN: size_t size, // IN: Bool isIovec) // IN: if src is a struct iovec * { VMCIQueueKernelIf *kernelIf = queue->kernelIf; size_t bytesCopied = 0; while (bytesCopied < size) { uint64 pageIndex = (queueOffset + bytesCopied) / PAGE_SIZE; size_t pageOffset = (queueOffset + bytesCopied) & (PAGE_SIZE - 1); void *va; size_t toCopy; if (kernelIf->isDataMapped) { va = (void *)((uint8 *)kernelIf->va + (pageIndex * PAGE_SIZE)); } else { va = kmap(kernelIf->page[pageIndex]); } ASSERT(va); if (size - bytesCopied > PAGE_SIZE - pageOffset) { /* Enough payload to fill up from this page. */ toCopy = PAGE_SIZE - pageOffset; } else { toCopy = size - bytesCopied; } if (isIovec) { struct iovec *iov = (struct iovec *)src; int err; /* The iovec will track bytesCopied internally. */ err = memcpy_fromiovec((uint8 *)va + pageOffset, iov, toCopy); if (err != 0) { if (!kernelIf->isDataMapped) { kunmap(kernelIf->page[pageIndex]); } return VMCI_ERROR_INVALID_ARGS; } } else { memcpy((uint8 *)va + pageOffset, (uint8 *)src + bytesCopied, toCopy); } bytesCopied += toCopy; if (!kernelIf->isDataMapped) { kunmap(kernelIf->page[pageIndex]); } } return VMCI_SUCCESS; } /* *----------------------------------------------------------------------------- * * __VMCIMemcpyFromQueue -- * * Copies to a given buffer or iovector from a VMCI Queue. Uses * kmap()/kunmap() to dynamically map/unmap required portions of the queue * by traversing the offset -> page translation structure for the queue. * Assumes that offset + size does not wrap around in the queue. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int __VMCIMemcpyFromQueue(void *dest, // OUT: const VMCIQueue *queue, // IN: uint64 queueOffset, // IN: size_t size, // IN: Bool isIovec) // IN: if dest is a struct iovec * { VMCIQueueKernelIf *kernelIf = queue->kernelIf; size_t bytesCopied = 0; while (bytesCopied < size) { uint64 pageIndex = (queueOffset + bytesCopied) / PAGE_SIZE; size_t pageOffset = (queueOffset + bytesCopied) & (PAGE_SIZE - 1); void *va; size_t toCopy; if (kernelIf->isDataMapped) { va = (void *)((uint8 *)kernelIf->va + (pageIndex * PAGE_SIZE)); } else { va = kmap(kernelIf->page[pageIndex]); } ASSERT(va); if (size - bytesCopied > PAGE_SIZE - pageOffset) { /* Enough payload to fill up this page. */ toCopy = PAGE_SIZE - pageOffset; } else { toCopy = size - bytesCopied; } if (isIovec) { struct iovec *iov = (struct iovec *)dest; int err; /* The iovec will track bytesCopied internally. */ err = memcpy_toiovec(iov, (uint8 *)va + pageOffset, toCopy); if (err != 0) { if (!kernelIf->isDataMapped) { kunmap(kernelIf->page[pageIndex]); } return VMCI_ERROR_INVALID_ARGS; } } else { memcpy((uint8 *)dest + bytesCopied, (uint8 *)va + pageOffset, toCopy); } bytesCopied += toCopy; if (!kernelIf->isDataMapped) { kunmap(kernelIf->page[pageIndex]); } } return VMCI_SUCCESS; } /* *----------------------------------------------------------------------------- * * VMCIMemcpyToQueue -- * * Copies from a given buffer to a VMCI Queue. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int VMCIMemcpyToQueue(VMCIQueue *queue, // OUT: uint64 queueOffset, // IN: const void *src, // IN: size_t srcOffset, // IN: size_t size, // IN: int bufType, // IN: Unused Bool canBlock) // IN: Unused { ASSERT(canBlock || !queue->kernelIf->host); return __VMCIMemcpyToQueue(queue, queueOffset, (uint8 *)src + srcOffset, size, FALSE); } /* *----------------------------------------------------------------------------- * * VMCIMemcpyFromQueue -- * * Copies to a given buffer from a VMCI Queue. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int VMCIMemcpyFromQueue(void *dest, // OUT: size_t destOffset, // IN: const VMCIQueue *queue, // IN: uint64 queueOffset, // IN: size_t size, // IN: int bufType, // IN: Unused Bool canBlock) // IN: Unused { ASSERT(canBlock || !queue->kernelIf->host); return __VMCIMemcpyFromQueue((uint8 *)dest + destOffset, queue, queueOffset, size, FALSE); } /* *----------------------------------------------------------------------------- * * VMCIMemcpyToQueueLocal -- * * Copies from a given buffer to a local VMCI queue. On Linux, this is the * same as a regular copy. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int VMCIMemcpyToQueueLocal(VMCIQueue *queue, // OUT uint64 queueOffset, // IN const void *src, // IN size_t srcOffset, // IN size_t size, // IN int bufType, // IN: Unused Bool canBlock) // IN: Unused { ASSERT(canBlock || !queue->kernelIf->host); return __VMCIMemcpyToQueue(queue, queueOffset, (uint8 *)src + srcOffset, size, FALSE);; } /* *----------------------------------------------------------------------------- * * VMCIMemcpyFromQueueLocal -- * * Copies to a given buffer from a VMCI Queue. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int VMCIMemcpyFromQueueLocal(void *dest, // OUT: size_t destOffset, // IN: const VMCIQueue *queue, // IN: uint64 queueOffset, // IN: size_t size, // IN: int bufType, // IN: Unused Bool canBlock) // IN: Unused { ASSERT(canBlock || !queue->kernelIf->host); return __VMCIMemcpyFromQueue((uint8 *)dest + destOffset, queue, queueOffset, size, FALSE); } /* *---------------------------------------------------------------------------- * * VMCIMemcpyToQueueV -- * * Copies from a given iovec from a VMCI Queue. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VMCIMemcpyToQueueV(VMCIQueue *queue, // OUT: uint64 queueOffset, // IN: const void *src, // IN: iovec size_t srcOffset, // IN: ignored size_t size, // IN: int bufType, // IN: Unused Bool canBlock) // IN: Unused { ASSERT(canBlock || !queue->kernelIf->host); /* * We ignore srcOffset because src is really a struct iovec * and will * maintain offset internally. */ return __VMCIMemcpyToQueue(queue, queueOffset, src, size, TRUE); } /* *---------------------------------------------------------------------------- * * VMCIMemcpyFromQueueV -- * * Copies to a given iovec from a VMCI Queue. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VMCIMemcpyFromQueueV(void *dest, // OUT: iovec size_t destOffset, // IN: ignored const VMCIQueue *queue, // IN: uint64 queueOffset, // IN: size_t size, // IN: int bufType, // IN: Unused Bool canBlock) // IN: Unused { ASSERT(canBlock || !queue->kernelIf->host); /* * We ignore destOffset because dest is really a struct iovec * and will * maintain offset internally. */ return __VMCIMemcpyFromQueue(dest, queue, queueOffset, size, TRUE); } #endif /* *----------------------------------------------------------------------------- * * VMCIWellKnownID_AllowMap -- * * Checks whether the calling context is allowed to register for the given * well known service ID. Currently returns FALSE if the service ID is * within the reserved range and VMCI_PRIVILEGE_FLAG_TRUSTED is not * provided as the input privilege flags. Otherwise returns TRUE. * XXX TODO access control based on host configuration information; this * will be platform specific implementation. * * Results: * Boolean value indicating access granted or denied. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool VMCIWellKnownID_AllowMap(VMCIId wellKnownID, // IN: VMCIPrivilegeFlags privFlags) // IN: { if (wellKnownID < VMCI_RESERVED_RESOURCE_ID_MAX && !(privFlags & VMCI_PRIVILEGE_FLAG_TRUSTED)) { return FALSE; } return TRUE; } /* *----------------------------------------------------------------------------- * * VMCIHost_AllocQueue -- * * Allocates kernel VA space of specified size plus space for the queue * and kernel interface. This is different from the guest queue allocator, * because we do not allocate our own queue header/data pages here but * share those of the guest. * * Results: * A pointer to an allocated and initialized VMCIQueue structure or NULL. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VMCIQueue * VMCIHost_AllocQueue(uint64 size) // IN: { VMCIQueue *queue; const size_t numPages = CEILING(size, PAGE_SIZE) + 1; const size_t queueSize = sizeof *queue + sizeof *(queue->kernelIf); const size_t queuePageSize = numPages * sizeof *queue->kernelIf->page; queue = VMCI_AllocKernelMem(queueSize + queuePageSize, VMCI_MEMORY_NORMAL); if (queue) { queue->qHeader = NULL; queue->savedHeader = NULL; queue->kernelIf = (VMCIQueueKernelIf *)((uint8 *)queue + sizeof *queue); queue->kernelIf->host = TRUE; queue->kernelIf->mutex = NULL; queue->kernelIf->numPages = numPages; queue->kernelIf->headerPage = (struct page **)((uint8*)queue + queueSize); queue->kernelIf->page = &queue->kernelIf->headerPage[1]; memset(queue->kernelIf->headerPage, 0, sizeof *queue->kernelIf->headerPage * queue->kernelIf->numPages); queue->kernelIf->va = NULL; queue->kernelIf->isDataMapped = FALSE; } return queue; } /* *----------------------------------------------------------------------------- * * VMCIHost_FreeQueue -- * * Frees kernel memory for a given queue (header plus translation * structure). * * Results: * None. * * Side effects: * Memory is freed. * *----------------------------------------------------------------------------- */ void VMCIHost_FreeQueue(VMCIQueue *queue, // IN: uint64 queueSize) // IN: { if (queue) { const uint queueSize = sizeof *queue + sizeof *(queue->kernelIf); VMCI_FreeKernelMem(queue, queueSize); } } /* *----------------------------------------------------------------------------- * * VMCI_InitQueueMutex() * * Initialize the mutex for the pair of queues. This mutex is used to * protect the qHeader and the buffer from changing out from under any * users of either queue. Of course, it's only any good if the mutexes * are actually acquired. Queue structure must lie on non-paged memory * or we cannot guarantee access to the mutex. * * Results: * None. * * Side Effects: * None. * *---------------------------------------------------------------------------- */ void VMCI_InitQueueMutex(VMCIQueue *produceQ, // IN/OUT VMCIQueue *consumeQ) // IN/OUT { ASSERT(produceQ); ASSERT(consumeQ); ASSERT(produceQ->kernelIf); ASSERT(consumeQ->kernelIf); /* * Only the host queue has shared state - the guest queues do not * need to synchronize access using a queue mutex. */ if (produceQ->kernelIf->host) { produceQ->kernelIf->mutex = &produceQ->kernelIf->__mutex; consumeQ->kernelIf->mutex = &produceQ->kernelIf->__mutex; sema_init(produceQ->kernelIf->mutex, 1); } } /* *----------------------------------------------------------------------------- * * VMCI_CleanupQueueMutex() * * Cleans up the mutex for the pair of queues. * * Results: * None. * * Side Effects: * None. * *---------------------------------------------------------------------------- */ void VMCI_CleanupQueueMutex(VMCIQueue *produceQ, // IN/OUT VMCIQueue *consumeQ) // IN/OUT { ASSERT(produceQ); ASSERT(consumeQ); ASSERT(produceQ->kernelIf); ASSERT(consumeQ->kernelIf); if (produceQ->kernelIf->host) { produceQ->kernelIf->mutex = NULL; consumeQ->kernelIf->mutex = NULL; } } /* *----------------------------------------------------------------------------- * * VMCI_AcquireQueueMutex() * * Acquire the mutex for the queue. Note that the produceQ and * the consumeQ share a mutex. So, only one of the two need to * be passed in to this routine. Either will work just fine. * * Results: * VMCI_SUCCESS always. * * Side Effects: * May block the caller. * *---------------------------------------------------------------------------- */ int VMCI_AcquireQueueMutex(VMCIQueue *queue, // IN Bool canBlock) // IN: Unused { ASSERT(queue); ASSERT(queue->kernelIf); if (queue->kernelIf->host) { ASSERT(canBlock); ASSERT(queue->kernelIf->mutex); down(queue->kernelIf->mutex); } return VMCI_SUCCESS; } /* *----------------------------------------------------------------------------- * * VMCI_ReleaseQueueMutex() * * Release the mutex for the queue. Note that the produceQ and * the consumeQ share a mutex. So, only one of the two need to * be passed in to this routine. Either will work just fine. * * Results: * None. * * Side Effects: * May block the caller. * *---------------------------------------------------------------------------- */ void VMCI_ReleaseQueueMutex(VMCIQueue *queue) // IN { ASSERT(queue); ASSERT(queue->kernelIf); if (queue->kernelIf->host) { ASSERT(queue->kernelIf->mutex); up(queue->kernelIf->mutex); } } /* *----------------------------------------------------------------------------- * * VMCI_LockQueueHeader() * * Acquire a spinlock guarding the queue header. Note that the produceQ * and the consumeQ share the lock mutex. So, only one of the two need to * be passed in to this routine. Either will work just fine. * * Results: * None. * * Side Effects: * None. * *---------------------------------------------------------------------------- */ void VMCI_LockQueueHeader(VMCIQueue *queue) // IN { ASSERT(queue); ASSERT(queue->kernelIf); ASSERT(!queue->kernelIf->host); /* * We don't support non-blocking on the host right now, so we won't get * here for a host queue. And there's no lock required on the guest. So * this is a NOP. */ } /* *----------------------------------------------------------------------------- * * VMCI_UnlockQueueHeader() * * Release the spinlock guarding the queue header. * * Results: * None. * * Side Effects: * None. * *---------------------------------------------------------------------------- */ void VMCI_UnlockQueueHeader(VMCIQueue *queue) // IN { ASSERT(queue); ASSERT(queue->kernelIf); ASSERT(!queue->kernelIf->host); } /* *----------------------------------------------------------------------------- * * VMCIReleasePageStorePages -- * * Helper function to release pages in the PageStoreAttachInfo * previously obtained using get_user_pages. * * Results: * None. * * Side Effects: * None. * *----------------------------------------------------------------------------- */ static void VMCIReleasePages(struct page **pages, // IN uint64 numPages, // IN Bool dirty) // IN { int i; for (i = 0; i < numPages; i++) { ASSERT(pages[i]); if (dirty) { set_page_dirty(pages[i]); } page_cache_release(pages[i]); pages[i] = NULL; } } /* *----------------------------------------------------------------------------- * * VMCIHost_RegisterUserMemory -- * * Registers the specification of the user pages used for backing a queue * pair. Enough information to map in pages is stored in the OS specific * part of the VMCIQueue structure. * * Results: * VMCI_SUCCESS on sucess, negative error code on failure. * * Side Effects: * None. * *----------------------------------------------------------------------------- */ int VMCIHost_RegisterUserMemory(unsigned int index, // IN QueuePairPageStore *pageStore, // IN VMCIQueue *produceQ, // OUT VMCIQueue *consumeQ) // OUT { VA64 produceUVA; VA64 consumeUVA; ASSERT(index == 0); ASSERT(produceQ->kernelIf->headerPage && consumeQ->kernelIf->headerPage); /* * The new style and the old style mapping only differs in that we either * get a single or two UVAs, so we split the single UVA range at the * appropriate spot. */ produceUVA = pageStore->pages; consumeUVA = pageStore->pages + produceQ->kernelIf->numPages * PAGE_SIZE; return VMCIHost_GetUserMemory(index, produceUVA, consumeUVA, produceQ, consumeQ); } /* *----------------------------------------------------------------------------- * * VMCIHost_UnregisterUserMemory -- * * Releases and removes the references to user pages stored in the attach * struct. * * Results: * None * * Side Effects: * Pages are released from the page cache and may become * swappable again. * *----------------------------------------------------------------------------- */ void VMCIHost_UnregisterUserMemory(unsigned int index, // IN VMCIQueue *produceQ, // IN/OUT VMCIQueue *consumeQ) // IN/OUT { ASSERT(index == 0); ASSERT(produceQ->kernelIf); ASSERT(consumeQ->kernelIf); ASSERT(!produceQ->qHeader && !consumeQ->qHeader); VMCIReleasePages(produceQ->kernelIf->headerPage, produceQ->kernelIf->numPages, TRUE); memset(produceQ->kernelIf->headerPage, 0, sizeof *produceQ->kernelIf->headerPage * produceQ->kernelIf->numPages); VMCIReleasePages(consumeQ->kernelIf->headerPage, consumeQ->kernelIf->numPages, TRUE); memset(consumeQ->kernelIf->headerPage, 0, sizeof *consumeQ->kernelIf->headerPage * consumeQ->kernelIf->numPages); } /* *----------------------------------------------------------------------------- * * VMCIHost_MapQueues -- * * Once VMCIHost_RegisterUserMemory has been performed on a * queue, the queue pair headers can be mapped into the * kernel. Once mapped, they must be unmapped with * VMCIHost_UnmapQueues prior to calling * VMCIHost_UnregisterUserMemory. * * Results: * VMCI_SUCCESS if pages are mapped, appropriate error code otherwise. * * Side Effects: * Pages are pinned. * *----------------------------------------------------------------------------- */ int VMCIHost_MapQueues(unsigned int index, // IN VMCIQueue *produceQ, // IN/OUT VMCIQueue *consumeQ, // IN/OUT uint32 flags) // UNUSED { int result; ASSERT(index == 0); if (!produceQ->qHeader || !consumeQ->qHeader) { struct page *headers[2]; if (produceQ->qHeader != consumeQ->qHeader) { return VMCI_ERROR_QUEUEPAIR_MISMATCH; } if (produceQ->kernelIf->headerPage == NULL || *produceQ->kernelIf->headerPage == NULL) { return VMCI_ERROR_UNAVAILABLE; } ASSERT(*produceQ->kernelIf->headerPage && *consumeQ->kernelIf->headerPage); headers[0] = *produceQ->kernelIf->headerPage; headers[1] = *consumeQ->kernelIf->headerPage; produceQ->qHeader = vmap(headers, 2, VM_MAP, PAGE_KERNEL); if (produceQ->qHeader != NULL) { consumeQ->qHeader = (VMCIQueueHeader *)((uint8 *)produceQ->qHeader + PAGE_SIZE); result = VMCI_SUCCESS; } else { Log("vmap failed\n"); result = VMCI_ERROR_NO_MEM; } } else { result = VMCI_SUCCESS; } return result; } /* *----------------------------------------------------------------------------- * * VMCIHost_UnmapQueues -- * * Unmaps previously mapped queue pair headers from the kernel. * * Results: * VMCI_SUCCESS always. * * Side Effects: * Pages are unpinned. * *----------------------------------------------------------------------------- */ int VMCIHost_UnmapQueues(unsigned int index, // IN VMCIGuestMemID gid, // IN VMCIQueue *produceQ, // IN/OUT VMCIQueue *consumeQ) // IN/OUT { ASSERT(index == 0); if (produceQ->qHeader) { ASSERT(consumeQ->qHeader); if (produceQ->qHeader < consumeQ->qHeader) { vunmap(produceQ->qHeader); } else { vunmap(consumeQ->qHeader); } produceQ->qHeader = NULL; consumeQ->qHeader = NULL; } return VMCI_SUCCESS; } /* *----------------------------------------------------------------------------- * * VMCIHost_GetUserMemory -- * * * Lock the user pages referenced by the {produce,consume}Buffer * struct into memory and populate the {produce,consume}Pages * arrays in the attach structure with them. * * Results: * VMCI_SUCCESS on sucess, negative error code on failure. * * Side Effects: * None. * *----------------------------------------------------------------------------- */ int VMCIHost_GetUserMemory(unsigned int index, // IN VA64 produceUVA, // IN VA64 consumeUVA, // IN VMCIQueue *produceQ, // OUT VMCIQueue *consumeQ) // OUT { int retval; int err = VMCI_SUCCESS; ASSERT(index == 0); down_write(¤t->mm->mmap_sem); retval = get_user_pages(current, current->mm, (VA)produceUVA, produceQ->kernelIf->numPages, 1, 0, produceQ->kernelIf->headerPage, NULL); if (retval < produceQ->kernelIf->numPages) { Log("get_user_pages(produce) failed (retval=%d)\n", retval); VMCIReleasePages(produceQ->kernelIf->headerPage, retval, FALSE); err = VMCI_ERROR_NO_MEM; goto out; } retval = get_user_pages(current, current->mm, (VA)consumeUVA, consumeQ->kernelIf->numPages, 1, 0, consumeQ->kernelIf->headerPage, NULL); if (retval < consumeQ->kernelIf->numPages) { Log("get_user_pages(consume) failed (retval=%d)\n", retval); VMCIReleasePages(consumeQ->kernelIf->headerPage, retval, FALSE); VMCIReleasePages(produceQ->kernelIf->headerPage, produceQ->kernelIf->numPages, FALSE); err = VMCI_ERROR_NO_MEM; } out: up_write(¤t->mm->mmap_sem); return err; } /* *----------------------------------------------------------------------------- * * VMCIHost_ReleaseUserMemory -- * Release the reference to user pages stored in the attach * struct * * Results: * None * * Side Effects: * Pages are released from the page cache and may become * swappable again. * *----------------------------------------------------------------------------- */ void VMCIHost_ReleaseUserMemory(unsigned int index, // IN VMCIQueue *produceQ, // IN/OUT VMCIQueue *consumeQ) // IN/OUT { ASSERT(index == 0); ASSERT(produceQ->kernelIf->headerPage); VMCIHost_UnregisterUserMemory(index, produceQ, consumeQ); } /* *----------------------------------------------------------------------------- * * VMCI_ReadPortBytes -- * * Copy memory from an I/O port to kernel memory. * * Results: * No results. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMCI_ReadPortBytes(VMCIIoHandle handle, // IN: Unused VMCIIoPort port, // IN uint8 *buffer, // OUT size_t bufferLength) // IN { insb(port, buffer, bufferLength); } open-vm-tools-9.4.0-1280544/modules/linux/vmci/linux/vmci_version.h0000644765153500003110000000221012220061556023212 0ustar dtormts/********************************************************* * Copyright (C) 2007-2012 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmci_version.h -- * * Version definitions for the Linux vmci driver. */ #ifndef _VMCI_VERSION_H_ #define _VMCI_VERSION_H_ #define VMCI_DRIVER_VERSION 9.5.13.0 #define VMCI_DRIVER_VERSION_COMMAS 9,5,13,0 #define VMCI_DRIVER_VERSION_STRING "9.5.13.0" #endif /* _VMCI_VERSION_H_ */ open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/0000755765153500003110000000000012220061556020474 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciCommonInt.h0000644765153500003110000001340312220061556023430 0ustar dtormts/********************************************************* * Copyright (C) 2006-2012 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciCommonInt.h -- * * Struct definitions for VMCI internal common code. */ #ifndef _VMCI_COMMONINT_H_ #define _VMCI_COMMONINT_H_ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vm_atomic.h" #include "vmci_defs.h" #include "vmci_call_defs.h" #include "vmci_infrastructure.h" #include "vmci_handle_array.h" #include "vmci_kernel_if.h" /* * The DatagramQueueEntry is a queue header for the in-kernel VMCI * datagram queues. It is allocated in non-paged memory, as the * content is accessed while holding a spinlock. The pending datagram * itself may be allocated from paged memory. We shadow the size of * the datagram in the non-paged queue entry as this size is used * while holding the same spinlock as above. */ typedef struct DatagramQueueEntry { VMCIListItem listItem; /* For queuing. */ size_t dgSize; /* Size of datagram. */ VMCIDatagram *dg; /* Pending datagram. */ } DatagramQueueEntry; /* * The VMCIFilterState captures the state of all VMCI filters in one * direction. The ranges array contains all filter list in a single * memory chunk, and the filter list pointers in the VMCIProtoFilters * point into the ranges array. */ typedef struct VMCIFilterState { VMCIProtoFilters filters; VMCIIdRange *ranges; size_t rangesSize; } VMCIFilterState; struct VMCIContext { VMCIListItem listItem; /* For global VMCI list. */ VMCIId cid; Atomic_uint32 refCount; VMCIList datagramQueue; /* Head of per VM queue. */ uint32 pendingDatagrams; size_t datagramQueueSize;/* Size of datagram queue in bytes. */ int userVersion; /* * Version of the code that created * this context; e.g., VMX. */ VMCILock lock; /* * Locks datagramQueue, inFilters, * doorbellArray, pendingDoorbellArray * and notifierArray. */ VMCIHandleArray *queuePairArray; /* * QueuePairs attached to. The array of * handles for queue pairs is accessed * from the code for QP API, and there * it is protected by the QP lock. It * is also accessed from the context * clean up path, which does not * require a lock. VMCILock is not * used to protect the QP array. */ VMCIHandleArray *doorbellArray; /* Doorbells created by context. */ VMCIHandleArray *pendingDoorbellArray; /* Doorbells pending for context. */ VMCIHandleArray *notifierArray; /* Contexts current context is subscribing to. */ VMCIHost hostContext; VMCIPrivilegeFlags privFlags; VMCIHostUser user; Bool validUser; #ifdef VMKERNEL Bool isQuiesced; /* Whether current VM is quiesced */ VMCIId migrateCid; /* The migrate cid if it is migrating */ VMCIMutex guestMemMutex; /* * Coordinates guest memory * registration/release during FSR. */ VMCIGuestMemID curGuestMemID; /* ID of current registered guest mem */ VMCIFilterState *inFilters; /* Ingoing filters for VMCI traffic. */ #endif #ifndef VMX86_SERVER Bool *notify; /* Notify flag pointer - hosted only. */ # ifdef __linux__ struct page *notifyPage; /* Page backing the notify UVA. */ # endif #endif }; /* *------------------------------------------------------------------------------ * * VMCIDenyInteraction -- * * Utilility function that checks whether two entities are allowed * to interact. If one of them is restricted, the other one must * be trusted. * * Result: * TRUE if the two entities are not allowed to interact. FALSE otherwise. * * Side effects: * None. * *------------------------------------------------------------------------------ */ static INLINE Bool VMCIDenyInteraction(VMCIPrivilegeFlags partOne, // IN VMCIPrivilegeFlags partTwo) // IN { return (((partOne & VMCI_PRIVILEGE_FLAG_RESTRICTED) && !(partTwo & VMCI_PRIVILEGE_FLAG_TRUSTED)) || ((partTwo & VMCI_PRIVILEGE_FLAG_RESTRICTED) && !(partOne & VMCI_PRIVILEGE_FLAG_TRUSTED))); } #endif /* _VMCI_COMMONINT_H_ */ open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciEvent.c0000644765153500003110000005032412220061556022604 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciEvent.c -- * * VMCI Event code for host and guests. */ #include "vmci_kernel_if.h" #include "vmci_defs.h" #include "vmci_infrastructure.h" #include "vmciEvent.h" #include "vmciKernelAPI.h" #if defined(VMKERNEL) # include "vmciVmkInt.h" # include "vm_libc.h" # include "helper_ext.h" # include "vmciDriver.h" #else # include "vmciDriver.h" #endif #define LGPFX "VMCIEvent: " #define EVENT_MAGIC 0xEABE0000 typedef struct VMCISubscription { VMCIId id; int refCount; Bool runDelayed; VMCIEvent destroyEvent; VMCI_Event event; VMCI_EventCB callback; void *callbackData; VMCIListItem subscriberListItem; } VMCISubscription; static VMCISubscription *VMCIEventFind(VMCIId subID); static int VMCIEventDeliver(VMCIEventMsg *eventMsg); static int VMCIEventRegisterSubscription(VMCISubscription *sub, VMCI_Event event, uint32 flags, VMCI_EventCB callback, void *callbackData); static VMCISubscription *VMCIEventUnregisterSubscription(VMCIId subID); static VMCIList subscriberArray[VMCI_EVENT_MAX]; static VMCILock subscriberLock; typedef struct VMCIDelayedEventInfo { VMCISubscription *sub; uint8 eventPayload[sizeof(VMCIEventData_Max)]; } VMCIDelayedEventInfo; typedef struct VMCIEventRef { VMCISubscription *sub; VMCIListItem listItem; } VMCIEventRef; /* *---------------------------------------------------------------------- * * VMCIEvent_Init -- * * General init code. * * Results: * VMCI_SUCCESS on success, appropriate error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCIEvent_Init(void) { int i; for (i = 0; i < VMCI_EVENT_MAX; i++) { VMCIList_Init(&subscriberArray[i]); } return VMCI_InitLock(&subscriberLock, "VMCIEventSubscriberLock", VMCI_LOCK_RANK_EVENT); } /* *---------------------------------------------------------------------- * * VMCIEvent_Exit -- * * General exit code. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void VMCIEvent_Exit(void) { VMCIListItem *iter, *iter2; VMCI_Event e; /* We free all memory at exit. */ for (e = 0; e < VMCI_EVENT_MAX; e++) { VMCIList_ScanSafe(iter, iter2, &subscriberArray[e]) { VMCISubscription *cur; /* * We should never get here because all events should have been * unregistered before we try to unload the driver module. * Also, delayed callbacks could still be firing so this cleanup * would not be safe. * Still it is better to free the memory than not ... so we * leave this code in just in case.... * */ ASSERT(FALSE); cur = VMCIList_Entry(iter, VMCISubscription, subscriberListItem); VMCI_FreeKernelMem(cur, sizeof *cur); } } VMCI_CleanupLock(&subscriberLock); } /* *----------------------------------------------------------------------------- * * VMCIEvent_Sync -- * * Use this as a synchronization point when setting globals, for example, * during device shutdown. * * Results: * TRUE. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMCIEvent_Sync(void) { VMCILockFlags lockFlags; VMCI_GrabLock_BH(&subscriberLock, &lockFlags); VMCI_ReleaseLock_BH(&subscriberLock, lockFlags); } /* *----------------------------------------------------------------------------- * * VMCIEvent_CheckHostCapabilities -- * * Verify that the host supports the hypercalls we need. If it does not, * try to find fallback hypercalls and use those instead. * * Results: * TRUE if required hypercalls (or fallback hypercalls) are * supported by the host, FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool VMCIEvent_CheckHostCapabilities(void) { /* VMCIEvent does not require any hypercalls. */ return TRUE; } /* *----------------------------------------------------------------------------- * * VMCIEventGet -- * * Gets a reference to the given VMCISubscription. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VMCIEventGet(VMCISubscription *entry) // IN { ASSERT(entry); entry->refCount++; } /* *----------------------------------------------------------------------------- * * VMCIEventRelease -- * * Releases the given VMCISubscription. * * Results: * None. * * Side effects: * Fires the destroy event if the reference count has gone to zero. * *----------------------------------------------------------------------------- */ static void VMCIEventRelease(VMCISubscription *entry) // IN { ASSERT(entry); ASSERT(entry->refCount > 0); entry->refCount--; if (entry->refCount == 0) { VMCI_SignalEvent(&entry->destroyEvent); } } /* *------------------------------------------------------------------------------ * * EventReleaseCB -- * * Callback to release the event entry reference. It is called by the * VMCI_WaitOnEvent function before it blocks. * * Result: * None. * * Side effects: * None. * *------------------------------------------------------------------------------ */ static int EventReleaseCB(void *clientData) // IN { VMCILockFlags flags; VMCISubscription *sub = (VMCISubscription *)clientData; ASSERT(sub); VMCI_GrabLock_BH(&subscriberLock, &flags); VMCIEventRelease(sub); VMCI_ReleaseLock_BH(&subscriberLock, flags); return 0; } /* *----------------------------------------------------------------------------- * * VMCIEventFind -- * * Find entry. Assumes lock is held. * * Results: * Entry if found, NULL if not. * * Side effects: * Increments the VMCISubscription refcount if an entry is found. * *----------------------------------------------------------------------------- */ static VMCISubscription * VMCIEventFind(VMCIId subID) // IN { VMCIListItem *iter; VMCI_Event e; for (e = 0; e < VMCI_EVENT_MAX; e++) { VMCIList_Scan(iter, &subscriberArray[e]) { VMCISubscription *cur = VMCIList_Entry(iter, VMCISubscription, subscriberListItem); if (cur->id == subID) { VMCIEventGet(cur); return cur; } } } return NULL; } /* *---------------------------------------------------------------------- * * VMCIEventDelayedDispatchCB -- * * Calls the specified callback in a delayed context. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void VMCIEventDelayedDispatchCB(void *data) // IN { VMCIDelayedEventInfo *eventInfo; VMCISubscription *sub; VMCI_EventData *ed; VMCILockFlags flags; eventInfo = (VMCIDelayedEventInfo *)data; ASSERT(eventInfo); ASSERT(eventInfo->sub); sub = eventInfo->sub; ed = (VMCI_EventData *)eventInfo->eventPayload; sub->callback(sub->id, ed, sub->callbackData); VMCI_GrabLock_BH(&subscriberLock, &flags); VMCIEventRelease(sub); VMCI_ReleaseLock_BH(&subscriberLock, flags); VMCI_FreeKernelMem(eventInfo, sizeof *eventInfo); } /* *---------------------------------------------------------------------------- * * VMCIEventDeliver -- * * Actually delivers the events to the subscribers. * * Results: * None. * * Side effects: * The callback function for each subscriber is invoked. * *---------------------------------------------------------------------------- */ static int VMCIEventDeliver(VMCIEventMsg *eventMsg) // IN { int err = VMCI_SUCCESS; VMCIListItem *iter; VMCILockFlags flags; VMCIList noDelayList; VMCIList_Init(&noDelayList); ASSERT(eventMsg); VMCI_GrabLock_BH(&subscriberLock, &flags); VMCIList_Scan(iter, &subscriberArray[eventMsg->eventData.event]) { VMCISubscription *cur = VMCIList_Entry(iter, VMCISubscription, subscriberListItem); ASSERT(cur && cur->event == eventMsg->eventData.event); if (cur->runDelayed) { VMCIDelayedEventInfo *eventInfo; if ((eventInfo = VMCI_AllocKernelMem(sizeof *eventInfo, (VMCI_MEMORY_ATOMIC | VMCI_MEMORY_NONPAGED))) == NULL) { err = VMCI_ERROR_NO_MEM; goto out; } VMCIEventGet(cur); memset(eventInfo, 0, sizeof *eventInfo); memcpy(eventInfo->eventPayload, VMCI_DG_PAYLOAD(eventMsg), (size_t)eventMsg->hdr.payloadSize); eventInfo->sub = cur; err = VMCI_ScheduleDelayedWork(VMCIEventDelayedDispatchCB, eventInfo); if (err != VMCI_SUCCESS) { VMCIEventRelease(cur); VMCI_FreeKernelMem(eventInfo, sizeof *eventInfo); goto out; } } else { VMCIEventRef *eventRef; /* * To avoid possible lock rank voilation when holding * subscriberLock, we construct a local list of * subscribers and release subscriberLock before * invokes the callbacks. This is similar to delayed * callbacks, but callbacks is invoked right away here. */ if ((eventRef = VMCI_AllocKernelMem(sizeof *eventRef, (VMCI_MEMORY_ATOMIC | VMCI_MEMORY_NONPAGED))) == NULL) { err = VMCI_ERROR_NO_MEM; goto out; } VMCIEventGet(cur); eventRef->sub = cur; VMCIList_InitEntry(&eventRef->listItem); VMCIList_Insert(&eventRef->listItem, &noDelayList); } } out: VMCI_ReleaseLock_BH(&subscriberLock, flags); if (!VMCIList_Empty(&noDelayList)) { VMCI_EventData *ed; VMCIListItem *iter2; VMCIList_ScanSafe(iter, iter2, &noDelayList) { VMCIEventRef *eventRef = VMCIList_Entry(iter, VMCIEventRef, listItem); VMCISubscription *cur = eventRef->sub; uint8 eventPayload[sizeof(VMCIEventData_Max)]; /* We set event data before each callback to ensure isolation. */ memset(eventPayload, 0, sizeof eventPayload); memcpy(eventPayload, VMCI_DG_PAYLOAD(eventMsg), (size_t)eventMsg->hdr.payloadSize); ed = (VMCI_EventData *)eventPayload; cur->callback(cur->id, ed, cur->callbackData); VMCI_GrabLock_BH(&subscriberLock, &flags); VMCIEventRelease(cur); VMCI_ReleaseLock_BH(&subscriberLock, flags); VMCI_FreeKernelMem(eventRef, sizeof *eventRef); } } return err; } /* *---------------------------------------------------------------------- * * VMCIEvent_Dispatch -- * * Dispatcher for the VMCI_EVENT_RECEIVE datagrams. Calls all * subscribers for given event. * * Results: * VMCI_SUCCESS on success, error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCIEvent_Dispatch(VMCIDatagram *msg) // IN { VMCIEventMsg *eventMsg = (VMCIEventMsg *)msg; ASSERT(msg && msg->src.context == VMCI_HYPERVISOR_CONTEXT_ID && msg->dst.resource == VMCI_EVENT_HANDLER); if (msg->payloadSize < sizeof(VMCI_Event) || msg->payloadSize > sizeof(VMCIEventData_Max)) { return VMCI_ERROR_INVALID_ARGS; } if (!VMCI_EVENT_VALID(eventMsg->eventData.event)) { return VMCI_ERROR_EVENT_UNKNOWN; } VMCIEventDeliver(eventMsg); return VMCI_SUCCESS; } /* *---------------------------------------------------------------------- * * VMCIEventRegisterSubscription -- * * Initialize and add subscription to subscriber list. * * Results: * VMCI_SUCCESS on success, error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int VMCIEventRegisterSubscription(VMCISubscription *sub, // IN VMCI_Event event, // IN uint32 flags, // IN VMCI_EventCB callback, // IN void *callbackData) // IN { # define VMCI_EVENT_MAX_ATTEMPTS 10 static VMCIId subscriptionID = 0; VMCILockFlags lockFlags; uint32 attempts = 0; int result; Bool success; ASSERT(sub); if (!VMCI_EVENT_VALID(event) || callback == NULL) { VMCI_DEBUG_LOG(4, (LGPFX"Failed to subscribe to event (type=%d) " "(callback=%p) (data=%p).\n", event, callback, callbackData)); return VMCI_ERROR_INVALID_ARGS; } if (vmkernel) { /* * In the vmkernel we defer delivery of events to a helper world. This * makes the event delivery more consistent across hosts and guests with * regard to which locks are held. Memory access events are an exception * to this, since clients need to know immediately that the device * memory is disabled (if we delay such events, then clients may be * notified too late). */ if (VMCI_EVENT_MEM_ACCESS_ON == event || VMCI_EVENT_MEM_ACCESS_OFF == event) { /* * Client must expect to get such events synchronously, and should * perform its locking accordingly. If it can't handle this, then * fail. */ if (flags & VMCI_FLAG_EVENT_DELAYED_CB) { return VMCI_ERROR_INVALID_ARGS; } sub->runDelayed = FALSE; } else { sub->runDelayed = TRUE; } } else if (!VMCI_CanScheduleDelayedWork()) { /* * If the platform doesn't support delayed work callbacks then don't * allow registration for them. */ if (flags & VMCI_FLAG_EVENT_DELAYED_CB) { return VMCI_ERROR_INVALID_ARGS; } sub->runDelayed = FALSE; } else { /* * The platform supports delayed work callbacks. Honor the requested * flags */ sub->runDelayed = (flags & VMCI_FLAG_EVENT_DELAYED_CB) ? TRUE : FALSE; } sub->refCount = 1; sub->event = event; sub->callback = callback; sub->callbackData = callbackData; VMCIList_InitEntry(&sub->subscriberListItem); VMCI_GrabLock_BH(&subscriberLock, &lockFlags); /* Check if creation of a new event is allowed. */ if (!VMCI_CanCreate()) { result = VMCI_ERROR_UNAVAILABLE; goto exit; } for (success = FALSE, attempts = 0; success == FALSE && attempts < VMCI_EVENT_MAX_ATTEMPTS; attempts++) { VMCISubscription *existingSub = NULL; /* * We try to get an id a couple of time before claiming we are out of * resources. */ sub->id = ++subscriptionID; /* Test for duplicate id. */ existingSub = VMCIEventFind(sub->id); if (existingSub == NULL) { /* We succeeded if we didn't find a duplicate. */ success = TRUE; } else { VMCIEventRelease(existingSub); } } if (success) { VMCI_CreateEvent(&sub->destroyEvent); VMCIList_Insert(&sub->subscriberListItem, &subscriberArray[event]); result = VMCI_SUCCESS; } else { result = VMCI_ERROR_NO_RESOURCES; } exit: VMCI_ReleaseLock_BH(&subscriberLock, lockFlags); return result; # undef VMCI_EVENT_MAX_ATTEMPTS } /* *---------------------------------------------------------------------- * * VMCIEventUnregisterSubscription -- * * Remove subscription from subscriber list. * * Results: * VMCISubscription when found, NULL otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ static VMCISubscription * VMCIEventUnregisterSubscription(VMCIId subID) // IN { VMCILockFlags flags; VMCISubscription *s; VMCI_GrabLock_BH(&subscriberLock, &flags); s = VMCIEventFind(subID); if (s != NULL) { VMCIEventRelease(s); VMCIList_Remove(&s->subscriberListItem); } VMCI_ReleaseLock_BH(&subscriberLock, flags); if (s != NULL) { VMCI_WaitOnEvent(&s->destroyEvent, EventReleaseCB, s); VMCI_DestroyEvent(&s->destroyEvent); } return s; } /* *---------------------------------------------------------------------- * * vmci_event_subscribe -- * * Subscribe to given event. The callback specified can be fired * in different contexts depending on what flag is specified while * registering. If flags contains VMCI_FLAG_EVENT_NONE then the * callback is fired with the subscriber lock held (and BH context * on the guest). If flags contain VMCI_FLAG_EVENT_DELAYED_CB then * the callback is fired with no locks held in thread context. * This is useful because other VMCIEvent functions can be called, * but it also increases the chances that an event will be dropped. * * Results: * VMCI_SUCCESS on success, error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_event_subscribe) int vmci_event_subscribe(VMCI_Event event, // IN #if !defined(linux) || defined(VMKERNEL) uint32 flags, // IN #endif // !linux || VMKERNEL VMCI_EventCB callback, // IN void *callbackData, // IN VMCIId *subscriptionID) // OUT { int retval; #if defined(linux) && !defined(VMKERNEL) uint32 flags = VMCI_FLAG_EVENT_NONE; #endif // linux && !VMKERNEL VMCISubscription *s = NULL; if (subscriptionID == NULL) { VMCI_DEBUG_LOG(4, (LGPFX"Invalid subscription (NULL).\n")); return VMCI_ERROR_INVALID_ARGS; } s = VMCI_AllocKernelMem(sizeof *s, VMCI_MEMORY_NONPAGED); if (s == NULL) { return VMCI_ERROR_NO_MEM; } retval = VMCIEventRegisterSubscription(s, event, flags, callback, callbackData); if (retval < VMCI_SUCCESS) { VMCI_FreeKernelMem(s, sizeof *s); return retval; } *subscriptionID = s->id; return retval; } /* *---------------------------------------------------------------------- * * vmci_event_unsubscribe -- * * Unsubscribe to given event. Removes it from list and frees it. * Will return callbackData if requested by caller. * * Results: * VMCI_SUCCESS on success, error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_event_unsubscribe) int vmci_event_unsubscribe(VMCIId subID) // IN { VMCISubscription *s; /* * Return subscription. At this point we know noone else is accessing * the subscription so we can free it. */ s = VMCIEventUnregisterSubscription(subID); if (s == NULL) { return VMCI_ERROR_NOT_FOUND; } VMCI_FreeKernelMem(s, sizeof *s); return VMCI_SUCCESS; } open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciDatagram.c0000644765153500003110000006475312220061556023256 0ustar dtormts/********************************************************* * Copyright (C) 2006-2011 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciDatagram.c -- * * This file implements the VMCI Simple Datagram API on the host. */ #include "vmci_kernel_if.h" #include "vm_assert.h" #include "vmci_defs.h" #include "vmci_infrastructure.h" #include "vmciCommonInt.h" #include "vmciContext.h" #include "vmciDatagram.h" #include "vmciDriver.h" #include "vmciEvent.h" #include "vmciHashtable.h" #include "vmciKernelAPI.h" #include "vmciResource.h" #include "vmciRoute.h" #if defined(VMKERNEL) # include "vmciVmkInt.h" # include "vm_libc.h" # include "helper_ext.h" #endif #define LGPFX "VMCIDatagram: " /* * DatagramEntry describes the datagram entity. It is used for datagram * entities created only on the host. */ typedef struct DatagramEntry { VMCIResource resource; uint32 flags; Bool runDelayed; VMCIDatagramRecvCB recvCB; void *clientData; VMCIEvent destroyEvent; VMCIPrivilegeFlags privFlags; } DatagramEntry; typedef struct VMCIDelayedDatagramInfo { Bool inDGHostQueue; DatagramEntry *entry; VMCIDatagram msg; } VMCIDelayedDatagramInfo; static Atomic_uint32 delayedDGHostQueueSize; static int VMCIDatagramGetPrivFlagsInt(VMCIId contextID, VMCIHandle handle, VMCIPrivilegeFlags *privFlags); static void DatagramFreeCB(void *resource); static int DatagramReleaseCB(void *clientData); /*------------------------------ Helper functions ----------------------------*/ /* *------------------------------------------------------------------------------ * * DatagramFreeCB -- * Callback to free datagram structure when resource is no longer used, * ie. the reference count reached 0. * * Result: * None. * *------------------------------------------------------------------------------ */ static void DatagramFreeCB(void *clientData) { DatagramEntry *entry = (DatagramEntry *)clientData; ASSERT(entry); VMCI_SignalEvent(&entry->destroyEvent); /* * The entry is freed in VMCIDatagram_DestroyHnd, who is waiting for the * above signal. */ } /* *------------------------------------------------------------------------------ * * DatagramReleaseCB -- * * Callback to release the resource reference. It is called by the * VMCI_WaitOnEvent function before it blocks. * * Result: * None. * *------------------------------------------------------------------------------ */ static int DatagramReleaseCB(void *clientData) { DatagramEntry *entry = (DatagramEntry *)clientData; ASSERT(entry); VMCIResource_Release(&entry->resource); return 0; } /* *------------------------------------------------------------------------------ * * DatagramCreateHnd -- * * Internal function to create a datagram entry given a handle. * * Results: * VMCI_SUCCESS if created, negative errno value otherwise. * * Side effects: * None. * *------------------------------------------------------------------------------ */ static int DatagramCreateHnd(VMCIId resourceID, // IN: uint32 flags, // IN: VMCIPrivilegeFlags privFlags, // IN: VMCIDatagramRecvCB recvCB, // IN: void *clientData, // IN: VMCIHandle *outHandle) // OUT: { int result; VMCIId contextID; VMCIHandle handle; DatagramEntry *entry; ASSERT(recvCB != NULL); ASSERT(outHandle != NULL); ASSERT(!(privFlags & ~VMCI_PRIVILEGE_ALL_FLAGS)); if ((flags & VMCI_FLAG_WELLKNOWN_DG_HND) != 0) { return VMCI_ERROR_INVALID_ARGS; } else { if ((flags & VMCI_FLAG_ANYCID_DG_HND) != 0) { contextID = VMCI_INVALID_ID; } else { contextID = vmci_get_context_id(); if (contextID == VMCI_INVALID_ID) { return VMCI_ERROR_NO_RESOURCES; } } if (resourceID == VMCI_INVALID_ID) { resourceID = VMCIResource_GetID(contextID); if (resourceID == VMCI_INVALID_ID) { return VMCI_ERROR_NO_HANDLE; } } handle = VMCI_MAKE_HANDLE(contextID, resourceID); } entry = VMCI_AllocKernelMem(sizeof *entry, VMCI_MEMORY_NONPAGED); if (entry == NULL) { VMCI_WARNING((LGPFX"Failed allocating memory for datagram entry.\n")); return VMCI_ERROR_NO_MEM; } if (!VMCI_CanScheduleDelayedWork()) { if (flags & VMCI_FLAG_DG_DELAYED_CB) { VMCI_FreeKernelMem(entry, sizeof *entry); return VMCI_ERROR_INVALID_ARGS; } entry->runDelayed = FALSE; } else { entry->runDelayed = (flags & VMCI_FLAG_DG_DELAYED_CB) ? TRUE : FALSE; } entry->flags = flags; entry->recvCB = recvCB; entry->clientData = clientData; VMCI_CreateEvent(&entry->destroyEvent); entry->privFlags = privFlags; /* Make datagram resource live. */ result = VMCIResource_Add(&entry->resource, VMCI_RESOURCE_TYPE_DATAGRAM, handle, DatagramFreeCB, entry); if (result != VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to add new resource (handle=0x%x:0x%x).\n", handle.context, handle.resource)); VMCI_DestroyEvent(&entry->destroyEvent); VMCI_FreeKernelMem(entry, sizeof *entry); return result; } *outHandle = handle; return VMCI_SUCCESS; } /*------------------------------ Init functions ----------------------------*/ /* *------------------------------------------------------------------------------ * * VMCIDatagram_Init -- * * Initialize Datagram API, ie. register the API functions with their * corresponding vectors. * * Result: * None. * * Side effects: * None. * *------------------------------------------------------------------------------ */ int VMCIDatagram_Init(void) { Atomic_Write(&delayedDGHostQueueSize, 0); return VMCI_SUCCESS; } /* *------------------------------------------------------------------------------ * * VMCIDatagram_Exit -- * * Cleanup Datagram API. * * Result: * None. * * Side effects: * None. * *------------------------------------------------------------------------------ */ void VMCIDatagram_Exit(void) { } /*------------------------------ Public API functions ------------------------*/ /* *------------------------------------------------------------------------------ * * vmci_datagram_create_handle -- * * Creates a host context datagram endpoint and returns a handle to it. * * Results: * VMCI_SUCCESS if created, negative errno value otherwise. * * Side effects: * None. * *------------------------------------------------------------------------------ */ VMCI_EXPORT_SYMBOL(vmci_datagram_create_handle) int vmci_datagram_create_handle( VMCIId resourceID, // IN: Optional, generated if VMCI_INVALID_ID uint32 flags, // IN: VMCIDatagramRecvCB recvCB, // IN: void *clientData, // IN: VMCIHandle *outHandle) // OUT: newly created handle { if (outHandle == NULL) { return VMCI_ERROR_INVALID_ARGS; } if (recvCB == NULL) { VMCI_DEBUG_LOG(4, (LGPFX"Client callback needed when creating datagram.\n")); return VMCI_ERROR_INVALID_ARGS; } return DatagramCreateHnd(resourceID, flags, VMCI_DEFAULT_PROC_PRIVILEGE_FLAGS, recvCB, clientData, outHandle); } /* *------------------------------------------------------------------------------ * * vmci_datagram_create_handle_priv -- * * Creates a host context datagram endpoint and returns a handle to it. * * Results: * VMCI_SUCCESS if created, negative errno value otherwise. * * Side effects: * None. * *------------------------------------------------------------------------------ */ VMCI_EXPORT_SYMBOL(vmci_datagram_create_handle_priv) int vmci_datagram_create_handle_priv( VMCIId resourceID, // IN: Optional, generated if VMCI_INVALID_ID uint32 flags, // IN: VMCIPrivilegeFlags privFlags, // IN: VMCIDatagramRecvCB recvCB, // IN: void *clientData, // IN: VMCIHandle *outHandle) // OUT: newly created handle { if (outHandle == NULL) { return VMCI_ERROR_INVALID_ARGS; } if (recvCB == NULL) { VMCI_DEBUG_LOG(4, (LGPFX"Client callback needed when creating datagram.\n")); return VMCI_ERROR_INVALID_ARGS; } if (privFlags & ~VMCI_PRIVILEGE_ALL_FLAGS) { return VMCI_ERROR_INVALID_ARGS; } return DatagramCreateHnd(resourceID, flags, privFlags, recvCB, clientData, outHandle); } /* *------------------------------------------------------------------------------ * * vmci_datagram_destroy_handle -- * * Destroys a handle. * * Results: * None. * * Side effects: * None. * *------------------------------------------------------------------------------ */ VMCI_EXPORT_SYMBOL(vmci_datagram_destroy_handle) int vmci_datagram_destroy_handle(VMCIHandle handle) // IN { DatagramEntry *entry; VMCIResource *resource = VMCIResource_Get(handle, VMCI_RESOURCE_TYPE_DATAGRAM); if (resource == NULL) { VMCI_DEBUG_LOG(4, (LGPFX"Failed to destroy datagram (handle=0x%x:0x%x).\n", handle.context, handle.resource)); return VMCI_ERROR_NOT_FOUND; } entry = RESOURCE_CONTAINER(resource, DatagramEntry, resource); VMCIResource_Remove(handle, VMCI_RESOURCE_TYPE_DATAGRAM); /* * We now wait on the destroyEvent and release the reference we got * above. */ VMCI_WaitOnEvent(&entry->destroyEvent, DatagramReleaseCB, entry); /* * We know that we are now the only reference to the above entry so * can safely free it. */ VMCI_DestroyEvent(&entry->destroyEvent); VMCI_FreeKernelMem(entry, sizeof *entry); return VMCI_SUCCESS; } /* *------------------------------------------------------------------------------ * * VMCIDatagramGetPrivFlagsInt -- * * Internal utilility function with the same purpose as * VMCIDatagram_GetPrivFlags that also takes a contextID. * * Result: * VMCI_SUCCESS on success, VMCI_ERROR_INVALID_ARGS if handle is invalid. * * Side effects: * None. * *------------------------------------------------------------------------------ */ static int VMCIDatagramGetPrivFlagsInt(VMCIId contextID, // IN VMCIHandle handle, // IN VMCIPrivilegeFlags *privFlags) // OUT { ASSERT(privFlags); ASSERT(contextID != VMCI_INVALID_ID); if (contextID == VMCI_HOST_CONTEXT_ID) { DatagramEntry *srcEntry; VMCIResource *resource; resource = VMCIResource_Get(handle, VMCI_RESOURCE_TYPE_DATAGRAM); if (resource == NULL) { return VMCI_ERROR_INVALID_ARGS; } srcEntry = RESOURCE_CONTAINER(resource, DatagramEntry, resource); *privFlags = srcEntry->privFlags; VMCIResource_Release(resource); } else if (contextID == VMCI_HYPERVISOR_CONTEXT_ID) { *privFlags = VMCI_MAX_PRIVILEGE_FLAGS; } else { *privFlags = vmci_context_get_priv_flags(contextID); } return VMCI_SUCCESS; } /* *------------------------------------------------------------------------------ * * VMCIDatagram_GetPrivFlags -- * * Utilility function that retrieves the privilege flags * associated with a given datagram handle. For hypervisor and * guest endpoints, the privileges are determined by the context * ID, but for host endpoints privileges are associated with the * complete handle. * * Result: * VMCI_SUCCESS on success, VMCI_ERROR_INVALID_ARGS if handle is invalid. * * Side effects: * None. * *------------------------------------------------------------------------------ */ int VMCIDatagram_GetPrivFlags(VMCIHandle handle, // IN VMCIPrivilegeFlags *privFlags) // OUT { if (privFlags == NULL || handle.context == VMCI_INVALID_ID) { return VMCI_ERROR_INVALID_ARGS; } return VMCIDatagramGetPrivFlagsInt(handle.context, handle, privFlags); } /* *----------------------------------------------------------------------------- * * VMCIDatagramDelayedDispatchCB -- * * Calls the specified callback in a delayed context. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VMCIDatagramDelayedDispatchCB(void *data) // IN { Bool inDGHostQueue; VMCIDelayedDatagramInfo *dgInfo = (VMCIDelayedDatagramInfo *)data; ASSERT(data); dgInfo->entry->recvCB(dgInfo->entry->clientData, &dgInfo->msg); VMCIResource_Release(&dgInfo->entry->resource); inDGHostQueue = dgInfo->inDGHostQueue; VMCI_FreeKernelMem(dgInfo, sizeof *dgInfo + (size_t)dgInfo->msg.payloadSize); if (inDGHostQueue) { Atomic_Dec(&delayedDGHostQueueSize); } } /* *------------------------------------------------------------------------------ * * VMCIDatagramDispatchAsHost -- * * Dispatch datagram as a host, to the host or other vm context. This * function cannot dispatch to hypervisor context handlers. This should * have been handled before we get here by VMCIDatagramDispatch. * * Result: * Number of bytes sent on success, appropriate error code otherwise. * * Side effects: * None. * *------------------------------------------------------------------------------ */ static int VMCIDatagramDispatchAsHost(VMCIId contextID, // IN: VMCIDatagram *dg) // IN: { int retval; size_t dgSize; VMCIPrivilegeFlags srcPrivFlags; ASSERT(dg); ASSERT(VMCI_HostPersonalityActive()); dgSize = VMCI_DG_SIZE(dg); if (contextID == VMCI_HOST_CONTEXT_ID && dg->dst.context == VMCI_HYPERVISOR_CONTEXT_ID) { VMCI_DEBUG_LOG(4, (LGPFX"Host cannot talk to hypervisor\n")); return VMCI_ERROR_DST_UNREACHABLE; } ASSERT(dg->dst.context != VMCI_HYPERVISOR_CONTEXT_ID); /* Chatty. */ // VMCI_DEBUG_LOG(10, (LGPFX"Sending from (handle=0x%x:0x%x) to " // "(handle=0x%x:0x%x) (size=%u bytes).\n", // dg->src.context, dg->src.resource, // dg->dst.context, dg->dst.resource, (uint32)dgSize)); /* * Check that source handle matches sending context. */ if (dg->src.context != contextID) { VMCI_DEBUG_LOG(4, (LGPFX"Sender context (ID=0x%x) is not owner of src " "datagram entry (handle=0x%x:0x%x).\n", contextID, dg->src.context, dg->src.resource)); return VMCI_ERROR_NO_ACCESS; } /* * Get hold of privileges of sending endpoint. */ retval = VMCIDatagramGetPrivFlagsInt(contextID, dg->src, &srcPrivFlags); if (retval != VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Couldn't get privileges (handle=0x%x:0x%x).\n", dg->src.context, dg->src.resource)); return retval; } /* Determine if we should route to host or guest destination. */ if (dg->dst.context == VMCI_HOST_CONTEXT_ID) { /* Route to host datagram entry. */ DatagramEntry *dstEntry; VMCIResource *resource; if (dg->src.context == VMCI_HYPERVISOR_CONTEXT_ID && dg->dst.resource == VMCI_EVENT_HANDLER) { return VMCIEvent_Dispatch(dg); } resource = VMCIResource_Get(dg->dst, VMCI_RESOURCE_TYPE_DATAGRAM); if (resource == NULL) { VMCI_DEBUG_LOG(4, (LGPFX"Sending to invalid destination " "(handle=0x%x:0x%x).\n", dg->dst.context, dg->dst.resource)); return VMCI_ERROR_INVALID_RESOURCE; } dstEntry = RESOURCE_CONTAINER(resource, DatagramEntry, resource); if (VMCIDenyInteraction(srcPrivFlags, dstEntry->privFlags)) { VMCIResource_Release(resource); return VMCI_ERROR_NO_ACCESS; } ASSERT(dstEntry->recvCB); /* * If a VMCI datagram destined for the host is also sent by the * host, we always run it delayed. This ensures that no locks * are held when the datagram callback runs. */ if (dstEntry->runDelayed || (dg->src.context == VMCI_HOST_CONTEXT_ID && VMCI_CanScheduleDelayedWork())) { VMCIDelayedDatagramInfo *dgInfo; if (Atomic_FetchAndAdd(&delayedDGHostQueueSize, 1) == VMCI_MAX_DELAYED_DG_HOST_QUEUE_SIZE) { Atomic_Dec(&delayedDGHostQueueSize); VMCIResource_Release(resource); return VMCI_ERROR_NO_MEM; } dgInfo = VMCI_AllocKernelMem(sizeof *dgInfo + (size_t)dg->payloadSize, (VMCI_MEMORY_ATOMIC | VMCI_MEMORY_NONPAGED)); if (NULL == dgInfo) { Atomic_Dec(&delayedDGHostQueueSize); VMCIResource_Release(resource); return VMCI_ERROR_NO_MEM; } dgInfo->inDGHostQueue = TRUE; dgInfo->entry = dstEntry; memcpy(&dgInfo->msg, dg, dgSize); retval = VMCI_ScheduleDelayedWork(VMCIDatagramDelayedDispatchCB, dgInfo); if (retval < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to schedule delayed work for datagram " "(result=%d).\n", retval)); VMCI_FreeKernelMem(dgInfo, sizeof *dgInfo + (size_t)dg->payloadSize); VMCIResource_Release(resource); Atomic_Dec(&delayedDGHostQueueSize); return retval; } } else { retval = dstEntry->recvCB(dstEntry->clientData, dg); VMCIResource_Release(resource); if (retval < VMCI_SUCCESS) { return retval; } } } else { /* * Route to destination VM context. */ VMCIDatagram *newDG; if (contextID != dg->dst.context) { if (VMCIDenyInteraction(srcPrivFlags, vmci_context_get_priv_flags(dg->dst.context))) { VMCI_DEBUG_LOG(4, (LGPFX"Interaction denied (%X/%X - %X/%X)\n", contextID, srcPrivFlags, dg->dst.context, vmci_context_get_priv_flags(dg->dst.context))); return VMCI_ERROR_NO_ACCESS; } else if (VMCI_CONTEXT_IS_VM(contextID)) { /* * If the sending context is a VM, it cannot reach another VM. */ if (!vmkernel) { VMCI_DEBUG_LOG(4, (LGPFX"Datagram communication between VMs not " "supported (src=0x%x, dst=0x%x).\n", contextID, dg->dst.context)); return VMCI_ERROR_DST_UNREACHABLE; } } } /* We make a copy to enqueue. */ newDG = VMCI_AllocKernelMem(dgSize, VMCI_MEMORY_NORMAL); if (newDG == NULL) { VMCI_DEBUG_LOG(4, (LGPFX"No memory for datagram\n")); return VMCI_ERROR_NO_MEM; } memcpy(newDG, dg, dgSize); retval = VMCIContext_EnqueueDatagram(dg->dst.context, newDG); if (retval < VMCI_SUCCESS) { VMCI_FreeKernelMem(newDG, dgSize); VMCI_DEBUG_LOG(4, (LGPFX"Enqueue failed\n")); return retval; } } /* The datagram is freed when the context reads it. */ /* Chatty. */ // VMCI_DEBUG_LOG(10, (LGPFX"Sent datagram (size=%u bytes).\n", // (uint32)dgSize)); /* * We currently truncate the size to signed 32 bits. This doesn't * matter for this handler as it only support 4Kb messages. */ return (int)dgSize; } /* *------------------------------------------------------------------------------ * * VMCIDatagramDispatchAsGuest -- * * Dispatch datagram as a guest, down through the VMX and potentially to * the host. * * Result: * Number of bytes sent on success, appropriate error code otherwise. * * Side effects: * None. * *------------------------------------------------------------------------------ */ static int VMCIDatagramDispatchAsGuest(VMCIDatagram *dg) { #if defined(VMKERNEL) VMCI_WARNING((LGPFX"Cannot send down to host from VMKERNEL.\n")); return VMCI_ERROR_DST_UNREACHABLE; #else // VMKERNEL int retval; VMCIResource *resource; resource = VMCIResource_Get(dg->src, VMCI_RESOURCE_TYPE_DATAGRAM); if (NULL == resource) { return VMCI_ERROR_NO_HANDLE; } retval = VMCI_SendDatagram(dg); VMCIResource_Release(resource); return retval; #endif // VMKERNEL } /* *------------------------------------------------------------------------------ * * VMCIDatagram_Dispatch -- * * Dispatch datagram. This will determine the routing for the datagram * and dispatch it accordingly. * * Result: * Number of bytes sent on success, appropriate error code otherwise. * * Side effects: * None. * *------------------------------------------------------------------------------ */ int VMCIDatagram_Dispatch(VMCIId contextID, VMCIDatagram *dg, Bool fromGuest) { int retval; VMCIRoute route; ASSERT(dg); ASSERT_ON_COMPILE(sizeof(VMCIDatagram) == 24); if (VMCI_DG_SIZE(dg) > VMCI_MAX_DG_SIZE) { VMCI_DEBUG_LOG(4, (LGPFX"Payload (size=%"FMT64"u bytes) too big to " "send.\n", dg->payloadSize)); return VMCI_ERROR_INVALID_ARGS; } retval = VMCI_Route(&dg->src, &dg->dst, fromGuest, &route); if (retval < VMCI_SUCCESS) { VMCI_DEBUG_LOG(4, (LGPFX"Failed to route datagram (src=0x%x, dst=0x%x, " "err=%d)\n.", dg->src.context, dg->dst.context, retval)); return retval; } if (VMCI_ROUTE_AS_HOST == route) { if (VMCI_INVALID_ID == contextID) { contextID = VMCI_HOST_CONTEXT_ID; } return VMCIDatagramDispatchAsHost(contextID, dg); } if (VMCI_ROUTE_AS_GUEST == route) { return VMCIDatagramDispatchAsGuest(dg); } VMCI_WARNING((LGPFX"Unknown route (%d) for datagram.\n", route)); return VMCI_ERROR_DST_UNREACHABLE; } /* *------------------------------------------------------------------------------ * * VMCIDatagram_InvokeGuestHandler -- * * Invoke the handler for the given datagram. This is intended to be * called only when acting as a guest and receiving a datagram from the * virtual device. * * Result: * VMCI_SUCCESS on success, other error values on failure. * * Side effects: * None. * *------------------------------------------------------------------------------ */ int VMCIDatagram_InvokeGuestHandler(VMCIDatagram *dg) // IN { #if defined(VMKERNEL) VMCI_WARNING((LGPFX"Cannot dispatch within guest in VMKERNEL.\n")); return VMCI_ERROR_DST_UNREACHABLE; #else // VMKERNEL int retval; VMCIResource *resource; DatagramEntry *dstEntry; ASSERT(dg); resource = VMCIResource_Get(dg->dst, VMCI_RESOURCE_TYPE_DATAGRAM); if (NULL == resource) { VMCI_DEBUG_LOG(4, (LGPFX"destination (handle=0x%x:0x%x) doesn't exist.\n", dg->dst.context, dg->dst.resource)); return VMCI_ERROR_NO_HANDLE; } dstEntry = RESOURCE_CONTAINER(resource, DatagramEntry, resource); if (dstEntry->runDelayed) { VMCIDelayedDatagramInfo *dgInfo; dgInfo = VMCI_AllocKernelMem(sizeof *dgInfo + (size_t)dg->payloadSize, (VMCI_MEMORY_ATOMIC | VMCI_MEMORY_NONPAGED)); if (NULL == dgInfo) { VMCIResource_Release(resource); retval = VMCI_ERROR_NO_MEM; goto exit; } dgInfo->inDGHostQueue = FALSE; dgInfo->entry = dstEntry; memcpy(&dgInfo->msg, dg, VMCI_DG_SIZE(dg)); retval = VMCI_ScheduleDelayedWork(VMCIDatagramDelayedDispatchCB, dgInfo); if (retval < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to schedule delayed work for datagram " "(result=%d).\n", retval)); VMCI_FreeKernelMem(dgInfo, sizeof *dgInfo + (size_t)dg->payloadSize); VMCIResource_Release(resource); dgInfo = NULL; goto exit; } } else { dstEntry->recvCB(dstEntry->clientData, dg); VMCIResource_Release(resource); retval = VMCI_SUCCESS; } exit: return retval; #endif // VMKERNEL } /* *------------------------------------------------------------------------------ * * vmci_datagram_send -- * * Sends the payload to the destination datagram handle. * * Results: * Returns number of bytes sent if success, or error code if failure. * * Side effects: * None. * *------------------------------------------------------------------------------ */ VMCI_EXPORT_SYMBOL(vmci_datagram_send) int vmci_datagram_send(VMCIDatagram *msg) // IN { if (msg == NULL) { return VMCI_ERROR_INVALID_ARGS; } return VMCIDatagram_Dispatch(VMCI_INVALID_ID, msg, FALSE); } /* *----------------------------------------------------------------------------- * * VMCIDatagram_Sync -- * * Use this as a synchronization point when setting globals, for example, * during device shutdown. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMCIDatagram_Sync(void) { VMCIResource_Sync(); } /* *----------------------------------------------------------------------------- * * VMCIDatagram_CheckHostCapabilities -- * * Verify that the host supports the resources we need. * None are required for datagrams since they are implicitly supported. * * Results: * TRUE. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool VMCIDatagram_CheckHostCapabilities(void) { return TRUE; } open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciDriver.h0000644765153500003110000000601612220061556022762 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciDriver.h -- * * VMCI host driver interface. */ #ifndef _VMCI_DRIVER_H_ #define _VMCI_DRIVER_H_ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vmci_defs.h" #include "vmci_infrastructure.h" #include "vmciContext.h" /* * A few macros to encapsulate logging in common code. The macros * result in LOG/LOGThrottled on vmkernel and Log on hosted. */ #ifdef _WIN32 # include "vmciLog.h" #else // _WIN32 #if defined(VMKERNEL) && !defined(VMKERNEL_OFFSET_CHECKER) /* * LOGLEVEL_MODULE is defined in another header that gets included into the * dummy file used by the offsetchecker, which causes it to barf on the * redefinition. */ # define LOGLEVEL_MODULE_LEN 0 # define LOGLEVEL_MODULE VMCIVMK # include "log.h" # ifdef VMX86_LOG # define _VMCILOG(_args...) LOG(i, _args) # define VMCI_DEBUG_LOG(_level, _args) \ do { \ int i = _level; \ _VMCILOG _args ; \ } while(FALSE) # else // VMX86_LOG # define VMCI_DEBUG_LOG(_level, _args) # endif // VMX86_LOG #else // VMKERNEL # define VMCI_DEBUG_LEVEL 4 # define VMCI_DEBUG_LOG(_level, _args) \ do { \ if (_level < VMCI_DEBUG_LEVEL) { \ Log _args ; \ } \ } while(FALSE) #endif // VMKERNEL #define VMCI_LOG(_args) Log _args #define VMCI_WARNING(_args) Warning _args #endif // _WIN32 int VMCI_SharedInit(void); void VMCI_SharedCleanup(void); int VMCI_HostInit(void); void VMCI_HostCleanup(void); VMCIId VMCI_GetContextID(void); int VMCI_SendDatagram(VMCIDatagram *dg); void VMCIUtil_Init(void); void VMCIUtil_Exit(void); Bool VMCI_CheckHostCapabilities(void); void VMCI_ReadDatagramsFromPort(VMCIIoHandle ioHandle, VMCIIoPort dgInPort, uint8 *dgInBuffer, size_t dgInBufferSize); Bool VMCI_DeviceEnabled(void); #if defined(_WIN64) int VMCIDoSendDatagram(unsigned int dgSize, ULONG *dataPort, ULONG *resultPort, VMCIDatagram *dg); #endif // _WIN64 #endif // _VMCI_DRIVER_H_ open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciContext.h0000644765153500003110000001215312220061556023152 0ustar dtormts/********************************************************* * Copyright (C) 2006-2012 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciContext.h -- * * VMCI state to enable sending calls between VMs. */ #ifndef _VMCI_CONTEXT_H_ #define _VMCI_CONTEXT_H_ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vmci_defs.h" #include "vmci_call_defs.h" #include "vmci_handle_array.h" #include "vmci_infrastructure.h" #include "vmci_kernel_if.h" #include "vmciCommonInt.h" #define MAX_QUEUED_GUESTCALLS_PER_VM 100 typedef struct VMCIContext VMCIContext; int VMCIContext_Init(void); void VMCIContext_Exit(void); int VMCIContext_InitContext(VMCIId cid, VMCIPrivilegeFlags flags, uintptr_t eventHnd, int version, VMCIHostUser *user, VMCIContext **context); #ifdef VMKERNEL void VMCIContext_SetFSRState(VMCIContext *context, Bool isQuiesced, VMCIId migrateCid, uintptr_t eventHnd, Bool isLocked); VMCIContext *VMCIContext_FindAndUpdateSrcFSR(VMCIId migrateCid, uintptr_t eventHnd, uintptr_t *srcEventHnd); Bool VMCIContext_IsActiveHnd(VMCIContext *context, uintptr_t eventHnd); uintptr_t VMCIContext_GetActiveHnd(VMCIContext *context); void VMCIContext_SetInactiveHnd(VMCIContext *context, uintptr_t eventHnd); Bool VMCIContext_RemoveHnd(VMCIContext *context, uintptr_t eventHnd, uint32 *numOld, uint32 *numNew); void VMCIContext_ClearDatagrams(VMCIContext *context); void VMCIContext_SetId(VMCIContext *context, VMCIId cid); #endif Bool VMCIContext_SupportsHostQP(VMCIContext *context); void VMCIContext_ReleaseContext(VMCIContext *context); int VMCIContext_EnqueueDatagram(VMCIId cid, VMCIDatagram *dg); int VMCIContext_DequeueDatagram(VMCIContext *context, size_t *maxSize, VMCIDatagram **dg); int VMCIContext_PendingDatagrams(VMCIId cid, uint32 *pending); VMCIContext *VMCIContext_Get(VMCIId cid); void VMCIContext_Release(VMCIContext *context); Bool VMCIContext_Exists(VMCIId cid); VMCIId VMCIContext_GetId(VMCIContext *context); int VMCIContext_AddNotification(VMCIId contextID, VMCIId remoteCID); int VMCIContext_RemoveNotification(VMCIId contextID, VMCIId remoteCID); int VMCIContext_GetCheckpointState(VMCIId contextID, uint32 cptType, uint32 *numCIDs, char **cptBufPtr); int VMCIContext_SetCheckpointState(VMCIId contextID, uint32 cptType, uint32 numCIDs, char *cptBuf); void VMCIContext_RegisterGuestMem(VMCIContext *context, VMCIGuestMemID gid); void VMCIContext_ReleaseGuestMem(VMCIContext *context, VMCIGuestMemID gid); int VMCIContext_QueuePairCreate(VMCIContext *context, VMCIHandle handle); int VMCIContext_QueuePairDestroy(VMCIContext *context, VMCIHandle handle); Bool VMCIContext_QueuePairExists(VMCIContext *context, VMCIHandle handle); #ifndef VMX86_SERVER void VMCIContext_CheckAndSignalNotify(VMCIContext *context); # ifdef __linux__ /* TODO Windows and Mac OS. */ void VMCIUnsetNotify(VMCIContext *context); # endif #endif int VMCIContext_DoorbellCreate(VMCIId contextID, VMCIHandle handle); int VMCIContext_DoorbellDestroy(VMCIId contextID, VMCIHandle handle); int VMCIContext_DoorbellDestroyAll(VMCIId contextID); int VMCIContext_NotifyDoorbell(VMCIId cid, VMCIHandle handle, VMCIPrivilegeFlags srcPrivFlags); int VMCIContext_ReceiveNotificationsGet(VMCIId contextID, VMCIHandleArray **dbHandleArray, VMCIHandleArray **qpHandleArray); void VMCIContext_ReceiveNotificationsRelease(VMCIId contextID, VMCIHandleArray *dbHandleArray, VMCIHandleArray *qpHandleArray, Bool success); #if defined(VMKERNEL) void VMCIContext_SignalPendingDoorbells(VMCIId contextID); void VMCIContext_SignalPendingDatagrams(VMCIId contextID); int VMCIContext_FilterSet(VMCIId cid, VMCIFilterState *filterState); int VMCI_Uuid2ContextId(const char *uuidString, VMCIId *contextID); #endif // VMKERNEL #endif // _VMCI_CONTEXT_H_ open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciResource.c0000644765153500003110000002403712220061556023314 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciResource.c -- * * Implementation of the VMCI Resource Access Control API. */ #include "vmci_kernel_if.h" #include "vm_assert.h" #include "vmci_defs.h" #include "vmci_infrastructure.h" #include "vmciCommonInt.h" #include "vmciHashtable.h" #include "vmciResource.h" #if defined(VMKERNEL) # include "vmciVmkInt.h" # include "vm_libc.h" # include "helper_ext.h" # include "vmciDriver.h" #else # include "vmciDriver.h" #endif #define LGPFX "VMCIResource: " /* 0 through VMCI_RESERVED_RESOURCE_ID_MAX are reserved. */ static uint32 resourceID = VMCI_RESERVED_RESOURCE_ID_MAX + 1; static VMCILock resourceIdLock; static void VMCIResourceDoRemove(VMCIResource *resource); static VMCIHashTable *resourceTable = NULL; /* Public Resource Access Control API. */ /* *------------------------------------------------------------------------------ * * VMCIResource_Init -- * * Initializes the VMCI Resource Access Control API. Creates a hashtable * to hold all resources, and registers vectors and callbacks for * hypercalls. * * Results: * None. * * Side effects: * None. * *------------------------------------------------------------------------------ */ int VMCIResource_Init(void) { int err = VMCI_InitLock(&resourceIdLock, "VMCIRIDLock", VMCI_LOCK_RANK_RESOURCE); if (err < VMCI_SUCCESS) { return err; } resourceTable = VMCIHashTable_Create(128); if (resourceTable == NULL) { VMCI_WARNING((LGPFX"Failed creating a resource hash table for VMCI.\n")); VMCI_CleanupLock(&resourceIdLock); return VMCI_ERROR_NO_MEM; } return VMCI_SUCCESS; } /* *------------------------------------------------------------------------------ * * VMCIResource_Exit -- * * Cleans up resources. * * Results: * None. * * Side effects: * None. * *------------------------------------------------------------------------------ */ void VMCIResource_Exit(void) { /* Cleanup resources.*/ VMCI_CleanupLock(&resourceIdLock); if (resourceTable) { VMCIHashTable_Destroy(resourceTable); } } /* *------------------------------------------------------------------------------ * * VMCIResource_GetID -- * * Return resource ID. The first VMCI_RESERVED_RESOURCE_ID_MAX are * reserved so we start from its value + 1. * * Result: * VMCI resource id on success, VMCI_INVALID_ID on failure. * * Side effects: * None. * * *------------------------------------------------------------------------------ */ VMCIId VMCIResource_GetID(VMCIId contextID) { VMCIId oldRID = resourceID; VMCIId currentRID; Bool foundRID = FALSE; /* * Generate a unique resource ID. Keep on trying until we wrap around * in the RID space. */ ASSERT(oldRID > VMCI_RESERVED_RESOURCE_ID_MAX); do { VMCILockFlags flags; VMCIHandle handle; VMCI_GrabLock(&resourceIdLock, &flags); currentRID = resourceID; handle = VMCI_MAKE_HANDLE(contextID, currentRID); resourceID++; if (UNLIKELY(resourceID == VMCI_INVALID_ID)) { /* * Skip the reserved rids. */ resourceID = VMCI_RESERVED_RESOURCE_ID_MAX + 1; } VMCI_ReleaseLock(&resourceIdLock, flags); foundRID = !VMCIHashTable_EntryExists(resourceTable, handle); } while (!foundRID && resourceID != oldRID); if (UNLIKELY(!foundRID)) { return VMCI_INVALID_ID; } else { return currentRID; } } /* *------------------------------------------------------------------------------ * * VMCIResource_Add -- * * Results: * VMCI_SUCCESS if successful, error code if not. * * Side effects: * None. * *------------------------------------------------------------------------------ */ int VMCIResource_Add(VMCIResource *resource, // IN VMCIResourceType resourceType, // IN VMCIHandle resourceHandle, // IN VMCIResourceFreeCB containerFreeCB, // IN void *containerObject) // IN { int result; ASSERT(resource); if (VMCI_HANDLE_EQUAL(resourceHandle, VMCI_INVALID_HANDLE)) { VMCI_DEBUG_LOG(4, (LGPFX"Invalid argument resource (handle=0x%x:0x%x).\n", resourceHandle.context, resourceHandle.resource)); return VMCI_ERROR_INVALID_ARGS; } VMCIHashTable_InitEntry(&resource->hashEntry, resourceHandle); resource->type = resourceType; resource->containerFreeCB = containerFreeCB; resource->containerObject = containerObject; /* Add resource to hashtable. */ result = VMCIHashTable_AddEntry(resourceTable, &resource->hashEntry); if (result != VMCI_SUCCESS) { VMCI_DEBUG_LOG(4, (LGPFX"Failed to add entry to hash table " "(result=%d).\n", result)); return result; } return result; } /* *------------------------------------------------------------------------------ * * VMCIResource_Remove -- * * Results: * None. * * Side effects: * None. * *------------------------------------------------------------------------------ */ void VMCIResource_Remove(VMCIHandle resourceHandle, // IN: VMCIResourceType resourceType) // IN: { VMCIResource *resource = VMCIResource_Get(resourceHandle, resourceType); if (resource == NULL) { return; } /* Remove resource from hashtable. */ VMCIHashTable_RemoveEntry(resourceTable, &resource->hashEntry); VMCIResource_Release(resource); /* resource could be freed by now. */ } /* *------------------------------------------------------------------------------ * * VMCIResource_Get -- * * Results: * Resource is successful. Otherwise NULL. * * Side effects: * None. * *------------------------------------------------------------------------------ */ VMCIResource * VMCIResource_Get(VMCIHandle resourceHandle, // IN VMCIResourceType resourceType) // IN { VMCIResource *resource; VMCIHashEntry *entry = VMCIHashTable_GetEntry(resourceTable, resourceHandle); if (entry == NULL) { return NULL; } resource = RESOURCE_CONTAINER(entry, VMCIResource, hashEntry); if (resourceType == VMCI_RESOURCE_TYPE_ANY || resource->type == resourceType) { return resource; } VMCIHashTable_ReleaseEntry(resourceTable, entry); return NULL; } /* *------------------------------------------------------------------------------ * * VMCIResource_Hold -- * * Hold the given resource. This will hold the hashtable entry. This * is like doing a Get() but without having to lookup the resource by * handle. * * Results: * None. * * Side effects: * None. * *------------------------------------------------------------------------------ */ void VMCIResource_Hold(VMCIResource *resource) { ASSERT(resource); VMCIHashTable_HoldEntry(resourceTable, &resource->hashEntry); } /* *------------------------------------------------------------------------------ * * VMCIResourceDoRemove -- * * Deallocates data structures associated with the given resource * and invoke any call back registered for the resource. * * Results: * None. * * Side effects: * May deallocate memory and invoke a callback for the removed resource. * *------------------------------------------------------------------------------ */ static void INLINE VMCIResourceDoRemove(VMCIResource *resource) { ASSERT(resource); if (resource->containerFreeCB) { resource->containerFreeCB(resource->containerObject); /* Resource has been freed don't dereference it. */ } } /* *------------------------------------------------------------------------------ * * VMCIResource_Release -- * * Results: * None. * * Side effects: * resource's containerFreeCB will get called if last reference. * *------------------------------------------------------------------------------ */ int VMCIResource_Release(VMCIResource *resource) { int result; ASSERT(resource); result = VMCIHashTable_ReleaseEntry(resourceTable, &resource->hashEntry); if (result == VMCI_SUCCESS_ENTRY_DEAD) { VMCIResourceDoRemove(resource); } /* * We propagate the information back to caller in case it wants to know * whether entry was freed. */ return result; } /* *------------------------------------------------------------------------------ * * VMCIResource_Handle -- * * Get the handle for the given resource. * * Results: * The resource's associated handle. * * Side effects: * None. * *------------------------------------------------------------------------------ */ VMCIHandle VMCIResource_Handle(VMCIResource *resource) { ASSERT(resource); return resource->hashEntry.handle; } /* *------------------------------------------------------------------------------ * * VMCIResource_Sync -- * * Use this as a synchronization point when setting globals, for example, * during device shutdown. * * Results: * None. * * Side effects: * None. * *------------------------------------------------------------------------------ */ void VMCIResource_Sync(void) { VMCIHashTable_Sync(resourceTable); } open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciDatagram.h0000644765153500003110000000335412220061556023251 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciDatagram.h -- * * Internal functions in the VMCI Simple Datagram API. */ #ifndef _VMCI_DATAGRAM_H_ #define _VMCI_DATAGRAM_H_ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vmciContext.h" #include "vmci_call_defs.h" #ifndef VMX86_SERVER #include "vmci_iocontrols.h" #endif // !VMX86_SERVER #define VMCI_MAX_DELAYED_DG_HOST_QUEUE_SIZE 256 /* Init functions. */ int VMCIDatagram_Init(void); void VMCIDatagram_Exit(void); /* Datagram API for non-public use. */ int VMCIDatagram_Dispatch(VMCIId contextID, VMCIDatagram *dg, Bool fromGuest); int VMCIDatagram_InvokeGuestHandler(VMCIDatagram *dg); int VMCIDatagram_GetPrivFlags(VMCIHandle handle, VMCIPrivilegeFlags *privFlags); /* Misc. */ void VMCIDatagram_Sync(void); Bool VMCIDatagram_CheckHostCapabilities(void); #endif // _VMCI_DATAGRAM_H_ open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciEvent.h0000644765153500003110000000252712220061556022613 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciEvent.h -- * * Event code for the vmci guest driver */ #ifndef __VMCI_EVENT_H__ #define __VMCI_EVENT_H__ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vmci_defs.h" #include "vmci_call_defs.h" int VMCIEvent_Init(void); void VMCIEvent_Exit(void); void VMCIEvent_Sync(void); int VMCIEvent_Dispatch(VMCIDatagram *msg); Bool VMCIEvent_CheckHostCapabilities(void); #endif //__VMCI_EVENT_H__ open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciHashtable.c0000644765153500003110000003622112220061556023416 0ustar dtormts/********************************************************* * Copyright (C) 2006-2012 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciHashtable.c -- * * Implementation of the VMCI Hashtable. * TODO: Look into what is takes to use lib/misc/hashTable.c instead of * our own implementation. */ #include "vmci_kernel_if.h" #include "vm_assert.h" #include "vmci_defs.h" #include "vmci_infrastructure.h" #include "vmciCommonInt.h" #include "vmciDriver.h" #include "vmciHashtable.h" #if defined(VMKERNEL) # include "vmciVmkInt.h" # include "vm_libc.h" # include "helper_ext.h" #endif #define LGPFX "VMCIHashTable: " #define VMCI_HASHTABLE_HASH(_h, _sz) \ VMCI_HashId(VMCI_HANDLE_TO_RESOURCE_ID(_h), (_sz)) static int HashTableUnlinkEntry(VMCIHashTable *table, VMCIHashEntry *entry); static Bool VMCIHashTableEntryExistsLocked(VMCIHashTable *table, VMCIHandle handle); /* *------------------------------------------------------------------------------ * * VMCIHashTable_Create -- * XXX Factor out the hashtable code to be shared amongst host and guest. * * Result: * None. * *------------------------------------------------------------------------------ */ VMCIHashTable * VMCIHashTable_Create(int size) { VMCIHashTable *table = VMCI_AllocKernelMem(sizeof *table, VMCI_MEMORY_NONPAGED); if (table == NULL) { return NULL; } table->entries = VMCI_AllocKernelMem(sizeof *table->entries * size, VMCI_MEMORY_NONPAGED); if (table->entries == NULL) { VMCI_FreeKernelMem(table, sizeof *table); return NULL; } memset(table->entries, 0, sizeof *table->entries * size); table->size = size; if (VMCI_InitLock(&table->lock, "VMCIHashTableLock", VMCI_LOCK_RANK_HASHTABLE) < VMCI_SUCCESS) { VMCI_FreeKernelMem(table->entries, sizeof *table->entries * size); VMCI_FreeKernelMem(table, sizeof *table); return NULL; } return table; } /* *------------------------------------------------------------------------------ * * VMCIHashTable_Destroy -- * This function should be called at module exit time. * We rely on the module ref count to insure that no one is accessing any * hash table entries at this point in time. Hence we should be able to just * remove all entries from the hash table. * * Result: * None. * *------------------------------------------------------------------------------ */ void VMCIHashTable_Destroy(VMCIHashTable *table) { VMCILockFlags flags; #if 0 DEBUG_ONLY(int i;) DEBUG_ONLY(int leakingEntries = 0;) #endif ASSERT(table); VMCI_GrabLock_BH(&table->lock, &flags); #if 0 #ifdef VMX86_DEBUG for (i = 0; i < table->size; i++) { VMCIHashEntry *head = table->entries[i]; while (head) { leakingEntries++; head = head->next; } } if (leakingEntries) { VMCI_WARNING((LGPFX"Leaking entries (%d) for hash table (%p).\n", leakingEntries, table)); } #endif // VMX86_DEBUG #endif VMCI_FreeKernelMem(table->entries, sizeof *table->entries * table->size); table->entries = NULL; VMCI_ReleaseLock_BH(&table->lock, flags); VMCI_CleanupLock(&table->lock); VMCI_FreeKernelMem(table, sizeof *table); } /* *------------------------------------------------------------------------------ * * VMCIHashTable_InitEntry -- * Initializes a hash entry; * * Result: * None. * *------------------------------------------------------------------------------ */ void VMCIHashTable_InitEntry(VMCIHashEntry *entry, // IN VMCIHandle handle) // IN { ASSERT(entry); entry->handle = handle; entry->refCount = 0; } /* *------------------------------------------------------------------------------ * * VMCIHashTable_AddEntry -- * XXX Factor out the hashtable code to be shared amongst host and guest. * * Result: * None. * *------------------------------------------------------------------------------ */ int VMCIHashTable_AddEntry(VMCIHashTable *table, // IN VMCIHashEntry *entry) // IN { int idx; VMCILockFlags flags; ASSERT(entry); ASSERT(table); VMCI_GrabLock_BH(&table->lock, &flags); /* Check if creation of a new hashtable entry is allowed. */ if (!VMCI_CanCreate()) { VMCI_ReleaseLock_BH(&table->lock, flags); return VMCI_ERROR_UNAVAILABLE; } if (VMCIHashTableEntryExistsLocked(table, entry->handle)) { VMCI_DEBUG_LOG(4, (LGPFX"Entry (handle=0x%x:0x%x) already exists.\n", entry->handle.context, entry->handle.resource)); VMCI_ReleaseLock_BH(&table->lock, flags); return VMCI_ERROR_DUPLICATE_ENTRY; } idx = VMCI_HASHTABLE_HASH(entry->handle, table->size); ASSERT(idx < table->size); /* New entry is added to top/front of hash bucket. */ entry->refCount++; entry->next = table->entries[idx]; table->entries[idx] = entry; VMCI_ReleaseLock_BH(&table->lock, flags); return VMCI_SUCCESS; } /* *------------------------------------------------------------------------------ * * VMCIHashTable_RemoveEntry -- * XXX Factor out the hashtable code to shared amongst API and perhaps * host and guest. * * Result: * None. * *------------------------------------------------------------------------------ */ int VMCIHashTable_RemoveEntry(VMCIHashTable *table, // IN VMCIHashEntry *entry) // IN { int result; VMCILockFlags flags; ASSERT(table); ASSERT(entry); VMCI_GrabLock_BH(&table->lock, &flags); /* First unlink the entry. */ result = HashTableUnlinkEntry(table, entry); if (result != VMCI_SUCCESS) { /* We failed to find the entry. */ goto done; } /* Decrement refcount and check if this is last reference. */ entry->refCount--; if (entry->refCount == 0) { result = VMCI_SUCCESS_ENTRY_DEAD; goto done; } done: VMCI_ReleaseLock_BH(&table->lock, flags); return result; } /* *------------------------------------------------------------------------------ * * VMCIHashTableGetEntryLocked -- * * Looks up an entry in the hash table, that is already locked. * * Result: * If the element is found, a pointer to the element is returned. * Otherwise NULL is returned. * * Side effects: * The reference count of the returned element is increased. * *------------------------------------------------------------------------------ */ static VMCIHashEntry * VMCIHashTableGetEntryLocked(VMCIHashTable *table, // IN VMCIHandle handle) // IN { VMCIHashEntry *cur = NULL; int idx; ASSERT(!VMCI_HANDLE_EQUAL(handle, VMCI_INVALID_HANDLE)); ASSERT(table); idx = VMCI_HASHTABLE_HASH(handle, table->size); cur = table->entries[idx]; while (TRUE) { if (cur == NULL) { break; } if (VMCI_HANDLE_TO_RESOURCE_ID(cur->handle) == VMCI_HANDLE_TO_RESOURCE_ID(handle)) { if ((VMCI_HANDLE_TO_CONTEXT_ID(cur->handle) == VMCI_HANDLE_TO_CONTEXT_ID(handle)) || (VMCI_INVALID_ID == VMCI_HANDLE_TO_CONTEXT_ID(cur->handle))) { cur->refCount++; break; } } cur = cur->next; } return cur; } /* *------------------------------------------------------------------------------ * * VMCIHashTable_GetEntry -- * XXX Factor out the hashtable code to shared amongst API and perhaps * host and guest. * * Result: * None. * *------------------------------------------------------------------------------ */ VMCIHashEntry * VMCIHashTable_GetEntry(VMCIHashTable *table, // IN VMCIHandle handle) // IN { VMCIHashEntry *entry; VMCILockFlags flags; if (VMCI_HANDLE_EQUAL(handle, VMCI_INVALID_HANDLE)) { return NULL; } ASSERT(table); VMCI_GrabLock_BH(&table->lock, &flags); entry = VMCIHashTableGetEntryLocked(table, handle); VMCI_ReleaseLock_BH(&table->lock, flags); return entry; } /* *------------------------------------------------------------------------------ * * VMCIHashTable_HoldEntry -- * * Hold the given entry. This will increment the entry's reference count. * This is like a GetEntry() but without having to lookup the entry by * handle. * * Result: * None. * * Side effects: * None. * *------------------------------------------------------------------------------ */ void VMCIHashTable_HoldEntry(VMCIHashTable *table, // IN VMCIHashEntry *entry) // IN/OUT { VMCILockFlags flags; ASSERT(table); ASSERT(entry); VMCI_GrabLock_BH(&table->lock, &flags); entry->refCount++; VMCI_ReleaseLock_BH(&table->lock, flags); } /* *------------------------------------------------------------------------------ * * VMCIHashTableReleaseEntryLocked -- * * Releases an element previously obtained with * VMCIHashTableGetEntryLocked. * * Result: * If the entry is removed from the hash table, VMCI_SUCCESS_ENTRY_DEAD * is returned. Otherwise, VMCI_SUCCESS is returned. * * Side effects: * The reference count of the entry is decreased and the entry is removed * from the hash table on 0. * *------------------------------------------------------------------------------ */ static int VMCIHashTableReleaseEntryLocked(VMCIHashTable *table, // IN VMCIHashEntry *entry) // IN { int result = VMCI_SUCCESS; ASSERT(table); ASSERT(entry); entry->refCount--; /* Check if this is last reference and report if so. */ if (entry->refCount == 0) { /* * Remove entry from hash table if not already removed. This could have * happened already because VMCIHashTable_RemoveEntry was called to unlink * it. We ignore if it is not found. Datagram handles will often have * RemoveEntry called, whereas SharedMemory regions rely on ReleaseEntry * to unlink the entry, since the creator does not call RemoveEntry when * it detaches. */ HashTableUnlinkEntry(table, entry); result = VMCI_SUCCESS_ENTRY_DEAD; } return result; } /* *------------------------------------------------------------------------------ * * VMCIHashTable_ReleaseEntry -- * XXX Factor out the hashtable code to shared amongst API and perhaps * host and guest. * * Result: * None. * *------------------------------------------------------------------------------ */ int VMCIHashTable_ReleaseEntry(VMCIHashTable *table, // IN VMCIHashEntry *entry) // IN { VMCILockFlags flags; int result; ASSERT(table); VMCI_GrabLock_BH(&table->lock, &flags); result = VMCIHashTableReleaseEntryLocked(table, entry); VMCI_ReleaseLock_BH(&table->lock, flags); return result; } /* *------------------------------------------------------------------------------ * * VMCIHashTable_EntryExists -- * XXX Factor out the hashtable code to shared amongst API and perhaps * host and guest. * * Result: * TRUE if handle already in hashtable. FALSE otherwise. * * Side effects: * None. * *------------------------------------------------------------------------------ */ Bool VMCIHashTable_EntryExists(VMCIHashTable *table, // IN VMCIHandle handle) // IN { Bool exists; VMCILockFlags flags; ASSERT(table); VMCI_GrabLock_BH(&table->lock, &flags); exists = VMCIHashTableEntryExistsLocked(table, handle); VMCI_ReleaseLock_BH(&table->lock, flags); return exists; } /* *------------------------------------------------------------------------------ * * VMCIHashTableEntryExistsLocked -- * * Unlocked version of VMCIHashTable_EntryExists. * * Result: * TRUE if handle already in hashtable. FALSE otherwise. * * Side effects: * None. * *------------------------------------------------------------------------------ */ static Bool VMCIHashTableEntryExistsLocked(VMCIHashTable *table, // IN VMCIHandle handle) // IN { VMCIHashEntry *entry; int idx; ASSERT(table); idx = VMCI_HASHTABLE_HASH(handle, table->size); entry = table->entries[idx]; while (entry) { if (VMCI_HANDLE_TO_RESOURCE_ID(entry->handle) == VMCI_HANDLE_TO_RESOURCE_ID(handle)) { if ((VMCI_HANDLE_TO_CONTEXT_ID(entry->handle) == VMCI_HANDLE_TO_CONTEXT_ID(handle)) || (VMCI_INVALID_ID == VMCI_HANDLE_TO_CONTEXT_ID(handle)) || (VMCI_INVALID_ID == VMCI_HANDLE_TO_CONTEXT_ID(entry->handle))) { return TRUE; } } entry = entry->next; } return FALSE; } /* *------------------------------------------------------------------------------ * * HashTableUnlinkEntry -- * XXX Factor out the hashtable code to shared amongst API and perhaps * host and guest. * Assumes caller holds table lock. * * Result: * None. * *------------------------------------------------------------------------------ */ static int HashTableUnlinkEntry(VMCIHashTable *table, // IN VMCIHashEntry *entry) // IN { int result; VMCIHashEntry *prev, *cur; int idx; idx = VMCI_HASHTABLE_HASH(entry->handle, table->size); prev = NULL; cur = table->entries[idx]; while (TRUE) { if (cur == NULL) { result = VMCI_ERROR_NOT_FOUND; break; } if (VMCI_HANDLE_EQUAL(cur->handle, entry->handle)) { ASSERT(cur == entry); /* Remove entry and break. */ if (prev) { prev->next = cur->next; } else { table->entries[idx] = cur->next; } cur->next = NULL; result = VMCI_SUCCESS; break; } prev = cur; cur = cur->next; } return result; } /* *----------------------------------------------------------------------------- * * VMCIHashTable_Sync -- * * Use this as a synchronization point when setting globals, for example, * during device shutdown. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMCIHashTable_Sync(VMCIHashTable *table) { VMCILockFlags flags; ASSERT(table); VMCI_GrabLock_BH(&table->lock, &flags); VMCI_ReleaseLock_BH(&table->lock, flags); } open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciResource.h0000644765153500003110000000513712220061556023321 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciResource.h -- * * VMCI Resource Access Control API. */ #ifndef _VMCI_RESOURCE_H_ #define _VMCI_RESOURCE_H_ #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vmci_defs.h" #include "vmci_kernel_if.h" #include "vmciHashtable.h" #include "vmciContext.h" #define RESOURCE_CONTAINER(ptr, type, member) \ ((type *)((char *)(ptr) - offsetof(type, member))) typedef void(*VMCIResourceFreeCB)(void *resource); typedef enum { VMCI_RESOURCE_TYPE_ANY, VMCI_RESOURCE_TYPE_API, VMCI_RESOURCE_TYPE_GROUP, VMCI_RESOURCE_TYPE_DATAGRAM, VMCI_RESOURCE_TYPE_DOORBELL, } VMCIResourceType; typedef struct VMCIResource { VMCIHashEntry hashEntry; VMCIResourceType type; VMCIResourceFreeCB containerFreeCB; // Callback to free container // object when refCount is 0. void *containerObject; // Container object reference. } VMCIResource; int VMCIResource_Init(void); void VMCIResource_Exit(void); void VMCIResource_Sync(void); VMCIId VMCIResource_GetID(VMCIId contextID); int VMCIResource_Add(VMCIResource *resource, VMCIResourceType resourceType, VMCIHandle resourceHandle, VMCIResourceFreeCB containerFreeCB, void *containerObject); void VMCIResource_Remove(VMCIHandle resourceHandle, VMCIResourceType resourceType); VMCIResource *VMCIResource_Get(VMCIHandle resourceHandle, VMCIResourceType resourceType); void VMCIResource_Hold(VMCIResource *resource); int VMCIResource_Release(VMCIResource *resource); VMCIHandle VMCIResource_Handle(VMCIResource *resource); #endif // _VMCI_RESOURCE_H_ open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciHashtable.h0000644765153500003110000000420112220061556023414 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciHashtable.h -- * * Hash table for use in the APIs. */ #ifndef _VMCI_HASHTABLE_H_ #define _VMCI_HASHTABLE_H_ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vmci_kernel_if.h" #include "vmci_defs.h" typedef struct VMCIHashEntry { VMCIHandle handle; int refCount; struct VMCIHashEntry *next; } VMCIHashEntry; typedef struct VMCIHashTable { VMCIHashEntry **entries; int size; // Number of buckets in above array. VMCILock lock; } VMCIHashTable; VMCIHashTable *VMCIHashTable_Create(int size); void VMCIHashTable_Destroy(VMCIHashTable *table); void VMCIHashTable_InitEntry(VMCIHashEntry *entry, VMCIHandle handle); int VMCIHashTable_AddEntry(VMCIHashTable *table, VMCIHashEntry *entry); int VMCIHashTable_RemoveEntry(VMCIHashTable *table, VMCIHashEntry *entry); VMCIHashEntry *VMCIHashTable_GetEntry(VMCIHashTable *table, VMCIHandle handle); void VMCIHashTable_HoldEntry(VMCIHashTable *table, VMCIHashEntry *entry); int VMCIHashTable_ReleaseEntry(VMCIHashTable *table, VMCIHashEntry *entry); Bool VMCIHashTable_EntryExists(VMCIHashTable *table, VMCIHandle handle); void VMCIHashTable_Sync(VMCIHashTable *table); #endif // _VMCI_HASHTABLE_H_ open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciRoute.h0000644765153500003110000000255512220061556022631 0ustar dtormts/********************************************************* * Copyright (C) 2011 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciRoute.h -- * * VMCI Routing. */ #ifndef _VMCI_ROUTE_H_ #define _VMCI_ROUTE_H_ #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vmci_defs.h" typedef enum { VMCI_ROUTE_NONE, VMCI_ROUTE_AS_HOST, VMCI_ROUTE_AS_GUEST, } VMCIRoute; int VMCI_Route(VMCIHandle *src, const VMCIHandle *dst, Bool fromGuest, VMCIRoute *route); const char *VMCI_RouteString(VMCIRoute route); #endif // _VMCI_ROUTE_H_ open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciDoorbell.c0000644765153500003110000010226712220061556023271 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciDoorbell.c -- * * This file implements the VMCI doorbell API on the host. */ #include "vmci_kernel_if.h" #include "vm_assert.h" #include "vmci_defs.h" #include "vmci_infrastructure.h" #include "vmciCommonInt.h" #include "vmciDatagram.h" #include "vmciDoorbell.h" #include "vmciDriver.h" #include "vmciKernelAPI.h" #include "vmciResource.h" #include "vmciRoute.h" #if defined(VMKERNEL) # include "vmciVmkInt.h" # include "vm_libc.h" # include "helper_ext.h" #endif #define LGPFX "VMCIDoorbell: " #if !defined(SOLARIS) && !defined(__APPLE__) #define VMCI_DOORBELL_INDEX_TABLE_SIZE 64 #define VMCI_DOORBELL_HASH(_idx) \ VMCI_HashId((_idx), VMCI_DOORBELL_INDEX_TABLE_SIZE) /* * DoorbellEntry describes the a doorbell notification handle allocated by the * host. */ typedef struct VMCIDoorbellEntry { VMCIResource resource; uint32 idx; VMCIListItem idxListItem; VMCIPrivilegeFlags privFlags; Bool isDoorbell; Bool runDelayed; VMCICallback notifyCB; void *clientData; VMCIEvent destroyEvent; Atomic_uint32 active; // Only used by guest personality } VMCIDoorbellEntry; typedef struct VMCIDoorbellIndexTable { VMCILock lock; VMCIList entries[VMCI_DOORBELL_INDEX_TABLE_SIZE]; } VMCIDoorbellIndexTable; /* The VMCI index table keeps track of currently registered doorbells. */ static VMCIDoorbellIndexTable vmciDoorbellIT; /* * The maxNotifyIdx is one larger than the currently known bitmap index in * use, and is used to determine how much of the bitmap needs to be scanned. */ static uint32 maxNotifyIdx; /* * The notifyIdxCount is used for determining whether there are free entries * within the bitmap (if notifyIdxCount + 1 < maxNotifyIdx). */ static uint32 notifyIdxCount; /* * The lastNotifyIdxReserved is used to track the last index handed out - in * the case where multiple handles share a notification index, we hand out * indexes round robin based on lastNotifyIdxReserved. */ static uint32 lastNotifyIdxReserved; /* This is a one entry cache used to by the index allocation. */ static uint32 lastNotifyIdxReleased = PAGE_SIZE; static void VMCIDoorbellFreeCB(void *clientData); static int VMCIDoorbellReleaseCB(void *clientData); static void VMCIDoorbellDelayedDispatchCB(void *data); /* *------------------------------------------------------------------------------ * * VMCIDoorbell_Init -- * * General init code. * * Result: * VMCI_SUCCESS on success, lock allocation error otherwise. * * Side effects: * None. * *------------------------------------------------------------------------------ */ int VMCIDoorbell_Init(void) { uint32 bucket; for (bucket = 0; bucket < ARRAYSIZE(vmciDoorbellIT.entries); ++bucket) { VMCIList_Init(&vmciDoorbellIT.entries[bucket]); } return VMCI_InitLock(&vmciDoorbellIT.lock, "VMCIDoorbellIndexTableLock", VMCI_LOCK_RANK_DOORBELL); } /* *------------------------------------------------------------------------------ * * VMCIDoorbell_Exit -- * * General init code. * * Result: * None. * * Side effects: * None. * *------------------------------------------------------------------------------ */ void VMCIDoorbell_Exit(void) { VMCI_CleanupLock(&vmciDoorbellIT.lock); } /* *------------------------------------------------------------------------------ * * VMCIDoorbellFreeCB -- * * Callback to free doorbell entry structure when resource is no longer used, * ie. the reference count reached 0. The entry is freed in * VMCIDoorbell_Destroy(), which is waiting on the signal that gets fired * here. * * Result: * None. * * Side effects: * Signals VMCI event. * *------------------------------------------------------------------------------ */ static void VMCIDoorbellFreeCB(void *clientData) // IN { VMCIDoorbellEntry *entry = (VMCIDoorbellEntry *)clientData; ASSERT(entry); VMCI_SignalEvent(&entry->destroyEvent); } /* *------------------------------------------------------------------------------ * * VMCIDoorbellReleaseCB -- * * Callback to release the resource reference. It is called by the * VMCI_WaitOnEvent function before it blocks. * * Result: * Always 0. * * Side effects: * None. * *------------------------------------------------------------------------------ */ static int VMCIDoorbellReleaseCB(void *clientData) // IN: doorbell entry { VMCIDoorbellEntry *entry = (VMCIDoorbellEntry *)clientData; ASSERT(entry); VMCIResource_Release(&entry->resource); return 0; } /* *------------------------------------------------------------------------------ * * VMCIDoorbellGetPrivFlags -- * * Utility function that retrieves the privilege flags associated * with a given doorbell handle. For guest endpoints, the * privileges are determined by the context ID, but for host * endpoints privileges are associated with the complete * handle. Hypervisor endpoints are not yet supported. * * Result: * VMCI_SUCCESS on success, * VMCI_ERROR_NOT_FOUND if handle isn't found, * VMCI_ERROR_INVALID_ARGS if handle is invalid. * * Side effects: * None. * *------------------------------------------------------------------------------ */ int VMCIDoorbellGetPrivFlags(VMCIHandle handle, // IN VMCIPrivilegeFlags *privFlags) // OUT { if (privFlags == NULL || handle.context == VMCI_INVALID_ID) { return VMCI_ERROR_INVALID_ARGS; } if (handle.context == VMCI_HOST_CONTEXT_ID) { VMCIDoorbellEntry *entry; VMCIResource *resource; resource = VMCIResource_Get(handle, VMCI_RESOURCE_TYPE_DOORBELL); if (resource == NULL) { return VMCI_ERROR_NOT_FOUND; } entry = RESOURCE_CONTAINER(resource, VMCIDoorbellEntry, resource); *privFlags = entry->privFlags; VMCIResource_Release(resource); } else if (handle.context == VMCI_HYPERVISOR_CONTEXT_ID) { /* Hypervisor endpoints for notifications are not supported (yet). */ return VMCI_ERROR_INVALID_ARGS; } else { *privFlags = vmci_context_get_priv_flags(handle.context); } return VMCI_SUCCESS; } /* *----------------------------------------------------------------------------- * * VMCIDoorbellIndexTableFind -- * * Find doorbell entry by bitmap index. * * Results: * Entry if found, NULL if not. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static VMCIDoorbellEntry * VMCIDoorbellIndexTableFind(uint32 idx) // IN { uint32 bucket = VMCI_DOORBELL_HASH(idx); VMCIListItem *iter; ASSERT(VMCI_GuestPersonalityActive()); VMCIList_Scan(iter, &vmciDoorbellIT.entries[bucket]) { VMCIDoorbellEntry *cur = VMCIList_Entry(iter, VMCIDoorbellEntry, idxListItem); ASSERT(cur); if (idx == cur->idx) { return cur; } } return NULL; } /* *------------------------------------------------------------------------------ * * VMCIDoorbellIndexTableAdd -- * * Add the given entry to the index table. This will hold() the entry's * resource so that the entry is not deleted before it is removed from the * table. * * Results: * None. * * Side effects: * None. * *------------------------------------------------------------------------------ */ static void VMCIDoorbellIndexTableAdd(VMCIDoorbellEntry *entry) // IN/OUT { uint32 bucket; uint32 newNotifyIdx; VMCILockFlags flags; ASSERT(entry); ASSERT(VMCI_GuestPersonalityActive()); VMCIResource_Hold(&entry->resource); VMCI_GrabLock_BH(&vmciDoorbellIT.lock, &flags); /* * Below we try to allocate an index in the notification bitmap with "not * too much" sharing between resources. If we use less that the full bitmap, * we either add to the end if there are no unused flags within the * currently used area, or we search for unused ones. If we use the full * bitmap, we allocate the index round robin. */ if (maxNotifyIdx < PAGE_SIZE || notifyIdxCount < PAGE_SIZE) { if (lastNotifyIdxReleased < maxNotifyIdx && !VMCIDoorbellIndexTableFind(lastNotifyIdxReleased)) { newNotifyIdx = lastNotifyIdxReleased; lastNotifyIdxReleased = PAGE_SIZE; } else { Bool reused = FALSE; newNotifyIdx = lastNotifyIdxReserved; if (notifyIdxCount + 1 < maxNotifyIdx) { do { if (!VMCIDoorbellIndexTableFind(newNotifyIdx)) { reused = TRUE; break; } newNotifyIdx = (newNotifyIdx + 1) % maxNotifyIdx; } while(newNotifyIdx != lastNotifyIdxReleased); } if (!reused) { newNotifyIdx = maxNotifyIdx; maxNotifyIdx++; } } } else { newNotifyIdx = (lastNotifyIdxReserved + 1) % PAGE_SIZE; } lastNotifyIdxReserved = newNotifyIdx; notifyIdxCount++; entry->idx = newNotifyIdx; bucket = VMCI_DOORBELL_HASH(entry->idx); VMCIList_Insert(&entry->idxListItem, &vmciDoorbellIT.entries[bucket]); VMCI_ReleaseLock_BH(&vmciDoorbellIT.lock, flags); } /* *------------------------------------------------------------------------------ * * VMCIDoorbellIndexTableRemove -- * * Remove the given entry from the index table. This will release() the * entry's resource. * * Results: * None. * * Side effects: * None. * *------------------------------------------------------------------------------ */ static void VMCIDoorbellIndexTableRemove(VMCIDoorbellEntry *entry) // IN/OUT { VMCILockFlags flags; ASSERT(entry); ASSERT(VMCI_GuestPersonalityActive()); VMCI_GrabLock_BH(&vmciDoorbellIT.lock, &flags); VMCIList_Remove(&entry->idxListItem); notifyIdxCount--; if (entry->idx == maxNotifyIdx - 1) { /* * If we delete an entry with the maximum known notification index, we * take the opportunity to prune the current max. As there might be other * unused indices immediately below, we lower the maximum until we hit an * index in use. */ while (maxNotifyIdx > 0 && !VMCIDoorbellIndexTableFind(maxNotifyIdx - 1)) { maxNotifyIdx--; } } lastNotifyIdxReleased = entry->idx; VMCI_ReleaseLock_BH(&vmciDoorbellIT.lock, flags); VMCIResource_Release(&entry->resource); } /* *------------------------------------------------------------------------------ * * VMCIDoorbellLink -- * * Creates a link between the given doorbell handle and the given * index in the bitmap in the device backend. * * Results: * VMCI_SUCCESS if success, appropriate error code otherwise. * * Side effects: * Notification state is created in hypervisor. * *------------------------------------------------------------------------------ */ static int VMCIDoorbellLink(VMCIHandle handle, // IN Bool isDoorbell, // IN uint32 notifyIdx) // IN { #if defined(VMKERNEL) VMCI_WARNING((LGPFX"Cannot send down to host from VMKERNEL.\n")); return VMCI_ERROR_DST_UNREACHABLE; #else // VMKERNEL VMCIId resourceID; VMCIDoorbellLinkMsg linkMsg; ASSERT(!VMCI_HANDLE_INVALID(handle)); ASSERT(VMCI_GuestPersonalityActive()); if (isDoorbell) { resourceID = VMCI_DOORBELL_LINK; } else { ASSERT(FALSE); return VMCI_ERROR_UNAVAILABLE; } linkMsg.hdr.dst = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, resourceID); linkMsg.hdr.src = VMCI_ANON_SRC_HANDLE; linkMsg.hdr.payloadSize = sizeof linkMsg - VMCI_DG_HEADERSIZE; linkMsg.handle = handle; linkMsg.notifyIdx = notifyIdx; return VMCI_SendDatagram((VMCIDatagram *)&linkMsg); #endif // VMKERNEL } /* *------------------------------------------------------------------------------ * * VMCIDoorbellUnlink -- * * Unlinks the given doorbell handle from an index in the bitmap in * the device backend. * * Results: * VMCI_SUCCESS if success, appropriate error code otherwise. * * Side effects: * Notification state is destroyed in hypervisor. * *------------------------------------------------------------------------------ */ static int VMCIDoorbellUnlink(VMCIHandle handle, // IN Bool isDoorbell) // IN { #if defined(VMKERNEL) VMCI_WARNING((LGPFX"Cannot send down to host from VMKERNEL.\n")); return VMCI_ERROR_DST_UNREACHABLE; #else // VMKERNEL VMCIId resourceID; VMCIDoorbellUnlinkMsg unlinkMsg; ASSERT(!VMCI_HANDLE_INVALID(handle)); ASSERT(VMCI_GuestPersonalityActive()); if (isDoorbell) { resourceID = VMCI_DOORBELL_UNLINK; } else { ASSERT(FALSE); return VMCI_ERROR_UNAVAILABLE; } unlinkMsg.hdr.dst = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, resourceID); unlinkMsg.hdr.src = VMCI_ANON_SRC_HANDLE; unlinkMsg.hdr.payloadSize = sizeof unlinkMsg - VMCI_DG_HEADERSIZE; unlinkMsg.handle = handle; return VMCI_SendDatagram((VMCIDatagram *)&unlinkMsg); #endif // VMKERNEL } /* *------------------------------------------------------------------------------ * * vmci_doorbell_create -- * * Creates a doorbell with the given callback. If the handle is * VMCI_INVALID_HANDLE, a free handle will be assigned, if * possible. The callback can be run immediately (potentially with * locks held - the default) or delayed (in a kernel thread) by * specifying the flag VMCI_FLAG_DELAYED_CB. If delayed execution * is selected, a given callback may not be run if the kernel is * unable to allocate memory for the delayed execution (highly * unlikely). * * Results: * VMCI_SUCCESS on success, appropriate error code otherwise. * * Side effects: * None. * *------------------------------------------------------------------------------ */ VMCI_EXPORT_SYMBOL(vmci_doorbell_create) int vmci_doorbell_create(VMCIHandle *handle, // IN/OUT uint32 flags, // IN VMCIPrivilegeFlags privFlags, // IN VMCICallback notifyCB, // IN void *clientData) // IN { VMCIDoorbellEntry *entry; VMCIHandle newHandle; int result; if (!handle || !notifyCB || flags & ~VMCI_FLAG_DELAYED_CB || privFlags & ~VMCI_PRIVILEGE_ALL_FLAGS) { return VMCI_ERROR_INVALID_ARGS; } entry = VMCI_AllocKernelMem(sizeof *entry, VMCI_MEMORY_NONPAGED); if (entry == NULL) { VMCI_WARNING((LGPFX"Failed allocating memory for datagram entry.\n")); return VMCI_ERROR_NO_MEM; } if (!VMCI_CanScheduleDelayedWork() && (flags & VMCI_FLAG_DELAYED_CB)) { result = VMCI_ERROR_INVALID_ARGS; goto freeMem; } if (VMCI_HANDLE_INVALID(*handle)) { VMCIId contextID = vmci_get_context_id(); VMCIId resourceID = VMCIResource_GetID(contextID); if (resourceID == VMCI_INVALID_ID) { result = VMCI_ERROR_NO_HANDLE; goto freeMem; } newHandle = VMCI_MAKE_HANDLE(contextID, resourceID); } else { Bool validContext; /* * Validate the handle. We must do both of the checks below * because we can be acting as both a host and a guest at the * same time. We always allow the host context ID, since the * host functionality is in practice always there with the * unified driver. */ validContext = FALSE; if (VMCI_HOST_CONTEXT_ID == handle->context) { validContext = TRUE; } if (VMCI_GuestPersonalityActive() && vmci_get_context_id() == handle->context) { validContext = TRUE; } if (!validContext || VMCI_INVALID_ID == handle->resource) { VMCI_DEBUG_LOG(4, (LGPFX"Invalid argument (handle=0x%x:0x%x).\n", handle->context, handle->resource)); result = VMCI_ERROR_INVALID_ARGS; goto freeMem; } newHandle = *handle; } entry->idx = 0; VMCIList_Init(&entry->idxListItem); entry->privFlags = privFlags; entry->isDoorbell = TRUE; entry->runDelayed = (flags & VMCI_FLAG_DELAYED_CB) ? TRUE : FALSE; entry->notifyCB = notifyCB; entry->clientData = clientData; Atomic_Write(&entry->active, 0); VMCI_CreateEvent(&entry->destroyEvent); result = VMCIResource_Add(&entry->resource, VMCI_RESOURCE_TYPE_DOORBELL, newHandle, VMCIDoorbellFreeCB, entry); if (result != VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to add new resource (handle=0x%x:0x%x).\n", newHandle.context, newHandle.resource)); if (result == VMCI_ERROR_DUPLICATE_ENTRY) { result = VMCI_ERROR_ALREADY_EXISTS; } goto destroy; } if (VMCI_GuestPersonalityActive()) { VMCIDoorbellIndexTableAdd(entry); result = VMCIDoorbellLink(newHandle, entry->isDoorbell, entry->idx); if (VMCI_SUCCESS != result) { goto destroyResource; } Atomic_Write(&entry->active, 1); } if (VMCI_HANDLE_INVALID(*handle)) { *handle = newHandle; } return result; destroyResource: VMCIDoorbellIndexTableRemove(entry); VMCIResource_Remove(newHandle, VMCI_RESOURCE_TYPE_DOORBELL); destroy: VMCI_DestroyEvent(&entry->destroyEvent); freeMem: VMCI_FreeKernelMem(entry, sizeof *entry); return result; } /* *------------------------------------------------------------------------------ * * vmci_doorbell_destroy -- * * Destroys a doorbell previously created with * vmci_doorbell_create. This operation may block waiting for a * callback to finish. * * Results: * VMCI_SUCCESS on success, appropriate error code otherwise. * * Side effects: * May block. * *------------------------------------------------------------------------------ */ VMCI_EXPORT_SYMBOL(vmci_doorbell_destroy) int vmci_doorbell_destroy(VMCIHandle handle) // IN { VMCIDoorbellEntry *entry; VMCIResource *resource; if (VMCI_HANDLE_INVALID(handle)) { return VMCI_ERROR_INVALID_ARGS; } resource = VMCIResource_Get(handle, VMCI_RESOURCE_TYPE_DOORBELL); if (resource == NULL) { VMCI_DEBUG_LOG(4, (LGPFX"Failed to destroy doorbell (handle=0x%x:0x%x).\n", handle.context, handle.resource)); return VMCI_ERROR_NOT_FOUND; } entry = RESOURCE_CONTAINER(resource, VMCIDoorbellEntry, resource); if (VMCI_GuestPersonalityActive()) { int result; VMCIDoorbellIndexTableRemove(entry); result = VMCIDoorbellUnlink(handle, entry->isDoorbell); if (VMCI_SUCCESS != result) { /* * The only reason this should fail would be an inconsistency between * guest and hypervisor state, where the guest believes it has an * active registration whereas the hypervisor doesn't. One case where * this may happen is if a doorbell is unregistered following a * hibernation at a time where the doorbell state hasn't been restored * on the hypervisor side yet. Since the handle has now been removed * in the guest, we just print a warning and return success. */ VMCI_DEBUG_LOG(4, (LGPFX"Unlink of %s (handle=0x%x:0x%x) unknown by " "hypervisor (error=%d).\n", entry->isDoorbell ? "doorbell" : "queuepair", handle.context, handle.resource, result)); } } /* * Now remove the resource from the table. It might still be in use * after this, in a callback or still on the delayed work queue. */ VMCIResource_Remove(handle, VMCI_RESOURCE_TYPE_DOORBELL); /* * We now wait on the destroyEvent and release the reference we got * above. */ VMCI_WaitOnEvent(&entry->destroyEvent, VMCIDoorbellReleaseCB, entry); /* * We know that we are now the only reference to the above entry so * can safely free it. */ VMCI_DestroyEvent(&entry->destroyEvent); VMCI_FreeKernelMem(entry, sizeof *entry); return VMCI_SUCCESS; } /* *------------------------------------------------------------------------------ * * VMCIDoorbellNotifyAsGuest -- * * Notify another guest or the host. We send a datagram down to the * host via the hypervisor with the notification info. * * Results: * VMCI_SUCCESS on success, appropriate error code otherwise. * * Side effects: * May do a hypercall. * *------------------------------------------------------------------------------ */ static int VMCIDoorbellNotifyAsGuest(VMCIHandle handle, // IN VMCIPrivilegeFlags privFlags) // IN { #if defined(VMKERNEL) VMCI_WARNING((LGPFX"Cannot send down to host from VMKERNEL.\n")); return VMCI_ERROR_DST_UNREACHABLE; #else // VMKERNEL VMCIDoorbellNotifyMsg notifyMsg; ASSERT(VMCI_GuestPersonalityActive()); notifyMsg.hdr.dst = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_DOORBELL_NOTIFY); notifyMsg.hdr.src = VMCI_ANON_SRC_HANDLE; notifyMsg.hdr.payloadSize = sizeof notifyMsg - VMCI_DG_HEADERSIZE; notifyMsg.handle = handle; return VMCI_SendDatagram((VMCIDatagram *)¬ifyMsg); #endif // VMKERNEL } /* *------------------------------------------------------------------------------ * * vmci_doorbell_notify -- * * Generates a notification on the doorbell identified by the * handle. For host side generation of notifications, the caller * can specify what the privilege of the calling side is. * * Results: * VMCI_SUCCESS on success, appropriate error code otherwise. * * Side effects: * May do a hypercall. * *------------------------------------------------------------------------------ */ VMCI_EXPORT_SYMBOL(vmci_doorbell_notify) int vmci_doorbell_notify(VMCIHandle dst, // IN VMCIPrivilegeFlags privFlags) // IN { int retval; VMCIRoute route; VMCIHandle src; if (VMCI_HANDLE_INVALID(dst) || (privFlags & ~VMCI_PRIVILEGE_ALL_FLAGS)) { return VMCI_ERROR_INVALID_ARGS; } src = VMCI_INVALID_HANDLE; retval = VMCI_Route(&src, &dst, FALSE, &route); if (retval < VMCI_SUCCESS) { return retval; } if (VMCI_ROUTE_AS_HOST == route) { return VMCIContext_NotifyDoorbell(VMCI_HOST_CONTEXT_ID, dst, privFlags); } if (VMCI_ROUTE_AS_GUEST == route) { return VMCIDoorbellNotifyAsGuest(dst, privFlags); } VMCI_WARNING((LGPFX"Unknown route (%d) for doorbell.\n", route)); return VMCI_ERROR_DST_UNREACHABLE; } /* *------------------------------------------------------------------------------ * * VMCIDoorbellDelayedDispatchCB -- * * Calls the specified callback in a delayed context. * * Results: * None. * * Side effects: * None. * *------------------------------------------------------------------------------ */ static void VMCIDoorbellDelayedDispatchCB(void *data) // IN { VMCIDoorbellEntry *entry = (VMCIDoorbellEntry *)data; ASSERT(data); entry->notifyCB(entry->clientData); VMCIResource_Release(&entry->resource); } /* *------------------------------------------------------------------------------ * * VMCIDoorbellHostContextNotify -- * * Dispatches a doorbell notification to the host context. * * Results: * VMCI_SUCCESS on success. Appropriate error code otherwise. * * Side effects: * None. * *------------------------------------------------------------------------------ */ int VMCIDoorbellHostContextNotify(VMCIId srcCID, // IN VMCIHandle handle) // IN { VMCIDoorbellEntry *entry; VMCIResource *resource; int result; ASSERT(VMCI_HostPersonalityActive()); if (VMCI_HANDLE_INVALID(handle)) { VMCI_DEBUG_LOG(4, (LGPFX"Notifying an invalid doorbell (handle=0x%x:0x%x).\n", handle.context, handle.resource)); return VMCI_ERROR_INVALID_ARGS; } resource = VMCIResource_Get(handle, VMCI_RESOURCE_TYPE_DOORBELL); if (resource == NULL) { VMCI_DEBUG_LOG(4, (LGPFX"Notifying an unknown doorbell (handle=0x%x:0x%x).\n", handle.context, handle.resource)); return VMCI_ERROR_NOT_FOUND; } entry = RESOURCE_CONTAINER(resource, VMCIDoorbellEntry, resource); if (entry->runDelayed) { result = VMCI_ScheduleDelayedWork(VMCIDoorbellDelayedDispatchCB, entry); if (result < VMCI_SUCCESS) { /* * If we failed to schedule the delayed work, we need to * release the resource immediately. Otherwise, the resource * will be released once the delayed callback has been * completed. */ VMCI_DEBUG_LOG(10, (LGPFX"Failed to schedule delayed doorbell " "notification (result=%d).\n", result)); VMCIResource_Release(resource); } } else { entry->notifyCB(entry->clientData); VMCIResource_Release(resource); result = VMCI_SUCCESS; } return result; } /* *------------------------------------------------------------------------------ * * VMCIDoorbell_Hibernate -- * * When a guest leaves hibernation, the device driver state is out of sync * with the device state, since the driver state has doorbells registered * that aren't known to the device. This function takes care of * reregistering any doorbells. In case an error occurs during * reregistration (this is highly unlikely since 1) it succeeded the first * time 2) the device driver is the only source of doorbell registrations), * we simply log the error. The doorbell can still be destroyed using * VMCIDoorbell_Destroy. * * Results: * None. * * Side effects: * None. * *------------------------------------------------------------------------------ */ void VMCIDoorbell_Hibernate(Bool enterHibernate) { uint32 bucket; VMCIListItem *iter; VMCILockFlags flags; if (!VMCI_GuestPersonalityActive() || enterHibernate) { return; } VMCI_GrabLock_BH(&vmciDoorbellIT.lock, &flags); for (bucket = 0; bucket < ARRAYSIZE(vmciDoorbellIT.entries); bucket++) { VMCIList_Scan(iter, &vmciDoorbellIT.entries[bucket]) { int result; VMCIHandle h; VMCIDoorbellEntry *cur; cur = VMCIList_Entry(iter, VMCIDoorbellEntry, idxListItem); h = VMCIResource_Handle(&cur->resource); result = VMCIDoorbellLink(h, cur->isDoorbell, cur->idx); if (result != VMCI_SUCCESS && result != VMCI_ERROR_DUPLICATE_ENTRY) { VMCI_WARNING((LGPFX"Failed to reregister doorbell " "(handle=0x%x:0x%x) of resource %s to index " "(error=%d).\n", h.context, h.resource, cur->isDoorbell ? "doorbell" : "queue pair", result)); } } } VMCI_ReleaseLock_BH(&vmciDoorbellIT.lock, flags); } /* *------------------------------------------------------------------------------ * * VMCIDoorbell_Sync -- * * Use this as a synchronization point when setting globals, for example, * during device shutdown. * * Results: * None. * * Side effects: * None. * *------------------------------------------------------------------------------ */ void VMCIDoorbell_Sync(void) { VMCILockFlags flags; VMCI_GrabLock_BH(&vmciDoorbellIT.lock, &flags); VMCI_ReleaseLock_BH(&vmciDoorbellIT.lock, flags); VMCIResource_Sync(); } /* *------------------------------------------------------------------------------ * * VMCI_RegisterNotificationBitmap -- * * Register the notification bitmap with the host. * * Results: * TRUE if the bitmap is registered successfully with the device, FALSE * otherwise. * * Side effects: * None. * *------------------------------------------------------------------------------ */ Bool VMCI_RegisterNotificationBitmap(PPN bitmapPPN) { int result; VMCINotifyBitmapSetMsg bitmapSetMsg; /* * Do not ASSERT() on the guest device here. This function can get called * during device initialization, so the ASSERT() will fail even though * the device is (almost) up. */ bitmapSetMsg.hdr.dst = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_SET_NOTIFY_BITMAP); bitmapSetMsg.hdr.src = VMCI_ANON_SRC_HANDLE; bitmapSetMsg.hdr.payloadSize = sizeof bitmapSetMsg - VMCI_DG_HEADERSIZE; bitmapSetMsg.bitmapPPN = bitmapPPN; result = VMCI_SendDatagram((VMCIDatagram *)&bitmapSetMsg); if (result != VMCI_SUCCESS) { VMCI_DEBUG_LOG(4, (LGPFX"Failed to register (PPN=%u) as " "notification bitmap (error=%d).\n", bitmapPPN, result)); return FALSE; } return TRUE; } /* *------------------------------------------------------------------------- * * VMCIDoorbellFireEntries -- * * Executes or schedules the handlers for a given notify index. * * Result: * Notification hash entry if found. NULL otherwise. * * Side effects: * Whatever the side effects of the handlers are. * *------------------------------------------------------------------------- */ static void VMCIDoorbellFireEntries(uint32 notifyIdx) // IN { uint32 bucket = VMCI_DOORBELL_HASH(notifyIdx); VMCIListItem *iter; VMCILockFlags flags; ASSERT(VMCI_GuestPersonalityActive()); VMCI_GrabLock_BH(&vmciDoorbellIT.lock, &flags); VMCIList_Scan(iter, &vmciDoorbellIT.entries[bucket]) { VMCIDoorbellEntry *cur = VMCIList_Entry(iter, VMCIDoorbellEntry, idxListItem); ASSERT(cur); if (cur->idx == notifyIdx && Atomic_Read(&cur->active) == 1) { ASSERT(cur->notifyCB); if (cur->runDelayed) { int err; VMCIResource_Hold(&cur->resource); err = VMCI_ScheduleDelayedWork(VMCIDoorbellDelayedDispatchCB, cur); if (err != VMCI_SUCCESS) { VMCIResource_Release(&cur->resource); goto out; } } else { cur->notifyCB(cur->clientData); } } } out: VMCI_ReleaseLock_BH(&vmciDoorbellIT.lock, flags); } /* *------------------------------------------------------------------------------ * * VMCI_ScanNotificationBitmap -- * * Scans the notification bitmap, collects pending notifications, * resets the bitmap and invokes appropriate callbacks. * * Results: * None. * * Side effects: * May schedule tasks, allocate memory and run callbacks. * *------------------------------------------------------------------------------ */ void VMCI_ScanNotificationBitmap(uint8 *bitmap) { uint32 idx; ASSERT(bitmap); ASSERT(VMCI_GuestPersonalityActive()); for (idx = 0; idx < maxNotifyIdx; idx++) { if (bitmap[idx] & 0x1) { bitmap[idx] &= ~1; VMCIDoorbellFireEntries(idx); } } } #else // SOLARIS) || __APPLE__ /* *----------------------------------------------------------------------------- * * VMCIDoorbell_Create/VMCIDoorbell_Destroy/VMCIDoorbell_Notify/ * VMCIDoorbellHostContextNotify/VMCIDoorbellGetPrivFlags/ * VMCIDoorbell_Init/VMCIDoorbell_Exit -- * * The doorbell functions have yet to be implemented for Solaris * and Mac OS X guest drivers. * * Results: * VMCI_ERROR_UNAVAILABLE. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(VMCIDoorbell_Create) int VMCIDoorbell_Create(VMCIHandle *handle, // IN uint32 flags, // IN VMCIPrivilegeFlags privFlags, // IN VMCICallback notifyCB, // IN void *clientData) // IN { return VMCI_ERROR_UNAVAILABLE; } VMCI_EXPORT_SYMBOL(VMCIDoorbell_Destroy) int VMCIDoorbell_Destroy(VMCIHandle handle) // IN { return VMCI_ERROR_UNAVAILABLE; } VMCI_EXPORT_SYMBOL(VMCIDoorbell_Notify) int VMCIDoorbell_Notify(VMCIHandle handle, // IN VMCIPrivilegeFlags privFlags) // IN { return VMCI_ERROR_UNAVAILABLE; } int VMCIDoorbellHostContextNotify(VMCIId srcCID, // IN VMCIHandle handle) // IN { return VMCI_ERROR_UNAVAILABLE; } int VMCIDoorbellGetPrivFlags(VMCIHandle handle, // IN VMCIPrivilegeFlags *privFlags) // OUT { return VMCI_ERROR_UNAVAILABLE; } int VMCIDoorbell_Init(void) { return VMCI_SUCCESS; } void VMCIDoorbell_Exit(void) { } #endif // SOLARIS) || __APPLE__ open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciQueuePair.c0000644765153500003110000030323212220061556023422 0ustar dtormts/********************************************************* * Copyright (C) 2007-2011 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciQueuePair.c -- * * VMCI QueuePair API implementation in the host driver. */ #include "vmci_kernel_if.h" #include "vm_assert.h" #include "vmci_defs.h" #include "vmci_handle_array.h" #include "vmci_infrastructure.h" #include "vmciCommonInt.h" #include "vmciContext.h" #include "vmciDatagram.h" #include "vmciDriver.h" #include "vmciEvent.h" #include "vmciHashtable.h" #include "vmciKernelAPI.h" #include "vmciQueuePair.h" #include "vmciResource.h" #include "vmciRoute.h" #if defined(VMKERNEL) # include "vmciVmkInt.h" # include "vm_libc.h" #endif #define LGPFX "VMCIQueuePair: " /* * In the following, we will distinguish between two kinds of VMX processes - * the ones with versions lower than VMCI_VERSION_NOVMVM that use specialized * VMCI page files in the VMX and supporting VM to VM communication) and the * newer ones that use the guest memory directly. We will in the following refer * to the older VMX versions as old-style VMX'en, and the newer ones as new-style * VMX'en. * * The state transition datagram is as follows (the VMCIQPB_ prefix has been * removed for readability) - see below for more details on the transtions: * * -------------- NEW ------------- * | | * \_/ \_/ * CREATED (nomem) <-----------------> CREATED * | | | * | o-----------------------o | * | | | * \_/ \_/ \_/ * ATTACHED (nomem) <----------------> ATTACHED * | | | * | o----------------------o | * | | | * \_/ \_/ \_/ * SHUTDOWN (nomem) <----------------> SHUTDOWN * | | * | | * -------------> gone <------------- * * In more detail. When a VMCI queue pair is first created, it will be in the * VMCIQPB_NEW state. It will then move into one of the following states: * - VMCIQPB_CREATED with hasMem[0] FALSE: this state indicates that either: * - the created was performed by a host endpoint, in which case there is no * backing memory yet. * - the create was initiated by an old-style VMX, that uses * VMCIQPBroker_SetPageStore to specify the UVAs of the queue pair at a * later point in time. This state can be distinguished from the one above * by the context ID of the creator. A host side is not allowed to attach * until the page store has been set. * - VMCIQPB_CREATED with hasMem[0] TRUE: this state is the result when the * queue pair is created by a VMX using the queue pair device backend that * sets the UVAs of the queue pair immediately and stores the information * for later attachers. At this point, it is ready for the host side to attach * to it. * Once the queue pair is in one of the created states (with the exception of the * case mentioned for older VMX'en above), it is possible to attach to the queue * pair. Again we have two new states possible: * - VMCIQPB_ATTACHED with hasMem[0] TRUE: this state can be reached through * the following paths: * - from VMCIQPB_CREATED without memory when a new-style VMX allocates a queue pair, * and attaches to a queue pair previously created by the host side. * - from VMCIQPB_CREATED with memory when the host side attaches to a queue pair * already created by a guest. * - from VMCIQPB_ATTACHED without memory, when an old-style VMX calls * VMCIQPBroker_SetPageStore (see below). * - VMCIQPB_ATTACHED with hasMem[0] FALSE: If the queue pair already was in the * VMCIQPB_CREATED without memory due to a host side create, an old-style VMX * will bring the queue pair into this state. Once VMCIQPBroker_SetPageStore is * called to register the user memory, the VMCIQPB_ATTACH with memory state will be * entered. * From the attached queue pair, the queue pair can enter the shutdown states * when either side of the queue pair detaches. If the guest side detaches first, * the queue pair will enter the VMCIQPB_SHUTDOWN without memory state, where the content * of the queue pair will no longer be available. If the host side detaches first, * the queue pair will either enter the VMCIQPB_SHUTDOWN with memory, if the guest memory * is currently mapped, or VMCIQPB_SHUTDOWN without memory, if the guest memory is not * mapped (e.g., the host detaches while a guest is stunned). * * New-style VMX'en will also unmap guest memory, if the guest is quiesced, e.g., * during a snapshot operation. In that case, the guest memory will no longer be * available, and the queue pair will transition from memory to memory-less state. * The VMX may later map the memory once more, in which case the queue * pair will transition from the memory-less state at that point back to the memory * state. */ typedef enum { VMCIQPB_NEW, VMCIQPB_CREATED, VMCIQPB_ATTACHED, VMCIQPB_SHUTDOWN, VMCIQPB_GONE } QPBrokerState; /* * In the queue pair broker, we always use the guest point of view for * the produce and consume queue values and references, e.g., the * produce queue size stored is the guests produce queue size. The * host endpoint will need to swap these around. The only exception is * the local queue pairs on the host, in which case the host endpoint * that creates the queue pair will have the right orientation, and * the attaching host endpoint will need to swap. */ typedef struct QueuePairEntry { VMCIListItem listItem; VMCIHandle handle; VMCIId peer; uint32 flags; uint64 produceSize; uint64 consumeSize; uint32 refCount; } QueuePairEntry; typedef struct QPBrokerEntry { QueuePairEntry qp; VMCIId createId; VMCIId attachId; QPBrokerState stateQP; Bool hasMem[2]; Bool requireTrustedAttach; Bool createdByTrusted; Bool vmciPageFiles; // Created by VMX using VMCI page files VMCIQueue *produceQ; VMCIQueue *consumeQ; VMCIQueueHeader savedProduceQ; VMCIQueueHeader savedConsumeQ; VMCIEventReleaseCB wakeupCB; void *clientData; void *localMem; // Kernel memory for local queue pair Bool isVM2VM; } QPBrokerEntry; #if !defined(VMKERNEL) typedef struct QPGuestEndpoint { QueuePairEntry qp; uint64 numPPNs; void *produceQ; void *consumeQ; Bool hibernateFailure; PPNSet ppnSet; } QPGuestEndpoint; #endif typedef struct QueuePairList { VMCIList head; Atomic_uint32 hibernate; VMCIMutex mutex; } QueuePairList; static QueuePairList qpBrokerList; #define QPE_NUM_PAGES(_QPE) ((uint32)(CEILING(_QPE.produceSize, PAGE_SIZE) + \ CEILING(_QPE.consumeSize, PAGE_SIZE) + 2)) #if !defined(VMKERNEL) static QueuePairList qpGuestEndpoints; static VMCIHandleArray *hibernateFailedList; static VMCILock hibernateFailedListLock; #endif static void VMCIQPBrokerLock(void); static void VMCIQPBrokerUnlock(void); static QueuePairEntry *QueuePairList_FindEntry(QueuePairList *qpList, VMCIHandle handle); static void QueuePairList_AddEntry(QueuePairList *qpList, QueuePairEntry *entry); static void QueuePairList_RemoveEntry(QueuePairList *qpList, QueuePairEntry *entry); static QueuePairEntry *QueuePairList_GetHead(QueuePairList *qpList); static int QueuePairNotifyPeer(Bool attach, VMCIHandle handle, VMCIId myId, VMCIId peerId); static int VMCIQPBrokerAllocInt(VMCIHandle handle, VMCIId peer, uint32 flags, VMCIPrivilegeFlags privFlags, uint64 produceSize, uint64 consumeSize, QueuePairPageStore *pageStore, VMCIContext *context, VMCIEventReleaseCB wakeupCB, void *clientData, QPBrokerEntry **ent, Bool *swap); static int VMCIQPBrokerAttach(QPBrokerEntry *entry, VMCIId peer, uint32 flags, VMCIPrivilegeFlags privFlags, uint64 produceSize, uint64 consumeSize, QueuePairPageStore *pageStore, VMCIContext *context, VMCIEventReleaseCB wakeupCB, void *clientData, QPBrokerEntry **ent); static int VMCIQPBrokerCreate(VMCIHandle handle, VMCIId peer, uint32 flags, VMCIPrivilegeFlags privFlags, uint64 produceSize, uint64 consumeSize, QueuePairPageStore *pageStore, VMCIContext *context, VMCIEventReleaseCB wakeupCB, void *clientData, QPBrokerEntry **ent); static int VMCIQueuePairAllocHostWork(VMCIHandle *handle, VMCIQueue **produceQ, uint64 produceSize, VMCIQueue **consumeQ, uint64 consumeSize, VMCIId peer, uint32 flags, VMCIPrivilegeFlags privFlags, VMCIEventReleaseCB wakeupCB, void *clientData); static int VMCIQueuePairDetachHostWork(VMCIHandle handle); static int QueuePairSaveHeaders(QPBrokerEntry *entry, VMCIId contextId); static void QueuePairResetSavedHeaders(QPBrokerEntry *entry); #if !defined(VMKERNEL) static int QueuePairNotifyPeerLocal(Bool attach, VMCIHandle handle); static QPGuestEndpoint *QPGuestEndpointCreate(VMCIHandle handle, VMCIId peer, uint32 flags, uint64 produceSize, uint64 consumeSize, void *produceQ, void *consumeQ); static void QPGuestEndpointDestroy(QPGuestEndpoint *entry); static int VMCIQueuePairAllocHypercall(const QPGuestEndpoint *entry); static int VMCIQueuePairAllocGuestWork(VMCIHandle *handle, VMCIQueue **produceQ, uint64 produceSize, VMCIQueue **consumeQ, uint64 consumeSize, VMCIId peer, uint32 flags, VMCIPrivilegeFlags privFlags); static int VMCIQueuePairDetachGuestWork(VMCIHandle handle); static int VMCIQueuePairDetachHypercall(VMCIHandle handle); static void VMCIQPMarkHibernateFailed(QPGuestEndpoint *entry); static void VMCIQPUnmarkHibernateFailed(QPGuestEndpoint *entry); extern int VMCI_SendDatagram(VMCIDatagram *); #endif /* *----------------------------------------------------------------------------- * * VMCIQPBEGetIndex -- * * Retrieve index into host's queue structures for queue entry. * * Results: * 0 or 1. Or crash. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static unsigned int VMCIQPBEGetIndex(const QPBrokerEntry *entry, // IN VMCIId contextId) // IN { ASSERT(entry->createId == contextId || entry->attachId == contextId); return (entry->isVM2VM && entry->createId != contextId) ? 1 : 0; } /* *----------------------------------------------------------------------------- * * VMCIQueuePair_Alloc -- * * Allocates a VMCI QueuePair. Only checks validity of input * arguments. The real work is done in the host or guest * specific function. * * Results: * VMCI_SUCCESS on success, appropriate error code otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int VMCIQueuePair_Alloc(VMCIHandle *handle, // IN/OUT VMCIQueue **produceQ, // OUT uint64 produceSize, // IN VMCIQueue **consumeQ, // OUT uint64 consumeSize, // IN VMCIId peer, // IN uint32 flags, // IN VMCIPrivilegeFlags privFlags, // IN Bool guestEndpoint, // IN VMCIEventReleaseCB wakeupCB, // IN void *clientData) // IN { if (!handle || !produceQ || !consumeQ || (!produceSize && !consumeSize) || (flags & ~VMCI_QP_ALL_FLAGS)) { return VMCI_ERROR_INVALID_ARGS; } if (guestEndpoint) { #if !defined(VMKERNEL) return VMCIQueuePairAllocGuestWork(handle, produceQ, produceSize, consumeQ, consumeSize, peer, flags, privFlags); #else return VMCI_ERROR_INVALID_ARGS; #endif } else { return VMCIQueuePairAllocHostWork(handle, produceQ, produceSize, consumeQ, consumeSize, peer, flags, privFlags, wakeupCB, clientData); } } /* *----------------------------------------------------------------------------- * * VMCIQueuePair_Detach -- * * Detaches from a VMCI QueuePair. Only checks validity of input argument. * Real work is done in the host or guest specific function. * * Results: * Success or failure. * * Side effects: * Memory is freed. * *----------------------------------------------------------------------------- */ int VMCIQueuePair_Detach(VMCIHandle handle, // IN Bool guestEndpoint) // IN { if (VMCI_HANDLE_INVALID(handle)) { return VMCI_ERROR_INVALID_ARGS; } if (guestEndpoint) { #if !defined(VMKERNEL) return VMCIQueuePairDetachGuestWork(handle); #else return VMCI_ERROR_INVALID_ARGS; #endif } else { return VMCIQueuePairDetachHostWork(handle); } } /* *----------------------------------------------------------------------------- * * QueuePairList_Init -- * * Initializes the list of QueuePairs. * * Results: * Success or failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE int QueuePairList_Init(QueuePairList *qpList) // IN { int ret; VMCIList_Init(&qpList->head); Atomic_Write(&qpList->hibernate, 0); ret = VMCIMutex_Init(&qpList->mutex, "VMCIQPListLock", VMCI_SEMA_RANK_QUEUEPAIRLIST); return ret; } /* *----------------------------------------------------------------------------- * * QueuePairList_Destroy -- * * Destroy the list's mutex. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE void QueuePairList_Destroy(QueuePairList *qpList) { VMCIMutex_Destroy(&qpList->mutex); VMCIList_Init(&qpList->head); } /* *----------------------------------------------------------------------------- * * VMCIQPBrokerLock -- * * Acquires the mutex protecting a VMCI queue pair broker transaction. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VMCIQPBrokerLock(void) { VMCIMutex_Acquire(&qpBrokerList.mutex); } /* *----------------------------------------------------------------------------- * * VMCIQPBrokerUnlock -- * * Releases the mutex protecting a VMCI queue pair broker transaction. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VMCIQPBrokerUnlock(void) { VMCIMutex_Release(&qpBrokerList.mutex); } /* *----------------------------------------------------------------------------- * * QueuePairList_FindEntry -- * * Finds the entry in the list corresponding to a given handle. Assumes * that the list is locked. * * Results: * Pointer to entry. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static QueuePairEntry * QueuePairList_FindEntry(QueuePairList *qpList, // IN VMCIHandle handle) // IN { VMCIListItem *next; if (VMCI_HANDLE_INVALID(handle)) { return NULL; } VMCIList_Scan(next, &qpList->head) { QueuePairEntry *entry = VMCIList_Entry(next, QueuePairEntry, listItem); if (VMCI_HANDLE_EQUAL(entry->handle, handle)) { return entry; } } return NULL; } /* *----------------------------------------------------------------------------- * * QueuePairList_AddEntry -- * * Adds the given entry to the list. Assumes that the list is locked. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void QueuePairList_AddEntry(QueuePairList *qpList, // IN QueuePairEntry *entry) // IN { if (entry) { VMCIList_Insert(&entry->listItem, &qpList->head); } } /* *----------------------------------------------------------------------------- * * QueuePairList_RemoveEntry -- * * Removes the given entry from the list. Assumes that the list is locked. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void QueuePairList_RemoveEntry(QueuePairList *qpList, // IN QueuePairEntry *entry) // IN { if (entry) { VMCIList_Remove(&entry->listItem); } } /* *----------------------------------------------------------------------------- * * QueuePairList_GetHead -- * * Returns the entry from the head of the list. Assumes that the list is * locked. * * Results: * Pointer to entry. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static QueuePairEntry * QueuePairList_GetHead(QueuePairList *qpList) { VMCIListItem *first = VMCIList_First(&qpList->head); if (first) { QueuePairEntry *entry = VMCIList_Entry(first, QueuePairEntry, listItem); return entry; } return NULL; } /* *----------------------------------------------------------------------------- * * VMCIQPBroker_Init -- * * Initalizes queue pair broker state. * * Results: * Success or failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int VMCIQPBroker_Init(void) { return QueuePairList_Init(&qpBrokerList); } /* *----------------------------------------------------------------------------- * * VMCIQPBroker_Exit -- * * Destroys the queue pair broker state. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMCIQPBroker_Exit(void) { QPBrokerEntry *entry; VMCIQPBrokerLock(); while ((entry = (QPBrokerEntry *)QueuePairList_GetHead(&qpBrokerList))) { QueuePairList_RemoveEntry(&qpBrokerList, &entry->qp); VMCI_FreeKernelMem(entry, sizeof *entry); } VMCIQPBrokerUnlock(); QueuePairList_Destroy(&qpBrokerList); } /* *----------------------------------------------------------------------------- * * VMCIQPBroker_Alloc -- * * Requests that a queue pair be allocated with the VMCI queue * pair broker. Allocates a queue pair entry if one does not * exist. Attaches to one if it exists, and retrieves the page * files backing that QueuePair. Assumes that the queue pair * broker lock is held. * * Results: * Success or failure. * * Side effects: * Memory may be allocated. * *----------------------------------------------------------------------------- */ int VMCIQPBroker_Alloc(VMCIHandle handle, // IN VMCIId peer, // IN uint32 flags, // IN VMCIPrivilegeFlags privFlags, // IN uint64 produceSize, // IN uint64 consumeSize, // IN QueuePairPageStore *pageStore, // IN/OUT VMCIContext *context) // IN: Caller { return VMCIQPBrokerAllocInt(handle, peer, flags, privFlags, produceSize, consumeSize, pageStore, context, NULL, NULL, NULL, NULL); } /* *----------------------------------------------------------------------------- * * QueuePairNotifyPeer -- * * Enqueues an event datagram to notify the peer VM attached to * the given queue pair handle about attach/detach event by the * given VM. * * Results: * Payload size of datagram enqueued on success, error code otherwise. * * Side effects: * Memory is allocated. * *----------------------------------------------------------------------------- */ int QueuePairNotifyPeer(Bool attach, // IN: attach or detach? VMCIHandle handle, // IN VMCIId myId, // IN VMCIId peerId) // IN: CID of VM to notify { int rv; VMCIEventMsg *eMsg; VMCIEventPayload_QP *evPayload; char buf[sizeof *eMsg + sizeof *evPayload]; if (VMCI_HANDLE_INVALID(handle) || myId == VMCI_INVALID_ID || peerId == VMCI_INVALID_ID) { return VMCI_ERROR_INVALID_ARGS; } /* * Notification message contains: queue pair handle and * attaching/detaching VM's context id. */ eMsg = (VMCIEventMsg *)buf; /* * In VMCIContext_EnqueueDatagram() we enforce the upper limit on number of * pending events from the hypervisor to a given VM otherwise a rogue VM * could do an arbitrary number of attach and detach operations causing memory * pressure in the host kernel. */ /* Clear out any garbage. */ memset(eMsg, 0, sizeof buf); eMsg->hdr.dst = VMCI_MAKE_HANDLE(peerId, VMCI_EVENT_HANDLER); eMsg->hdr.src = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_CONTEXT_RESOURCE_ID); eMsg->hdr.payloadSize = sizeof *eMsg + sizeof *evPayload - sizeof eMsg->hdr; eMsg->eventData.event = attach ? VMCI_EVENT_QP_PEER_ATTACH : VMCI_EVENT_QP_PEER_DETACH; evPayload = VMCIEventMsgPayload(eMsg); evPayload->handle = handle; evPayload->peerId = myId; rv = VMCIDatagram_Dispatch(VMCI_HYPERVISOR_CONTEXT_ID, (VMCIDatagram *)eMsg, FALSE); if (rv < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to enqueue QueuePair %s event datagram for " "context (ID=0x%x).\n", attach ? "ATTACH" : "DETACH", peerId)); } return rv; } /* *---------------------------------------------------------------------- * * VMCIQueuePairAllocHostWork -- * * This function implements the kernel API for allocating a queue * pair. * * Results: * VMCI_SUCCESS on succes and appropriate failure code otherwise. * * Side effects: * May allocate memory. * *---------------------------------------------------------------------- */ static int VMCIQueuePairAllocHostWork(VMCIHandle *handle, // IN/OUT VMCIQueue **produceQ, // OUT uint64 produceSize, // IN VMCIQueue **consumeQ, // OUT uint64 consumeSize, // IN VMCIId peer, // IN uint32 flags, // IN VMCIPrivilegeFlags privFlags, // IN VMCIEventReleaseCB wakeupCB, // IN void *clientData) // IN { VMCIContext *context; QPBrokerEntry *entry; int result; Bool swap; if (VMCI_HANDLE_INVALID(*handle)) { VMCIId resourceID = VMCIResource_GetID(VMCI_HOST_CONTEXT_ID); if (resourceID == VMCI_INVALID_ID) { return VMCI_ERROR_NO_HANDLE; } *handle = VMCI_MAKE_HANDLE(VMCI_HOST_CONTEXT_ID, resourceID); } context = VMCIContext_Get(VMCI_HOST_CONTEXT_ID); ASSERT(context); entry = NULL; result = VMCIQPBrokerAllocInt(*handle, peer, flags, privFlags, produceSize, consumeSize, NULL, context, wakeupCB, clientData, &entry, &swap); if (result == VMCI_SUCCESS) { if (swap) { /* * If this is a local queue pair, the attacher will swap around produce * and consume queues. */ *produceQ = entry->consumeQ; *consumeQ = entry->produceQ; } else { *produceQ = entry->produceQ; *consumeQ = entry->consumeQ; } } else { *handle = VMCI_INVALID_HANDLE; VMCI_DEBUG_LOG(4, (LGPFX"queue pair broker failed to alloc (result=%d).\n", result)); } VMCIContext_Release(context); return result; } /* *---------------------------------------------------------------------- * * VMCIQueuePairDetachHostWork -- * * This function implements the host kernel API for detaching from * a queue pair. * * Results: * VMCI_SUCCESS on success and appropriate failure code otherwise. * * Side effects: * May deallocate memory. * *---------------------------------------------------------------------- */ static int VMCIQueuePairDetachHostWork(VMCIHandle handle) // IN { int result; VMCIContext *context; context = VMCIContext_Get(VMCI_HOST_CONTEXT_ID); result = VMCIQPBroker_Detach(handle, context); VMCIContext_Release(context); return result; } /* *----------------------------------------------------------------------------- * * VMCIQPBrokerAllocInt -- * * QueuePair_Alloc for use when setting up queue pair endpoints * on the host. Like QueuePair_Alloc, but returns a pointer to * the QPBrokerEntry on success. * * Results: * Success or failure. * * Side effects: * Memory may be allocated. * *----------------------------------------------------------------------------- */ static int VMCIQPBrokerAllocInt(VMCIHandle handle, // IN VMCIId peer, // IN uint32 flags, // IN VMCIPrivilegeFlags privFlags, // IN uint64 produceSize, // IN uint64 consumeSize, // IN QueuePairPageStore *pageStore, // IN/OUT VMCIContext *context, // IN: Caller VMCIEventReleaseCB wakeupCB, // IN void *clientData, // IN QPBrokerEntry **ent, // OUT Bool *swap) // OUT: swap queues? { const VMCIId contextId = VMCIContext_GetId(context); Bool create; QPBrokerEntry *entry; Bool isLocal = flags & VMCI_QPFLAG_LOCAL; int result; if (VMCI_HANDLE_INVALID(handle) || (flags & ~VMCI_QP_ALL_FLAGS) || (isLocal && (!vmkernel || contextId != VMCI_HOST_CONTEXT_ID || handle.context != contextId)) || !(produceSize || consumeSize) || !context || contextId == VMCI_INVALID_ID || handle.context == VMCI_INVALID_ID) { VMCI_DEBUG_LOG(5, ("Invalid argument - handle, flags, whatever\n")); return VMCI_ERROR_INVALID_ARGS; } if (pageStore && !VMCI_QP_PAGESTORE_IS_WELLFORMED(pageStore)) { VMCI_DEBUG_LOG(5, ("Invalid argument - page store\n")); return VMCI_ERROR_INVALID_ARGS; } /* * In the initial argument check, we ensure that non-vmkernel hosts * are not allowed to create local queue pairs. */ ASSERT(vmkernel || !isLocal); VMCIQPBrokerLock(); if (!isLocal && VMCIContext_QueuePairExists(context, handle)) { VMCI_DEBUG_LOG(4, (LGPFX"Context (ID=0x%x) already attached to queue pair " "(handle=0x%x:0x%x).\n", contextId, handle.context, handle.resource)); VMCIQPBrokerUnlock(); return VMCI_ERROR_ALREADY_EXISTS; } entry = (QPBrokerEntry *)QueuePairList_FindEntry(&qpBrokerList, handle); if (!entry) { create = TRUE; result = VMCIQPBrokerCreate(handle, peer, flags, privFlags, produceSize, consumeSize, pageStore, context, wakeupCB, clientData, ent); } else { create = FALSE; result = VMCIQPBrokerAttach(entry, peer, flags, privFlags, produceSize, consumeSize, pageStore, context, wakeupCB, clientData, ent); } VMCIQPBrokerUnlock(); if (swap) { *swap = (contextId == VMCI_HOST_CONTEXT_ID) && !(create && isLocal); } return result; } /* *----------------------------------------------------------------------------- * * VMCIQPBrokerCreate -- * * The first endpoint issuing a queue pair allocation will create the state * of the queue pair in the queue pair broker. * * If the creator is a guest, it will associate a VMX virtual address range * with the queue pair as specified by the pageStore. For compatibility with * older VMX'en, that would use a separate step to set the VMX virtual * address range, the virtual address range can be registered later using * VMCIQPBroker_SetPageStore. In that case, a pageStore of NULL should be * used. * * If the creator is the host, a pageStore of NULL should be used as well, * since the host is not able to supply a page store for the queue pair. * * For older VMX and host callers, the queue pair will be created in the * VMCIQPB_CREATED_NO_MEM state, and for current VMX callers, it will be * created in VMCOQPB_CREATED_MEM state. * * Results: * VMCI_SUCCESS on success, appropriate error code otherwise. * * Side effects: * Memory will be allocated, and pages may be pinned. * *----------------------------------------------------------------------------- */ static int VMCIQPBrokerCreate(VMCIHandle handle, // IN VMCIId peer, // IN uint32 flags, // IN VMCIPrivilegeFlags privFlags, // IN uint64 produceSize, // IN uint64 consumeSize, // IN QueuePairPageStore *pageStore, // IN VMCIContext *context, // IN: Caller VMCIEventReleaseCB wakeupCB, // IN void *clientData, // IN QPBrokerEntry **ent) // OUT { QPBrokerEntry *entry = NULL; const VMCIId contextId = VMCIContext_GetId(context); Bool isLocal = flags & VMCI_QPFLAG_LOCAL; int result; uint64 guestProduceSize; uint64 guestConsumeSize; Bool isVM2VM; /* * Do not create if the caller asked not to. */ if (flags & VMCI_QPFLAG_ATTACH_ONLY) { VMCI_DEBUG_LOG(5, ("QP Create - attach only\n")); return VMCI_ERROR_NOT_FOUND; } /* * Creator's context ID should match handle's context ID or the creator * must allow the context in handle's context ID as the "peer". */ if (handle.context != contextId && handle.context != peer) { VMCI_DEBUG_LOG(5, ("QP Create - contextId fail, %x != %x, %x\n", handle.context, contextId, peer)); return VMCI_ERROR_NO_ACCESS; } isVM2VM = VMCI_CONTEXT_IS_VM(contextId) && VMCI_CONTEXT_IS_VM(peer); if (isVM2VM) { VMCI_DEBUG_LOG(5, ("QP Create - VM2VM\n")); return VMCI_ERROR_DST_UNREACHABLE; } /* * Creator's context ID for local queue pairs should match the * peer, if a peer is specified. */ if (isLocal && peer != VMCI_INVALID_ID && contextId != peer) { VMCI_DEBUG_LOG(5, ("QP Create - peer %x, context %x\n", peer, contextId)); return VMCI_ERROR_NO_ACCESS; } entry = VMCI_AllocKernelMem(sizeof *entry, VMCI_MEMORY_ATOMIC); if (!entry) { VMCI_DEBUG_LOG(5, ("QP Create - no memory\n")); return VMCI_ERROR_NO_MEM; } if (VMCIContext_GetId(context) == VMCI_HOST_CONTEXT_ID && !isLocal) { /* * The queue pair broker entry stores values from the guest * point of view, so a creating host side endpoint should swap * produce and consume values -- unless it is a local queue * pair, in which case no swapping is necessary, since the local * attacher will swap queues. */ guestProduceSize = consumeSize; guestConsumeSize = produceSize; } else { guestProduceSize = produceSize; guestConsumeSize = consumeSize; } memset(entry, 0, sizeof *entry); entry->qp.handle = handle; entry->qp.peer = peer; entry->qp.flags = flags; entry->qp.produceSize = guestProduceSize; entry->qp.consumeSize = guestConsumeSize; entry->qp.refCount = 1; entry->createId = contextId; entry->attachId = VMCI_INVALID_ID; entry->stateQP = VMCIQPB_NEW; entry->requireTrustedAttach = (context->privFlags & VMCI_PRIVILEGE_FLAG_RESTRICTED) ? TRUE : FALSE; entry->createdByTrusted = (privFlags & VMCI_PRIVILEGE_FLAG_TRUSTED) ? TRUE : FALSE; entry->vmciPageFiles = FALSE; entry->wakeupCB = wakeupCB; entry->clientData = clientData; entry->isVM2VM = FALSE; /* It is not VM2VM until VM attaches... */ entry->produceQ = VMCIHost_AllocQueue(guestProduceSize); if (entry->produceQ == NULL) { result = VMCI_ERROR_NO_MEM; VMCI_DEBUG_LOG(5, ("QP Create - no memory PQ\n")); goto error; } entry->consumeQ = VMCIHost_AllocQueue(guestConsumeSize); if (entry->consumeQ == NULL) { result = VMCI_ERROR_NO_MEM; VMCI_DEBUG_LOG(5, ("QP Create - no memory CQ\n")); goto error; } VMCI_InitQueueMutex(entry->produceQ, entry->consumeQ); VMCIList_InitEntry(&entry->qp.listItem); if (isLocal) { ASSERT(pageStore == NULL); entry->localMem = VMCI_AllocKernelMem(QPE_NUM_PAGES(entry->qp) * PAGE_SIZE, VMCI_MEMORY_NONPAGED); if (entry->localMem == NULL) { result = VMCI_ERROR_NO_MEM; VMCI_DEBUG_LOG(5, ("QP Create - no memory LM\n")); goto error; } entry->stateQP = VMCIQPB_CREATED; entry->hasMem[0] = TRUE; entry->produceQ->qHeader = entry->localMem; entry->consumeQ->qHeader = (VMCIQueueHeader *)((uint8 *)entry->localMem + (CEILING(entry->qp.produceSize, PAGE_SIZE) + 1) * PAGE_SIZE); VMCIQueueHeader_Init(entry->produceQ->qHeader, handle); VMCIQueueHeader_Init(entry->consumeQ->qHeader, handle); } else if (pageStore) { ASSERT(entry->createId != VMCI_HOST_CONTEXT_ID); /* * The VMX already initialized the queue pair headers, so no * need for the kernel side to do that. */ result = VMCIHost_RegisterUserMemory(0, pageStore, entry->produceQ, entry->consumeQ); if (result < VMCI_SUCCESS) { VMCI_DEBUG_LOG(5, ("QP Create - cannot register user memory\n")); goto error; } VMCIHost_MarkQueuesAvailable(0, entry->produceQ, entry->consumeQ); entry->stateQP = VMCIQPB_CREATED; entry->hasMem[0] = TRUE; } else { /* * A create without a pageStore may be either a host side create (in which * case we are waiting for the guest side to supply the memory) or an old * style queue pair create (in which case we will expect a set page store * call as the next step). */ entry->stateQP = VMCIQPB_CREATED; } QueuePairList_AddEntry(&qpBrokerList, &entry->qp); if (ent != NULL) { *ent = entry; } VMCIContext_QueuePairCreate(context, handle); return VMCI_SUCCESS; error: if (entry != NULL) { if (entry->produceQ != NULL) { VMCIHost_FreeQueue(entry->produceQ, guestProduceSize); } if (entry->consumeQ != NULL) { VMCIHost_FreeQueue(entry->consumeQ, guestConsumeSize); } VMCI_FreeKernelMem(entry, sizeof *entry); } return result; } /* *----------------------------------------------------------------------------- * * VMCIQPBrokerAttach -- * * The second endpoint issuing a queue pair allocation will attach to the * queue pair registered with the queue pair broker. * * If the attacher is a guest, it will associate a VMX virtual address range * with the queue pair as specified by the pageStore. At this point, the * already attach host endpoint may start using the queue pair, and an * attach event is sent to it. For compatibility with older VMX'en, that * used a separate step to set the VMX virtual address range, the virtual * address range can be registered later using VMCIQPBroker_SetPageStore. In * that case, a pageStore of NULL should be used, and the attach event will * be generated once the actual page store has been set. * * If the attacher is the host, a pageStore of NULL should be used as well, * since the page store information is already set by the guest. * * For new VMX and host callers, the queue pair will be moved to the * VMCIQPB_ATTACHED_MEM state, and for older VMX callers, it will be * moved to the VMCOQPB_ATTACHED_NO_MEM state. * * Results: * VMCI_SUCCESS on success, appropriate error code otherwise. * * Side effects: * Memory will be allocated, and pages may be pinned. * *----------------------------------------------------------------------------- */ static int VMCIQPBrokerAttach(QPBrokerEntry *entry, // IN VMCIId peer, // IN uint32 flags, // IN VMCIPrivilegeFlags privFlags, // IN uint64 produceSize, // IN uint64 consumeSize, // IN QueuePairPageStore *pageStore, // IN/OUT VMCIContext *context, // IN: Caller VMCIEventReleaseCB wakeupCB, // IN void *clientData, // IN QPBrokerEntry **ent) // OUT { const VMCIId contextId = VMCIContext_GetId(context); Bool isLocal = flags & VMCI_QPFLAG_LOCAL; int result; Bool isVM2VM; if (entry->stateQP != VMCIQPB_CREATED) { VMCI_DEBUG_LOG(5, ("QP Attach - state is %x\n", entry->stateQP)); return VMCI_ERROR_UNAVAILABLE; } if (isLocal) { if (!(entry->qp.flags & VMCI_QPFLAG_LOCAL) || contextId != entry->createId) { VMCI_DEBUG_LOG(5, ("QP Attach - invalid args, ctx=%x, createId=%x\n", contextId, entry->createId)); return VMCI_ERROR_INVALID_ARGS; } } else if (contextId == entry->createId || contextId == entry->attachId) { VMCI_DEBUG_LOG(5, ("QP Attach - already, ctx=%x, create=%x, attach=%x\n", contextId, entry->createId, entry->attachId)); return VMCI_ERROR_ALREADY_EXISTS; } ASSERT(entry->qp.refCount < 2); ASSERT(entry->attachId == VMCI_INVALID_ID); isVM2VM = VMCI_CONTEXT_IS_VM(contextId) && VMCI_CONTEXT_IS_VM(entry->createId); if (isVM2VM) { VMCI_DEBUG_LOG(5, ("QP Attach - VM2VM\n")); return VMCI_ERROR_DST_UNREACHABLE; } /* * If we are attaching from a restricted context then the queuepair * must have been created by a trusted endpoint. */ if (context->privFlags & VMCI_PRIVILEGE_FLAG_RESTRICTED) { if (!entry->createdByTrusted) { VMCI_DEBUG_LOG(5, ("QP Attach - restricted vs trusted\n")); return VMCI_ERROR_NO_ACCESS; } } /* * If we are attaching to a queuepair that was created by a restricted * context then we must be trusted. */ if (entry->requireTrustedAttach) { if (!(privFlags & VMCI_PRIVILEGE_FLAG_TRUSTED)) { VMCI_DEBUG_LOG(5, ("QP Attach - trusted attach required\n")); return VMCI_ERROR_NO_ACCESS; } } /* * If the creator specifies VMCI_INVALID_ID in "peer" field, access * control check is not performed. */ if (entry->qp.peer != VMCI_INVALID_ID && entry->qp.peer != contextId) { VMCI_DEBUG_LOG(5, ("QP Attach - bad peer id %x != %x\n", contextId, entry->qp.peer)); return VMCI_ERROR_NO_ACCESS; } if (entry->createId == VMCI_HOST_CONTEXT_ID) { /* * Do not attach if the caller doesn't support Host Queue Pairs * and a host created this queue pair. */ if (!VMCIContext_SupportsHostQP(context)) { VMCI_DEBUG_LOG(5, ("QP Attach - no attach to host qp\n")); return VMCI_ERROR_INVALID_RESOURCE; } } else if (contextId == VMCI_HOST_CONTEXT_ID) { VMCIContext *createContext; Bool supportsHostQP; /* * Do not attach a host to a user created queue pair if that * user doesn't support host queue pair end points. */ createContext = VMCIContext_Get(entry->createId); supportsHostQP = VMCIContext_SupportsHostQP(createContext); VMCIContext_Release(createContext); if (!supportsHostQP) { VMCI_DEBUG_LOG(5, ("QP Attach - no host attach to qp\n")); return VMCI_ERROR_INVALID_RESOURCE; } } if ((entry->qp.flags & ~VMCI_QP_ASYMM) != (flags & ~VMCI_QP_ASYMM_PEER)) { VMCI_DEBUG_LOG(5, ("QP Attach - flags mismatch\n")); return VMCI_ERROR_QUEUEPAIR_MISMATCH; } if (contextId != VMCI_HOST_CONTEXT_ID && !isVM2VM) { /* * The queue pair broker entry stores values from the guest * point of view, so an attaching guest should match the values * stored in the entry. */ if (entry->qp.produceSize != produceSize || entry->qp.consumeSize != consumeSize) { VMCI_DEBUG_LOG(5, ("QP Attach - queue size mismatch\n")); return VMCI_ERROR_QUEUEPAIR_MISMATCH; } } else if (entry->qp.produceSize != consumeSize || entry->qp.consumeSize != produceSize) { VMCI_DEBUG_LOG(5, ("QP Attach - host queue size mismatch\n")); return VMCI_ERROR_QUEUEPAIR_MISMATCH; } if (contextId != VMCI_HOST_CONTEXT_ID) { /* * If a guest attached to a queue pair, it will supply the backing memory. * If this is a pre NOVMVM vmx, the backing memory will be supplied by * calling VMCIQPBroker_SetPageStore() following the return of the * VMCIQPBroker_Alloc() call. If it is a vmx of version NOVMVM or later, * the page store must be supplied as part of the VMCIQPBroker_Alloc call. * Under all circumstances must the initially created queue pair not have * any memory associated with it already. */ if (isVM2VM) { if (!pageStore || entry->stateQP != VMCIQPB_CREATED) { VMCI_DEBUG_LOG(5, ("QP Attach - bad QP state for VM2VM, %x, %p\n", entry->stateQP, pageStore)); return VMCI_ERROR_INVALID_ARGS; } } else { if (entry->stateQP != VMCIQPB_CREATED || entry->hasMem[0]) { VMCI_DEBUG_LOG(5, ("QP Attach - bad QP state, %x\n", entry->stateQP)); return VMCI_ERROR_INVALID_ARGS; } } if (pageStore != NULL) { unsigned int index; ASSERT(entry->isVM2VM == FALSE); entry->isVM2VM = isVM2VM; /* * Patch up host state to point to guest supplied memory. The VMX * already initialized the queue pair headers, so no need for the * kernel side to do that. */ index = isVM2VM ? 1 : 0; result = VMCIHost_RegisterUserMemory(index, pageStore, entry->produceQ, entry->consumeQ); if (result < VMCI_SUCCESS) { VMCI_DEBUG_LOG(5, ("QP Attach - cannot register memory\n")); entry->isVM2VM = FALSE; return result; } VMCIHost_MarkQueuesAvailable(index, entry->produceQ, entry->consumeQ); if (entry->qp.flags & VMCI_QPFLAG_NONBLOCK) { result = VMCIHost_MapQueues(index, entry->produceQ, entry->consumeQ, entry->qp.flags); if (result < VMCI_SUCCESS) { VMCIHost_ReleaseUserMemory(index, entry->produceQ, entry->consumeQ); entry->isVM2VM = FALSE; VMCI_DEBUG_LOG(5, ("QP Attach - cannot map queues\n")); return result; } } entry->stateQP = VMCIQPB_ATTACHED; entry->hasMem[index] = TRUE; } else { entry->stateQP = VMCIQPB_ATTACHED; } } else if (entry->stateQP == VMCIQPB_CREATED && !entry->hasMem[0]) { /* * The host side is attempting to attach to a queue pair that doesn't have * any memory associated with it. This must be a pre NOVMVM vmx that hasn't * set the page store information yet, or a quiesced VM. */ VMCI_DEBUG_LOG(5, ("QP Attach - QP without memory\n")); return VMCI_ERROR_UNAVAILABLE; } else { /* * For non-blocking queue pairs, we cannot rely on enqueue/dequeue to map * in the pages on the host-side, since it may block, so we make an attempt * here. */ if (flags & VMCI_QPFLAG_NONBLOCK) { /* * We only have to do work here if this is a host-to-VM queuepair. * Otherwise there's nothing to map, since the pages backing the * queues are allocated directly out of host memory. */ if (!isLocal) { VMCIHost_MarkQueuesAvailable(0, entry->produceQ, entry->consumeQ); result = VMCIHost_MapQueues(0, entry->produceQ, entry->consumeQ, flags); if (result < VMCI_SUCCESS) { VMCI_DEBUG_LOG(5, ("QP Attach - cannot map queues for host\n")); return result; } } entry->qp.flags |= flags & (VMCI_QPFLAG_NONBLOCK | VMCI_QPFLAG_PINNED); } /* * The host side has successfully attached to a queue pair. */ entry->stateQP = VMCIQPB_ATTACHED; } if (entry->stateQP == VMCIQPB_ATTACHED && entry->hasMem[0] && (!entry->isVM2VM || entry->hasMem[1])) { result = QueuePairNotifyPeer(TRUE, entry->qp.handle, contextId, entry->createId); if (result < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to notify peer (ID=0x%x) of attach to queue " "pair (handle=0x%x:0x%x).\n", entry->createId, entry->qp.handle.context, entry->qp.handle.resource)); } } entry->attachId = contextId; entry->qp.refCount++; if (wakeupCB) { ASSERT(!entry->wakeupCB); entry->wakeupCB = wakeupCB; entry->clientData = clientData; } /* * When attaching to local queue pairs, the context already has * an entry tracking the queue pair, so don't add another one. */ if (!isLocal) { VMCIContext_QueuePairCreate(context, entry->qp.handle); } else { ASSERT(VMCIContext_QueuePairExists(context, entry->qp.handle)); } if (ent != NULL) { *ent = entry; } return VMCI_SUCCESS; } /* *----------------------------------------------------------------------------- * * VMCIQPBroker_SetPageStore -- * * VMX'en with versions lower than VMCI_VERSION_NOVMVM use a separate * step to add the UVAs of the VMX mapping of the queue pair. This function * provides backwards compatibility with such VMX'en, and takes care of * registering the page store for a queue pair previously allocated by the * VMX during create or attach. This function will move the queue pair state * to either from VMCIQBP_CREATED_NO_MEM to VMCIQBP_CREATED_MEM or * VMCIQBP_ATTACHED_NO_MEM to VMCIQBP_ATTACHED_MEM. If moving to the * attached state with memory, the queue pair is ready to be used by the * host peer, and an attached event will be generated. * * Assumes that the queue pair broker lock is held. * * This function is only used by the hosted platform, since there is no * issue with backwards compatibility for vmkernel. * * Results: * VMCI_SUCCESS on success, appropriate error code otherwise. * * Side effects: * Pages may get pinned. * *----------------------------------------------------------------------------- */ int VMCIQPBroker_SetPageStore(VMCIHandle handle, // IN VA64 produceUVA, // IN VA64 consumeUVA, // IN VMCIContext *context) // IN: Caller { QPBrokerEntry *entry; int result; const VMCIId contextId = VMCIContext_GetId(context); unsigned int index; if (VMCI_HANDLE_INVALID(handle) || !context || contextId == VMCI_INVALID_ID) { return VMCI_ERROR_INVALID_ARGS; } /* * We only support guest to host queue pairs, so the VMX must * supply UVAs for the mapped page files. */ if (produceUVA == 0 || consumeUVA == 0) { return VMCI_ERROR_INVALID_ARGS; } VMCIQPBrokerLock(); if (!VMCIContext_QueuePairExists(context, handle)) { VMCI_WARNING((LGPFX"Context (ID=0x%x) not attached to queue pair " "(handle=0x%x:0x%x).\n", contextId, handle.context, handle.resource)); result = VMCI_ERROR_NOT_FOUND; goto out; } entry = (QPBrokerEntry *)QueuePairList_FindEntry(&qpBrokerList, handle); if (!entry) { result = VMCI_ERROR_NOT_FOUND; goto out; } /* * If I'm the owner then I can set the page store. * * Or, if a host created the QueuePair and I'm the attached peer * then I can set the page store. */ if (entry->createId != contextId && (entry->createId != VMCI_HOST_CONTEXT_ID || entry->attachId != contextId)) { result = VMCI_ERROR_QUEUEPAIR_NOTOWNER; goto out; } index = VMCIQPBEGetIndex(entry, contextId); if (entry->hasMem[index] || (entry->stateQP != VMCIQPB_CREATED && entry->stateQP == VMCIQPB_ATTACHED)) { result = VMCI_ERROR_UNAVAILABLE; goto out; } result = VMCIHost_GetUserMemory(index, produceUVA, consumeUVA, entry->produceQ, entry->consumeQ); if (result < VMCI_SUCCESS) { goto out; } VMCIHost_MarkQueuesAvailable(index, entry->produceQ, entry->consumeQ); result = VMCIHost_MapQueues(index, entry->produceQ, entry->consumeQ, 0); if (result < VMCI_SUCCESS) { VMCIHost_ReleaseUserMemory(index, entry->produceQ, entry->consumeQ); goto out; } entry->hasMem[index] = TRUE; entry->vmciPageFiles = TRUE; if (entry->stateQP == VMCIQPB_ATTACHED && entry->hasMem[0] && (!entry->isVM2VM || entry->hasMem[1])) { result = QueuePairNotifyPeer(TRUE, handle, contextId, entry->createId); if (result < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to notify peer (ID=0x%x) of attach to queue " "pair (handle=0x%x:0x%x).\n", entry->createId, entry->qp.handle.context, entry->qp.handle.resource)); } } result = VMCI_SUCCESS; out: VMCIQPBrokerUnlock(); return result; } /* *----------------------------------------------------------------------------- * * VMCIQPBroker_Detach -- * * The main entry point for detaching from a queue pair registered with the * queue pair broker. If more than one endpoint is attached to the queue * pair, the first endpoint will mainly decrement a reference count and * generate a notification to its peer. The last endpoint will clean up * the queue pair state registered with the broker. * * When a guest endpoint detaches, it will unmap and unregister the guest * memory backing the queue pair. If the host is still attached, it will * no longer be able to access the queue pair content. * * If the queue pair is already in a state where there is no memory * registered for the queue pair (any *_NO_MEM state), it will transition to * the VMCIQPB_SHUTDOWN_NO_MEM state. This will also happen, if a guest * endpoint is the first of two endpoints to detach. If the host endpoint is * the first out of two to detach, the queue pair will move to the * VMCIQPB_SHUTDOWN_MEM state. * * Results: * VMCI_SUCCESS on success, appropriate error code otherwise. * * Side effects: * Memory may be freed, and pages may be unpinned. * *----------------------------------------------------------------------------- */ int VMCIQPBroker_Detach(VMCIHandle handle, // IN VMCIContext *context) // IN { QPBrokerEntry *entry; const VMCIId contextId = VMCIContext_GetId(context); VMCIId peerId; Bool isLocal = FALSE; int result; unsigned int index; if (VMCI_HANDLE_INVALID(handle) || !context || contextId == VMCI_INVALID_ID) { return VMCI_ERROR_INVALID_ARGS; } VMCIQPBrokerLock(); if (!VMCIContext_QueuePairExists(context, handle)) { VMCI_DEBUG_LOG(4, (LGPFX"Context (ID=0x%x) not attached to queue pair " "(handle=0x%x:0x%x).\n", contextId, handle.context, handle.resource)); result = VMCI_ERROR_NOT_FOUND; goto out; } entry = (QPBrokerEntry *)QueuePairList_FindEntry(&qpBrokerList, handle); if (!entry) { VMCI_DEBUG_LOG(4, (LGPFX"Context (ID=0x%x) reports being attached to queue pair " "(handle=0x%x:0x%x) that isn't present in broker.\n", contextId, handle.context, handle.resource)); result = VMCI_ERROR_NOT_FOUND; goto out; } if (contextId != entry->createId && contextId != entry->attachId) { result = VMCI_ERROR_QUEUEPAIR_NOTATTACHED; goto out; } index = VMCIQPBEGetIndex(entry, contextId); if (contextId == entry->createId) { peerId = entry->attachId; entry->createId = VMCI_INVALID_ID; } else { peerId = entry->createId; entry->attachId = VMCI_INVALID_ID; } entry->qp.refCount--; isLocal = entry->qp.flags & VMCI_QPFLAG_LOCAL; if (contextId != VMCI_HOST_CONTEXT_ID) { int result; Bool headersMapped; ASSERT(!isLocal); /* * Pre NOVMVM vmx'en may detach from a queue pair before setting the page * store, and in that case there is no user memory to detach from. Also, * more recent VMX'en may detach from a queue pair in the quiesced state. */ VMCI_AcquireQueueMutex(entry->produceQ, TRUE); headersMapped = entry->produceQ->qHeader || entry->consumeQ->qHeader; if (entry->hasMem[index]) { VMCIHost_MarkQueuesUnavailable(index, entry->produceQ, entry->consumeQ); result = VMCIHost_UnmapQueues(index, INVALID_VMCI_GUEST_MEM_ID, entry->produceQ, entry->consumeQ); if (result < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to unmap queue headers for queue pair " "(handle=0x%x:0x%x,result=%d).\n", handle.context, handle.resource, result)); } if (entry->vmciPageFiles) { VMCIHost_ReleaseUserMemory(index, entry->produceQ, entry->consumeQ); } else { VMCIHost_UnregisterUserMemory(index, entry->produceQ, entry->consumeQ); } entry->hasMem[index] = FALSE; } if (!headersMapped) { QueuePairResetSavedHeaders(entry); } if (index == 1) { entry->isVM2VM = FALSE; } VMCI_ReleaseQueueMutex(entry->produceQ); if (!headersMapped && entry->wakeupCB) { entry->wakeupCB(entry->clientData); } } else { if (entry->wakeupCB) { entry->wakeupCB = NULL; entry->clientData = NULL; } } if (entry->qp.refCount == 0) { QueuePairList_RemoveEntry(&qpBrokerList, &entry->qp); if (isLocal) { VMCI_FreeKernelMem(entry->localMem, QPE_NUM_PAGES(entry->qp) * PAGE_SIZE); entry->hasMem[0] = FALSE; } ASSERT(entry->hasMem[0] == FALSE); ASSERT(entry->hasMem[1] == FALSE); VMCI_CleanupQueueMutex(entry->produceQ, entry->consumeQ); VMCIHost_FreeQueue(entry->produceQ, entry->qp.produceSize); VMCIHost_FreeQueue(entry->consumeQ, entry->qp.consumeSize); VMCI_FreeKernelMem(entry, sizeof *entry); VMCIContext_QueuePairDestroy(context, handle); } else { ASSERT(peerId != VMCI_INVALID_ID); QueuePairNotifyPeer(FALSE, handle, contextId, peerId); entry->stateQP = VMCIQPB_SHUTDOWN; if (!isLocal) { VMCIContext_QueuePairDestroy(context, handle); } } result = VMCI_SUCCESS; out: VMCIQPBrokerUnlock(); return result; } /* *----------------------------------------------------------------------------- * * VMCIQPBroker_Map -- * * Establishes the necessary mappings for a queue pair given a * reference to the queue pair guest memory. This is usually * called when a guest is unquiesced and the VMX is allowed to * map guest memory once again. * * Results: * VMCI_SUCCESS on success, appropriate error code otherwise. * * Side effects: * Memory may be allocated, and pages may be pinned. * *----------------------------------------------------------------------------- */ int VMCIQPBroker_Map(VMCIHandle handle, // IN VMCIContext *context, // IN VMCIQPGuestMem guestMem) // IN { QPBrokerEntry *entry; const VMCIId contextId = VMCIContext_GetId(context); Bool isLocal = FALSE; int result; unsigned int endpoint; unsigned int index; if (VMCI_HANDLE_INVALID(handle) || !context || contextId == VMCI_INVALID_ID) { return VMCI_ERROR_INVALID_ARGS; } VMCIQPBrokerLock(); if (!VMCIContext_QueuePairExists(context, handle)) { VMCI_DEBUG_LOG(4, (LGPFX"Context (ID=0x%x) not attached to queue pair " "(handle=0x%x:0x%x).\n", contextId, handle.context, handle.resource)); result = VMCI_ERROR_NOT_FOUND; goto out; } entry = (QPBrokerEntry *)QueuePairList_FindEntry(&qpBrokerList, handle); if (!entry) { VMCI_DEBUG_LOG(4, (LGPFX"Context (ID=0x%x) reports being attached to queue pair " "(handle=0x%x:0x%x) that isn't present in broker.\n", contextId, handle.context, handle.resource)); result = VMCI_ERROR_NOT_FOUND; goto out; } if (contextId != entry->createId && contextId != entry->attachId) { result = VMCI_ERROR_QUEUEPAIR_NOTATTACHED; goto out; } index = VMCIQPBEGetIndex(entry, contextId); endpoint = contextId == entry->createId ? 0 : 1; isLocal = entry->qp.flags & VMCI_QPFLAG_LOCAL; if (vmkernel) { /* * On vmkernel, the readiness of the queue pair can be signalled * immediately since the guest memory is already registered. */ VMCI_AcquireQueueMutex(entry->produceQ, TRUE); VMCIHost_MarkQueuesAvailable(index, entry->produceQ, entry->consumeQ); if (entry->qp.flags & VMCI_QPFLAG_NONBLOCK) { result = VMCIHost_MapQueues(index, entry->produceQ, entry->consumeQ, entry->qp.flags); } else { result = VMCI_SUCCESS; } if (result == VMCI_SUCCESS) { QueuePairResetSavedHeaders(entry); } VMCI_ReleaseQueueMutex(entry->produceQ); if (result == VMCI_SUCCESS) { if (entry->wakeupCB) { entry->wakeupCB(entry->clientData); } } } else if (contextId != VMCI_HOST_CONTEXT_ID) { QueuePairPageStore pageStore; ASSERT((entry->stateQP == VMCIQPB_CREATED || entry->stateQP == VMCIQPB_SHUTDOWN || entry->stateQP == VMCIQPB_ATTACHED) && !entry->hasMem[0]); ASSERT(!isLocal); pageStore.pages = guestMem; pageStore.len = QPE_NUM_PAGES(entry->qp); VMCI_AcquireQueueMutex(entry->produceQ, TRUE); QueuePairResetSavedHeaders(entry); result = VMCIHost_RegisterUserMemory(index, &pageStore, entry->produceQ, entry->consumeQ); VMCIHost_MarkQueuesAvailable(index, entry->produceQ, entry->consumeQ); VMCI_ReleaseQueueMutex(entry->produceQ); if (result == VMCI_SUCCESS) { entry->hasMem[index] = TRUE; if (entry->wakeupCB) { entry->wakeupCB(entry->clientData); } } } else { result = VMCI_SUCCESS; } out: VMCIQPBrokerUnlock(); return result; } /* *----------------------------------------------------------------------------- * * QueuePairSaveHeaders -- * * Saves a snapshot of the queue headers for the given QP broker * entry. Should be used when guest memory is unmapped. * * Results: * VMCI_SUCCESS on success, appropriate error code if guest memory * can't be accessed.. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int QueuePairSaveHeaders(QPBrokerEntry *entry, // IN VMCIId contextId) // IN { int result; if (entry->produceQ->savedHeader != NULL && entry->consumeQ->savedHeader != NULL) { /* * If the headers have already been saved, we don't need to do * it again, and we don't want to map in the headers * unnecessarily. */ return VMCI_SUCCESS; } if (NULL == entry->produceQ->qHeader || NULL == entry->consumeQ->qHeader) { unsigned int index; /* * If this is second VM, do not save headers: qHeader is for VM which * created queue pair only. And no API which uses savedHeader should * be used together with VM2VM queue pair anyway. */ index = VMCIQPBEGetIndex(entry, contextId); if (index != 0) { return VMCI_SUCCESS; } result = VMCIHost_MapQueues(index, entry->produceQ, entry->consumeQ, 0); if (result < VMCI_SUCCESS) { return result; } } memcpy(&entry->savedProduceQ, entry->produceQ->qHeader, sizeof entry->savedProduceQ); entry->produceQ->savedHeader = &entry->savedProduceQ; memcpy(&entry->savedConsumeQ, entry->consumeQ->qHeader, sizeof entry->savedConsumeQ); entry->consumeQ->savedHeader = &entry->savedConsumeQ; return VMCI_SUCCESS; } /* *----------------------------------------------------------------------------- * * QueuePairResetSavedHeaders -- * * Resets saved queue headers for the given QP broker * entry. Should be used when guest memory becomes available * again, or the guest detaches. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void QueuePairResetSavedHeaders(QPBrokerEntry *entry) // IN { if (vmkernel) { VMCI_LockQueueHeader(entry->produceQ); } entry->produceQ->savedHeader = NULL; entry->consumeQ->savedHeader = NULL; if (vmkernel) { VMCI_UnlockQueueHeader(entry->produceQ); } } /* *----------------------------------------------------------------------------- * * VMCIQPBroker_Unmap -- * * Removes all references to the guest memory of a given queue pair, and * will move the queue pair from state *_MEM to *_NO_MEM. It is usually * called when a VM is being quiesced where access to guest memory should * avoided. * * Results: * VMCI_SUCCESS on success, appropriate error code otherwise. * * Side effects: * Memory may be freed, and pages may be unpinned. * *----------------------------------------------------------------------------- */ int VMCIQPBroker_Unmap(VMCIHandle handle, // IN VMCIContext *context, // IN VMCIGuestMemID gid) // IN { QPBrokerEntry *entry; const VMCIId contextId = VMCIContext_GetId(context); Bool isLocal = FALSE; int result; unsigned int index; if (VMCI_HANDLE_INVALID(handle) || !context || contextId == VMCI_INVALID_ID) { return VMCI_ERROR_INVALID_ARGS; } VMCIQPBrokerLock(); if (!VMCIContext_QueuePairExists(context, handle)) { VMCI_DEBUG_LOG(4, (LGPFX"Context (ID=0x%x) not attached to queue pair " "(handle=0x%x:0x%x).\n", contextId, handle.context, handle.resource)); result = VMCI_ERROR_NOT_FOUND; goto out; } entry = (QPBrokerEntry *)QueuePairList_FindEntry(&qpBrokerList, handle); if (!entry) { VMCI_DEBUG_LOG(4, (LGPFX"Context (ID=0x%x) reports being attached to queue pair " "(handle=0x%x:0x%x) that isn't present in broker.\n", contextId, handle.context, handle.resource)); result = VMCI_ERROR_NOT_FOUND; goto out; } if (contextId != entry->createId && contextId != entry->attachId) { result = VMCI_ERROR_QUEUEPAIR_NOTATTACHED; goto out; } index = VMCIQPBEGetIndex(entry, contextId); isLocal = entry->qp.flags & VMCI_QPFLAG_LOCAL; if (contextId != VMCI_HOST_CONTEXT_ID) { ASSERT(entry->hasMem[index]); ASSERT(!isLocal); VMCI_AcquireQueueMutex(entry->produceQ, TRUE); result = QueuePairSaveHeaders(entry, contextId); if (result < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to save queue headers for queue pair " "(handle=0x%x:0x%x,result=%d).\n", handle.context, handle.resource, result)); } VMCIHost_MarkQueuesUnavailable(index, entry->produceQ, entry->consumeQ); VMCIHost_UnmapQueues(index, gid, entry->produceQ, entry->consumeQ); if (!vmkernel) { /* * On hosted, when we unmap queue pairs, the VMX will also * unmap the guest memory, so we invalidate the previously * registered memory. If the queue pair is mapped again at a * later point in time, we will need to reregister the user * memory with a possibly new user VA. */ VMCIHost_UnregisterUserMemory(index, entry->produceQ, entry->consumeQ); entry->hasMem[index] = FALSE; } VMCI_ReleaseQueueMutex(entry->produceQ); } result = VMCI_SUCCESS; out: VMCIQPBrokerUnlock(); return result; } #if !defined(VMKERNEL) /* *----------------------------------------------------------------------------- * * VMCIQPGuestEndpoints_Init -- * * Initalizes data structure state keeping track of queue pair * guest endpoints. * * Results: * VMCI_SUCCESS on success and appropriate failure code otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int VMCIQPGuestEndpoints_Init(void) { int err; err = QueuePairList_Init(&qpGuestEndpoints); if (err < VMCI_SUCCESS) { return err; } hibernateFailedList = VMCIHandleArray_Create(0); if (NULL == hibernateFailedList) { QueuePairList_Destroy(&qpGuestEndpoints); return VMCI_ERROR_NO_MEM; } /* * The lock rank must be lower than subscriberLock in vmciEvent, * since we hold the hibernateFailedListLock while generating * detach events. */ err = VMCI_InitLock(&hibernateFailedListLock, "VMCIQPHibernateFailed", VMCI_LOCK_RANK_QPHIBERNATE); if (err < VMCI_SUCCESS) { VMCIHandleArray_Destroy(hibernateFailedList); hibernateFailedList = NULL; QueuePairList_Destroy(&qpGuestEndpoints); } return err; } /* *----------------------------------------------------------------------------- * * VMCIQPGuestEndpoints_Exit -- * * Destroys all guest queue pair endpoints. If active guest queue * pairs still exist, hypercalls to attempt detach from these * queue pairs will be made. Any failure to detach is silently * ignored. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMCIQPGuestEndpoints_Exit(void) { QPGuestEndpoint *entry; VMCIMutex_Acquire(&qpGuestEndpoints.mutex); while ((entry = (QPGuestEndpoint *)QueuePairList_GetHead(&qpGuestEndpoints))) { /* * Don't make a hypercall for local QueuePairs. */ if (!(entry->qp.flags & VMCI_QPFLAG_LOCAL)) { VMCIQueuePairDetachHypercall(entry->qp.handle); } /* * We cannot fail the exit, so let's reset refCount. */ entry->qp.refCount = 0; QueuePairList_RemoveEntry(&qpGuestEndpoints, &entry->qp); QPGuestEndpointDestroy(entry); } Atomic_Write(&qpGuestEndpoints.hibernate, 0); VMCIMutex_Release(&qpGuestEndpoints.mutex); QueuePairList_Destroy(&qpGuestEndpoints); VMCI_CleanupLock(&hibernateFailedListLock); VMCIHandleArray_Destroy(hibernateFailedList); } /* *----------------------------------------------------------------------------- * * VMCIQPGuestEndpoints_Sync -- * * Use this as a synchronization point when setting globals, for example, * during device shutdown. * * Results: * TRUE. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMCIQPGuestEndpoints_Sync(void) { VMCIMutex_Acquire(&qpGuestEndpoints.mutex); VMCIMutex_Release(&qpGuestEndpoints.mutex); } /* *----------------------------------------------------------------------------- * * QPGuestEndpointCreate -- * * Allocates and initializes a QPGuestEndpoint structure. * Allocates a QueuePair rid (and handle) iff the given entry has * an invalid handle. 0 through VMCI_RESERVED_RESOURCE_ID_MAX * are reserved handles. Assumes that the QP list mutex is held * by the caller. * * Results: * Pointer to structure intialized. * * Side effects: * None. * *----------------------------------------------------------------------------- */ QPGuestEndpoint * QPGuestEndpointCreate(VMCIHandle handle, // IN VMCIId peer, // IN uint32 flags, // IN uint64 produceSize, // IN uint64 consumeSize, // IN void *produceQ, // IN void *consumeQ) // IN { static VMCIId queuePairRID = VMCI_RESERVED_RESOURCE_ID_MAX + 1; QPGuestEndpoint *entry; const uint64 numPPNs = CEILING(produceSize, PAGE_SIZE) + CEILING(consumeSize, PAGE_SIZE) + 2; /* One page each for the queue headers. */ ASSERT((produceSize || consumeSize) && produceQ && consumeQ); if (VMCI_HANDLE_INVALID(handle)) { VMCIId contextID = vmci_get_context_id(); VMCIId oldRID = queuePairRID; /* * Generate a unique QueuePair rid. Keep on trying until we wrap around * in the RID space. */ ASSERT(oldRID > VMCI_RESERVED_RESOURCE_ID_MAX); do { handle = VMCI_MAKE_HANDLE(contextID, queuePairRID); entry = (QPGuestEndpoint *)QueuePairList_FindEntry(&qpGuestEndpoints, handle); queuePairRID++; if (UNLIKELY(!queuePairRID)) { /* * Skip the reserved rids. */ queuePairRID = VMCI_RESERVED_RESOURCE_ID_MAX + 1; } } while (entry && queuePairRID != oldRID); if (UNLIKELY(entry != NULL)) { ASSERT(queuePairRID == oldRID); /* * We wrapped around --- no rids were free. */ return NULL; } } ASSERT(!VMCI_HANDLE_INVALID(handle) && QueuePairList_FindEntry(&qpGuestEndpoints, handle) == NULL); entry = VMCI_AllocKernelMem(sizeof *entry, VMCI_MEMORY_NORMAL); if (entry) { entry->qp.handle = handle; entry->qp.peer = peer; entry->qp.flags = flags; entry->qp.produceSize = produceSize; entry->qp.consumeSize = consumeSize; entry->qp.refCount = 0; entry->numPPNs = numPPNs; memset(&entry->ppnSet, 0, sizeof entry->ppnSet); entry->produceQ = produceQ; entry->consumeQ = consumeQ; VMCIList_InitEntry(&entry->qp.listItem); } return entry; } /* *----------------------------------------------------------------------------- * * QPGuestEndpointDestroy -- * * Frees a QPGuestEndpoint structure. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void QPGuestEndpointDestroy(QPGuestEndpoint *entry) // IN { ASSERT(entry); ASSERT(entry->qp.refCount == 0); VMCI_FreePPNSet(&entry->ppnSet); VMCI_CleanupQueueMutex(entry->produceQ, entry->consumeQ); VMCI_FreeQueue(entry->produceQ, entry->qp.produceSize); VMCI_FreeQueue(entry->consumeQ, entry->qp.consumeSize); VMCI_FreeKernelMem(entry, sizeof *entry); } /* *----------------------------------------------------------------------------- * * VMCIQueuePairAllocHypercall -- * * Helper to make a QueuePairAlloc hypercall when the driver is * supporting a guest device. * * Results: * Result of the hypercall. * * Side effects: * Memory is allocated & freed. * *----------------------------------------------------------------------------- */ static int VMCIQueuePairAllocHypercall(const QPGuestEndpoint *entry) // IN { VMCIQueuePairAllocMsg *allocMsg; size_t msgSize; int result; if (!entry || entry->numPPNs <= 2) { return VMCI_ERROR_INVALID_ARGS; } ASSERT(!(entry->qp.flags & VMCI_QPFLAG_LOCAL)); msgSize = sizeof *allocMsg + (size_t)entry->numPPNs * sizeof(PPN); allocMsg = VMCI_AllocKernelMem(msgSize, VMCI_MEMORY_NONPAGED); if (!allocMsg) { return VMCI_ERROR_NO_MEM; } allocMsg->hdr.dst = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_QUEUEPAIR_ALLOC); allocMsg->hdr.src = VMCI_ANON_SRC_HANDLE; allocMsg->hdr.payloadSize = msgSize - VMCI_DG_HEADERSIZE; allocMsg->handle = entry->qp.handle; allocMsg->peer = entry->qp.peer; allocMsg->flags = entry->qp.flags; allocMsg->produceSize = entry->qp.produceSize; allocMsg->consumeSize = entry->qp.consumeSize; allocMsg->numPPNs = entry->numPPNs; result = VMCI_PopulatePPNList((uint8 *)allocMsg + sizeof *allocMsg, &entry->ppnSet); if (result == VMCI_SUCCESS) { result = VMCI_SendDatagram((VMCIDatagram *)allocMsg); } VMCI_FreeKernelMem(allocMsg, msgSize); return result; } /* *----------------------------------------------------------------------------- * * VMCIQueuePairAllocGuestWork -- * * This functions handles the actual allocation of a VMCI queue * pair guest endpoint. Allocates physical pages for the queue * pair. It makes OS dependent calls through generic wrappers. * * Results: * Success or failure. * * Side effects: * Memory is allocated. * *----------------------------------------------------------------------------- */ static int VMCIQueuePairAllocGuestWork(VMCIHandle *handle, // IN/OUT VMCIQueue **produceQ, // OUT uint64 produceSize, // IN VMCIQueue **consumeQ, // OUT uint64 consumeSize, // IN VMCIId peer, // IN uint32 flags, // IN VMCIPrivilegeFlags privFlags) // IN { const uint64 numProducePages = CEILING(produceSize, PAGE_SIZE) + 1; const uint64 numConsumePages = CEILING(consumeSize, PAGE_SIZE) + 1; void *myProduceQ = NULL; void *myConsumeQ = NULL; int result; QPGuestEndpoint *queuePairEntry = NULL; /* * XXX Check for possible overflow of 'size' arguments when passed to * compat_get_order (after some arithmetic ops). */ ASSERT(handle && produceQ && consumeQ && (produceSize || consumeSize)); if (privFlags != VMCI_NO_PRIVILEGE_FLAGS) { return VMCI_ERROR_NO_ACCESS; } VMCIMutex_Acquire(&qpGuestEndpoints.mutex); /* Check if creation/attachment of a queuepair is allowed. */ if (!VMCI_CanCreate()) { result = VMCI_ERROR_UNAVAILABLE; goto error; } if ((Atomic_Read(&qpGuestEndpoints.hibernate) == 1) && !(flags & VMCI_QPFLAG_LOCAL)) { /* * While guest OS is in hibernate state, creating non-local * queue pairs is not allowed after the point where the VMCI * guest driver converted the existing queue pairs to local * ones. */ result = VMCI_ERROR_UNAVAILABLE; goto error; } if ((queuePairEntry = (QPGuestEndpoint *) QueuePairList_FindEntry(&qpGuestEndpoints, *handle))) { if (queuePairEntry->qp.flags & VMCI_QPFLAG_LOCAL) { /* Local attach case. */ if (queuePairEntry->qp.refCount > 1) { VMCI_DEBUG_LOG(4, (LGPFX"Error attempting to attach more than " "once.\n")); result = VMCI_ERROR_UNAVAILABLE; goto errorKeepEntry; } if (queuePairEntry->qp.produceSize != consumeSize || queuePairEntry->qp.consumeSize != produceSize || queuePairEntry->qp.flags != (flags & ~VMCI_QPFLAG_ATTACH_ONLY)) { VMCI_DEBUG_LOG(4, (LGPFX"Error mismatched queue pair in local " "attach.\n")); result = VMCI_ERROR_QUEUEPAIR_MISMATCH; goto errorKeepEntry; } /* * Do a local attach. We swap the consume and produce queues for the * attacher and deliver an attach event. */ result = QueuePairNotifyPeerLocal(TRUE, *handle); if (result < VMCI_SUCCESS) { goto errorKeepEntry; } myProduceQ = queuePairEntry->consumeQ; myConsumeQ = queuePairEntry->produceQ; goto out; } result = VMCI_ERROR_ALREADY_EXISTS; goto errorKeepEntry; } myProduceQ = VMCI_AllocQueue(produceSize, flags); if (!myProduceQ) { VMCI_WARNING((LGPFX"Error allocating pages for produce queue.\n")); result = VMCI_ERROR_NO_MEM; goto error; } myConsumeQ = VMCI_AllocQueue(consumeSize, flags); if (!myConsumeQ) { VMCI_WARNING((LGPFX"Error allocating pages for consume queue.\n")); result = VMCI_ERROR_NO_MEM; goto error; } queuePairEntry = QPGuestEndpointCreate(*handle, peer, flags, produceSize, consumeSize, myProduceQ, myConsumeQ); if (!queuePairEntry) { VMCI_WARNING((LGPFX"Error allocating memory in %s.\n", __FUNCTION__)); result = VMCI_ERROR_NO_MEM; goto error; } result = VMCI_AllocPPNSet(myProduceQ, numProducePages, myConsumeQ, numConsumePages, &queuePairEntry->ppnSet); if (result < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"VMCI_AllocPPNSet failed.\n")); goto error; } /* * It's only necessary to notify the host if this queue pair will be * attached to from another context. */ if (queuePairEntry->qp.flags & VMCI_QPFLAG_LOCAL) { /* Local create case. */ VMCIId contextId = vmci_get_context_id(); /* * Enforce similar checks on local queue pairs as we do for regular ones. * The handle's context must match the creator or attacher context id * (here they are both the current context id) and the attach-only flag * cannot exist during create. We also ensure specified peer is this * context or an invalid one. */ if (queuePairEntry->qp.handle.context != contextId || (queuePairEntry->qp.peer != VMCI_INVALID_ID && queuePairEntry->qp.peer != contextId)) { result = VMCI_ERROR_NO_ACCESS; goto error; } if (queuePairEntry->qp.flags & VMCI_QPFLAG_ATTACH_ONLY) { result = VMCI_ERROR_NOT_FOUND; goto error; } } else { result = VMCIQueuePairAllocHypercall(queuePairEntry); if (result < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"VMCIQueuePairAllocHypercall result = %d.\n", result)); goto error; } } VMCI_InitQueueMutex((VMCIQueue *)myProduceQ, (VMCIQueue *)myConsumeQ); QueuePairList_AddEntry(&qpGuestEndpoints, &queuePairEntry->qp); out: queuePairEntry->qp.refCount++; *handle = queuePairEntry->qp.handle; *produceQ = (VMCIQueue *)myProduceQ; *consumeQ = (VMCIQueue *)myConsumeQ; /* * We should initialize the queue pair header pages on a local queue pair * create. For non-local queue pairs, the hypervisor initializes the header * pages in the create step. */ if ((queuePairEntry->qp.flags & VMCI_QPFLAG_LOCAL) && queuePairEntry->qp.refCount == 1) { VMCIQueueHeader_Init((*produceQ)->qHeader, *handle); VMCIQueueHeader_Init((*consumeQ)->qHeader, *handle); } VMCIMutex_Release(&qpGuestEndpoints.mutex); return VMCI_SUCCESS; error: VMCIMutex_Release(&qpGuestEndpoints.mutex); if (queuePairEntry) { /* The queues will be freed inside the destroy routine. */ QPGuestEndpointDestroy(queuePairEntry); } else { if (myProduceQ) { VMCI_FreeQueue(myProduceQ, produceSize); } if (myConsumeQ) { VMCI_FreeQueue(myConsumeQ, consumeSize); } } return result; errorKeepEntry: /* This path should only be used when an existing entry was found. */ ASSERT(queuePairEntry->qp.refCount > 0); VMCIMutex_Release(&qpGuestEndpoints.mutex); return result; } /* *----------------------------------------------------------------------------- * * VMCIQueuePairDetachHypercall -- * * Helper to make a QueuePairDetach hypercall when the driver is * supporting a guest device. * * Results: * Result of the hypercall. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int VMCIQueuePairDetachHypercall(VMCIHandle handle) // IN { VMCIQueuePairDetachMsg detachMsg; detachMsg.hdr.dst = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_QUEUEPAIR_DETACH); detachMsg.hdr.src = VMCI_ANON_SRC_HANDLE; detachMsg.hdr.payloadSize = sizeof handle; detachMsg.handle = handle; return VMCI_SendDatagram((VMCIDatagram *)&detachMsg); } /* *----------------------------------------------------------------------------- * * VMCIQueuePairDetachGuestWork -- * * Helper for VMCI QueuePair detach interface. Frees the physical * pages for the queue pair. * * Results: * Success or failure. * * Side effects: * Memory may be freed. * *----------------------------------------------------------------------------- */ static int VMCIQueuePairDetachGuestWork(VMCIHandle handle) // IN { int result; QPGuestEndpoint *entry; uint32 refCount; ASSERT(!VMCI_HANDLE_INVALID(handle)); VMCIMutex_Acquire(&qpGuestEndpoints.mutex); entry = (QPGuestEndpoint *)QueuePairList_FindEntry(&qpGuestEndpoints, handle); if (!entry) { VMCIMutex_Release(&qpGuestEndpoints.mutex); return VMCI_ERROR_NOT_FOUND; } ASSERT(entry->qp.refCount >= 1); if (entry->qp.flags & VMCI_QPFLAG_LOCAL) { result = VMCI_SUCCESS; if (entry->qp.refCount > 1) { result = QueuePairNotifyPeerLocal(FALSE, handle); /* * We can fail to notify a local queuepair because we can't allocate. * We still want to release the entry if that happens, so don't bail * out yet. */ } } else { result = VMCIQueuePairDetachHypercall(handle); if (entry->hibernateFailure) { if (result == VMCI_ERROR_NOT_FOUND) { /* * If a queue pair detach failed when entering * hibernation, the guest driver and the device may * disagree on its existence when coming out of * hibernation. The guest driver will regard it as a * non-local queue pair, but the device state is gone, * since the device has been powered off. In this case, we * treat the queue pair as a local queue pair with no * peer. */ ASSERT(entry->qp.refCount == 1); result = VMCI_SUCCESS; } if (result == VMCI_SUCCESS) { VMCIQPUnmarkHibernateFailed(entry); } } if (result < VMCI_SUCCESS) { /* * We failed to notify a non-local queuepair. That other queuepair * might still be accessing the shared memory, so don't release the * entry yet. It will get cleaned up by VMCIQueuePair_Exit() * if necessary (assuming we are going away, otherwise why did this * fail?). */ VMCIMutex_Release(&qpGuestEndpoints.mutex); return result; } } /* * If we get here then we either failed to notify a local queuepair, or * we succeeded in all cases. Release the entry if required. */ entry->qp.refCount--; if (entry->qp.refCount == 0) { QueuePairList_RemoveEntry(&qpGuestEndpoints, &entry->qp); } /* If we didn't remove the entry, this could change once we unlock. */ refCount = entry ? entry->qp.refCount : 0xffffffff; /* * Value does not matter, silence the * compiler. */ VMCIMutex_Release(&qpGuestEndpoints.mutex); if (refCount == 0) { QPGuestEndpointDestroy(entry); } return result; } /* *---------------------------------------------------------------------------- * * QueuePairNotifyPeerLocal -- * * Dispatches a queue pair event message directly into the local event * queue. * * Results: * VMCI_SUCCESS on success, error code otherwise * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int QueuePairNotifyPeerLocal(Bool attach, // IN: attach or detach? VMCIHandle handle) // IN: queue pair handle { VMCIEventMsg *eMsg; VMCIEventPayload_QP *ePayload; /* buf is only 48 bytes. */ char buf[sizeof *eMsg + sizeof *ePayload]; VMCIId contextId = vmci_get_context_id(); eMsg = (VMCIEventMsg *)buf; ePayload = VMCIEventMsgPayload(eMsg); eMsg->hdr.dst = VMCI_MAKE_HANDLE(contextId, VMCI_EVENT_HANDLER); eMsg->hdr.src = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_CONTEXT_RESOURCE_ID); eMsg->hdr.payloadSize = sizeof *eMsg + sizeof *ePayload - sizeof eMsg->hdr; eMsg->eventData.event = attach ? VMCI_EVENT_QP_PEER_ATTACH : VMCI_EVENT_QP_PEER_DETACH; ePayload->peerId = contextId; ePayload->handle = handle; return VMCIEvent_Dispatch((VMCIDatagram *)eMsg); } /* *----------------------------------------------------------------------------- * * VMCIQPMarkHibernateFailed -- * * Helper function that marks a queue pair entry as not being * converted to a local version during hibernation. Must be * called with the queue pair list mutex held. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VMCIQPMarkHibernateFailed(QPGuestEndpoint *entry) // IN { VMCILockFlags flags; VMCIHandle handle; /* * entry->handle is located in paged memory, so it can't be * accessed while holding a spinlock. */ handle = entry->qp.handle; entry->hibernateFailure = TRUE; VMCI_GrabLock_BH(&hibernateFailedListLock, &flags); VMCIHandleArray_AppendEntry(&hibernateFailedList, handle); VMCI_ReleaseLock_BH(&hibernateFailedListLock, flags); } /* *----------------------------------------------------------------------------- * * VMCIQPUnmarkHibernateFailed -- * * Helper function that removes a queue pair entry from the group * of handles marked as having failed hibernation. Must be called * with the queue pair list lock held. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VMCIQPUnmarkHibernateFailed(QPGuestEndpoint *entry) // IN { VMCILockFlags flags; VMCIHandle handle; /* * entry->handle is located in paged memory, so it can't be * accessed while holding a spinlock. */ handle = entry->qp.handle; entry->hibernateFailure = FALSE; VMCI_GrabLock_BH(&hibernateFailedListLock, &flags); VMCIHandleArray_RemoveEntry(hibernateFailedList, handle); VMCI_ReleaseLock_BH(&hibernateFailedListLock, flags); } /* *---------------------------------------------------------------------------- * * VMCIQPGuestEndpoints_Convert -- * * Guest queue pair endpoints may be converted to local ones in * two cases: when entering hibernation or when the device is * powered off before entering a sleep mode. Below we first * discuss the case of hibernation and then the case of entering * sleep state. * * When the guest enters hibernation, any non-local queue pairs * will disconnect no later than at the time the VMCI device * powers off. To preserve the content of the non-local queue * pairs for this guest, we make a local copy of the content and * disconnect from the queue pairs. This will ensure that the * peer doesn't continue to update the queue pair state while the * guest OS is checkpointing the memory (otherwise we might end * up with a inconsistent snapshot where the pointers of the * consume queue are checkpointed later than the data pages they * point to, possibly indicating that non-valid data is * valid). While we are in hibernation mode, we block the * allocation of new non-local queue pairs. Note that while we * are doing the conversion to local queue pairs, we are holding * the queue pair list lock, which will prevent concurrent * creation of additional non-local queue pairs. * * The hibernation cannot fail, so if we are unable to either * save the queue pair state or detach from a queue pair, we deal * with it by keeping the queue pair around, and converting it to * a local queue pair when going out of hibernation. Since * failing a detach is highly unlikely (it would require a queue * pair being actively used as part of a DMA operation), this is * an acceptable fall back. Once we come back from hibernation, * these queue pairs will no longer be external, so we simply * mark them as local at that point. * * For the sleep state, the VMCI device will also be put into the * D3 power state, which may make the device inaccessible to the * guest driver (Windows unmaps the I/O space). When entering * sleep state, the hypervisor is likely to suspend the guest as * well, which will again convert all queue pairs to local ones. * However, VMCI device clients, e.g., VMCI Sockets, may attempt * to use queue pairs after the device has been put into the D3 * power state, so we convert the queue pairs to local ones in * that case as well. When exiting the sleep states, the device * has not been reset, so all device state is still in sync with * the device driver, so no further processing is necessary at * that point. * * Results: * None. * * Side effects: * Queue pairs are detached. * *---------------------------------------------------------------------------- */ void VMCIQPGuestEndpoints_Convert(Bool toLocal, // IN Bool deviceReset) // IN { if (toLocal) { VMCIListItem *next; VMCIMutex_Acquire(&qpGuestEndpoints.mutex); VMCIList_Scan(next, &qpGuestEndpoints.head) { QPGuestEndpoint *entry = (QPGuestEndpoint *)VMCIList_Entry( next, QueuePairEntry, listItem); if (!(entry->qp.flags & VMCI_QPFLAG_LOCAL)) { UNUSED_PARAM(VMCIQueue *prodQ); // Only used on Win32 UNUSED_PARAM(VMCIQueue *consQ); // Only used on Win32 void *oldProdQ; UNUSED_PARAM(void *oldConsQ); // Only used on Win32 int result; prodQ = (VMCIQueue *)entry->produceQ; consQ = (VMCIQueue *)entry->consumeQ; oldConsQ = oldProdQ = NULL; VMCI_AcquireQueueMutex(prodQ, TRUE); result = VMCI_ConvertToLocalQueue(consQ, prodQ, entry->qp.consumeSize, TRUE, &oldConsQ); if (result != VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Hibernate failed to create local consume " "queue from handle %x:%x (error: %d)\n", entry->qp.handle.context, entry->qp.handle.resource, result)); VMCI_ReleaseQueueMutex(prodQ); VMCIQPMarkHibernateFailed(entry); continue; } result = VMCI_ConvertToLocalQueue(prodQ, consQ, entry->qp.produceSize, FALSE, &oldProdQ); if (result != VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Hibernate failed to create local produce " "queue from handle %x:%x (error: %d)\n", entry->qp.handle.context, entry->qp.handle.resource, result)); VMCI_RevertToNonLocalQueue(consQ, oldConsQ, entry->qp.consumeSize); VMCI_ReleaseQueueMutex(prodQ); VMCIQPMarkHibernateFailed(entry); continue; } /* * Now that the contents of the queue pair has been saved, * we can detach from the non-local queue pair. This will * discard the content of the non-local queues. */ result = VMCIQueuePairDetachHypercall(entry->qp.handle); if (result < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Hibernate failed to detach from handle " "%x:%x\n", entry->qp.handle.context, entry->qp.handle.resource)); VMCI_RevertToNonLocalQueue(consQ, oldConsQ, entry->qp.consumeSize); VMCI_RevertToNonLocalQueue(prodQ, oldProdQ, entry->qp.produceSize); VMCI_ReleaseQueueMutex(prodQ); VMCIQPMarkHibernateFailed(entry); continue; } entry->qp.flags |= VMCI_QPFLAG_LOCAL; VMCI_ReleaseQueueMutex(prodQ); VMCI_FreeQueueBuffer(oldProdQ, entry->qp.produceSize); VMCI_FreeQueueBuffer(oldConsQ, entry->qp.consumeSize); QueuePairNotifyPeerLocal(FALSE, entry->qp.handle); } } Atomic_Write(&qpGuestEndpoints.hibernate, 1); VMCIMutex_Release(&qpGuestEndpoints.mutex); } else { VMCILockFlags flags; VMCIHandle handle; /* * When a guest enters hibernation, there may be queue pairs * around, that couldn't be converted to local queue * pairs. When coming out of hibernation, these queue pairs * will be restored as part of the guest main mem by the OS * hibernation code and they can now be regarded as local * versions. Since they are no longer connected, detach * notifications are sent to the local endpoint. */ VMCI_GrabLock_BH(&hibernateFailedListLock, &flags); while (VMCIHandleArray_GetSize(hibernateFailedList) > 0) { handle = VMCIHandleArray_RemoveTail(hibernateFailedList); if (deviceReset) { QueuePairNotifyPeerLocal(FALSE, handle); } } VMCI_ReleaseLock_BH(&hibernateFailedListLock, flags); Atomic_Write(&qpGuestEndpoints.hibernate, 0); } } #endif /* !VMKERNEL */ open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciDoorbell.h0000644765153500003110000000304112220061556023264 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciDoorbell.h -- * * Internal functions in the VMCI Doorbell API. */ #ifndef VMCI_DOORBELL_H #define VMCI_DOORBELL_H #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vmci_kernel_if.h" #include "vmci_defs.h" int VMCIDoorbell_Init(void); void VMCIDoorbell_Exit(void); void VMCIDoorbell_Hibernate(Bool enterHibernation); void VMCIDoorbell_Sync(void); int VMCIDoorbellHostContextNotify(VMCIId srcCID, VMCIHandle handle); int VMCIDoorbellGetPrivFlags(VMCIHandle handle, VMCIPrivilegeFlags *privFlags); Bool VMCI_RegisterNotificationBitmap(PPN bitmapPPN); void VMCI_ScanNotificationBitmap(uint8 *bitmap); #endif // VMCI_DOORBELL_H open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciPageChannel.c0000644765153500003110000014170712220061556023676 0ustar dtormts/********************************************************* * Copyright (C) 2011 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciPacket.c -- * * Implementation of vPageChannel for guest kernels. */ #include "vmci_kernel_if.h" #include "vm_assert.h" #include "vmci_defs.h" #include "vmci_page_channel.h" #include "vmciDriver.h" #include "vmciKernelAPI.h" #if !defined(linux) || defined(VMKERNEL) #error "Wrong platform." #endif // !linux || VMKERNEL #define LGPFX "vPageChannel: " /* * This threshold is to account for packets being in-flight. We can't keep * an accurate count of receive buffers, it's just an estimate, so we allow * some slack. */ #define VMCI_PACKET_RECV_THRESHOLD 150 /* * Maximum number of elements per DGRAM packet (for setting receive buffers). */ #define VMCI_PACKET_DGRAM_MAX_ELEMS \ ((VMCI_MAX_DG_PAYLOAD_SIZE - sizeof(VPageChannelPacket)) / \ sizeof(VPageChannelElem)) /* * Maximum number of elements in a PAGE-sized packet (as above). */ #define VMCI_PACKET_PAGE_MAX_ELEMS \ ((PAGE_SIZE - sizeof(VPageChannelPacket)) / \ sizeof(VPageChannelElem)) /* * All flags. We use this to check the validity of the flags, so put it here * instead of in the header, otherwise people might assume we mean for them * to use it. */ #define VPAGECHANNEL_FLAGS_ALL \ (VPAGECHANNEL_FLAGS_NOTIFY_ONLY | \ VPAGECHANNEL_FLAGS_RECV_DELAYED | \ VPAGECHANNEL_FLAGS_SEND_WHILE_ATOMIC) /* * Page channel. This is opaque to clients. */ struct VPageChannel { VPageChannelState state; VMCIHandle dgHandle; uint32 flags; VPageChannelRecvCB recvCB; void *clientRecvData; VPageChannelAllocElemFn elemAllocFn; void *allocClientData; VPageChannelFreeElemFn elemFreeFn; void *freeClientData; /* * QueuePair info. */ VMCIQPair *qpair; VMCIHandle qpHandle; uint64 produceQSize; uint64 consumeQSize; VMCIId attachSubId; VMCIId detachSubId; Bool useSpinLock; spinlock_t qpRecvLock; spinlock_t qpSendLock; struct semaphore qpRecvMutex; struct semaphore qpSendMutex; /* * Doorbell info. */ VMCIHandle doorbellHandle; VMCIHandle peerDoorbellHandle; /* * Receiving buffer. */ Atomic_Int curRecvBufs; int recvBufsTarget; int defaultRecvBufs; int maxRecvBufs; VMCIId resourceId; VMCIHandle peerDgHandle; Bool inPoll; }; static int VPageChannelSendControl(VPageChannel *channel, VPageChannelPacketType type, char *message, int len, int numElems, VPageChannelElem *elems); static int VPageChannelSignal(VPageChannel *channel); static int VPageChannelSendPacket(VPageChannel *channel, VPageChannelPacket *packet, Bool needsLock, Bool signalPending); /* *----------------------------------------------------------------------------- * * VPageChannelAcquireSendLock * * Acquire the channel's send lock. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VPageChannelAcquireSendLock(VPageChannel *channel, // IN unsigned long *flags) // OUT { ASSERT(channel); *flags = 0; /* Make compiler happy about it being unused in some paths. */ if (channel->useSpinLock) { spin_lock_irqsave(&channel->qpSendLock, *flags); } else { down(&channel->qpSendMutex); } } /* *----------------------------------------------------------------------------- * * VPageChannelReleaseSendLock * * Release the channel's send lock. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VPageChannelReleaseSendLock(VPageChannel *channel, // IN unsigned long flags) // IN { ASSERT(channel); if (channel->useSpinLock) { spin_unlock_irqrestore(&channel->qpSendLock, flags); } else { up(&channel->qpSendMutex); } } /* *----------------------------------------------------------------------------- * * VPageChannelAcquireRecvLock * * Acquire the channel's receive lock. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VPageChannelAcquireRecvLock(VPageChannel *channel, // IN unsigned long *flags) // OUT { ASSERT(channel); ASSERT(flags); *flags = 0; /* Make compiler happy about it being unused in some paths. */ if (channel->useSpinLock) { spin_lock_irqsave(&channel->qpRecvLock, *flags); } else { down(&channel->qpRecvMutex); } } /* *----------------------------------------------------------------------------- * * VPageChannelReleaseRecvLock * * Release the channel's receive lock. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VPageChannelReleaseRecvLock(VPageChannel *channel, // IN unsigned long flags) // IN { ASSERT(channel); if (channel->useSpinLock) { spin_unlock_irqrestore(&channel->qpRecvLock, flags); } else { up(&channel->qpRecvMutex); } } /* *----------------------------------------------------------------------------- * * VPageChannelAddRecvBuffers -- * * Add receiving buffers for the channel. This will ask the client to * to allocate the required elements and then pass those to the peer. * * If "onInit" is TRUE (which is is during channel initialization) then * the DGRAM control channel will be used, and multiple packets will be * sent if necessary. Also, the packet allocation will be blocking. * * If "onInit" is FALSE, then the queuepair will be used, multiple * packets may be sent, and the packet allocation may be atomic, * depending on how the channel is configured. * * Results: * The number of buffers actually sent to the peer. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int VPageChannelAddRecvBuffers(VPageChannel *channel, // IN int numElems, // IN Bool onInit) // IN { int n; int sent; int maxElems; Bool isAtomic; size_t size; unsigned long flags; VPageChannelElem *elems; VPageChannelPacket *packet; ASSERT(channel); sent = 0; size = 0; elems = NULL; packet = NULL; if (onInit || (channel->flags & VPAGECHANNEL_FLAGS_RECV_DELAYED)) { /* * If we are initializing the channel, or we are running in a delayed * context (recv() in this case), then we can using blocking allocation * and we can allocate large packets. Also, no need to take the * send lock here, we can just take it for each packet. */ isAtomic = FALSE; maxElems = VMCI_PACKET_DGRAM_MAX_ELEMS; flags = 0; /* Silence compiler. */ } else { /* * We're in an atomic context. We must allocate page-sized packets * atomically and send them over the queuepair. Since this can * cause a lot of signalling, we optimize by taking the send lock * once for all packets, and only signalling when we are done. */ isAtomic = TRUE; maxElems = VMCI_PACKET_PAGE_MAX_ELEMS; VPageChannelAcquireSendLock(channel, &flags); } n = min_t(int, maxElems, numElems); while (n > 0) { int retval; int allocNum; /* * First packet is always big enough to cover any remaining elements, * so just allocate it once. */ if (NULL == packet) { size = sizeof(VPageChannelPacket) + (n * sizeof(VPageChannelElem)); packet = (VPageChannelPacket *) VMCI_AllocKernelMem(size, isAtomic ? VMCI_MEMORY_ATOMIC : VMCI_MEMORY_NORMAL); if (packet == NULL) { VMCI_WARNING((LGPFX"Failed to allocate packet (channel=%p) " "(size=%"FMTSZ"u).\n", channel, size)); goto exit; } packet->type = VPCPacket_SetRecvBuffer; packet->msgLen = 0; elems = VPAGECHANNEL_PACKET_ELEMS(packet); } allocNum = channel->elemAllocFn(channel->allocClientData, elems, n); if (0 == allocNum) { /* * If the client failed to allocate any elements at all then just * bail out and return whatever number we managed to send so far * (if any). */ VMCI_WARNING((LGPFX"Failed to allocate receive buffer (channel=%p) " "(expected=%d).\n", channel, n)); goto exit; } /* * We wanted "n" elements, but we might only have "allocNum" because * that's all the client could allocate. Pass down whatever we got. */ packet->numElems = allocNum; if (onInit) { retval = VPageChannelSendControl(channel, VPCPacket_SetRecvBuffer, NULL, 0, allocNum, elems); } else { /* * Do not ask for the lock here if we are atomic, we take care of * that ourselves. Similarly, if we are atomic then we will do our * own signalling, so inform the send that there is a signal already * pending. */ retval = VPageChannelSendPacket(channel, packet, isAtomic ? FALSE : TRUE, // needsLock isAtomic ? TRUE : FALSE); // signalPending /* * XXX, what if this is a non-blocking queuepair and we fail to * send because it's full and we can't wait? Is it even worth it * to loop? */ } if (retval < VMCI_SUCCESS) { /* * Failure to send is fatal. Release the client's elements and * bail out. */ VMCI_WARNING((LGPFX"Failed to set receive buffers (channel=%p) " "(err=%d).\n", channel, retval)); channel->elemFreeFn(channel->freeClientData, elems, allocNum); goto exit; } Atomic_Add32(&channel->curRecvBufs, allocNum); sent += allocNum; numElems -= allocNum; n = min_t(int, maxElems, numElems); } exit: if (isAtomic) { /* * We're done sending packets, so now we can signal. Even if we only * sent some of the requested buffers, we must signal anyway, otherwise * the peer won't know about the ones we did send. */ (void)VPageChannelSignal(channel); VPageChannelReleaseSendLock(channel, flags); } if (NULL != packet) { VMCI_FreeKernelMem(packet, size); } return sent; } /* *----------------------------------------------------------------------------- * * VPageChannelRecvPacket -- * * Process a VMCI packet. * * Results: * Always VMCI_SUCCESS. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int VPageChannelRecvPacket(VPageChannel *channel, // IN VPageChannelPacket *packet) // IN { int curRecvBufs; int recvBufsTarget; ASSERT(channel); ASSERT(packet); if (packet->type != VPCPacket_Data && packet->type != VPCPacket_Completion_Notify && packet->type != VPCPacket_RequestBuffer && packet->type != VPCPacket_HyperConnect && packet->type != VPCPacket_HyperDisconnect) { VMCI_WARNING((LGPFX"Received invalid packet (channel=%p) " "(type=%d).\n", channel, packet->type)); return VMCI_ERROR_INVALID_ARGS; } VMCI_DEBUG_LOG(10, (LGPFX"Received packet (channel=%p) (type=%d) " "(elems=%d).\n", channel, packet->type, packet->numElems)); if (packet->type == VPCPacket_HyperConnect) { VPageChannelHyperConnectMessage *message; if (packet->msgLen < sizeof *message) { VMCI_WARNING((LGPFX"Received invalid hypervisor connection message " "(channel=%p) (size=%u).\n", channel, packet->msgLen)); return VMCI_ERROR_INVALID_ARGS; } message = (VPageChannelHyperConnectMessage *) VPAGECHANNEL_PACKET_MESSAGE(packet); channel->peerDoorbellHandle = message->doorbellHandle; VMCI_DEBUG_LOG(10, (LGPFX"Connected to peer (channel=%p) " "(db handle=0x%x:0x%x).\n", channel, channel->peerDoorbellHandle.context, channel->peerDoorbellHandle.resource)); return VMCI_SUCCESS; } recvBufsTarget = channel->recvBufsTarget; switch (packet->type) { case VPCPacket_RequestBuffer: /* * Increase the number of receive buffers by channel->defaultRecvBufs * if the hypervisor requests it. */ VMCI_DEBUG_LOG(10, (LGPFX"Requested more buffers (channel=%p) " "(cur=%d) (target=%d) (max=%d).\n", channel, Atomic_Read32(&channel->curRecvBufs), channel->recvBufsTarget, channel->maxRecvBufs)); if (channel->recvBufsTarget < channel->maxRecvBufs) { recvBufsTarget = channel->recvBufsTarget + channel->defaultRecvBufs; } break; case VPCPacket_Data: channel->recvCB(channel->clientRecvData, packet); Atomic_Sub32(&channel->curRecvBufs, packet->numElems); ASSERT(Atomic_Read32(&channel->curRecvBufs) > 0); break; case VPCPacket_Completion_Notify: channel->recvCB(channel->clientRecvData, packet); break; case VPCPacket_HyperDisconnect: VMCI_DEBUG_LOG(10, (LGPFX"Hypervisor requested disconnection " "(channel=%p) (numElems=%d).\n", channel, packet->numElems)); if (packet->numElems > 0) { channel->elemFreeFn(channel->freeClientData, VPAGECHANNEL_PACKET_ELEMS(packet), packet->numElems); } (void)VPageChannelSendControl(channel, VPCPacket_GuestDisconnect, NULL, 0, 0, NULL); if (channel->state < VPCState_Disconnecting) { channel->state = VPCState_Disconnecting; } return VMCI_SUCCESS; default: ASSERT_NOT_IMPLEMENTED(FALSE); break; } /* * Set more receive buffers if it is below the threshold. We bump it up * here even when not requested to do so. This is to account for buffers * being in-flight, i.e., in packets that have not yet been processed by * the other side. When we increase here, we also tack on extra threshold, * in the hope that we won't hit this again. */ curRecvBufs = Atomic_Read32(&channel->curRecvBufs); if (curRecvBufs < (recvBufsTarget - VMCI_PACKET_RECV_THRESHOLD)) { int numElems = recvBufsTarget + VMCI_PACKET_RECV_THRESHOLD - curRecvBufs; (void)VPageChannelAddRecvBuffers(channel, numElems, FALSE); channel->recvBufsTarget = recvBufsTarget; } return VMCI_SUCCESS; } /* *----------------------------------------------------------------------------- * * VPageChannelDgRecvFunc -- * * Callback function to receive a VMCI packet. This is only used until * the connection is made; after that, packets are received over the * queuepair. * * Results: * VMCI_SUCCESS on success, negative values on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int VPageChannelDgRecvFunc(void *clientData, // IN VMCIDatagram *dg) // IN { VPageChannel *channel = (VPageChannel *)clientData; ASSERT(channel); ASSERT(dg); if (dg->src.context != VMCI_HOST_CONTEXT_ID || dg->src.resource != channel->peerDgHandle.resource) { VMCI_WARNING((LGPFX"Received a packet from an unknown source " "(channel=%p) (handle=0x%x:0x%x).\n", channel, dg->src.context, dg->src.resource)); return VMCI_ERROR_NO_ACCESS; } if (dg->payloadSize < sizeof (VPageChannelPacket)) { VMCI_WARNING((LGPFX"Received invalid packet (channel=%p) " "(size=%"FMT64"u).\n", channel, dg->payloadSize)); return VMCI_ERROR_INVALID_ARGS; } return VPageChannelRecvPacket(channel, VMCI_DG_PAYLOAD(dg)); } /* *---------------------------------------------------------------------------- * * VPageChannelDoDoorbellCallback * * Process a doorbell notification. Will read packets from the queuepair * until empty. * * XXX, this function is now identical to the one with the same name in * modules/vmkernel/vmci/vmciPacketVMK.c. We should share this code. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VPageChannelDoDoorbellCallback(VPageChannel *channel) // IN/OUT { Bool inUse; unsigned long flags; VPageChannelPacket packetHeader; ASSERT(channel); if (VPCState_Connected != channel->state) { VMCI_WARNING((LGPFX"Not connected (channel=%p).\n", channel)); return; } VPageChannelAcquireRecvLock(channel, &flags); inUse = channel->inPoll; channel->inPoll = TRUE; VPageChannelReleaseRecvLock(channel, flags); if (inUse) { return; } retry: while (vmci_qpair_consume_buf_ready(channel->qpair) >= sizeof packetHeader) { ssize_t retSize, totalSize; VPageChannelPacket *packet; retSize = vmci_qpair_peek(channel->qpair, &packetHeader, sizeof packetHeader, /* XXX, UTIL_VMKERNEL_BUFFER for VMKernel. */ 0); if (retSize < sizeof packetHeader) { /* * XXX, deal with partial read. */ VMCI_WARNING((LGPFX"Failed to peek (channel=%p) " "(required=%"FMTSZ"d) (err=%"FMTSZ"d).\n", channel, sizeof packetHeader, retSize)); break; } totalSize = sizeof packetHeader + packetHeader.msgLen + packetHeader.numElems * sizeof(VPageChannelElem); retSize = vmci_qpair_consume_buf_ready(channel->qpair); if (retSize < totalSize) { /* * XXX, deal with partial read. */ VMCI_WARNING((LGPFX"Received partial packet (channel=%p) " "(type=%d) (len=%d) (num elems=%d) (avail=%"FMTSZ"d) " "(requested=%"FMTSZ"d).\n", channel, packetHeader.type, packetHeader.msgLen, packetHeader.numElems, retSize, totalSize)); break; } packet = (VPageChannelPacket *) VMCI_AllocKernelMem(totalSize, VMCI_MEMORY_ATOMIC); if (!packet) { VMCI_WARNING((LGPFX"Failed to allocate packet (channel=%p) " "(size=%"FMTSZ"d).\n", channel, totalSize)); break; } retSize = vmci_qpair_dequeue(channel->qpair, packet, totalSize, /* XXX, UTIL_VMKERNEL_BUFFER for VMKernel. */ 0); if (retSize < totalSize) { /* * XXX, deal with partial read. */ VMCI_WARNING((LGPFX"Failed to dequeue (channel=%p) " "(required=%"FMTSZ"d) (err=%"FMTSZ"d).\n", channel, totalSize, retSize)); VMCI_FreeKernelMem(packet, totalSize); break; } VPageChannelRecvPacket(channel, packet); VMCI_FreeKernelMem(packet, totalSize); } VPageChannelAcquireRecvLock(channel, &flags); /* * The doorbell may have been notified between when we we finished reading * data and when we grabbed the lock. If that happens, then there may be * data, but we bailed out of that second notification because inPoll was * already set. So that we don't miss anything, do a final check here under * the lock for any data that might have arrived. */ if (vmci_qpair_consume_buf_ready(channel->qpair) >= sizeof packetHeader) { VPageChannelReleaseRecvLock(channel, flags); goto retry; } channel->inPoll = FALSE; VPageChannelReleaseRecvLock(channel, flags); } /* *---------------------------------------------------------------------------- * * VPageChannelDoorbellCallback -- * * Callback for doorbell notification. Will invoke the channel's receive * function directly or process the packets in the queuepair. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VPageChannelDoorbellCallback(void *clientData) // IN/OUT { VPageChannel *channel = (VPageChannel *)clientData; ASSERT(channel); if (channel->flags & VPAGECHANNEL_FLAGS_NOTIFY_ONLY) { channel->recvCB(channel->clientRecvData, NULL); } else { VPageChannelDoDoorbellCallback(channel); } } /* *---------------------------------------------------------------------------- * * VPageChannelSendConnectionMessage -- * * Send a connection control message to the hypervisor. * * Results: * VMCI_SUCCESS if sent, negative values on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VPageChannelSendConnectionMessage(VPageChannel *channel) // IN { VPageChannelGuestConnectMessage message; ASSERT(channel); channel->state = VPCState_Connecting; memset(&message, 0, sizeof message); message.dgHandle = channel->dgHandle; message.qpHandle = channel->qpHandle; message.produceQSize = channel->produceQSize; message.consumeQSize = channel->consumeQSize; message.doorbellHandle = channel->doorbellHandle; VMCI_DEBUG_LOG(10, (LGPFX"Sending guest connect (channel=%p) " "(qp handle=0x%x:0x%x).\n", channel, channel->qpHandle.context, channel->qpHandle.resource)); return VPageChannelSendControl(channel, VPCPacket_GuestConnect, (char *)&message, sizeof message, 0, NULL); } /* *---------------------------------------------------------------------------- * * VPageChannelPeerAttachCB -- * * Invoked when a peer attaches to a queue pair. * * Results: * None. * * Side effects: * May modify page channel state. * *---------------------------------------------------------------------------- */ static void VPageChannelPeerAttachCB(VMCIId subId, // IN VMCI_EventData *eData, // IN void *clientData) // IN { VPageChannel *channel; VMCIEventPayload_QP *ePayload; ASSERT(eData); ASSERT(clientData); channel = (VPageChannel *)clientData; ePayload = VMCIEventDataPayload(eData); if (VMCI_HANDLE_EQUAL(channel->qpHandle, ePayload->handle)) { VMCI_DEBUG_LOG(10, (LGPFX"Peer attached (channel=%p) " "(qp handle=0x%x:0x%x).\n", channel, ePayload->handle.context, ePayload->handle.resource)); channel->state = VPCState_Connected; } } /* *---------------------------------------------------------------------------- * * VPageChannelPeerDetachCB -- * * Invoked when a peer detaches from a queue pair. * * Results: * None. * * Side effects: * May modify page channel state. * *---------------------------------------------------------------------------- */ static void VPageChannelPeerDetachCB(VMCIId subId, // IN VMCI_EventData *eData, // IN void *clientData) // IN { VPageChannel *channel; VMCIEventPayload_QP *ePayload; ASSERT(eData); ASSERT(clientData); channel = (VPageChannel *)clientData; ePayload = VMCIEventDataPayload(eData); if (VMCI_HANDLE_EQUAL(channel->qpHandle, ePayload->handle)) { VMCI_DEBUG_LOG(10, (LGPFX"Peer detached (channel=%p) " "(qp handle=0x%x:0x%x).\n", channel, ePayload->handle.context, ePayload->handle.resource)); channel->state = VPCState_Disconnected; } } /* *---------------------------------------------------------------------------- * * VPageChannelDestroyQueuePair -- * * Destroy the channel's queuepair, along with the event subscriptions. * * Results: * None. * * Side effects: * May modify page channel state. * *---------------------------------------------------------------------------- */ static void VPageChannelDestroyQueuePair(VPageChannel *channel) // IN/OUT { ASSERT(channel); if (channel->attachSubId != VMCI_INVALID_ID) { vmci_event_unsubscribe(channel->attachSubId); channel->attachSubId = VMCI_INVALID_ID; } if (channel->detachSubId != VMCI_INVALID_ID) { vmci_event_unsubscribe(channel->detachSubId); channel->detachSubId = VMCI_INVALID_ID; } if (!VMCI_HANDLE_INVALID(channel->qpHandle)) { ASSERT(channel->qpair); vmci_qpair_detach(&channel->qpair); channel->qpHandle = VMCI_INVALID_HANDLE; channel->qpair = NULL; } channel->state = VPCState_Disconnected; } /* *---------------------------------------------------------------------------- * * VPageChannelCreateQueuePair -- * * Create queuepair for data communication. * * Results: * VMCI_SUCCESS if the queuepair is created, negative values on failure. * * Side effects: * May modify page channel state. * *---------------------------------------------------------------------------- */ static int VPageChannelCreateQueuePair(VPageChannel *channel) // IN/OUT { int err; uint32 flags; ASSERT(channel); ASSERT(VMCI_HANDLE_INVALID(channel->qpHandle)); ASSERT(NULL == channel->qpair); ASSERT(VMCI_INVALID_ID == channel->detachSubId); ASSERT(VMCI_INVALID_ID == channel->attachSubId); if (channel->flags & VPAGECHANNEL_FLAGS_SEND_WHILE_ATOMIC || !(channel->flags & VPAGECHANNEL_FLAGS_RECV_DELAYED)) { channel->useSpinLock = TRUE; spin_lock_init(&channel->qpSendLock); spin_lock_init(&channel->qpRecvLock); } else { sema_init(&channel->qpSendMutex, 1); sema_init(&channel->qpRecvMutex, 1); } err = vmci_event_subscribe(VMCI_EVENT_QP_PEER_ATTACH, #if !defined(linux) || defined(VMKERNEL) VMCI_FLAG_EVENT_NONE, #endif // !linux || VMKERNEL VPageChannelPeerAttachCB, channel, &channel->attachSubId); if (err < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to subscribe to attach event " "(channel=%p) (err=%d).\n", channel, err)); goto error; } err = vmci_event_subscribe(VMCI_EVENT_QP_PEER_DETACH, #if !defined(linux) || defined(VMKERNEL) VMCI_FLAG_EVENT_NONE, #endif // !linux || VMKERNEL VPageChannelPeerDetachCB, channel, &channel->detachSubId); if (err < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to subscribe to detach event " "(channel=%p) (err=%d).\n", channel, err)); goto error; } if (channel->useSpinLock) { flags = VMCI_QPFLAG_NONBLOCK | VMCI_QPFLAG_PINNED; } else { flags = 0; } err = vmci_qpair_alloc(&channel->qpair, &channel->qpHandle, channel->produceQSize, channel->consumeQSize, VMCI_HOST_CONTEXT_ID, flags, VMCI_NO_PRIVILEGE_FLAGS); if (err < 0) { VMCI_WARNING((LGPFX"Could not create queue pair (err=%d).\n", err)); goto error; } VMCI_DEBUG_LOG(10, (LGPFX"Allocated queuepair (channel=%p) " "(qp handle=0x%x:0x%x) " "(produce=%"FMT64"u) (consume=%"FMT64"u).\n", channel, channel->qpHandle.context, channel->qpHandle.resource, channel->produceQSize, channel->consumeQSize)); return VMCI_SUCCESS; error: VPageChannelDestroyQueuePair(channel); return err; } /* *----------------------------------------------------------------------------- * * VPageChannel_CreateInVM -- * * Create a page channel in the guest kernel. * * Results: * VMCI_SUCCESS if created, negative errno value otherwise. * * Side effects: * May set the receive buffers if a default size is given. * *----------------------------------------------------------------------------- */ int VPageChannel_CreateInVM(VPageChannel **channel, // IN/OUT VMCIId resourceId, // IN VMCIId peerResourceId, // IN uint64 produceQSize, // IN uint64 consumeQSize, // IN uint32 channelFlags, // IN VPageChannelRecvCB recvCB, // IN void *clientRecvData, // IN VPageChannelAllocElemFn elemAllocFn, // IN void *allocClientData, // IN VPageChannelFreeElemFn elemFreeFn, // IN void *freeClientData, // IN int defaultRecvBuffers, // IN int maxRecvBuffers) // IN { int retval; int flags; VPageChannel *pageChannel; ASSERT(channel); ASSERT(VMCI_INVALID_ID != resourceId); ASSERT(VMCI_INVALID_ID != peerResourceId); ASSERT(recvCB); if (channelFlags & ~(VPAGECHANNEL_FLAGS_ALL)) { VMCI_WARNING((LGPFX"Invalid argument (flags=0x%x).\n", channelFlags)); return VMCI_ERROR_INVALID_ARGS; } pageChannel = VMCI_AllocKernelMem(sizeof *pageChannel, VMCI_MEMORY_NONPAGED); if (!pageChannel) { VMCI_WARNING((LGPFX"Failed to allocate channel memory.\n")); return VMCI_ERROR_NO_MEM; } /* * XXX, we should support a default internal allocation function. */ memset(pageChannel, 0, sizeof *pageChannel); pageChannel->state = VPCState_Unconnected; pageChannel->dgHandle = VMCI_INVALID_HANDLE; pageChannel->attachSubId = VMCI_INVALID_ID; pageChannel->detachSubId = VMCI_INVALID_ID; pageChannel->qpHandle = VMCI_INVALID_HANDLE; pageChannel->qpair = NULL; pageChannel->doorbellHandle = VMCI_INVALID_HANDLE; pageChannel->peerDoorbellHandle = VMCI_INVALID_HANDLE; pageChannel->flags = channelFlags; pageChannel->recvCB = recvCB; pageChannel->clientRecvData = clientRecvData; pageChannel->elemAllocFn = elemAllocFn; pageChannel->allocClientData = allocClientData; pageChannel->elemFreeFn = elemFreeFn; pageChannel->freeClientData = freeClientData; pageChannel->resourceId = resourceId; pageChannel->peerDgHandle = VMCI_MAKE_HANDLE(VMCI_HOST_CONTEXT_ID, peerResourceId); Atomic_Write32(&pageChannel->curRecvBufs, 0); pageChannel->recvBufsTarget = defaultRecvBuffers; pageChannel->defaultRecvBufs = defaultRecvBuffers; pageChannel->maxRecvBufs = maxRecvBuffers + VMCI_PACKET_RECV_THRESHOLD; pageChannel->produceQSize = produceQSize; pageChannel->consumeQSize = consumeQSize; /* * Create a datagram handle over which we will connection handshake packets * (once the queuepair is created we can send packets over that instead). * This handle has a delayed callback regardless of the channel flags, * because we may have to create a queuepair inside the callback. */ flags = VMCI_FLAG_DG_DELAYED_CB; retval = vmci_datagram_create_handle(resourceId, flags, VPageChannelDgRecvFunc, pageChannel, &pageChannel->dgHandle); if (retval < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to create datagram handle " "(channel=%p) (err=%d).\n", channel, retval)); goto error; } VMCI_DEBUG_LOG(10, (LGPFX"Created datagram (channel=%p) " "(handle=0x%x:0x%x).\n", channel, pageChannel->dgHandle.context, pageChannel->dgHandle.resource)); /* * Create a doorbell handle. This is used by the peer to signal the * arrival of packets in the queuepair. This handle has a delayed * callback depending on the channel flags. */ flags = channelFlags & VPAGECHANNEL_FLAGS_RECV_DELAYED ? VMCI_FLAG_DELAYED_CB : 0; retval = vmci_doorbell_create(&pageChannel->doorbellHandle, flags, VMCI_PRIVILEGE_FLAG_RESTRICTED, VPageChannelDoorbellCallback, pageChannel); if (retval < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to create doorbell " "(channel=%p) (err=%d).\n", channel, retval)); goto error; } VMCI_DEBUG_LOG(10, (LGPFX"Created doorbell (channel=%p) " "(handle=0x%x:0x%x).\n", channel, pageChannel->doorbellHandle.context, pageChannel->doorbellHandle.resource)); /* * Now create the queuepair, over which we can pass data packets. */ retval = VPageChannelCreateQueuePair(pageChannel); if (retval < VMCI_SUCCESS) { goto error; } /* * Set the receiving buffers before sending the connection message to * avoid a race when the connection is made, but there is no receiving * buffer yet. */ if (defaultRecvBuffers) { int numElems = defaultRecvBuffers + VMCI_PACKET_RECV_THRESHOLD; if (0 == VPageChannelAddRecvBuffers(pageChannel, numElems, TRUE)) { /* * AddRecvBuffers() returns the number of buffers actually added. If * we failed to add any at all, then fail. */ retval = VMCI_ERROR_NO_MEM; goto error; } } retval = VPageChannelSendConnectionMessage(pageChannel); if (retval < VMCI_SUCCESS) { goto error; } VMCI_DEBUG_LOG(10, (LGPFX"Created (channel=%p) (handle=0x%x:0x%x).\n", pageChannel, pageChannel->dgHandle.context, pageChannel->dgHandle.resource)); *channel = pageChannel; return retval; error: VPageChannel_Destroy(pageChannel); return retval; } EXPORT_SYMBOL(VPageChannel_CreateInVM); /* *----------------------------------------------------------------------------- * * VPageChannel_Destroy -- * * Destroy the page channel. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VPageChannel_Destroy(VPageChannel *channel) // IN/OUT { ASSERT(channel); VPageChannelDestroyQueuePair(channel); if (!VMCI_HANDLE_INVALID(channel->doorbellHandle)) { vmci_doorbell_destroy(channel->doorbellHandle); } if (!VMCI_HANDLE_INVALID(channel->dgHandle)) { vmci_datagram_destroy_handle(channel->dgHandle); } channel->state = VPCState_Free; VMCI_FreeKernelMem(channel, sizeof *channel); VMCI_DEBUG_LOG(10, (LGPFX"Destroyed (channel=%p).\n", channel)); } EXPORT_SYMBOL(VPageChannel_Destroy); /* *----------------------------------------------------------------------------- * * VPageChannelAllocDatagram -- * * Allocate a datagram for the packet. This is only used until the * connection is made; after that, packets are passed over the queuepair. * * XXX, this function is now identical to the one of the same name in * modules/vmkernel/vmci/vmciPacketVMK.c. We should share this code. * * Results: * VMCI_SUCCESS and a datagram if successfully allocated, negative error * value on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int VPageChannelAllocDatagram(VPageChannel *channel, // IN size_t messageLen, // IN int numElems, // IN VMCIDatagram **outDg) // OUT { size_t size; VMCIDatagram *dg; ASSERT(channel); ASSERT(outDg); *outDg = NULL; size = VMCI_DG_HEADERSIZE + sizeof(VPageChannelPacket) + messageLen + numElems * sizeof (VPageChannelElem); if (size > VMCI_MAX_DG_SIZE) { VMCI_WARNING((LGPFX"Requested datagram size too large (channel=%p) " "(size=%"FMTSZ"u).", channel, size)); return VMCI_ERROR_PAYLOAD_TOO_LARGE; } dg = VMCI_AllocKernelMem(size, VMCI_MEMORY_ATOMIC); if (!dg) { VMCI_WARNING((LGPFX"Failed to allocate datagram (channel=%p).", channel)); return VMCI_ERROR_NO_MEM; } memset(dg, 0, size); dg->dst = channel->peerDgHandle; dg->src = channel->dgHandle; dg->payloadSize = size - VMCI_DG_HEADERSIZE; /* Chatty. */ // VMCI_DEBUG_LOG(10, // (LGPFX"Allocated datagram (payload=%"FMT64"u).\n", // dg->payloadSize)); *outDg = dg; return VMCI_SUCCESS; } /* *----------------------------------------------------------------------------- * * VPageChannelSendControl -- * * A packet is constructed to send the message and buffer to the guest * via the control channel (datagram). This is only necessary until the * queuepair is connected. * * Results: * VMCI_SUCCESS if the packet is sent successfully, negative error number * otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int VPageChannelSendControl(VPageChannel *channel, // IN VPageChannelPacketType type, // IN char *message, // IN int len, // IN int numElems, // IN VPageChannelElem *elems) // IN { int retval; VPageChannelPacket *packet; VMCIDatagram *dg; ASSERT(channel); ASSERT(type == VPCPacket_Data || type == VPCPacket_GuestConnect || type == VPCPacket_SetRecvBuffer || type == VPCPacket_GuestDisconnect); dg = NULL; retval = VPageChannelAllocDatagram(channel, len, numElems, &dg); if (retval < VMCI_SUCCESS) { return retval; } packet = (VPageChannelPacket *)VMCI_DG_PAYLOAD(dg); packet->type = type; packet->msgLen = len; packet->numElems = numElems; if (len) { ASSERT(message); memcpy(VPAGECHANNEL_PACKET_MESSAGE(packet), message, len); } if (numElems) { ASSERT(elems); memcpy(VPAGECHANNEL_PACKET_ELEMS(packet), elems, numElems * sizeof (VPageChannelElem)); } retval = vmci_datagram_send(dg); if (retval < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to send packet (channel=%p) to " "(handle=0x%x:0x%x) (err=%d).\n", channel, dg->dst.context, dg->dst.resource, retval)); } else { /* * We don't care about how many bytes were sent, and callers may not * expect > 0 to mean success, so just convert to exactly success. */ retval = VMCI_SUCCESS; } VMCI_FreeKernelMem(dg, VMCI_DG_SIZE(dg)); return retval; } /* *----------------------------------------------------------------------------- * * VPageChannelSignal -- * * Signal the channel's peer via the doorbell. * * Results: * VMCI_SUCCESS if signalled, negative error number otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int VPageChannelSignal(VPageChannel *channel) // IN { int retval; ASSERT(channel); retval = vmci_doorbell_notify(channel->peerDoorbellHandle, /* XXX, TRUSTED for VMKernel. */ VMCI_PRIVILEGE_FLAG_RESTRICTED); if (retval < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to notify doorbell (channel=%p) " "(handle=0x%x:0x%x) (err=%d).\n", channel, channel->peerDoorbellHandle.context, channel->peerDoorbellHandle.resource, retval)); } return retval; } /* *----------------------------------------------------------------------------- * * VPageChannel_SendPacket -- * * Send a VMCI packet to the hypervisor. * * XXX, this is now identical to the function of the same name in * modules/vmkernel/vmci/vmciPacketVMK.c. We should share this code. * * "needsLock" indicates whether this function should acquire the send * lock. If TRUE, then it will be acquired; if FALSE, then it is the * caller's responsibility. This is internal only. * * "signalPending" indicates whether the caller will take care of * signalling/the caller knows that there is already a signal pending, * in which case this function will not check for/send one. This is * internal only, clients cannot specify this. * * Results: * VMCI_SUCCESS if sent, negative error number otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int VPageChannelSendPacket(VPageChannel *channel, // IN VPageChannelPacket *packet, // IN Bool needsLock, // IN Bool signalPending) // IN { int retval; ssize_t totalSize, sentSize; ssize_t freeSpace; unsigned long flags; ASSERT(channel); if (VPCState_Connected != channel->state) { VMCI_WARNING((LGPFX"Not connected (channel=%p).\n", channel)); return VMCI_ERROR_DST_UNREACHABLE; } ASSERT(packet); totalSize = sizeof(VPageChannelPacket) + packet->msgLen + packet->numElems * sizeof(VPageChannelElem); if (needsLock) { VPageChannelAcquireSendLock(channel, &flags); } else { flags = 0; /* Silence compiler. */ } freeSpace = vmci_qpair_produce_free_space(channel->qpair); if (freeSpace < totalSize) { VMCI_WARNING((LGPFX"No free space in queuepair (channel=%p) " "(required=%"FMTSZ"d) (actual=%"FMTSZ"d).\n", channel, totalSize, freeSpace)); retval = VMCI_ERROR_NO_MEM; goto exit; } sentSize = vmci_qpair_enqueue(channel->qpair, packet, totalSize, 0); if (!signalPending) { if (sentSize == vmci_qpair_produce_buf_ready(channel->qpair)) { retval = VPageChannelSignal(channel); if (retval < VMCI_SUCCESS) { goto exit; } } } if (sentSize < totalSize) { /* * XXX, deal with partial sending. */ VMCI_WARNING((LGPFX"No free space in queuepair (channel=%p) " "(required=%"FMTSZ"d) (actual=%"FMTSZ"d).\n", channel, totalSize, sentSize)); retval = VMCI_ERROR_NO_MEM; goto exit; } VMCI_DEBUG_LOG(10, (LGPFX"Sent packet (channel=%p) (size=%"FMTSZ"d).\n", channel, sentSize)); retval = VMCI_SUCCESS; exit: if (needsLock) { VPageChannelReleaseSendLock(channel, flags); } return retval; } /* *----------------------------------------------------------------------------- * * VPageChannel_SendPacket -- * * Send a VMCI packet to the hypervisor. * * XXX, this is now identical to the function of the same name in * modules/vmkernel/vmci/vmciPacketVMK.c. We should share this code. * * Results: * VMCI_SUCCESS if sent, negative error number otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int VPageChannel_SendPacket(VPageChannel *channel, // IN VPageChannelPacket *packet) // IN { return VPageChannelSendPacket(channel, packet, TRUE, FALSE); } EXPORT_SYMBOL(VPageChannel_SendPacket); /* *----------------------------------------------------------------------------- * * VPageChannel_Send -- * * A packet is constructed to send the message and buffer to the guest. * * XXX, this is now identical to the function of the same name in * modules/vmkernel/vmci/vmciPacketVMK.c. We should share this code. * * Results: * VMCI_SUCCESS if the packet is sent successfully, negative error number * otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int VPageChannel_Send(VPageChannel *channel, // IN/OUT VPageChannelPacketType type, // IN char *message, // IN int len, // IN VPageChannelBuffer *buffer) // IN { int retval; int numElems; ssize_t totalSize; VPageChannelPacket *packet; ASSERT(channel); if (VPCState_Connected != channel->state) { VMCI_WARNING((LGPFX"Not connected (channel=%p).\n", channel)); return VMCI_ERROR_DST_UNREACHABLE; } if (buffer) { numElems = buffer->numElems; } else { numElems = 0; } totalSize = sizeof(VPageChannelPacket) + len + numElems * sizeof(VPageChannelElem); packet = (VPageChannelPacket *) VMCI_AllocKernelMem(totalSize, channel->flags & VPAGECHANNEL_FLAGS_SEND_WHILE_ATOMIC ? VMCI_MEMORY_ATOMIC : VMCI_MEMORY_NORMAL); if (!packet) { VMCI_WARNING((LGPFX"Failed to allocate packet (channel=%p) " "(size=%"FMTSZ"d).", channel, totalSize)); return VMCI_ERROR_NO_MEM; } packet->type = type; packet->msgLen = len; packet->numElems = numElems; if (len) { ASSERT(message); memcpy(VPAGECHANNEL_PACKET_MESSAGE(packet), message, len); } if (numElems) { ASSERT(buffer); ASSERT(buffer->elems); memcpy(VPAGECHANNEL_PACKET_ELEMS(packet), buffer->elems, numElems * sizeof (VPageChannelElem)); } retval = VPageChannel_SendPacket(channel, packet); VMCI_FreeKernelMem(packet, totalSize); return retval; } EXPORT_SYMBOL(VPageChannel_Send); /* *----------------------------------------------------------------------------- * * VPageChannel_PollTx -- * * The caller does its own coalescing and notifies us that it starts tx. * * Results: * None. * * Side effects: * We do not do our own coalescing. * *----------------------------------------------------------------------------- */ void VPageChannel_PollRecvQ(VPageChannel *channel) // IN { if (VPCState_Connected != channel->state) { VPageChannelDoDoorbellCallback(channel); } } EXPORT_SYMBOL(VPageChannel_PollRecvQ); open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciRoute.c0000644765153500003110000002145312220061556022622 0ustar dtormts/********************************************************* * Copyright (C) 2011-2012 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciRoute.c -- * * Implementation of VMCI routing rules. */ #include "vmci_kernel_if.h" #include "vm_assert.h" #include "vmci_defs.h" #include "vmci_infrastructure.h" #include "vmciCommonInt.h" #include "vmciContext.h" #include "vmciDriver.h" #include "vmciKernelAPI.h" #include "vmciRoute.h" #if defined(VMKERNEL) # include "vmciVmkInt.h" # include "vm_libc.h" # include "helper_ext.h" #endif #define LGPFX "VMCIRoute: " /* *------------------------------------------------------------------------------ * * VMCI_Route -- * * Make a routing decision for the given source and destination handles. * This will try to determine the route using the handles and the available * devices. * * Result: * A VMCIRoute value. * * Side effects: * Sets the source context if it is invalid. * *------------------------------------------------------------------------------ */ int VMCI_Route(VMCIHandle *src, // IN/OUT const VMCIHandle *dst, // IN Bool fromGuest, // IN VMCIRoute *route) // OUT { Bool hasHostDevice; Bool hasGuestDevice; ASSERT(src); ASSERT(dst); ASSERT(route); *route = VMCI_ROUTE_NONE; /* * "fromGuest" is only ever set to TRUE by IOCTL_VMCI_DATAGRAM_SEND (or by * the vmkernel equivalent), which comes from the VMX, so we know it is * coming from a guest. */ /* * To avoid inconsistencies, test these once. We will test them again * when we do the actual send to ensure that we do not touch a non-existent * device. */ hasHostDevice = VMCI_HostPersonalityActive(); hasGuestDevice = VMCI_GuestPersonalityActive(); /* Must have a valid destination context. */ if (VMCI_INVALID_ID == dst->context) { return VMCI_ERROR_INVALID_ARGS; } /* Anywhere to hypervisor. */ if (VMCI_HYPERVISOR_CONTEXT_ID == dst->context) { /* * If this message already came from a guest then we cannot send it * to the hypervisor. It must come from a local client. */ if (fromGuest) { return VMCI_ERROR_DST_UNREACHABLE; } /* We must be acting as a guest in order to send to the hypervisor. */ if (!hasGuestDevice) { return VMCI_ERROR_DEVICE_NOT_FOUND; } /* And we cannot send if the source is the host context. */ if (VMCI_HOST_CONTEXT_ID == src->context) { return VMCI_ERROR_INVALID_ARGS; } /* * If the client passed the ANON source handle then respect it (both * context and resource are invalid). However, if they passed only * an invalid context, then they probably mean ANY, in which case we * should set the real context here before passing it down. */ if (VMCI_INVALID_ID == src->context && VMCI_INVALID_ID != src->resource) { src->context = vmci_get_context_id(); } /* Send from local client down to the hypervisor. */ *route = VMCI_ROUTE_AS_GUEST; return VMCI_SUCCESS; } /* Anywhere to local client on host. */ if (VMCI_HOST_CONTEXT_ID == dst->context) { /* * If it is not from a guest but we are acting as a guest, then we need * to send it down to the host. Note that if we are also acting as a * host then this will prevent us from sending from local client to * local client, but we accept that restriction as a way to remove * any ambiguity from the host context. */ if (src->context == VMCI_HYPERVISOR_CONTEXT_ID) { /* * If the hypervisor is the source, this is host local * communication. The hypervisor may send vmci event * datagrams to the host itself, but it will never send * datagrams to an "outer host" through the guest device. */ if (hasHostDevice) { *route = VMCI_ROUTE_AS_HOST; return VMCI_SUCCESS; } else { return VMCI_ERROR_DEVICE_NOT_FOUND; } } if (!fromGuest && hasGuestDevice) { /* If no source context then use the current. */ if (VMCI_INVALID_ID == src->context) { src->context = vmci_get_context_id(); } /* Send it from local client down to the host. */ *route = VMCI_ROUTE_AS_GUEST; return VMCI_SUCCESS; } /* * Otherwise we already received it from a guest and it is destined * for a local client on this host, or it is from another local client * on this host. We must be acting as a host to service it. */ if (!hasHostDevice) { return VMCI_ERROR_DEVICE_NOT_FOUND; } if (VMCI_INVALID_ID == src->context) { /* * If it came from a guest then it must have a valid context. * Otherwise we can use the host context. */ if (fromGuest) { return VMCI_ERROR_INVALID_ARGS; } src->context = VMCI_HOST_CONTEXT_ID; } /* Route to local client. */ *route = VMCI_ROUTE_AS_HOST; return VMCI_SUCCESS; } /* If we are acting as a host then this might be destined for a guest. */ if (hasHostDevice) { /* It will have a context if it is meant for a guest. */ if (VMCIContext_Exists(dst->context)) { if (VMCI_INVALID_ID == src->context) { /* * If it came from a guest then it must have a valid context. * Otherwise we can use the host context. */ if (fromGuest) { return VMCI_ERROR_INVALID_ARGS; } src->context = VMCI_HOST_CONTEXT_ID; } else if (VMCI_CONTEXT_IS_VM(src->context) && src->context != dst->context) { /* * VM to VM communication is not allowed. Since we catch * all communication destined for the host above, this * must be destined for a VM since there is a valid * context. */ ASSERT(VMCI_CONTEXT_IS_VM(dst->context)); return VMCI_ERROR_DST_UNREACHABLE; } /* Pass it up to the guest. */ *route = VMCI_ROUTE_AS_HOST; return VMCI_SUCCESS; } else if (!hasGuestDevice) { /* * The host is attempting to reach a CID without an active context, and * we can't send it down, since we have no guest device. */ return VMCI_ERROR_DST_UNREACHABLE; } } /* * We must be a guest trying to send to another guest, which means * we need to send it down to the host. We do not filter out VM to * VM communication here, since we want to be able to use the guest * driver on older versions that do support VM to VM communication. */ if (!hasGuestDevice) { /* * Ending up here means we have neither guest nor host device. That * shouldn't happen, since any VMCI client in the kernel should have done * a successful VMCI_DeviceGet. */ ASSERT(FALSE); return VMCI_ERROR_DEVICE_NOT_FOUND; } /* If no source context then use the current context. */ if (VMCI_INVALID_ID == src->context) { src->context = vmci_get_context_id(); } /* * Send it from local client down to the host, which will route it to * the other guest for us. */ *route = VMCI_ROUTE_AS_GUEST; return VMCI_SUCCESS; } /* *------------------------------------------------------------------------------ * * VMCI_RouteString -- * * Get a string for the given route. * * Result: * A string representing the route, if the route is valid, otherwise an * empty string. * * Side effects: * None. * *------------------------------------------------------------------------------ */ const char * VMCI_RouteString(VMCIRoute route) // IN { const char *vmciRouteStrings[] = { "none", "as host", "as guest", }; if (route >= VMCI_ROUTE_NONE && route <= VMCI_ROUTE_AS_GUEST) { return vmciRouteStrings[route]; } return ""; } open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciContext.c0000644765153500003110000021667512220061556023164 0ustar dtormts/********************************************************* * Copyright (C) 2006-2012 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciContext.c -- * * Platform independent routines for VMCI calls. */ #include "vmci_kernel_if.h" #include "vm_assert.h" #include "vmci_defs.h" #include "vmci_infrastructure.h" #include "vmciCommonInt.h" #include "vmciContext.h" #include "vmciDatagram.h" #include "vmciDoorbell.h" #include "vmciDriver.h" #include "vmciEvent.h" #include "vmciKernelAPI.h" #include "vmciQueuePair.h" #if defined(VMKERNEL) # include "vmciVmkInt.h" # include "vm_libc.h" # include "helper_ext.h" #endif #define LGPFX "VMCIContext: " static void VMCIContextFreeContext(VMCIContext *context); static Bool VMCIContextExists(VMCIId cid); static int VMCIContextFireNotification(VMCIId contextID, VMCIPrivilegeFlags privFlags); #if defined(VMKERNEL) static void VMCIContextReleaseGuestMemLocked(VMCIContext *context, VMCIGuestMemID gid); static void VMCIContextInFilterCleanup(VMCIContext *context); #endif /* * List of current VMCI contexts. */ static struct { VMCIList head; VMCILock lock; VMCILock firingLock; } contextList; /* *---------------------------------------------------------------------- * * VMCIContextSignalNotify -- * * Sets the notify flag to TRUE. Assumes that the context lock is * held. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE void VMCIContextSignalNotify(VMCIContext *context) // IN: { #ifndef VMX86_SERVER if (context->notify) { *context->notify = TRUE; } #endif } /* *---------------------------------------------------------------------- * * VMCIContextClearNotify -- * * Sets the notify flag to FALSE. Assumes that the context lock is * held. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE void VMCIContextClearNotify(VMCIContext *context) // IN: { #ifndef VMX86_SERVER if (context->notify) { *context->notify = FALSE; } #endif } /* *---------------------------------------------------------------------- * * VMCIContextClearNotifyAndCall -- * * If nothing requires the attention of the guest, clears both * notify flag and call. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE void VMCIContextClearNotifyAndCall(VMCIContext *context) // IN: { if (context->pendingDatagrams == 0 && VMCIHandleArray_GetSize(context->pendingDoorbellArray) == 0) { VMCIHost_ClearCall(&context->hostContext); VMCIContextClearNotify(context); } } #ifndef VMX86_SERVER /* *---------------------------------------------------------------------- * * VMCIContext_CheckAndSignalNotify -- * * Sets the context's notify flag iff datagrams are pending for this * context. Called from VMCISetupNotify(). * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void VMCIContext_CheckAndSignalNotify(VMCIContext *context) // IN: { VMCILockFlags flags; ASSERT(context); VMCI_GrabLock(&context->lock, &flags); if (context->pendingDatagrams) { VMCIContextSignalNotify(context); } VMCI_ReleaseLock(&context->lock, flags); } #endif /* *---------------------------------------------------------------------- * * VMCIContext_Init -- * * Initializes the VMCI context module. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCIContext_Init(void) { int err; VMCIList_Init(&contextList.head); err = VMCI_InitLock(&contextList.lock, "VMCIContextListLock", VMCI_LOCK_RANK_CONTEXTLIST); if (err < VMCI_SUCCESS) { return err; } err = VMCI_InitLock(&contextList.firingLock, "VMCIContextFiringLock", VMCI_LOCK_RANK_CONTEXTFIRE); if (err < VMCI_SUCCESS) { VMCI_CleanupLock(&contextList.lock); } return err; } /* *---------------------------------------------------------------------- * * VMCIContext_Exit -- * * Cleans up the contexts module. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void VMCIContext_Exit(void) { VMCI_CleanupLock(&contextList.firingLock); VMCI_CleanupLock(&contextList.lock); } /* *---------------------------------------------------------------------- * * VMCIContext_InitContext -- * * Allocates and initializes a VMCI context. * * Results: * Returns 0 on success, appropriate error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCIContext_InitContext(VMCIId cid, // IN VMCIPrivilegeFlags privFlags, // IN uintptr_t eventHnd, // IN int userVersion, // IN: User's vers no. VMCIHostUser *user, // IN VMCIContext **outContext) // OUT { VMCILockFlags flags; VMCIContext *context; int result; if (privFlags & ~VMCI_PRIVILEGE_ALL_FLAGS) { VMCI_DEBUG_LOG(4, (LGPFX"Invalid flag (flags=0x%x) for VMCI context.\n", privFlags)); return VMCI_ERROR_INVALID_ARGS; } if (userVersion == 0) { return VMCI_ERROR_INVALID_ARGS; } context = VMCI_AllocKernelMem(sizeof *context, VMCI_MEMORY_NONPAGED); if (context == NULL) { VMCI_WARNING((LGPFX"Failed to allocate memory for VMCI context.\n")); return VMCI_ERROR_NO_MEM; } memset(context, 0, sizeof *context); VMCIList_InitEntry(&context->listItem); VMCIList_Init(&context->datagramQueue); context->userVersion = userVersion; context->queuePairArray = VMCIHandleArray_Create(0); if (!context->queuePairArray) { result = VMCI_ERROR_NO_MEM; goto error; } context->doorbellArray = VMCIHandleArray_Create(0); if (!context->doorbellArray) { result = VMCI_ERROR_NO_MEM; goto error; } context->pendingDoorbellArray = VMCIHandleArray_Create(0); if (!context->pendingDoorbellArray) { result = VMCI_ERROR_NO_MEM; goto error; } context->notifierArray = VMCIHandleArray_Create(0); if (context->notifierArray == NULL) { result = VMCI_ERROR_NO_MEM; goto error; } result = VMCI_InitLock(&context->lock, "VMCIContextLock", VMCI_LOCK_RANK_CONTEXT); if (result < VMCI_SUCCESS) { goto error; } Atomic_Write(&context->refCount, 1); #if defined(VMKERNEL) result = VMCIMutex_Init(&context->guestMemMutex, "VMCIGuestMem", VMCI_SEMA_RANK_GUESTMEM); if (result < VMCI_SUCCESS) { VMCI_CleanupLock(&context->lock); goto error; } context->curGuestMemID = INVALID_VMCI_GUEST_MEM_ID; context->inFilters = NULL; #endif /* Inititialize host-specific VMCI context. */ VMCIHost_InitContext(&context->hostContext, eventHnd); context->privFlags = privFlags; /* * If we collide with an existing context we generate a new and use it * instead. The VMX will determine if regeneration is okay. Since there * isn't 4B - 16 VMs running on a given host, the below loop will terminate. */ VMCI_GrabLock(&contextList.lock, &flags); ASSERT(cid != VMCI_INVALID_ID); while (VMCIContextExists(cid)) { /* * If the cid is below our limit and we collide we are creating duplicate * contexts internally so we want to assert fail in that case. */ ASSERT(cid >= VMCI_RESERVED_CID_LIMIT); /* We reserve the lowest 16 ids for fixed contexts. */ cid = MAX(cid, VMCI_RESERVED_CID_LIMIT-1) + 1; if (cid == VMCI_INVALID_ID) { cid = VMCI_RESERVED_CID_LIMIT; } } ASSERT(!VMCIContextExists(cid)); context->cid = cid; context->validUser = user != NULL; if (context->validUser) { context->user = *user; } VMCIList_Insert(&context->listItem, &contextList.head); VMCI_ReleaseLock(&contextList.lock, flags); #ifdef VMKERNEL VMCIContext_SetFSRState(context, FALSE, VMCI_INVALID_ID, eventHnd, FALSE); #endif #ifndef VMX86_SERVER context->notify = NULL; # ifdef __linux__ context->notifyPage = NULL; # endif #endif *outContext = context; return VMCI_SUCCESS; error: if (context->notifierArray) { VMCIHandleArray_Destroy(context->notifierArray); } if (context->queuePairArray) { VMCIHandleArray_Destroy(context->queuePairArray); } if (context->doorbellArray) { VMCIHandleArray_Destroy(context->doorbellArray); } if (context->pendingDoorbellArray) { VMCIHandleArray_Destroy(context->pendingDoorbellArray); } VMCI_FreeKernelMem(context, sizeof *context); return result; } /* *---------------------------------------------------------------------- * * VMCIContext_ReleaseContext -- * * Cleans up a VMCI context. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void VMCIContext_ReleaseContext(VMCIContext *context) // IN { VMCILockFlags flags; /* Dequeue VMCI context. */ VMCI_GrabLock(&contextList.lock, &flags); VMCIList_Remove(&context->listItem); VMCI_ReleaseLock(&contextList.lock, flags); VMCIContext_Release(context); } /* *----------------------------------------------------------------------------- * * VMCIContextFreeContext -- * * Deallocates all parts of a context datastructure. This * functions doesn't lock the context, because it assumes that * the caller is holding the last reference to context. As paged * memory may be freed as part of the call, the function must be * called without holding any spinlocks as this is not allowed on * Windows. * * Results: * None. * * Side effects: * Paged memory is freed. * *----------------------------------------------------------------------------- */ static void VMCIContextFreeContext(VMCIContext *context) // IN { VMCIListItem *curr; VMCIListItem *next; DatagramQueueEntry *dqEntry; VMCIHandle tempHandle; /* Fire event to all contexts interested in knowing this context is dying. */ VMCIContextFireNotification(context->cid, context->privFlags); /* * Cleanup all queue pair resources attached to context. If the VM dies * without cleaning up, this code will make sure that no resources are * leaked. */ tempHandle = VMCIHandleArray_GetEntry(context->queuePairArray, 0); while (!VMCI_HANDLE_EQUAL(tempHandle, VMCI_INVALID_HANDLE)) { if (VMCIQPBroker_Detach(tempHandle, context) < VMCI_SUCCESS) { /* * When VMCIQPBroker_Detach() succeeds it removes the handle from the * array. If detach fails, we must remove the handle ourselves. */ VMCIHandleArray_RemoveEntry(context->queuePairArray, tempHandle); } tempHandle = VMCIHandleArray_GetEntry(context->queuePairArray, 0); } /* * It is fine to destroy this without locking the datagramQueue, as * this is the only thread having a reference to the context. */ VMCIList_ScanSafe(curr, next, &context->datagramQueue) { dqEntry = VMCIList_Entry(curr, DatagramQueueEntry, listItem); VMCIList_Remove(curr); ASSERT(dqEntry && dqEntry->dg); ASSERT(dqEntry->dgSize == VMCI_DG_SIZE(dqEntry->dg)); VMCI_FreeKernelMem(dqEntry->dg, dqEntry->dgSize); VMCI_FreeKernelMem(dqEntry, sizeof *dqEntry); } VMCIHandleArray_Destroy(context->notifierArray); VMCIHandleArray_Destroy(context->queuePairArray); VMCIHandleArray_Destroy(context->doorbellArray); VMCIHandleArray_Destroy(context->pendingDoorbellArray); VMCI_CleanupLock(&context->lock); #if defined(VMKERNEL) VMCIContextInFilterCleanup(context); VMCIMutex_Destroy(&context->guestMemMutex); #endif VMCIHost_ReleaseContext(&context->hostContext); #ifndef VMX86_SERVER # ifdef __linux__ /* TODO Windows and Mac OS. */ VMCIUnsetNotify(context); # endif #endif VMCI_FreeKernelMem(context, sizeof *context); } /* *---------------------------------------------------------------------- * * VMCIContext_PendingDatagrams -- * * Returns the current number of pending datagrams. The call may * also serve as a synchronization point for the datagram queue, * as no enqueue operations can occur concurrently. * * Results: * Length of datagram queue for the given context. * * Side effects: * Locks datagram queue. * *---------------------------------------------------------------------- */ int VMCIContext_PendingDatagrams(VMCIId cid, // IN uint32 *pending) // OUT { VMCIContext *context; VMCILockFlags flags; context = VMCIContext_Get(cid); if (context == NULL) { return VMCI_ERROR_INVALID_ARGS; } VMCI_GrabLock(&context->lock, &flags); if (pending) { *pending = context->pendingDatagrams; } VMCI_ReleaseLock(&context->lock, flags); VMCIContext_Release(context); return VMCI_SUCCESS; } /* *---------------------------------------------------------------------- * * VMCIContext_EnqueueDatagram -- * * Queues a VMCI datagram for the appropriate target VM * context. * * Results: * Size of enqueued data on success, appropriate error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCIContext_EnqueueDatagram(VMCIId cid, // IN: Target VM VMCIDatagram *dg) // IN: { DatagramQueueEntry *dqEntry; VMCIContext *context; VMCILockFlags flags; VMCIHandle dgSrc; size_t vmciDgSize; ASSERT(dg); vmciDgSize = VMCI_DG_SIZE(dg); ASSERT(vmciDgSize <= VMCI_MAX_DG_SIZE); /* Get the target VM's VMCI context. */ context = VMCIContext_Get(cid); if (context == NULL) { VMCI_DEBUG_LOG(4, (LGPFX"Invalid context (ID=0x%x).\n", cid)); return VMCI_ERROR_INVALID_ARGS; } /* Allocate guest call entry and add it to the target VM's queue. */ dqEntry = VMCI_AllocKernelMem(sizeof *dqEntry, VMCI_MEMORY_NONPAGED); if (dqEntry == NULL) { VMCI_WARNING((LGPFX"Failed to allocate memory for datagram.\n")); VMCIContext_Release(context); return VMCI_ERROR_NO_MEM; } dqEntry->dg = dg; dqEntry->dgSize = vmciDgSize; dgSrc = dg->src; VMCIList_InitEntry(&dqEntry->listItem); VMCI_GrabLock(&context->lock, &flags); #if defined(VMKERNEL) if (context->inFilters != NULL) { if (VMCIFilterDenyDgIn(context->inFilters->filters, dg)) { VMCI_ReleaseLock(&context->lock, flags); VMCIContext_Release(context); VMCI_FreeKernelMem(dqEntry, sizeof *dqEntry); return VMCI_ERROR_NO_ACCESS; } } #endif /* * We put a higher limit on datagrams from the hypervisor. If the pending * datagram is not from hypervisor, then we check if enqueueing it would * exceed the VMCI_MAX_DATAGRAM_QUEUE_SIZE limit on the destination. If the * pending datagram is from hypervisor, we allow it to be queued at the * destination side provided we don't reach the * VMCI_MAX_DATAGRAM_AND_EVENT_QUEUE_SIZE limit. */ if (context->datagramQueueSize + vmciDgSize >= VMCI_MAX_DATAGRAM_QUEUE_SIZE && (!VMCI_HANDLE_EQUAL(dgSrc, VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_CONTEXT_RESOURCE_ID)) || context->datagramQueueSize + vmciDgSize >= VMCI_MAX_DATAGRAM_AND_EVENT_QUEUE_SIZE)) { VMCI_ReleaseLock(&context->lock, flags); VMCIContext_Release(context); VMCI_FreeKernelMem(dqEntry, sizeof *dqEntry); VMCI_DEBUG_LOG(10, (LGPFX"Context (ID=0x%x) receive queue is full.\n", cid)); return VMCI_ERROR_NO_RESOURCES; } VMCIList_Insert(&dqEntry->listItem, &context->datagramQueue); context->pendingDatagrams++; context->datagramQueueSize += vmciDgSize; VMCIContextSignalNotify(context); VMCIHost_SignalCall(&context->hostContext); VMCI_ReleaseLock(&context->lock, flags); VMCIContext_Release(context); return vmciDgSize; } #undef VMCI_MAX_DATAGRAM_AND_EVENT_QUEUE_SIZE /* *---------------------------------------------------------------------- * * VMCIContextExists -- * * Internal helper to check if a context with the specified context * ID exists. Assumes the contextList.lock is held. * * Results: * TRUE if a context exists with the given cid. * FALSE otherwise * * Side effects: * None. * *---------------------------------------------------------------------- */ static Bool VMCIContextExists(VMCIId cid) // IN { VMCIContext *context; VMCIListItem *next; Bool rv = FALSE; VMCIList_Scan(next, &contextList.head) { context = VMCIList_Entry(next, VMCIContext, listItem); if (context->cid == cid) { rv = TRUE; break; } } return rv; } /* *---------------------------------------------------------------------- * * VMCIContext_Exists -- * * Verifies whether a context with the specified context ID exists. * * Results: * TRUE if a context exists with the given cid. * FALSE otherwise * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool VMCIContext_Exists(VMCIId cid) // IN { VMCILockFlags flags; Bool rv; VMCI_GrabLock(&contextList.lock, &flags); rv = VMCIContextExists(cid); VMCI_ReleaseLock(&contextList.lock, flags); return rv; } /* *---------------------------------------------------------------------- * * VMCIContext_Get -- * * Retrieves VMCI context corresponding to the given cid. * * Results: * VMCI context on success, NULL otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ VMCIContext * VMCIContext_Get(VMCIId cid) // IN { VMCIContext *context = NULL; VMCIListItem *next; VMCILockFlags flags; if (cid == VMCI_INVALID_ID) { return NULL; } VMCI_GrabLock(&contextList.lock, &flags); if (VMCIList_Empty(&contextList.head)) { goto out; } VMCIList_Scan(next, &contextList.head) { context = VMCIList_Entry(next, VMCIContext, listItem); if (context->cid == cid) { /* * At this point, we are sure that the reference count is * larger already than zero. When starting the destruction of * a context, we always remove it from the context list * before decreasing the reference count. As we found the * context here, it hasn't been destroyed yet. This means * that we are not about to increase the reference count of * something that is in the process of being destroyed. */ Atomic_Inc(&context->refCount); break; } } out: VMCI_ReleaseLock(&contextList.lock, flags); return (context && context->cid == cid) ? context : NULL; } /* *---------------------------------------------------------------------- * * VMCIContext_Release -- * * Releases the VMCI context. If this is the last reference to * the context it will be deallocated. A context is created with * a reference count of one, and on destroy, it is removed from * the context list before its reference count is * decremented. Thus, if we reach zero, we are sure that nobody * else are about to increment it (they need the entry in the * context list for that). This function musn't be called with a * lock held. * * Results: * None. * * Side effects: * Paged memory may be deallocated. * *---------------------------------------------------------------------- */ void VMCIContext_Release(VMCIContext *context) // IN { uint32 refCount; ASSERT(context); refCount = Atomic_FetchAndDec(&context->refCount); if (refCount == 1) { VMCIContextFreeContext(context); } } /* *---------------------------------------------------------------------- * * VMCIContext_DequeueDatagram -- * * Dequeues the next datagram and returns it to caller. * The caller passes in a pointer to the max size datagram * it can handle and the datagram is only unqueued if the * size is less than maxSize. If larger maxSize is set to * the size of the datagram to give the caller a chance to * set up a larger buffer for the guestcall. * * Results: * On success: 0 if no more pending datagrams, otherwise the size of * the next pending datagram. * On failure: appropriate error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCIContext_DequeueDatagram(VMCIContext *context, // IN size_t *maxSize, // IN/OUT: max size of datagram caller can handle. VMCIDatagram **dg) // OUT: { DatagramQueueEntry *dqEntry; VMCIListItem *listItem; VMCILockFlags flags; int rv; ASSERT(context && dg); /* Dequeue the next datagram entry. */ VMCI_GrabLock(&context->lock, &flags); if (context->pendingDatagrams == 0) { VMCIContextClearNotifyAndCall(context); VMCI_ReleaseLock(&context->lock, flags); VMCI_DEBUG_LOG(4, (LGPFX"No datagrams pending.\n")); return VMCI_ERROR_NO_MORE_DATAGRAMS; } listItem = VMCIList_First(&context->datagramQueue); ASSERT (listItem != NULL); dqEntry = VMCIList_Entry(listItem, DatagramQueueEntry, listItem); ASSERT(dqEntry->dg); /* Check size of caller's buffer. */ if (*maxSize < dqEntry->dgSize) { *maxSize = dqEntry->dgSize; VMCI_ReleaseLock(&context->lock, flags); VMCI_DEBUG_LOG(4, (LGPFX"Caller's buffer should be at least " "(size=%u bytes).\n", (uint32)*maxSize)); return VMCI_ERROR_NO_MEM; } VMCIList_Remove(listItem); context->pendingDatagrams--; context->datagramQueueSize -= dqEntry->dgSize; if (context->pendingDatagrams == 0) { VMCIContextClearNotifyAndCall(context); rv = VMCI_SUCCESS; } else { /* * Return the size of the next datagram. */ DatagramQueueEntry *nextEntry; listItem = VMCIList_First(&context->datagramQueue); ASSERT(listItem); nextEntry = VMCIList_Entry(listItem, DatagramQueueEntry, listItem); ASSERT(nextEntry && nextEntry->dg); /* * The following size_t -> int truncation is fine as the maximum size of * a (routable) datagram is 68KB. */ rv = (int)nextEntry->dgSize; } VMCI_ReleaseLock(&context->lock, flags); /* Caller must free datagram. */ ASSERT(dqEntry->dgSize == VMCI_DG_SIZE(dqEntry->dg)); *dg = dqEntry->dg; dqEntry->dg = NULL; VMCI_FreeKernelMem(dqEntry, sizeof *dqEntry); return rv; } #ifdef VMKERNEL /* *---------------------------------------------------------------------- * * VMCIContext_SetFSRState -- * * Set the states related to FSR (quiesced state, migrateCid, * active event handle). * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void VMCIContext_SetFSRState(VMCIContext *context, // IN Bool isQuiesced, // IN VMCIId migrateCid, // IN uintptr_t eventHnd, // IN Bool isLocked) // IN { VMCILockFlags flags; if (!context) { return; } if (!isLocked) { VMCI_GrabLock(&context->lock, &flags); } context->isQuiesced = isQuiesced; context->migrateCid = migrateCid; VMCIHost_SetActiveHnd(&context->hostContext, eventHnd); if (!isLocked) { VMCI_ReleaseLock(&context->lock, flags); } } /* *---------------------------------------------------------------------- * * VMCIContext_FindAndUpdateSrcFSR -- * * Find the source context for fast-suspend-resume. If found, the * source context's FSR state is changed to reflect the new active * event handle. * * Results: * If found, source context for fast-suspend-resume, NULL otherwise. * * Side effects: * The source context reference count increased and the caller is * supposed to release the context once it is done using it. * *---------------------------------------------------------------------- */ VMCIContext * VMCIContext_FindAndUpdateSrcFSR(VMCIId migrateCid, // IN uintptr_t eventHnd, // IN uintptr_t *srcEventHnd) // IN/OUT { VMCIContext *contextSrc = VMCIContext_Get(migrateCid); if (contextSrc) { VMCILockFlags flags; VMCI_GrabLock(&contextSrc->lock, &flags); if (contextSrc->isQuiesced && contextSrc->migrateCid == migrateCid) { if (srcEventHnd) { *srcEventHnd = VMCIHost_GetActiveHnd(&contextSrc->hostContext); ASSERT(*srcEventHnd != VMCI_INVALID_ID); } VMCIContext_SetFSRState(contextSrc, FALSE, VMCI_INVALID_ID, eventHnd, TRUE); VMCI_ReleaseLock(&contextSrc->lock, flags); return contextSrc; } VMCI_ReleaseLock(&contextSrc->lock, flags); VMCIContext_Release(contextSrc); } return NULL; } /* *---------------------------------------------------------------------- * * VMCIContext_IsActiveHnd -- * * Whether the curent event handle is the active handle. * * Results: * TRUE if the event handle is active, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool VMCIContext_IsActiveHnd(VMCIContext *context, // IN uintptr_t eventHnd) // IN { VMCILockFlags flags; Bool isActive; ASSERT(context); VMCI_GrabLock(&context->lock, &flags); isActive = VMCIHost_IsActiveHnd(&context->hostContext, eventHnd); VMCI_ReleaseLock(&context->lock, flags); return isActive; } /* *---------------------------------------------------------------------- * * VMCIContext_GetActiveHnd -- * * Returns the curent event handle. * * Results: * The current active handle. * * Side effects: * None. * *---------------------------------------------------------------------- */ uintptr_t VMCIContext_GetActiveHnd(VMCIContext *context) // IN { VMCILockFlags flags; uintptr_t activeHnd; ASSERT(context); VMCI_GrabLock(&context->lock, &flags); activeHnd = VMCIHost_GetActiveHnd(&context->hostContext); VMCI_ReleaseLock(&context->lock, flags); return activeHnd; } /* *---------------------------------------------------------------------- * * VMCIContext_SetInactiveHnd -- * * Set the handle to be the inactive one. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void VMCIContext_SetInactiveHnd(VMCIContext *context, // IN uintptr_t eventHnd) // IN { VMCILockFlags flags; ASSERT(context); VMCI_GrabLock(&context->lock, &flags); VMCIHost_SetInactiveHnd(&context->hostContext, eventHnd); VMCI_ReleaseLock(&context->lock, flags); } /* *---------------------------------------------------------------------- * * VMCIContext_RemoveHnd -- * * Remove the event handle from host context. * * Results: * Whether the handle exists and removed, also number of handles * before removal and number of handles after removal. * * Side effects: * If this is active handle, the inactive handle becomes active. * *---------------------------------------------------------------------- */ Bool VMCIContext_RemoveHnd(VMCIContext *context, // IN uintptr_t eventHnd, // IN uint32 *numOld, // OUT uint32 *numNew) // OUT { VMCILockFlags flags; uint32 numHandleOld, numHandleNew; Bool ret; ASSERT(context); VMCI_GrabLock(&context->lock, &flags); numHandleOld = VMCIHost_NumHnds(&context->hostContext); ret = VMCIHost_RemoveHnd(&context->hostContext, eventHnd); numHandleNew = VMCIHost_NumHnds(&context->hostContext); /* * This is needed to prevent FSR to share this * context while this context is being destroyed. */ if (ret && numHandleOld == 1 && numHandleNew == 1) { context->migrateCid = VMCI_INVALID_ID; } VMCI_ReleaseLock(&context->lock, flags); if (numOld) { *numOld = numHandleOld; } if (numNew) { *numNew = numHandleNew; } return ret; } /* *----------------------------------------------------------------------------- * * VMCIContext_ClearDatagrams -- * * Clear pending datagrams. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMCIContext_ClearDatagrams(VMCIContext *context) // IN { int retval; VMCIDatagram *dg = NULL; size_t size = VMCI_MAX_DG_SIZE; uint32 pending; /* Drop all datagrams that are currently pending for given context. */ if (context == NULL) { return; } retval = VMCIContext_PendingDatagrams(context->cid, &pending); if (retval != VMCI_SUCCESS) { /* * This shouldn't happen as we already verified that the context * exists. */ ASSERT(FALSE); return; } /* * We drain the queue for any datagrams pending at the beginning of * the loop. As datagrams may arrive at any point in time, we * cannot guarantee that the queue is empty after this point. Only * removing a fixed number of pending datagrams prevents us from * looping forever. */ while (pending > 0 && VMCIContext_DequeueDatagram(context, &size, &dg) >= 0) { ASSERT(dg); VMCI_FreeKernelMem(dg, VMCI_DG_SIZE(dg)); --pending; } } /* *---------------------------------------------------------------------- * * VMCIContext_SetId -- * * Set the cid of given VMCI context. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void VMCIContext_SetId(VMCIContext *context, // IN VMCIId cid) // IN: { VMCILockFlags flags; if (!context) { return; } VMCI_GrabLock(&context->lock, &flags); context->cid = cid; VMCI_ReleaseLock(&context->lock, flags); } #endif /* *---------------------------------------------------------------------- * * VMCIContext_GetId -- * * Retrieves cid of given VMCI context. * * Results: * VMCIId of context on success, VMCI_INVALID_ID otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ VMCIId VMCIContext_GetId(VMCIContext *context) // IN: { if (!context) { return VMCI_INVALID_ID; } ASSERT(context->cid != VMCI_INVALID_ID); return context->cid; } /* *---------------------------------------------------------------------- * * vmci_context_get_priv_flags -- * * Retrieves the privilege flags of the given VMCI context ID. * * Results: * Context's privilege flags. * * Side effects: * None. * *---------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_context_get_priv_flags) VMCIPrivilegeFlags vmci_context_get_priv_flags(VMCIId contextID) // IN { if (VMCI_HostPersonalityActive()) { VMCIPrivilegeFlags flags; VMCIContext *context; context = VMCIContext_Get(contextID); if (!context) { return VMCI_LEAST_PRIVILEGE_FLAGS; } flags = context->privFlags; VMCIContext_Release(context); return flags; } return VMCI_NO_PRIVILEGE_FLAGS; } /* *---------------------------------------------------------------------- * * VMCIContext_AddNotification -- * * Add remoteCID to list of contexts current contexts wants * notifications from/about. * * Results: * VMCI_SUCCESS on success, error code otherwise. * * Side effects: * As in VMCIHandleArray_AppendEntry(). * *---------------------------------------------------------------------- */ int VMCIContext_AddNotification(VMCIId contextID, // IN: VMCIId remoteCID) // IN: { int result = VMCI_ERROR_ALREADY_EXISTS; VMCILockFlags flags; VMCILockFlags firingFlags; VMCIHandle notifierHandle; VMCIContext *context = VMCIContext_Get(contextID); if (context == NULL) { return VMCI_ERROR_NOT_FOUND; } if (VMCI_CONTEXT_IS_VM(contextID) && VMCI_CONTEXT_IS_VM(remoteCID)) { VMCI_DEBUG_LOG(4, (LGPFX"Context removed notifications for other VMs not " "supported (src=0x%x, remote=0x%x).\n", contextID, remoteCID)); result = VMCI_ERROR_DST_UNREACHABLE; goto out; } if (context->privFlags & VMCI_PRIVILEGE_FLAG_RESTRICTED) { result = VMCI_ERROR_NO_ACCESS; goto out; } notifierHandle = VMCI_MAKE_HANDLE(remoteCID, VMCI_EVENT_HANDLER); VMCI_GrabLock(&contextList.firingLock, &firingFlags); VMCI_GrabLock(&context->lock, &flags); if (!VMCIHandleArray_HasEntry(context->notifierArray, notifierHandle)) { VMCIHandleArray_AppendEntry(&context->notifierArray, notifierHandle); result = VMCI_SUCCESS; } VMCI_ReleaseLock(&context->lock, flags); VMCI_ReleaseLock(&contextList.firingLock, firingFlags); out: VMCIContext_Release(context); return result; } /* *---------------------------------------------------------------------- * * VMCIContext_RemoveNotification -- * * Remove remoteCID from current context's list of contexts it is * interested in getting notifications from/about. * * Results: * VMCI_SUCCESS on success, error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCIContext_RemoveNotification(VMCIId contextID, // IN: VMCIId remoteCID) // IN: { VMCILockFlags flags; VMCILockFlags firingFlags; VMCIContext *context = VMCIContext_Get(contextID); VMCIHandle tmpHandle; if (context == NULL) { return VMCI_ERROR_NOT_FOUND; } VMCI_GrabLock(&contextList.firingLock, &firingFlags); VMCI_GrabLock(&context->lock, &flags); tmpHandle = VMCIHandleArray_RemoveEntry(context->notifierArray, VMCI_MAKE_HANDLE(remoteCID, VMCI_EVENT_HANDLER)); VMCI_ReleaseLock(&context->lock, flags); VMCI_ReleaseLock(&contextList.firingLock, firingFlags); VMCIContext_Release(context); if (VMCI_HANDLE_EQUAL(tmpHandle, VMCI_INVALID_HANDLE)) { return VMCI_ERROR_NOT_FOUND; } return VMCI_SUCCESS; } /* *---------------------------------------------------------------------- * * VMCIContextFireNotification -- * * Fire notification for all contexts interested in given cid. * * Results: * VMCI_SUCCESS on success, error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int VMCIContextFireNotification(VMCIId contextID, // IN VMCIPrivilegeFlags privFlags) // IN { uint32 i, arraySize; VMCIListItem *next; VMCILockFlags flags; VMCILockFlags firingFlags; VMCIHandleArray *subscriberArray; VMCIHandle contextHandle = VMCI_MAKE_HANDLE(contextID, VMCI_EVENT_HANDLER); /* * We create an array to hold the subscribers we find when scanning through * all contexts. */ subscriberArray = VMCIHandleArray_Create(0); if (subscriberArray == NULL) { return VMCI_ERROR_NO_MEM; } /* * Scan all contexts to find who is interested in being notified about * given contextID. We have a special firingLock that we use to synchronize * across all notification operations. This avoids us having to take the * context lock for each HasEntry call and it solves a lock ranking issue. */ VMCI_GrabLock(&contextList.firingLock, &firingFlags); VMCI_GrabLock(&contextList.lock, &flags); VMCIList_Scan(next, &contextList.head) { VMCIContext *subCtx = VMCIList_Entry(next, VMCIContext, listItem); /* * We only deliver notifications of the removal of contexts, if * the two contexts are allowed to interact. */ if (VMCIHandleArray_HasEntry(subCtx->notifierArray, contextHandle) && !VMCIDenyInteraction(privFlags, subCtx->privFlags)) { VMCIHandleArray_AppendEntry(&subscriberArray, VMCI_MAKE_HANDLE(subCtx->cid, VMCI_EVENT_HANDLER)); } } VMCI_ReleaseLock(&contextList.lock, flags); VMCI_ReleaseLock(&contextList.firingLock, firingFlags); /* Fire event to all subscribers. */ arraySize = VMCIHandleArray_GetSize(subscriberArray); for (i = 0; i < arraySize; i++) { int result; VMCIEventMsg *eMsg; VMCIEventPayload_Context *evPayload; char buf[sizeof *eMsg + sizeof *evPayload]; eMsg = (VMCIEventMsg *)buf; /* Clear out any garbage. */ memset(eMsg, 0, sizeof *eMsg + sizeof *evPayload); eMsg->hdr.dst = VMCIHandleArray_GetEntry(subscriberArray, i); eMsg->hdr.src = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_CONTEXT_RESOURCE_ID); eMsg->hdr.payloadSize = sizeof *eMsg + sizeof *evPayload - sizeof eMsg->hdr; eMsg->eventData.event = VMCI_EVENT_CTX_REMOVED; evPayload = VMCIEventMsgPayload(eMsg); evPayload->contextID = contextID; result = VMCIDatagram_Dispatch(VMCI_HYPERVISOR_CONTEXT_ID, (VMCIDatagram *)eMsg, FALSE); if (result < VMCI_SUCCESS) { VMCI_DEBUG_LOG(4, (LGPFX"Failed to enqueue event datagram " "(type=%d) for context (ID=0x%x).\n", eMsg->eventData.event, eMsg->hdr.dst.context)); /* We continue to enqueue on next subscriber. */ } } VMCIHandleArray_Destroy(subscriberArray); return VMCI_SUCCESS; } /* *---------------------------------------------------------------------- * * VMCIContext_GetCheckpointState -- * * Get current context's checkpoint state of given type. * * Results: * VMCI_SUCCESS on success, error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCIContext_GetCheckpointState(VMCIId contextID, // IN: uint32 cptType, // IN: uint32 *bufSize, // IN/OUT: char **cptBufPtr) // OUT: { int i, result; VMCILockFlags flags; uint32 arraySize, cptDataSize; VMCIHandleArray *array; VMCIContext *context; char *cptBuf; Bool getContextID; ASSERT(bufSize && cptBufPtr); context = VMCIContext_Get(contextID); if (context == NULL) { return VMCI_ERROR_NOT_FOUND; } VMCI_GrabLock(&context->lock, &flags); if (cptType == VMCI_NOTIFICATION_CPT_STATE) { ASSERT(context->notifierArray); array = context->notifierArray; getContextID = TRUE; } else if (cptType == VMCI_WELLKNOWN_CPT_STATE) { /* * For compatibility with VMX'en with VM to VM communication, we * always return zero wellknown handles. */ *bufSize = 0; *cptBufPtr = NULL; result = VMCI_SUCCESS; goto release; } else if (cptType == VMCI_DOORBELL_CPT_STATE) { ASSERT(context->doorbellArray); array = context->doorbellArray; getContextID = FALSE; } else { VMCI_DEBUG_LOG(4, (LGPFX"Invalid cpt state (type=%d).\n", cptType)); result = VMCI_ERROR_INVALID_ARGS; goto release; } arraySize = VMCIHandleArray_GetSize(array); if (arraySize > 0) { if (cptType == VMCI_DOORBELL_CPT_STATE) { cptDataSize = arraySize * sizeof(VMCIDoorbellCptState); } else { cptDataSize = arraySize * sizeof(VMCIId); } if (*bufSize < cptDataSize) { *bufSize = cptDataSize; result = VMCI_ERROR_MORE_DATA; goto release; } cptBuf = VMCI_AllocKernelMem(cptDataSize, VMCI_MEMORY_NONPAGED | VMCI_MEMORY_ATOMIC); if (cptBuf == NULL) { result = VMCI_ERROR_NO_MEM; goto release; } for (i = 0; i < arraySize; i++) { VMCIHandle tmpHandle = VMCIHandleArray_GetEntry(array, i); if (cptType == VMCI_DOORBELL_CPT_STATE) { ((VMCIDoorbellCptState *)cptBuf)[i].handle = tmpHandle; } else { ((VMCIId *)cptBuf)[i] = getContextID ? tmpHandle.context : tmpHandle.resource; } } *bufSize = cptDataSize; *cptBufPtr = cptBuf; } else { *bufSize = 0; *cptBufPtr = NULL; } result = VMCI_SUCCESS; release: VMCI_ReleaseLock(&context->lock, flags); VMCIContext_Release(context); return result; } /* *---------------------------------------------------------------------- * * VMCIContext_SetCheckpointState -- * * Set current context's checkpoint state of given type. * * Results: * VMCI_SUCCESS on success, error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCIContext_SetCheckpointState(VMCIId contextID, // IN: uint32 cptType, // IN: uint32 bufSize, // IN: char *cptBuf) // IN: { uint32 i; VMCIId currentID; int result = VMCI_SUCCESS; uint32 numIDs = bufSize / sizeof(VMCIId); ASSERT(cptBuf); if (cptType == VMCI_WELLKNOWN_CPT_STATE && numIDs > 0) { /* * We would end up here if VMX with VM to VM communication * attempts to restore a checkpoint with wellknown handles. */ VMCI_WARNING((LGPFX"Attempt to restore checkpoint with obsolete " "wellknown handles.\n")); return VMCI_ERROR_OBSOLETE; } if (cptType != VMCI_NOTIFICATION_CPT_STATE) { VMCI_DEBUG_LOG(4, (LGPFX"Invalid cpt state (type=%d).\n", cptType)); return VMCI_ERROR_INVALID_ARGS; } for (i = 0; i < numIDs && result == VMCI_SUCCESS; i++) { currentID = ((VMCIId *)cptBuf)[i]; result = VMCIContext_AddNotification(contextID, currentID); if (result != VMCI_SUCCESS) { break; } } if (result != VMCI_SUCCESS) { VMCI_DEBUG_LOG(4, (LGPFX"Failed to set cpt state (type=%d) (error=%d).\n", cptType, result)); } return result; } /* *---------------------------------------------------------------------- * * VMCIContext_ReceiveNotificationsGet -- * * Retrieves the specified context's pending notifications in the * form of a handle array. The handle arrays returned are the * actual data - not a copy and should not be modified by the * caller. They must be released using * VMCIContext_ReceiveNotificationsRelease. * * Results: * VMCI_SUCCESS on success, error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCIContext_ReceiveNotificationsGet(VMCIId contextID, // IN VMCIHandleArray **dbHandleArray, // OUT VMCIHandleArray **qpHandleArray) // OUT { VMCIContext *context; VMCILockFlags flags; int result = VMCI_SUCCESS; ASSERT(dbHandleArray && qpHandleArray); context = VMCIContext_Get(contextID); if (context == NULL) { return VMCI_ERROR_NOT_FOUND; } VMCI_GrabLock(&context->lock, &flags); *dbHandleArray = context->pendingDoorbellArray; context->pendingDoorbellArray = VMCIHandleArray_Create(0); if (!context->pendingDoorbellArray) { context->pendingDoorbellArray = *dbHandleArray; *dbHandleArray = NULL; result = VMCI_ERROR_NO_MEM; } *qpHandleArray = NULL; VMCI_ReleaseLock(&context->lock, flags); VMCIContext_Release(context); return result; } /* *---------------------------------------------------------------------- * * VMCIContext_ReceiveNotificationsRelease -- * * Releases handle arrays with pending notifications previously * retrieved using VMCIContext_ReceiveNotificationsGet. If the * notifications were not successfully handed over to the guest, * success must be false. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void VMCIContext_ReceiveNotificationsRelease(VMCIId contextID, // IN VMCIHandleArray *dbHandleArray, // IN VMCIHandleArray *qpHandleArray, // IN Bool success) // IN { VMCIContext *context = VMCIContext_Get(contextID); if (context) { VMCILockFlags flags; VMCI_GrabLock(&context->lock, &flags); if (!success) { VMCIHandle handle; /* * New notifications may have been added while we were not * holding the context lock, so we transfer any new pending * doorbell notifications to the old array, and reinstate the * old array. */ handle = VMCIHandleArray_RemoveTail(context->pendingDoorbellArray); while (!VMCI_HANDLE_INVALID(handle)) { ASSERT(VMCIHandleArray_HasEntry(context->doorbellArray, handle)); if (!VMCIHandleArray_HasEntry(dbHandleArray, handle)) { VMCIHandleArray_AppendEntry(&dbHandleArray, handle); } handle = VMCIHandleArray_RemoveTail(context->pendingDoorbellArray); } VMCIHandleArray_Destroy(context->pendingDoorbellArray); context->pendingDoorbellArray = dbHandleArray; dbHandleArray = NULL; } else { VMCIContextClearNotifyAndCall(context); } VMCI_ReleaseLock(&context->lock, flags); VMCIContext_Release(context); } else { /* * The OS driver part is holding on to the context for the * duration of the receive notification ioctl, so it should * still be here. */ ASSERT(FALSE); } if (dbHandleArray) { VMCIHandleArray_Destroy(dbHandleArray); } if (qpHandleArray) { VMCIHandleArray_Destroy(qpHandleArray); } } /* *---------------------------------------------------------------------- * * VMCIContext_DoorbellCreate -- * * Registers that a new doorbell handle has been allocated by the * context. Only doorbell handles registered can be notified. * * Results: * VMCI_SUCCESS on success, appropriate error code otherewise. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCIContext_DoorbellCreate(VMCIId contextID, // IN VMCIHandle handle) // IN { VMCIContext *context; VMCILockFlags flags; int result; if (contextID == VMCI_INVALID_ID || VMCI_HANDLE_INVALID(handle)) { return VMCI_ERROR_INVALID_ARGS; } context = VMCIContext_Get(contextID); if (context == NULL) { return VMCI_ERROR_NOT_FOUND; } VMCI_GrabLock(&context->lock, &flags); if (!VMCIHandleArray_HasEntry(context->doorbellArray, handle)) { VMCIHandleArray_AppendEntry(&context->doorbellArray, handle); result = VMCI_SUCCESS; } else { result = VMCI_ERROR_DUPLICATE_ENTRY; } VMCI_ReleaseLock(&context->lock, flags); VMCIContext_Release(context); return result; } /* *---------------------------------------------------------------------- * * VMCIContext_DoorbellDestroy -- * * Unregisters a doorbell handle that was previously registered * with VMCIContext_DoorbellCreate. * * Results: * VMCI_SUCCESS on success, appropriate error code otherewise. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCIContext_DoorbellDestroy(VMCIId contextID, // IN VMCIHandle handle) // IN { VMCIContext *context; VMCILockFlags flags; VMCIHandle removedHandle; if (contextID == VMCI_INVALID_ID || VMCI_HANDLE_INVALID(handle)) { return VMCI_ERROR_INVALID_ARGS; } context = VMCIContext_Get(contextID); if (context == NULL) { return VMCI_ERROR_NOT_FOUND; } VMCI_GrabLock(&context->lock, &flags); removedHandle = VMCIHandleArray_RemoveEntry(context->doorbellArray, handle); VMCIHandleArray_RemoveEntry(context->pendingDoorbellArray, handle); VMCI_ReleaseLock(&context->lock, flags); VMCIContext_Release(context); if (VMCI_HANDLE_INVALID(removedHandle)) { return VMCI_ERROR_NOT_FOUND; } else { return VMCI_SUCCESS; } } /* *---------------------------------------------------------------------- * * VMCIContext_DoorbellDestroyAll -- * * Unregisters all doorbell handles that were previously * registered with VMCIContext_DoorbellCreate. * * Results: * VMCI_SUCCESS on success, appropriate error code otherewise. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCIContext_DoorbellDestroyAll(VMCIId contextID) // IN { VMCIContext *context; VMCILockFlags flags; VMCIHandle removedHandle; if (contextID == VMCI_INVALID_ID) { return VMCI_ERROR_INVALID_ARGS; } context = VMCIContext_Get(contextID); if (context == NULL) { return VMCI_ERROR_NOT_FOUND; } VMCI_GrabLock(&context->lock, &flags); do { removedHandle = VMCIHandleArray_RemoveTail(context->doorbellArray); } while(!VMCI_HANDLE_INVALID(removedHandle)); do { removedHandle = VMCIHandleArray_RemoveTail(context->pendingDoorbellArray); } while(!VMCI_HANDLE_INVALID(removedHandle)); VMCI_ReleaseLock(&context->lock, flags); VMCIContext_Release(context); return VMCI_SUCCESS; } /* *---------------------------------------------------------------------- * * VMCIContext_NotifyDoorbell -- * * Registers a notification of a doorbell handle initiated by the * specified source context. The notification of doorbells are * subject to the same isolation rules as datagram delivery. To * allow host side senders of notifications a finer granularity * of sender rights than those assigned to the sending context * itself, the host context is required to specify a different * set of privilege flags that will override the privileges of * the source context. * * Results: * VMCI_SUCCESS on success, appropriate error code otherewise. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCIContext_NotifyDoorbell(VMCIId srcCID, // IN VMCIHandle handle, // IN VMCIPrivilegeFlags srcPrivFlags) // IN { VMCIContext *dstContext; VMCILockFlags flags; int result; if (VMCI_HANDLE_INVALID(handle)) { return VMCI_ERROR_INVALID_ARGS; } /* Get the target VM's VMCI context. */ dstContext = VMCIContext_Get(handle.context); if (dstContext == NULL) { VMCI_DEBUG_LOG(4, (LGPFX"Invalid context (ID=0x%x).\n", handle.context)); return VMCI_ERROR_NOT_FOUND; } if (srcCID != handle.context) { VMCIPrivilegeFlags dstPrivFlags; if (!vmkernel && VMCI_CONTEXT_IS_VM(srcCID) && VMCI_CONTEXT_IS_VM(handle.context)) { VMCI_DEBUG_LOG(4, (LGPFX"Doorbell notification from VM to VM not " "supported (src=0x%x, dst=0x%x).\n", srcCID, handle.context)); result = VMCI_ERROR_DST_UNREACHABLE; goto out; } result = VMCIDoorbellGetPrivFlags(handle, &dstPrivFlags); if (result < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to get privilege flags for destination " "(handle=0x%x:0x%x).\n", handle.context, handle.resource)); goto out; } if (srcCID != VMCI_HOST_CONTEXT_ID || srcPrivFlags == VMCI_NO_PRIVILEGE_FLAGS) { srcPrivFlags = vmci_context_get_priv_flags(srcCID); } if (VMCIDenyInteraction(srcPrivFlags, dstPrivFlags)) { result = VMCI_ERROR_NO_ACCESS; goto out; } } if (handle.context == VMCI_HOST_CONTEXT_ID) { result = VMCIDoorbellHostContextNotify(srcCID, handle); } else { VMCI_GrabLock(&dstContext->lock, &flags); #if defined(VMKERNEL) if (dstContext->inFilters != NULL && VMCIFilterProtoDeny(dstContext->inFilters->filters, handle.resource, VMCI_FP_DOORBELL)) { result = VMCI_ERROR_NO_ACCESS; } else #endif // VMKERNEL if (!VMCIHandleArray_HasEntry(dstContext->doorbellArray, handle)) { result = VMCI_ERROR_NOT_FOUND; } else { if (!VMCIHandleArray_HasEntry(dstContext->pendingDoorbellArray, handle)) { VMCIHandleArray_AppendEntry(&dstContext->pendingDoorbellArray, handle); VMCIContextSignalNotify(dstContext); #if defined(VMKERNEL) VMCIHost_SignalBitmap(&dstContext->hostContext); #else VMCIHost_SignalCall(&dstContext->hostContext); #endif } result = VMCI_SUCCESS; } VMCI_ReleaseLock(&dstContext->lock, flags); } out: VMCIContext_Release(dstContext); return result; } #ifdef VMKERNEL /* *---------------------------------------------------------------------- * * VMCIContext_SignalPendingDoorbells -- * * Signals the guest if any doorbell notifications are * pending. This is used after the VMCI device is unquiesced to * ensure that no pending notifications go unnoticed, since * signals may not be fully processed while the device is * quiesced. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void VMCIContext_SignalPendingDoorbells(VMCIId contextID) { VMCIContext *context; VMCILockFlags flags; Bool pending; context = VMCIContext_Get(contextID); if (!context) { ASSERT(FALSE); return; } VMCI_GrabLock(&context->lock, &flags); pending = VMCIHandleArray_GetSize(context->pendingDoorbellArray) > 0; VMCI_ReleaseLock(&context->lock, flags); if (pending) { VMCIHost_SignalBitmap(&context->hostContext); } VMCIContext_Release(context); } /* *---------------------------------------------------------------------- * * VMCIContext_SignalPendingDatagrams -- * * Signals the guest if any datagrams are pending. This is used * after the VMCI device is unquiesced to ensure that no pending * datagrams go unnoticed, since signals may not be fully * processed while the device is quiesced. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void VMCIContext_SignalPendingDatagrams(VMCIId contextID) { Bool pending; VMCIContext *context; VMCILockFlags flags; context = VMCIContext_Get(contextID); if (!context) { ASSERT(FALSE); return; } VMCI_GrabLock(&context->lock, &flags); pending = context->pendingDatagrams; VMCI_ReleaseLock(&context->lock, flags); if (pending) { VMCIHost_SignalCall(&context->hostContext); } VMCIContext_Release(context); } #endif // defined(VMKERNEL) /* *---------------------------------------------------------------------- * * vmci_cid_2_host_vm_id -- * * Maps a context ID to the host specific (process/world) ID * of the VM/VMX. * * Results: * VMCI_SUCCESS on success, error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_cid_2_host_vm_id) int vmci_cid_2_host_vm_id(VMCIId contextID, // IN void *hostVmID, // OUT size_t hostVmIDLen) // IN { #if defined(VMKERNEL) VMCIContext *context; VMCIHostVmID vmID; int result; context = VMCIContext_Get(contextID); if (!context) { return VMCI_ERROR_NOT_FOUND; } result = VMCIHost_ContextToHostVmID(&context->hostContext, &vmID); if (result == VMCI_SUCCESS) { if (sizeof vmID == hostVmIDLen) { memcpy(hostVmID, &vmID, hostVmIDLen); } else { result = VMCI_ERROR_INVALID_ARGS; } } VMCIContext_Release(context); return result; #else // !defined(VMKERNEL) return VMCI_ERROR_UNAVAILABLE; #endif } /* *---------------------------------------------------------------------- * * vmci_is_context_owner -- * * Determines whether a given host OS specific representation of * user is the owner of the VM/VMX. * * Results: * Linux: 1 (true) if hostUser is owner, 0 (false) otherwise. * Other: VMCI_SUCCESS if the hostUser is owner, error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_is_context_owner) #if defined(linux) && !defined(VMKERNEL) int vmci_is_context_owner(VMCIId contextID, // IN uid_t uid) // IN { int isOwner = 0; if (VMCI_HostPersonalityActive()) { VMCIContext *context = VMCIContext_Get(contextID); if (context) { if (context->validUser) { if (VMCIHost_CompareUser((VMCIHostUser *)&uid, &context->user) == VMCI_SUCCESS) { isOwner = 1; } } VMCIContext_Release(context); } } return isOwner; } #else // !linux || VMKERNEL int vmci_is_context_owner(VMCIId contextID, // IN void *hostUser) // IN { if (VMCI_HostPersonalityActive()) { VMCIContext *context; VMCIHostUser *user = (VMCIHostUser *)hostUser; int retval; if (vmkernel) { return VMCI_ERROR_UNAVAILABLE; } if (!hostUser) { return VMCI_ERROR_INVALID_ARGS; } context = VMCIContext_Get(contextID); if (!context) { return VMCI_ERROR_NOT_FOUND; } if (context->validUser) { retval = VMCIHost_CompareUser(user, &context->user); } else { retval = VMCI_ERROR_UNAVAILABLE; } VMCIContext_Release(context); return retval; } return VMCI_ERROR_UNAVAILABLE; } #endif // !linux || VMKERNEL /* *---------------------------------------------------------------------- * * VMCIContext_SupportsHostQP -- * * Can host QPs be connected to this user process. The answer is * FALSE unless a sufficient version number has previously been set * by this caller. * * Results: * TRUE if context supports host queue pairs, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool VMCIContext_SupportsHostQP(VMCIContext *context) // IN: Context structure { #ifdef VMKERNEL return TRUE; #else if (!context || context->userVersion < VMCI_VERSION_HOSTQP) { return FALSE; } return TRUE; #endif } /* *---------------------------------------------------------------------- * * VMCIContext_QueuePairCreate -- * * Registers that a new queue pair handle has been allocated by * the context. * * Results: * VMCI_SUCCESS on success, appropriate error code otherewise. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCIContext_QueuePairCreate(VMCIContext *context, // IN: Context structure VMCIHandle handle) // IN { int result; if (context == NULL || VMCI_HANDLE_INVALID(handle)) { return VMCI_ERROR_INVALID_ARGS; } if (!VMCIHandleArray_HasEntry(context->queuePairArray, handle)) { VMCIHandleArray_AppendEntry(&context->queuePairArray, handle); result = VMCI_SUCCESS; } else { result = VMCI_ERROR_DUPLICATE_ENTRY; } return result; } /* *---------------------------------------------------------------------- * * VMCIContext_QueuePairDestroy -- * * Unregisters a queue pair handle that was previously registered * with VMCIContext_QueuePairCreate. * * Results: * VMCI_SUCCESS on success, appropriate error code otherewise. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCIContext_QueuePairDestroy(VMCIContext *context, // IN: Context structure VMCIHandle handle) // IN { VMCIHandle removedHandle; if (context == NULL || VMCI_HANDLE_INVALID(handle)) { return VMCI_ERROR_INVALID_ARGS; } removedHandle = VMCIHandleArray_RemoveEntry(context->queuePairArray, handle); if (VMCI_HANDLE_INVALID(removedHandle)) { return VMCI_ERROR_NOT_FOUND; } else { return VMCI_SUCCESS; } } /* *---------------------------------------------------------------------- * * VMCIContext_QueuePairExists -- * * Determines whether a given queue pair handle is registered * with the given context. * * Results: * TRUE, if queue pair is registered with context. FALSE, otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool VMCIContext_QueuePairExists(VMCIContext *context, // IN: Context structure VMCIHandle handle) // IN { Bool result; if (context == NULL || VMCI_HANDLE_INVALID(handle)) { return VMCI_ERROR_INVALID_ARGS; } result = VMCIHandleArray_HasEntry(context->queuePairArray, handle); return result; } /* *---------------------------------------------------------------------- * * VMCIContext_RegisterGuestMem -- * * Tells the context that guest memory is available for * access. This should only be used when unquiescing the VMCI * device of a guest. * * Results: * None. * * Side effects: * Notifies host side endpoints of queue pairs that the queue pairs * can be accessed. * *---------------------------------------------------------------------- */ void VMCIContext_RegisterGuestMem(VMCIContext *context, // IN: Context structure VMCIGuestMemID gid) // IN: Reference to guest { #ifdef VMKERNEL uint32 numQueuePairs; uint32 cur; VMCIMutex_Acquire(&context->guestMemMutex); if (context->curGuestMemID != INVALID_VMCI_GUEST_MEM_ID) { if (context->curGuestMemID != gid) { /* * The guest memory has been registered with a different guest * memory ID. This is possible if we attempt to continue the * execution of the source VMX following a failed FSR. */ VMCIContextReleaseGuestMemLocked(context, context->curGuestMemID); } else { /* * When unquiescing the device during a restore sync not part * of an FSR, we will already have registered the guest * memory when creating the device, so we don't need to do it * again. Also, there are no active queue pairs at this * point, so nothing to do. */ ASSERT(VMCIHandleArray_GetSize(context->queuePairArray) == 0); goto out; } } context->curGuestMemID = gid; /* * It is safe to access the queue pair array here, since no changes * to the queuePairArray can take place until after the unquiescing * is complete. */ numQueuePairs = VMCIHandleArray_GetSize(context->queuePairArray); for (cur = 0; cur < numQueuePairs; cur++) { VMCIHandle handle; handle = VMCIHandleArray_GetEntry(context->queuePairArray, cur); if (!VMCI_HANDLE_EQUAL(handle, VMCI_INVALID_HANDLE)) { int res; res = VMCIQPBroker_Map(handle, context, NULL); if (res < VMCI_SUCCESS) { VMCI_WARNING(("Failed to map guest memory for queue pair " "(handle=0x%x:0x%x, res=%d).\n", handle.context, handle.resource, res)); } } } out: VMCIMutex_Release(&context->guestMemMutex); #endif } #ifdef VMKERNEL /* *---------------------------------------------------------------------- * * VMCIContextReleaseGuestMemLocked -- * * A version of VMCIContext_ReleaseGuestMem that assumes that the * guest mem lock is already held. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void VMCIContextReleaseGuestMemLocked(VMCIContext *context, // IN: Context structure VMCIGuestMemID gid) // IN: Reference to guest { uint32 numQueuePairs; uint32 cur; /* * It is safe to access the queue pair array here, since no changes * to the queuePairArray can take place when the the quiescing * has been initiated. */ numQueuePairs = VMCIHandleArray_GetSize(context->queuePairArray); for (cur = 0; cur < numQueuePairs; cur++) { VMCIHandle handle; handle = VMCIHandleArray_GetEntry(context->queuePairArray, cur); if (!VMCI_HANDLE_EQUAL(handle, VMCI_INVALID_HANDLE)) { int res; res = VMCIQPBroker_Unmap(handle, context, gid); if (res < VMCI_SUCCESS) { VMCI_WARNING(("Failed to unmap guest memory for queue pair " "(handle=0x%x:0x%x, res=%d).\n", handle.context, handle.resource, res)); } } } } #endif /* *---------------------------------------------------------------------- * * VMCIContext_ReleaseGuestMem -- * * Releases all the contexts references to guest memory, if the * caller identified by the gid was the last one to register the * guest memory. This should only be used when quiescing or * cleaning up the VMCI device of a guest. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void VMCIContext_ReleaseGuestMem(VMCIContext *context, // IN: Context structure VMCIGuestMemID gid) // IN: Reference to guest { #ifdef VMKERNEL VMCIMutex_Acquire(&context->guestMemMutex); if (context->curGuestMemID == gid) { /* * In the case of an FSR, we may have multiple VMX'en * registering and releasing guest memory concurrently. The * common case is that the source will clean up its device state * after a successful FSR, where the destination may already * have registered guest memory. So we only release guest * memory, if this is the same gid, that registered the memory. */ VMCIContextReleaseGuestMemLocked(context, gid); context->curGuestMemID = INVALID_VMCI_GUEST_MEM_ID; } VMCIMutex_Release(&context->guestMemMutex); #endif } #if defined(VMKERNEL) /* *---------------------------------------------------------------------- * * VMCIContext_FilterSet -- * * Sets an ingoing (host to guest) filter for the VMCI firewall of the * given context. If a filter list already exists for the given filter * entry, the old entry will be deleted. It is assumed that the list * can be used as is, and that the memory backing it will be freed by the * VMCI Context module once the filter is deleted. * * Results: * VMCI_SUCCESS on success, * VMCI_ERROR_NOT_FOUND if there is no active context linked to the cid, * VMCI_ERROR_INVALID_ARGS if a non-VM cid is specified. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCIContext_FilterSet(VMCIId cid, // IN VMCIFilterState *filters) // IN { VMCIContext *context; VMCILockFlags flags; VMCIFilterState *oldState; if (!VMCI_CONTEXT_IS_VM(cid)) { return VMCI_ERROR_INVALID_ARGS; } context = VMCIContext_Get(cid); if (!context) { return VMCI_ERROR_NOT_FOUND; } VMCI_GrabLock(&context->lock, &flags); oldState = context->inFilters; context->inFilters = filters; VMCI_ReleaseLock(&context->lock, flags); if (oldState) { VMCIVMKDevFreeFilterState(oldState); } VMCIContext_Release(context); return VMCI_SUCCESS; } /* *---------------------------------------------------------------------- * * VMCIContextInFilterCleanup -- * * When a context is destroyed, all filters will be deleted. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void VMCIContextInFilterCleanup(VMCIContext *context) { if (context->inFilters != NULL) { VMCIVMKDevFreeFilterState(context->inFilters); context->inFilters = NULL; } } /* *---------------------------------------------------------------------- * * VMCI_Uuid2ContextId -- * * Given a running VM's UUID, retrieve the VM's VMCI context ID. * The given UUID is local to the host; it is _not_ the UUID * handed out by VC. It comes from the "bios.uuid" field in the * VMX file. We walk the context list and try to match the given * UUID against each context. If we get a match, we return the * contexts's VMCI ID. * * Results: * VMCI_SUCCESS if found and *contextID contains the CID. * VMCI_ERROR_INVALID_ARGS for bad parameters. * VMCI_ERROR_NOT_FOUND if no match. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCI_Uuid2ContextId(const char *uuidString, // IN VMCIId *contextID) // OUT { int err; VMCIListItem *next; VMCILockFlags flags; if (!uuidString || *uuidString == '\0' || !contextID) { return VMCI_ERROR_INVALID_ARGS; } err = VMCI_ERROR_NOT_FOUND; VMCI_GrabLock(&contextList.lock, &flags); VMCIList_Scan(next, &contextList.head) { VMCIContext *context = VMCIList_Entry(next, VMCIContext, listItem); if (VMCIHost_ContextHasUuid(&context->hostContext, uuidString) == VMCI_SUCCESS) { *contextID = context->cid; err = VMCI_SUCCESS; break; } } VMCI_ReleaseLock(&contextList.lock, flags); return err; } #endif // VMKERNEL open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciQPair.c0000644765153500003110000012132212220061556022534 0ustar dtormts/********************************************************* * Copyright (C) 2010-2012 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciQPair.c -- * * This file implements Queue accessor methods. * * VMCIQPair is a new interface that hides the queue pair internals. * Rather than access each queue in a pair directly, operations are now * performed on the queue as a whole. This is simpler and less * error-prone, and allows for future queue pair features to be added * under the hood with no change to the client code. * * This also helps in a particular case on Windows hosts, where the memory * allocated by the client (e.g., VMX) will disappear when the client does * (e.g., abnormal termination). The kernel can't lock user memory into * its address space indefinitely. By guarding access to the queue * contents we can correctly handle the case where the client disappears. * * On code style: * * + This entire file started its life as a cut-and-paste of the * static INLINE functions in bora/public/vmci_queue_pair.h. * From there, new copies of the routines were made named * without the prefix VMCI, without the underscore (the one * that followed VMCIQueue_). The no-underscore versions of * the routines require that the mutexes are held. * * + The code -always- uses the xyzLocked() version of any given * routine even when the wrapped function is a one-liner. The * reason for this decision was to ensure that we didn't have * copies of logic lying around that needed to be maintained. * * + Note that we still pass around 'const VMCIQueue *'s. * * + Note that mutex is a field within VMCIQueue. We skirt the * issue of passing around a const VMCIQueue, even though the * mutex field (__mutex, specifically) will get modified by not * ever referring to the mutex -itself- except during * initialization. Beyond that, the code only passes the * pointer to the mutex, which is also a member of VMCIQueue, * obviously, and which doesn't change after initialization. * This eliminates having to redefine all the functions that * are currently taking const VMCIQueue's so that these * functions are compatible with those definitions. */ #include "vmci_kernel_if.h" #include "vm_assert.h" #include "vmci_handle_array.h" #include "vmci_defs.h" #include "vmciKernelAPI.h" #include "vmciQueue.h" #include "vmciQueuePair.h" #include "vmciRoute.h" /* * VMCIQPair * * This structure is opaque to the clients. */ struct VMCIQPair { VMCIHandle handle; VMCIQueue *produceQ; VMCIQueue *consumeQ; uint64 produceQSize; uint64 consumeQSize; VMCIId peer; uint32 flags; VMCIPrivilegeFlags privFlags; Bool guestEndpoint; uint32 blocked; VMCIEvent event; }; static int VMCIQPairMapQueueHeaders(VMCIQueue *produceQ, VMCIQueue *consumeQ, Bool canBlock); static int VMCIQPairGetQueueHeaders(const VMCIQPair *qpair, VMCIQueueHeader **produceQHeader, VMCIQueueHeader **consumeQHeader); static int VMCIQPairWakeupCB(void *clientData); static int VMCIQPairReleaseMutexCB(void *clientData); static Bool VMCIQPairWaitForReadyQueue(VMCIQPair *qpair); /* *----------------------------------------------------------------------------- * * VMCIQPairLock -- * * Helper routine that will lock the QPair before subsequent operations. * * Results: * VMCI_SUCCESS if lock acquired. VMCI_ERROR_WOULD_BLOCK if queue mutex * couldn't be acquired and qpair isn't allowed to block. * * Side effects: * May block. * *----------------------------------------------------------------------------- */ static INLINE int VMCIQPairLock(const VMCIQPair *qpair) // IN { #if !defined VMX86_VMX if (qpair->flags & VMCI_QPFLAG_PINNED) { VMCI_LockQueueHeader(qpair->produceQ); return VMCI_SUCCESS; } return VMCI_AcquireQueueMutex(qpair->produceQ, !(qpair->flags & VMCI_QPFLAG_NONBLOCK)); #else return VMCI_SUCCESS #endif } /* *----------------------------------------------------------------------------- * * VMCIQPairUnlock -- * * Helper routine that will unlock the QPair after various operations. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE void VMCIQPairUnlock(const VMCIQPair *qpair) // IN { #if !defined VMX86_VMX if (qpair->flags & VMCI_QPFLAG_PINNED) { VMCI_UnlockQueueHeader(qpair->produceQ); } else { VMCI_ReleaseQueueMutex(qpair->produceQ); } #endif } /* *----------------------------------------------------------------------------- * * VMCIQPairHeaderLock -- * * Helper routine that will lock the queue pair header before subsequent * operations. If the queue pair is non blocking, a spinlock will be used. * Otherwise, a regular mutex locking the complete queue pair will be used. * * Results: * None. * * Side effects: * May block. * *----------------------------------------------------------------------------- */ static INLINE void VMCIQPairLockHeader(const VMCIQPair *qpair) // IN { #if !defined VMX86_VMX if (qpair->flags & VMCI_QPFLAG_NONBLOCK) { VMCI_LockQueueHeader(qpair->produceQ); } else { (void)VMCI_AcquireQueueMutex(qpair->produceQ, !(qpair->flags & VMCI_QPFLAG_NONBLOCK)); } #endif } /* *----------------------------------------------------------------------------- * * VMCIQPairUnlockHeader -- * * Helper routine that unlocks the queue pair header after calling * VMCIQPairHeaderLock. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE void VMCIQPairUnlockHeader(const VMCIQPair *qpair) // IN { #if !defined VMX86_VMX if (qpair->flags & VMCI_QPFLAG_NONBLOCK) { VMCI_UnlockQueueHeader(qpair->produceQ); } else { VMCI_ReleaseQueueMutex(qpair->produceQ); } #endif } /* *----------------------------------------------------------------------------- * * VMCIQPairGetQueueHeaders -- * * Helper routine that will retrieve the produce and consume * headers of a given queue pair. If the guest memory of the * queue pair is currently not available, the saved queue headers * will be returned, if these are available. * * Results: * VMCI_SUCCESS if either current or saved queue headers are found. * Appropriate error code otherwise. * * Side effects: * May block. * *----------------------------------------------------------------------------- */ static int VMCIQPairGetQueueHeaders(const VMCIQPair *qpair, // IN VMCIQueueHeader **produceQHeader, // OUT VMCIQueueHeader **consumeQHeader) // OUT { int result; result = VMCIQPairMapQueueHeaders(qpair->produceQ, qpair->consumeQ, !(qpair->flags & VMCI_QPFLAG_NONBLOCK)); if (result == VMCI_SUCCESS) { *produceQHeader = qpair->produceQ->qHeader; *consumeQHeader = qpair->consumeQ->qHeader; } else if (qpair->produceQ->savedHeader && qpair->consumeQ->savedHeader) { ASSERT(!qpair->guestEndpoint); *produceQHeader = qpair->produceQ->savedHeader; *consumeQHeader = qpair->consumeQ->savedHeader; result = VMCI_SUCCESS; } return result; } /* *----------------------------------------------------------------------------- * * VMCIQPairMapQueueHeaders -- * * The queue headers may not be mapped at all times. If a queue is * currently not mapped, it will be attempted to do so. * * Results: * VMCI_SUCCESS if queues were validated, appropriate error code otherwise. * * Side effects: * May attempt to map in guest memory. * *----------------------------------------------------------------------------- */ static int VMCIQPairMapQueueHeaders(VMCIQueue *produceQ, // IN VMCIQueue *consumeQ, // IN Bool canBlock) // IN { int result; if (NULL == produceQ->qHeader || NULL == consumeQ->qHeader) { if (canBlock) { /* * We return data from creator of the queue in VM2VM case. * That should be OK, as if they do not match then there * is somebody else in progress of making them match, and * you should not be looking at somebody else's queue if * queue is active. */ result = VMCIHost_MapQueues(0, produceQ, consumeQ, 0); } else { result = VMCI_ERROR_QUEUEPAIR_NOT_READY; } if (result < VMCI_SUCCESS) { if (produceQ->savedHeader && consumeQ->savedHeader) { return VMCI_ERROR_QUEUEPAIR_NOT_READY; } else { return VMCI_ERROR_QUEUEPAIR_NOTATTACHED; } } } return VMCI_SUCCESS; } /* *----------------------------------------------------------------------------- * * VMCIQPairWakeupCB -- * * Callback from VMCI queue pair broker indicating that a queue * pair that was previously not ready, now either is ready or * gone forever. * * Results: * VMCI_SUCCESS always. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int VMCIQPairWakeupCB(void *clientData) { VMCIQPair *qpair = (VMCIQPair *)clientData; ASSERT(qpair); VMCIQPairLock(qpair); while (qpair->blocked > 0) { qpair->blocked--; VMCI_SignalEvent(&qpair->event); } VMCIQPairUnlock(qpair); return VMCI_SUCCESS; } /* *----------------------------------------------------------------------------- * * VMCIQPairReleaseMutexCB -- * * Callback from VMCI_WaitOnEvent releasing the queue pair mutex * protecting the queue pair header state. * * Results: * 0 always. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int VMCIQPairReleaseMutexCB(void *clientData) { VMCIQPair *qpair = (VMCIQPair *)clientData; ASSERT(qpair); VMCIQPairUnlock(qpair); return 0; } /* *----------------------------------------------------------------------------- * * VMCIQPairWaitForReadyQueue -- * * Makes the calling thread wait for the queue pair to become * ready for host side access. * * Results: * TRUE when thread is woken up after queue pair state change. * FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool VMCIQPairWaitForReadyQueue(VMCIQPair *qpair) { if (UNLIKELY(qpair->guestEndpoint)) { ASSERT(FALSE); return FALSE; } if (qpair->flags & VMCI_QPFLAG_NONBLOCK) { return FALSE; } qpair->blocked++; VMCI_WaitOnEvent(&qpair->event, VMCIQPairReleaseMutexCB, qpair); VMCIQPairLock(qpair); return TRUE; } /* *----------------------------------------------------------------------------- * * vmci_qpair_alloc -- * * This is the client interface for allocating the memory for a * VMCIQPair structure and then attaching to the underlying * queue. If an error occurs allocating the memory for the * VMCIQPair structure, no attempt is made to attach. If an * error occurs attaching, then there's the VMCIQPair structure * is freed. * * Results: * An err, if < 0. * * Side effects: * Windows blocking call. * *----------------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_qpair_alloc) int vmci_qpair_alloc(VMCIQPair **qpair, // OUT VMCIHandle *handle, // OUT uint64 produceQSize, // IN uint64 consumeQSize, // IN VMCIId peer, // IN uint32 flags, // IN VMCIPrivilegeFlags privFlags) // IN { VMCIQPair *myQPair; int retval; VMCIHandle src = VMCI_INVALID_HANDLE; VMCIHandle dst = VMCI_MAKE_HANDLE(peer, VMCI_INVALID_ID); VMCIRoute route; VMCIEventReleaseCB wakeupCB; void *clientData; /* * Restrict the size of a queuepair. The device already enforces a limit * on the total amount of memory that can be allocated to queuepairs for a * guest. However, we try to allocate this memory before we make the * queuepair allocation hypercall. On Windows and Mac OS, we request a * single, continguous block, and it will fail if the OS cannot satisfy the * request. On Linux, we allocate each page separately, which means rather * than fail, the guest will thrash while it tries to allocate, and will * become increasingly unresponsive to the point where it appears to be hung. * So we place a limit on the size of an individual queuepair here, and * leave the device to enforce the restriction on total queuepair memory. * (Note that this doesn't prevent all cases; a user with only this much * physical memory could still get into trouble.) The error used by the * device is NO_RESOURCES, so use that here too. */ if (produceQSize + consumeQSize < MAX(produceQSize, consumeQSize) || produceQSize + consumeQSize > VMCI_MAX_GUEST_QP_MEMORY) { return VMCI_ERROR_NO_RESOURCES; } retval = VMCI_Route(&src, &dst, FALSE, &route); if (retval < VMCI_SUCCESS) { if (VMCI_GuestPersonalityActive()) { route = VMCI_ROUTE_AS_GUEST; } else { route = VMCI_ROUTE_AS_HOST; } } if ((flags & (VMCI_QPFLAG_NONBLOCK | VMCI_QPFLAG_PINNED)) && !vmkernel) { #if defined(linux) if (VMCI_ROUTE_AS_GUEST != route) #endif // linux { return VMCI_ERROR_INVALID_ARGS; } } if (flags & VMCI_QPFLAG_PINNED) { /* * Pinned pages implies non-blocking mode. Technically it doesn't * have to, but there doesn't seem much point in pinning the pages if you * can block since the queues will be small, so there's no performance * gain to be had. */ if (!(flags & VMCI_QPFLAG_NONBLOCK)) { return VMCI_ERROR_INVALID_ARGS; } /* Limit the amount of memory that can be pinned. */ if (produceQSize + consumeQSize > VMCI_MAX_PINNED_QP_MEMORY) { return VMCI_ERROR_NO_RESOURCES; } } myQPair = VMCI_AllocKernelMem(sizeof *myQPair, VMCI_MEMORY_NONPAGED); if (!myQPair) { return VMCI_ERROR_NO_MEM; } myQPair->produceQSize = produceQSize; myQPair->consumeQSize = consumeQSize; myQPair->peer = peer; myQPair->flags = flags; myQPair->privFlags = privFlags; wakeupCB = clientData = NULL; if (VMCI_ROUTE_AS_HOST == route) { myQPair->guestEndpoint = FALSE; if (!(flags & VMCI_QPFLAG_LOCAL)) { myQPair->blocked = 0; VMCI_CreateEvent(&myQPair->event); wakeupCB = VMCIQPairWakeupCB; clientData = (void *)myQPair; } } else { myQPair->guestEndpoint = TRUE; } retval = VMCIQueuePair_Alloc(handle, &myQPair->produceQ, myQPair->produceQSize, &myQPair->consumeQ, myQPair->consumeQSize, myQPair->peer, myQPair->flags, myQPair->privFlags, myQPair->guestEndpoint, wakeupCB, clientData); if (retval < VMCI_SUCCESS) { if (VMCI_ROUTE_AS_HOST == route && !(flags & VMCI_QPFLAG_LOCAL)) { VMCI_DestroyEvent(&myQPair->event); } VMCI_FreeKernelMem(myQPair, sizeof *myQPair); return retval; } *qpair = myQPair; myQPair->handle = *handle; return retval; } /* *----------------------------------------------------------------------------- * * vmci_qpair_detach -- * * This is the client interface for detaching from a VMCIQPair. * Note that this routine will free the memory allocated for the * VMCIQPair structure, too. * * Results: * An error, if < 0. * * Side effects: * Will clear the caller's pointer to the VMCIQPair structure. * *----------------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_qpair_detach) int vmci_qpair_detach(VMCIQPair **qpair) // IN/OUT { int result; VMCIQPair *oldQPair; if (!qpair || !(*qpair)) { return VMCI_ERROR_INVALID_ARGS; } oldQPair = *qpair; result = VMCIQueuePair_Detach(oldQPair->handle, oldQPair->guestEndpoint); /* * The guest can fail to detach for a number of reasons, and if it does so, * it will cleanup the entry (if there is one). The host can fail too, but * it won't cleanup the entry immediately, it will do that later when the * context is freed. Either way, we need to release the qpair struct here; * there isn't much the caller can do, and we don't want to leak. */ if (!(oldQPair->guestEndpoint || (oldQPair->flags & VMCI_QPFLAG_LOCAL))) { VMCI_DestroyEvent(&oldQPair->event); } VMCI_FreeKernelMem(oldQPair, sizeof *oldQPair); *qpair = NULL; return result; } /* *----------------------------------------------------------------------------- * * vmci_qpair_get_produce_indexes -- * * This is the client interface for getting the current indexes of the * QPair from the point of the view of the caller as the producer. * * Results: * err, if < 0 * Success otherwise. * * Side effects: * Windows blocking call. * *----------------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_qpair_get_produce_indexes) int vmci_qpair_get_produce_indexes(const VMCIQPair *qpair, // IN uint64 *producerTail, // OUT uint64 *consumerHead) // OUT { VMCIQueueHeader *produceQHeader; VMCIQueueHeader *consumeQHeader; int result; if (!qpair) { return VMCI_ERROR_INVALID_ARGS; } VMCIQPairLockHeader(qpair); result = VMCIQPairGetQueueHeaders(qpair, &produceQHeader, &consumeQHeader); if (result == VMCI_SUCCESS) { VMCIQueueHeader_GetPointers(produceQHeader, consumeQHeader, producerTail, consumerHead); } VMCIQPairUnlockHeader(qpair); if (result == VMCI_SUCCESS && ((producerTail && *producerTail >= qpair->produceQSize) || (consumerHead && *consumerHead >= qpair->produceQSize))) { return VMCI_ERROR_INVALID_SIZE; } return result; } /* *----------------------------------------------------------------------------- * * vmci_qpair_get_consume_indexes -- * * This is the client interface for getting the current indexes of the * QPair from the point of the view of the caller as the consumer. * * Results: * err, if < 0 * Success otherwise. * * Side effects: * Windows blocking call. * *----------------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_qpair_get_consume_indexes) int vmci_qpair_get_consume_indexes(const VMCIQPair *qpair, // IN uint64 *consumerTail, // OUT uint64 *producerHead) // OUT { VMCIQueueHeader *produceQHeader; VMCIQueueHeader *consumeQHeader; int result; if (!qpair) { return VMCI_ERROR_INVALID_ARGS; } VMCIQPairLockHeader(qpair); result = VMCIQPairGetQueueHeaders(qpair, &produceQHeader, &consumeQHeader); if (result == VMCI_SUCCESS) { VMCIQueueHeader_GetPointers(consumeQHeader, produceQHeader, consumerTail, producerHead); } VMCIQPairUnlockHeader(qpair); if (result == VMCI_SUCCESS && ((consumerTail && *consumerTail >= qpair->consumeQSize) || (producerHead && *producerHead >= qpair->consumeQSize))) { return VMCI_ERROR_INVALID_SIZE; } return result; } /* *----------------------------------------------------------------------------- * * vmci_qpair_produce_free_space -- * * This is the client interface for getting the amount of free * space in the QPair from the point of the view of the caller as * the producer which is the common case. * * Results: * Err, if < 0. * Full queue if = 0. * Number of available bytes into which data can be enqueued if > 0. * * Side effects: * Windows blocking call. * *----------------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_qpair_produce_free_space) int64 vmci_qpair_produce_free_space(const VMCIQPair *qpair) // IN { VMCIQueueHeader *produceQHeader; VMCIQueueHeader *consumeQHeader; int64 result; if (!qpair) { return VMCI_ERROR_INVALID_ARGS; } VMCIQPairLockHeader(qpair); result = VMCIQPairGetQueueHeaders(qpair, &produceQHeader, &consumeQHeader); if (result == VMCI_SUCCESS) { result = VMCIQueueHeader_FreeSpace(produceQHeader, consumeQHeader, qpair->produceQSize); } else { result = 0; } VMCIQPairUnlockHeader(qpair); return result; } /* *----------------------------------------------------------------------------- * * vmci_qpair_consume_free_space -- * * This is the client interface for getting the amount of free * space in the QPair from the point of the view of the caller as * the consumer which is not the common case (see * VMCIQPair_ProduceFreeSpace(), above). * * Results: * Err, if < 0. * Full queue if = 0. * Number of available bytes into which data can be enqueued if > 0. * * Side effects: * Windows blocking call. * *----------------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_qpair_consume_free_space) int64 vmci_qpair_consume_free_space(const VMCIQPair *qpair) // IN { VMCIQueueHeader *produceQHeader; VMCIQueueHeader *consumeQHeader; int64 result; if (!qpair) { return VMCI_ERROR_INVALID_ARGS; } VMCIQPairLockHeader(qpair); result = VMCIQPairGetQueueHeaders(qpair, &produceQHeader, &consumeQHeader); if (result == VMCI_SUCCESS) { result = VMCIQueueHeader_FreeSpace(consumeQHeader, produceQHeader, qpair->consumeQSize); } else { result = 0; } VMCIQPairUnlockHeader(qpair); return result; } /* *----------------------------------------------------------------------------- * * vmci_qpair_produce_buf_ready -- * * This is the client interface for getting the amount of * enqueued data in the QPair from the point of the view of the * caller as the producer which is not the common case (see * VMCIQPair_ConsumeBufReady(), above). * * Results: * Err, if < 0. * Empty queue if = 0. * Number of bytes ready to be dequeued if > 0. * * Side effects: * Windows blocking call. * *----------------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_qpair_produce_buf_ready) int64 vmci_qpair_produce_buf_ready(const VMCIQPair *qpair) // IN { VMCIQueueHeader *produceQHeader; VMCIQueueHeader *consumeQHeader; int64 result; if (!qpair) { return VMCI_ERROR_INVALID_ARGS; } VMCIQPairLockHeader(qpair); result = VMCIQPairGetQueueHeaders(qpair, &produceQHeader, &consumeQHeader); if (result == VMCI_SUCCESS) { result = VMCIQueueHeader_BufReady(produceQHeader, consumeQHeader, qpair->produceQSize); } else { result = 0; } VMCIQPairUnlockHeader(qpair); return result; } /* *----------------------------------------------------------------------------- * * vmci_qpair_consume_buf_ready -- * * This is the client interface for getting the amount of * enqueued data in the QPair from the point of the view of the * caller as the consumer which is the normal case. * * Results: * Err, if < 0. * Empty queue if = 0. * Number of bytes ready to be dequeued if > 0. * * Side effects: * Windows blocking call. * *----------------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_qpair_consume_buf_ready) int64 vmci_qpair_consume_buf_ready(const VMCIQPair *qpair) // IN { VMCIQueueHeader *produceQHeader; VMCIQueueHeader *consumeQHeader; int64 result; if (!qpair) { return VMCI_ERROR_INVALID_ARGS; } VMCIQPairLockHeader(qpair); result = VMCIQPairGetQueueHeaders(qpair, &produceQHeader, &consumeQHeader); if (result == VMCI_SUCCESS) { result = VMCIQueueHeader_BufReady(consumeQHeader, produceQHeader, qpair->consumeQSize); } else { result = 0; } VMCIQPairUnlockHeader(qpair); return result; } /* *----------------------------------------------------------------------------- * * EnqueueLocked -- * * Enqueues a given buffer to the produce queue using the provided * function. As many bytes as possible (space available in the queue) * are enqueued. * * Assumes the queue->mutex has been acquired. * * Results: * VMCI_ERROR_QUEUEPAIR_NOSPACE if no space was available to enqueue data. * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue * (as defined by the queue size). * VMCI_ERROR_INVALID_ARGS, if an error occured when accessing the buffer. * VMCI_ERROR_QUEUEPAIR_NOTATTACHED, if the queue pair pages aren't * available. * Otherwise, the number of bytes written to the queue is returned. * * Side effects: * Updates the tail pointer of the produce queue. * *----------------------------------------------------------------------------- */ static ssize_t EnqueueLocked(VMCIQueue *produceQ, // IN VMCIQueue *consumeQ, // IN const uint64 produceQSize, // IN const void *buf, // IN size_t bufSize, // IN int bufType, // IN VMCIMemcpyToQueueFunc memcpyToQueue, // IN Bool canBlock) // IN { int64 freeSpace; uint64 tail; size_t written; ssize_t result; #if !defined VMX86_VMX if (UNLIKELY(VMCI_EnqueueToDevNull(produceQ))) { return (ssize_t) bufSize; } result = VMCIQPairMapQueueHeaders(produceQ, consumeQ, canBlock); if (UNLIKELY(result != VMCI_SUCCESS)) { return result; } #endif freeSpace = VMCIQueueHeader_FreeSpace(produceQ->qHeader, consumeQ->qHeader, produceQSize); if (freeSpace == 0) { return VMCI_ERROR_QUEUEPAIR_NOSPACE; } if (freeSpace < VMCI_SUCCESS) { return (ssize_t)freeSpace; } written = (size_t)(freeSpace > bufSize ? bufSize : freeSpace); tail = VMCIQueueHeader_ProducerTail(produceQ->qHeader); if (LIKELY(tail + written < produceQSize)) { result = memcpyToQueue(produceQ, tail, buf, 0, written, bufType, canBlock); } else { /* Tail pointer wraps around. */ const size_t tmp = (size_t)(produceQSize - tail); result = memcpyToQueue(produceQ, tail, buf, 0, tmp, bufType, canBlock); if (result >= VMCI_SUCCESS) { result = memcpyToQueue(produceQ, 0, buf, tmp, written - tmp, bufType, canBlock); } } if (result < VMCI_SUCCESS) { return result; } VMCIQueueHeader_AddProducerTail(produceQ->qHeader, written, produceQSize); return written; } /* *----------------------------------------------------------------------------- * * DequeueLocked -- * * Dequeues data (if available) from the given consume queue. Writes data * to the user provided buffer using the provided function. * * Assumes the queue->mutex has been acquired. * * Results: * VMCI_ERROR_QUEUEPAIR_NODATA if no data was available to dequeue. * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue * (as defined by the queue size). * VMCI_ERROR_INVALID_ARGS, if an error occured when accessing the buffer. * Otherwise the number of bytes dequeued is returned. * * Side effects: * Updates the head pointer of the consume queue. * *----------------------------------------------------------------------------- */ static ssize_t DequeueLocked(VMCIQueue *produceQ, // IN VMCIQueue *consumeQ, // IN const uint64 consumeQSize, // IN void *buf, // IN size_t bufSize, // IN int bufType, // IN VMCIMemcpyFromQueueFunc memcpyFromQueue, // IN Bool updateConsumer, // IN Bool canBlock) // IN { int64 bufReady; uint64 head; size_t read; ssize_t result; #if !defined VMX86_VMX result = VMCIQPairMapQueueHeaders(produceQ, consumeQ, canBlock); if (UNLIKELY(result != VMCI_SUCCESS)) { return result; } #endif bufReady = VMCIQueueHeader_BufReady(consumeQ->qHeader, produceQ->qHeader, consumeQSize); if (bufReady == 0) { return VMCI_ERROR_QUEUEPAIR_NODATA; } if (bufReady < VMCI_SUCCESS) { return (ssize_t)bufReady; } read = (size_t)(bufReady > bufSize ? bufSize : bufReady); head = VMCIQueueHeader_ConsumerHead(produceQ->qHeader); if (LIKELY(head + read < consumeQSize)) { result = memcpyFromQueue(buf, 0, consumeQ, head, read, bufType, canBlock); } else { /* Head pointer wraps around. */ const size_t tmp = (size_t)(consumeQSize - head); result = memcpyFromQueue(buf, 0, consumeQ, head, tmp, bufType, canBlock); if (result >= VMCI_SUCCESS) { result = memcpyFromQueue(buf, tmp, consumeQ, 0, read - tmp, bufType, canBlock); } } if (result < VMCI_SUCCESS) { return result; } if (updateConsumer) { VMCIQueueHeader_AddConsumerHead(produceQ->qHeader, read, consumeQSize); } return read; } /* *----------------------------------------------------------------------------- * * vmci_qpair_enqueue -- * * This is the client interface for enqueueing data into the queue. * * Results: * Err, if < 0. * Number of bytes enqueued if >= 0. * * Side effects: * Windows blocking call. * *----------------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_qpair_enqueue) ssize_t vmci_qpair_enqueue(VMCIQPair *qpair, // IN const void *buf, // IN size_t bufSize, // IN int bufType) // IN { ssize_t result; if (!qpair || !buf) { return VMCI_ERROR_INVALID_ARGS; } result = VMCIQPairLock(qpair); if (result != VMCI_SUCCESS) { return result; } do { result = EnqueueLocked(qpair->produceQ, qpair->consumeQ, qpair->produceQSize, buf, bufSize, bufType, qpair->flags & VMCI_QPFLAG_LOCAL? VMCIMemcpyToQueueLocal: VMCIMemcpyToQueue, !(qpair->flags & VMCI_QPFLAG_NONBLOCK)); if (result == VMCI_ERROR_QUEUEPAIR_NOT_READY) { if (!VMCIQPairWaitForReadyQueue(qpair)) { result = VMCI_ERROR_WOULD_BLOCK; } } } while (result == VMCI_ERROR_QUEUEPAIR_NOT_READY); VMCIQPairUnlock(qpair); return result; } /* *----------------------------------------------------------------------------- * * vmci_qpair_dequeue -- * * This is the client interface for dequeueing data from the queue. * * Results: * Err, if < 0. * Number of bytes dequeued if >= 0. * * Side effects: * Windows blocking call. * *----------------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_qpair_dequeue) ssize_t vmci_qpair_dequeue(VMCIQPair *qpair, // IN void *buf, // IN size_t bufSize, // IN int bufType) // IN { ssize_t result; if (!qpair || !buf) { return VMCI_ERROR_INVALID_ARGS; } result = VMCIQPairLock(qpair); if (result != VMCI_SUCCESS) { return result; } do { result = DequeueLocked(qpair->produceQ, qpair->consumeQ, qpair->consumeQSize, buf, bufSize, bufType, qpair->flags & VMCI_QPFLAG_LOCAL? VMCIMemcpyFromQueueLocal: VMCIMemcpyFromQueue, TRUE, !(qpair->flags & VMCI_QPFLAG_NONBLOCK)); if (result == VMCI_ERROR_QUEUEPAIR_NOT_READY) { if (!VMCIQPairWaitForReadyQueue(qpair)) { result = VMCI_ERROR_WOULD_BLOCK; } } } while (result == VMCI_ERROR_QUEUEPAIR_NOT_READY); VMCIQPairUnlock(qpair); return result; } /* *----------------------------------------------------------------------------- * * vmci_qpair_peek -- * * This is the client interface for peeking into a queue. (I.e., * copy data from the queue without updating the head pointer.) * * Results: * Err, if < 0. * Number of bytes peeked, if >= 0. * * Side effects: * Windows blocking call. * *----------------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_qpair_peek) ssize_t vmci_qpair_peek(VMCIQPair *qpair, // IN void *buf, // IN size_t bufSize, // IN int bufType) // IN { ssize_t result; if (!qpair || !buf) { return VMCI_ERROR_INVALID_ARGS; } result = VMCIQPairLock(qpair); if (result != VMCI_SUCCESS) { return result; } do { result = DequeueLocked(qpair->produceQ, qpair->consumeQ, qpair->consumeQSize, buf, bufSize, bufType, qpair->flags & VMCI_QPFLAG_LOCAL? VMCIMemcpyFromQueueLocal: VMCIMemcpyFromQueue, FALSE, !(qpair->flags & VMCI_QPFLAG_NONBLOCK)); if (result == VMCI_ERROR_QUEUEPAIR_NOT_READY) { if (!VMCIQPairWaitForReadyQueue(qpair)) { result = VMCI_ERROR_WOULD_BLOCK; } } } while (result == VMCI_ERROR_QUEUEPAIR_NOT_READY); VMCIQPairUnlock(qpair); return result; } #if defined (SOLARIS) || (defined(__APPLE__) && !defined (VMX86_TOOLS)) || \ (defined(__linux__) && defined(__KERNEL__)) || \ (defined(_WIN32) && defined(WINNT_DDK)) /* *----------------------------------------------------------------------------- * * vmci_qpair_enquev -- * * This is the client interface for enqueueing data into the queue. * * Results: * Err, if < 0. * Number of bytes enqueued if >= 0. * * Side effects: * Windows blocking call. * *----------------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_qpair_enquev) ssize_t vmci_qpair_enquev(VMCIQPair *qpair, // IN void *iov, // IN size_t iovSize, // IN int bufType) // IN { ssize_t result; if (!qpair || !iov) { return VMCI_ERROR_INVALID_ARGS; } result = VMCIQPairLock(qpair); if (result != VMCI_SUCCESS) { return result; } do { result = EnqueueLocked(qpair->produceQ, qpair->consumeQ, qpair->produceQSize, iov, iovSize, bufType, qpair->flags & VMCI_QPFLAG_LOCAL? VMCIMemcpyToQueueVLocal: VMCIMemcpyToQueueV, !(qpair->flags & VMCI_QPFLAG_NONBLOCK)); if (result == VMCI_ERROR_QUEUEPAIR_NOT_READY) { if (!VMCIQPairWaitForReadyQueue(qpair)) { result = VMCI_ERROR_WOULD_BLOCK; } } } while (result == VMCI_ERROR_QUEUEPAIR_NOT_READY); VMCIQPairUnlock(qpair); return result; } /* *----------------------------------------------------------------------------- * * vmci_qpair_dequev -- * * This is the client interface for dequeueing data from the queue. * * Results: * Err, if < 0. * Number of bytes dequeued if >= 0. * * Side effects: * Windows blocking call. * *----------------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_qpair_dequev) ssize_t vmci_qpair_dequev(VMCIQPair *qpair, // IN void *iov, // IN size_t iovSize, // IN int bufType) // IN { ssize_t result; if (!qpair || !iov) { return VMCI_ERROR_INVALID_ARGS; } result = VMCIQPairLock(qpair); if (result != VMCI_SUCCESS) { return result; } do { result = DequeueLocked(qpair->produceQ, qpair->consumeQ, qpair->consumeQSize, iov, iovSize, bufType, qpair->flags & VMCI_QPFLAG_LOCAL? VMCIMemcpyFromQueueVLocal: VMCIMemcpyFromQueueV, TRUE, !(qpair->flags & VMCI_QPFLAG_NONBLOCK)); if (result == VMCI_ERROR_QUEUEPAIR_NOT_READY) { if (!VMCIQPairWaitForReadyQueue(qpair)) { result = VMCI_ERROR_WOULD_BLOCK; } } } while (result == VMCI_ERROR_QUEUEPAIR_NOT_READY); VMCIQPairUnlock(qpair); return result; } /* *----------------------------------------------------------------------------- * * vmci_qpair_peekv -- * * This is the client interface for peeking into a queue. (I.e., * copy data from the queue without updating the head pointer.) * * Results: * Err, if < 0. * Number of bytes peeked, if >= 0. * * Side effects: * Windows blocking call. * *----------------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_qpair_peekv) ssize_t vmci_qpair_peekv(VMCIQPair *qpair, // IN void *iov, // IN size_t iovSize, // IN int bufType) // IN { ssize_t result; if (!qpair || !iov) { return VMCI_ERROR_INVALID_ARGS; } result = VMCIQPairLock(qpair); if (result != VMCI_SUCCESS) { return result; } do { result = DequeueLocked(qpair->produceQ, qpair->consumeQ, qpair->consumeQSize, iov, iovSize, bufType, qpair->flags & VMCI_QPFLAG_LOCAL? VMCIMemcpyFromQueueVLocal: VMCIMemcpyFromQueueV, FALSE, !(qpair->flags & VMCI_QPFLAG_NONBLOCK)); if (result == VMCI_ERROR_QUEUEPAIR_NOT_READY) { if (!VMCIQPairWaitForReadyQueue(qpair)) { result = VMCI_ERROR_WOULD_BLOCK; } } } while (result == VMCI_ERROR_QUEUEPAIR_NOT_READY); VMCIQPairUnlock(qpair); return result; } #endif /* Systems that support struct iovec */ open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciQueuePair.h0000644765153500003110000000722512220061556023432 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciQueuePair.h -- * * VMCI QueuePair API implementation in the host driver. */ #ifndef _VMCI_QUEUE_PAIR_H_ #define _VMCI_QUEUE_PAIR_H_ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vmci_defs.h" #include "vmci_iocontrols.h" #include "vmci_kernel_if.h" #include "vmciContext.h" #include "vmciQueue.h" /* * QueuePairPageStore describes how the memory of a given queue pair * is backed. When the queue pair is between the host and a guest, the * page store consists of references to the guest pages. On vmkernel, * this is a list of PPNs, and on hosted, it is a user VA where the * queue pair is mapped into the VMX address space. */ typedef struct QueuePairPageStore { VMCIQPGuestMem pages; // Reference to pages backing the queue pair. uint32 len; // Length of pageList/virtual addres range (in pages). } QueuePairPageStore; /* *------------------------------------------------------------------------------ * * VMCI_QP_PAGESTORE_IS_WELLFORMED -- * * Utility function that checks whether the fields of the page * store contain valid values. * * Result: * TRUE if the page store is wellformed. FALSE otherwise. * * Side effects: * None. * *------------------------------------------------------------------------------ */ static INLINE Bool VMCI_QP_PAGESTORE_IS_WELLFORMED(QueuePairPageStore *pageStore) // IN { return pageStore->len >= 2; } int VMCIQPBroker_Init(void); void VMCIQPBroker_Exit(void); int VMCIQPBroker_Alloc(VMCIHandle handle, VMCIId peer, uint32 flags, VMCIPrivilegeFlags privFlags, uint64 produceSize, uint64 consumeSize, QueuePairPageStore *pageStore, VMCIContext *context); int VMCIQPBroker_SetPageStore(VMCIHandle handle, VA64 produceUVA, VA64 consumeUVA, VMCIContext *context); int VMCIQPBroker_Detach(VMCIHandle handle, VMCIContext *context); int VMCIQPGuestEndpoints_Init(void); void VMCIQPGuestEndpoints_Exit(void); void VMCIQPGuestEndpoints_Sync(void); void VMCIQPGuestEndpoints_Convert(Bool toLocal, Bool deviceReset); int VMCIQueuePair_Alloc(VMCIHandle *handle, VMCIQueue **produceQ, uint64 produceSize, VMCIQueue **consumeQ, uint64 consumeSize, VMCIId peer, uint32 flags, VMCIPrivilegeFlags privFlags, Bool guestEndpoint, VMCIEventReleaseCB wakeupCB, void *clientData); int VMCIQueuePair_Detach(VMCIHandle handle, Bool guestEndpoint); int VMCIQPBroker_Map(VMCIHandle handle, VMCIContext *context, VMCIQPGuestMem guestMem); int VMCIQPBroker_Unmap(VMCIHandle handle, VMCIContext *context, VMCIGuestMemID gid); #endif /* !_VMCI_QUEUE_PAIR_H_ */ open-vm-tools-9.4.0-1280544/modules/linux/vmci/common/vmciDriver.c0000644765153500003110000004433512220061556022763 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciDriver.c -- * * VMCI initialization and ioctl handling. */ #include "vmci_kernel_if.h" #include "vm_assert.h" #include "vmci_defs.h" #include "vmci_infrastructure.h" #include "vmciCommonInt.h" #include "vmciContext.h" #include "vmciDatagram.h" #include "vmciDoorbell.h" #include "vmciDriver.h" #include "vmciEvent.h" #include "vmciHashtable.h" #include "vmciKernelAPI.h" #include "vmciQueuePair.h" #include "vmciResource.h" #if defined(VMKERNEL) # include "vmciVmkInt.h" # include "vm_libc.h" # include "helper_ext.h" #endif #define LGPFX "VMCI: " static VMCIId ctxUpdateSubID = VMCI_INVALID_ID; static VMCIContext *hostContext; static Atomic_uint32 vmContextID = { VMCI_INVALID_ID }; /* *---------------------------------------------------------------------- * * VMCI_HostInit -- * * Initializes the host driver specific components of VMCI. * * Results: * VMCI_SUCCESS if successful, appropriate error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCI_HostInit(void) { int result; /* * In theory, it is unsafe to pass an eventHnd of -1 to platforms which use * it (VMKernel/Windows/Mac OS at the time of this writing). In practice we * are fine though, because the event is never used in the case of the host * context. */ result = VMCIContext_InitContext(VMCI_HOST_CONTEXT_ID, VMCI_DEFAULT_PROC_PRIVILEGE_FLAGS, -1, VMCI_VERSION, NULL, &hostContext); if (result < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to initialize VMCIContext (result=%d).\n", result)); goto errorExit; } result = VMCIQPBroker_Init(); if (result < VMCI_SUCCESS) { goto hostContextExit; } VMCI_DEBUG_LOG(0, (LGPFX"host components initialized.\n")); return VMCI_SUCCESS; hostContextExit: VMCIContext_ReleaseContext(hostContext); errorExit: return result; } /* *---------------------------------------------------------------------- * * VMCI_HostCleanup -- * * Cleans up the host specific components of the VMCI module. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void VMCI_HostCleanup(void) { VMCIContext_ReleaseContext(hostContext); VMCIQPBroker_Exit(); } #if defined(__APPLE__) || defined(SOLARIS) || defined(VMKERNEL) /* Windows has its own implementation of this, and Linux doesn't need one. */ /* *---------------------------------------------------------------------- * * vmci_device_get -- * * Verifies that a valid VMCI device is present, and indicates * the callers intention to use the device until it calls * VMCI_DeviceRelease(). * * Results: * TRUE if a valid VMCI device is present, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_device_get) Bool vmci_device_get(uint32 *apiVersion, // IN/OUT VMCI_DeviceShutdownFn *deviceShutdownCB, // UNUSED void *userData, // UNUSED void **deviceRegistration) // OUT { if (NULL != deviceRegistration) { *deviceRegistration = NULL; } if (*apiVersion > VMCI_KERNEL_API_VERSION) { *apiVersion = VMCI_KERNEL_API_VERSION; return FALSE; } if (!VMCI_DeviceEnabled()) { return FALSE; } return TRUE; } /* *---------------------------------------------------------------------- * * vmci_device_release -- * * Indicates that the caller is done using the VMCI device. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_device_release) void vmci_device_release(void *deviceRegistration) // UNUSED { } #endif // __APPLE__ || SOLARIS || VMKERNEL /* *----------------------------------------------------------------------------- * * VMCIUtilCidUpdate -- * * Gets called with the new context id if updated or resumed. * * Results: * Context id. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VMCIUtilCidUpdate(VMCIId subID, // IN: VMCI_EventData *eventData, // IN: void *clientData) // IN: { VMCIEventPayload_Context *evPayload = VMCIEventDataPayload(eventData); if (subID != ctxUpdateSubID) { VMCI_DEBUG_LOG(4, (LGPFX"Invalid subscriber (ID=0x%x).\n", subID)); return; } if (eventData == NULL || evPayload->contextID == VMCI_INVALID_ID) { VMCI_DEBUG_LOG(4, (LGPFX"Invalid event data.\n")); return; } VMCI_LOG((LGPFX"Updating context from (ID=0x%x) to (ID=0x%x) on event " "(type=%d).\n", Atomic_Read(&vmContextID), evPayload->contextID, eventData->event)); Atomic_Write(&vmContextID, evPayload->contextID); } /* *----------------------------------------------------------------------------- * * VMCIUtil_Init -- * * Subscribe to context id update event. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMCIUtil_Init(void) { /* * We subscribe to the VMCI_EVENT_CTX_ID_UPDATE here so we can update the * internal context id when needed. */ if (vmci_event_subscribe(VMCI_EVENT_CTX_ID_UPDATE, #if !defined(linux) || defined(VMKERNEL) VMCI_FLAG_EVENT_NONE, #endif // !linux || VMKERNEL VMCIUtilCidUpdate, NULL, &ctxUpdateSubID) < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to subscribe to event (type=%d).\n", VMCI_EVENT_CTX_ID_UPDATE)); } } /* *----------------------------------------------------------------------------- * * VMCIUtil_Exit -- * * Cleanup * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMCIUtil_Exit(void) { if (vmci_event_unsubscribe(ctxUpdateSubID) < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to unsubscribe to event (type=%d) with " "subscriber (ID=0x%x).\n", VMCI_EVENT_CTX_ID_UPDATE, ctxUpdateSubID)); } } /* *----------------------------------------------------------------------------- * * VMCIUtil_CheckHostCapabilities -- * * Verify that the host supports the hypercalls we need. If it does not, * try to find fallback hypercalls and use those instead. * * Results: * TRUE if required hypercalls (or fallback hypercalls) are * supported by the host, FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ #define VMCI_UTIL_NUM_RESOURCES 1 static Bool VMCIUtilCheckHostCapabilities(void) { int result; VMCIResourcesQueryMsg *msg; uint32 msgSize = sizeof(VMCIResourcesQueryHdr) + VMCI_UTIL_NUM_RESOURCES * sizeof(VMCI_Resource); VMCIDatagram *checkMsg = VMCI_AllocKernelMem(msgSize, VMCI_MEMORY_NONPAGED); if (checkMsg == NULL) { VMCI_WARNING((LGPFX"Check host: Insufficient memory.\n")); return FALSE; } checkMsg->dst = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_RESOURCES_QUERY); checkMsg->src = VMCI_ANON_SRC_HANDLE; checkMsg->payloadSize = msgSize - VMCI_DG_HEADERSIZE; msg = (VMCIResourcesQueryMsg *)VMCI_DG_PAYLOAD(checkMsg); msg->numResources = VMCI_UTIL_NUM_RESOURCES; msg->resources[0] = VMCI_GET_CONTEXT_ID; result = VMCI_SendDatagram(checkMsg); VMCI_FreeKernelMem(checkMsg, msgSize); /* We need the vector. There are no fallbacks. */ return (result == 0x1); } /* *----------------------------------------------------------------------------- * * VMCI_CheckHostCapabilities -- * * Tell host which guestcalls we support and let each API check * that the host supports the hypercalls it needs. If a hypercall * is not supported, the API can check for a fallback hypercall, * or fail the check. * * Results: * TRUE if successful, FALSE otherwise. * * Side effects: * Fallback mechanisms may be enabled in the API and vmmon. * *----------------------------------------------------------------------------- */ Bool VMCI_CheckHostCapabilities(void) { Bool result = VMCIEvent_CheckHostCapabilities(); result &= VMCIDatagram_CheckHostCapabilities(); result &= VMCIUtilCheckHostCapabilities(); if (!result) { /* If it failed, then make sure this goes to the system event log. */ VMCI_WARNING((LGPFX"Host capability checked failed.\n")); } else { VMCI_DEBUG_LOG(0, (LGPFX"Host capability check passed.\n")); } return result; } /* *---------------------------------------------------------------------- * * VMCI_ReadDatagramsFromPort -- * * Reads datagrams from the data in port and dispatches them. We * always start reading datagrams into only the first page of the * datagram buffer. If the datagrams don't fit into one page, we * use the maximum datagram buffer size for the remainder of the * invocation. This is a simple heuristic for not penalizing * small datagrams. * * This function assumes that it has exclusive access to the data * in port for the duration of the call. * * Results: * No result. * * Side effects: * Datagram handlers may be invoked. * *---------------------------------------------------------------------- */ void VMCI_ReadDatagramsFromPort(VMCIIoHandle ioHandle, // IN VMCIIoPort dgInPort, // IN uint8 *dgInBuffer, // IN size_t dgInBufferSize) // IN { VMCIDatagram *dg; size_t currentDgInBufferSize = PAGE_SIZE; size_t remainingBytes; ASSERT(dgInBufferSize >= PAGE_SIZE); VMCI_ReadPortBytes(ioHandle, dgInPort, dgInBuffer, currentDgInBufferSize); dg = (VMCIDatagram *)dgInBuffer; remainingBytes = currentDgInBufferSize; while (dg->dst.resource != VMCI_INVALID_ID || remainingBytes > PAGE_SIZE) { unsigned dgInSize; /* * When the input buffer spans multiple pages, a datagram can * start on any page boundary in the buffer. */ if (dg->dst.resource == VMCI_INVALID_ID) { ASSERT(remainingBytes > PAGE_SIZE); dg = (VMCIDatagram *)ROUNDUP((uintptr_t)dg + 1, PAGE_SIZE); ASSERT((uint8 *)dg < dgInBuffer + currentDgInBufferSize); remainingBytes = (size_t)(dgInBuffer + currentDgInBufferSize - (uint8 *)dg); continue; } dgInSize = VMCI_DG_SIZE_ALIGNED(dg); if (dgInSize <= dgInBufferSize) { int result; /* * If the remaining bytes in the datagram buffer doesn't * contain the complete datagram, we first make sure we have * enough room for it and then we read the reminder of the * datagram and possibly any following datagrams. */ if (dgInSize > remainingBytes) { if (remainingBytes != currentDgInBufferSize) { /* * We move the partial datagram to the front and read * the reminder of the datagram and possibly following * calls into the following bytes. */ memmove(dgInBuffer, dgInBuffer + currentDgInBufferSize - remainingBytes, remainingBytes); dg = (VMCIDatagram *)dgInBuffer; } if (currentDgInBufferSize != dgInBufferSize) { currentDgInBufferSize = dgInBufferSize; } VMCI_ReadPortBytes(ioHandle, dgInPort, dgInBuffer + remainingBytes, currentDgInBufferSize - remainingBytes); } /* We special case event datagrams from the hypervisor. */ if (dg->src.context == VMCI_HYPERVISOR_CONTEXT_ID && dg->dst.resource == VMCI_EVENT_HANDLER) { result = VMCIEvent_Dispatch(dg); } else { result = VMCIDatagram_InvokeGuestHandler(dg); } if (result < VMCI_SUCCESS) { VMCI_DEBUG_LOG(4, (LGPFX"Datagram with resource (ID=0x%x) failed " "(err=%d).\n", dg->dst.resource, result)); } /* On to the next datagram. */ dg = (VMCIDatagram *)((uint8 *)dg + dgInSize); } else { size_t bytesToSkip; /* * Datagram doesn't fit in datagram buffer of maximal size. We drop it. */ VMCI_DEBUG_LOG(4, (LGPFX"Failed to receive datagram (size=%u bytes).\n", dgInSize)); bytesToSkip = dgInSize - remainingBytes; if (currentDgInBufferSize != dgInBufferSize) { currentDgInBufferSize = dgInBufferSize; } for (;;) { VMCI_ReadPortBytes(ioHandle, dgInPort, dgInBuffer, currentDgInBufferSize); if (bytesToSkip <= currentDgInBufferSize) { break; } bytesToSkip -= currentDgInBufferSize; } dg = (VMCIDatagram *)(dgInBuffer + bytesToSkip); } remainingBytes = (size_t) (dgInBuffer + currentDgInBufferSize - (uint8 *)dg); if (remainingBytes < VMCI_DG_HEADERSIZE) { /* Get the next batch of datagrams. */ VMCI_ReadPortBytes(ioHandle, dgInPort, dgInBuffer, currentDgInBufferSize); dg = (VMCIDatagram *)dgInBuffer; remainingBytes = currentDgInBufferSize; } } } /* *---------------------------------------------------------------------------- * * vmci_get_context_id -- * * Returns the current context ID. Note that since this is accessed only * from code running in the host, this always returns the host context ID. * * Results: * Context ID. * * Side effects: * None. * *---------------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_get_context_id) VMCIId vmci_get_context_id(void) { if (VMCI_GuestPersonalityActive()) { if (Atomic_Read(&vmContextID) == VMCI_INVALID_ID) { uint32 result; VMCIDatagram getCidMsg; getCidMsg.dst = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_GET_CONTEXT_ID); getCidMsg.src = VMCI_ANON_SRC_HANDLE; getCidMsg.payloadSize = 0; result = VMCI_SendDatagram(&getCidMsg); Atomic_Write(&vmContextID, result); } return Atomic_Read(&vmContextID); } else if (VMCI_HostPersonalityActive()) { return VMCI_HOST_CONTEXT_ID; } return VMCI_INVALID_ID; } /* *---------------------------------------------------------------------- * * vmci_version -- * * Returns the version of the VMCI driver. * * Results: * Returns a version number. * * Side effects: * None. * *---------------------------------------------------------------------- */ VMCI_EXPORT_SYMBOL(vmci_version) uint32 vmci_version(void) { return VMCI_VERSION; } /* *---------------------------------------------------------------------- * * VMCI_SharedInit -- * * Initializes VMCI components shared between guest and host * driver. This registers core hypercalls. * * Results: * VMCI_SUCCESS if successful, appropriate error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VMCI_SharedInit(void) { int result; result = VMCIResource_Init(); if (result < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to initialize VMCIResource (result=%d).\n", result)); goto errorExit; } result = VMCIContext_Init(); if (result < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to initialize VMCIContext (result=%d).\n", result)); goto resourceExit; } result = VMCIDatagram_Init(); if (result < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to initialize VMCIDatagram (result=%d).\n", result)); goto contextExit; } result = VMCIEvent_Init(); if (result < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to initialize VMCIEvent (result=%d).\n", result)); goto datagramExit; } result = VMCIDoorbell_Init(); if (result < VMCI_SUCCESS) { VMCI_WARNING((LGPFX"Failed to initialize VMCIDoorbell (result=%d).\n", result)); goto eventExit; } VMCI_DEBUG_LOG(0, (LGPFX"shared components initialized.\n")); return VMCI_SUCCESS; eventExit: VMCIEvent_Exit(); datagramExit: VMCIDatagram_Exit(); contextExit: VMCIContext_Exit(); resourceExit: VMCIResource_Exit(); errorExit: return result; } /* *---------------------------------------------------------------------- * * VMCI_SharedCleanup -- * * Cleans up VMCI components shared between guest and host * driver. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void VMCI_SharedCleanup(void) { VMCIDoorbell_Exit(); VMCIEvent_Exit(); VMCIDatagram_Exit(); VMCIContext_Exit(); VMCIResource_Exit(); } open-vm-tools-9.4.0-1280544/modules/linux/vmci/Makefile.kernel0000644765153500003110000000420512220061556022124 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 2007 VMware, Inc. All rights reserved. # # 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 version 2 and no later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ########################################################## CC_OPTS += -DVMCI INCLUDE += -I$(SRCROOT)/shared -I$(SRCROOT)/common -I$(SRCROOT)/linux EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE) obj-m += $(DRIVER).o $(DRIVER)-y := $(subst $(SRCROOT)/, , $(patsubst %.c, %.o, \ $(wildcard $(SRCROOT)/linux/*.c $(SRCROOT)/common/*.c))) # # In open-vm-tools, need to compile the common sources from the shared directory. # DRIVERLOG := driverLog.o $(DRIVER)-y += $(DRIVERLOG) VMCI_PATH := $(shell cd $(SRCROOT) && pwd) ifdef OVT_SOURCE_DIR DRIVERLOG_PATH := $(OVT_SOURCE_DIR)/modules/linux/shared else DRIVERLOG_PATH := $(VMCI_PATH)/shared endif $(addprefix $(VMCI_PATH)/,$(DRIVERLOG)): $(VMCI_PATH)/%.o: $(DRIVERLOG_PATH)/%.c $(Q)$(rule_cc_o_c) clean: rm -rf $(wildcard $(DRIVER).mod.c $(DRIVER).ko .tmp_versions \ Module.symvers Modules.symvers Module.markers modules.order \ $(foreach dir,linux/ common/ \ ./,$(addprefix $(dir),.*.cmd .*.o.flags *.o))) ifneq ($(MODULEBUILDDIR),) rm -f $(MODULEBUILDDIR)/VMwareVMCIModule.symvers endif # # If this build generated a Module.symvers, copy it to a public place where # the VMCI Sockets build will be able to find it. # postbuild:: ifeq ($(call vm_check_file,$(SRCROOT)/Module.symvers), yes) ifneq ($(MODULEBUILDDIR),) cp -f $(SRCROOT)/Module.symvers $(MODULEBUILDDIR)/VMwareVMCIModule.symvers endif endif open-vm-tools-9.4.0-1280544/modules/linux/vmci/COPYING0000644765153500003110000004310312220061556020240 0ustar dtormts GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. open-vm-tools-9.4.0-1280544/modules/linux/vmci/Makefile0000644765153500003110000001053712220061556020652 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 1998 VMware, Inc. All rights reserved. # # 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 version 2 and no later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ########################################################## #### #### VMware kernel module Makefile to be distributed externally #### #### #### SRCROOT _must_ be a relative path. #### SRCROOT = . # # open-vm-tools doesn't replicate shared source files for different modules; # instead, files are kept in shared locations. So define a few useful macros # to be able to handle both cases cleanly. # INCLUDE := ifdef OVT_SOURCE_DIR AUTOCONF_DIR := $(OVT_SOURCE_DIR)/modules/linux/shared/autoconf VMLIB_PATH = $(OVT_SOURCE_DIR)/lib/$(1) INCLUDE += -I$(OVT_SOURCE_DIR)/modules/linux/shared INCLUDE += -I$(OVT_SOURCE_DIR)/lib/include else AUTOCONF_DIR := $(SRCROOT)/shared/autoconf INCLUDE += -I$(SRCROOT)/shared endif VM_UNAME = $(shell uname -r) # Header directory for the running kernel ifdef LINUXINCLUDE HEADER_DIR = $(LINUXINCLUDE) else HEADER_DIR = /lib/modules/$(VM_UNAME)/build/include endif BUILD_DIR = $(HEADER_DIR)/.. DRIVER := vmci PRODUCT := tools-source # Grep program GREP = /bin/grep vm_check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null \ > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) vm_check_file = $(shell if test -f $(1); then echo "yes"; else echo "no"; fi) ifndef VM_KBUILD VM_KBUILD := no ifeq ($(call vm_check_file,$(BUILD_DIR)/Makefile), yes) ifneq ($(call vm_check_file,$(BUILD_DIR)/Rules.make), yes) VM_KBUILD := 26 endif endif export VM_KBUILD endif ifndef VM_KBUILD_SHOWN ifeq ($(VM_KBUILD), no) VM_DUMMY := $(shell echo >&2 "Using standalone build system.") else ifeq ($(VM_KBUILD), 24) VM_DUMMY := $(shell echo >&2 "Using 2.4.x kernel build system.") else VM_DUMMY := $(shell echo >&2 "Using 2.6.x kernel build system.") endif endif VM_KBUILD_SHOWN := yes export VM_KBUILD_SHOWN endif ifneq ($(VM_KBUILD), no) VMCCVER := $(shell $(CC) -dumpversion) # If there is no version defined, we are in toplevel pass, not yet in kernel makefiles... ifeq ($(VERSION),) ifeq ($(VM_KBUILD), 24) DRIVER_KO := $(DRIVER).o else DRIVER_KO := $(DRIVER).ko endif .PHONY: $(DRIVER_KO) auto-build: $(DRIVER_KO) cp -f $< $(SRCROOT)/../$(DRIVER).o # $(DRIVER_KO) is a phony target, so compare file times explicitly $(DRIVER): $(DRIVER_KO) if [ $< -nt $@ ] || [ ! -e $@ ] ; then cp -f $< $@; fi # Pass gcc version down the chain, so we can detect if kernel attempts to use unapproved compiler VM_CCVER := $(VMCCVER) export VM_CCVER VM_CC := $(CC) export VM_CC MAKEOVERRIDES := $(filter-out CC=%,$(MAKEOVERRIDES)) # # Define a setup target that gets built before the actual driver. # This target may not be used at all, but if it is then it will be defined # in Makefile.kernel # prebuild:: ; postbuild:: ; $(DRIVER_KO): prebuild $(MAKE) -C $(BUILD_DIR) SUBDIRS=$$PWD SRCROOT=$$PWD/$(SRCROOT) \ MODULEBUILDDIR=$(MODULEBUILDDIR) modules $(MAKE) -C $$PWD SRCROOT=$$PWD/$(SRCROOT) \ MODULEBUILDDIR=$(MODULEBUILDDIR) postbuild endif vm_check_build = $(shell if $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ $(CPPFLAGS) $(CFLAGS) $(CFLAGS_KERNEL) $(LINUXINCLUDE) \ $(EXTRA_CFLAGS) -Iinclude2/asm/mach-default \ -DKBUILD_BASENAME=\"$(DRIVER)\" \ -Werror -S -o /dev/null -xc $(1) \ > /dev/null 2>&1; then echo "$(2)"; else echo "$(3)"; fi) CC_WARNINGS := -Wall -Wstrict-prototypes CC_OPTS := $(GLOBAL_DEFS) $(CC_WARNINGS) -DVMW_USING_KBUILD ifdef VMX86_DEVEL CC_OPTS += -DVMX86_DEVEL endif ifdef VMX86_DEBUG CC_OPTS += -DVMX86_DEBUG endif include $(SRCROOT)/Makefile.kernel ifdef TOPDIR ifeq ($(VM_KBUILD), 24) O_TARGET := $(DRIVER).o obj-y := $($(DRIVER)-y) include $(TOPDIR)/Rules.make endif endif else include $(SRCROOT)/Makefile.normal endif #.SILENT: open-vm-tools-9.4.0-1280544/modules/linux/vmci/shared/0000755765153500003110000000000012220061556020452 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/linux/vmci/shared/vmci_page_channel.h0000644765153500003110000005630412220061556024255 0ustar dtormts/********************************************************* * Copyright (C) 2011-2012 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmci_page_channel.h * * vPageChannel structure and functions. */ #ifndef _VMCI_PAGE_CHANNEL_H_ #define _VMCI_PAGE_CHANNEL_H_ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vmci_defs.h" #include "vmci_call_defs.h" /** \cond PRIVATE */ #define VPAGECHANNEL_MAX_TX_BUF_SIZE (1 << 14) #define VPAGECHANNEL_MAX_PAGES_PER_TX_BUFFER \ (VPAGECHANNEL_MAX_TX_BUF_SIZE / PAGE_SIZE + 1) /** \endcond */ /** * \brief Get a pointer to the elements in a packet. * * Returns a pointer to the elements at the end of a page channel packet. * * \see VPageChannelElem * \see VPageChannelPacket */ #define VPAGECHANNEL_PACKET_ELEMS(packet) \ (VPageChannelElem *)((char *)(packet) + \ sizeof(VPageChannelPacket) + \ packet->msgLen) /** * \brief Get a pointer to the message in a packet. * * Returns a pointer to the message embedded in a page channel packet. * * \see VPageChannelPacket */ #define VPAGECHANNEL_PACKET_MESSAGE(packet) \ (char *)((char *)(packet) + sizeof(VPageChannelPacket)) /** * \brief Notify client directly, and do not read packets. * * This flag indicates that the channel should invoke the client's receive * callback directly when any packets are available. If not specified, then * when a notification is received, packets are read from the channel and the * callback invoked for each one separately. * * \note Not applicable to VMKernel. * * \see VPageChannel_CreateInVM() */ #define VPAGECHANNEL_FLAGS_NOTIFY_ONLY 0x1 /** * \brief Invoke client's receive callback in delayed context. * * This flag indicates that all callbacks run in a delayed context, and the * caller and callback are allowed to block. If not specified, then callbacks * run in interrupt context and the channel will not block, and the caller * is not allowed to block. * * \note Not applicable to VMKernel. * * \see VPageChannel_CreateInVM() */ #define VPAGECHANNEL_FLAGS_RECV_DELAYED 0x2 /** * \brief Send from an atomic context. * * This flag indicates that the client wishes to call Send() from an atomic * context and that the channel should not block. If the channel is not * allowed to block, then the channel's pages are permanently mapped and * pinned. Note that this will limit the total size of the channel to * VMCI_MAX_PINNED_QP_MEMORY. * * \note Not applicable to VMKernel. * * \see VPageChannel_CreateInVM() */ #define VPAGECHANNEL_FLAGS_SEND_WHILE_ATOMIC 0x4 /** * \brief An element describing a data range. * * Describes a data range, starting at a base address and for a given * length, i.e., an element of a scatter-gather list. Indicates physical * address for the guest and machine address for hypervisor. Can be passed * via packets or buffers. * * \note Structure is packed. * * \see VPageChannelPacket * \see VPageChanelBuffer */ typedef #include "vmware_pack_begin.h" struct VPageChannelElem { union { /** \brief Physical address for guest. */ uint64 pa; /** \brief Machine address for hypervisor. */ uint64 ma; }; /** \brief Length of range. */ uint32 le; } #include "vmware_pack_end.h" VPageChannelElem; /** * \brief Page channel page types. * * The various types of page channel packets. * * \see VPageChannelPacket */ typedef enum { /** \brief Data packet. */ VPCPacket_Data = 1, /** \brief Completion notification, from hypervisor to guest. */ VPCPacket_Completion_Notify, /** \cond PRIVATE */ /** \brief Connect to hypervisor, internal. */ VPCPacket_GuestConnect, /** \brief Complete connection handshake, internal. */ VPCPacket_HyperConnect, /** \brief Request buffers, internal. */ VPCPacket_RequestBuffer, /** \brief Set buffers, internal. */ VPCPacket_SetRecvBuffer, /** \brief Hypervisor channel disconnect, internal. */ VPCPacket_HyperDisconnect, /** \brief Guest channel ACK hypervisor disconnect, internal. */ VPCPacket_GuestDisconnect, /** \endcond */ } VPageChannelPacketType; /** * \brief Page channel packet structure. * * A packet structure for passing control/data between guest and hypervisor. * Can optionally contain a message and also a number of elements. * * \note Structure is packed. * * \see VPageChannelPacketType */ typedef #include "vmware_pack_begin.h" struct VPageChannelPacket { /** \brief Type of packet. */ VPageChannelPacketType type; /** \brief Length of optional message. */ uint32 msgLen; /** \brief Number of optional elements in packet. */ uint32 numElems; /** \brief Followed by msgLen of message and numElems VPageChannelElem. */ } #include "vmware_pack_end.h" VPageChannelPacket; /** * \brief Page channel buffer structure. * * A buffer of elements (a scatter-gather list). * * \note Structure is packed. * * \see VPageChannelElem */ typedef #include "vmware_pack_begin.h" struct VPageChannelBuffer { /** \brief Number of elements. */ uint32 numElems; /** \brief First element. */ VPageChannelElem elems[1]; /** \brief Followed by numElems - 1 of VPageChannelElem. */ } #include "vmware_pack_end.h" VPageChannelBuffer; /** \cond PRIVATE */ typedef #include "vmware_pack_begin.h" struct VPageChannelGuestConnectMessage { /** \brief Guest channel's datagram handle for control channel. */ VMCIHandle dgHandle; /** \brief Guest channel's queuepair handle. */ VMCIHandle qpHandle; /** \brief Size of producer queue in queuepair in bytes. */ uint64 produceQSize; /** \brief Size of consumer queue in queuepair in bytes. */ uint64 consumeQSize; /** \brief Guest channel's doorbell handle. */ VMCIHandle doorbellHandle; } #include "vmware_pack_end.h" VPageChannelGuestConnectMessage; typedef #include "vmware_pack_begin.h" struct VPageChannelHyperConnectMessage { /** \brief Hypervisor's doorbell handle. */ VMCIHandle doorbellHandle; } #include "vmware_pack_end.h" VPageChannelHyperConnectMessage; /** \endcond PRIVATE */ /** \cond PRIVATE */ typedef enum VPageChannelState { VPCState_Free = 0, VPCState_Unconnected, VPCState_Connecting, VPCState_Connected, VPCState_Disconnecting, VPCState_Disconnected, } VPageChannelState; /** \endcond PRIVATE */ /** * \brief Opaque page channel type. */ struct VPageChannel; typedef struct VPageChannel VPageChannel; /** * \brief Client receive callback type. * * Type of receive callback, invoked when there are data packets in the * channel. The client provides a callback with this type to * VPageChannel_CreateInVM(). If VPAGECHANNEL_FLAGS_NOTIFY_ONLY is specified * in the channel creation flags, then \c packet is \c NULL; otherwise, * \c packet points to a channel packet. * * \see VPageChannel_CreateInVM() * \see VPageChannelPacket */ typedef void (*VPageChannelRecvCB)(void *clientData, VPageChannelPacket *packet); #if !defined(VMKERNEL) /** * \brief Client element allocation callback type. * * Type of element allocation callback, invoked when the channel needs * elements. The client provides a callback of this type to * VPageChannel_CreateInVM(). * * \see VPageChannel_CreateInVM() * \see VPageChannelElem * \see VPageChannelFreeElemFn */ typedef int (*VPageChannelAllocElemFn)(void *clientData, VPageChannelElem *elems, int numElems); /** * \brief Client element release callback type. * * Type of element release callback, invoked when the channel releases * elements. The client provides a callback of this type to * VPageChannel_CreateInVM(). * * \see VPageChannel_CreateInVM() * \see VPageChannelElem * \see VPageChannelAllocElemFn */ typedef void (*VPageChannelFreeElemFn)(void *clientData, VPageChannelElem *elems, int numElems); /* ************************************************************************ * VPageChannel_CreateInVM */ /** * * \brief Create guest page channel. * * Creates a page channel in the guest. The channel should be released * with VPageChannel_Destroy(). * * \note Only applicable in the guest. * * \see VPageChannel_CreateInVMK() * \see VPageChannel_Destroy() * * \param[out] channel Pointer to a newly constructed page * channel if successful. * \param[in] resourceId Resource ID on which the channel should * register its control channel. * \param[in] peerResourceId Resource ID of peer's control channel. * \param[in] produceQSize Size of producer queue in queuepair in * bytes. * \param[in] consumeQSize Size of consumer queue in queuepair in * bytes. * \param[in] flags Channel flags. * \param[in] recvCB Client's receive callback. * \param[in] clientRecvData Client data for client's receive * callback. * \param[in] elemAlloc Element allocation callback for * allocating page ranges (scatter-gather * elements). * \param[in] allocClientData Client data for element allocation * callback. * \param[in] elemFree Element release callback for elements. * \param[in] freeClientData Client data for element release * callback. * \param[in] defRecvBufs Default number of elements sent to * hypervisor channel. * \param[in] maxRecvBufs Maximum number of elements that can be * sent to the hypervisor channel. * * \retval VMCI_SUCCESS Creation succeeded, \c *channel contains * a pointer to a valid channel. * \retval other Failure. * ************************************************************************ */ int VPageChannel_CreateInVM(VPageChannel **channel, VMCIId resourceId, VMCIId peerResourceId, uint64 produceQSize, uint64 consumeQSize, uint32 flags, VPageChannelRecvCB recvCB, void *clientRecvData, VPageChannelAllocElemFn elemAlloc, void *allocClientData, VPageChannelFreeElemFn elemFree, void *freeClientData, int defRecvBufs, int maxRecvBufs); #else // VMKERNEL /** * \brief Type of VM memory access off callback. * * This callback is invoked when the memory of the VM containing the peer * endpoint becomes inaccessible, for example due to a crash. When this * occurs, the client should unmap any guest pages and cleanup any state. * This callback runs in a blockable context. The client is not allowed to * call VPageChannel_Destroy() from inside the callback, or it will deadlock, * since that function will wait for the callback to complete. * * \note Only applicable on VMKernel. * * \see VPageChannel_CreateInVMK() */ typedef void (*VPageChannelMemAccessOffCB)(void *clientData); /* ************************************************************************ * VPageChannel_CreateInVMK */ /** * * \brief Create a page channel in VMKernel. * * Creates a page channel. The channel should be released with * VPageChannel_Destroy(). * * \note Only applicable on VMKernel. * * \see VPageChannel_CreateInVM() * \see VPageChannel_Destroy() * * \param[out] channel Pointer to a newly constructed page * channel if successful. * \param[in] resourceId Resource ID on which to register * control channel. * \param[in] recvCB Client's receive callback. * \param[in] clientRecvData Client data for receive callback. * \param[in] memAccessOffCB Client's mem access off callback. * \param[in] memAccessOffData Client data for mem access off. * * \retval VMCI_SUCCESS Creation succeeded, \c *channel * contains a pointer to a valid channel. * \retval other Failure. * *********************************************************************** */ int VPageChannel_CreateInVMK(VPageChannel **channel, VMCIId resourceId, VPageChannelRecvCB recvCB, void *clientRecvData, VPageChannelMemAccessOffCB memAccessOffCB, void *memAccessOffData); /* ************************************************************************ * VPageChannel_ReserveBuffers */ /** * * \brief Reserve guest elements. * * Reserve sufficient guest elements to cover the given length. The * buffers can then be posted to the guest. This allocates both the * buffer and the elements within the buffer. * * \note Only applicable on VMKernel. * * \see VPageChannel_ReleaseBuffers() * * \param[in] channel Page channel. * \param[in] dataLen Length to reserve in bytes. * \param[out] buffer Pointer to a buffer containing elements to cover * the given length if successful. * * \retval VMCI_SUCCESS Reservation succeeded, \c *buffer contains * a pointer to a valid buffer. * \retval other Failure. * ************************************************************************ */ int VPageChannel_ReserveBuffers(VPageChannel *channel, size_t dataLen, VPageChannelBuffer **buffer); /* ************************************************************************ * VPageChannel_ReleaseBuffers */ /** * * \brief Release guest elements. * * \note Only applicable on VMKernel. * * \see VPageChannel_ReserveBuffers() * * Release guest elements previous reserved with * VPageChannel_ReserveBuffers(). If the buffers were sent to the guest, * then only the buffer itself should be released, i.e., * \c returnToFreePool should be \c FALSE; the guest will release the * buffers on completion. Otherwise, if for some reason they are not * sent after reserving them, then \c returnToFreePool should be set to * \c TRUE. * * \param[in] channel Page channel. * \param[in] buffer Buffer to be released. * \param[in] returnToFreePool If \c TRUE, then release the elements * of the buffer along with the buffer * itself. If \c FALSE, then release only * the buffer pointer itself. * ************************************************************************ */ void VPageChannel_ReleaseBuffers(VPageChannel *channel, VPageChannelBuffer *buffer, Bool returnToFreePool); /* ************************************************************************ * VPageChannel_CompletionNotify */ /** * * \brief Notify channel of completion. * * This function is called when the client is finished using the elements * (scatter-gather list) of a packet. This will generated a notification * to the guest to pass ownership of the buffers back to the guest. This * can also be used to read back the data from the hypervisor and send * it to the guest. * * \note Only applicable on VMKernel. * * \see VPageChannel_ReserveBuffers * * \param[in] channel Channel on which I/O is complete. * \param[in] message Optional message to send to guest. * \param[in] len Length of optional message. * \param[in] buffer Buffer used for I/O. * ************************************************************************ */ int VPageChannel_CompletionNotify(VPageChannel *channel, char *message, int len, VPageChannelBuffer *buffer); /* ************************************************************************ * VPageChannel_MapToMa */ /** * * \brief Map guest PA in an element to a list of MAs. * * Map a guest physical address to a list of hypervisor machine * addresses. * * \note Only applicable on VMKernel. * * \param[in] channel Channel on which to map. * \param[in] paElem Guest's physical address. * \param[out] maElems Hypervisor machine addresses. * \param[in] numElems Max number of hypervisor elements. * * \retval elems Number of mapped elements. * ************************************************************************ */ int VPageChannel_MapToMa(VPageChannel *channel, VPageChannelElem paElem, VPageChannelElem *maElems, uint32 numElems); /* ************************************************************************ * VPageChannel_UnmapMa */ /** * * \brief Unmap MA for a buffer. * * Unmap hypervisor machine addresses referring to a guest physical * addresses. * * \note Only applicable on VMKernel. * * \see VPageChannel_MapToMa * * \param[in] channel Channel for which to unmap. * \param[in] buffer Buffer containing elements to unmap. * \param[in] numElems Number of elements to unmap. * * \retval 0 Unmap successful. * \retval -1 World not found for channel. * ************************************************************************ */ int VPageChannel_UnmapMa(VPageChannel *channel, VPageChannelBuffer *buffer, int numElems); #endif // VMKERNEL /* ************************************************************************ * VPageChannel_Destroy */ /** * * \brief Destroy the given channel. * * Destroy the given channel. This will disconnect from the peer * channel (if connected) and release all resources. * * \see VPageChannel_CreateInVMK * \see VPageChannel_CreateInVM * * \param[in] channel The channel to be destroyed. * ************************************************************************ */ void VPageChannel_Destroy(VPageChannel *channel); /* ************************************************************************ * VPageChannel_Send */ /** * * \brief Send a packet to the channel's peer. * * Send a packet to the channel's peer. A message and a number of * elements may optionally be sent. If the send is successful, the * elements are owned by the peer and only the buffer itself should * be released, but not the elements within. If the send fails, the * client should release the buffer and the elements. * * \see VPageChannel_SendPacket * * \param[in] channel Channel on which to send. * \param[in] type Type of packet to send. * \param[in] message Optional message to send. * \param[in] len Length of optional message. * \param[in] buffer Buffer (of elements) to send. * * \retval VMCI_SUCCESS Packet successfully sent, buffer elements * owned by peer. * \retval other Failure to send, client should release * elements. * ************************************************************************ */ int VPageChannel_Send(VPageChannel *channel, VPageChannelPacketType type, char *message, int len, VPageChannelBuffer *buffer); /* ************************************************************************ * VPageChannel_SendPacket */ /** * * \brief Send the given packet to the channel's peer. * * Send a client-constructed packet to the channel's peer. If the * send is successful, any elements in the packet are owned by the * peer. Otherwise, the client retains ownership. * * \see VPageChannel_Send * * \param[in] channel Channel on which to send. * \param[in] packet Packet to be sent. * * \retval VMCI_SUCCESS Packet successfully sent, buffer elements * owned by peer. * \retval other Failure to send, client should release * elements. * ************************************************************************ */ int VPageChannel_SendPacket(VPageChannel *channel, VPageChannelPacket *packet); /* ************************************************************************ * VPageChannel_PollRecvQ */ /** * * \brief Poll the channel's receive queue for packets. * * Poll the channel's receive queue for packets from the peer. If any * packets are available, the channel's receive callback will be invoked. * * \param[in] channel Channel to poll. * ************************************************************************ */ void VPageChannel_PollRecvQ(VPageChannel *channel); /* ************************************************************************ * VPageChannel_BufferLen */ /** * * \brief Determine the length of a packet. * * Determine the length of the given packet in bytes. * * \param[in] packet Packet for which length is to be determined. * * \retval bytes Size of the packet in bytes. * ************************************************************************ */ static INLINE size_t VPageChannelPacket_BufferLen(VPageChannelPacket *packet) // IN { size_t len, i; VPageChannelElem *elems; ASSERT(packet); len = 0; elems = VPAGECHANNEL_PACKET_ELEMS(packet); for (i = 0; i < packet->numElems; i++) { len += elems[i].le; } return len; } /** \cond PRIVATE */ #if defined(linux) && !defined(VMKERNEL) #include "compat_pci.h" #define vmci_pci_map_page(_pg, _off, _sz, _dir) \ pci_map_page(NULL, (_pg), (_off), (_sz), (_dir)) #define vmci_pci_unmap_page(_dma, _sz, _dir) \ pci_unmap_page(NULL, (_dma), (_sz), (_dir)) #endif // linux && !VMKERNEL /** \endcond PRIVATE */ #endif // _VMCI_PACKET_H_ open-vm-tools-9.4.0-1280544/modules/linux/vmci/shared/vmci_handle_array.h0000644765153500003110000002166712220061556024306 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmci_handle_array.h -- * * Simple dynamic array. */ #ifndef _VMCI_HANDLE_ARRAY_H_ #define _VMCI_HANDLE_ARRAY_H_ #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vmci_kernel_if.h" #include "vmware.h" #include "vmci_defs.h" #include "vm_assert.h" #ifdef VMKERNEL #include "vm_libc.h" #endif // VMKERNEL #ifdef SOLARIS #include #include #include #include #endif #define VMCI_HANDLE_ARRAY_DEFAULT_SIZE 4 typedef struct VMCIHandleArray { uint32 capacity; uint32 size; VMCIHandle entries[1]; } VMCIHandleArray; /* *----------------------------------------------------------------------------------- * * VMCIHandleArray_Create -- * * Results: * Array if successful, NULL if not. * * Side effects: * None. * *----------------------------------------------------------------------------------- */ static INLINE VMCIHandleArray * VMCIHandleArray_Create(uint32 capacity) { VMCIHandleArray *array; if (capacity == 0) { capacity = VMCI_HANDLE_ARRAY_DEFAULT_SIZE; } array = (VMCIHandleArray *)VMCI_AllocKernelMem(sizeof array->capacity + sizeof array->size + capacity * sizeof(VMCIHandle), VMCI_MEMORY_NONPAGED | VMCI_MEMORY_ATOMIC); if (array == NULL) { return NULL; } array->capacity = capacity; array->size = 0; return array; } /* *----------------------------------------------------------------------------------- * * VMCIHandleArray_Destroy -- * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------------- */ static INLINE void VMCIHandleArray_Destroy(VMCIHandleArray *array) { VMCI_FreeKernelMem(array, sizeof array->capacity + sizeof array->size + array->capacity * sizeof(VMCIHandle)); } /* *----------------------------------------------------------------------------------- * * VMCIHandleArray_AppendEntry -- * * Results: * None. * * Side effects: * Array may be reallocated. * *----------------------------------------------------------------------------------- */ static INLINE void VMCIHandleArray_AppendEntry(VMCIHandleArray **arrayPtr, VMCIHandle handle) { VMCIHandleArray *array; ASSERT(arrayPtr && *arrayPtr); array = *arrayPtr; if (UNLIKELY(array->size >= array->capacity)) { /* reallocate. */ uint32 arraySize = sizeof array->capacity + sizeof array->size + array->capacity * sizeof(VMCIHandle); VMCIHandleArray *newArray = (VMCIHandleArray *) VMCI_AllocKernelMem(arraySize + array->capacity * sizeof(VMCIHandle), VMCI_MEMORY_NONPAGED | VMCI_MEMORY_ATOMIC); if (newArray == NULL) { return; } memcpy(newArray, array, arraySize); newArray->capacity *= 2; VMCI_FreeKernelMem(array, arraySize); *arrayPtr = newArray; array = newArray; } array->entries[array->size] = handle; array->size++; } /* *----------------------------------------------------------------------------------- * * VMCIHandleArray_RemoveEntry -- * * Results: * Handle that was removed, VMCI_INVALID_HANDLE if entry not found. * * Side effects: * None. * *----------------------------------------------------------------------------------- */ static INLINE VMCIHandle VMCIHandleArray_RemoveEntry(VMCIHandleArray *array, VMCIHandle entryHandle) { uint32 i; VMCIHandle handle = VMCI_INVALID_HANDLE; ASSERT(array); for (i = 0; i < array->size; i++) { if (VMCI_HANDLE_EQUAL(array->entries[i], entryHandle)) { handle = array->entries[i]; array->entries[i] = array->entries[array->size-1]; array->entries[array->size-1] = VMCI_INVALID_HANDLE; array->size--; break; } } return handle; } /* *----------------------------------------------------------------------------------- * * VMCIHandleArray_RemoveTail -- * * Results: * Handle that was removed, VMCI_INVALID_HANDLE if array was empty. * * Side effects: * None. * *----------------------------------------------------------------------------------- */ static INLINE VMCIHandle VMCIHandleArray_RemoveTail(VMCIHandleArray *array) { VMCIHandle handle; if (array->size == 0) { return VMCI_INVALID_HANDLE; } handle = array->entries[array->size-1]; array->entries[array->size-1] = VMCI_INVALID_HANDLE; array->size--; return handle; } /* *----------------------------------------------------------------------------------- * * VMCIHandleArray_GetEntry -- * * Results: * Handle at given index, VMCI_INVALID_HANDLE if invalid index. * * Side effects: * None. * *----------------------------------------------------------------------------------- */ static INLINE VMCIHandle VMCIHandleArray_GetEntry(const VMCIHandleArray *array, uint32 index) { ASSERT(array); if (UNLIKELY(index >= array->size)) { return VMCI_INVALID_HANDLE; } return array->entries[index]; } /* *----------------------------------------------------------------------------------- * * VMCIHandleArray_GetSize -- * * Results: * Number of entries in array. * * Side effects: * None. * *----------------------------------------------------------------------------------- */ static INLINE uint32 VMCIHandleArray_GetSize(const VMCIHandleArray *array) { ASSERT(array); return array->size; } /* *----------------------------------------------------------------------------------- * * VMCIHandleArray_HasEntry -- * * Results: * TRUE is entry exists in array, FALSE if not. * * Side effects: * None. * *----------------------------------------------------------------------------------- */ static INLINE Bool VMCIHandleArray_HasEntry(const VMCIHandleArray *array, VMCIHandle entryHandle) { uint32 i; ASSERT(array); for (i = 0; i < array->size; i++) { if (VMCI_HANDLE_EQUAL(array->entries[i], entryHandle)) { return TRUE; } } return FALSE; } /* *----------------------------------------------------------------------------------- * * VMCIHandleArray_GetCopy -- * * Results: * Returns pointer to copy of array on success or NULL, if memory allocation * fails. * * Side effects: * Allocates nonpaged memory. * *----------------------------------------------------------------------------------- */ static INLINE VMCIHandleArray * VMCIHandleArray_GetCopy(const VMCIHandleArray *array) { VMCIHandleArray *arrayCopy; ASSERT(array); arrayCopy = (VMCIHandleArray *)VMCI_AllocKernelMem(sizeof array->capacity + sizeof array->size + array->size * sizeof(VMCIHandle), VMCI_MEMORY_NONPAGED | VMCI_MEMORY_ATOMIC); if (arrayCopy != NULL) { memcpy(&arrayCopy->size, &array->size, sizeof array->size + array->size * sizeof(VMCIHandle)); arrayCopy->capacity = array->size; } return arrayCopy; } /* *----------------------------------------------------------------------------------- * * VMCIHandleArray_GetHandles -- * * Results: * NULL if the array is empty. Otherwise, a pointer to the array * of VMCI handles in the handle array. * * Side effects: * None. * *----------------------------------------------------------------------------------- */ static INLINE VMCIHandle * VMCIHandleArray_GetHandles(VMCIHandleArray *array) // IN { ASSERT(array); if (array->size) { return array->entries; } else { return NULL; } } #endif // _VMCI_HANDLE_ARRAY_H_ open-vm-tools-9.4.0-1280544/modules/linux/vmci/shared/vmciQueue.h0000644765153500003110000001725612220061556022601 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef _VMCI_QUEUE_H_ #define _VMCI_QUEUE_H_ /* * * vmciQueue.h -- * * Defines the queue structure, and helper functions to enqueue and dequeue * items. XXX needs checksumming? */ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMX #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #if defined(SOLARIS) || defined(__APPLE__) # include #endif #if defined VMKERNEL # include "vm_atomic.h" # include "return_status.h" # include "util_copy_dist.h" #endif /* * VMCIQueue * * This data type contains the information about a queue. * * There are two queues (hence, queue pairs) per transaction model between a * pair of end points, A & B. One queue is used by end point A to transmit * commands and responses to B. The other queue is used by B to transmit * commands and responses. * * VMCIQueueKernelIf is a per-OS defined Queue structure. It contains either a * direct pointer to the linear address of the buffer contents or a pointer to * structures which help the OS locate those data pages. See vmciKernelIf.c * for each platform for its definition. */ typedef struct VMCIQueueKernelIf VMCIQueueKernelIf; typedef struct VMCIQueue { VMCIQueueHeader *qHeader; VMCIQueueHeader *savedHeader; VMCIQueueKernelIf *kernelIf; } VMCIQueue; /* * ESX uses a buffer type for the memcpy functions. Currently, none * of the hosted products use such a field. And, to keep the function * definitions simple, we use a define to declare the type parameter. */ #ifdef VMKERNEL #define BUF_TYPE Util_BufferType #else #define BUF_TYPE int #endif /* *----------------------------------------------------------------------------- * * VMCIMemcpy{To,From}QueueFunc() prototypes. Functions of these * types are passed around to enqueue and dequeue routines. Note that * often the functions passed are simply wrappers around memcpy * itself. * * Note: In order for the memcpy typedefs to be compatible with the VMKernel, * there's an unused last parameter for the hosted side. In * ESX, that parameter holds a buffer type. * *----------------------------------------------------------------------------- */ typedef int VMCIMemcpyToQueueFunc(VMCIQueue *queue, uint64 queueOffset, const void *src, size_t srcOffset, size_t size, BUF_TYPE bufType, Bool canBlock); typedef int VMCIMemcpyFromQueueFunc(void *dest, size_t destOffset, const VMCIQueue *queue, uint64 queueOffset, size_t size, BUF_TYPE bufType, Bool canBlock); #if defined(_WIN32) && defined(WINNT_DDK) /* * Windows needs iovec for the V functions. We use an MDL for the actual * buffers, but we also have an offset that comes from WSK_BUF. */ typedef struct iovec { PMDL mdl; // List of memory descriptors. ULONG offset; // Base offset. }; #endif // _WIN32 && WINNT_DDK /* *----------------------------------------------------------------------------- * * VMCIMemcpy{To,From}Queue[V][Local]() prototypes * * Note that these routines are NOT SAFE to call on a host end-point * until the guest end of the queue pair has attached -AND- * SetPageStore(). The VMX crosstalk device will issue the * SetPageStore() on behalf of the guest when the guest creates a * QueuePair or attaches to one created by the host. So, if the guest * notifies the host that it's attached then the queue is safe to use. * Also, if the host registers notification of the connection of the * guest, then it will only receive that notification when the guest * has issued the SetPageStore() call and not before (when the guest * had attached). * *----------------------------------------------------------------------------- */ int VMCIMemcpyToQueue(VMCIQueue *queue, uint64 queueOffset, const void *src, size_t srcOffset, size_t size, BUF_TYPE bufType, Bool canBlock); int VMCIMemcpyFromQueue(void *dest, size_t destOffset, const VMCIQueue *queue, uint64 queueOffset, size_t size, BUF_TYPE bufType, Bool canBlock); int VMCIMemcpyToQueueLocal(VMCIQueue *queue, uint64 queueOffset, const void *src, size_t srcOffset, size_t size, BUF_TYPE bufType, Bool canBlock); int VMCIMemcpyFromQueueLocal(void *dest, size_t destOffset, const VMCIQueue *queue, uint64 queueOffset, size_t size, BUF_TYPE bufType, Bool canBlock); #if defined VMKERNEL || defined (SOLARIS) || \ (defined(__APPLE__) && !defined (VMX86_TOOLS)) || \ (defined(__linux__) && defined(__KERNEL__)) || \ (defined(_WIN32) && defined(WINNT_DDK)) int VMCIMemcpyToQueueV(VMCIQueue *queue, uint64 queueOffset, const void *src, size_t srcOffset, size_t size, BUF_TYPE bufType, Bool canBlock); int VMCIMemcpyFromQueueV(void *dest, size_t destOffset, const VMCIQueue *queue, uint64 queueOffset, size_t size, BUF_TYPE bufType, Bool canBlock); # if defined(VMKERNEL) int VMCIMemcpyToQueueVLocal(VMCIQueue *queue, uint64 queueOffset, const void *src, size_t srcOffset, size_t size, BUF_TYPE bufType, Bool canBlock); int VMCIMemcpyFromQueueVLocal(void *dest, size_t destOffset, const VMCIQueue *queue, uint64 queueOffset, size_t size, BUF_TYPE bufType, Bool canBlock); # else /* * For non-vmkernel platforms, the local versions are identical to the * non-local ones. */ static INLINE int VMCIMemcpyToQueueVLocal(VMCIQueue *queue, // IN/OUT uint64 queueOffset, // IN const void *src, // IN: iovec size_t srcOffset, // IN size_t size, // IN BUF_TYPE bufType, // IN Bool canBlock) // IN { return VMCIMemcpyToQueueV(queue, queueOffset, src, srcOffset, size, bufType, canBlock); } static INLINE int VMCIMemcpyFromQueueVLocal(void *dest, // IN/OUT: iovec size_t destOffset, // IN const VMCIQueue *queue, // IN uint64 queueOffset, // IN size_t size, // IN BUF_TYPE bufType, // IN Bool canBlock) // IN { return VMCIMemcpyFromQueueV(dest, destOffset, queue, queueOffset, size, bufType, canBlock); } # endif /* !VMKERNEL */ #endif /* Does the O/S support iovec? */ #endif /* !_VMCI_QUEUE_H_ */ open-vm-tools-9.4.0-1280544/modules/linux/vmci/shared/pgtbl.h0000644765153500003110000002232612220061556021740 0ustar dtormts/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __PGTBL_H__ # define __PGTBL_H__ #include #include "compat_pgtable.h" #include "compat_spinlock.h" #include "compat_page.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 11) # define compat_active_mm mm #else # define compat_active_mm active_mm #endif /* *----------------------------------------------------------------------------- * * PgtblPte2MPN -- * * Returns the page structure associated to a Page Table Entry. * * This function is not allowed to schedule() because it can be called while * holding a spinlock --hpreg * * Results: * INVALID_MPN on failure * mpn on success * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE MPN PgtblPte2MPN(pte_t *pte) // IN { if (pte_present(*pte) == 0) { return INVALID_MPN; } return pte_pfn(*pte); } /* *----------------------------------------------------------------------------- * * PgtblPte2Page -- * * Returns the page structure associated to a Page Table Entry. * * This function is not allowed to schedule() because it can be called while * holding a spinlock --hpreg * * Results: * The page structure if the page table entry points to a physical page * NULL if the page table entry does not point to a physical page * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE struct page * PgtblPte2Page(pte_t *pte) // IN { if (pte_present(*pte) == 0) { return NULL; } return compat_pte_page(*pte); } /* *----------------------------------------------------------------------------- * * PgtblPGD2PTELocked -- * * Walks through the hardware page tables to try to find the pte * associated to a virtual address. * * Results: * pte. Caller must call pte_unmap if valid pte returned. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE pte_t * PgtblPGD2PTELocked(compat_pgd_t *pgd, // IN: PGD to start with VA addr) // IN: Address in the virtual address // space of that process { compat_pud_t *pud; pmd_t *pmd; pte_t *pte; if (compat_pgd_present(*pgd) == 0) { return NULL; } pud = compat_pud_offset(pgd, addr); if (compat_pud_present(*pud) == 0) { return NULL; } pmd = pmd_offset_map(pud, addr); if (pmd_present(*pmd) == 0) { pmd_unmap(pmd); return NULL; } pte = pte_offset_map(pmd, addr); pmd_unmap(pmd); return pte; } /* *----------------------------------------------------------------------------- * * PgtblVa2PTELocked -- * * Walks through the hardware page tables to try to find the pte * associated to a virtual address. * * Results: * pte. Caller must call pte_unmap if valid pte returned. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE pte_t * PgtblVa2PTELocked(struct mm_struct *mm, // IN: Mm structure of a process VA addr) // IN: Address in the virtual address // space of that process { return PgtblPGD2PTELocked(compat_pgd_offset(mm, addr), addr); } /* *----------------------------------------------------------------------------- * * PgtblVa2MPNLocked -- * * Retrieve MPN for a given va. * * Caller must call pte_unmap if valid pte returned. The mm->page_table_lock * must be held, so this function is not allowed to schedule() --hpreg * * Results: * INVALID_MPN on failure * mpn on success * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE MPN PgtblVa2MPNLocked(struct mm_struct *mm, // IN: Mm structure of a process VA addr) // IN: Address in the virtual address { pte_t *pte; pte = PgtblVa2PTELocked(mm, addr); if (pte != NULL) { MPN mpn = PgtblPte2MPN(pte); pte_unmap(pte); return mpn; } return INVALID_MPN; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) /* *----------------------------------------------------------------------------- * * PgtblKVa2MPNLocked -- * * Retrieve MPN for a given kernel va. * * Caller must call pte_unmap if valid pte returned. The mm->page_table_lock * must be held, so this function is not allowed to schedule() --hpreg * * Results: * INVALID_MPN on failure * mpn on success * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE MPN PgtblKVa2MPNLocked(struct mm_struct *mm, // IN: Mm structure of a caller VA addr) // IN: Address in the virtual address { pte_t *pte; pte = PgtblPGD2PTELocked(compat_pgd_offset_k(mm, addr), addr); if (pte != NULL) { MPN mpn = PgtblPte2MPN(pte); pte_unmap(pte); return mpn; } return INVALID_MPN; } #endif /* *----------------------------------------------------------------------------- * * PgtblVa2PageLocked -- * * Return the "page" struct for a given va. * * Results: * struct page or NULL. The mm->page_table_lock must be held, so this * function is not allowed to schedule() --hpreg * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE struct page * PgtblVa2PageLocked(struct mm_struct *mm, // IN: Mm structure of a process VA addr) // IN: Address in the virtual address { pte_t *pte; pte = PgtblVa2PTELocked(mm, addr); if (pte != NULL) { struct page *page = PgtblPte2Page(pte); pte_unmap(pte); return page; } else { return NULL; } } /* *----------------------------------------------------------------------------- * * PgtblVa2MPN -- * * Walks through the hardware page tables of the current process to try to * find the page structure associated to a virtual address. * * Results: * Same as PgtblVa2MPNLocked() * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE int PgtblVa2MPN(VA addr) // IN { struct mm_struct *mm; MPN mpn; /* current->mm is NULL for kernel threads, so use active_mm. */ mm = current->compat_active_mm; if (compat_get_page_table_lock(mm)) { spin_lock(compat_get_page_table_lock(mm)); } mpn = PgtblVa2MPNLocked(mm, addr); if (compat_get_page_table_lock(mm)) { spin_unlock(compat_get_page_table_lock(mm)); } return mpn; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) /* *----------------------------------------------------------------------------- * * PgtblKVa2MPN -- * * Walks through the hardware page tables of the current process to try to * find the page structure associated to a virtual address. * * Results: * Same as PgtblVa2MPNLocked() * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE int PgtblKVa2MPN(VA addr) // IN { struct mm_struct *mm; MPN mpn; mm = current->compat_active_mm; if (compat_get_page_table_lock(mm)) { spin_lock(compat_get_page_table_lock(mm)); } mpn = PgtblKVa2MPNLocked(mm, addr); if (compat_get_page_table_lock(mm)) { spin_unlock(compat_get_page_table_lock(mm)); } return mpn; } #endif /* *----------------------------------------------------------------------------- * * PgtblVa2Page -- * * Walks through the hardware page tables of the current process to try to * find the page structure associated to a virtual address. * * Results: * Same as PgtblVa2PageLocked() * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE struct page * PgtblVa2Page(VA addr) // IN { struct mm_struct *mm; struct page *page; mm = current->compat_active_mm; if (compat_get_page_table_lock(mm)) { spin_lock(compat_get_page_table_lock(mm)); } page = PgtblVa2PageLocked(mm, addr); if (compat_get_page_table_lock(mm)) { spin_unlock(compat_get_page_table_lock(mm)); } return page; } #endif /* __PGTBL_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/vsock/0000755765153500003110000000000012220061556017373 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/linux/vsock/linux/0000755765153500003110000000000012220061556020532 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/linux/vsock/linux/stats.h0000644765153500003110000001760612220061556022053 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * stats.h -- * * Stats functions for Linux vsock module. */ #ifndef __STATS_H__ #define __STATS_H__ #include "driver-config.h" #include "vm_basic_math.h" #include "vsockCommon.h" #include "vsockPacket.h" /* * Define VSOCK_GATHER_STATISTICS to turn on statistics gathering. * Currently this consists of 3 types of stats: * 1. The number of control datagram messages sent. * 2. The level of queuepair fullness (in 10% buckets) whenever data is * about to be enqueued or dequeued from the queuepair. * 3. The total number of bytes enqueued/dequeued. */ //#define VSOCK_GATHER_STATISTICS 1 #ifdef VSOCK_GATHER_STATISTICS #define VSOCK_NUM_QUEUE_LEVEL_BUCKETS 10 extern uint64 vSockStatsCtlPktCount[VSOCK_PACKET_TYPE_MAX]; extern uint64 vSockStatsConsumeQueueHist[VSOCK_NUM_QUEUE_LEVEL_BUCKETS]; extern uint64 vSockStatsProduceQueueHist[VSOCK_NUM_QUEUE_LEVEL_BUCKETS]; extern Atomic_uint64 vSockStatsConsumeTotal; extern Atomic_uint64 vSockStatsProduceTotal; #define VSOCK_STATS_STREAM_CONSUME_HIST(vsk) \ VSockVmciStatsUpdateQueueBucketCount((vsk)->qpair, \ (vsk)->consumeSize, \ VMCIQPair_ConsumeBufReady((vsk)->qpair), \ vSockStatsConsumeQueueHist) #define VSOCK_STATS_STREAM_PRODUCE_HIST(vsk) \ VSockVmciStatsUpdateQueueBucketCount((vsk)->qpair, \ (vsk)->produceSize, \ VMCIQPair_ProduceBufReady((vsk)->qpair), \ vSockStatsProduceQueueHist) #define VSOCK_STATS_CTLPKT_LOG(pktType) \ do { \ ++vSockStatsCtlPktCount[pktType]; \ } while (0) #define VSOCK_STATS_STREAM_CONSUME(bytes) \ Atomic_FetchAndAdd64(&vSockStatsConsumeTotal, bytes) #define VSOCK_STATS_STREAM_PRODUCE(bytes) \ Atomic_FetchAndAdd64(&vSockStatsProduceTotal, bytes) #define VSOCK_STATS_CTLPKT_DUMP_ALL() VSockVmciStatsCtlPktDumpAll() #define VSOCK_STATS_HIST_DUMP_ALL() VSockVmciStatsHistDumpAll() #define VSOCK_STATS_TOTALS_DUMP_ALL() VSockVmciStatsTotalsDumpAll() #define VSOCK_STATS_RESET() VSockVmciStatsReset() /* *---------------------------------------------------------------------------- * * VSockVmciStatsUpdateQueueBucketCount -- * * Given a queue, determine how much data is enqueued and add that to * the specified queue level statistic bucket. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static INLINE void VSockVmciStatsUpdateQueueBucketCount(VMCIQPair *qpair, // IN uint64 queueSize, // IN uint64 dataReady, // IN uint64 queueHist[]) // IN/OUT { uint64 bucket = 0; uint32 remainder = 0; ASSERT(qpair); ASSERT(queueHist); /* * We can't do 64 / 64 = 64 bit divides on linux because it requires a * libgcc which is not linked into the kernel module. Since this code is * only used by developers we just limit the queueSize to be less than * MAX_UINT for now. */ ASSERT(queueSize <= MAX_UINT32); Div643264(dataReady * 10, queueSize, &bucket, &remainder); ASSERT(bucket < VSOCK_NUM_QUEUE_LEVEL_BUCKETS); ++queueHist[bucket]; } /* *---------------------------------------------------------------------------- * * VSockVmciStatsCtlPktDumpAll -- * * Prints all stream control packet counts out to the console using * the appropriate platform logging. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static INLINE void VSockVmciStatsCtlPktDumpAll(void) { uint32 index; ASSERT_ON_COMPILE(VSOCK_PACKET_TYPE_MAX == ARRAYSIZE(vSockStatsCtlPktCount)); for (index = 0; index < ARRAYSIZE(vSockStatsCtlPktCount); index++) { Warning("Control packet count: Type = %u, Count = %"FMT64"u\n", index, vSockStatsCtlPktCount[index]); } } /* *---------------------------------------------------------------------------- * * VSockVmciStatsHistDumpAll -- * * Prints the produce and consume queue histograms to the console. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static INLINE void VSockVmciStatsHistDumpAll(void) { uint32 index; #define VSOCK_DUMP_HIST(strname, name) do { \ for (index = 0; index < ARRAYSIZE(name); index++) { \ Warning(strname " Bucket count %u = %"FMT64"u\n", \ index, name[index]); \ } \ } while (0) VSOCK_DUMP_HIST("Produce Queue", vSockStatsProduceQueueHist); VSOCK_DUMP_HIST("Consume Queue", vSockStatsConsumeQueueHist); #undef VSOCK_DUMP_HIST } /* *---------------------------------------------------------------------------- * * VSockVmciStatsTotalsDumpAll -- * * Prints the produce and consume totals. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static INLINE void VSockVmciStatsTotalsDumpAll(void) { Warning("Produced %"FMT64"u total bytes\n", Atomic_Read64(&vSockStatsProduceTotal)); Warning("Consumed %"FMT64"u total bytes\n", Atomic_Read64(&vSockStatsConsumeTotal)); } /* *---------------------------------------------------------------------------- * * VSockVmciStatsReset -- * * Reset all VSock statistics. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static INLINE void VSockVmciStatsReset(void) { uint32 index; #define VSOCK_RESET_ARRAY(name) do { \ for (index = 0; index < ARRAYSIZE(name); index++) { \ name[index] = 0; \ } \ } while (0) VSOCK_RESET_ARRAY(vSockStatsCtlPktCount); VSOCK_RESET_ARRAY(vSockStatsProduceQueueHist); VSOCK_RESET_ARRAY(vSockStatsConsumeQueueHist); #undef VSOCK_RESET_ARRAY Atomic_Write64(&vSockStatsConsumeTotal, 0); Atomic_Write64(&vSockStatsProduceTotal, 0); } #else #define VSOCK_STATS_STREAM_CONSUME_HIST(vsk) #define VSOCK_STATS_STREAM_PRODUCE_HIST(vsk) #define VSOCK_STATS_STREAM_PRODUCE(bytes) #define VSOCK_STATS_STREAM_CONSUME(bytes) #define VSOCK_STATS_CTLPKT_LOG(pktType) #define VSOCK_STATS_CTLPKT_DUMP_ALL() #define VSOCK_STATS_HIST_DUMP_ALL() #define VSOCK_STATS_TOTALS_DUMP_ALL() #define VSOCK_STATS_RESET() #endif // VSOCK_GATHER_STATISTICS #endif // __STATS_H__ open-vm-tools-9.4.0-1280544/modules/linux/vsock/linux/util.c0000644765153500003110000005273112220061556021663 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * util.c -- * * Utility functions for Linux VSocket module. */ #include "driver-config.h" #include #include #include "compat_sock.h" #include "af_vsock.h" #include "util.h" struct list_head vsockBindTable[VSOCK_HASH_SIZE + 1]; struct list_head vsockConnectedTable[VSOCK_HASH_SIZE]; struct list_head vsockSeqTable[VSOCK_HASH_SIZE]; DEFINE_SPINLOCK(vsockTableLock); DEFINE_SPINLOCK(vsockSeqTableLock); /* *---------------------------------------------------------------------------- * * VSockVmciLogPkt -- * * Logs the provided packet. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void VSockVmciLogPkt(char const *function, // IN uint32 line, // IN VSockPacket *pkt) // IN { char buf[256]; char *cur = buf; int left = sizeof buf; int written = 0; char *typeStrings[] = { [VSOCK_PACKET_TYPE_INVALID] = "INVALID", [VSOCK_PACKET_TYPE_REQUEST] = "REQUEST", [VSOCK_PACKET_TYPE_NEGOTIATE] = "NEGOTIATE", [VSOCK_PACKET_TYPE_OFFER] = "OFFER", [VSOCK_PACKET_TYPE_ATTACH] = "ATTACH", [VSOCK_PACKET_TYPE_WROTE] = "WROTE", [VSOCK_PACKET_TYPE_READ] = "READ", [VSOCK_PACKET_TYPE_RST] = "RST", [VSOCK_PACKET_TYPE_SHUTDOWN] = "SHUTDOWN", [VSOCK_PACKET_TYPE_WAITING_WRITE] = "WAITING_WRITE", [VSOCK_PACKET_TYPE_WAITING_READ] = "WAITING_READ", [VSOCK_PACKET_TYPE_REQUEST2] = "REQUEST2", [VSOCK_PACKET_TYPE_NEGOTIATE2] = "NEGOTIATE2", }; written = snprintf(cur, left, "PKT: %u:%u -> %u:%u", VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.src), pkt->srcPort, VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.dst), pkt->dstPort); if (written >= left) { goto error; } left -= written; cur += written; switch (pkt->type) { case VSOCK_PACKET_TYPE_REQUEST: case VSOCK_PACKET_TYPE_NEGOTIATE: written = snprintf(cur, left, ", %s, size = %"FMT64"u", typeStrings[pkt->type], pkt->u.size); break; case VSOCK_PACKET_TYPE_OFFER: case VSOCK_PACKET_TYPE_ATTACH: written = snprintf(cur, left, ", %s, handle = %u:%u", typeStrings[pkt->type], VMCI_HANDLE_TO_CONTEXT_ID(pkt->u.handle), VMCI_HANDLE_TO_RESOURCE_ID(pkt->u.handle)); break; case VSOCK_PACKET_TYPE_WROTE: case VSOCK_PACKET_TYPE_READ: case VSOCK_PACKET_TYPE_RST: written = snprintf(cur, left, ", %s", typeStrings[pkt->type]); break; case VSOCK_PACKET_TYPE_SHUTDOWN: { Bool recv; Bool send; recv = pkt->u.mode & RCV_SHUTDOWN; send = pkt->u.mode & SEND_SHUTDOWN; written = snprintf(cur, left, ", %s, mode = %c%c", typeStrings[pkt->type], recv ? 'R' : ' ', send ? 'S' : ' '); } break; case VSOCK_PACKET_TYPE_WAITING_WRITE: case VSOCK_PACKET_TYPE_WAITING_READ: written = snprintf(cur, left, ", %s, generation = %"FMT64"u, " "offset = %"FMT64"u", typeStrings[pkt->type], pkt->u.wait.generation, pkt->u.wait.offset); break; case VSOCK_PACKET_TYPE_REQUEST2: case VSOCK_PACKET_TYPE_NEGOTIATE2: written = snprintf(cur, left, ", %s, size = %"FMT64"u, " "proto = %u", typeStrings[pkt->type], pkt->u.size, pkt->proto); break; default: written = snprintf(cur, left, ", unrecognized type"); } if (written >= left) { goto error; } left -= written; cur += written; written = snprintf(cur, left, " [%s:%u]\n", function, line); if (written >= left) { goto error; } LOG(8, ("%s", buf)); return; error: LOG(8, ("could not log packet\n")); } /* *---------------------------------------------------------------------------- * * VSockVmciInitTables -- * * Initializes the tables used for socket lookup. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void VSockVmciInitTables(void) { uint32 i; for (i = 0; i < ARRAYSIZE(vsockBindTable); i++) { INIT_LIST_HEAD(&vsockBindTable[i]); } for (i = 0; i < ARRAYSIZE(vsockConnectedTable); i++) { INIT_LIST_HEAD(&vsockConnectedTable[i]); } for (i = 0; i < ARRAYSIZE(vsockSeqTable); i++) { INIT_LIST_HEAD(&vsockSeqTable[i]); } } /* *---------------------------------------------------------------------------- * * __VSockVmciInsertBound -- * * Inserts socket into the bound table. * * Note that this assumes any necessary locks are held. * * Results: * None. * * Side effects: * The reference count for sk is incremented. * *---------------------------------------------------------------------------- */ void __VSockVmciInsertBound(struct list_head *list, // IN struct sock *sk) // IN { VSockVmciSock *vsk; ASSERT(list); ASSERT(sk); vsk = vsock_sk(sk); sock_hold(sk); list_add(&vsk->boundTable, list); } /* *---------------------------------------------------------------------------- * * __VSockVmciInsertConnected -- * * Inserts socket into the connected table. * * Note that this assumes any necessary locks are held. * * Results: * None. * * Side effects: * The reference count for sk is incremented. * *---------------------------------------------------------------------------- */ void __VSockVmciInsertConnected(struct list_head *list, // IN struct sock *sk) // IN { VSockVmciSock *vsk; ASSERT(list); ASSERT(sk); vsk = vsock_sk(sk); sock_hold(sk); list_add(&vsk->connectedTable, list); } /* *---------------------------------------------------------------------------- * * __VSockVmciInsertSeq -- * * Inserts socket into the sequential table. * * Note that this assumes any necessary locks are held. * * Results: * None. * * Side effects: * The reference count for sk is incremented. * *---------------------------------------------------------------------------- */ void __VSockVmciInsertSeq(struct list_head *list, // IN struct sock *sk) // IN { VSockVmciSock *vsk; ASSERT(list); ASSERT(sk); vsk = vsock_sk(sk); sock_hold(sk); list_add(&vsk->seqTable, list); } /* *---------------------------------------------------------------------------- * * __VSockVmciRemoveBound -- * * Removes socket from the bound table. * * Note that this assumes any necessary locks are held. * * Results: * None. * * Side effects: * The reference count for sk is decremented. * *---------------------------------------------------------------------------- */ void __VSockVmciRemoveBound(struct sock *sk) // IN { VSockVmciSock *vsk; ASSERT(sk); ASSERT(__VSockVmciInBoundTable(sk)); vsk = vsock_sk(sk); list_del_init(&vsk->boundTable); sock_put(sk); } /* *---------------------------------------------------------------------------- * * __VSockVmciRemoveConnected -- * * Removes socket from the connected table. * * Note that this assumes any necessary locks are held. * * Results: * None. * * Side effects: * The reference count for sk is decremented. * *---------------------------------------------------------------------------- */ void __VSockVmciRemoveConnected(struct sock *sk) // IN { VSockVmciSock *vsk; ASSERT(sk); ASSERT(__VSockVmciInConnectedTable(sk)); vsk = vsock_sk(sk); list_del_init(&vsk->connectedTable); sock_put(sk); } /* *---------------------------------------------------------------------------- * * __VSockVmciRemoveSeq -- * * Removes socket from the sequential table. * * Note that this assumes any necessary locks are held. * * Results: * None. * * Side effects: * The reference count for sk is decremented. * *---------------------------------------------------------------------------- */ void __VSockVmciRemoveSeq(struct sock *sk) // IN { VSockVmciSock *vsk; ASSERT(sk); ASSERT(__VSockVmciInSeqTable(sk)); vsk = vsock_sk(sk); list_del_init(&vsk->seqTable); sock_put(sk); } /* *---------------------------------------------------------------------------- * * __VSockVmciFindBoundSocket -- * * Finds the socket corresponding to the provided address in the bound * sockets hash table. * * Note that this assumes any necessary locks are held. * * Results: * The sock structure if found, NULL if not found. * * Side effects: * None. * *---------------------------------------------------------------------------- */ struct sock * __VSockVmciFindBoundSocket(struct sockaddr_vm *addr) // IN { VSockVmciSock *vsk; struct sock *sk; ASSERT(addr); list_for_each_entry(vsk, vsockBoundSockets(addr), boundTable) { if (VSockAddr_EqualsAddrAny(addr, &vsk->localAddr)) { sk = sk_vsock(vsk); /* We only store stream sockets in the bound table. */ ASSERT(sk->sk_socket ? sk->sk_socket->type == SOCK_STREAM : 1); goto found; } } sk = NULL; found: return sk; } /* *---------------------------------------------------------------------------- * * __VSockVmciFindConnectedSocket -- * * Finds the socket corresponding to the provided addresses in the connected * sockets hash table. * * Note that this assumes any necessary locks are held. * * Results: * The sock structure if found, NULL if not found. * * Side effects: * None. * *---------------------------------------------------------------------------- */ struct sock * __VSockVmciFindConnectedSocket(struct sockaddr_vm *src, // IN struct sockaddr_vm *dst) // IN { VSockVmciSock *vsk; struct sock *sk; ASSERT(src); ASSERT(dst); list_for_each_entry(vsk, vsockConnectedSockets(src, dst), connectedTable) { if (VSockAddr_EqualsAddr(src, &vsk->remoteAddr) && VSockAddr_EqualsAddr(dst, &vsk->localAddr)) { sk = sk_vsock(vsk); goto found; } } sk = NULL; found: return sk; } /* *---------------------------------------------------------------------------- * * __VSockVmciInBoundTable -- * * Determines whether the provided socket is in the bound table. * * Results: * TRUE is socket is in bound table, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool __VSockVmciInBoundTable(struct sock *sk) // IN { VSockVmciSock *vsk; ASSERT(sk); vsk = vsock_sk(sk); return !list_empty(&vsk->boundTable); } /* *---------------------------------------------------------------------------- * * __VSockVmciInConnectedTable -- * * Determines whether the provided socket is in the connected table. * * Results: * TRUE is socket is in connected table, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool __VSockVmciInConnectedTable(struct sock *sk) // IN { VSockVmciSock *vsk; ASSERT(sk); vsk = vsock_sk(sk); return !list_empty(&vsk->connectedTable); } /* *---------------------------------------------------------------------------- * * __VSockVmciInSeqTable -- * * Determines whether the provided socket is in the sequential table. * * Results: * TRUE is socket is in sequential table, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool __VSockVmciInSeqTable(struct sock *sk) // IN { VSockVmciSock *vsk; ASSERT(sk); vsk = vsock_sk(sk); return !list_empty(&vsk->seqTable); } /* *---------------------------------------------------------------------------- * * VSockVmciGetPending -- * * Retrieves a pending connection that matches the addresses specified in * the provided packet. * * Assumes the socket lock is held for listener. * * Results: * Socket of the pending connection on success, NULL if not found. * * Side effects: * A reference is held on the socket until the release function is called. * *---------------------------------------------------------------------------- */ struct sock * VSockVmciGetPending(struct sock *listener, // IN: listening socket VSockPacket *pkt) // IN: incoming packet { VSockVmciSock *vlistener; VSockVmciSock *vpending; struct sock *pending; ASSERT(listener); ASSERT(pkt); vlistener = vsock_sk(listener); list_for_each_entry(vpending, &vlistener->pendingLinks, pendingLinks) { struct sockaddr_vm src; struct sockaddr_vm dst; VSockAddr_Init(&src, VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.src), pkt->srcPort); VSockAddr_Init(&dst, VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.dst), pkt->dstPort); if (VSockAddr_EqualsAddr(&src, &vpending->remoteAddr) && VSockAddr_EqualsAddr(&dst, &vpending->localAddr)) { pending = sk_vsock(vpending); sock_hold(pending); goto found; } } pending = NULL; found: return pending; } /* *---------------------------------------------------------------------------- * * VSockVmciReleasePending -- * * Releases the reference on a socket previously obtained by a call to * VSockVmciGetPending(). * * Results: * None. * * Side effects: * The socket may be freed if this was the last reference. * *---------------------------------------------------------------------------- */ void VSockVmciReleasePending(struct sock *pending) // IN: pending connection { ASSERT(pending); sock_put(pending); } /* *---------------------------------------------------------------------------- * * VSockVmciAddPending -- * * Adds a pending connection on listener's pending list. * * Assumes the socket lock is held for listener. * Assumes the socket lock is held for pending. * * Results: * None. * * Side effects: * The reference count of the sockets is incremented. * *---------------------------------------------------------------------------- */ void VSockVmciAddPending(struct sock *listener, // IN: listening socket struct sock *pending) // IN: pending connection { VSockVmciSock *vlistener; VSockVmciSock *vpending; ASSERT(listener); ASSERT(pending); vlistener = vsock_sk(listener); vpending = vsock_sk(pending); sock_hold(pending); sock_hold(listener); list_add_tail(&vpending->pendingLinks, &vlistener->pendingLinks); } /* *---------------------------------------------------------------------------- * * VSockVmciRemovePending -- * * Removes a pending connection from the listener's pending list. * * Assumes the socket lock is held for listener. * Assumes the socket lock is held for pending. * * Results: * None. * * Side effects: * The reference count of the sockets is decremented. * *---------------------------------------------------------------------------- */ void VSockVmciRemovePending(struct sock *listener, // IN: listening socket struct sock *pending) // IN: pending connection { VSockVmciSock *vpending; ASSERT(listener); ASSERT(pending); vpending = vsock_sk(pending); list_del_init(&vpending->pendingLinks); sock_put(listener); sock_put(pending); } /* *---------------------------------------------------------------------------- * * VSockVmciEnqueueAccept -- * * Enqueues the connected socket on the listening socket's accepting * queue. * * Assumes the socket lock is held for listener. * Assumes the socket lock is held for connected. * * Results: * None. * * Side effects: * The sockets' reference counts are incremented. * *---------------------------------------------------------------------------- */ void VSockVmciEnqueueAccept(struct sock *listener, // IN: listening socket struct sock *connected) // IN: connected socket { VSockVmciSock *vlistener; VSockVmciSock *vconnected; ASSERT(listener); ASSERT(connected); vlistener = vsock_sk(listener); vconnected = vsock_sk(connected); sock_hold(connected); sock_hold(listener); list_add_tail(&vconnected->acceptQueue, &vlistener->acceptQueue); } /* *---------------------------------------------------------------------------- * * VSockVmciDequeueAccept -- * * Dequeues the next connected socket from the listening socket's accept * queue. * * Assumes the socket lock is held for listener. * * Note that the caller must call sock_put() on the returned socket once it * is done with the socket. * * Results: * The next socket from the queue, or NULL if the queue is empty. * * Side effects: * The reference count of the listener is decremented. * *---------------------------------------------------------------------------- */ struct sock * VSockVmciDequeueAccept(struct sock *listener) // IN: listening socket { VSockVmciSock *vlistener; VSockVmciSock *vconnected; ASSERT(listener); vlistener = vsock_sk(listener); if (list_empty(&vlistener->acceptQueue)) { return NULL; } vconnected = list_entry(vlistener->acceptQueue.next, VSockVmciSock, acceptQueue); ASSERT(vconnected); list_del_init(&vconnected->acceptQueue); sock_put(listener); /* * The caller will need a reference on the connected socket so we let it * call sock_put(). */ ASSERT(sk_vsock(vconnected)); return sk_vsock(vconnected); } /* *---------------------------------------------------------------------------- * * VSockVmciRemoveAccept -- * * Removes a socket from the accept queue of a listening socket. * * Assumes the socket lock is held for listener. * Assumes the socket lock is held for connected. * * Results: * None. * * Side effects: * The sockets' reference counts are decremented. * *---------------------------------------------------------------------------- */ void VSockVmciRemoveAccept(struct sock *listener, // IN: listening socket struct sock *connected) // IN: connected socket { VSockVmciSock *vconnected; ASSERT(listener); ASSERT(connected); if (!VSockVmciInAcceptQueue(connected)) { return; } vconnected = vsock_sk(connected); ASSERT(vconnected->listener == listener); list_del_init(&vconnected->acceptQueue); sock_put(listener); sock_put(connected); } /* *---------------------------------------------------------------------------- * * VSockVmciInAcceptQueue -- * * Determines whether a socket is on an accept queue. * * Assumes the socket lock is held for sk. * * Results: * TRUE if the socket is in an accept queue, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool VSockVmciInAcceptQueue(struct sock *sk) // IN: socket { ASSERT(sk); /* * If our accept queue isn't empty, it means we're linked into some listener * socket's accept queue. */ return !VSockVmciIsAcceptQueueEmpty(sk); } /* *---------------------------------------------------------------------------- * * VSockVmciIsAcceptQueueEmpty -- * * Determines whether the provided socket's accept queue is empty. * * Assumes the socket lock is held for sk. * * Results: * TRUE if the socket's accept queue is empty, FALSE otherwsise. * * Side effects: * None. * * *---------------------------------------------------------------------------- */ Bool VSockVmciIsAcceptQueueEmpty(struct sock *sk) // IN: socket { VSockVmciSock *vsk; ASSERT(sk); vsk = vsock_sk(sk); return list_empty(&vsk->acceptQueue); } /* *---------------------------------------------------------------------------- * * VSockVmciIsPending -- * * Determines whether a socket is pending. * * Assumes the socket lock is held for sk. * * Results: * TRUE if the socket is pending, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool VSockVmciIsPending(struct sock *sk) // IN: socket { VSockVmciSock *vsk; ASSERT(sk); vsk = vsock_sk(sk); return !list_empty(&vsk->pendingLinks); } open-vm-tools-9.4.0-1280544/modules/linux/vsock/linux/vsockAddr.h0000644765153500003110000000406512220061556022630 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vsockAddr.h -- * * VSockets address constants, types and functions. */ #ifndef _VSOCK_ADDR_H_ #define _VSOCK_ADDR_H_ /* Assert that the given address is valid. */ #define VSOCK_ADDR_ASSERT(_a) \ ASSERT(0 == VSockAddr_Validate((_a))) #define VSOCK_ADDR_NOFAMILY_ASSERT(_a) \ ASSERT(0 == VSockAddr_ValidateNoFamily((_a))) void VSockAddr_Init(struct sockaddr_vm *addr, uint32 cid, uint32 port); void VSockAddr_InitNoFamily(struct sockaddr_vm *addr, uint32 cid, uint32 port); int32 VSockAddr_Validate(const struct sockaddr_vm *addr); int32 VSockAddr_ValidateNoFamily(const struct sockaddr_vm *addr); Bool VSockAddr_Bound(struct sockaddr_vm *addr); void VSockAddr_Unbind(struct sockaddr_vm *addr); Bool VSockAddr_EqualsAddr(struct sockaddr_vm *addr, struct sockaddr_vm *other); Bool VSockAddr_EqualsAddrAny(struct sockaddr_vm *addr, struct sockaddr_vm *other); Bool VSockAddr_EqualsHandlePort(struct sockaddr_vm *addr, VMCIHandle handle, uint32 port); int32 VSockAddr_Cast(const struct sockaddr *addr, int32 len, struct sockaddr_vm **outAddr); Bool VSockAddr_SocketContextStream(uint32 cid); Bool VSockAddr_SocketContextDgram(uint32 cid, uint32 rid); #endif // _VSOCK_ADDR_H_ open-vm-tools-9.4.0-1280544/modules/linux/vsock/linux/stats.c0000644765153500003110000000251312220061556022035 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * stats.c -- * * Linux stats for the VMCI Stream Sockets protocol. */ #include "driver-config.h" #include #include "compat_sock.h" #include "af_vsock.h" #include "stats.h" #ifdef VSOCK_GATHER_STATISTICS uint64 vSockStatsCtlPktCount[VSOCK_PACKET_TYPE_MAX]; uint64 vSockStatsConsumeQueueHist[VSOCK_NUM_QUEUE_LEVEL_BUCKETS]; uint64 vSockStatsProduceQueueHist[VSOCK_NUM_QUEUE_LEVEL_BUCKETS]; Atomic_uint64 vSockStatsConsumeTotal; Atomic_uint64 vSockStatsProduceTotal; #endif open-vm-tools-9.4.0-1280544/modules/linux/vsock/linux/vmci_sockets_packet.h0000644765153500003110000001355012220061556024727 0ustar dtormts/********************************************************* * Copyright (C) 2012 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmci_sockets_packet.h -- * * Definition of VMCI Sockets packet format, constants, and types. */ #ifndef _VMCI_SOCKETS_PACKET_H_ #define _VMCI_SOCKETS_PACKET_H_ #include "vmci_defs.h" #include "vmci_call_defs.h" /* * STREAM control packets. */ /* If the packet format changes in a release then this should change too. */ #define VSOCK_PACKET_VERSION 1 /* The resource ID on which control packets are sent. */ #define VSOCK_PACKET_RID 1 /* * Assert that the given packet is valid. * We check that the two original reserved fields equal zero because the * version of the common code that shipped with ESX 4.0 and WS 6.5 did so and * will return a RST packet if they aren't set that way. For newer packet * types added after that release we don't do this. */ #define VSOCK_PACKET_ASSERT(_p) \ do { \ ASSERT((_p)); \ ASSERT((_p)->type < VSOCK_PACKET_TYPE_MAX); \ if ((_p)->type < VSOCK_PACKET_TYPE_REQUEST2) { \ ASSERT(0 == (_p)->proto); \ ASSERT(0 == (_p)->_reserved2); \ } \ } while(0) typedef enum VSockPacketType { VSOCK_PACKET_TYPE_INVALID = 0, // Invalid type. VSOCK_PACKET_TYPE_REQUEST, // Connection request (WR/WW/READ/WRITE) VSOCK_PACKET_TYPE_NEGOTIATE, // Connection negotiate. VSOCK_PACKET_TYPE_OFFER, // Connection offer queue pair. VSOCK_PACKET_TYPE_ATTACH, // Connection attach. VSOCK_PACKET_TYPE_WROTE, // Wrote data to queue pair. VSOCK_PACKET_TYPE_READ, // Read data from queue pair. VSOCK_PACKET_TYPE_RST, // Reset. VSOCK_PACKET_TYPE_SHUTDOWN, // Shutdown the connection. VSOCK_PACKET_TYPE_WAITING_WRITE, // Notify peer we are waiting to write. VSOCK_PACKET_TYPE_WAITING_READ, // Notify peer we are waiting to read. VSOCK_PACKET_TYPE_REQUEST2, // Connection request (new proto flags) VSOCK_PACKET_TYPE_NEGOTIATE2, // Connection request (new proto flags) VSOCK_PACKET_TYPE_MAX // Last message. } VSockPacketType; typedef uint16 VSockProtoVersion; #define VSOCK_PROTO_INVALID 0 // Invalid protocol version. #define VSOCK_PROTO_PKT_ON_NOTIFY (1 << 0) // Queuepair inspection proto. #define VSOCK_PROTO_ALL_SUPPORTED (VSOCK_PROTO_PKT_ON_NOTIFY) typedef struct VSockWaitingInfo { uint64 generation; // Generation of the queue. uint64 offset; // Offset within the queue. } VSockWaitingInfo; /* * Control packet type for STREAM sockets. DGRAMs have no control packets * nor special packet header for data packets, they are just raw VMCI DGRAM * messages. For STREAMs, control packets are sent over the control channel * while data is written and read directly from queue pairs with no packet * format. */ typedef struct VSockPacket { VMCIDatagram dg; // Datagram header. uint8 version; // Version. uint8 type; // Type of message. VSockProtoVersion proto; // Supported proto versions in CONNECT2 and // NEGOTIATE2. 0 otherwise. uint32 srcPort; // Source port. uint32 dstPort; // Destination port. uint32 _reserved2; // Reserved. union { uint64 size; // Size of queue pair for request/negotiation. uint64 mode; // Mode of shutdown for shutdown. VMCIHandle handle; // Queue pair handle once size negotiated. VSockWaitingInfo wait; // Information provided for wait notifications. } u; } VSockPacket; /* * SEQPACKET packets. */ #define VSOCK_SEQ_PACKET_VERSION_1 1 #define VSOCK_SEQ_PACKET_VERSION VSOCK_SEQ_PACKET_VERSION_1 /* Get the packet's payload size in bytes. */ #define VSOCK_SEQ_PACKET_PAYLOAD_SIZE(_pkt) \ (VMCI_DG_SIZE(&(_pkt)->hdr.dg) - (_pkt)->hdr.offset) /* Get a pointer to the packet's payload. */ #define VSOCK_SEQ_PACKET_PAYLOAD(_pkt) \ (void *)((char *)_pkt + (_pkt)->hdr.offset) typedef enum VSockSeqPacketType { VSOCK_SEQ_PACKET_TYPE_INVALID = 0, // Invalid type. VSOCK_SEQ_PACKET_TYPE_CONNECT, // Connection request. VSOCK_SEQ_PACKET_TYPE_DATA, // Data. VSOCK_SEQ_PACKET_TYPE_SHUTDOWN, // Shutdown. VSOCK_SEQ_PACKET_TYPE_CLOSE, // Close (graceful or error). } VSockSeqPacketType; /* Header for all packet versions. */ typedef struct VSockSeqPacketHdr { VMCIDatagram dg; // Datagram header. uint8 version; // Version. uint8 type; // Type of message. uint16 offset; // Offset of data from start of packet. int32 val; // Value. } VSockSeqPacketHdr; /* Combination of all versions. */ typedef struct VSockSeqPacket { VSockSeqPacketHdr hdr; /* Other versions go here. */ /* Data is at base + hdr.offset. */ } VSockSeqPacket; /* * Size assertions. */ MY_ASSERTS(VSockSeqPacketAsserts, ASSERT_ON_COMPILE(sizeof (VSockPacket) == 56); ASSERT_ON_COMPILE(sizeof (VSockSeqPacket) == 32); ) #endif // _VMCI_SOCKETS_PACKET_H_ open-vm-tools-9.4.0-1280544/modules/linux/vsock/linux/af_vsock.h0000644765153500003110000002067712220061556022512 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * af_vsock.h -- * * Definitions for Linux VSockets module. */ #ifndef __AF_VSOCK_H__ #define __AF_VSOCK_H__ #include "vsockCommon.h" #include "vsockPacket.h" #include "compat_workqueue.h" #include "vmciKernelAPI.h" #include "notify.h" #ifdef VMX86_DEVEL extern int LOGLEVEL_THRESHOLD; #define LOG(level, args) ((void) (LOGLEVEL_THRESHOLD >= (level) ? (Log args) : 0)) #else #define LOG(level, args) #endif # define vsock_sk(__sk) ((VSockVmciSock *)__sk) # define sk_vsock(__vsk) (&(__vsk)->sk) typedef struct VSockVmciSock { /* sk must be the first member. */ struct sock sk; struct sockaddr_vm localAddr; struct sockaddr_vm remoteAddr; /* Links for the global tables of bound, connected and sequential sockets. */ struct list_head boundTable; struct list_head connectedTable; struct list_head seqTable; /* * Accessed without the socket lock held. This means it can never be * modified outsided of socket create or destruct. */ Bool trusted; Bool cachedPeerAllowDgram; /* Dgram communication allowed to cached peer? */ VMCIId cachedPeer; /* Context ID of last dgram destination check. */ uid_t owner; VMCIHandle dgHandle; /* For SOCK_DGRAM only. */ /* Rest are SOCK_STREAM only. */ VMCIHandle qpHandle; VMCIQPair *qpair; uint64 produceSize; uint64 consumeSize; uint64 queuePairSize; uint64 queuePairMinSize; uint64 queuePairMaxSize; long connectTimeout; VSockVmciNotify notify; VSockVmciNotifyOps *notifyOps; VMCIId attachSubId; VMCIId detachSubId; /* Listening socket that this came from. */ struct sock *listener; /* * Used for pending list and accept queue during connection handshake. The * listening socket is the head for both lists. Sockets created for * connection requests are placed in the pending list until they are * connected, at which point they are put in the accept queue list so they * can be accepted in accept(). If accept() cannot accept the connection, * it is marked as rejected so the cleanup function knows to clean up the * socket. */ struct list_head pendingLinks; struct list_head acceptQueue; Bool rejected; compat_delayed_work dwork; uint32 peerShutdown; Bool sentRequest; Bool ignoreConnectingRst; } VSockVmciSock; int VSockVmciSendControlPktBH(struct sockaddr_vm *src, struct sockaddr_vm *dst, VSockPacketType type, uint64 size, uint64 mode, VSockWaitingInfo *wait, VMCIHandle handle); int VSockVmciReplyControlPktFast(VSockPacket *pkt, VSockPacketType type, uint64 size, uint64 mode, VSockWaitingInfo *wait, VMCIHandle handle); int VSockVmciSendControlPkt(struct sock *sk, VSockPacketType type, uint64 size, uint64 mode, VSockWaitingInfo *wait, VSockProtoVersion version, VMCIHandle handle); int64 VSockVmciStreamHasData(VSockVmciSock *vsk); int64 VSockVmciStreamHasSpace(VSockVmciSock *vsk); #define VSOCK_SEND_RESET_BH(_dst, _src, _pkt) \ ((_pkt)->type == VSOCK_PACKET_TYPE_RST) ? \ 0 : \ VSockVmciSendControlPktBH(_dst, _src, VSOCK_PACKET_TYPE_RST, 0, \ 0, NULL, VMCI_INVALID_HANDLE) #define VSOCK_SEND_INVALID_BH(_dst, _src) \ VSockVmciSendControlPktBH(_dst, _src, VSOCK_PACKET_TYPE_INVALID, 0, \ 0, NULL, VMCI_INVALID_HANDLE) #define VSOCK_SEND_WROTE_BH(_dst, _src) \ VSockVmciSendControlPktBH(_dst, _src, VSOCK_PACKET_TYPE_WROTE, 0, \ 0, NULL, VMCI_INVALID_HANDLE) #define VSOCK_SEND_READ_BH(_dst, _src) \ VSockVmciSendControlPktBH(_dst, _src, VSOCK_PACKET_TYPE_READ, 0, \ 0, NULL, VMCI_INVALID_HANDLE) #define VSOCK_SEND_RESET(_sk, _pkt) \ ((_pkt)->type == VSOCK_PACKET_TYPE_RST) ? \ 0 : \ VSockVmciSendControlPkt(_sk, VSOCK_PACKET_TYPE_RST, \ 0, 0, NULL, VSOCK_PROTO_INVALID, \ VMCI_INVALID_HANDLE) #define VSOCK_SEND_NEGOTIATE(_sk, _size) \ VSockVmciSendControlPkt(_sk, VSOCK_PACKET_TYPE_NEGOTIATE, \ _size, 0, NULL, VSOCK_PROTO_INVALID, \ VMCI_INVALID_HANDLE) #define VSOCK_SEND_NEGOTIATE2(_sk, _size, signalProto) \ VSockVmciSendControlPkt(_sk, VSOCK_PACKET_TYPE_NEGOTIATE2, \ _size, 0, NULL, signalProto, \ VMCI_INVALID_HANDLE) #define VSOCK_SEND_QP_OFFER(_sk, _handle) \ VSockVmciSendControlPkt(_sk, VSOCK_PACKET_TYPE_OFFER, \ 0, 0, NULL, VSOCK_PROTO_INVALID, _handle) #define VSOCK_SEND_CONN_REQUEST(_sk, _size) \ VSockVmciSendControlPkt(_sk, VSOCK_PACKET_TYPE_REQUEST, \ _size, 0, NULL, VSOCK_PROTO_INVALID, \ VMCI_INVALID_HANDLE) #define VSOCK_SEND_CONN_REQUEST2(_sk, _size, signalProto) \ VSockVmciSendControlPkt(_sk, VSOCK_PACKET_TYPE_REQUEST2, \ _size, 0, NULL, signalProto, \ VMCI_INVALID_HANDLE) #define VSOCK_SEND_ATTACH(_sk, _handle) \ VSockVmciSendControlPkt(_sk, VSOCK_PACKET_TYPE_ATTACH, \ 0, 0, NULL, VSOCK_PROTO_INVALID, _handle) #define VSOCK_SEND_WROTE(_sk) \ VSockVmciSendControlPkt(_sk, VSOCK_PACKET_TYPE_WROTE, \ 0, 0, NULL, VSOCK_PROTO_INVALID, \ VMCI_INVALID_HANDLE) #define VSOCK_SEND_READ(_sk) \ VSockVmciSendControlPkt(_sk, VSOCK_PACKET_TYPE_READ, \ 0, 0, NULL, VSOCK_PROTO_INVALID, \ VMCI_INVALID_HANDLE) #define VSOCK_SEND_SHUTDOWN(_sk, _mode) \ VSockVmciSendControlPkt(_sk, VSOCK_PACKET_TYPE_SHUTDOWN, \ 0, _mode, NULL, VSOCK_PROTO_INVALID, \ VMCI_INVALID_HANDLE) #define VSOCK_SEND_WAITING_WRITE(_sk, _waitInfo) \ VSockVmciSendControlPkt(_sk, VSOCK_PACKET_TYPE_WAITING_WRITE, \ 0, 0, _waitInfo, VSOCK_PROTO_INVALID, \ VMCI_INVALID_HANDLE) #define VSOCK_SEND_WAITING_READ(_sk, _waitInfo) \ VSockVmciSendControlPkt(_sk, VSOCK_PACKET_TYPE_WAITING_READ, \ 0, 0, _waitInfo, VSOCK_PROTO_INVALID, \ VMCI_INVALID_HANDLE) #define VSOCK_REPLY_RESET(_pkt) \ VSockVmciReplyControlPktFast(_pkt, VSOCK_PACKET_TYPE_RST, \ 0, 0, NULL, VMCI_INVALID_HANDLE) #endif /* __AF_VSOCK_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/vsock/linux/notifyQState.c0000644765153500003110000004646412220061556023346 0ustar dtormts/********************************************************* * Copyright (C) 2009-2011 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * notifyQState.c -- * * Linux control notifications based on Queuepair state for the VMCI * Stream Sockets protocol. */ #include "driver-config.h" #include #include "compat_sock.h" #include "notify.h" #include "af_vsock.h" #define PKT_FIELD(vsk, fieldName) \ (vsk)->notify.pktQState.fieldName /* *---------------------------------------------------------------------------- * * VSockVmciNotifyWaitingWrite -- * * Determines if the conditions have been met to notify a waiting writer. * * Results: * TRUE if a notification should be sent, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static Bool VSockVmciNotifyWaitingWrite(VSockVmciSock *vsk) // IN { Bool retval; uint64 notifyLimit; if (!PKT_FIELD(vsk, peerWaitingWrite)) { return FALSE; } /* * When the sender blocks, we take that as a sign that the sender * is faster than the receiver. To reduce the transmit rate of the * sender, we delay the sending of the read notification by * decreasing the writeNotifyWindow. The notification is delayed * until the number of bytes used in the queue drops below the * writeNotifyWindow. */ if (!PKT_FIELD(vsk, peerWaitingWriteDetected)) { PKT_FIELD(vsk, peerWaitingWriteDetected) = TRUE; if (PKT_FIELD(vsk, writeNotifyWindow) < PAGE_SIZE) { PKT_FIELD(vsk, writeNotifyWindow) = PKT_FIELD(vsk, writeNotifyMinWindow); } else { PKT_FIELD(vsk, writeNotifyWindow) -= PAGE_SIZE; if (PKT_FIELD(vsk, writeNotifyWindow) < PKT_FIELD(vsk, writeNotifyMinWindow)) { PKT_FIELD(vsk, writeNotifyWindow) = PKT_FIELD(vsk, writeNotifyMinWindow); } } } notifyLimit = vsk->consumeSize - PKT_FIELD(vsk, writeNotifyWindow); /* * The notifyLimit is used to delay notifications in the case where * flow control is enabled. Below the test is expressed in terms of * free space in the queue: * if freeSpace > ConsumeSize - writeNotifyWindow then notify * An alternate way of expressing this is to rewrite the expression * to use the data ready in the receive queue: * if writeNotifyWindow > bufferReady then notify * as freeSpace == ConsumeSize - bufferReady. */ retval = vmci_qpair_consume_free_space(vsk->qpair) > notifyLimit; if (retval) { /* * Once we notify the peer, we reset the detected flag so the * next wait will again cause a decrease in the window size. */ PKT_FIELD(vsk, peerWaitingWriteDetected) = FALSE; } return retval; } /* *---------------------------------------------------------------------------- * * VSockVmciHandleRead -- * * Handles an incoming read message. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VSockVmciHandleRead(struct sock *sk, // IN VSockPacket *pkt, // IN: unused Bool bottomHalf, // IN: unused struct sockaddr_vm *dst, // IN: unused struct sockaddr_vm *src) // IN: unused { sk->sk_write_space(sk); } /* *---------------------------------------------------------------------------- * * VSockVmciHandleWrote -- * * Handles an incoming wrote message. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VSockVmciHandleWrote(struct sock *sk, // IN VSockPacket *pkt, // IN: unused Bool bottomHalf, // IN: unused struct sockaddr_vm *dst, // IN: unused struct sockaddr_vm *src) // IN: unused { sk->sk_data_ready(sk, 0); } /* *---------------------------------------------------------------------------- * * VSockVmciBlockUpdateWriteWindow -- * * Updates the write window when we are blocking for data. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VSockVmciBlockUpdateWriteWindow(struct sock *sk) // IN { VSockVmciSock *vsk; vsk = vsock_sk(sk); if (PKT_FIELD(vsk, writeNotifyWindow) < vsk->consumeSize) { PKT_FIELD(vsk, writeNotifyWindow) = MIN(PKT_FIELD(vsk, writeNotifyWindow) + PAGE_SIZE, vsk->consumeSize); } } /* *---------------------------------------------------------------------------- * * VSockVmciSendReadNotification -- * * Sends a read notification to this socket's peer. * * Results: * >= 0 if the datagram is sent successfully, negative error value * otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciSendReadNotification(struct sock *sk) // IN { VSockVmciSock *vsk; Bool sentRead; unsigned int retries; int err; ASSERT(sk); vsk = vsock_sk(sk); sentRead = FALSE; retries = 0; err = 0; if (VSockVmciNotifyWaitingWrite(vsk)) { /* * Notify the peer that we have read, retrying the send on failure up to our * maximum value. XXX For now we just log the failure, but later we should * schedule a work item to handle the resend until it succeeds. That would * require keeping track of work items in the vsk and cleaning them up upon * socket close. */ while (!(vsk->peerShutdown & RCV_SHUTDOWN) && !sentRead && retries < VSOCK_MAX_DGRAM_RESENDS) { err = VSOCK_SEND_READ(sk); if (err >= 0) { sentRead = TRUE; } retries++; } if (retries >= VSOCK_MAX_DGRAM_RESENDS && !sentRead) { Warning("unable to send read notification to peer for socket %p.\n", sk); } else { PKT_FIELD(vsk, peerWaitingWrite) = FALSE; } } return err; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktSocketInit -- * * Function that is called after a socket is created and before any * notify ops are used. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VSockVmciNotifyPktSocketInit(struct sock *sk) // IN { VSockVmciSock *vsk; vsk = vsock_sk(sk); PKT_FIELD(vsk, writeNotifyWindow) = PAGE_SIZE; PKT_FIELD(vsk, writeNotifyMinWindow) = PAGE_SIZE; PKT_FIELD(vsk, peerWaitingWrite) = FALSE; PKT_FIELD(vsk, peerWaitingWriteDetected) = FALSE; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktSocketDestruct -- * * Function that is called when the socket is being released. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VSockVmciNotifyPktSocketDestruct(struct sock *sk) // IN { VSockVmciSock *vsk; vsk = vsock_sk(sk); PKT_FIELD(vsk, writeNotifyWindow) = PAGE_SIZE; PKT_FIELD(vsk, writeNotifyMinWindow) = PAGE_SIZE; PKT_FIELD(vsk, peerWaitingWrite) = FALSE; PKT_FIELD(vsk, peerWaitingWriteDetected) = FALSE; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktPollIn -- * * Called by the poll function to figure out if there is data to read * and to setup future notifications if needed. Only called on sockets * that aren't shutdown for recv. * * Results: * 0 on success. Negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int32 VSockVmciNotifyPktPollIn(struct sock *sk, // IN size_t target, // IN Bool *dataReadyNow) // IN { VSockVmciSock *vsk; ASSERT(sk); ASSERT(dataReadyNow); vsk = vsock_sk(sk); if (VSockVmciStreamHasData(vsk)) { *dataReadyNow = TRUE; } else { /* * We can't read right now because there is nothing in the queue. * Ask for notifications when there is something to read. */ if (sk->sk_state == SS_CONNECTED) { VSockVmciBlockUpdateWriteWindow(sk); } *dataReadyNow = FALSE; } return 0; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktPollOut * * Called by the poll function to figure out if there is space to write * and to setup future notifications if needed. Only called on a * connected socket that isn't shutdown for send. * * Results: * 0 on success. Negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int32 VSockVmciNotifyPktPollOut(struct sock *sk, // IN size_t target, // IN Bool *spaceAvailNow) // IN { int64 produceQFreeSpace; VSockVmciSock *vsk; ASSERT(sk); ASSERT(spaceAvailNow); vsk = vsock_sk(sk); produceQFreeSpace = VSockVmciStreamHasSpace(vsk); if (produceQFreeSpace > 0) { *spaceAvailNow = TRUE; return 0; } else if (produceQFreeSpace == 0) { /* * This is a connected socket but we can't currently send data. Nothing * else to do. */ *spaceAvailNow = FALSE; } return 0; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktRecvInit -- * * Called at the start of a stream recv call with the socket lock held. * * Results: * 0 on success. Negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int32 VSockVmciNotifyPktRecvInit(struct sock *sk, // IN size_t target, // IN VSockVmciRecvNotifyData *data) // IN { VSockVmciSock *vsk; ASSERT(sk); ASSERT(data); vsk = vsock_sk(sk); data->consumeHead = 0; data->produceTail = 0; data->notifyOnBlock = FALSE; if (PKT_FIELD(vsk, writeNotifyMinWindow) < target + 1) { ASSERT(target < vsk->consumeSize); PKT_FIELD(vsk, writeNotifyMinWindow) = target + 1; if (PKT_FIELD(vsk, writeNotifyWindow) < PKT_FIELD(vsk, writeNotifyMinWindow)) { /* * If the current window is smaller than the new minimal * window size, we need to reevaluate whether we need to * notify the sender. If the number of ready bytes are * smaller than the new window, we need to send a * notification to the sender before we block. */ PKT_FIELD(vsk, writeNotifyWindow) = PKT_FIELD(vsk, writeNotifyMinWindow); data->notifyOnBlock = TRUE; } } return 0; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktRecvPreBlock -- * * Called right before a socket is about to block with the socket lock * held. The socket lock may have been released between the entry * function and the preblock call. * * Note: This function may be called multiple times before the post * block function is called. * * Results: * 0 on success. Negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int32 VSockVmciNotifyPktRecvPreBlock(struct sock *sk, // IN size_t target, // IN VSockVmciRecvNotifyData *data) // IN { int err; ASSERT(sk); ASSERT(data); err = 0; VSockVmciBlockUpdateWriteWindow(sk); if (data->notifyOnBlock) { err = VSockVmciSendReadNotification(sk); if (err < 0) { return err; } data->notifyOnBlock = FALSE; } return err; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktRecvPostDequeue -- * * Called right after we dequeue / peek data from a socket. * * Results: * 0 on success. Negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int32 VSockVmciNotifyPktRecvPostDequeue(struct sock *sk, // IN size_t target, // IN ssize_t copied, // IN Bool dataRead, // IN VSockVmciRecvNotifyData *data) // IN { VSockVmciSock *vsk; int err; Bool wasFull = FALSE; uint64 freeSpace; ASSERT(sk); ASSERT(data); vsk = vsock_sk(sk); err = 0; if (dataRead) { Atomic_MFence(); freeSpace = vmci_qpair_consume_free_space(vsk->qpair); wasFull = freeSpace == copied; if (wasFull) { PKT_FIELD(vsk, peerWaitingWrite) = TRUE; } err = VSockVmciSendReadNotification(sk); if (err < 0) { return err; } /* See the comment in VSockVmciNotifyPktSendPostEnqueue */ sk->sk_data_ready(sk, 0); } return err; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktSendInit -- * * Called at the start of a stream send call with the socket lock held. * * Results: * 0 on success. A negative error code on failure. * * Side effects: * *---------------------------------------------------------------------------- */ static int32 VSockVmciNotifyPktSendInit(struct sock *sk, // IN VSockVmciSendNotifyData *data) // IN { ASSERT(sk); ASSERT(data); data->consumeHead = 0; data->produceTail = 0; return 0; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifySendPostEnqueue -- * * Called right after we enqueue data to a socket. * * Results: * 0 on success. Negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int32 VSockVmciNotifyPktSendPostEnqueue(struct sock *sk, // IN ssize_t written, // IN VSockVmciSendNotifyData *data) // IN { int err = 0; VSockVmciSock *vsk; Bool sentWrote = FALSE; Bool wasEmpty; int retries = 0; ASSERT(sk); ASSERT(data); vsk = vsock_sk(sk); Atomic_MFence(); wasEmpty = (vmci_qpair_produce_buf_ready(vsk->qpair) == written); if (wasEmpty) { while (!(vsk->peerShutdown & RCV_SHUTDOWN) && !sentWrote && retries < VSOCK_MAX_DGRAM_RESENDS) { err = VSOCK_SEND_WROTE(sk); if (err >= 0) { sentWrote = TRUE; } retries++; } } if (retries >= VSOCK_MAX_DGRAM_RESENDS && !sentWrote) { Warning("unable to send wrote notification to peer for socket %p.\n", sk); return err; } return err; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktHandlePkt * * Called when a notify packet is recieved for a socket in the connected * state. Note this might be called from a bottom half. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VSockVmciNotifyPktHandlePkt(struct sock *sk, // IN VSockPacket *pkt, // IN Bool bottomHalf, // IN struct sockaddr_vm *dst, // IN struct sockaddr_vm *src, // IN Bool *pktProcessed) // In { Bool processed = FALSE; ASSERT(sk); ASSERT(pkt); switch (pkt->type) { case VSOCK_PACKET_TYPE_WROTE: VSockVmciHandleWrote(sk, pkt, bottomHalf, dst, src); processed = TRUE; break; case VSOCK_PACKET_TYPE_READ: VSockVmciHandleRead(sk, pkt, bottomHalf, dst, src); processed = TRUE; break; } if (pktProcessed) { *pktProcessed = processed; } } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktProcessRequest * * Called near the end of process request. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VSockVmciNotifyPktProcessRequest(struct sock *sk) // IN { VSockVmciSock *vsk; ASSERT(sk); vsk = vsock_sk(sk); PKT_FIELD(vsk, writeNotifyWindow) = vsk->consumeSize; if (vsk->consumeSize < PKT_FIELD(vsk, writeNotifyMinWindow)) { PKT_FIELD(vsk, writeNotifyMinWindow) = vsk->consumeSize; } } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktProcessNegotiate * * Called near the end of process negotiate. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VSockVmciNotifyPktProcessNegotiate(struct sock *sk) // IN { VSockVmciSock *vsk; ASSERT(sk); vsk = vsock_sk(sk); PKT_FIELD(vsk, writeNotifyWindow) = vsk->consumeSize; if (vsk->consumeSize < PKT_FIELD(vsk, writeNotifyMinWindow)) { PKT_FIELD(vsk, writeNotifyMinWindow) = vsk->consumeSize; } } /* Socket always on control packet based operations. */ VSockVmciNotifyOps vSockVmciNotifyPktQStateOps = { VSockVmciNotifyPktSocketInit, VSockVmciNotifyPktSocketDestruct, VSockVmciNotifyPktPollIn, VSockVmciNotifyPktPollOut, VSockVmciNotifyPktHandlePkt, VSockVmciNotifyPktRecvInit, VSockVmciNotifyPktRecvPreBlock, NULL, /* recvPreDequeue */ VSockVmciNotifyPktRecvPostDequeue, VSockVmciNotifyPktSendInit, NULL, /* sendPreBlock */ NULL, /* sendPreEnqueue */ VSockVmciNotifyPktSendPostEnqueue, VSockVmciNotifyPktProcessRequest, VSockVmciNotifyPktProcessNegotiate, }; open-vm-tools-9.4.0-1280544/modules/linux/vsock/linux/vsockAddr.c0000644765153500003110000002574512220061556022633 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vsockAddr.c -- * * VSockets address implementation. */ /* * These includes come before vsockCommon.h to ensure that VMware's ASSERT * macro is used instead of Linux's irda.h definition. */ #if defined(linux) && !defined(VMKERNEL) # if defined(__KERNEL__) # include "driver-config.h" # include # include "compat_sock.h" # else # include # include # endif #elif defined(VMKERNEL) # include "vm_libc.h" # include "return_status.h" #elif defined(__APPLE__) # include #endif #include "vsockCommon.h" /* *----------------------------------------------------------------------------- * * VSockAddr_Init -- * * Initialize the given address with the given context id and port. This * will clear the address, set the correct family, and add the given * values. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VSockAddr_Init(struct sockaddr_vm *addr, // OUT uint32 cid, // IN uint32 port) // IN { ASSERT(addr); VSockAddr_InitNoFamily(addr, cid, port); addr->svm_family = VMCISockGetAFValueInt(); VSOCK_ADDR_ASSERT(addr); } /* *----------------------------------------------------------------------------- * * VSockAddr_InitNoFamily -- * * Initialize the given address with the given context id and port. This * will clear the address and add the given values, but not set the * family. Note that this is needed because in some places we don't want * to re-register the address family in the Linux kernel and all we need * is to check the context id and port. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VSockAddr_InitNoFamily(struct sockaddr_vm *addr, // OUT uint32 cid, // IN uint32 port) // IN { ASSERT(addr); memset(addr, 0, sizeof *addr); #if defined(__APPLE__) addr->svm_len = sizeof *addr; #endif addr->svm_cid = cid; addr->svm_port = port; VSOCK_ADDR_NOFAMILY_ASSERT(addr); } /* *----------------------------------------------------------------------------- * * VSockAddr_Validate -- * * Try to validate the given address. The address must not be null and * must have the correct address family. Any reserved fields must be * zero. * * Results: * 0 on success, EFAULT if the address is null, EAFNOSUPPORT if the * address is of the wrong family, and EINVAL if the reserved fields are * not zero. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int32 VSockAddr_Validate(const struct sockaddr_vm *addr) // IN { int32 err; if (NULL == addr) { err = EFAULT; goto exit; } if (VMCISockGetAFValueInt() != addr->svm_family) { err = EAFNOSUPPORT; goto exit; } if (0 != addr->svm_zero[0]) { err = EINVAL; goto exit; } err = 0; exit: return sockerr2err(err); } /* *----------------------------------------------------------------------------- * * VSockAddr_ValidateNoFamily -- * * Try to validate the given address. The address must not be null and * any reserved fields must be zero, but the address family is not * checked. Note that this is needed because in some places we don't want * to re-register the address family with the Linux kernel. * * Also note that we duplicate the code from _Validate() since we want to * retain the ordering or the error return values. * * Results: * 0 on success, EFAULT if the address is null and EINVAL if the reserved * fields are not zero. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int32 VSockAddr_ValidateNoFamily(const struct sockaddr_vm *addr) // IN { int32 err; if (NULL == addr) { err = EFAULT; goto exit; } if (0 != addr->svm_zero[0]) { err = EINVAL; goto exit; } err = 0; exit: return sockerr2err(err); } /* *---------------------------------------------------------------------------- * * VSockAddr_Bound -- * * Determines whether the provided address is bound. * * Results: * TRUE if the address structure is bound, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool VSockAddr_Bound(struct sockaddr_vm *addr) // IN: socket address to check { ASSERT(addr); return addr->svm_port != VMADDR_PORT_ANY; } /* *---------------------------------------------------------------------------- * * VSockAddr_Unbind -- * * Unbind the given addresss. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void VSockAddr_Unbind(struct sockaddr_vm *addr) // IN { VSockAddr_Init(addr, VMADDR_CID_ANY, VMADDR_PORT_ANY); } /* *---------------------------------------------------------------------------- * * VSockAddr_EqualsAddr -- * * Determine if the given addresses are equal. * * Results: * TRUE if the addresses are equal, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool VSockAddr_EqualsAddr(struct sockaddr_vm *addr, // IN struct sockaddr_vm *other) // IN { /* * XXX We don't ASSERT on the family here since this is used on the receive * path in Linux and we don't want to re-register the address family * unnecessarily. */ VSOCK_ADDR_NOFAMILY_ASSERT(addr); VSOCK_ADDR_NOFAMILY_ASSERT(other); return (addr->svm_cid == other->svm_cid && addr->svm_port == other->svm_port); } /* *---------------------------------------------------------------------------- * * VSockAddr_EqualsAddrAny -- * * Determine if the given addresses are equal. Will accept either an exact * match or one where the rids match and that either the cids match or * are set to VMADDR_CID_ANY. * * Results: * TRUE if the addresses are equal, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool VSockAddr_EqualsAddrAny(struct sockaddr_vm *addr, // IN struct sockaddr_vm *other) // IN { VSOCK_ADDR_NOFAMILY_ASSERT(addr); VSOCK_ADDR_NOFAMILY_ASSERT(other); if (addr->svm_cid == VMADDR_CID_ANY || other->svm_cid == VMADDR_CID_ANY || addr->svm_cid == other->svm_cid) { return (addr->svm_port == other->svm_port); } return FALSE; } /* *---------------------------------------------------------------------------- * * VSockAddr_EqualsHandlePort -- * * Determines if the given address matches the given handle and port. * * Results: * TRUE if the address matches the handle and port, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool VSockAddr_EqualsHandlePort(struct sockaddr_vm *addr, // IN VMCIHandle handle, // IN uint32 port) // IN { VSOCK_ADDR_ASSERT(addr); return (addr->svm_cid == VMCI_HANDLE_TO_CONTEXT_ID(handle) && addr->svm_port == port); } /* *----------------------------------------------------------------------------- * * VSockAddr_Cast -- * * Try to cast the given generic address to a VM address. The given * length must match that of a VM address and the address must be valid. * The "outAddr" parameter contains the address if successful. * * Results: * 0 on success, EFAULT if the length is too small. See * VSockAddr_Validate() for other possible return codes. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int32 VSockAddr_Cast(const struct sockaddr *addr, // IN int32 len, // IN struct sockaddr_vm **outAddr) // OUT { int32 err; ASSERT(outAddr); if (len < sizeof **outAddr) { err = EFAULT; goto exit; } *outAddr = (struct sockaddr_vm *) addr; err = VSockAddr_Validate(*outAddr); exit: return sockerr2err(err); } /* *---------------------------------------------------------------------------- * * VSockAddr_SocketContextStream -- * * Determines whether the provided context id represents a context that * contains a stream socket endpoints. * * Results: * TRUE if the context does have socket endpoints, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool VSockAddr_SocketContextStream(uint32 cid) // IN { uint32 i; VMCIId nonSocketContexts[] = { VMCI_HYPERVISOR_CONTEXT_ID, VMCI_WELL_KNOWN_CONTEXT_ID, }; ASSERT_ON_COMPILE(sizeof cid == sizeof *nonSocketContexts); for (i = 0; i < ARRAYSIZE(nonSocketContexts); i++) { if (cid == nonSocketContexts[i]) { return FALSE; } } return TRUE; } /* *---------------------------------------------------------------------------- * * VSockAddr_SocketContextDgram -- * * Determines whether the provided represent * a protected datagram endpoint. * * Results: * TRUE if the context does have socket endpoints, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool VSockAddr_SocketContextDgram(uint32 cid, // IN uint32 rid) // IN { if (cid == VMCI_HYPERVISOR_CONTEXT_ID) { /* * Registrations of PBRPC Servers do not modify VMX/Hypervisor state and * are allowed. */ if (rid == VMCI_UNITY_PBRPC_REGISTER) { return TRUE; } else { return FALSE; } } return TRUE; } open-vm-tools-9.4.0-1280544/modules/linux/vsock/linux/vsockSocketWrapper.h0000644765153500003110000002251112220061556024543 0ustar dtormts/********************************************************* * Copyright (C) 2007-2011 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vsockSocketWrapper.h -- * * Socket wrapper constants, types and functions. */ #ifndef _VSOCK_SOCKET_WRAPPER_H_ #define _VSOCK_SOCKET_WRAPPER_H_ /* * Socket states and flags. Note that MSG_WAITALL is only defined on 2K3, * XP-SP2 and above. Since we currently build for 2K to maintain backwards * compatibility, we pull the value from the newer header. Same for the * POLLXXX flags, which are not defined before Vista. */ #if defined(_WIN32) # define MSG_DONTWAIT 0 # define MSG_NOSIGNAL 0 # if (_WIN32_WINNT < 0x0502) # define MSG_WAITALL 0x8 # endif # if (_WIN32_WINNT < 0x0600) # define POLLRDNORM 0x0100 # define POLLRDBAND 0x0200 # define POLLIN (POLLRDNORM | POLLRDBAND) # define POLLPRI 0x0400 # define POLLWRNORM 0x0010 # define POLLOUT (POLLWRNORM) # define POLLWRBAND 0x0020 # define POLLERR 0x0001 # define POLLHUP 0x0002 # define POLLNVAL 0x0004 # endif #endif #if defined __APPLE__ # define MSG_NOSIGNAL 0 /* * Custom options for setting socket behavious in kVsockSetOptions. * These values fall after the common Mac OS X Socket options * in /usr/inclue/sys/socket.h */ #define SO_NONBLOCKING 0x1200 #endif // __APPLE__ #if defined(_WIN32) || defined(VMKERNEL) || defined(__APPLE__) # define SS_FREE 0 # define SS_UNCONNECTED 1 # define SS_CONNECTING 2 # define SS_CONNECTED 3 # define SS_DISCONNECTING 4 # define SS_DISCONNECTED 5 # define RCV_SHUTDOWN 1 # define SEND_SHUTDOWN 2 # define SHUTDOWN_MASK 3 #endif // _WIN32 || VMKERNEL /* * For signalling sockets. These are defined as standard on Windows. We do * not use them on Linux. So define them here only for VMKernel. */ #if defined(_WIN32) # define SOCKET_EVENT_READ FD_READ # define SOCKET_EVENT_WRITE FD_WRITE # define SOCKET_EVENT_ACCEPT FD_ACCEPT # define SOCKET_EVENT_CONNECT FD_CONNECT # define SOCKET_EVENT_CLOSE FD_CLOSE #else #if defined(VMKERNEL) || defined(__APPLE__) # define SOCKET_EVENT_READ 0x1 # define SOCKET_EVENT_WRITE 0x2 # define SOCKET_EVENT_ACCEPT 0x8 # define SOCKET_EVENT_CONNECT 0x10 # define SOCKET_EVENT_CLOSE 0x20 #endif // VMKERNEL #endif // _WIN32 /* * Custom socket control option values. These are internal. The public ones * are in vmci_sockets.h. As with the public options, use the address family * as the option level. */ #define SO_VMCI_EVENT_ENUMERATE_SELECT 1000 /* * Error codes. */ #if defined(_WIN32) # if !defined(EINTR) # define EINTR WSAEINTR # endif # if !defined(EACCES) # define EACCES WSAEACCES # endif # if !defined(EFAULT) # define EFAULT WSAEFAULT # endif # if !defined(EINVAL) # define EINVAL WSAEINVAL # endif # if !defined(EPERM) # define EPERM WSAEACCES /* WSA doesn't have EPERM */ # endif # if !defined(ENOSYS) # define ENOSYS WSAEOPNOTSUPP # endif # if !defined(EAGAIN) # define EAGAIN WSAEWOULDBLOCK # endif # define EWOULDBLOCK WSAEWOULDBLOCK # define EINPROGRESS WSAEINPROGRESS # define EALREADY WSAEALREADY # define ENOTSOCK WSAENOTSOCK # define EDESTADDRREQ WSAEDESTADDRREQ # define EMSGSIZE WSAEMSGSIZE # define EPROTOTYPE WSAEPROTOTYPE # define ENOPROTOOPT WSAENOPROTOOPT # define EPROTONOSUPPORT WSAEPROTONOSUPPORT # define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT # define EOPNOTSUPP WSAEOPNOTSUPP # define EPFNOSUPPORT WSAEPFNOSUPPORT # define EAFNOSUPPORT WSAEAFNOSUPPORT # define EADDRINUSE WSAEADDRINUSE # define EADDRNOTAVAIL WSAEADDRNOTAVAIL # define ENETDOWN WSAENETDOWN # define ENETUNREACH WSAENETUNREACH # define ENETRESET WSAENETRESET # define ECONNABORTED WSAECONNABORTED # define ECONNRESET WSAECONNRESET # define ENOBUFS WSAENOBUFS # define EISCONN WSAEISCONN # define ENOTCONN WSAENOTCONN # define ESHUTDOWN WSAESHUTDOWN # define ETIMEDOUT WSAETIMEDOUT # define ECONNREFUSED WSAECONNREFUSED # define EHOSTDOWN WSAEHOSTDOWN # define EHOSTUNREACH WSAEHOSTUNREACH # define __ELOCALSHUTDOWN ESHUTDOWN # define __ELOCALRCVSHUTDOWN __ELOCALSHUTDOWN # define __EPEERSHUTDOWN ECONNABORTED # define __ECONNINPROGRESS EWOULDBLOCK # define __ESNDRCVTIMEDOUT ETIMEDOUT # define ESYSNOTREADY WSASYSNOTREADY #elif defined(VMKERNEL) # define EINTR VMK_WAIT_INTERRUPTED # define EPERM VMK_ACCESS_DENIED # define EACCES VMK_NO_ACCESS # define EFAULT VMK_INVALID_ADDRESS # define EINVAL VMK_FAILURE # define EWOULDBLOCK VMK_WOULD_BLOCK # define EINPROGRESS VMK_EINPROGRESS # define EALREADY VMK_EALREADY # define ENOTSOCK VMK_NOT_A_SOCKET # define EDESTADDRREQ VMK_EDESTADDRREQ /* * Do not change EMSGSIZE definition without changing uses of * VMK_LIMIT_EXCEEDED in userSocketVmci.c's implementation of recvmsg(). */ # define EMSGSIZE VMK_LIMIT_EXCEEDED # define EPROTOTYPE VMK_NOT_SUPPORTED # define ENOPROTOOPT VMK_NOT_SUPPORTED # define EPROTONOSUPPORT VMK_EPROTONOSUPPORT # define ESOCKTNOSUPPORT VMK_NOT_SUPPORTED # define EOPNOTSUPP VMK_EOPNOTSUPP # define EPFNOSUPPORT VMK_ADDRFAM_UNSUPP # define EAFNOSUPPORT VMK_ADDRFAM_UNSUPP # define EADDRINUSE VMK_EADDRINUSE # define EADDRNOTAVAIL VMK_EADDRNOTAVAIL # define ENETDOWN VMK_ENETDOWN # define ENETUNREACH VMK_ENETUNREACH # define ENETRESET VMK_ENETRESET # define ECONNABORTED VMK_ECONNABORTED # define ECONNRESET VMK_ECONNRESET # define ENOBUFS VMK_NO_MEMORY # define ENOMEM VMK_NO_MEMORY # define EISCONN VMK_ALREADY_CONNECTED # define ENOTCONN VMK_ENOTCONN # define ESHUTDOWN VMK_ESHUTDOWN # define ETIMEDOUT VMK_TIMEOUT # define ECONNREFUSED VMK_ECONNREFUSED # define EHOSTDOWN VMK_EHOSTDOWN # define EHOSTUNREACH VMK_EHOSTUNREACH # define EPIPE VMK_BROKEN_PIPE # define __ELOCALSHUTDOWN EPIPE # define __ELOCALRCVSHUTDOWN 0 # define __EPEERSHUTDOWN EPIPE # define __ECONNINPROGRESS EINPROGRESS # define __ESNDRCVTIMEDOUT VMK_WOULD_BLOCK # define ESYSNOTREADY VMK_NOT_SUPPORTED # define EAGAIN VMK_RETRY #elif defined(__APPLE__) # define __ELOCALSHUTDOWN ESHUTDOWN # define __ELOCALRCVSHUTDOWN 0 # define __EPEERSHUTDOWN ECONNABORTED # define __ECONNINPROGRESS EINPROGRESS # define __ESNDRCVTIMEDOUT EAGAIN # define ESYSNOTREADY EOPNOTSUPP #elif defined(linux) # define ESYSNOTREADY EOPNOTSUPP #endif // _WIN32 #if defined(_WIN32) # define sockerr() WSAGetLastError() # define sockerr2err(_e) (((_e) < 0) ? -(_e) : (_e)) # define sockcleanup() WSACleanup() typedef uint32 socklen_t; typedef uint32 in_addr_t; #else // _WIN32 #if defined(VMKERNEL) # define SOCKET_ERROR (-1) # define INVALID_SOCKET ((SOCKET) -1) # define sockerr() errno # define sockerr2err(_e) (_e) # define sockcleanup() do {} while (0) # define closesocket(_s) close((_s)) typedef int32 SOCKET; #else #if defined(linux) || defined(__APPLE__) # define SOCKET_ERROR (-1) # define INVALID_SOCKET ((SOCKET) -1) # define sockerr() errno # define sockcleanup() do {} while (0) #if defined(linux) # define sockerr2err(_e) (((_e) > 0) ? -(_e) : (_e)) # define closesocket(_s) close((_s)) typedef int32 SOCKET; #else # define sockerr2err(_e) (_e) # define closesocket(_s) VMCISock_close(_s) typedef int32 SOCKET; #endif #endif // linux #endif // VMKERNEL #endif // _WIN32 /* * There is no SS_XXX state equivalent to TCP_LISTEN. Linux does have a flag * __SO_ACCEPTCON which some of the socket implementations use, but it does * not fit in the state field (although it is sometimes incorrectly used that * way). So we define our own listen state here for all platforms. */ #define SS_LISTEN 255 /* * Initialize sockets. This is really for platforms that do not have * on-by-default socket implementations like Windows. */ int sockinit(void); #endif // _VSOCK_SOCKET_WRAPPER_H_ open-vm-tools-9.4.0-1280544/modules/linux/vsock/linux/notify.c0000644765153500003110000007522212220061556022216 0ustar dtormts/********************************************************* * Copyright (C) 2009-2011 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * notify.c -- * * Linux control notifications for the VMCI Stream Sockets protocol. */ #include "driver-config.h" #include #include "compat_sock.h" #include "notify.h" #include "af_vsock.h" #define PKT_FIELD(vsk, fieldName) \ (vsk)->notify.pkt.fieldName #define VSOCK_MAX_DGRAM_RESENDS 10 /* *---------------------------------------------------------------------------- * * VSockVmciNotifyWaitingWrite -- * * Determines if the conditions have been met to notify a waiting writer. * * Results: * TRUE if a notification should be sent, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static Bool VSockVmciNotifyWaitingWrite(VSockVmciSock *vsk) // IN { #if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY) Bool retval; uint64 notifyLimit; if (!PKT_FIELD(vsk, peerWaitingWrite)) { return FALSE; } #ifdef VSOCK_OPTIMIZATION_FLOW_CONTROL /* * When the sender blocks, we take that as a sign that the sender * is faster than the receiver. To reduce the transmit rate of the * sender, we delay the sending of the read notification by * decreasing the writeNotifyWindow. The notification is delayed * until the number of bytes used in the queue drops below the * writeNotifyWindow. */ if (!PKT_FIELD(vsk, peerWaitingWriteDetected)) { PKT_FIELD(vsk, peerWaitingWriteDetected) = TRUE; if (PKT_FIELD(vsk, writeNotifyWindow) < PAGE_SIZE) { PKT_FIELD(vsk, writeNotifyWindow) = PKT_FIELD(vsk, writeNotifyMinWindow); } else { PKT_FIELD(vsk, writeNotifyWindow) -= PAGE_SIZE; if (PKT_FIELD(vsk, writeNotifyWindow) < PKT_FIELD(vsk, writeNotifyMinWindow)) { PKT_FIELD(vsk, writeNotifyWindow) = PKT_FIELD(vsk, writeNotifyMinWindow); } } } notifyLimit = vsk->consumeSize - PKT_FIELD(vsk, writeNotifyWindow); #else notifyLimit = 0; #endif // VSOCK_OPTIMIZATION_FLOW_CONTROL /* * For now we ignore the wait information and just see if the free * space exceeds the notify limit. Note that improving this * function to be more intelligent will not require a protocol * change and will retain compatibility between endpoints with * mixed versions of this function. * * The notifyLimit is used to delay notifications in the case where * flow control is enabled. Below the test is expressed in terms of * free space in the queue: * if freeSpace > ConsumeSize - writeNotifyWindow then notify * An alternate way of expressing this is to rewrite the expression * to use the data ready in the receive queue: * if writeNotifyWindow > bufferReady then notify * as freeSpace == ConsumeSize - bufferReady. */ retval = vmci_qpair_consume_free_space(vsk->qpair) > notifyLimit; #ifdef VSOCK_OPTIMIZATION_FLOW_CONTROL if (retval) { /* * Once we notify the peer, we reset the detected flag so the * next wait will again cause a decrease in the window size. */ PKT_FIELD(vsk, peerWaitingWriteDetected) = FALSE; } #endif // VSOCK_OPTIMIZATION_FLOW_CONTROL return retval; #else return TRUE; #endif } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyWaitingRead -- * v * Determines if the conditions have been met to notify a waiting reader. * * Results: * TRUE if a notification should be sent, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static Bool VSockVmciNotifyWaitingRead(VSockVmciSock *vsk) // IN { #if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY) if (!PKT_FIELD(vsk, peerWaitingRead)) { return FALSE; } /* * For now we ignore the wait information and just see if there is any data * for our peer to read. Note that improving this function to be more intelligent will * not require a protocol change and will retain compatibility between * endpoints with mixed versions of this function. */ return vmci_qpair_produce_buf_ready(vsk->qpair) > 0; #else return TRUE; #endif } /* *---------------------------------------------------------------------------- * * VSockVmciHandleWaitingRead -- * * Handles an incoming waiting read message. * * Results: * None. * * Side effects: * May send a notification to the peer, may update socket's wait info * structure. * *---------------------------------------------------------------------------- */ static void VSockVmciHandleWaitingRead(struct sock *sk, // IN VSockPacket *pkt, // IN Bool bottomHalf, // IN struct sockaddr_vm *dst, // IN struct sockaddr_vm *src) // IN { #if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY) VSockVmciSock *vsk; vsk = vsock_sk(sk); PKT_FIELD(vsk, peerWaitingRead) = TRUE; memcpy(&PKT_FIELD(vsk, peerWaitingReadInfo), &pkt->u.wait, sizeof PKT_FIELD(vsk, peerWaitingReadInfo)); if (VSockVmciNotifyWaitingRead(vsk)) { Bool sent; if (bottomHalf) { sent = VSOCK_SEND_WROTE_BH(dst, src) > 0; } else { sent = VSOCK_SEND_WROTE(sk) > 0; } if (sent) { PKT_FIELD(vsk, peerWaitingRead) = FALSE; } } #endif } /* *---------------------------------------------------------------------------- * * VSockVmciHandleWaitingWrite -- * * Handles an incoming waiting write message. * * Results: * None. * * Side effects: * May send a notification to the peer, may update socket's wait info * structure. * *---------------------------------------------------------------------------- */ static void VSockVmciHandleWaitingWrite(struct sock *sk, // IN VSockPacket *pkt, // IN Bool bottomHalf, // IN struct sockaddr_vm *dst, // IN struct sockaddr_vm *src) // IN { #if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY) VSockVmciSock *vsk; vsk = vsock_sk(sk); PKT_FIELD(vsk, peerWaitingWrite) = TRUE; memcpy(&PKT_FIELD(vsk, peerWaitingWriteInfo), &pkt->u.wait, sizeof PKT_FIELD(vsk,peerWaitingWriteInfo)); if (VSockVmciNotifyWaitingWrite(vsk)) { Bool sent; if (bottomHalf) { sent = VSOCK_SEND_READ_BH(dst, src) > 0; } else { sent = VSOCK_SEND_READ(sk) > 0; } if (sent) { PKT_FIELD(vsk, peerWaitingWrite) = FALSE; } } #endif } /* *---------------------------------------------------------------------------- * * VSockVmciHandleRead -- * * Handles an incoming read message. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VSockVmciHandleRead(struct sock *sk, // IN VSockPacket *pkt, // IN: unused Bool bottomHalf, // IN: unused struct sockaddr_vm *dst, // IN: unused struct sockaddr_vm *src) // IN: unused { #if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY) VSockVmciSock *vsk; vsk = vsock_sk(sk); PKT_FIELD(vsk, sentWaitingWrite) = FALSE; #endif sk->sk_write_space(sk); } /* *---------------------------------------------------------------------------- * * VSockVmciSendWaitingRead -- * * Sends a waiting read notification to this socket's peer. * * Results: * TRUE if the datagram is sent successfully, FALSE otherwise. * * Side effects: * Our peer will notify us when there is data to read from our consume * queue. * *---------------------------------------------------------------------------- */ static Bool VSockVmciSendWaitingRead(struct sock *sk, // IN uint64 roomNeeded) // IN { #if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY) VSockVmciSock *vsk; VSockWaitingInfo waitingInfo; uint64 tail; uint64 head; uint64 roomLeft; Bool ret; ASSERT(sk); vsk = vsock_sk(sk); if (PKT_FIELD(vsk, sentWaitingRead)) { return TRUE; } if (PKT_FIELD(vsk, writeNotifyWindow) < vsk->consumeSize) { PKT_FIELD(vsk, writeNotifyWindow) = MIN(PKT_FIELD(vsk, writeNotifyWindow) + PAGE_SIZE, vsk->consumeSize); } vmci_qpair_get_consume_indexes(vsk->qpair, &tail, &head); roomLeft = vsk->consumeSize - head; if (roomNeeded >= roomLeft) { waitingInfo.offset = roomNeeded - roomLeft; waitingInfo.generation = PKT_FIELD(vsk, consumeQGeneration) + 1; } else { waitingInfo.offset = head + roomNeeded; waitingInfo.generation = PKT_FIELD(vsk, consumeQGeneration); } ret = VSOCK_SEND_WAITING_READ(sk, &waitingInfo) > 0; if (ret) { PKT_FIELD(vsk, sentWaitingRead) = TRUE; } return ret; #else return TRUE; #endif } /* *---------------------------------------------------------------------------- * * VSockVmciSendWaitingWrite -- * * Sends a waiting write notification to this socket's peer. * * Results: * TRUE if the datagram is sent successfully or does not need to be sent. * FALSE otherwise. * * Side effects: * Our peer will notify us when there is room to write in to our produce * queue. * *---------------------------------------------------------------------------- */ static Bool VSockVmciSendWaitingWrite(struct sock *sk, // IN uint64 roomNeeded) // IN { #if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY) VSockVmciSock *vsk; VSockWaitingInfo waitingInfo; uint64 tail; uint64 head; uint64 roomLeft; Bool ret; ASSERT(sk); vsk = vsock_sk(sk); if (PKT_FIELD(vsk, sentWaitingWrite)) { return TRUE; } vmci_qpair_get_produce_indexes(vsk->qpair, &tail, &head); roomLeft = vsk->produceSize - tail; if (roomNeeded + 1 >= roomLeft) { /* Wraps around to current generation. */ waitingInfo.offset = roomNeeded + 1 - roomLeft; waitingInfo.generation = PKT_FIELD(vsk, produceQGeneration); } else { waitingInfo.offset = tail + roomNeeded + 1; waitingInfo.generation = PKT_FIELD(vsk, produceQGeneration) - 1; } ret = VSOCK_SEND_WAITING_WRITE(sk, &waitingInfo) > 0; if (ret) { PKT_FIELD(vsk, sentWaitingWrite) = TRUE; } return ret; #else return TRUE; #endif } /* *---------------------------------------------------------------------------- * * VSockVmciSendReadNotification -- * * Sends a read notification to this socket's peer. * * Results: * >= 0 if the datagram is sent successfully, negative error value * otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciSendReadNotification(struct sock *sk) // IN { VSockVmciSock *vsk; Bool sentRead; unsigned int retries; int err; ASSERT(sk); vsk = vsock_sk(sk); sentRead = FALSE; retries = 0; err = 0; if (VSockVmciNotifyWaitingWrite(vsk)) { /* * Notify the peer that we have read, retrying the send on failure up to our * maximum value. XXX For now we just log the failure, but later we should * schedule a work item to handle the resend until it succeeds. That would * require keeping track of work items in the vsk and cleaning them up upon * socket close. */ while (!(vsk->peerShutdown & RCV_SHUTDOWN) && !sentRead && retries < VSOCK_MAX_DGRAM_RESENDS) { err = VSOCK_SEND_READ(sk); if (err >= 0) { sentRead = TRUE; } retries++; } if (retries >= VSOCK_MAX_DGRAM_RESENDS) { Warning("unable to send read notification to peer for socket %p.\n", sk); } else { #if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY) PKT_FIELD(vsk, peerWaitingWrite) = FALSE; #endif } } return err; } /* *---------------------------------------------------------------------------- * * VSockVmciHandleWrote -- * * Handles an incoming wrote message. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VSockVmciHandleWrote(struct sock *sk, // IN VSockPacket *pkt, // IN: unused Bool bottomHalf, // IN: unused struct sockaddr_vm *dst, // IN: unused struct sockaddr_vm *src) // IN: unused { #if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY) VSockVmciSock *vsk; vsk = vsock_sk(sk); PKT_FIELD(vsk, sentWaitingRead) = FALSE; #endif sk->sk_data_ready(sk, 0); } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktSocketInit -- * * Function that is called after a socket is created and before any * notify ops are used. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VSockVmciNotifyPktSocketInit(struct sock *sk) // IN { VSockVmciSock *vsk; vsk = vsock_sk(sk); PKT_FIELD(vsk, writeNotifyWindow) = PAGE_SIZE; PKT_FIELD(vsk, writeNotifyMinWindow) = PAGE_SIZE; PKT_FIELD(vsk, peerWaitingRead) = FALSE; PKT_FIELD(vsk, peerWaitingWrite) = FALSE; PKT_FIELD(vsk, peerWaitingWriteDetected) = FALSE; PKT_FIELD(vsk, sentWaitingRead) = FALSE; PKT_FIELD(vsk, sentWaitingWrite) = FALSE; PKT_FIELD(vsk, produceQGeneration) = 0; PKT_FIELD(vsk, consumeQGeneration) = 0; memset(&PKT_FIELD(vsk, peerWaitingReadInfo), 0, sizeof PKT_FIELD(vsk, peerWaitingReadInfo)); memset(&PKT_FIELD(vsk, peerWaitingWriteInfo), 0, sizeof PKT_FIELD(vsk, peerWaitingWriteInfo)); } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktSocketDestruct -- * * Function that is called when the socket is being released. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VSockVmciNotifyPktSocketDestruct(struct sock *sk) // IN { return; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktPollIn -- * * Called by the poll function to figure out if there is data to read * and to setup future notifications if needed. Only called on sockets * that aren't shutdown for recv. * * Results: * 0 on success. Negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int32 VSockVmciNotifyPktPollIn(struct sock *sk, // IN size_t target, // IN Bool *dataReadyNow) // IN { VSockVmciSock *vsk; ASSERT(sk); ASSERT(dataReadyNow); vsk = vsock_sk(sk); if (VSockVmciStreamHasData(vsk)) { *dataReadyNow = TRUE; } else { /* * We can't read right now because there is nothing in the queue. * Ask for notifications when there is something to read. */ if (sk->sk_state == SS_CONNECTED) { if (!VSockVmciSendWaitingRead(sk, 1)) { return -1; } } *dataReadyNow = FALSE; } return 0; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktPollOut * * Called by the poll function to figure out if there is space to write * and to setup future notifications if needed. Only called on a * connected socket that isn't shutdown for send. * * Results: * 0 on success. Negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int32 VSockVmciNotifyPktPollOut(struct sock *sk, // IN size_t target, // IN Bool *spaceAvailNow) // IN { int64 produceQFreeSpace; VSockVmciSock *vsk; ASSERT(sk); ASSERT(spaceAvailNow); vsk = vsock_sk(sk); produceQFreeSpace = VSockVmciStreamHasSpace(vsk); if (produceQFreeSpace > 0) { *spaceAvailNow = TRUE; return 0; } else if (produceQFreeSpace == 0) { /* * This is a connected socket but we can't currently send data. Notify * the peer that we are waiting if the queue is full. * We only send a waiting write if the queue is full because otherwise * we end up in an infinite WAITING_WRITE, READ, WAITING_WRITE, READ, etc. * loop. Treat failing to send the notification as a socket error, passing * that back through the mask. */ if (!VSockVmciSendWaitingWrite(sk, 1)) { return -1; } *spaceAvailNow = FALSE; } return 0; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktRecvInit -- * * Called at the start of a stream recv call with the socket lock held. * * Results: * 0 on success. Negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int32 VSockVmciNotifyPktRecvInit(struct sock *sk, // IN size_t target, // IN VSockVmciRecvNotifyData *data) // IN { VSockVmciSock *vsk; ASSERT(sk); ASSERT(data); vsk = vsock_sk(sk); #ifdef VSOCK_OPTIMIZATION_WAITING_NOTIFY data->consumeHead = 0; data->produceTail = 0; #ifdef VSOCK_OPTIMIZATION_FLOW_CONTROL data->notifyOnBlock = FALSE; if (PKT_FIELD(vsk, writeNotifyMinWindow) < target + 1) { ASSERT(target < vsk->consumeSize); PKT_FIELD(vsk, writeNotifyMinWindow) = target + 1; if (PKT_FIELD(vsk, writeNotifyWindow) < PKT_FIELD(vsk, writeNotifyMinWindow)) { /* * If the current window is smaller than the new minimal * window size, we need to reevaluate whether we need to * notify the sender. If the number of ready bytes are * smaller than the new window, we need to send a * notification to the sender before we block. */ PKT_FIELD(vsk, writeNotifyWindow) = PKT_FIELD(vsk, writeNotifyMinWindow); data->notifyOnBlock = TRUE; } } #endif #endif return 0; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktRecvPreBlock -- * * Called right before a socket is about to block with the socket lock * held. The socket lock may have been released between the entry * function and the preblock call. * * Note: This function may be called multiple times before the post * block function is called. * * Results: * 0 on success. Negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int32 VSockVmciNotifyPktRecvPreBlock(struct sock *sk, // IN size_t target, // IN VSockVmciRecvNotifyData *data) // IN { int err; ASSERT(sk); ASSERT(data); err = 0; /* Notify our peer that we are waiting for data to read. */ if (!VSockVmciSendWaitingRead(sk, target)) { err = -EHOSTUNREACH; return err; } #ifdef VSOCK_OPTIMIZATION_FLOW_CONTROL if (data->notifyOnBlock) { err = VSockVmciSendReadNotification(sk); if (err < 0) { return err; } data->notifyOnBlock = FALSE; } #endif return err; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktRecvPreDequeue -- * * Called right before we dequeue / peek data from a socket. * * Results: * 0 on success. Negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int32 VSockVmciNotifyPktRecvPreDequeue(struct sock *sk, // IN size_t target, // IN VSockVmciRecvNotifyData *data) // IN { VSockVmciSock *vsk; ASSERT(sk); ASSERT(data); vsk = vsock_sk(sk); /* * Now consume up to len bytes from the queue. Note that since we have the * socket locked we should copy at least ready bytes. */ #if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY) vmci_qpair_get_consume_indexes(vsk->qpair, &data->produceTail, &data->consumeHead); #endif return 0; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktRecvPostDequeue -- * * Called right after we dequeue / peek data from a socket. * * Results: * 0 on success. Negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int32 VSockVmciNotifyPktRecvPostDequeue(struct sock *sk, // IN size_t target, // IN ssize_t copied, // IN Bool dataRead, // IN VSockVmciRecvNotifyData *data) // IN { VSockVmciSock *vsk; int err; ASSERT(sk); ASSERT(data); vsk = vsock_sk(sk); err = 0; if (dataRead) { #if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY) /* * Detect a wrap-around to maintain queue generation. Note that this is * safe since we hold the socket lock across the two queue pair * operations. */ if (copied >= vsk->consumeSize - data->consumeHead) { PKT_FIELD(vsk, consumeQGeneration)++; } #endif err = VSockVmciSendReadNotification(sk); if (err < 0) { return err; } } return err; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktSendInit -- * * Called at the start of a stream send call with the socket lock held. * * Results: * 0 on success. A negative error code on failure. * * Side effects: * *---------------------------------------------------------------------------- */ static int32 VSockVmciNotifyPktSendInit(struct sock *sk, // IN VSockVmciSendNotifyData *data) // IN { ASSERT(sk); ASSERT(data); #ifdef VSOCK_OPTIMIZATION_WAITING_NOTIFY data->consumeHead = 0; data->produceTail = 0; #endif return 0; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktSendPreBlock -- * * Called right before a socket is about to block with the socket lock * held. The socket lock may have been released between the entry * function and the preblock call. * * Note: This function may be called multiple times before the post * block function is called. * * Results. * 0 on success. A negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int32 VSockVmciNotifyPktSendPreBlock(struct sock *sk, // IN VSockVmciSendNotifyData *data) // IN { ASSERT(sk); ASSERT(data); /* Notify our peer that we are waiting for room to write. */ if (!VSockVmciSendWaitingWrite(sk, 1)) { return -EHOSTUNREACH; } return 0; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifySendPreEnqueue -- * * Called right before we Enqueue to a socket. * * Results: * 0 on success. Negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int32 VSockVmciNotifyPktSendPreEnqueue(struct sock *sk, // IN VSockVmciSendNotifyData *data) // IN { VSockVmciSock *vsk; ASSERT(sk); ASSERT(data); vsk = vsock_sk(sk); #if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY) vmci_qpair_get_produce_indexes(vsk->qpair, &data->produceTail, &data->consumeHead); #endif return 0;; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifySendPostEnqueue -- * * Called right after we enqueue data to a socket. * * Results: * 0 on success. Negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int32 VSockVmciNotifyPktSendPostEnqueue(struct sock *sk, // IN ssize_t written, // IN VSockVmciSendNotifyData *data) // IN { int err = 0; VSockVmciSock *vsk; Bool sentWrote = FALSE; int retries = 0; ASSERT(sk); ASSERT(data); vsk = vsock_sk(sk); #if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY) /* * Detect a wrap-around to maintain queue generation. Note that this is * safe since we hold the socket lock across the two queue pair * operations. */ if (written >= vsk->produceSize - data->produceTail) { PKT_FIELD(vsk, produceQGeneration)++; } #endif if (VSockVmciNotifyWaitingRead(vsk)) { /* * Notify the peer that we have written, retrying the send on failure up to * our maximum value. See the XXX comment for the corresponding piece of * code in StreamRecvmsg() for potential improvements. */ while (!(vsk->peerShutdown & RCV_SHUTDOWN) && !sentWrote && retries < VSOCK_MAX_DGRAM_RESENDS) { err = VSOCK_SEND_WROTE(sk); if (err >= 0) { sentWrote = TRUE; } retries++; } if (retries >= VSOCK_MAX_DGRAM_RESENDS) { Warning("unable to send wrote notification to peer for socket %p.\n", sk); return err; } else { #if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY) PKT_FIELD(vsk, peerWaitingRead) = FALSE; #endif } } return err; } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktHandlePkt * * Called when a notify packet is recieved for a socket in the connected * state. Note this might be called from a bottom half. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VSockVmciNotifyPktHandlePkt(struct sock *sk, // IN VSockPacket *pkt, // IN Bool bottomHalf, // IN struct sockaddr_vm *dst, // IN struct sockaddr_vm *src, // IN Bool *pktProcessed) // In { Bool processed = FALSE; ASSERT(sk); ASSERT(pkt); switch (pkt->type) { case VSOCK_PACKET_TYPE_WROTE: VSockVmciHandleWrote(sk, pkt, bottomHalf, dst, src); processed = TRUE; break; case VSOCK_PACKET_TYPE_READ: VSockVmciHandleRead(sk, pkt, bottomHalf, dst, src); processed = TRUE; break; case VSOCK_PACKET_TYPE_WAITING_WRITE: VSockVmciHandleWaitingWrite(sk, pkt, bottomHalf, dst, src); processed = TRUE; break; case VSOCK_PACKET_TYPE_WAITING_READ: VSockVmciHandleWaitingRead(sk, pkt, bottomHalf, dst, src); processed = TRUE; break; } if (pktProcessed) { *pktProcessed = processed; } } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktProcessRequest * * Called near the end of process request. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VSockVmciNotifyPktProcessRequest(struct sock *sk) // IN { VSockVmciSock *vsk; ASSERT(sk); vsk = vsock_sk(sk); PKT_FIELD(vsk, writeNotifyWindow) = vsk->consumeSize; if (vsk->consumeSize < PKT_FIELD(vsk, writeNotifyMinWindow)) { PKT_FIELD(vsk, writeNotifyMinWindow) = vsk->consumeSize; } } /* *---------------------------------------------------------------------------- * * VSockVmciNotifyPktProcessNegotiate * * Called near the end of process negotiate. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VSockVmciNotifyPktProcessNegotiate(struct sock *sk) // IN { VSockVmciSock *vsk; ASSERT(sk); vsk = vsock_sk(sk); PKT_FIELD(vsk, writeNotifyWindow) = vsk->consumeSize; if (vsk->consumeSize < PKT_FIELD(vsk, writeNotifyMinWindow)) { PKT_FIELD(vsk, writeNotifyMinWindow) = vsk->consumeSize; } } /* Socket control packet based operations. */ VSockVmciNotifyOps vSockVmciNotifyPktOps = { VSockVmciNotifyPktSocketInit, VSockVmciNotifyPktSocketDestruct, VSockVmciNotifyPktPollIn, VSockVmciNotifyPktPollOut, VSockVmciNotifyPktHandlePkt, VSockVmciNotifyPktRecvInit, VSockVmciNotifyPktRecvPreBlock, VSockVmciNotifyPktRecvPreDequeue, VSockVmciNotifyPktRecvPostDequeue, VSockVmciNotifyPktSendInit, VSockVmciNotifyPktSendPreBlock, VSockVmciNotifyPktSendPreEnqueue, VSockVmciNotifyPktSendPostEnqueue, VSockVmciNotifyPktProcessRequest, VSockVmciNotifyPktProcessNegotiate, }; open-vm-tools-9.4.0-1280544/modules/linux/vsock/linux/util.h0000644765153500003110000003334512220061556021670 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * util.h -- * * Utility functions for Linux VSocket module. */ #ifndef __UTIL_H__ #define __UTIL_H__ #include "driver-config.h" #include "compat_sock.h" #include "compat_spinlock.h" #include "vsockCommon.h" #include "vsockPacket.h" /* * Each bound VSocket is stored in the bind hash table and each connected * VSocket is stored in the connected hash table. * * Unbound sockets are all put on the same list attached to the end of the hash * table (vsockUnboundSockets). Bound sockets are added to the hash table in * the bucket that their local address hashes to (vsockBoundSockets(addr) * represents the list that addr hashes to). * * Specifically, we initialize the vsockBindTable array to a size of * VSOCK_HASH_SIZE + 1 so that vsockBindTable[0] through * vsockBindTable[VSOCK_HASH_SIZE - 1] are for bound sockets and * vsockBindTable[VSOCK_HASH_SIZE] is for unbound sockets. The hash function * mods with VSOCK_HASH_SIZE - 1 to ensure this. * * Connected sequential sockets are put in the seq table. */ #define VSOCK_HASH_SIZE 251 #define LAST_RESERVED_PORT 1023 #define MAX_PORT_RETRIES 24 extern struct list_head vsockBindTable[VSOCK_HASH_SIZE + 1]; extern struct list_head vsockConnectedTable[VSOCK_HASH_SIZE]; extern struct list_head vsockSeqTable[VSOCK_HASH_SIZE]; extern spinlock_t vsockTableLock; extern spinlock_t vsockSeqTableLock; #define VSOCK_HASH(addr) ((addr)->svm_port % (VSOCK_HASH_SIZE - 1)) #define vsockBoundSockets(addr) (&vsockBindTable[VSOCK_HASH(addr)]) #define vsockUnboundSockets (&vsockBindTable[VSOCK_HASH_SIZE]) /* XXX This can probably be implemented in a better way. */ #define VSOCK_CONN_HASH(src, dst) \ (((src)->svm_cid ^ (dst)->svm_port) % (VSOCK_HASH_SIZE - 1)) #define vsockConnectedSockets(src, dst) \ (&vsockConnectedTable[VSOCK_CONN_HASH(src, dst)]) #define vsockConnectedSocketsVsk(vsk) \ vsockConnectedSockets(&(vsk)->remoteAddr, &(vsk)->localAddr) #define VSOCK_SEQ_HASH(src, dst) VSOCK_CONN_HASH(src, dst) #define vsockSeqSockets(src, dst) \ (&vsockSeqTable[VSOCK_SEQ_HASH(src, dst)]) #define vsockSeqSocketsVsk(vsk) \ vsockSeqSockets(&(vsk)->remoteAddr, &(vsk)->localAddr) /* * Prototypes. */ void VSockVmciLogPkt(char const *function, uint32 line, VSockPacket *pkt); void VSockVmciInitTables(void); void __VSockVmciInsertBound(struct list_head *list, struct sock *sk); void __VSockVmciInsertConnected(struct list_head *list, struct sock *sk); void __VSockVmciInsertSeq(struct list_head *list, struct sock *sk); void __VSockVmciRemoveBound(struct sock *sk); void __VSockVmciRemoveConnected(struct sock *sk); void __VSockVmciRemoveSeq(struct sock *sk); struct sock *__VSockVmciFindBoundSocket(struct sockaddr_vm *addr); struct sock *__VSockVmciFindConnectedSocket(struct sockaddr_vm *src, struct sockaddr_vm *dst); Bool __VSockVmciInBoundTable(struct sock *sk); Bool __VSockVmciInConnectedTable(struct sock *sk); Bool __VSockVmciInSeqTable(struct sock *sk); struct sock *VSockVmciGetPending(struct sock *listener, VSockPacket *pkt); void VSockVmciReleasePending(struct sock *pending); void VSockVmciAddPending(struct sock *listener, struct sock *pending); void VSockVmciRemovePending(struct sock *listener, struct sock *pending); void VSockVmciEnqueueAccept(struct sock *listener, struct sock *connected); struct sock *VSockVmciDequeueAccept(struct sock *listener); void VSockVmciRemoveAccept(struct sock *listener, struct sock *connected); Bool VSockVmciInAcceptQueue(struct sock *sk); Bool VSockVmciIsAcceptQueueEmpty(struct sock *sk); Bool VSockVmciIsPending(struct sock *sk); static INLINE void VSockVmciInsertBound(struct list_head *list, struct sock *sk); static INLINE void VSockVmciInsertConnected(struct list_head *list, struct sock *sk); static INLINE void VSockVmciInsertSeq(struct list_head *list, struct sock *sk); static INLINE void VSockVmciRemoveBound(struct sock *sk); static INLINE void VSockVmciRemoveConnected(struct sock *sk); static INLINE void VSockVmciRemoveSeq(struct sock *sk); static INLINE struct sock *VSockVmciFindBoundSocket(struct sockaddr_vm *addr); static INLINE struct sock *VSockVmciFindConnectedSocket(struct sockaddr_vm *src, struct sockaddr_vm *dst); static INLINE Bool VSockVmciInBoundTable(struct sock *sk); static INLINE Bool VSockVmciInConnectedTable(struct sock *sk); static INLINE Bool VSockVmciInSeqTable(struct sock *sk); /* *---------------------------------------------------------------------------- * * VSockVmciInsertBound -- * * Inserts socket into the bound table. * * Note that it is important to invoke the bottom-half versions of the * spinlock functions since these may be called from tasklets. * * Results: * None. * * Side effects: * vsockTableLock is acquired and released. * *---------------------------------------------------------------------------- */ static INLINE void VSockVmciInsertBound(struct list_head *list, // IN struct sock *sk) // IN { ASSERT(list); ASSERT(sk); spin_lock_bh(&vsockTableLock); __VSockVmciInsertBound(list, sk); spin_unlock_bh(&vsockTableLock); } /* *---------------------------------------------------------------------------- * * VSockVmciInsertConnected -- * * Inserts socket into the connected table. * * Note that it is important to invoke the bottom-half versions of the * spinlock functions since these may be called from tasklets. * * Results: * None. * * Side effects: * vsockTableLock is acquired and released. * *---------------------------------------------------------------------------- */ static INLINE void VSockVmciInsertConnected(struct list_head *list, // IN struct sock *sk) // IN { ASSERT(list); ASSERT(sk); spin_lock_bh(&vsockTableLock); __VSockVmciInsertConnected(list, sk); spin_unlock_bh(&vsockTableLock); } /* *---------------------------------------------------------------------------- * * VSockVmciInsertSeq -- * * Inserts socket into the sequential table. * * Note that it is important to invoke the bottom-half versions of the * spinlock functions since these may be called from tasklets. * * Results: * None. * * Side effects: * vsockSeqTableLock is acquired and released. * *---------------------------------------------------------------------------- */ static INLINE void VSockVmciInsertSeq(struct list_head *list, // IN struct sock *sk) // IN { ASSERT(list); ASSERT(sk); spin_lock_bh(&vsockSeqTableLock); __VSockVmciInsertSeq(list, sk); spin_unlock_bh(&vsockSeqTableLock); } /* *---------------------------------------------------------------------------- * * VSockVmciRemoveBound -- * * Removes socket from the bound list. * * Note that it is important to invoke the bottom-half versions of the * spinlock functions since these may be called from tasklets. * * Results: * None. * * Side effects: * vsockTableLock is acquired and released. * *---------------------------------------------------------------------------- */ static INLINE void VSockVmciRemoveBound(struct sock *sk) // IN { ASSERT(sk); spin_lock_bh(&vsockTableLock); __VSockVmciRemoveBound(sk); spin_unlock_bh(&vsockTableLock); } /* *---------------------------------------------------------------------------- * * VSockVmciRemoveConnected -- * * Removes socket from the connected list. * * Note that it is important to invoke the bottom-half versions of the * spinlock functions since these may be called from tasklets. * * Results: * None. * * Side effects: * vsockTableLock is acquired and released. * *---------------------------------------------------------------------------- */ static INLINE void VSockVmciRemoveConnected(struct sock *sk) // IN { ASSERT(sk); spin_lock_bh(&vsockTableLock); __VSockVmciRemoveConnected(sk); spin_unlock_bh(&vsockTableLock); } /* *---------------------------------------------------------------------------- * * VSockVmciRemoveSeq -- * * Removes socket from the sequential list. * * Note that it is important to invoke the bottom-half versions of the * spinlock functions since these may be called from tasklets. * * Results: * None. * * Side effects: * vsockSeqTableLock is acquired and released. * *---------------------------------------------------------------------------- */ static INLINE void VSockVmciRemoveSeq(struct sock *sk) // IN { ASSERT(sk); spin_lock_bh(&vsockSeqTableLock); __VSockVmciRemoveSeq(sk); spin_unlock_bh(&vsockSeqTableLock); } /* *---------------------------------------------------------------------------- * * VSockVmciFindBoundSocket -- * * Finds the socket corresponding to the provided address in the bound * sockets hash table. * * Note that it is important to invoke the bottom-half versions of the * spinlock functions since these are called from tasklets. * * Results: * The sock structure if found, NULL on failure. * * Side effects: * vsockTableLock is acquired and released. * The socket's reference count is increased. * *---------------------------------------------------------------------------- */ static INLINE struct sock * VSockVmciFindBoundSocket(struct sockaddr_vm *addr) // IN { struct sock *sk; ASSERT(addr); spin_lock_bh(&vsockTableLock); sk = __VSockVmciFindBoundSocket(addr); if (sk) { sock_hold(sk); } spin_unlock_bh(&vsockTableLock); return sk; } /* *---------------------------------------------------------------------------- * * VSockVmciFindConnectedSocket -- * * Finds the socket corresponding to the provided address in the connected * sockets hash table. * * Note that it is important to invoke the bottom-half versions of the * spinlock functions since these are called from tasklets. * * Results: * The sock structure if found, NULL on failure. * * Side effects: * vsockTableLock is acquired and released. * The socket's reference count is increased. * *---------------------------------------------------------------------------- */ static INLINE struct sock * VSockVmciFindConnectedSocket(struct sockaddr_vm *src, // IN struct sockaddr_vm *dst) // IN { struct sock *sk; ASSERT(src); ASSERT(dst); spin_lock_bh(&vsockTableLock); sk = __VSockVmciFindConnectedSocket(src, dst); if (sk) { sock_hold(sk); } spin_unlock_bh(&vsockTableLock); return sk; } /* *---------------------------------------------------------------------------- * * VSockVmciInBoundTable -- * * Determines whether the provided socket is in the bound table. * * Note that it is important to invoke the bottom-half versions of the * spinlock functions since these may be called from tasklets. * * Results: * TRUE is socket is in bound table, FALSE otherwise. * * Side effects: * vsockTableLock is acquired and released. * *---------------------------------------------------------------------------- */ static INLINE Bool VSockVmciInBoundTable(struct sock *sk) // IN { Bool ret; ASSERT(sk); spin_lock_bh(&vsockTableLock); ret = __VSockVmciInBoundTable(sk); spin_unlock_bh(&vsockTableLock); return ret; } /* *---------------------------------------------------------------------------- * * VSockVmciInConnectedTable -- * * Determines whether the provided socket is in the connected table. * * Note that it is important to invoke the bottom-half versions of the * spinlock functions since these may be called from tasklets. * * Results: * TRUE is socket is in connected table, FALSE otherwise. * * Side effects: * vsockTableLock is acquired and released. * *---------------------------------------------------------------------------- */ static INLINE Bool VSockVmciInConnectedTable(struct sock *sk) // IN { Bool ret; ASSERT(sk); spin_lock_bh(&vsockTableLock); ret = __VSockVmciInConnectedTable(sk); spin_unlock_bh(&vsockTableLock); return ret; } /* *---------------------------------------------------------------------------- * * VSockVmciInSeqTable -- * * Determines whether the provided socket is in the sequential table. * * Note that it is important to invoke the bottom-half versions of the * spinlock functions since these may be called from tasklets. * * Results: * TRUE is socket is in sequential table, FALSE otherwise. * * Side effects: * vsockSeqTableLock is acquired and released. * *---------------------------------------------------------------------------- */ static INLINE Bool VSockVmciInSeqTable(struct sock *sk) // IN { Bool ret; ASSERT(sk); spin_lock_bh(&vsockSeqTableLock); ret = __VSockVmciInSeqTable(sk); spin_unlock_bh(&vsockSeqTableLock); return ret; } #endif /* __UTIL_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/vsock/linux/af_vsock.c0000644765153500003110000050574112220061556022505 0ustar dtormts/********************************************************* * Copyright (C) 2007-2011 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * af_vsock.c -- * * Linux socket module for the VMCI Sockets protocol family. */ /* * Implementation notes: * * - There are two kinds of sockets: those created by user action (such as * calling socket(2)) and those created by incoming connection request * packets. * * - There are two "global" tables, one for bound sockets (sockets that have * specified an address that they are responsible for) and one for connected * sockets (sockets that have established a connection with another socket). * These tables are "global" in that all sockets on the system are placed * within them. * - Note, though, that the bound table contains an extra entry for a list of * unbound sockets and SOCK_DGRAM sockets will always remain in that list. * The bound table is used solely for lookup of sockets when packets are * received and that's not necessary for SOCK_DGRAM sockets since we create * a datagram handle for each and need not perform a lookup. Keeping * SOCK_DGRAM sockets out of the bound hash buckets will reduce the chance * of collisions when looking for SOCK_STREAM sockets and prevents us from * having to check the socket type in the hash table lookups. * * - Sockets created by user action will either be "client" sockets that * initiate a connection or "server" sockets that listen for connections; we * do not support simultaneous connects (two "client" sockets connecting). * * - "Server" sockets are referred to as listener sockets throughout this * implementation because they are in the SS_LISTEN state. When a connection * request is received (the second kind of socket mentioned above), we create * a new socket and refer to it as a pending socket. These pending sockets * are placed on the pending connection list of the listener socket. When * future packets are received for the address the listener socket is bound * to, we check if the source of the packet is from one that has an existing * pending connection. If it does, we process the packet for the pending * socket. When that socket reaches the connected state, it is removed from * the listener socket's pending list and enqueued in the listener socket's * accept queue. Callers of accept(2) will accept connected sockets from the * listener socket's accept queue. If the socket cannot be accepted for some * reason then it is marked rejected. Once the connection is accepted, it is * owned by the user process and the responsibility for cleanup falls with * that user process. * * - It is possible that these pending sockets will never reach the connected * state; in fact, we may never receive another packet after the connection * request. Because of this, we must schedule a cleanup function to run in * the future, after some amount of time passes where a connection should * have been established. This function ensures that the socket is off all * lists so it cannot be retrieved, then drops all references to the socket * so it is cleaned up (sock_put() -> sk_free() -> our sk_destruct * implementation). Note this function will also cleanup rejected sockets, * those that reach the connected state but leave it before they have been * accepted. * * - Sockets created by user action will be cleaned up when the user * process calls close(2), causing our release implementation to be called. * Our release implementation will perform some cleanup then drop the * last reference so our sk_destruct implementation is invoked. Our * sk_destruct implementation will perform additional cleanup that's common * for both types of sockets. * * - A socket's reference count is what ensures that the structure won't be * freed. Each entry in a list (such as the "global" bound and connected * tables and the listener socket's pending list and connected queue) ensures * a reference. When we defer work until process context and pass a socket * as our argument, we must ensure the reference count is increased to ensure * the socket isn't freed before the function is run; the deferred function * will then drop the reference. * */ #include "driver-config.h" #define EXPORT_SYMTAB #include #include #include #include #include #include #include #include #include #include #include #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) # include #else # include #endif #include #if defined(__x86_64__) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12) # include /* Use weak: not all kernels export sys_ioctl for use by modules */ asmlinkage __attribute__((weak)) long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); #endif #include "compat_cred.h" #include "compat_module.h" #include "compat_kernel.h" #include "compat_sock.h" #include "compat_version.h" #include "compat_workqueue.h" #include "compat_mutex.h" #include "vmware.h" #include "vsockCommon.h" #include "vsockPacket.h" #include "vsockVmci.h" #include "vmci_iocontrols.h" #include "af_vsock.h" #include "stats.h" #include "util.h" #include "vsock_version.h" #include "driverLog.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9) # error "Linux kernels before 2.6.9 are not supported." #endif /* * All kernels above 2.6.33 have the kern parameter for the create * call in struct net_proto_family. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33) && \ !defined(VMW_NETCREATE_KERNARG) # define VMW_NETCREATE_KERNARG #endif #define VSOCK_INVALID_FAMILY NPROTO #define VSOCK_AF_IS_REGISTERED(val) ((val) >= 0 && (val) < NPROTO) /* Some kernel versions don't define __user. Define it ourself if so. */ #ifndef __user #define __user #endif /* * Prototypes */ int VSockVmci_GetAFValue(void); /* Internal functions. */ static Bool VSockVmciProtoToNotifyStruct(struct sock *sk, VSockProtoVersion *proto, Bool oldPktProto); static int VSockVmciGetAFValue(void); static int VSockVmciRecvDgramCB(void *data, VMCIDatagram *dg); static int VSockVmciRecvSeqCB(void *data, VMCIDatagram *dg); static int VSockVmciRecvStreamCB(void *data, VMCIDatagram *dg); static void VSockVmciPeerAttachCB(VMCIId subId, VMCI_EventData *ed, void *clientData); static void VSockVmciPeerDetachCB(VMCIId subId, VMCI_EventData *ed, void *clientData); static void VSockVmciRecvPktWork(compat_work_arg work); static int VSockVmciRecvListen(struct sock *sk, VSockPacket *pkt); static int VSockVmciRecvConnectingServer(struct sock *sk, struct sock *pending, VSockPacket *pkt); static int VSockVmciRecvConnectingClient(struct sock *sk, VSockPacket *pkt); static int VSockVmciRecvConnectingClientNegotiate(struct sock *sk, VSockPacket *pkt); static int VSockVmciRecvConnectingClientInvalid(struct sock *sk, VSockPacket *pkt); static int VSockVmciRecvConnected(struct sock *sk, VSockPacket *pkt); static int __VSockVmciBind(struct sock *sk, struct sockaddr_vm *addr); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14) static struct sock *__VSockVmciCreate(struct socket *sock, struct sock *parent, unsigned int priority, unsigned short type); #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) static struct sock *__VSockVmciCreate(struct socket *sock, struct sock *parent, gfp_t priority, unsigned short type); #else static struct sock *__VSockVmciCreate(struct net *net, struct socket *sock, struct sock *parent, gfp_t priority, unsigned short type); #endif static void VSockVmciTestUnregister(void); static int VSockVmciRegisterWithVmci(void); static void VSockVmciUnregisterWithVmci(void); static int VSockVmciRegisterAddressFamily(void); static void VSockVmciUnregisterAddressFamily(void); /* Socket operations. */ static void VSockVmciSkDestruct(struct sock *sk); static int VSockVmciQueueRcvSkb(struct sock *sk, struct sk_buff *skb); static int VSockVmciRelease(struct socket *sock); static int VSockVmciBind(struct socket *sock, struct sockaddr *addr, int addrLen); static int VSockVmciDgramConnect(struct socket *sock, struct sockaddr *addr, int addrLen, int flags); static int VSockVmciSeqConnect(struct socket *sock, struct sockaddr *addr, int addrLen, int flags); static int VSockVmciStreamConnect(struct socket *sock, struct sockaddr *addr, int addrLen, int flags); static int VSockVmciAccept(struct socket *sock, struct socket *newsock, int flags); static int VSockVmciGetname(struct socket *sock, struct sockaddr *addr, int *addrLen, int peer); static unsigned int VSockVmciPoll(struct file *file, struct socket *sock, poll_table *wait); static int VSockVmciListen(struct socket *sock, int backlog); static int VSockVmciShutdown(struct socket *sock, int mode); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) typedef int VSockSetsockoptLenType; #else typedef unsigned int VSockSetsockoptLenType; #endif static int VSockVmciStreamSetsockopt(struct socket *sock, int level, int optname, char __user *optval, VSockSetsockoptLenType optlen); static int VSockVmciStreamGetsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user * optlen); static int VSockVmciDgramSendmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg, size_t len); static int VSockVmciDgramRecvmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg, size_t len, int flags); static int VSockVmciSeqSendmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg, size_t len); static int VSockVmciSeqRecvmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg, size_t len, int flags); static int VSockVmciStreamSendmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg, size_t len); static int VSockVmciStreamRecvmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg, size_t len, int flags); static int VSockVmciCreate( #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) struct net *net, #endif struct socket *sock, int protocol #ifdef VMW_NETCREATE_KERNARG , int kern #endif ); /* * Device operations. */ int VSockVmciDevOpen(struct inode *inode, struct file *file); int VSockVmciDevRelease(struct inode *inode, struct file *file); static int VSockVmciDevIoctl(struct inode *inode, struct file *filp, u_int iocmd, unsigned long ioarg); #if defined(HAVE_COMPAT_IOCTL) || defined(HAVE_UNLOCKED_IOCTL) static long VSockVmciDevUnlockedIoctl(struct file *filp, u_int iocmd, unsigned long ioarg); #endif /* * Variables. */ /* Protocol family. */ static struct proto vsockVmciProto = { .name = "AF_VMCI", #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) /* Added in 2.6.10. */ .owner = THIS_MODULE, #endif /* * From 2.6.9 until 2.6.11, these address families called sk_alloc_slab() * and the allocated slab was assigned to the slab variable in the proto * struct and was created of size slab_obj_size. * As of 2.6.12 and later, this slab allocation was moved into * proto_register() and only done if you specified a non-zero value for * the second argument (alloc_slab); the size of the slab element was * changed to obj_size. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12) .slab_obj_size = sizeof (VSockVmciSock), #else .obj_size = sizeof (VSockVmciSock), #endif }; static struct net_proto_family vsockVmciFamilyOps = { .family = VSOCK_INVALID_FAMILY, .create = VSockVmciCreate, .owner = THIS_MODULE, }; /* Socket operations, split for DGRAM, STREAM and SEQPACKET sockets. */ static struct proto_ops vsockVmciDgramOps = { .family = VSOCK_INVALID_FAMILY, .owner = THIS_MODULE, .release = VSockVmciRelease, .bind = VSockVmciBind, .connect = VSockVmciDgramConnect, .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = VSockVmciGetname, .poll = VSockVmciPoll, .ioctl = sock_no_ioctl, .listen = sock_no_listen, .shutdown = VSockVmciShutdown, .setsockopt = sock_no_setsockopt, .getsockopt = sock_no_getsockopt, .sendmsg = VSockVmciDgramSendmsg, .recvmsg = VSockVmciDgramRecvmsg, .mmap = sock_no_mmap, .sendpage = sock_no_sendpage, }; static struct proto_ops vsockVmciSeqOps = { .family = VSOCK_INVALID_FAMILY, .owner = THIS_MODULE, .release = VSockVmciRelease, .bind = VSockVmciBind, .connect = VSockVmciSeqConnect, .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = VSockVmciGetname, .poll = VSockVmciPoll, .ioctl = sock_no_ioctl, .listen = sock_no_listen, .shutdown = VSockVmciShutdown, .setsockopt = sock_no_setsockopt, .getsockopt = sock_no_getsockopt, .sendmsg = VSockVmciSeqSendmsg, .recvmsg = VSockVmciSeqRecvmsg, .mmap = sock_no_mmap, .sendpage = sock_no_sendpage, }; static struct proto_ops vsockVmciStreamOps = { .family = VSOCK_INVALID_FAMILY, .owner = THIS_MODULE, .release = VSockVmciRelease, .bind = VSockVmciBind, .connect = VSockVmciStreamConnect, .socketpair = sock_no_socketpair, .accept = VSockVmciAccept, .getname = VSockVmciGetname, .poll = VSockVmciPoll, .ioctl = sock_no_ioctl, .listen = VSockVmciListen, .shutdown = VSockVmciShutdown, .setsockopt = VSockVmciStreamSetsockopt, .getsockopt = VSockVmciStreamGetsockopt, .sendmsg = VSockVmciStreamSendmsg, .recvmsg = VSockVmciStreamRecvmsg, .mmap = sock_no_mmap, .sendpage = sock_no_sendpage, }; static struct file_operations vsockVmciDeviceOps = { .owner = THIS_MODULE, #ifdef HAVE_UNLOCKED_IOCTL .unlocked_ioctl = VSockVmciDevUnlockedIoctl, #else .ioctl = VSockVmciDevIoctl, #endif #ifdef HAVE_COMPAT_IOCTL .compat_ioctl = VSockVmciDevUnlockedIoctl, #endif .open = VSockVmciDevOpen, .release = VSockVmciDevRelease, }; static struct miscdevice vsockVmciDevice = { .name = "vsock", .minor = MISC_DYNAMIC_MINOR, .fops = &vsockVmciDeviceOps, }; typedef struct VSockRecvPktInfo { compat_work work; struct sock *sk; VSockPacket pkt; } VSockRecvPktInfo; static compat_define_mutex(registrationMutex); static int devOpenCount = 0; static int vsockVmciSocketCount = 0; static int vsockVmciKernClientCount = 0; static Bool vmciDevicePresent = FALSE; static VMCIHandle vmciStreamHandle = { VMCI_INVALID_ID, VMCI_INVALID_ID }; static VMCIId qpResumedSubId = VMCI_INVALID_ID; static VMCIId ctxUpdatedSubId = VMCI_INVALID_ID; static int PROTOCOL_OVERRIDE = -1; /* * Netperf benchmarks have shown significant throughput improvements when the * QP size is bumped from 64k to 256k. These measurements were taken during the * K/L.next timeframe. Give users better performance by default. */ #define VSOCK_DEFAULT_QP_SIZE_MIN 128 #define VSOCK_DEFAULT_QP_SIZE 262144 #define VSOCK_DEFAULT_QP_SIZE_MAX 262144 /* * The default peer timeout indicates how long we will wait for a peer * response to a control message. */ #define VSOCK_DEFAULT_CONNECT_TIMEOUT (2 * HZ) #define VSOCK_SEND_SEQ_CLOSE(_vsk, _err) \ VSockVmciSendSeqPacket((_vsk), VSOCK_SEQ_PACKET_TYPE_CLOSE, (_err)) #define VSOCK_SEND_SEQ_SHUTDOWN(_vsk, _mode) \ VSockVmciSendSeqPacket((_vsk), VSOCK_SEQ_PACKET_TYPE_SHUTDOWN, (_mode)) #ifdef VMX86_DEVEL # define LOG_PACKET(_pkt) VSockVmciLogPkt(__FUNCTION__, __LINE__, _pkt) #else # define LOG_PACKET(_pkt) #endif /* *---------------------------------------------------------------------------- * * VSockVmciOldProtoOverride -- * * Check to see if the user has asked us to override all sockets to use * the vsock notify protocol. * * Results: * TRUE if there is a protocol override in effect. * - oldPktProto is TRUE the original protocol should be used. * FALSE if there is no override in effect. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static Bool VSockVmciOldProtoOverride(Bool *oldPktProto) // IN { ASSERT(oldPktProto); if (PROTOCOL_OVERRIDE != -1) { if (PROTOCOL_OVERRIDE == 0) { *oldPktProto = TRUE; } else { *oldPktProto = FALSE; } Warning("Proto override in use.\n"); return TRUE; } return FALSE; } /* *---------------------------------------------------------------------------- * * VSockVmciProtoToNotifyStruct -- * * Given a particular notify protocol version, setup the socket's notify * struct correctly. * * Results: * TRUE on success. FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static Bool VSockVmciProtoToNotifyStruct(struct sock *sk, // IN VSockProtoVersion *proto, // IN Bool oldPktProto) // IN { VSockVmciSock *vsk; ASSERT(sk); ASSERT(proto); vsk = vsock_sk(sk); if (oldPktProto) { if (*proto != VSOCK_PROTO_INVALID) { Warning("Can't set both an old and new protocol\n"); return FALSE; } vsk->notifyOps = &vSockVmciNotifyPktOps; goto exit; } switch(*proto) { case VSOCK_PROTO_PKT_ON_NOTIFY: vsk->notifyOps= &vSockVmciNotifyPktQStateOps; break; default: Warning("Unknown notify protocol version\n"); return FALSE; } exit: NOTIFYCALL(vsk, socketInit, sk); return TRUE; } /* *---------------------------------------------------------------------------- * * VSockVmciNewProtoSupportedVersions * * Gets the supported REQUEST2/NEGOTIATE2 vsock protocol versions. * * Results: * Either 1 specific protocol version (override mode) or * VSOCK_PROTO_ALL_SUPPORTED. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static VSockProtoVersion VSockVmciNewProtoSupportedVersions(void) // IN { if (PROTOCOL_OVERRIDE != -1) { return PROTOCOL_OVERRIDE; } return VSOCK_PROTO_ALL_SUPPORTED; } /* *---------------------------------------------------------------------------- * * VSockSocket_Trusted -- * * We allow two kinds of sockets to communicate with a restricted VM: * 1) trusted sockets * 2) sockets from applications running as the same user as the VM (this * is only true for the host side and only when using hosted products) * * Results: * TRUE if trusted communication is allowed to peerCid, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool VSockVmciTrusted(VSockVmciSock *vsock, // IN: Local socket VMCIId peerCid) // IN: Context ID of peer { return vsock->trusted || vmci_is_context_owner(peerCid, vsock->owner); } /* *---------------------------------------------------------------------------- * * VSockSocket_AllowDgram -- * * We allow sending datagrams to and receiving datagrams from a * restricted VM only if it is trusted as described in * VSockVmciTrusted. * * Results: * TRUE if datagram communication is allowed to peerCid, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool VSockVmciAllowDgram(VSockVmciSock *vsock, // IN: Local socket VMCIId peerCid) // IN: Context ID of peer { if (vsock->cachedPeer != peerCid) { vsock->cachedPeer = peerCid; if (!VSockVmciTrusted(vsock, peerCid) && (vmci_context_get_priv_flags(peerCid) & VMCI_PRIVILEGE_FLAG_RESTRICTED)) { vsock->cachedPeerAllowDgram = FALSE; } else { vsock->cachedPeerAllowDgram = TRUE; } } return vsock->cachedPeerAllowDgram; } /* *---------------------------------------------------------------------------- * * VMCISock_GetAFValue -- * * Kernel interface that allows external kernel modules to get the current * VMCI Sockets address family. * This version of the function is exported to kernel clients and should not * change. * * Results: * The address family on success, a negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VMCISock_GetAFValue(void) { int afvalue; compat_mutex_lock(®istrationMutex); /* * Kernel clients are required to explicitly register themselves before they * can use VMCI Sockets. */ if (vsockVmciKernClientCount <= 0) { afvalue = -1; goto exit; } afvalue = VSockVmciGetAFValue(); exit: compat_mutex_unlock(®istrationMutex); return afvalue; } EXPORT_SYMBOL(VMCISock_GetAFValue); /* *---------------------------------------------------------------------------- * * VMCISock_GetLocalCID -- * * Kernel interface that allows external kernel modules to get the current * VMCI context id. * This version of the function is exported to kernel clients and should not * change. * * Results: * The context id on success, a negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VMCISock_GetLocalCID(void) { int cid; compat_mutex_lock(®istrationMutex); /* * Kernel clients are required to explicitly register themselves before they * can use VMCI Sockets. */ if (vsockVmciKernClientCount <= 0) { cid = -1; goto exit; } cid = vmci_get_context_id(); exit: compat_mutex_unlock(®istrationMutex); return cid; } EXPORT_SYMBOL(VMCISock_GetLocalCID); /* *---------------------------------------------------------------------------- * * VMCISock_KernelRegister -- * * Allows a kernel client to register with VMCI Sockets. Must be called * before VMCISock_GetAFValue within a kernel module. Note that we don't * actually register the address family until the first time the module * needs to use it. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void VMCISock_KernelRegister(void) { compat_mutex_lock(®istrationMutex); vsockVmciKernClientCount++; compat_mutex_unlock(®istrationMutex); } EXPORT_SYMBOL(VMCISock_KernelRegister); /* *---------------------------------------------------------------------------- * * VMCISock_KernelDeregister -- * * Allows a kernel client to unregister with VMCI Sockets. Every call * to VMCISock_KernRegister must be matched with a call to * VMCISock_KernUnregister. * * Results: None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void VMCISock_KernelDeregister(void) { compat_mutex_lock(®istrationMutex); vsockVmciKernClientCount--; VSockVmciTestUnregister(); compat_mutex_unlock(®istrationMutex); } EXPORT_SYMBOL(VMCISock_KernelDeregister); /* *---------------------------------------------------------------------------- * * VSockVmciGetAFValue -- * * Returns the address family value being used. * Note: The registration mutex must be held when calling this function. * * Results: * The address family on success, a negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciGetAFValue(void) { int afvalue; afvalue = vsockVmciFamilyOps.family; if (!VSOCK_AF_IS_REGISTERED(afvalue)) { afvalue = VSockVmciRegisterAddressFamily(); } return afvalue; } /* *---------------------------------------------------------------------------- * * VSockVmci_GetAFValue -- * * Returns the address family value being used. * * Results: * The address family on success, a negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VSockVmci_GetAFValue(void) { int afvalue; compat_mutex_lock(®istrationMutex); afvalue = VSockVmciGetAFValue(); compat_mutex_unlock(®istrationMutex); return afvalue; } /* * Helper functions. */ /* *---------------------------------------------------------------------------- * * VSockVmciQueuePairAlloc -- * * Allocates or attaches to a queue pair. Tries to register with trusted * status if requested but does not fail if the queuepair could not be * allocate as trusted (running in the guest) * * Results: * 0 on success. A VSock error on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciQueuePairAlloc(VMCIQPair **qpair, // OUT VMCIHandle *handle, // IN/OUT uint64 produceSize, // IN uint64 consumeSize, // IN VMCIId peer, // IN uint32 flags, // IN Bool trusted) // IN { int err = 0; if (trusted) { /* * Try to allocate our queue pair as trusted. This will only work * if vsock is running in the host. */ err = vmci_qpair_alloc(qpair, handle, produceSize, consumeSize, peer, flags, VMCI_PRIVILEGE_FLAG_TRUSTED); if (err != VMCI_ERROR_NO_ACCESS) { goto out; } } err = vmci_qpair_alloc(qpair, handle, produceSize, consumeSize, peer, flags, VMCI_NO_PRIVILEGE_FLAGS); out: if (err < 0) { Log("Could not attach to queue pair with %d\n", err); err = VSockVmci_ErrorToVSockError(err); } return err; } /* *---------------------------------------------------------------------------- * * VSockVmciDatagramCreateHnd -- * * Creates a datagram handle. Tries to register with trusted * status but does not fail if the handler could not be allocated * as trusted (running in the guest). * * Results: * 0 on success. A VMCI error on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciDatagramCreateHnd(VMCIId resourceID, // IN uint32 flags, // IN VMCIDatagramRecvCB recvCB, // IN void *clientData, // IN VMCIHandle *outHandle) // OUT { int err = 0; /* * Try to allocate our datagram handler as trusted. This will only work * if vsock is running in the host. */ err = vmci_datagram_create_handle_priv(resourceID, flags, VMCI_PRIVILEGE_FLAG_TRUSTED, recvCB, clientData, outHandle); if (err == VMCI_ERROR_NO_ACCESS) { err = vmci_datagram_create_handle(resourceID, flags, recvCB, clientData, outHandle); } return err; } /* *---------------------------------------------------------------------------- * * VSockVmciTestUnregister -- * * Tests if it's necessary to unregister the socket family, and does so. * * Note that this assumes the registration lock is held. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VSockVmciTestUnregister(void) { if (devOpenCount <= 0 && vsockVmciSocketCount <= 0 && vsockVmciKernClientCount <= 0) { if (VSOCK_AF_IS_REGISTERED(vsockVmciFamilyOps.family)) { VSockVmciUnregisterAddressFamily(); } } } /* *---------------------------------------------------------------------------- * * VSockVmciRecvDgramCB -- * * VMCI Datagram receive callback. This function is used specifically for * SOCK_DGRAM sockets. * * This is invoked as part of a tasklet that's scheduled when the VMCI * interrupt fires. This is run in bottom-half context and if it ever needs * to sleep it should defer that work to a work queue. * * Results: * Zero on success, negative error code on failure. * * Side effects: * An sk_buff is created and queued with this socket. * *---------------------------------------------------------------------------- */ static int VSockVmciRecvDgramCB(void *data, // IN VMCIDatagram *dg) // IN { struct sock *sk; size_t size; struct sk_buff *skb; VSockVmciSock *vsk; ASSERT(dg); ASSERT(dg->payloadSize <= VMCI_MAX_DG_PAYLOAD_SIZE); sk = (struct sock *)data; ASSERT(sk); /* XXX Figure out why sk->sk_socket can be NULL. */ ASSERT(sk->sk_socket ? sk->sk_socket->type == SOCK_DGRAM : 1); /* * This handler is privileged when this module is running on the * host. We will get datagrams from all endpoints (even VMs that * are in a restricted context). If we get one from a restricted * context then the destination socket must be trusted. * * NOTE: We access the socket struct without holding the lock here. This * is ok because the field we are interested is never modified outside * of the create and destruct socket functions. */ vsk = vsock_sk(sk); if (!VSockVmciAllowDgram(vsk, VMCI_HANDLE_TO_CONTEXT_ID(dg->src))) { return VMCI_ERROR_NO_ACCESS; } size = VMCI_DG_SIZE(dg); /* * Attach the packet to the socket's receive queue as an sk_buff. */ skb = alloc_skb(size, GFP_ATOMIC); if (skb) { /* compat_sk_receive_skb() will do a sock_put(), so hold here. */ sock_hold(sk); skb_put(skb, size); memcpy(skb->data, dg, size); compat_sk_receive_skb(sk, skb, 0); } return VMCI_SUCCESS; } /* *---------------------------------------------------------------------------- * * VSockVmciSendSeqPacket -- * * Send a sequential packet. This uses a stack-allocated packet, i.e., * it isn't meant for DATA packets, but it works fine for the other packet * types. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciSendSeqPacket(VSockVmciSock *vsk, // IN VSockSeqPacketType type, // IN uint32 mode) // IN { int err; VSockSeqPacket pkt; ASSERT(vsk); VSockSeqPacket_Init(&pkt, &vsk->localAddr, &vsk->remoteAddr, type, mode); err = vmci_datagram_send(&pkt.hdr.dg); if (err < 0) { err = VSockVmci_ErrorToVSockError(err); } return err; } /* *---------------------------------------------------------------------------- * * VSockVmciRecvSeqCB -- * * VMCI Datagram receive callback. This function is used specifically for * SOCK_SEQPACKET sockets. * * This is invoked as part of a tasklet that's scheduled when the VMCI * interrupt fires. This is run in bottom-half context and if it ever needs * to sleep it should defer that work to a work queue. * * Results: * Zero on success, negative error code on failure. * * Side effects: * An sk_buff is created and queued with this socket. * *---------------------------------------------------------------------------- */ static int VSockVmciRecvSeqCB(void *data, // IN VMCIDatagram *dg) // IN { struct sock *sk; size_t size; VSockVmciSock *vsk; VSockSeqPacket *pkt; ASSERT(dg); ASSERT(dg->payloadSize <= VMCI_MAX_DG_PAYLOAD_SIZE); sk = (struct sock *)data; ASSERT(sk); /* XXX, figure out why sk->sk_socket can be NULL. */ if (!sk->sk_socket) { return EINVAL; } ASSERT(sk->sk_socket->type == SOCK_SEQPACKET); if (VMCI_HYPERVISOR_CONTEXT_ID != dg->src.context) { return VMCI_ERROR_NO_ACCESS; } if (VMCI_RPC_PRIVILEGED != dg->src.resource && VMCI_RPC_UNPRIVILEGED != dg->src.resource) { return VMCI_ERROR_NO_ACCESS; } size = VMCI_DG_SIZE(dg); if (size < sizeof *pkt) { return VMCI_ERROR_INVALID_ARGS; } vsk = vsock_sk(sk); pkt = (VSockSeqPacket *)dg; /* * After this point, if we fail to handle the packet, we need to send a * close to the peer with an error. Otherwise it might hang, waiting for a * response to a packet that we discarded. */ if (VSOCK_SEQ_PACKET_VERSION_1 != pkt->hdr.version) { VSOCK_SEND_SEQ_CLOSE(vsk, EINVAL); return VMCI_ERROR_INVALID_ARGS; } if (SS_CONNECTED != sk->sk_socket->state) { VSOCK_SEND_SEQ_CLOSE(vsk, ENOTCONN); return VMCI_ERROR_DST_UNREACHABLE; } switch (pkt->hdr.type) { case VSOCK_SEQ_PACKET_TYPE_DATA: { struct sk_buff *skb; /* * Attach the packet to the socket's receive queue as an sk_buff. */ size -= sizeof *pkt; skb = alloc_skb(size, GFP_ATOMIC); if (!skb) { VSOCK_SEND_SEQ_CLOSE(vsk, ENOMEM); return VMCI_ERROR_NO_MEM; } /* compat_sk_receive_skb() will do a sock_put(), so hold here. */ sock_hold(sk); skb_put(skb, size); memcpy(skb->data, VSOCK_SEQ_PACKET_PAYLOAD(pkt), size); /* * XXX, this can drop the skb. We need to find an alternative that * will return an error if that happens, so that we can send a reset * to the peer, i.e., * * if (!receive_skb(sk, skb)) { * VSOCK_SEND_SEQ_CLOSE(vsk, ENOMEM); * return VMCI_ERROR_NO_MEM; * } */ compat_sk_receive_skb(sk, skb, 0); break; } case VSOCK_SEQ_PACKET_TYPE_CLOSE: bh_lock_sock(sk); sock_set_flag(sk, SOCK_DONE); vsk->peerShutdown = SHUTDOWN_MASK; sk->sk_state = TCP_CLOSE; /* * A close packet with an error code means a forceful reset, whereas * no error means a graceful close. */ if (pkt->hdr.val) { sk->sk_socket->state = SS_UNCONNECTED; sk->sk_err = pkt->hdr.val; sk->sk_error_report(sk); } else { if (skb_queue_empty(&sk->sk_receive_queue)) { sk->sk_socket->state = SS_DISCONNECTING; } sk->sk_state_change(sk); } bh_unlock_sock(sk); break; /* * There's no reason for us to receive a shutdown packet in this direction, * or any other packet for that matter. Inform the peer that the packet * is invalid. */ default: VSOCK_SEND_SEQ_CLOSE(vsk, EINVAL); return VMCI_ERROR_INVALID_ARGS; } return VMCI_SUCCESS; } /* *---------------------------------------------------------------------------- * * VSockVmciRecvStreamCB -- * * VMCI stream receive callback for control datagrams. This function is * used specifically for SOCK_STREAM sockets. * * This is invoked as part of a tasklet that's scheduled when the VMCI * interrupt fires. This is run in bottom-half context but it defers most * of its work to the packet handling work queue. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciRecvStreamCB(void *data, // IN VMCIDatagram *dg) // IN { struct sock *sk; struct sockaddr_vm dst; struct sockaddr_vm src; VSockPacket *pkt; VSockVmciSock *vsk; Bool bhProcessPkt; int err; ASSERT(dg); ASSERT(dg->payloadSize <= VMCI_MAX_DG_PAYLOAD_SIZE); sk = NULL; err = VMCI_SUCCESS; bhProcessPkt = FALSE; /* * Ignore incoming packets from contexts without sockets, or resources that * aren't vsock implementations. */ if (!VSockAddr_SocketContextStream(VMCI_HANDLE_TO_CONTEXT_ID(dg->src)) || VSOCK_PACKET_RID != VMCI_HANDLE_TO_RESOURCE_ID(dg->src)) { return VMCI_ERROR_NO_ACCESS; } if (VMCI_DG_SIZE(dg) < sizeof *pkt) { /* Drop datagrams that do not contain full VSock packets. */ return VMCI_ERROR_INVALID_ARGS; } pkt = (VSockPacket *)dg; LOG_PACKET(pkt); /* * Find the socket that should handle this packet. First we look for * a connected socket and if there is none we look for a socket bound to * the destintation address. * * Note that we don't initialize the family member of the src and dst * sockaddr_vm since we don't want to call VMCISock_GetAFValue() and * possibly register the address family. */ VSockAddr_InitNoFamily(&src, VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.src), pkt->srcPort); VSockAddr_InitNoFamily(&dst, VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.dst), pkt->dstPort); sk = VSockVmciFindConnectedSocket(&src, &dst); if (!sk) { sk = VSockVmciFindBoundSocket(&dst); if (!sk) { /* * We could not find a socket for this specified address. If this * packet is a RST, we just drop it. If it is another packet, we send * a RST. Note that we do not send a RST reply to RSTs so that we do * not continually send RSTs between two endpoints. * * Note that since this is a reply, dst is src and src is dst. */ if (VSOCK_SEND_RESET_BH(&dst, &src, pkt) < 0) { Log("unable to send reset.\n"); } err = VMCI_ERROR_NOT_FOUND; goto out; } } /* * If the received packet type is beyond all types known to this * implementation, reply with an invalid message. Hopefully this will help * when implementing backwards compatibility in the future. */ if (pkt->type >= VSOCK_PACKET_TYPE_MAX) { VSOCK_SEND_INVALID_BH(&dst, &src); err = VMCI_ERROR_INVALID_ARGS; goto out; } /* * This handler is privileged when this module is running on the host. * We will get datagram connect requests from all endpoints (even VMs that * are in a restricted context). If we get one from a restricted context * then the destination socket must be trusted. * * NOTE: We access the socket struct without holding the lock here. This * is ok because the field we are interested is never modified outside * of the create and destruct socket functions. */ vsk = vsock_sk(sk); if (!VSockVmciAllowDgram(vsk, VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.src))) { err = VMCI_ERROR_NO_ACCESS; goto out; } /* * We do most everything in a work queue, but let's fast path the * notification of reads and writes to help data transfer performance. We * can only do this if there is no process context code executing for this * socket since that may change the state. */ bh_lock_sock(sk); if (!sock_owned_by_user(sk) && sk->sk_state == SS_CONNECTED) { NOTIFYCALL(vsk, handleNotifyPkt, sk, pkt, TRUE, &dst, &src, &bhProcessPkt); } bh_unlock_sock(sk); if (!bhProcessPkt) { VSockRecvPktInfo *recvPktInfo; recvPktInfo = kmalloc(sizeof *recvPktInfo, GFP_ATOMIC); if (!recvPktInfo) { if (VSOCK_SEND_RESET_BH(&dst, &src, pkt) < 0) { Warning("unable to send reset\n"); } err = VMCI_ERROR_NO_MEM; goto out; } recvPktInfo->sk = sk; memcpy(&recvPktInfo->pkt, pkt, sizeof recvPktInfo->pkt); COMPAT_INIT_WORK(&recvPktInfo->work, VSockVmciRecvPktWork, recvPktInfo); compat_schedule_work(&recvPktInfo->work); /* * Clear sk so that the reference count incremented by one of the Find * functions above is not decremented below. We need that reference * count for the packet handler we've scheduled to run. */ sk = NULL; } out: if (sk) { sock_put(sk); } return err; } /* *---------------------------------------------------------------------------- * * VSockVmciPeerAttachCB -- * * Invoked when a peer attaches to a queue pair. * * Right now this does not do anything. * * Results: * None. * * Side effects: * May modify socket state and signal socket. * *---------------------------------------------------------------------------- */ static void VSockVmciPeerAttachCB(VMCIId subId, // IN VMCI_EventData *eData, // IN void *clientData) // IN { struct sock *sk; VMCIEventPayload_QP *ePayload; VSockVmciSock *vsk; ASSERT(eData); ASSERT(clientData); sk = (struct sock *)clientData; ePayload = VMCIEventDataPayload(eData); vsk = vsock_sk(sk); /* * We don't ask for delayed CBs when we subscribe to this event (we pass 0 * as flags to VMCIEvent_Subscribe()). VMCI makes no guarantees in that * case about what context we might be running in, so it could be BH or * process, blockable or non-blockable. And bh_lock_sock() is very * particular about how it gets called (it's *not* the same as * spin_lock_bh(), it expands directly into a spin_lock()). So we need to * account for all possible contexts here. */ local_bh_disable(); bh_lock_sock(sk); /* * XXX This is lame, we should provide a way to lookup sockets by qpHandle. */ if (VMCI_HANDLE_EQUAL(vsk->qpHandle, ePayload->handle)) { /* * XXX This doesn't do anything, but in the future we may want to set * a flag here to verify the attach really did occur and we weren't just * sent a datagram claiming it was. */ goto out; } out: bh_unlock_sock(sk); local_bh_enable(); } /* *---------------------------------------------------------------------------- * * VSockVmciHandleDetach -- * * Perform the work necessary when the peer has detached. * * Note that this assumes the socket lock is held. * * Results: * None. * * Side effects: * The socket's and its peer's shutdown mask will be set appropriately, * and any callers waiting on this socket will be awoken. * *---------------------------------------------------------------------------- */ static void VSockVmciHandleDetach(struct sock *sk) // IN { VSockVmciSock *vsk; ASSERT(sk); vsk = vsock_sk(sk); if (!VMCI_HANDLE_INVALID(vsk->qpHandle)) { ASSERT(vsk->qpair); sock_set_flag(sk, SOCK_DONE); /* On a detach the peer will not be sending or receiving anymore. */ vsk->peerShutdown = SHUTDOWN_MASK; /* * We should not be sending anymore since the peer won't be there to * receive, but we can still receive if there is data left in our consume * queue. */ if (VSockVmciStreamHasData(vsk) <= 0) { if (sk->sk_state == SS_CONNECTING) { /* * The peer may detach from a queue pair while we are * still in the connecting state, i.e., if the peer VM is * killed after attaching to a queue pair, but before we * complete the handshake. In that case, we treat the * detach event like a reset. */ sk->sk_state = SS_UNCONNECTED; sk->sk_err = ECONNRESET; sk->sk_error_report(sk); return; } sk->sk_state = SS_UNCONNECTED; } sk->sk_state_change(sk); } } /* *---------------------------------------------------------------------------- * * VSockVmciPeerDetachCB -- * * Invoked when a peer detaches from a queue pair. * * Results: * None. * * Side effects: * May modify socket state and signal socket. * *---------------------------------------------------------------------------- */ static void VSockVmciPeerDetachCB(VMCIId subId, // IN VMCI_EventData *eData, // IN void *clientData) // IN { struct sock *sk; VMCIEventPayload_QP *ePayload; VSockVmciSock *vsk; ASSERT(eData); ASSERT(clientData); sk = (struct sock *)clientData; ePayload = VMCIEventDataPayload(eData); vsk = vsock_sk(sk); if (VMCI_HANDLE_INVALID(ePayload->handle)) { return; } /* Same rules for locking as for PeerAttachCB(). */ local_bh_disable(); bh_lock_sock(sk); /* * XXX This is lame, we should provide a way to lookup sockets by qpHandle. */ if (VMCI_HANDLE_EQUAL(vsk->qpHandle, ePayload->handle)) { VSockVmciHandleDetach(sk); } bh_unlock_sock(sk); local_bh_enable(); } /* *---------------------------------------------------------------------------- * * VSockVmciQPResumedCB -- * * Invoked when a VM is resumed. We must mark all connected stream sockets * as detached. * * Results: * None. * * Side effects: * May modify socket state and signal socket. * *---------------------------------------------------------------------------- */ static void VSockVmciQPResumedCB(VMCIId subId, // IN VMCI_EventData *eData, // IN void *clientData) // IN { uint32 i; spin_lock_bh(&vsockTableLock); /* * XXX This loop should probably be provided by util.{h,c}, but that's for * another day. */ for (i = 0; i < ARRAYSIZE(vsockConnectedTable); i++) { VSockVmciSock *vsk; list_for_each_entry(vsk, &vsockConnectedTable[i], connectedTable) { struct sock *sk = sk_vsock(vsk); /* * XXX Technically this is racy but the resulting outcome from such * a race is relatively harmless. My next change will be a fix to * this. */ VSockVmciHandleDetach(sk); } } spin_unlock_bh(&vsockTableLock); } /* *---------------------------------------------------------------------------- * * VSockVmciContextUpdatedCB -- * * Invoked when a VM is resumed (technically when the context ID changes, * but the event is actually sent even when it does not, so this works * well for catching resumes). We must mark all connected sequential * sockets as detached. * * Results: * None. * * Side effects: * May modify socket state and signal socket. * *---------------------------------------------------------------------------- */ static void VSockVmciContextUpdatedCB(VMCIId subId, // IN VMCI_EventData *eData, // IN void *clientData) // IN { uint32 i; spin_lock_bh(&vsockSeqTableLock); for (i = 0; i < ARRAYSIZE(vsockSeqTable); i++) { VSockVmciSock *vsk; list_for_each_entry(vsk, &vsockSeqTable[i], seqTable) { struct sock *sk = sk_vsock(vsk); sock_set_flag(sk, SOCK_DONE); vsk->peerShutdown = SHUTDOWN_MASK; sk->sk_state = TCP_CLOSE; if (skb_queue_empty(&sk->sk_receive_queue)) { sk->sk_socket->state = SS_DISCONNECTING; } sk->sk_state_change(sk); } } spin_unlock_bh(&vsockSeqTableLock); } /* *---------------------------------------------------------------------------- * * VSockVmciPendingWork -- * * Releases the resources for a pending socket if it has not reached the * connected state and been accepted by a user process. * * Results: * None. * * Side effects: * The socket may be removed from the connected list and all its resources * freed. * *---------------------------------------------------------------------------- */ static void VSockVmciPendingWork(compat_delayed_work_arg work) // IN { struct sock *sk; struct sock *listener; VSockVmciSock *vsk; Bool cleanup; vsk = COMPAT_DELAYED_WORK_GET_DATA(work, VSockVmciSock, dwork); ASSERT(vsk); sk = sk_vsock(vsk); listener = vsk->listener; cleanup = TRUE; ASSERT(listener); lock_sock(listener); lock_sock(sk); /* * The socket should be on the pending list or the accept queue, but not * both. It's also possible that the socket isn't on either. */ ASSERT( ( VSockVmciIsPending(sk) && !VSockVmciInAcceptQueue(sk)) || (!VSockVmciIsPending(sk) && VSockVmciInAcceptQueue(sk)) || (!VSockVmciIsPending(sk) && !VSockVmciInAcceptQueue(sk))); if (VSockVmciIsPending(sk)) { VSockVmciRemovePending(listener, sk); } else if (!vsk->rejected) { /* * We are not on the pending list and accept() did not reject us, so we * must have been accepted by our user process. We just need to drop our * references to the sockets and be on our way. */ cleanup = FALSE; goto out; } listener->sk_ack_backlog--; /* * We need to remove ourself from the global connected sockets list so * incoming packets can't find this socket, and to reduce the reference * count. */ if (VSockVmciInConnectedTable(sk)) { VSockVmciRemoveConnected(sk); } sk->sk_state = SS_FREE; out: release_sock(sk); release_sock(listener); if (cleanup) { sock_put(sk); } sock_put(sk); sock_put(listener); } /* *---------------------------------------------------------------------------- * * VSockVmciRecvPktWork -- * * Handles an incoming control packet for the provided socket. This is the * state machine for our stream sockets. * * Results: * None. * * Side effects: * May set state and wakeup threads waiting for socket state to change. * *---------------------------------------------------------------------------- */ static void VSockVmciRecvPktWork(compat_work_arg work) // IN { VSockRecvPktInfo *recvPktInfo; VSockPacket *pkt; struct sock *sk; recvPktInfo = COMPAT_WORK_GET_DATA(work, VSockRecvPktInfo, work); ASSERT(recvPktInfo); sk = recvPktInfo->sk; pkt = &recvPktInfo->pkt; ASSERT(pkt); ASSERT(pkt->type < VSOCK_PACKET_TYPE_MAX); lock_sock(sk); switch (sk->sk_state) { case SS_LISTEN: VSockVmciRecvListen(sk, pkt); break; case SS_CONNECTING: /* * Processing of pending connections for servers goes through the * listening socket, so see VSockVmciRecvListen() for that path. */ VSockVmciRecvConnectingClient(sk, pkt); break; case SS_CONNECTED: VSockVmciRecvConnected(sk, pkt); break; default: /* * Because this function does not run in the same context as * VSockVmciRecvStreamCB it is possible that the socket * has closed. We need to let the other side know or it could * be sitting in a connect and hang forever. Send a reset to prevent * that. */ VSOCK_SEND_RESET(sk, pkt); goto out; } out: release_sock(sk); kfree(recvPktInfo); /* * Release reference obtained in the stream callback when we fetched this * socket out of the bound or connected list. */ sock_put(sk); } /* *---------------------------------------------------------------------------- * * VSockVmciRecvListen -- * * Receives packets for sockets in the listen state. * * Note that this assumes the socket lock is held. * * Results: * Zero on success, negative error code on failure. * * Side effects: * A new socket may be created and a negotiate control packet is sent. * *---------------------------------------------------------------------------- */ static int VSockVmciRecvListen(struct sock *sk, // IN VSockPacket *pkt) // IN { struct sock *pending; VSockVmciSock *vpending; int err; uint64 qpSize; Bool oldRequest = FALSE; Bool oldPktProto = FALSE; ASSERT(sk); ASSERT(pkt); ASSERT(sk->sk_state == SS_LISTEN); err = 0; /* * Because we are in the listen state, we could be receiving a packet for * ourself or any previous connection requests that we received. If it's * the latter, we try to find a socket in our list of pending connections * and, if we do, call the appropriate handler for the state that that * socket is in. Otherwise we try to service the connection request. */ pending = VSockVmciGetPending(sk, pkt); if (pending) { lock_sock(pending); switch (pending->sk_state) { case SS_CONNECTING: err = VSockVmciRecvConnectingServer(sk, pending, pkt); break; default: VSOCK_SEND_RESET(pending, pkt); err = -EINVAL; } if (err < 0) { VSockVmciRemovePending(sk, pending); } release_sock(pending); VSockVmciReleasePending(pending); return err; } /* * The listen state only accepts connection requests. Reply with a reset * unless we received a reset. */ if (!(pkt->type == VSOCK_PACKET_TYPE_REQUEST || pkt->type == VSOCK_PACKET_TYPE_REQUEST2)) { VSOCK_REPLY_RESET(pkt); return -EINVAL; } if (pkt->u.size == 0) { VSOCK_REPLY_RESET(pkt); return -EINVAL; } /* * If this socket can't accommodate this connection request, we send * a reset. Otherwise we create and initialize a child socket and reply * with a connection negotiation. */ if (sk->sk_ack_backlog >= sk->sk_max_ack_backlog) { VSOCK_REPLY_RESET(pkt); return -ECONNREFUSED; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) pending = __VSockVmciCreate(NULL, sk, GFP_KERNEL, sk->sk_type); #else pending = __VSockVmciCreate(compat_sock_net(sk), NULL, sk, GFP_KERNEL, sk->sk_type); #endif if (!pending) { VSOCK_SEND_RESET(sk, pkt); return -ENOMEM; } vpending = vsock_sk(pending); ASSERT(vpending); ASSERT(vsock_sk(sk)->localAddr.svm_port == pkt->dstPort); VSockAddr_Init(&vpending->localAddr, VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.dst), pkt->dstPort); VSockAddr_Init(&vpending->remoteAddr, VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.src), pkt->srcPort); /* * If the proposed size fits within our min/max, accept * it. Otherwise propose our own size. */ if (pkt->u.size >= vpending->queuePairMinSize && pkt->u.size <= vpending->queuePairMaxSize) { qpSize = pkt->u.size; } else { qpSize = vpending->queuePairSize; } /* * Figure out if we are using old or new requests based on the overrides * pkt types sent by our peer. */ if (VSockVmciOldProtoOverride(&oldPktProto)) { oldRequest = oldPktProto; } else { if (pkt->type == VSOCK_PACKET_TYPE_REQUEST) { oldRequest = TRUE; } else if (pkt->type == VSOCK_PACKET_TYPE_REQUEST2) { oldRequest = FALSE; } } if (oldRequest) { /* Handle a REQUEST (or override) */ VSockProtoVersion version = VSOCK_PROTO_INVALID; if (VSockVmciProtoToNotifyStruct(pending, &version, TRUE)) { err = VSOCK_SEND_NEGOTIATE(pending, qpSize); } else { err = -EINVAL; } } else { /* Handle a REQUEST2 (or override) */ int protoInt = pkt->proto; int pos; uint16 activeProtoVersion = 0; /* * The list of possible protocols is the intersection of all protocols * the client supports ... plus all the protocols we support. */ protoInt &= VSockVmciNewProtoSupportedVersions(); /* We choose the highest possible protocol version and use that one. */ pos = mssb32(protoInt); if (pos) { activeProtoVersion = (1 << (pos - 1)); if (VSockVmciProtoToNotifyStruct(pending, &activeProtoVersion, FALSE)) { err = VSOCK_SEND_NEGOTIATE2(pending, qpSize, activeProtoVersion); } else { err = -EINVAL; } } else { err = -EINVAL; } } if (err < 0) { VSOCK_SEND_RESET(sk, pkt); sock_put(pending); err = VSockVmci_ErrorToVSockError(err); goto out; } VSockVmciAddPending(sk, pending); sk->sk_ack_backlog++; pending->sk_state = SS_CONNECTING; vpending->produceSize = vpending->consumeSize = qpSize; vpending->queuePairSize = qpSize; NOTIFYCALL(vpending, processRequest, pending); /* * We might never receive another message for this socket and it's not * connected to any process, so we have to ensure it gets cleaned up * ourself. Our delayed work function will take care of that. Note that we * do not ever cancel this function since we have few guarantees about its * state when calling cancel_delayed_work(). Instead we hold a reference on * the socket for that function and make it capable of handling cases where * it needs to do nothing but release that reference. */ vpending->listener = sk; sock_hold(sk); sock_hold(pending); COMPAT_INIT_DELAYED_WORK(&vpending->dwork, VSockVmciPendingWork, vpending); compat_schedule_delayed_work(&vpending->dwork, HZ); out: return err; } /* *---------------------------------------------------------------------------- * * VSockVmciRecvConnectingServer -- * * Receives packets for sockets in the connecting state on the server side. * * Connecting sockets on the server side can only receive queue pair offer * packets. All others should be treated as cause for closing the * connection. * * Note that this assumes the socket lock is held for both sk and pending. * * Results: * Zero on success, negative error code on failure. * * Side effects: * A queue pair may be created, an attach control packet may be sent, the * socket may transition to the connected state, and a pending caller in * accept() may be woken up. * *---------------------------------------------------------------------------- */ static int VSockVmciRecvConnectingServer(struct sock *listener, // IN: the listening socket struct sock *pending, // IN: the pending connection VSockPacket *pkt) // IN: current packet { VSockVmciSock *vpending; VMCIHandle handle; VMCIQPair *qpair; Bool isLocal; uint32 flags; VMCIId detachSubId; int err; int skerr; ASSERT(listener); ASSERT(pkt); ASSERT(listener->sk_state == SS_LISTEN); ASSERT(pending->sk_state == SS_CONNECTING); vpending = vsock_sk(pending); detachSubId = VMCI_INVALID_ID; switch (pkt->type) { case VSOCK_PACKET_TYPE_OFFER: if (VMCI_HANDLE_INVALID(pkt->u.handle)) { VSOCK_SEND_RESET(pending, pkt); skerr = EPROTO; err = -EINVAL; goto destroy; } break; default: /* Close and cleanup the connection. */ VSOCK_SEND_RESET(pending, pkt); skerr = EPROTO; err = pkt->type == VSOCK_PACKET_TYPE_RST ? 0 : -EINVAL; goto destroy; } ASSERT(pkt->type == VSOCK_PACKET_TYPE_OFFER); /* * In order to complete the connection we need to attach to the offered * queue pair and send an attach notification. We also subscribe to the * detach event so we know when our peer goes away, and we do that before * attaching so we don't miss an event. If all this succeeds, we update our * state and wakeup anything waiting in accept() for a connection. */ /* * We don't care about attach since we ensure the other side has attached by * specifying the ATTACH_ONLY flag below. */ err = vmci_event_subscribe(VMCI_EVENT_QP_PEER_DETACH, VSockVmciPeerDetachCB, pending, &detachSubId); if (err < VMCI_SUCCESS) { VSOCK_SEND_RESET(pending, pkt); err = VSockVmci_ErrorToVSockError(err); skerr = -err; goto destroy; } vpending->detachSubId = detachSubId; /* Now attach to the queue pair the client created. */ handle = pkt->u.handle; /* * vpending->localAddr always has a context id so we do not * need to worry about VMADDR_CID_ANY in this case. */ isLocal = vpending->remoteAddr.svm_cid == vpending->localAddr.svm_cid; flags = VMCI_QPFLAG_ATTACH_ONLY; flags |= isLocal ? VMCI_QPFLAG_LOCAL : 0; err = VSockVmciQueuePairAlloc(&qpair, &handle, vpending->produceSize, vpending->consumeSize, VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.src), flags, VSockVmciTrusted(vpending, vpending->remoteAddr.svm_cid)); if (err < 0) { VSOCK_SEND_RESET(pending, pkt); skerr = -err; goto destroy; } ASSERT(VMCI_HANDLE_EQUAL(handle, pkt->u.handle)); vpending->qpHandle = handle; vpending->qpair = qpair; /* * When we send the attach message, we must be ready to handle * incoming control messages on the newly connected socket. So we * move the pending socket to the connected state before sending * the attach message. Otherwise, an incoming packet triggered by * the attach being received by the peer may be processed * concurrently with what happens below after sending the attach * message, and that incoming packet will find the listening socket * instead of the (currently) pending socket. Note that enqueueing * the socket increments the reference count, so even if a reset * comes before the connection is accepted, the socket will be * valid until it is removed from the queue. * * If we fail sending the attach below, we remove the socket from * the connected list and move the socket to SS_UNCONNECTED before * releasing the lock, so a pending slow path processing of an * incoming packet will not see the socket in the connected state * in that case. */ pending->sk_state = SS_CONNECTED; VSockVmciInsertConnected(vsockConnectedSocketsVsk(vpending), pending); /* Notify our peer of our attach. */ err = VSOCK_SEND_ATTACH(pending, handle); if (err < 0) { VSockVmciRemoveConnected(pending); Log("Could not send attach\n"); VSOCK_SEND_RESET(pending, pkt); err = VSockVmci_ErrorToVSockError(err); skerr = -err; goto destroy; } /* * We have a connection. Move the now connected socket from the * listener's pending list to the accept queue so callers of * accept() can find it. */ VSockVmciRemovePending(listener, pending); VSockVmciEnqueueAccept(listener, pending); /* * Callers of accept() will be be waiting on the listening socket, not the * pending socket. */ listener->sk_state_change(listener); return 0; destroy: pending->sk_err = skerr; pending->sk_state = SS_UNCONNECTED; /* * As long as we drop our reference, all necessary cleanup will handle when * the cleanup function drops its reference and our destruct implementation * is called. Note that since the listen handler will remove pending from * the pending list upon our failure, the cleanup function won't drop the * additional reference, which is why we do it here. */ sock_put(pending); return err; } /* *---------------------------------------------------------------------------- * * VSockVmciRecvConnectingClient -- * * Receives packets for sockets in the connecting state on the client side. * * Connecting sockets on the client side should only receive attach packets. * All others should be treated as cause for closing the connection. * * Note that this assumes the socket lock is held for both sk and pending. * * Results: * Zero on success, negative error code on failure. * * Side effects: * The socket may transition to the connected state and wakeup the pending * caller of connect(). * *---------------------------------------------------------------------------- */ static int VSockVmciRecvConnectingClient(struct sock *sk, // IN: socket VSockPacket *pkt) // IN: current packet { VSockVmciSock *vsk; int err; int skerr; ASSERT(sk); ASSERT(pkt); ASSERT(sk->sk_state == SS_CONNECTING); vsk = vsock_sk(sk); switch (pkt->type) { case VSOCK_PACKET_TYPE_ATTACH: if (VMCI_HANDLE_INVALID(pkt->u.handle) || !VMCI_HANDLE_EQUAL(pkt->u.handle, vsk->qpHandle)) { skerr = EPROTO; err = -EINVAL; goto destroy; } /* * Signify the socket is connected and wakeup the waiter in connect(). * Also place the socket in the connected table for accounting (it can * already be found since it's in the bound table). */ sk->sk_state = SS_CONNECTED; sk->sk_socket->state = SS_CONNECTED; VSockVmciInsertConnected(vsockConnectedSocketsVsk(vsk), sk); sk->sk_state_change(sk); break; case VSOCK_PACKET_TYPE_NEGOTIATE: case VSOCK_PACKET_TYPE_NEGOTIATE2: if (pkt->u.size == 0 || VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.src) != vsk->remoteAddr.svm_cid || pkt->srcPort != vsk->remoteAddr.svm_port || !VMCI_HANDLE_INVALID(vsk->qpHandle) || vsk->qpair || vsk->produceSize != 0 || vsk->consumeSize != 0 || vsk->attachSubId != VMCI_INVALID_ID || vsk->detachSubId != VMCI_INVALID_ID) { skerr = EPROTO; err = -EINVAL; goto destroy; } err = VSockVmciRecvConnectingClientNegotiate(sk, pkt); if (err) { skerr = -err; goto destroy; } break; case VSOCK_PACKET_TYPE_INVALID: err = VSockVmciRecvConnectingClientInvalid(sk, pkt); if (err) { skerr = -err; goto destroy; } break; case VSOCK_PACKET_TYPE_RST: /* * Older versions of the linux code (WS 6.5 / ESX 4.0) used to continue * processing here after they sent an INVALID packet. This meant that we * got a RST after the INVALID. We ignore a RST after an INVALID. The * common code doesn't send the RST ... so we can hang if an old version * of the common code fails between getting a REQUEST and sending an * OFFER back. Not much we can do about it... except hope that it * doesn't happen. */ if (vsk->ignoreConnectingRst) { vsk->ignoreConnectingRst = FALSE; } else { skerr = ECONNRESET; err = 0; goto destroy; } break; default: /* Close and cleanup the connection. */ skerr = EPROTO; err = -EINVAL; goto destroy; } ASSERT(pkt->type == VSOCK_PACKET_TYPE_ATTACH || pkt->type == VSOCK_PACKET_TYPE_NEGOTIATE || pkt->type == VSOCK_PACKET_TYPE_NEGOTIATE2 || pkt->type == VSOCK_PACKET_TYPE_INVALID || pkt->type == VSOCK_PACKET_TYPE_RST); return 0; destroy: VSOCK_SEND_RESET(sk, pkt); sk->sk_state = SS_UNCONNECTED; sk->sk_err = skerr; sk->sk_error_report(sk); return err; } /* *---------------------------------------------------------------------------- * * VSockVmciRecvConnectingClientNegotiate -- * * Handles a negotiate packet for a client in the connecting state. * * Note that this assumes the socket lock is held for both sk and pending. * * Results: * Zero on success, negative error code on failure. * * Side effects: * The socket may transition to the connected state and wakeup the pending * caller of connect(). * *---------------------------------------------------------------------------- */ static int VSockVmciRecvConnectingClientNegotiate(struct sock *sk, // IN: socket VSockPacket *pkt) // IN: current packet { int err; VSockVmciSock *vsk; VMCIHandle handle; VMCIQPair *qpair; VMCIId attachSubId; VMCIId detachSubId; Bool isLocal; uint32 flags; Bool oldProto = TRUE; Bool oldPktProto; VSockProtoVersion version; vsk = vsock_sk(sk); handle = VMCI_INVALID_HANDLE; attachSubId = VMCI_INVALID_ID; detachSubId = VMCI_INVALID_ID; ASSERT(sk); ASSERT(pkt); ASSERT(pkt->u.size > 0); ASSERT(vsk->remoteAddr.svm_cid == VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.src)); ASSERT(vsk->remoteAddr.svm_port == pkt->srcPort); ASSERT(VMCI_HANDLE_INVALID(vsk->qpHandle)); ASSERT(vsk->qpair == NULL); ASSERT(vsk->produceSize == 0); ASSERT(vsk->consumeSize == 0); ASSERT(vsk->attachSubId == VMCI_INVALID_ID); ASSERT(vsk->detachSubId == VMCI_INVALID_ID); /* * If we have gotten here then we should be past the point where old linux * vsock could have sent the bogus rst. */ vsk->sentRequest = FALSE; vsk->ignoreConnectingRst = FALSE; /* Verify that we're OK with the proposed queue pair size */ if (pkt->u.size < vsk->queuePairMinSize || pkt->u.size > vsk->queuePairMaxSize) { err = -EINVAL; goto destroy; } /* * At this point we know the CID the peer is using to talk to us. */ if (vsk->localAddr.svm_cid == VMADDR_CID_ANY) { vsk->localAddr.svm_cid = VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.dst); } /* * Setup the notify ops to be the highest supported version that both the * server and the client support. */ if (VSockVmciOldProtoOverride(&oldPktProto)) { oldProto = oldPktProto; } else { if (pkt->type == VSOCK_PACKET_TYPE_NEGOTIATE) { oldProto = TRUE; } else if (pkt->type == VSOCK_PACKET_TYPE_NEGOTIATE2) { oldProto = FALSE; } } if (oldProto) { version = VSOCK_PROTO_INVALID; } else { version = pkt->proto; } if (!VSockVmciProtoToNotifyStruct(sk, &version, oldProto)) { err = -EINVAL; goto destroy; } /* * Subscribe to attach and detach events first. * * XXX We attach once for each queue pair created for now so it is easy * to find the socket (it's provided), but later we should only subscribe * once and add a way to lookup sockets by queue pair handle. */ err = vmci_event_subscribe(VMCI_EVENT_QP_PEER_ATTACH, VSockVmciPeerAttachCB, sk, &attachSubId); if (err < VMCI_SUCCESS) { err = VSockVmci_ErrorToVSockError(err); goto destroy; } err = vmci_event_subscribe(VMCI_EVENT_QP_PEER_DETACH, VSockVmciPeerDetachCB, sk, &detachSubId); if (err < VMCI_SUCCESS) { err = VSockVmci_ErrorToVSockError(err); goto destroy; } /* Make VMCI select the handle for us. */ handle = VMCI_INVALID_HANDLE; isLocal = vsk->remoteAddr.svm_cid == vsk->localAddr.svm_cid; flags = isLocal ? VMCI_QPFLAG_LOCAL : 0; err = VSockVmciQueuePairAlloc(&qpair, &handle, pkt->u.size, pkt->u.size, vsk->remoteAddr.svm_cid, flags, VSockVmciTrusted(vsk, vsk->remoteAddr.svm_cid)); if (err < 0) { goto destroy; } err = VSOCK_SEND_QP_OFFER(sk, handle); if (err < 0) { err = VSockVmci_ErrorToVSockError(err); goto destroy; } vsk->qpHandle = handle; vsk->qpair = qpair; vsk->produceSize = vsk->consumeSize = pkt->u.size; vsk->attachSubId = attachSubId; vsk->detachSubId = detachSubId; NOTIFYCALL(vsk, processNegotiate, sk); return 0; destroy: if (attachSubId != VMCI_INVALID_ID) { vmci_event_unsubscribe(attachSubId); ASSERT(vsk->attachSubId == VMCI_INVALID_ID); } if (detachSubId != VMCI_INVALID_ID) { vmci_event_unsubscribe(detachSubId); ASSERT(vsk->detachSubId == VMCI_INVALID_ID); } if (!VMCI_HANDLE_INVALID(handle)) { ASSERT(vsk->qpair); vmci_qpair_detach(&qpair); ASSERT(VMCI_HANDLE_INVALID(vsk->qpHandle)); } return err; } /* *---------------------------------------------------------------------------- * * VSockVmciRecvConnectingClientInvalid -- * * Handles an invalid packet for a client in the connecting state. * * Note that this assumes the socket lock is held for both sk and pending. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciRecvConnectingClientInvalid(struct sock *sk, // IN: socket VSockPacket *pkt) // IN: current packet { int err = 0; VSockVmciSock *vsk; ASSERT(sk); ASSERT(pkt); vsk = vsock_sk(sk); if (vsk->sentRequest) { vsk->sentRequest = FALSE; vsk->ignoreConnectingRst = TRUE; err = VSOCK_SEND_CONN_REQUEST(sk, vsk->queuePairSize); if (err < 0) { err = VSockVmci_ErrorToVSockError(err); } else { err = 0; } } return err; } /* *---------------------------------------------------------------------------- * * VSockVmciRecvConnected -- * * Receives packets for sockets in the connected state. * * Connected sockets should only ever receive detach, wrote, read, or reset * control messages. Others are treated as errors that are ignored. * * Wrote and read signify that the peer has produced or consumed, * respectively. * * Detach messages signify that the connection is being closed cleanly and * reset messages signify that the connection is being closed in error. * * Note that this assumes the socket lock is held. * * Results: * Zero on success, negative error code on failure. * * Side effects: * A queue pair may be created, an offer control packet sent, and the socket * may transition to the connecting state. * * *---------------------------------------------------------------------------- */ static int VSockVmciRecvConnected(struct sock *sk, // IN VSockPacket *pkt) // IN { VSockVmciSock *vsk; Bool pktProcessed = FALSE; ASSERT(sk); ASSERT(pkt); ASSERT(sk->sk_state == SS_CONNECTED); /* * In cases where we are closing the connection, it's sufficient to mark * the state change (and maybe error) and wake up any waiting threads. * Since this is a connected socket, it's owned by a user process and will * be cleaned up when the failure is passed back on the current or next * system call. Our system call implementations must therefore check for * error and state changes on entry and when being awoken. */ switch (pkt->type) { case VSOCK_PACKET_TYPE_SHUTDOWN: if (pkt->u.mode) { vsk = vsock_sk(sk); vsk->peerShutdown |= pkt->u.mode; sk->sk_state_change(sk); } break; case VSOCK_PACKET_TYPE_RST: vsk = vsock_sk(sk); /* * It is possible that we sent our peer a message (e.g * a WAITING_READ) right before we got notified that the peer * had detached. If that happens then we can get a RST pkt back * from our peer even though there is data available for us * to read. In that case, don't shutdown the socket completely * but instead allow the local client to finish reading data * off the queuepair. Always treat a RST pkt in connected mode * like a clean shutdown. */ sock_set_flag(sk, SOCK_DONE); vsk->peerShutdown = SHUTDOWN_MASK; if (VSockVmciStreamHasData(vsk) <= 0) { sk->sk_state = SS_DISCONNECTING; } sk->sk_state_change(sk); break; default: vsk = vsock_sk(sk); NOTIFYCALL(vsk, handleNotifyPkt, sk, pkt, FALSE, NULL, NULL, &pktProcessed); if (!pktProcessed) { return -EINVAL; } break; } return 0; } /* *---------------------------------------------------------------------------- * * __VSockVmciSendControlPkt -- * * Common code to send a control packet. * * Results: * Size of datagram sent on success, negative error code otherwise. * If convertError is TRUE, error code is a vsock error, otherwise, * result is a VMCI error code. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int __VSockVmciSendControlPkt(VSockPacket *pkt, // IN struct sockaddr_vm *src, // IN struct sockaddr_vm *dst, // IN VSockPacketType type, // IN uint64 size, // IN uint64 mode, // IN VSockWaitingInfo *wait, // IN VSockProtoVersion proto, // IN VMCIHandle handle, // IN Bool convertError) // IN { int err; ASSERT(pkt); /* * This function can be called in different contexts, so family value is not * necessarily consistent. */ VSOCK_ADDR_NOFAMILY_ASSERT(src); VSOCK_ADDR_NOFAMILY_ASSERT(dst); VSockPacket_Init(pkt, src, dst, type, size, mode, wait, proto, handle); LOG_PACKET(pkt); VSOCK_STATS_CTLPKT_LOG(pkt->type); err = vmci_datagram_send(&pkt->dg); if (convertError && (err < 0)) { return VSockVmci_ErrorToVSockError(err); } return err; } /* *---------------------------------------------------------------------------- * * VSockVmciReplyControlPktFast -- * * Sends a control packet back to the source of an incoming packet. * The control packet is allocated in the stack. * * Results: * Size of datagram sent on success, negative error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VSockVmciReplyControlPktFast(VSockPacket *pkt, // IN VSockPacketType type, // IN uint64 size, // IN uint64 mode, // IN VSockWaitingInfo *wait, // IN VMCIHandle handle) // IN { VSockPacket reply; struct sockaddr_vm src, dst; ASSERT(pkt); if (pkt->type == VSOCK_PACKET_TYPE_RST) { return 0; } else { VSockPacket_GetAddresses(pkt, &src, &dst); return __VSockVmciSendControlPkt(&reply, &src, &dst, type, size, mode, wait, VSOCK_PROTO_INVALID, handle, TRUE); } } /* *---------------------------------------------------------------------------- * * VSockVmciSendControlPktBH -- * * Sends a control packet from bottom-half context. The control packet is * static data to minimize the resource cost. * * Results: * Size of datagram sent on success, negative error code otherwise. Note * that we return a VMCI error message since that's what callers will need * to provide. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VSockVmciSendControlPktBH(struct sockaddr_vm *src, // IN struct sockaddr_vm *dst, // IN VSockPacketType type, // IN uint64 size, // IN uint64 mode, // IN VSockWaitingInfo *wait, // IN VMCIHandle handle) // IN { /* * Note that it is safe to use a single packet across all CPUs since two * tasklets of the same type are guaranteed to not ever run simultaneously. * If that ever changes, or VMCI stops using tasklets, we can use per-cpu * packets. */ static VSockPacket pkt; return __VSockVmciSendControlPkt(&pkt, src, dst, type, size, mode, wait, VSOCK_PROTO_INVALID, handle, FALSE); } /* *---------------------------------------------------------------------------- * * VSockVmciSendControlPkt -- * * Sends a control packet. * * Results: * Size of datagram sent on success, negative error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VSockVmciSendControlPkt(struct sock *sk, // IN VSockPacketType type, // IN uint64 size, // IN uint64 mode, // IN VSockWaitingInfo *wait, // IN VSockProtoVersion proto, // IN VMCIHandle handle) // IN { VSockPacket *pkt; VSockVmciSock *vsk; int err; ASSERT(sk); /* * New sockets for connection establishment won't have socket structures * yet; if one exists, ensure it is of the proper type. */ ASSERT(sk->sk_socket ? sk->sk_socket->type == SOCK_STREAM : 1); vsk = vsock_sk(sk); if (!VSockAddr_Bound(&vsk->localAddr)) { return -EINVAL; } if (!VSockAddr_Bound(&vsk->remoteAddr)) { return -EINVAL; } pkt = kmalloc(sizeof *pkt, GFP_KERNEL); if (!pkt) { return -ENOMEM; } err = __VSockVmciSendControlPkt(pkt, &vsk->localAddr, &vsk->remoteAddr, type, size, mode, wait, proto, handle, TRUE); kfree(pkt); return err; } /* *---------------------------------------------------------------------------- * * __VSockVmciBind -- * * Common functionality needed to bind the specified address to the * VSocket. If VMADDR_CID_ANY or VMADDR_PORT_ANY are specified, the context * ID or port are selected automatically. * * Results: * Zero on success, negative error code on failure. * * Side effects: * On success, a new datagram handle is created. * *---------------------------------------------------------------------------- */ static int __VSockVmciBind(struct sock *sk, // IN/OUT struct sockaddr_vm *addr) // IN { static unsigned int port = LAST_RESERVED_PORT + 1; struct sockaddr_vm newAddr; VSockVmciSock *vsk; VMCIId cid; int err; ASSERT(sk); ASSERT(sk->sk_socket); ASSERT(addr); vsk = vsock_sk(sk); /* First ensure this socket isn't already bound. */ if (VSockAddr_Bound(&vsk->localAddr)) { return -EINVAL; } /* * Now bind to the provided address or select appropriate values if none are * provided (VMADDR_CID_ANY and VMADDR_PORT_ANY). Note that like AF_INET * prevents binding to a non-local IP address (in most cases), we only allow * binding to the local CID. */ VSockAddr_Init(&newAddr, VMADDR_CID_ANY, VMADDR_PORT_ANY); cid = vmci_get_context_id(); if (addr->svm_cid != cid && addr->svm_cid != VMADDR_CID_ANY) { return -EADDRNOTAVAIL; } newAddr.svm_cid = addr->svm_cid; switch (sk->sk_socket->type) { case SOCK_STREAM: { spin_lock_bh(&vsockTableLock); if (addr->svm_port == VMADDR_PORT_ANY) { Bool found = FALSE; unsigned int i; for (i = 0; i < MAX_PORT_RETRIES; i++) { if (port <= LAST_RESERVED_PORT) { port = LAST_RESERVED_PORT + 1; } newAddr.svm_port = port++; if (!__VSockVmciFindBoundSocket(&newAddr)) { found = TRUE; break; } } if (!found) { err = -EADDRNOTAVAIL; goto out; } } else { /* If port is in reserved range, ensure caller has necessary privileges. */ if (addr->svm_port <= LAST_RESERVED_PORT && !capable(CAP_NET_BIND_SERVICE)) { err = -EACCES; goto out; } newAddr.svm_port = addr->svm_port; if (__VSockVmciFindBoundSocket(&newAddr)) { err = -EADDRINUSE; goto out; } } break; } case SOCK_DGRAM: case SOCK_SEQPACKET: { uint32 flags = 0; /* VMCI will select a resource ID for us if we provide VMCI_INVALID_ID. */ newAddr.svm_port = addr->svm_port == VMADDR_PORT_ANY ? VMCI_INVALID_ID : addr->svm_port; if (newAddr.svm_port <= LAST_RESERVED_PORT && !capable(CAP_NET_BIND_SERVICE)) { err = -EACCES; goto out; } if (newAddr.svm_cid == VMADDR_CID_ANY) { flags = VMCI_FLAG_ANYCID_DG_HND; } err = VSockVmciDatagramCreateHnd(newAddr.svm_port, flags, sk->sk_socket->type == SOCK_DGRAM ? VSockVmciRecvDgramCB : VSockVmciRecvSeqCB, sk, &vsk->dgHandle); if (err < VMCI_SUCCESS) { err = VSockVmci_ErrorToVSockError(err); goto out; } newAddr.svm_port = VMCI_HANDLE_TO_RESOURCE_ID(vsk->dgHandle); break; } default: { err = -EINVAL; goto out; } } /* * VSockVmci_GetAFValue() acquires a mutex and may sleep, so fill the * field after unlocking socket tables. */ VSockAddr_InitNoFamily(&vsk->localAddr, newAddr.svm_cid, newAddr.svm_port); /* * Remove stream sockets from the unbound list and add them to the hash * table for easy lookup by its address. The unbound list is simply an * extra entry at the end of the hash table, a trick used by AF_UNIX. */ if (sk->sk_socket->type == SOCK_STREAM) { __VSockVmciRemoveBound(sk); __VSockVmciInsertBound(vsockBoundSockets(&vsk->localAddr), sk); spin_unlock_bh(&vsockTableLock); } vsk->localAddr.svm_family = VSockVmci_GetAFValue(); VSOCK_ADDR_ASSERT(&vsk->localAddr); return 0; out: if (sk->sk_socket->type == SOCK_STREAM) { spin_unlock_bh(&vsockTableLock); } return err; } /* *---------------------------------------------------------------------------- * * __VSockVmciCreate -- * * Does the work to create the sock structure. * Note: If sock is NULL then the type field must be non-zero. * Otherwise, sock is non-NULL and the type of sock is used in the * newly created socket. * * Results: * sock structure on success, NULL on failure. * * Side effects: * Allocated sk is added to the unbound sockets list iff it is owned by * a struct socket. * *---------------------------------------------------------------------------- */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14) static struct sock * __VSockVmciCreate(struct socket *sock, // IN: Owning socket, may be NULL struct sock *parent, // IN: Parent socket, may be NULL unsigned int priority, // IN: Allocation flags unsigned short type) // IN: Socket type if sock is NULL #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) static struct sock * __VSockVmciCreate(struct socket *sock, // IN: Owning socket, may be NULL struct sock *parent, // IN: Parent socket, may be NULL gfp_t priority, // IN: Allocation flags unsigned short type) // IN: Socket type if sock is NULL #else static struct sock * __VSockVmciCreate(struct net *net, // IN: Network namespace struct socket *sock, // IN: Owning socket, may be NULL struct sock *parent, // IN: Parent socket, may be NULL gfp_t priority, // IN: Allocation flags unsigned short type) // IN: Socket type if sock is NULL #endif { struct sock *sk; VSockVmciSock *psk; VSockVmciSock *vsk; ASSERT((sock && !type) || (!sock && type)); vsk = NULL; /* * From 2.6.9 to until 2.6.12 sk_alloc() used a cache in * the protocol structure, but you still had to specify the size and cache * yourself. * Most recently (in 2.6.24), sk_alloc() was changed to expect the * network namespace, and the option to zero the sock was dropped. * */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12) sk = sk_alloc(vsockVmciFamilyOps.family, priority, vsockVmciProto.slab_obj_size, vsockVmciProto.slab); #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) sk = sk_alloc(vsockVmciFamilyOps.family, priority, &vsockVmciProto, 1); #else sk = sk_alloc(net, vsockVmciFamilyOps.family, priority, &vsockVmciProto); #endif if (!sk) { return NULL; } /* * If we go this far, we know the socket family is registered, so there's no * need to register it now. */ compat_mutex_lock(®istrationMutex); vsockVmciSocketCount++; compat_mutex_unlock(®istrationMutex); sock_init_data(sock, sk); /* * sk->sk_type is normally set in sock_init_data, but only if * sock is non-NULL. We make sure that our sockets always have a type * by setting it here if needed. */ if (!sock) { sk->sk_type = type; } vsk = vsock_sk(sk); VSockAddr_Init(&vsk->localAddr, VMADDR_CID_ANY, VMADDR_PORT_ANY); VSockAddr_Init(&vsk->remoteAddr, VMADDR_CID_ANY, VMADDR_PORT_ANY); sk->sk_destruct = VSockVmciSkDestruct; sk->sk_backlog_rcv = VSockVmciQueueRcvSkb; sk->sk_state = 0; sock_reset_flag(sk, SOCK_DONE); INIT_LIST_HEAD(&vsk->boundTable); INIT_LIST_HEAD(&vsk->connectedTable); INIT_LIST_HEAD(&vsk->seqTable); vsk->dgHandle = VMCI_INVALID_HANDLE; vsk->qpHandle = VMCI_INVALID_HANDLE; vsk->qpair = NULL; vsk->produceSize = vsk->consumeSize = 0; vsk->listener = NULL; INIT_LIST_HEAD(&vsk->pendingLinks); INIT_LIST_HEAD(&vsk->acceptQueue); vsk->rejected = FALSE; vsk->sentRequest = FALSE; vsk->ignoreConnectingRst = FALSE; vsk->attachSubId = vsk->detachSubId = VMCI_INVALID_ID; vsk->peerShutdown = 0; if (parent) { psk = vsock_sk(parent); vsk->trusted = psk->trusted; vsk->owner = psk->owner; vsk->queuePairSize = psk->queuePairSize; vsk->queuePairMinSize = psk->queuePairMinSize; vsk->queuePairMaxSize = psk->queuePairMaxSize; vsk->connectTimeout = psk->connectTimeout; } else { vsk->trusted = capable(CAP_NET_ADMIN); vsk->owner = current_uid(); vsk->queuePairSize = VSOCK_DEFAULT_QP_SIZE; vsk->queuePairMinSize = VSOCK_DEFAULT_QP_SIZE_MIN; vsk->queuePairMaxSize = VSOCK_DEFAULT_QP_SIZE_MAX; vsk->connectTimeout = VSOCK_DEFAULT_CONNECT_TIMEOUT; } vsk->notifyOps = NULL; if (sock) { VSockVmciInsertBound(vsockUnboundSockets, sk); } return sk; } /* *---------------------------------------------------------------------------- * * __VSockVmciRelease -- * * Releases the provided socket. * * Results: * None. * * Side effects: * Any pending sockets are also released. * *---------------------------------------------------------------------------- */ static void __VSockVmciRelease(struct sock *sk) // IN { if (sk) { struct sk_buff *skb; struct sock *pending; struct VSockVmciSock *vsk; vsk = vsock_sk(sk); pending = NULL; /* Compiler warning. */ if (VSockVmciInBoundTable(sk)) { VSockVmciRemoveBound(sk); } if (VSockVmciInConnectedTable(sk)) { VSockVmciRemoveConnected(sk); } if (VSockVmciInSeqTable(sk)) { VSockVmciRemoveSeq(sk); } if (!VMCI_HANDLE_INVALID(vsk->dgHandle)) { if (SOCK_SEQPACKET == sk->sk_type && TCP_ESTABLISHED == sk->sk_state) { VSOCK_SEND_SEQ_CLOSE(vsk, 0); } vmci_datagram_destroy_handle(vsk->dgHandle); vsk->dgHandle = VMCI_INVALID_HANDLE; } lock_sock(sk); sock_orphan(sk); sk->sk_shutdown = SHUTDOWN_MASK; while ((skb = skb_dequeue(&sk->sk_receive_queue))) { kfree_skb(skb); } /* Clean up any sockets that never were accepted. */ while ((pending = VSockVmciDequeueAccept(sk)) != NULL) { __VSockVmciRelease(pending); sock_put(pending); } release_sock(sk); sock_put(sk); } } /* * Sock operations. */ /* *---------------------------------------------------------------------------- * * VSockVmciSkDestruct -- * * Destroys the provided socket. This is called by sk_free(), which is * invoked when the reference count of the socket drops to zero. * * Results: * None. * * Side effects: * Socket count is decremented. * *---------------------------------------------------------------------------- */ static void VSockVmciSkDestruct(struct sock *sk) // IN { VSockVmciSock *vsk; vsk = vsock_sk(sk); if (vsk->attachSubId != VMCI_INVALID_ID) { vmci_event_unsubscribe(vsk->attachSubId); vsk->attachSubId = VMCI_INVALID_ID; } if (vsk->detachSubId != VMCI_INVALID_ID) { vmci_event_unsubscribe(vsk->detachSubId); vsk->detachSubId = VMCI_INVALID_ID; } if (!VMCI_HANDLE_INVALID(vsk->qpHandle)) { ASSERT(vsk->qpair); vmci_qpair_detach(&vsk->qpair); vsk->qpHandle = VMCI_INVALID_HANDLE; ASSERT(vsk->qpair == NULL); vsk->produceSize = vsk->consumeSize = 0; } /* * Each list entry holds a reference on the socket, so we should not even be * here if the socket is in one of our lists. If we are we have a stray * sock_put() that needs to go away. */ ASSERT(!VSockVmciInBoundTable(sk)); ASSERT(!VSockVmciInConnectedTable(sk)); ASSERT(!VSockVmciIsPending(sk)); ASSERT(!VSockVmciInAcceptQueue(sk)); /* * When clearing these addresses, there's no need to set the family and * possibly register the address family with the kernel. */ VSockAddr_InitNoFamily(&vsk->localAddr, VMADDR_CID_ANY, VMADDR_PORT_ANY); VSockAddr_InitNoFamily(&vsk->remoteAddr, VMADDR_CID_ANY, VMADDR_PORT_ANY); NOTIFYCALL(vsk, socketDestruct, sk); compat_mutex_lock(®istrationMutex); vsockVmciSocketCount--; VSockVmciTestUnregister(); compat_mutex_unlock(®istrationMutex); VSOCK_STATS_CTLPKT_DUMP_ALL(); VSOCK_STATS_HIST_DUMP_ALL(); VSOCK_STATS_TOTALS_DUMP_ALL(); } /* *---------------------------------------------------------------------------- * * VSockVmciQueueRcvSkb -- * * Receives skb on the socket's receive queue. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciQueueRcvSkb(struct sock *sk, // IN struct sk_buff *skb) // IN { int err; err = sock_queue_rcv_skb(sk, skb); if (err) { kfree_skb(skb); } return err; } /* *---------------------------------------------------------------------------- * * VSockVmciRegisterProto -- * * Registers the vmci sockets protocol family. * * Results: * Zero on success, error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciRegisterProto(void) { int err = 0; /* * From 2.6.9 until 2.6.11, these address families called sk_alloc_slab() * and the allocated slab was assigned to the slab variable in the proto * struct and was created of size slab_obj_size. As of 2.6.12 and later, * this slab allocation was moved * into proto_register() and only done if you specified a non-zero value * for the second argument (alloc_slab); the size of the slab element was * changed to obj_size. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12) err = sk_alloc_slab(&vsockVmciProto, "vsock"); if (err != 0) { sk_alloc_slab_error(&vsockVmciProto); } #else /* Specify 1 as the second argument so the slab is created for us. */ err = proto_register(&vsockVmciProto, 1); #endif return err; } /* *---------------------------------------------------------------------------- * * VSockVmciUnregisterProto -- * * Unregisters the vmci sockets protocol family. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void VSockVmciUnregisterProto(void) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12) sk_free_slab(&vsockVmciProto); #else proto_unregister(&vsockVmciProto); #endif VSOCK_STATS_RESET(); } /* *---------------------------------------------------------------------------- * * VSockVmciRegisterAddressFamily -- * * Registers our socket address family with the kernel. * * Note that this assumes the registration lock is held. * * Results: * The address family value on success, negative error code on failure. * * Side effects: * Callers of socket operations with the returned value, on success, will * be able to use our socket implementation. * *---------------------------------------------------------------------------- */ static int VSockVmciRegisterAddressFamily(void) { int err = 0; int i; /* * Linux will not allocate an address family to code that is not part of the * kernel proper, so until that time comes we need a workaround. Here we * loop through the allowed values and claim the first one that's not * currently used. Users will then make an ioctl(2) into our module to * retrieve this value before calling socket(2). * * This is undesirable, but it's better than having users' programs break * when a hard-coded, currently-available value gets assigned to someone * else in the future. */ for (i = NPROTO - 1; i >= 0; i--) { vsockVmciFamilyOps.family = i; err = sock_register(&vsockVmciFamilyOps); if (err) { vsockVmciFamilyOps.family = VSOCK_INVALID_FAMILY; } else { vsockVmciDgramOps.family = i; vsockVmciStreamOps.family = i; vsockVmciSeqOps.family = i; err = i; break; } } if (VSOCK_INVALID_FAMILY == vsockVmciFamilyOps.family) { Warning("Could not register address family.\n"); } return err; } /* *---------------------------------------------------------------------------- * * VSockVmciUnregisterAddressFamily -- * * Unregisters the address family with the kernel. * * Note that this assumes the registration lock is held. * * Results: * None. * * Side effects: * Our socket implementation is no longer accessible. * *---------------------------------------------------------------------------- */ static void VSockVmciUnregisterAddressFamily(void) { if (vsockVmciFamilyOps.family != VSOCK_INVALID_FAMILY) { sock_unregister(vsockVmciFamilyOps.family); } vsockVmciDgramOps.family = vsockVmciFamilyOps.family = VSOCK_INVALID_FAMILY; vsockVmciStreamOps.family = vsockVmciFamilyOps.family; vsockVmciSeqOps.family = vsockVmciFamilyOps.family; } /* *---------------------------------------------------------------------------- * * VSockVmciRegisterWithVmci -- * * Registers with the VMCI device, and creates control message * and event handlers. * * Results: * Zero on success, error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciRegisterWithVmci(void) { int err = 0; uint32 apiVersion; /* * We don't call into the vmci module if the vmci device isn't * present. */ apiVersion = VMCI_KERNEL_API_VERSION_1; vmciDevicePresent = vmci_device_get(&apiVersion, NULL, NULL, NULL); if (!vmciDevicePresent) { Warning("VMCI device not present.\n"); return -1; } /* * Create the datagram handle that we will use to send and receive all * VSocket control messages for this context. */ err = VSockVmciDatagramCreateHnd(VSOCK_PACKET_RID, VMCI_FLAG_ANYCID_DG_HND, VSockVmciRecvStreamCB, NULL, &vmciStreamHandle); if (err < VMCI_SUCCESS) { Warning("Unable to create datagram handle. (%d)\n", err); err = VSockVmci_ErrorToVSockError(err); goto out; } err = vmci_event_subscribe(VMCI_EVENT_QP_RESUMED, VSockVmciQPResumedCB, NULL, &qpResumedSubId); if (err < VMCI_SUCCESS) { Warning("Unable to subscribe to QP resumed event. (%d)\n", err); err = VSockVmci_ErrorToVSockError(err); qpResumedSubId = VMCI_INVALID_ID; goto out; } err = vmci_event_subscribe(VMCI_EVENT_CTX_ID_UPDATE, VSockVmciContextUpdatedCB, NULL, &ctxUpdatedSubId); if (err < VMCI_SUCCESS) { Warning("Unable to subscribe to context updated event. (%d)\n", err); err = VSockVmci_ErrorToVSockError(err); ctxUpdatedSubId = VMCI_INVALID_ID; goto out; } out: if (err != 0) { VSockVmciUnregisterWithVmci(); } return err; } /* *---------------------------------------------------------------------------- * * VSockVmciUnregisterWithVmci -- * * Destroys control message and event handlers, and unregisters * with the VMCI device * * Results: * None. * * Side effects: * Our socket implementation is no longer accessible. * *---------------------------------------------------------------------------- */ static void VSockVmciUnregisterWithVmci(void) { if (!vmciDevicePresent) { /* Nothing was registered. */ return; } if (!VMCI_HANDLE_INVALID(vmciStreamHandle)) { if (vmci_datagram_destroy_handle(vmciStreamHandle) != VMCI_SUCCESS) { Warning("Could not destroy VMCI datagram handle.\n"); } vmciStreamHandle = VMCI_INVALID_HANDLE; } if (qpResumedSubId != VMCI_INVALID_ID) { vmci_event_unsubscribe(qpResumedSubId); qpResumedSubId = VMCI_INVALID_ID; } if (ctxUpdatedSubId != VMCI_INVALID_ID) { vmci_event_unsubscribe(ctxUpdatedSubId); ctxUpdatedSubId = VMCI_INVALID_ID; } vmci_device_release(NULL); vmciDevicePresent = FALSE; } /* *---------------------------------------------------------------------------- * * VSockVmciStreamHasData -- * * Gets the amount of data available for a given stream socket's consume * queue. * * Note that this assumes the socket lock is held. * * Results: * The amount of data available or a VMCI error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int64 VSockVmciStreamHasData(VSockVmciSock *vsk) // IN { ASSERT(vsk); return vmci_qpair_consume_buf_ready(vsk->qpair); } /* *---------------------------------------------------------------------------- * * VSockVmciStreamHasSpace -- * * Gets the amount of space available for a give stream socket's produce * queue. * * Note that this assumes the socket lock is held. * * Results: * The amount of space available or a VMCI error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int64 VSockVmciStreamHasSpace(VSockVmciSock *vsk) // IN { ASSERT(vsk); return vmci_qpair_produce_free_space(vsk->qpair); } /* * Socket operations. */ /* *---------------------------------------------------------------------------- * * VSockVmciRelease -- * * Releases the provided socket by freeing the contents of its queue. This * is called when a user process calls close(2) on the socket. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciRelease(struct socket *sock) // IN { __VSockVmciRelease(sock->sk); sock->sk = NULL; sock->state = SS_FREE; return 0; } /* *---------------------------------------------------------------------------- * * VSockVmciBind -- * * Binds the provided address to the provided socket. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciBind(struct socket *sock, // IN struct sockaddr *addr, // IN int addrLen) // IN { int err; struct sock *sk; struct sockaddr_vm *vmciAddr; sk = sock->sk; if (VSockAddr_Cast(addr, addrLen, &vmciAddr) != 0) { return -EINVAL; } lock_sock(sk); err = __VSockVmciBind(sk, vmciAddr); release_sock(sk); return err; } /* *---------------------------------------------------------------------------- * * VSockVmciDgramConnect -- * * Connects a datagram socket. This can be called multiple times to change * the socket's association and can be called with a sockaddr whose family * is set to AF_UNSPEC to dissolve any existing association. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciDgramConnect(struct socket *sock, // IN struct sockaddr *addr, // IN int addrLen, // IN int flags) // IN { int err; struct sock *sk; VSockVmciSock *vsk; struct sockaddr_vm *remoteAddr; sk = sock->sk; vsk = vsock_sk(sk); err = VSockAddr_Cast(addr, addrLen, &remoteAddr); if (err == -EAFNOSUPPORT && remoteAddr->svm_family == AF_UNSPEC) { lock_sock(sk); VSockAddr_Init(&vsk->remoteAddr, VMADDR_CID_ANY, VMADDR_PORT_ANY); sock->state = SS_UNCONNECTED; release_sock(sk); return 0; } else if (err != 0) { return -EINVAL; } lock_sock(sk); if (!VSockAddr_Bound(&vsk->localAddr)) { struct sockaddr_vm localAddr; VSockAddr_Init(&localAddr, VMADDR_CID_ANY, VMADDR_PORT_ANY); if ((err = __VSockVmciBind(sk, &localAddr))) { goto out; } } if (!VSockAddr_SocketContextDgram(remoteAddr->svm_cid, remoteAddr->svm_port)) { err = -EINVAL; goto out; } memcpy(&vsk->remoteAddr, remoteAddr, sizeof vsk->remoteAddr); sock->state = SS_CONNECTED; out: release_sock(sk); return err; } /* *---------------------------------------------------------------------------- * * VSockVmciSeqConnect -- * * Connects a sequential socket. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciSeqConnect(struct socket *sock, // IN struct sockaddr *addr, // IN int addrLen, // IN int flags) // IN { int err; struct sock *sk; VSockVmciSock *vsk; VSockSeqPacket pkt; struct sockaddr_vm *remoteAddr; sk = sock->sk; vsk = vsock_sk(sk); lock_sock(sk); if (SS_CONNECTED == sock->state) { err = -EISCONN; goto out; } else if (SS_CONNECTING == sock->state || SS_DISCONNECTING == sock->state) { err = -EINVAL; goto out; } if (VSockAddr_Cast(addr, addrLen, &remoteAddr) != 0) { err = -EINVAL; goto out; } if (!VSockAddr_Bound(&vsk->localAddr)) { struct sockaddr_vm localAddr; VSockAddr_Init(&localAddr, VMADDR_CID_ANY, VMADDR_PORT_ANY); if ((err = __VSockVmciBind(sk, &localAddr))) { goto out; } } if (VMCI_HYPERVISOR_CONTEXT_ID != remoteAddr->svm_cid) { err = -EINVAL; goto out; } if (VMCI_RPC_PRIVILEGED != remoteAddr->svm_port && VMCI_RPC_UNPRIVILEGED != remoteAddr->svm_port) { err = -EINVAL; goto out; } /* * No need to call SocketContextDgram() here, we already do specific checks * on the context and port above. All we have to do here is ensure that * only the superuser gets access to the privileged RPC handler. */ if (VMCI_RPC_PRIVILEGED == remoteAddr->svm_port && !capable(CAP_SYS_ADMIN)) { err = -EACCES; goto out; } VSockSeqPacket_Init(&pkt, &vsk->localAddr, remoteAddr, VSOCK_SEQ_PACKET_TYPE_CONNECT, 0); err = vmci_datagram_send(&pkt.hdr.dg); if (err < 0) { err = VSockVmci_ErrorToVSockError(err); goto out; } /* * It's not necessary to get an acknowledgement. We're sending to the * hypervisor, which means the result of the call tells us whether the * endpoint accepted it or not. So as long as it returns success, * we are connected. */ memcpy(&vsk->remoteAddr, remoteAddr, sizeof vsk->remoteAddr); /* * The skb routines actually check if this is a sequential socket, and if * so, they require that the socket be in the TCP established state. So * we need to use the TCP states for sk_state rather than the SS states * (our STREAM sockets cheat and get away with it, we should fix that). */ sock->state = SS_CONNECTED; sk->sk_state = TCP_ESTABLISHED; VSockVmciInsertSeq(vsockSeqSocketsVsk(vsk), sk); sk->sk_state_change(sk); err = 0; out: release_sock(sk); return err; } /* *---------------------------------------------------------------------------- * * VSockVmciConnectTimeout -- * * Asynchronous connection attempts schedule this timeout function * to notify the connector of an unsuccessfull connection * attempt. If the socket is still in the connecting state and * hasn't been closed, we mark the socket as timed out. Otherwise, * we do nothing. * * Results: * None. * * Side effects: * May destroy the socket. * *---------------------------------------------------------------------------- */ static void VSockVmciConnectTimeout(compat_delayed_work_arg work) // IN { struct sock *sk; VSockVmciSock *vsk; vsk = COMPAT_DELAYED_WORK_GET_DATA(work, VSockVmciSock, dwork); ASSERT(vsk); sk = sk_vsock(vsk); lock_sock(sk); if (sk->sk_state == SS_CONNECTING && (sk->sk_shutdown != SHUTDOWN_MASK)) { sk->sk_state = SS_UNCONNECTED; sk->sk_err = ETIMEDOUT; sk->sk_error_report(sk); } release_sock(sk); sock_put(sk); } /* *---------------------------------------------------------------------------- * * VSockVmciStreamConnect -- * * Connects a stream socket. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciStreamConnect(struct socket *sock, // IN struct sockaddr *addr, // IN int addrLen, // IN int flags) // IN { int err; struct sock *sk; VSockVmciSock *vsk; struct sockaddr_vm *remoteAddr; long timeout; Bool oldPktProto = FALSE; DEFINE_WAIT(wait); err = 0; sk = sock->sk; vsk = vsock_sk(sk); lock_sock(sk); /* XXX AF_UNSPEC should make us disconnect like AF_INET. */ switch (sock->state) { case SS_CONNECTED: err = -EISCONN; goto out; case SS_DISCONNECTING: err = -EINVAL; goto out; case SS_CONNECTING: /* * This continues on so we can move sock into the SS_CONNECTED state once * the connection has completed (at which point err will be set to zero * also). Otherwise, we will either wait for the connection or return * -EALREADY should this be a non-blocking call. */ err = -EALREADY; break; default: ASSERT(sk->sk_state == SS_FREE || sk->sk_state == SS_UNCONNECTED || sk->sk_state == SS_LISTEN); if ((sk->sk_state == SS_LISTEN) || VSockAddr_Cast(addr, addrLen, &remoteAddr) != 0) { err = -EINVAL; goto out; } /* The hypervisor and well-known contexts do not have socket endpoints. */ if (!VSockAddr_SocketContextStream(remoteAddr->svm_cid)) { err = -ENETUNREACH; goto out; } /* Set the remote address that we are connecting to. */ memcpy(&vsk->remoteAddr, remoteAddr, sizeof vsk->remoteAddr); /* Autobind this socket to the local address if necessary. */ if (!VSockAddr_Bound(&vsk->localAddr)) { struct sockaddr_vm localAddr; VSockAddr_Init(&localAddr, VMADDR_CID_ANY, VMADDR_PORT_ANY); if ((err = __VSockVmciBind(sk, &localAddr))) { goto out; } } sk->sk_state = SS_CONNECTING; if (VSockVmciOldProtoOverride(&oldPktProto) && oldPktProto) { err = VSOCK_SEND_CONN_REQUEST(sk, vsk->queuePairSize); if (err < 0) { sk->sk_state = SS_UNCONNECTED; goto out; } } else { int supportedProtoVersions = VSockVmciNewProtoSupportedVersions(); err = VSOCK_SEND_CONN_REQUEST2(sk, vsk->queuePairSize, supportedProtoVersions); if (err < 0) { sk->sk_state = SS_UNCONNECTED; goto out; } vsk->sentRequest = TRUE; } /* * Mark sock as connecting and set the error code to in progress in case * this is a non-blocking connect. */ sock->state = SS_CONNECTING; err = -EINPROGRESS; } /* * The receive path will handle all communication until we are able to enter * the connected state. Here we wait for the connection to be completed or * a notification of an error. */ timeout = vsk->connectTimeout; prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); while (sk->sk_state != SS_CONNECTED && sk->sk_err == 0) { if (flags & O_NONBLOCK) { /* * If we're not going to block, we schedule a timeout * function to generate a timeout on the connection attempt, * in case the peer doesn't respond in a timely manner. We * hold on to the socket until the timeout fires. */ sock_hold(sk); COMPAT_INIT_DELAYED_WORK(&vsk->dwork, VSockVmciConnectTimeout, vsk); compat_schedule_delayed_work(&vsk->dwork, timeout); /* Skip ahead to preserve error code set above. */ goto outWait; } release_sock(sk); timeout = schedule_timeout(timeout); lock_sock(sk); if (signal_pending(current)) { err = sock_intr_errno(timeout); goto outWaitError; } else if (timeout == 0) { err = -ETIMEDOUT; goto outWaitError; } prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); } if (sk->sk_err) { err = -sk->sk_err; goto outWaitError; } else { ASSERT(sk->sk_state == SS_CONNECTED); err = 0; } outWait: finish_wait(sk_sleep(sk), &wait); out: release_sock(sk); return err; outWaitError: sk->sk_state = SS_UNCONNECTED; sock->state = SS_UNCONNECTED; goto outWait; } /* *---------------------------------------------------------------------------- * * VSockVmciAccept -- * * Accepts next available connection request for this socket. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciAccept(struct socket *sock, // IN struct socket *newsock, // IN/OUT int flags) // IN { struct sock *listener; int err; struct sock *connected; VSockVmciSock *vconnected; long timeout; DEFINE_WAIT(wait); err = 0; listener = sock->sk; lock_sock(listener); if (sock->type != SOCK_STREAM) { err = -EOPNOTSUPP; goto out; } if (listener->sk_state != SS_LISTEN) { err = -EINVAL; goto out; } /* * Wait for children sockets to appear; these are the new sockets created * upon connection establishment. */ timeout = sock_sndtimeo(listener, flags & O_NONBLOCK); prepare_to_wait(sk_sleep(listener), &wait, TASK_INTERRUPTIBLE); while ((connected = VSockVmciDequeueAccept(listener)) == NULL && listener->sk_err == 0) { release_sock(listener); timeout = schedule_timeout(timeout); lock_sock(listener); if (signal_pending(current)) { err = sock_intr_errno(timeout); goto outWait; } else if (timeout == 0) { err = -EAGAIN; goto outWait; } prepare_to_wait(sk_sleep(listener), &wait, TASK_INTERRUPTIBLE); } if (listener->sk_err) { err = -listener->sk_err; } if (connected) { listener->sk_ack_backlog--; lock_sock(connected); vconnected = vsock_sk(connected); /* * If the listener socket has received an error, then we should reject * this socket and return. Note that we simply mark the socket rejected, * drop our reference, and let the cleanup function handle the cleanup; * the fact that we found it in the listener's accept queue guarantees * that the cleanup function hasn't run yet. */ if (err) { vconnected->rejected = TRUE; release_sock(connected); sock_put(connected); goto outWait; } newsock->state = SS_CONNECTED; sock_graft(connected, newsock); release_sock(connected); sock_put(connected); } outWait: finish_wait(sk_sleep(listener), &wait); out: release_sock(listener); return err; } /* *---------------------------------------------------------------------------- * * VSockVmciGetname -- * * Provides the local or remote address for the socket. * * Results: * Zero on success, negative error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciGetname(struct socket *sock, // IN struct sockaddr *addr, // OUT int *addrLen, // OUT int peer) // IN { int err; struct sock *sk; VSockVmciSock *vsk; struct sockaddr_vm *vmciAddr; sk = sock->sk; vsk = vsock_sk(sk); err = 0; lock_sock(sk); if (peer) { if (sock->state != SS_CONNECTED) { err = -ENOTCONN; goto out; } vmciAddr = &vsk->remoteAddr; } else { vmciAddr = &vsk->localAddr; } if (!vmciAddr) { err = -EINVAL; goto out; } /* * sys_getsockname() and sys_getpeername() pass us a MAX_SOCK_ADDR-sized * buffer and don't set addrLen. Unfortunately that macro is defined in * socket.c instead of .h, so we hardcode its value here. */ ASSERT_ON_COMPILE(sizeof *vmciAddr <= 128); memcpy(addr, vmciAddr, sizeof *vmciAddr); *addrLen = sizeof *vmciAddr; out: release_sock(sk); return err; } /* *---------------------------------------------------------------------------- * * VSockVmciPoll -- * * Waits on file for activity then provides mask indicating state of socket. * * Results: * Mask of flags containing socket state. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static unsigned int VSockVmciPoll(struct file *file, // IN struct socket *sock, // IN poll_table *wait) // IN { struct sock *sk; unsigned int mask; VSockVmciSock *vsk; sk = sock->sk; vsk = vsock_sk(sk); poll_wait(file, sk_sleep(sk), wait); mask = 0; if (sk->sk_err) { /* Signify that there has been an error on this socket. */ mask |= POLLERR; } /* * INET sockets treat local write shutdown and peer write shutdown * as a case of POLLHUP set. */ if ((sk->sk_shutdown == SHUTDOWN_MASK) || ((sk->sk_shutdown & SEND_SHUTDOWN) && (vsk->peerShutdown & SEND_SHUTDOWN))) { mask |= POLLHUP; } /* POLLRDHUP wasn't added until 2.6.17. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17) if (sk->sk_shutdown & RCV_SHUTDOWN || vsk->peerShutdown & SEND_SHUTDOWN) { mask |= POLLRDHUP; } #endif if (sock->type == SOCK_DGRAM) { /* * For datagram sockets we can read if there is something in the queue * and write as long as the socket isn't shutdown for sending. */ if (!skb_queue_empty(&sk->sk_receive_queue) || (sk->sk_shutdown & RCV_SHUTDOWN)) { mask |= POLLIN | POLLRDNORM; } if (!(sk->sk_shutdown & SEND_SHUTDOWN)) { mask |= POLLOUT | POLLWRNORM | POLLWRBAND; } } else if (sock->type == SOCK_STREAM) { lock_sock(sk); /* * Listening sockets that have connections in their accept queue can be read. */ if (sk->sk_state == SS_LISTEN && !VSockVmciIsAcceptQueueEmpty(sk)) { mask |= POLLIN | POLLRDNORM; } /* * If there is something in the queue then we can read. */ if (!VMCI_HANDLE_INVALID(vsk->qpHandle) && !(sk->sk_shutdown & RCV_SHUTDOWN)) { Bool dataReadyNow = FALSE; int32 ret = 0; NOTIFYCALLRET(vsk, ret, pollIn, sk, 1, &dataReadyNow); if (ret < 0) { mask |= POLLERR; } else { if (dataReadyNow) { mask |= POLLIN | POLLRDNORM; } } } /* * Sockets whose connections have been closed, reset, or terminated * should also be considered read, and we check the shutdown flag for * that. */ if (sk->sk_shutdown & RCV_SHUTDOWN || vsk->peerShutdown & SEND_SHUTDOWN) { mask |= POLLIN | POLLRDNORM; } /* * Connected sockets that can produce data can be written. */ if (sk->sk_state == SS_CONNECTED) { if (!(sk->sk_shutdown & SEND_SHUTDOWN)) { Bool spaceAvailNow = FALSE; int32 ret = 0; NOTIFYCALLRET(vsk, ret, pollOut, sk, 1, &spaceAvailNow); if (ret < 0) { mask |= POLLERR; } else { if (spaceAvailNow) { /* Remove POLLWRBAND since INET sockets are not setting it.*/ mask |= POLLOUT | POLLWRNORM; } } } } /* * Simulate INET socket poll behaviors, which sets POLLOUT|POLLWRNORM when * peer is closed and nothing to read, but local send is not shutdown. */ if (sk->sk_state == SS_UNCONNECTED) { if (!(sk->sk_shutdown & SEND_SHUTDOWN)) { mask |= POLLOUT | POLLWRNORM; } } release_sock(sk); } else if (sock->type == SOCK_SEQPACKET) { lock_sock(sk); /* * If there is something in the queue then we can read. */ if (!skb_queue_empty(&sk->sk_receive_queue) && !(sk->sk_shutdown & RCV_SHUTDOWN)) { mask |= POLLIN | POLLRDNORM; } /* * Sockets whose connections have beed closed, reset or terminated * should also be considered readable, and we check the shutdown flag * for that. */ if (sk->sk_shutdown & RCV_SHUTDOWN || vsk->peerShutdown & SEND_SHUTDOWN) { mask |= POLLIN | POLLRDNORM; } /* * Connected sockets that can produce data can be written. */ if (sk->sk_state == TCP_ESTABLISHED && !(sk->sk_shutdown & SEND_SHUTDOWN)) { mask |= POLLOUT | POLLWRNORM; } release_sock(sk); } return mask; } /* *---------------------------------------------------------------------------- * * VSockVmciListen -- * * Signify that this socket is listening for connection requests. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciListen(struct socket *sock, // IN int backlog) // IN { int err; struct sock *sk; VSockVmciSock *vsk; sk = sock->sk; lock_sock(sk); if (sock->type != SOCK_STREAM) { err = -EOPNOTSUPP; goto out; } if (sock->state != SS_UNCONNECTED) { err = -EINVAL; goto out; } vsk = vsock_sk(sk); if (!VSockAddr_Bound(&vsk->localAddr)) { err = -EINVAL; goto out; } sk->sk_max_ack_backlog = backlog; sk->sk_state = SS_LISTEN; err = 0; out: release_sock(sk); return err; } /* *---------------------------------------------------------------------------- * * VSockVmciShutdown -- * * Shuts down the provided socket in the provided method. * * Results: * Zero on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciShutdown(struct socket *sock, // IN int mode) // IN { int32 err; struct sock *sk; /* * User level uses SHUT_RD (0) and SHUT_WR (1), but the kernel uses * RCV_SHUTDOWN (1) and SEND_SHUTDOWN (2), so we must increment mode here * like the other address families do. Note also that the increment makes * SHUT_RDWR (2) into RCV_SHUTDOWN | SEND_SHUTDOWN (3), which is what we * want. */ mode++; if ((mode & ~SHUTDOWN_MASK) || !mode) { return -EINVAL; } /* * If this is a STREAM/SEQPACKET socket and it is not connected then bail * out immediately. If it is a DGRAM socket then we must first kick the * socket so that it wakes up from any sleeping calls, for example recv(), * and then afterwards return the error. */ sk = sock->sk; if (sock->state == SS_UNCONNECTED) { err = -ENOTCONN; if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) { return err; } } else { sock->state = SS_DISCONNECTING; err = 0; } /* * It doesn't make any sense to try and shutdown a sequential socket to * the hypervisor in the recv direction, only for send or for both. */ if (sk->sk_type == SOCK_SEQPACKET && mode == RCV_SHUTDOWN) { err = -EINVAL; return err; } /* Receive and send shutdowns are treated alike. */ mode = mode & (RCV_SHUTDOWN | SEND_SHUTDOWN); if (mode) { lock_sock(sk); sk->sk_shutdown |= mode; if (sk->sk_type == SOCK_SEQPACKET) { sk->sk_state = TCP_CLOSE; } sk->sk_state_change(sk); release_sock(sk); if (sk->sk_type == SOCK_STREAM) { sock_reset_flag(sk, SOCK_DONE); VSOCK_SEND_SHUTDOWN(sk, mode); } else if (sk->sk_type == SOCK_SEQPACKET) { sock_reset_flag(sk, SOCK_DONE); err = VSOCK_SEND_SEQ_SHUTDOWN(vsock_sk(sk), mode); } } return err; } /* *---------------------------------------------------------------------------- * * VSockVmciDgramSendmsg -- * * Sends a datagram. * * Results: * Number of bytes sent on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciDgramSendmsg(struct kiocb *kiocb, // UNUSED struct socket *sock, // IN: socket to send on struct msghdr *msg, // IN: message to send size_t len) // IN: length of message { int err; struct sock *sk; VSockVmciSock *vsk; struct sockaddr_vm *remoteAddr; VMCIDatagram *dg; if (msg->msg_flags & MSG_OOB) { return -EOPNOTSUPP; } if (len > VMCI_MAX_DG_PAYLOAD_SIZE) { return -EMSGSIZE; } /* For now, MSG_DONTWAIT is always assumed... */ err = 0; sk = sock->sk; vsk = vsock_sk(sk); lock_sock(sk); if (!VSockAddr_Bound(&vsk->localAddr)) { struct sockaddr_vm localAddr; VSockAddr_Init(&localAddr, VMADDR_CID_ANY, VMADDR_PORT_ANY); if ((err = __VSockVmciBind(sk, &localAddr))) { goto out; } } /* * If the provided message contains an address, use that. Otherwise fall * back on the socket's remote handle (if it has been connected). */ if (msg->msg_name && VSockAddr_Cast(msg->msg_name, msg->msg_namelen, &remoteAddr) == 0) { /* Ensure this address is of the right type and is a valid destination. */ // XXXAB Temporary to handle test program if (remoteAddr->svm_cid == VMADDR_CID_ANY) { remoteAddr->svm_cid = vmci_get_context_id(); } if (!VSockAddr_Bound(remoteAddr)) { err = -EINVAL; goto out; } } else if (sock->state == SS_CONNECTED) { remoteAddr = &vsk->remoteAddr; // XXXAB Temporary to handle test program if (remoteAddr->svm_cid == VMADDR_CID_ANY) { remoteAddr->svm_cid = vmci_get_context_id(); } /* XXX Should connect() or this function ensure remoteAddr is bound? */ if (!VSockAddr_Bound(&vsk->remoteAddr)) { err = -EINVAL; goto out; } } else { err = -EINVAL; goto out; } /* * Make sure that we don't allow a userlevel app to send datagrams * to the hypervisor that modify VMCI device state. */ if (!VSockAddr_SocketContextDgram(remoteAddr->svm_cid, remoteAddr->svm_port)) { err = -EINVAL; goto out; } if (!VSockVmciAllowDgram(vsk, remoteAddr->svm_cid)) { err = -EPERM; goto out; } /* * Allocate a buffer for the user's message and our packet header. */ dg = kmalloc(len + sizeof *dg, GFP_KERNEL); if (!dg) { err = -ENOMEM; goto out; } memcpy_fromiovec(VMCI_DG_PAYLOAD(dg), msg->msg_iov, len); dg->dst = VMCI_MAKE_HANDLE(remoteAddr->svm_cid, remoteAddr->svm_port); dg->src = VMCI_MAKE_HANDLE(vsk->localAddr.svm_cid, vsk->localAddr.svm_port); dg->payloadSize = len; err = vmci_datagram_send(dg); kfree(dg); if (err < 0) { err = VSockVmci_ErrorToVSockError(err); goto out; } err -= sizeof *dg; out: release_sock(sk); return err; } /* *---------------------------------------------------------------------------- * * VSockVmciSeqSendmsg -- * * Sends a datagram. * * Results: * Number of bytes sent on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciSeqSendmsg(struct kiocb *kiocb, // UNUSED struct socket *sock, // IN: socket to send on struct msghdr *msg, // IN: message to send size_t len) // IN: length of message { int err; struct sock *sk; VSockVmciSock *vsk; VSockSeqPacket *pkt; sk = sock->sk; vsk = vsock_sk(sk); if (msg->msg_flags & MSG_OOB) { return -EOPNOTSUPP; } if (len > VMCI_MAX_DG_PAYLOAD_SIZE) { return -EMSGSIZE; } lock_sock(sk); /* Callers should not provide a destination with sequential sockets. */ if (msg->msg_namelen) { err = sock->state == SS_CONNECTED ? -EISCONN : -EOPNOTSUPP; goto out; } /* Send data only if we're not shutdown in that direction. */ if (sk->sk_shutdown & SEND_SHUTDOWN) { err = -EPIPE; goto out; } if (sock->state != SS_CONNECTED) { err = -ENOTCONN; goto out; } /* * We already managed to connect, which means we must already have the * right privs to send to our peer. So no need for the usual datagram * checks here, they were done by connect(). */ /* * Allocate a buffer for the user's message and our packet header. */ pkt = kmalloc(len + sizeof *pkt, GFP_KERNEL); if (!pkt) { err = -ENOMEM; goto out; } VSockSeqPacket_Init(pkt, &vsk->localAddr, &vsk->remoteAddr, VSOCK_SEQ_PACKET_TYPE_DATA, 0); pkt->hdr.dg.payloadSize += len; err = memcpy_fromiovec(VSOCK_SEQ_PACKET_PAYLOAD(pkt), msg->msg_iov, len); if (0 != err) { kfree(pkt); goto out; } err = vmci_datagram_send(&pkt->hdr.dg); kfree(pkt); if (err < 0) { err = VSockVmci_ErrorToVSockError(err); goto out; } err = len; out: release_sock(sk); return err; } /* *---------------------------------------------------------------------------- * * VSockVmciStreamSetsockopt -- * * Set a socket option on a stream socket * * Results: * 0 on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VSockVmciStreamSetsockopt(struct socket *sock, // IN/OUT int level, // IN int optname, // IN char __user *optval, // IN VSockSetsockoptLenType optlen) // IN { int err; struct sock *sk; VSockVmciSock *vsk; uint64 val; if (level != VSockVmci_GetAFValue()) { return -ENOPROTOOPT; } # define COPY_IN(_v) \ do { \ if (optlen < sizeof _v) { \ err = -EINVAL; \ goto exit; \ } \ if (copy_from_user(&_v, optval, sizeof _v) != 0) { \ err = -EFAULT; \ goto exit; \ } \ } while (0) err = 0; sk = sock->sk; vsk = vsock_sk(sk); ASSERT(vsk->queuePairMinSize <= vsk->queuePairSize && vsk->queuePairSize <= vsk->queuePairMaxSize); lock_sock(sk); switch (optname) { case SO_VMCI_BUFFER_SIZE: COPY_IN(val); if (val < vsk->queuePairMinSize) { vsk->queuePairMinSize = val; } if (val > vsk->queuePairMaxSize) { vsk->queuePairMaxSize = val; } vsk->queuePairSize = val; break; case SO_VMCI_BUFFER_MAX_SIZE: COPY_IN(val); if (val < vsk->queuePairSize) { vsk->queuePairSize = val; } vsk->queuePairMaxSize = val; break; case SO_VMCI_BUFFER_MIN_SIZE: COPY_IN(val); if (val > vsk->queuePairSize) { vsk->queuePairSize = val; } vsk->queuePairMinSize = val; break; case SO_VMCI_CONNECT_TIMEOUT: { struct timeval tv; COPY_IN(tv); if (tv.tv_sec >= 0 && tv.tv_usec < USEC_PER_SEC && tv.tv_sec < (MAX_SCHEDULE_TIMEOUT/HZ - 1)) { vsk->connectTimeout = tv.tv_sec * HZ + CEILING(tv.tv_usec, (1000000 / HZ)); if (vsk->connectTimeout == 0) { vsk->connectTimeout = VSOCK_DEFAULT_CONNECT_TIMEOUT; } } else { err = -ERANGE; } break; } default: err = -ENOPROTOOPT; break; } # undef COPY_IN ASSERT(vsk->queuePairMinSize <= vsk->queuePairSize && vsk->queuePairSize <= vsk->queuePairMaxSize); exit: release_sock(sk); return err; } /* *---------------------------------------------------------------------------- * * VSockVmciStreamGetsockopt -- * * Get a socket option for a stream socket * * Results: * 0 on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VSockVmciStreamGetsockopt(struct socket *sock, // IN int level, // IN int optname, // IN char __user *optval, // OUT int __user * optlen) // IN/OUT { int err; int len; struct sock *sk; VSockVmciSock *vsk; if (level != VSockVmci_GetAFValue()) { return -ENOPROTOOPT; } if ((err = get_user(len, optlen)) != 0) { return err; } # define COPY_OUT(_v) \ do { \ if (len < sizeof _v) { \ return -EINVAL; \ } \ len = sizeof _v; \ if (copy_to_user(optval, &_v, len) != 0) { \ return -EFAULT; \ } \ } while (0) err = 0; sk = sock->sk; vsk = vsock_sk(sk); switch (optname) { case SO_VMCI_BUFFER_SIZE: COPY_OUT(vsk->queuePairSize); break; case SO_VMCI_BUFFER_MAX_SIZE: COPY_OUT(vsk->queuePairMaxSize); break; case SO_VMCI_BUFFER_MIN_SIZE: COPY_OUT(vsk->queuePairMinSize); break; case SO_VMCI_CONNECT_TIMEOUT: { struct timeval tv; tv.tv_sec = vsk->connectTimeout / HZ; tv.tv_usec = (vsk->connectTimeout - tv.tv_sec * HZ) * (1000000 / HZ); COPY_OUT(tv); break; } default: return -ENOPROTOOPT; } if ((err = put_user(len, optlen)) != 0) { return -EFAULT; } # undef COPY_OUT return 0; } /* *---------------------------------------------------------------------------- * * VSockVmciStreamSendmsg -- * * Sends a message on the socket. * * Results: * Number of bytes sent on success, negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciStreamSendmsg(struct kiocb *kiocb, // UNUSED struct socket *sock, // IN: socket to send on struct msghdr *msg, // IN: message to send size_t len) // IN: length of message { struct sock *sk; VSockVmciSock *vsk; ssize_t totalWritten; long timeout; int err; VSockVmciSendNotifyData sendData; DEFINE_WAIT(wait); sk = sock->sk; vsk = vsock_sk(sk); totalWritten = 0; err = 0; if (msg->msg_flags & MSG_OOB) { return -EOPNOTSUPP; } lock_sock(sk); /* Callers should not provide a destination with stream sockets. */ if (msg->msg_namelen) { err = sk->sk_state == SS_CONNECTED ? -EISCONN : -EOPNOTSUPP; goto out; } /* Send data only if both sides are not shutdown in the direction. */ if (sk->sk_shutdown & SEND_SHUTDOWN || vsk->peerShutdown & RCV_SHUTDOWN) { err = -EPIPE; goto out; } if (sk->sk_state != SS_CONNECTED || !VSockAddr_Bound(&vsk->localAddr)) { err = -ENOTCONN; goto out; } if (!VSockAddr_Bound(&vsk->remoteAddr)) { err = -EDESTADDRREQ; goto out; } /* * Wait for room in the produce queue to enqueue our user's data. */ timeout = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); NOTIFYCALLRET(vsk, err, sendInit, sk, &sendData); if (err < 0) { goto out; } prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); while (totalWritten < len) { ssize_t written; while (VSockVmciStreamHasSpace(vsk) == 0 && sk->sk_err == 0 && !(sk->sk_shutdown & SEND_SHUTDOWN) && !(vsk->peerShutdown & RCV_SHUTDOWN)) { /* Don't wait for non-blocking sockets. */ if (timeout == 0) { err = -EAGAIN; goto outWait; } NOTIFYCALLRET(vsk, err, sendPreBlock, sk, &sendData); if (err < 0) { goto outWait; } release_sock(sk); timeout = schedule_timeout(timeout); lock_sock(sk); if (signal_pending(current)) { err = sock_intr_errno(timeout); goto outWait; } else if (timeout == 0) { err = -EAGAIN; goto outWait; } prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); } /* * These checks occur both as part of and after the loop conditional * since we need to check before and after sleeping. */ if (sk->sk_err) { err = -sk->sk_err; goto outWait; } else if ((sk->sk_shutdown & SEND_SHUTDOWN) || (vsk->peerShutdown & RCV_SHUTDOWN)) { err = -EPIPE; goto outWait; } VSOCK_STATS_STREAM_PRODUCE_HIST(vsk); NOTIFYCALLRET(vsk, err, sendPreEnqueue, sk, &sendData); if (err < 0) { goto outWait; } /* * Note that enqueue will only write as many bytes as are free in the * produce queue, so we don't need to ensure len is smaller than the queue * size. It is the caller's responsibility to check how many bytes we were * able to send. */ written = vmci_qpair_enquev(vsk->qpair, msg->msg_iov, len - totalWritten, 0); if (written < 0) { err = -ENOMEM; goto outWait; } totalWritten += written; NOTIFYCALLRET(vsk, err, sendPostEnqueue, sk, written, &sendData); if (err < 0) { goto outWait; } } ASSERT(totalWritten <= INT_MAX); outWait: if (totalWritten > 0) { VSOCK_STATS_STREAM_PRODUCE(totalWritten); err = totalWritten; } finish_wait(sk_sleep(sk), &wait); out: release_sock(sk); return err; } /* *---------------------------------------------------------------------------- * * VSockVmciDgramRecvmsg -- * * Receives a datagram and places it in the caller's msg. * * Results: * The size of the payload on success, negative value on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciDgramRecvmsg(struct kiocb *kiocb, // UNUSED struct socket *sock, // IN: socket to receive from struct msghdr *msg, // IN/OUT: message to receive into size_t len, // IN: length of receive buffer int flags) // IN: receive flags { int err; int noblock; struct sock *sk; VMCIDatagram *dg; size_t payloadLen; struct sk_buff *skb; sk = sock->sk; noblock = flags & MSG_DONTWAIT; if (flags & MSG_OOB || flags & MSG_ERRQUEUE) { return -EOPNOTSUPP; } /* Retrieve the head sk_buff from the socket's receive queue. */ err = 0; skb = skb_recv_datagram(sk, flags, noblock, &err); if (err) { return err; } if (!skb) { return -EAGAIN; } dg = (VMCIDatagram *)skb->data; if (!dg) { /* err is 0, meaning we read zero bytes. */ goto out; } payloadLen = dg->payloadSize; /* Ensure the sk_buff matches the payload size claimed in the packet. */ if (payloadLen != skb->len - sizeof *dg) { err = -EINVAL; goto out; } if (payloadLen > len) { payloadLen = len; msg->msg_flags |= MSG_TRUNC; } /* Place the datagram payload in the user's iovec. */ err = skb_copy_datagram_iovec(skb, sizeof *dg, msg->msg_iov, payloadLen); if (err) { goto out; } msg->msg_namelen = 0; if (msg->msg_name) { struct sockaddr_vm *vmciAddr; /* Provide the address of the sender. */ vmciAddr = (struct sockaddr_vm *)msg->msg_name; VSockAddr_Init(vmciAddr, VMCI_HANDLE_TO_CONTEXT_ID(dg->src), VMCI_HANDLE_TO_RESOURCE_ID(dg->src)); msg->msg_namelen = sizeof *vmciAddr; } err = payloadLen; out: skb_free_datagram(sk, skb); return err; } /* *---------------------------------------------------------------------------- * * VSockVmciSeqRecvmsg -- * * Receives a datagram and places it in the caller's msg. * * Results: * The size of the payload on success, negative value on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciSeqRecvmsg(struct kiocb *kiocb, // UNUSED struct socket *sock, // IN: socket to receive from struct msghdr *msg, // IN/OUT: message to receive into size_t len, // IN: length of receive buffer int flags) // IN: receive flags { int err; int noblock; size_t payloadLen; struct sock *sk; struct sk_buff *skb; if (flags & MSG_OOB || flags & MSG_ERRQUEUE) { return -EOPNOTSUPP; } sk = sock->sk; noblock = flags & MSG_DONTWAIT; /* Retrieve the head sk_buff from the socket's receive queue. */ err = 0; skb = skb_recv_datagram(sk, flags, noblock, &err); if (err) { return err; } if (!skb) { return -EAGAIN; } if (!skb->data) { /* err is 0, meaning we read zero bytes. */ goto out; } payloadLen = skb->len; if (payloadLen > len) { payloadLen = len; msg->msg_flags |= MSG_TRUNC; /* * XXX, we're supposed to be a reliable protocol, so while it's fine to * return a partial packet here, we shouldn't drop the remainder. We * should keep it around so that a subsequent recv() can read it and * then get the end of record marker (see below). */ } else { /* We managed to read the whole payload, so mark the end of record. */ msg->msg_flags |= MSG_EOR; } /* Place the datagram payload in the user's iovec. */ err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, payloadLen); if (err) { goto out; } msg->msg_namelen = 0; if (msg->msg_name) { VSockVmciSock *vsk; struct sockaddr_vm *vmciAddr; /* Provide the address of the sender. */ vsk = vsock_sk(sk); vmciAddr = (struct sockaddr_vm *)msg->msg_name; VSockAddr_Init(vmciAddr, vsk->remoteAddr.svm_cid, vsk->remoteAddr.svm_port); msg->msg_namelen = sizeof *vmciAddr; } err = payloadLen; out: skb_free_datagram(sk, skb); return err; } /* *---------------------------------------------------------------------------- * * VSockVmciStreamRecvmsg -- * * Receives a datagram and places it in the caller's msg. * * Results: * The size of the payload on success, negative value on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciStreamRecvmsg(struct kiocb *kiocb, // UNUSED struct socket *sock, // IN: socket to receive from struct msghdr *msg, // IN/OUT: message to receive into size_t len, // IN: length of receive buffer int flags) // IN: receive flags { struct sock *sk; VSockVmciSock *vsk; int err; size_t target; ssize_t copied; long timeout; VSockVmciRecvNotifyData recvData; DEFINE_WAIT(wait); sk = sock->sk; vsk = vsock_sk(sk); err = 0; lock_sock(sk); if (sk->sk_state != SS_CONNECTED) { /* * Recvmsg is supposed to return 0 if a peer performs an orderly shutdown. * Differentiate between that case and when a peer has not connected or a * local shutdown occured with the SOCK_DONE flag. */ if (sock_flag(sk, SOCK_DONE)) { err = 0; } else { err = -ENOTCONN; } goto out; } if (flags & MSG_OOB) { err = -EOPNOTSUPP; goto out; } /* * We don't check peerShutdown flag here since peer may actually shut down, * but there can be data in the VMCI queue that local socket can receive. */ if (sk->sk_shutdown & RCV_SHUTDOWN) { err = 0; goto out; } /* * It is valid on Linux to pass in a zero-length receive buffer. This * is not an error. We may as well bail out now. Note that if we don't, * we will fail "ASSERT(copied >= target)" after we dequeue, because the * minimum target is always 1 byte. */ if (!len) { err = 0; goto out; } /* * We must not copy less than target bytes into the user's buffer before * returning successfully, so we wait for the consume queue to have that * much data to consume before dequeueing. Note that this makes it * impossible to handle cases where target is greater than the queue size. */ target = sock_rcvlowat(sk, flags & MSG_WAITALL, len); if (target >= vsk->consumeSize) { err = -ENOMEM; goto out; } timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); copied = 0; NOTIFYCALLRET(vsk, err, recvInit, sk, target, &recvData); if (err < 0) { goto out; } prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); while (1) { int64 ready = VSockVmciStreamHasData(vsk); if (ready < 0) { /* * Invalid queue pair content. XXX This should be changed to * a connection reset in a later change. */ err = -ENOMEM; goto outWait; } else if (ready > 0) { ssize_t read; VSOCK_STATS_STREAM_CONSUME_HIST(vsk); NOTIFYCALLRET(vsk, err, recvPreDequeue, sk, target, &recvData); if (err < 0) { break; } if (flags & MSG_PEEK) { read = vmci_qpair_peekv(vsk->qpair, msg->msg_iov, len - copied, 0); } else { read = vmci_qpair_dequev(vsk->qpair, msg->msg_iov, len - copied, 0); } if (read < 0) { err = -ENOMEM; break; } ASSERT(read <= INT_MAX); copied += read; NOTIFYCALLRET(vsk, err, recvPostDequeue, sk, target, read, !(flags & MSG_PEEK), &recvData); if (err < 0) { goto outWait; } if (read >= target || flags & MSG_PEEK) { break; } target -= read; } else { if (sk->sk_err != 0 || (sk->sk_shutdown & RCV_SHUTDOWN) || (vsk->peerShutdown & SEND_SHUTDOWN)) { break; } /* Don't wait for non-blocking sockets. */ if (timeout == 0) { err = -EAGAIN; break; } NOTIFYCALLRET(vsk, err, recvPreBlock, sk, target, &recvData); if (err < 0) { break; } release_sock(sk); timeout = schedule_timeout(timeout); lock_sock(sk); if (signal_pending(current)) { err = sock_intr_errno(timeout); break; } else if (timeout == 0) { err = -EAGAIN; break; } prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); } } if (sk->sk_err) { err = -sk->sk_err; } else if (sk->sk_shutdown & RCV_SHUTDOWN) { err = 0; } if (copied > 0) { /* * We only do these additional bookkeeping/notification steps if we * actually copied something out of the queue pair instead of just peeking * ahead. */ if (!(flags & MSG_PEEK)) { VSOCK_STATS_STREAM_CONSUME(copied); /* * If the other side has shutdown for sending and there is nothing more * to read, then modify the socket state. */ if (vsk->peerShutdown & SEND_SHUTDOWN) { if (VSockVmciStreamHasData(vsk) <= 0) { sk->sk_state = SS_UNCONNECTED; sock_set_flag(sk, SOCK_DONE); sk->sk_state_change(sk); } } } err = copied; } outWait: finish_wait(sk_sleep(sk), &wait); out: release_sock(sk); return err; } /* * Protocol operation. */ /* *---------------------------------------------------------------------------- * * VSockVmciCreate -- * * Creates a VSocket socket. * * Results: * Zero on success, negative error code on failure. * * Side effects: * Socket count is incremented. * *---------------------------------------------------------------------------- */ static int VSockVmciCreate( #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) struct net *net, // IN #endif struct socket *sock, // IN int protocol // IN #ifdef VMW_NETCREATE_KERNARG , int kern // IN #endif ) { if (!sock) { return -EINVAL; } if (protocol) { return -EPROTONOSUPPORT; } switch (sock->type) { case SOCK_DGRAM: sock->ops = &vsockVmciDgramOps; break; case SOCK_STREAM: sock->ops = &vsockVmciStreamOps; break; case SOCK_SEQPACKET: sock->ops = &vsockVmciSeqOps; break; default: return -ESOCKTNOSUPPORT; } sock->state = SS_UNCONNECTED; #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) return __VSockVmciCreate(sock, NULL, GFP_KERNEL, 0) ? 0 : -ENOMEM; #else return __VSockVmciCreate(net, sock, NULL, GFP_KERNEL, 0) ? 0 : -ENOMEM; #endif } /* *---------------------------------------------------------------------------- * * VSockVmciIoctl32Handler -- * * Handler for 32-bit ioctl(2) on 64-bit. * * Results: * Same as VsockVmciDevIoctl(). * * Side effects: * None. * *---------------------------------------------------------------------------- */ #ifdef VM_X86_64 #ifndef HAVE_COMPAT_IOCTL static int VSockVmciIoctl32Handler(unsigned int fd, // IN unsigned int iocmd, // IN unsigned long ioarg, // IN/OUT struct file * filp) // IN { int ret; ret = -ENOTTY; if (filp && filp->f_op && filp->f_op->ioctl == VSockVmciDevIoctl) { ret = VSockVmciDevIoctl(filp->f_dentry->d_inode, filp, iocmd, ioarg); } return ret; } #endif /* !HAVE_COMPAT_IOCTL */ /* *---------------------------------------------------------------------------- * * register_ioctl32_handlers -- * * Registers the ioctl conversion handler. * * Results: * Zero on success, error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int register_ioctl32_handlers(void) { #ifndef HAVE_COMPAT_IOCTL { int i; for (i = IOCTL_VMCI_SOCKETS_FIRST; i < IOCTL_VMCI_SOCKETS_LAST; i++) { int retval = register_ioctl32_conversion(i, VSockVmciIoctl32Handler); if (retval) { Warning("Fail to register ioctl32 conversion for cmd %d\n", i); return retval; } } } #endif /* !HAVE_COMPAT_IOCTL */ return 0; } /* *---------------------------------------------------------------------------- * * unregister_ioctl32_handlers -- * * Unregisters the ioctl converstion handler. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void unregister_ioctl32_handlers(void) { #ifndef HAVE_COMPAT_IOCTL { int i; for (i = IOCTL_VMCI_SOCKETS_FIRST; i < IOCTL_VMCI_SOCKETS_LAST; i++) { int retval = unregister_ioctl32_conversion(i); if (retval) { Warning("Fail to unregister ioctl32 conversion for cmd %d\n", i); } } } #endif /* !HAVE_COMPAT_IOCTL */ } #else /* VM_X86_64 */ #define register_ioctl32_handlers() (0) #define unregister_ioctl32_handlers() do { } while (0) #endif /* VM_X86_64 */ /* * Device operations. */ /* *---------------------------------------------------------------------------- * * VSockVmciDevOpen -- * * Invoked when the device is opened. Simply maintains a count of open * instances. * * Results: * Zero on success, negative value otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VSockVmciDevOpen(struct inode *inode, // IN struct file *file) // IN { compat_mutex_lock(®istrationMutex); devOpenCount++; compat_mutex_unlock(®istrationMutex); return 0; } /* *---------------------------------------------------------------------------- * * VSockVmciDevRelease -- * * Invoked when the device is closed. Updates the open instance count and * unregisters the socket family if this is the last user. * * Results: * Zero on success, negative value otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int VSockVmciDevRelease(struct inode *inode, // IN struct file *file) // IN { compat_mutex_lock(®istrationMutex); devOpenCount--; VSockVmciTestUnregister(); compat_mutex_unlock(®istrationMutex); return 0; } /* *---------------------------------------------------------------------------- * * VSockVmciDevIoctl -- * * ioctl(2) handler. * * Results: * Zero on success, negative error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VSockVmciDevIoctl(struct inode *inode, // IN struct file *filp, // IN u_int iocmd, // IN unsigned long ioarg) // IN/OUT { int retval; retval = 0; switch (iocmd) { case IOCTL_VMCI_SOCKETS_VERSION: { uint16 parts[4] = { VSOCK_DRIVER_VERSION_COMMAS }; uint32 version = VMCI_SOCKETS_MAKE_VERSION(parts); if (copy_to_user((void*)ioarg, &version, sizeof version) != 0) { retval = -EFAULT; } break; } case IOCTL_VMCI_SOCKETS_GET_AF_VALUE: { int family; family = VSockVmci_GetAFValue(); if (family < 0) { Warning("AF_VSOCK is not registered\n"); } if (copy_to_user((void *)ioarg, &family, sizeof family) != 0) { retval = -EFAULT; } break; } case IOCTL_VMCI_SOCKETS_GET_LOCAL_CID: { VMCIId cid = vmci_get_context_id(); if (copy_to_user((void *)ioarg, &cid, sizeof cid) != 0) { retval = -EFAULT; } break; } default: Warning("Unknown ioctl %d\n", iocmd); retval = -EINVAL; } return retval; } #if defined(HAVE_COMPAT_IOCTL) || defined(HAVE_UNLOCKED_IOCTL) /* *----------------------------------------------------------------------------- * * VSockVmciDevUnlockedIoctl -- * * Wrapper for VSockVmciDevIoctl() supporting the compat_ioctl and * unlocked_ioctl methods that have signatures different from the * old ioctl. Used as compat_ioctl method for 32bit apps running * on 64bit kernel and for unlocked_ioctl on systems supporting * those. VSockVmciDevIoctl() may safely be called without holding * the BKL. * * Results: * Same as VSockVmciDevIoctl(). * * Side effects: * None. * *----------------------------------------------------------------------------- */ static long VSockVmciDevUnlockedIoctl(struct file *filp, // IN u_int iocmd, // IN unsigned long ioarg) // IN/OUT { return VSockVmciDevIoctl(NULL, filp, iocmd, ioarg); } #endif /* * Module operations. */ /* *---------------------------------------------------------------------------- * * VSockVmciInit -- * * Initialization routine for the VSockets module. * * Results: * Zero on success, error code on failure. * * Side effects: * The VSocket protocol family and socket operations are registered. * *---------------------------------------------------------------------------- */ static int __init VSockVmciInit(void) { int err; DriverLog_Init("VSock"); request_module("vmci"); err = misc_register(&vsockVmciDevice); if (err) { return -ENOENT; } err = register_ioctl32_handlers(); if (err) { misc_deregister(&vsockVmciDevice); return err; } err = VSockVmciRegisterWithVmci(); if (err) { Warning("Cannot register with VMCI device.\n"); unregister_ioctl32_handlers(); misc_deregister(&vsockVmciDevice); return err; } err = VSockVmciRegisterProto(); if (err) { Warning("Cannot register vsock protocol.\n"); VSockVmciUnregisterWithVmci(); unregister_ioctl32_handlers(); misc_deregister(&vsockVmciDevice); return err; } VSockVmciInitTables(); return 0; } /* *---------------------------------------------------------------------------- * * VSocketVmciExit -- * * VSockets module exit routine. * * Results: * None. * * Side effects: * Unregisters VSocket protocol family and socket operations. * *---------------------------------------------------------------------------- */ static void __exit VSockVmciExit(void) { unregister_ioctl32_handlers(); misc_deregister(&vsockVmciDevice); compat_mutex_lock(®istrationMutex); VSockVmciUnregisterAddressFamily(); compat_mutex_unlock(®istrationMutex); VSockVmciUnregisterProto(); VSockVmciUnregisterWithVmci(); } module_init(VSockVmciInit); module_exit(VSockVmciExit); MODULE_AUTHOR("VMware, Inc."); MODULE_DESCRIPTION("VMware Virtual Socket Family"); MODULE_VERSION(VSOCK_DRIVER_VERSION_STRING); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("vmware_vsock"); /* * Starting with SLE10sp2, Novell requires that IHVs sign a support agreement * with them and mark their kernel modules as externally supported via a * change to the module header. If this isn't done, the module will not load * by default (i.e., neither mkinitrd nor modprobe will accept it). */ MODULE_INFO(supported, "external"); #ifdef VMX86_DEVEL /* We only support protocol negotiation overrides on devel builds. */ module_param(PROTOCOL_OVERRIDE, int, 0444); MODULE_PARM_DESC(PROTOCOL_OVERRIDE, "Specify a vsock protocol (auto negotiated by default"); int LOGLEVEL_THRESHOLD = 4; module_param(LOGLEVEL_THRESHOLD, int, 0444); MODULE_PARM_DESC(LOGLEVEL_THRESHOLD, "Set verbosity (0 means no log, 10 means very verbose, 4 is default)"); #endif open-vm-tools-9.4.0-1280544/modules/linux/vsock/linux/notify.h0000644765153500003110000001162712220061556022222 0ustar dtormts/********************************************************* * Copyright (C) 2009-2011 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * notify.h -- * * Notify functions for Linux VSocket module. */ #ifndef __NOTIFY_H__ #define __NOTIFY_H__ #include "driver-config.h" #include "vsockCommon.h" #include "vsockPacket.h" /* Comment this out to compare with old protocol. */ #define VSOCK_OPTIMIZATION_WAITING_NOTIFY 1 #if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY) /* Comment this out to remove flow control for "new" protocol */ # define VSOCK_OPTIMIZATION_FLOW_CONTROL 1 #endif #define VSOCK_MAX_DGRAM_RESENDS 10 #define NOTIFYCALLRET(vsk, rv, mod_fn, args...) \ do { \ if (vsk->notifyOps && \ vsk->notifyOps->mod_fn != NULL) { \ rv = (vsk->notifyOps->mod_fn)(args); \ } else { \ rv = 0; \ } \ } while (0) #define NOTIFYCALL(vsk, mod_fn, args...) \ do { \ if (vsk->notifyOps && \ vsk->notifyOps->mod_fn != NULL) { \ (vsk->notifyOps->mod_fn)(args); \ } \ } while (0) typedef struct VSockVmciNotifyPkt { uint64 writeNotifyWindow; uint64 writeNotifyMinWindow; Bool peerWaitingRead; Bool peerWaitingWrite; Bool peerWaitingWriteDetected; Bool sentWaitingRead; Bool sentWaitingWrite; VSockWaitingInfo peerWaitingReadInfo; VSockWaitingInfo peerWaitingWriteInfo; uint64 produceQGeneration; uint64 consumeQGeneration; } VSockVmciNotifyPkt; typedef struct VSockVmciNotifyPktQState { uint64 writeNotifyWindow; uint64 writeNotifyMinWindow; Bool peerWaitingWrite; Bool peerWaitingWriteDetected; } VSockVmciNotifyPktQState; typedef union VSockVmciNotify { VSockVmciNotifyPkt pkt; VSockVmciNotifyPktQState pktQState; } VSockVmciNotify; typedef struct VSockVmciRecvNotifyData { uint64 consumeHead; uint64 produceTail; Bool notifyOnBlock; } VSockVmciRecvNotifyData; typedef struct VSockVmciSendNotifyData { uint64 consumeHead; uint64 produceTail; } VSockVmciSendNotifyData; /* Socket notification callbacks. */ typedef struct VSockVmciNotifyOps { void (*socketInit)(struct sock *sk); void (*socketDestruct)(struct sock *sk); int32 (*pollIn)(struct sock *sk, size_t target, Bool *dataReadyNow); int32 (*pollOut)(struct sock *sk, size_t target, Bool *spaceAvailNow); void (*handleNotifyPkt)(struct sock *sk, VSockPacket *pkt, Bool bottomHalf, struct sockaddr_vm *dst, struct sockaddr_vm *src, Bool *pktProcessed); int32 (*recvInit)(struct sock *sk, size_t target, VSockVmciRecvNotifyData *data); int32 (*recvPreBlock)(struct sock *sk, size_t target, VSockVmciRecvNotifyData *data); int32 (*recvPreDequeue)(struct sock *sk, size_t target, VSockVmciRecvNotifyData *data); int32 (*recvPostDequeue)(struct sock *sk, size_t target, ssize_t copied, Bool dataRead, VSockVmciRecvNotifyData *data); int32 (*sendInit)(struct sock *sk, VSockVmciSendNotifyData *data); int32 (*sendPreBlock)(struct sock *sk, VSockVmciSendNotifyData *data); int32 (*sendPreEnqueue)(struct sock *sk, VSockVmciSendNotifyData *data); int32 (*sendPostEnqueue)(struct sock *sk, ssize_t written, VSockVmciSendNotifyData *data); void (*processRequest)(struct sock *sk); void (*processNegotiate)(struct sock *sk); } VSockVmciNotifyOps; extern VSockVmciNotifyOps vSockVmciNotifyPktOps; extern VSockVmciNotifyOps vSockVmciNotifyPktQStateOps; #endif /* __NOTIFY_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/vsock/linux/vsockCommon.h0000644765153500003110000001643612220061556023213 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vsockCommon.h -- * * VSockets common constants, types and functions. */ #ifndef _VSOCK_COMMON_H_ #define _VSOCK_COMMON_H_ /* * VMCISockGetAFValueInt is defined separately from VMCISock_GetAFValue because * it is used in several different contexts. In particular it is called from * vsockAddr.c which gets compiled into both our kernel modules as well as * the user level vsock library. In the linux kernel we need different behavior * than external kernel modules using VMCI Sockets api inside the kernel. */ #if defined _WIN32 # define VMCI_SOCKETS_AF_VALUE 28 # if defined WINNT_DDK # define _WIN2K_COMPAT_SLIST_USAGE # include # include # define _INC_WINDOWS /* In the kernel we can't call into the provider. */ # define VMCISockGetAFValueInt() VMCI_SOCKETS_AF_VALUE # else // WINNT_DDK /* In userland, just use the normal exported userlevel api. */ # define VMCISockGetAFValueInt() VMCISock_GetAFValue() # include # endif // WINNT_DDK #elif defined VMKERNEL # include "uwvmkAPI.h" # define VMCI_SOCKETS_AF_VALUE AF_VMCI /* Defined in uwvmkAPI.h. */ /* The address family is fixed in the vmkernel. */ # define VMCISockGetAFValueInt() VMCI_SOCKETS_AF_VALUE #elif defined linux # if defined __KERNEL__ /* Include compat_page.h now so PAGE_SIZE and friends don't get redefined. */ # include "driver-config.h" # include "compat_page.h" /* * In the kernel we call back into af_vsock.c to get the address family * being used. Otherwise an ioctl(2) is performed (see vmci_sockets.h). */ extern int VSockVmci_GetAFValue(void); # define VMCISockGetAFValueInt() VSockVmci_GetAFValue() # else // __KERNEL__ /* In userland, just use the normal exported userlevel api. */ # define VMCISockGetAFValueInt() VMCISock_GetAFValue() # endif #elif defined __APPLE__ # if defined KERNEL # include # define VMCI_SOCKETS_AF_VALUE 14 # define VMCISockGetAFValueInt() VMCI_SOCKETS_AF_VALUE # else // KERNEL # define VMCISockGetAFValueInt() VMCISock_GetAFValue() # endif // KERNEL #endif // __APPLE__ #include "vmware.h" #include "vm_basic_asm.h" #include "vmci_defs.h" #include "vmci_call_defs.h" #include "vmci_infrastructure.h" #include "vmci_sockets_int.h" #include "vmci_sockets.h" #if defined WINNT_DDK # include #endif // WINNT_DDK #include "vsockAddr.h" #include "vsockSocketWrapper.h" /* Memory allocation flags. */ #define VSOCK_MEMORY_NORMAL 0 #define VSOCK_MEMORY_ATOMIC (1 << 0) #define VSOCK_MEMORY_NONPAGED (1 << 1) /* *----------------------------------------------------------------------------- * * VSockVA64ToPtr -- * * Convert a VA64 to a pointer. * * Results: * Virtual address. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void * VSockVA64ToPtr(VA64 va64) // IN { #ifdef VM_X86_64 ASSERT_ON_COMPILE(sizeof (void *) == 8); #else ASSERT_ON_COMPILE(sizeof (void *) == 4); // Check that nothing of value will be lost. ASSERT(!(va64 >> 32)); #endif return (void *)(uintptr_t)va64; } /* *----------------------------------------------------------------------------- * * VSockPtrToVA64 -- * * Convert a pointer to a VA64. * * Results: * Virtual address. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE VA64 VSockPtrToVA64(void const *ptr) // IN { ASSERT_ON_COMPILE(sizeof ptr <= sizeof (VA64)); return (VA64)(uintptr_t)ptr; } #if defined(_WIN32) && !defined(WINNT_DDK) /* VSock transport provider structures */ __declspec(selectany) extern const WSAPROTOCOL_INFOW vsockProtocolInfos[] = { { (XP1_CONNECTIONLESS | /* No connection required. */ XP1_MESSAGE_ORIENTED), /* Message. */ 0, /* Reserved. */ 0, /* Reserved. */ 0, /* Reserved. */ PFL_MATCHES_PROTOCOL_ZERO, /* Always protocol 0. */ { 0 }, /* None. */ 0, /* Assigned by Winsock. */ { 1, 0 }, /* Base provider. */ 0, /* Version 0. */ VMCI_SOCKETS_AF_VALUE, /* VMCI sockets protocol. */ 16, /* Maximum address length in bytes. */ 16, /* Minimum address length in bytes. */ SOCK_DGRAM, /* STREAM. */ 0, /* Protocol. */ 0, /* Protocol max offset. */ BIGENDIAN, /* Network byte order. */ SECURITY_PROTOCOL_NONE, /* No security. */ 0, /* Message size unimportant. */ 0, /* None. */ L"VMCI sockets DGRAM" /* Protocol name. */ }, { (XP1_GUARANTEED_DELIVERY | /* Guaranteed delivery. */ XP1_GUARANTEED_ORDER | /* Guaranteed order. */ XP1_GRACEFUL_CLOSE), /* Graceful close. */ 0, /* Reserved. */ 0, /* Reserved. */ 0, /* Reserved. */ PFL_MATCHES_PROTOCOL_ZERO, /* Always protocol 0. */ { 0 }, /* None. */ 0, /* Assigned by Winsock. */ { 1, 0 }, /* Base provider. */ 0, /* Version 0. */ VMCI_SOCKETS_AF_VALUE, /* VMCI sockets protocol. */ 16, /* Maximum address length in bytes. */ 16, /* Minimum address length in bytes. */ SOCK_STREAM, /* STREAM. */ 0, /* Protocol. */ 0, /* Protocol max offset. */ BIGENDIAN, /* Network byte order. */ SECURITY_PROTOCOL_NONE, /* No security. */ 0, /* Message size unimportant. */ 0, /* None. */ L"VMCI sockets STREAM" /* Protocol name. */ }, }; __declspec(selectany) extern const size_t numVSockProtocolInfos = ARRAYSIZE(vsockProtocolInfos); /* {570ADC4B-67B2-42ce-92B2-ACD33D88D842} */ __declspec(selectany) extern const GUID vsockProviderID = { 0x570adc4b, 0x67b2, 0x42ce, { 0x92, 0xb2, 0xac, 0xd3, 0x3d, 0x88, 0xd8, 0x42 } }; #endif // _WIN32 && !WINNT_DDK #endif // _VSOCK_COMMON_H_ open-vm-tools-9.4.0-1280544/modules/linux/vsock/linux/vsock_version.h0000644765153500003110000000221512220061556023575 0ustar dtormts/********************************************************* * Copyright (C) 2011-2012 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vsock_version.h -- * * Version definitions for the Linux vsock driver. */ #ifndef _VSOCK_VERSION_H_ #define _VSOCK_VERSION_H_ #define VSOCK_DRIVER_VERSION 9.5.6.0 #define VSOCK_DRIVER_VERSION_COMMAS 9,5.6,0 #define VSOCK_DRIVER_VERSION_STRING "9.5.6.0" #endif /* _VSOCK_VERSION_H_ */ open-vm-tools-9.4.0-1280544/modules/linux/vsock/linux/vmci_sockets_int.h0000644765153500003110000000462112220061556024251 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmci_sockets_int.h -- * * VMCI sockets private constants and types. * * This file is internal only, we do not ship the kernel interface yet. * You need to include this file *before* vmci_sockets.h in your kernel * module. */ #ifndef _VMCI_SOCKETS_INT_H_ #define _VMCI_SOCKETS_INT_H_ #if defined(_WIN32) # if defined(NT_INCLUDED) # if (_WIN32_WINNT < 0x0600) /* * WinSockKernel is targetted at Vista and later. We want to allow * drivers built from W2K onwards to work with the interface, so we * need to define some missing types before we bring in the WSK header. */ typedef unsigned short u_short; # include # include typedef WSACMSGHDR CMSGHDR, *PCMSGHDR; # endif // (_WIN32_WINNT < 0x0600) # include NTSTATUS VMCISock_WskRegister(PWSK_CLIENT_NPI wskClientNpi, PWSK_REGISTRATION wskRegistration); NTSTATUS VMCISock_WskDeregister(PWSK_REGISTRATION wskRegistration); NTSTATUS VMCISock_WskCaptureProviderNPI(PWSK_REGISTRATION wskRegistration, ULONG waitTimeout, PWSK_PROVIDER_NPI wskProviderNpi); NTSTATUS VMCISock_WskReleaseProviderNPI(PWSK_REGISTRATION wskRegistration); NTSTATUS VMCISock_WskGetAFValue(PWSK_CLIENT wskClient, PIRP irp); NTSTATUS VMCISock_WskGetLocalCID(PWSK_CLIENT wskClient, PIRP irp); # endif // NT_INCLUDED #endif // _WIN32 #endif // _VMCI_SOCKETS_INT_H_ open-vm-tools-9.4.0-1280544/modules/linux/vsock/linux/vsockVmci.h0000644765153500003110000000745112220061556022656 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vsockVmci.h -- * * VSockets VMCI constants, types and functions. */ #ifndef _VSOCK_VMCI_H_ #define _VSOCK_VMCI_H_ extern VMCIId VMCI_GetContextID(void); /* *----------------------------------------------------------------------------- * * VSockVmci_IsLocal -- * * Determine if the given handle points to the local context. * * Results: * TRUE if the given handle is for the local context, FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE Bool VSockVmci_IsLocal(VMCIHandle handle) // IN { return VMCI_GetContextID() == VMCI_HANDLE_TO_CONTEXT_ID(handle); } /* *---------------------------------------------------------------------------- * * VSockVmci_ErrorToVSockError -- * * Converts from a VMCI error code to a VSock error code. * * Results: * Appropriate error code. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static INLINE int32 VSockVmci_ErrorToVSockError(int32 vmciError) // IN { int32 err; switch (vmciError) { case VMCI_ERROR_NO_MEM: #if defined(_WIN32) err = ENOBUFS; #else // _WIN32 err = ENOMEM; #endif // _WIN32 break; case VMCI_ERROR_DUPLICATE_ENTRY: err = EADDRINUSE; break; case VMCI_ERROR_NO_ACCESS: err = EPERM; break; case VMCI_ERROR_NO_RESOURCES: err = ENOBUFS; break; case VMCI_ERROR_INVALID_RESOURCE: err = EHOSTUNREACH; break; case VMCI_ERROR_MODULE_NOT_LOADED: err = ESYSNOTREADY; break; case VMCI_ERROR_NO_HANDLE: err = ENETUNREACH; break; case VMCI_ERROR_INVALID_ARGS: default: err = EINVAL; } return sockerr2err(err); } /* *---------------------------------------------------------------------------- * * VSockVmci_GetVmciObjSocket -- * * Get a socket from a VMCI object, but only if the object is of the * appropriate type. * * Results: * A socket if the object is of the correct type, NULL otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static INLINE void * VSockVmci_GetVmciObjSocket(VMCIObj *obj) // IN { ASSERT(obj); if (NULL != obj->ptr && VMCIOBJ_SOCKET == obj->type) { return obj->ptr; } return NULL; } /* *---------------------------------------------------------------------------- * * VSockVmci_SetVmciObjSocket -- * * Set the socket in a VMCI object. This will also set the type * accordingly. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static INLINE void VSockVmci_SetVmciObjSocket(VMCIObj *obj, // OUT void *s) // IN { ASSERT(obj); ASSERT(s); obj->ptr = s; obj->type = VMCIOBJ_SOCKET; } #endif // _VSOCK_VMCI_H_ open-vm-tools-9.4.0-1280544/modules/linux/vsock/linux/vsockPacket.h0000644765153500003110000001651112220061556023164 0ustar dtormts/********************************************************* * Copyright (C) 2007-2012 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vsockPacket.h -- * * Packet constants, types and functions. */ #ifndef _VSOCK_PACKET_H_ #define _VSOCK_PACKET_H_ #include "vmci_sockets_packet.h" #if defined(_WIN32) || defined(VMKERNEL) || defined(__APPLE__) # include "vsockOSInt.h" #else # define VSockOS_ClearMemory(_dst, _sz) memset(_dst, 0, _sz) # define VSockOS_Memcpy(_dst, _src, _sz) memcpy(_dst, _src, _sz) #endif /* *----------------------------------------------------------------------------- * * VSockPacket_Init -- * * Initialize the given packet. The packet version is set and the fields * are filled out. Reserved fields are cleared. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE void VSockPacket_Init(VSockPacket *pkt, // OUT struct sockaddr_vm *src, // IN struct sockaddr_vm *dst, // IN uint8 type, // IN uint64 size, // IN uint64 mode, // IN VSockWaitingInfo *wait, // IN VSockProtoVersion proto, // IN VMCIHandle handle) // IN { ASSERT(pkt); VSOCK_ADDR_NOFAMILY_ASSERT(src); VSOCK_ADDR_NOFAMILY_ASSERT(dst); /* * We register the stream control handler as an any cid handle so we * must always send from a source address of VMADDR_CID_ANY */ pkt->dg.src = VMCI_MAKE_HANDLE(VMADDR_CID_ANY, VSOCK_PACKET_RID); pkt->dg.dst = VMCI_MAKE_HANDLE(dst->svm_cid, VSOCK_PACKET_RID); pkt->dg.payloadSize = sizeof *pkt - sizeof pkt->dg; pkt->version = VSOCK_PACKET_VERSION; pkt->type = type; pkt->srcPort = src->svm_port; pkt->dstPort = dst->svm_port; VSockOS_ClearMemory(&pkt->proto, sizeof pkt->proto); VSockOS_ClearMemory(&pkt->_reserved2, sizeof pkt->_reserved2); switch (pkt->type) { case VSOCK_PACKET_TYPE_INVALID: pkt->u.size = 0; break; case VSOCK_PACKET_TYPE_REQUEST: case VSOCK_PACKET_TYPE_NEGOTIATE: pkt->u.size = size; break; case VSOCK_PACKET_TYPE_OFFER: case VSOCK_PACKET_TYPE_ATTACH: pkt->u.handle = handle; break; case VSOCK_PACKET_TYPE_WROTE: case VSOCK_PACKET_TYPE_READ: case VSOCK_PACKET_TYPE_RST: pkt->u.size = 0; break; case VSOCK_PACKET_TYPE_SHUTDOWN: pkt->u.mode = mode; break; case VSOCK_PACKET_TYPE_WAITING_READ: case VSOCK_PACKET_TYPE_WAITING_WRITE: ASSERT(wait); VSockOS_Memcpy(&pkt->u.wait, wait, sizeof pkt->u.wait); break; case VSOCK_PACKET_TYPE_REQUEST2: case VSOCK_PACKET_TYPE_NEGOTIATE2: pkt->u.size = size; pkt->proto = proto; break; } VSOCK_PACKET_ASSERT(pkt); } /* *----------------------------------------------------------------------------- * * VSockPacket_Validate -- * * Validate the given packet. * * Results: * 0 on success, EFAULT if the address is invalid, EINVAL if the packet * fields are invalid. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE int32 VSockPacket_Validate(VSockPacket *pkt) { int32 err = EINVAL; if (NULL == pkt) { err = EFAULT; goto exit; } if (VMCI_HANDLE_INVALID(pkt->dg.src)) { goto exit; } if (VMCI_HANDLE_INVALID(pkt->dg.dst)) { goto exit; } if (VMCI_INVALID_ID == pkt->dstPort || VMCI_INVALID_ID == pkt->srcPort) { goto exit; } if (VSOCK_PACKET_VERSION != pkt->version) { goto exit; } /* See the comment above VSOCK_PACKET_ASSERT. */ if (pkt->type < VSOCK_PACKET_TYPE_REQUEST2) { if (0 != pkt->proto || 0 != pkt->_reserved2) { goto exit; } } switch (pkt->type) { case VSOCK_PACKET_TYPE_INVALID: if (0 != pkt->u.size) { goto exit; } break; case VSOCK_PACKET_TYPE_REQUEST: case VSOCK_PACKET_TYPE_NEGOTIATE: if (0 == pkt->u.size) { goto exit; } break; case VSOCK_PACKET_TYPE_OFFER: case VSOCK_PACKET_TYPE_ATTACH: if (VMCI_HANDLE_INVALID(pkt->u.handle)) { goto exit; } break; case VSOCK_PACKET_TYPE_WROTE: case VSOCK_PACKET_TYPE_READ: case VSOCK_PACKET_TYPE_RST: if (0 != pkt->u.size) { goto exit; } break; } err = 0; exit: return sockerr2err(err); } /* *----------------------------------------------------------------------------- * * VSockPacket_GetAddresses -- * * Get the local and remote addresses from the given packet. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE void VSockPacket_GetAddresses(VSockPacket *pkt, // IN struct sockaddr_vm *local, // OUT struct sockaddr_vm *remote) // OUT { VSOCK_PACKET_ASSERT(pkt); VSockAddr_Init(local, VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.dst), pkt->dstPort); VSockAddr_Init(remote, VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.src), pkt->srcPort); } /* * SEQPACKET packets. */ /* *----------------------------------------------------------------------------- * * VSockSeqPacket_Init * * Initialize the given packet. This will use the current version and * set the offset to point after the current (combined) structure. The * length will be set to include the combined structure. To add data * after calling this function, do "pkt->hdr.dg.payloadSize += dataLen". * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE void VSockSeqPacket_Init(VSockSeqPacket *pkt, // IN/OUT struct sockaddr_vm *src, // IN struct sockaddr_vm *dst, // IN uint8 type, // IN int32 val) // IN { ASSERT(pkt); VSOCK_ADDR_NOFAMILY_ASSERT(src); VSOCK_ADDR_NOFAMILY_ASSERT(dst); pkt->hdr.dg.src = VMCI_MAKE_HANDLE(src->svm_cid, src->svm_port); pkt->hdr.dg.dst = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, dst->svm_port); pkt->hdr.dg.payloadSize = sizeof *pkt - sizeof pkt->hdr.dg; pkt->hdr.version = VSOCK_SEQ_PACKET_VERSION; pkt->hdr.type = type; pkt->hdr.offset = sizeof *pkt; pkt->hdr.val = val; } #endif // _VSOCK_PACKET_H_ open-vm-tools-9.4.0-1280544/modules/linux/vsock/Makefile.kernel0000644765153500003110000000502612220061556022315 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 2007 VMware, Inc. All rights reserved. # # 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 version 2 and no later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ########################################################## vm_product_defines = $(if $(findstring tools,$(1)), -DVMX86_TOOLS,) CC_OPTS += $(call vm_product_defines, $(PRODUCT)) INCLUDE += -I. INCLUDE += -I$(SRCROOT)/include INCLUDE += -I$(SRCROOT)/linux INCLUDE += -I$(SRCROOT)/common EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE) EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/netcreate_num_params.c, -DVMW_NETCREATE_KERNARG, ) MODPOST_VMCI_SYMVERS := $(wildcard $(MODULEBUILDDIR)/VMwareVMCIModule.symvers) obj-m += $(DRIVER).o $(DRIVER)-y := $(subst $(SRCROOT)/, , $(patsubst %.c, %.o, $(wildcard $(SRCROOT)/linux/*.c))) # # In open-vm-tools, need to compile the common sources from the shared directory. # DRIVERLOG := driverLog.o $(DRIVER)-y += $(DRIVERLOG) VSOCK_PATH := $(shell cd $(SRCROOT) && pwd) ifdef OVT_SOURCE_DIR DRIVERLOG_PATH := $(OVT_SOURCE_DIR)/modules/linux/shared else DRIVERLOG_PATH := $(VSOCK_PATH)/shared endif $(addprefix $(VSOCK_PATH)/,$(DRIVERLOG)): $(VSOCK_PATH)/%.o: $(DRIVERLOG_PATH)/%.c $(Q)$(rule_cc_o_c) clean: rm -rf $(wildcard $(DRIVER).mod.c $(DRIVER).ko .tmp_versions \ Module.symvers Module.markers modules.order \ $(foreach dir,./ linux/ \ ,$(addprefix $(dir),.*.cmd .*.o.flags *.o))) # # The VSock kernel module uses symbols from the VMCI kernel module. Copy the # Module.symvers file here so that the Vsock module knows about the VMCI version. This is not done for tar builds because the tools install takes care of it. # prebuild:: ifneq ($(MODULEBUILDDIR),) ifeq ($(MODPOST_VMCI_SYMVERS),) $(shell echo >&2 "Building VMCI Sockets without VMCI module symbols.") else $(shell echo >&2 "Building VMCI Sockets with VMCI module symbols.") cp -f $(MODPOST_VMCI_SYMVERS) $(SRCROOT)/Module.symvers endif endif open-vm-tools-9.4.0-1280544/modules/linux/vsock/README0000644765153500003110000000075512220061556020262 0ustar dtormtsThis files in this directory and its subdirectories are the kernel module for the VMware VSockets module. In order to build, make certain the Makefile is correct and then just type make from this directory. A copy of the module will be left in driver-/vsock- (e.g. driver-up-2.4.20/vsock-up-2.4.20) for 2.4 series kernels and in ../vsock.o for 2.6 series kernels. If you have any problems or questions, send mail to support@vmware.com open-vm-tools-9.4.0-1280544/modules/linux/vsock/COPYING0000644765153500003110000004310312220061556020427 0ustar dtormts GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. open-vm-tools-9.4.0-1280544/modules/linux/vsock/Makefile0000644765153500003110000001054012220061556021033 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 1998 VMware, Inc. All rights reserved. # # 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 version 2 and no later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ########################################################## #### #### VMware kernel module Makefile to be distributed externally #### #### #### SRCROOT _must_ be a relative path. #### SRCROOT = . # # open-vm-tools doesn't replicate shared source files for different modules; # instead, files are kept in shared locations. So define a few useful macros # to be able to handle both cases cleanly. # INCLUDE := ifdef OVT_SOURCE_DIR AUTOCONF_DIR := $(OVT_SOURCE_DIR)/modules/linux/shared/autoconf VMLIB_PATH = $(OVT_SOURCE_DIR)/lib/$(1) INCLUDE += -I$(OVT_SOURCE_DIR)/modules/linux/shared INCLUDE += -I$(OVT_SOURCE_DIR)/lib/include else AUTOCONF_DIR := $(SRCROOT)/shared/autoconf INCLUDE += -I$(SRCROOT)/shared endif VM_UNAME = $(shell uname -r) # Header directory for the running kernel ifdef LINUXINCLUDE HEADER_DIR = $(LINUXINCLUDE) else HEADER_DIR = /lib/modules/$(VM_UNAME)/build/include endif BUILD_DIR = $(HEADER_DIR)/.. DRIVER := vsock PRODUCT := tools-source # Grep program GREP = /bin/grep vm_check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null \ > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) vm_check_file = $(shell if test -f $(1); then echo "yes"; else echo "no"; fi) ifndef VM_KBUILD VM_KBUILD := no ifeq ($(call vm_check_file,$(BUILD_DIR)/Makefile), yes) ifneq ($(call vm_check_file,$(BUILD_DIR)/Rules.make), yes) VM_KBUILD := 26 endif endif export VM_KBUILD endif ifndef VM_KBUILD_SHOWN ifeq ($(VM_KBUILD), no) VM_DUMMY := $(shell echo >&2 "Using standalone build system.") else ifeq ($(VM_KBUILD), 24) VM_DUMMY := $(shell echo >&2 "Using 2.4.x kernel build system.") else VM_DUMMY := $(shell echo >&2 "Using 2.6.x kernel build system.") endif endif VM_KBUILD_SHOWN := yes export VM_KBUILD_SHOWN endif ifneq ($(VM_KBUILD), no) VMCCVER := $(shell $(CC) -dumpversion) # If there is no version defined, we are in toplevel pass, not yet in kernel makefiles... ifeq ($(VERSION),) ifeq ($(VM_KBUILD), 24) DRIVER_KO := $(DRIVER).o else DRIVER_KO := $(DRIVER).ko endif .PHONY: $(DRIVER_KO) auto-build: $(DRIVER_KO) cp -f $< $(SRCROOT)/../$(DRIVER).o # $(DRIVER_KO) is a phony target, so compare file times explicitly $(DRIVER): $(DRIVER_KO) if [ $< -nt $@ ] || [ ! -e $@ ] ; then cp -f $< $@; fi # Pass gcc version down the chain, so we can detect if kernel attempts to use unapproved compiler VM_CCVER := $(VMCCVER) export VM_CCVER VM_CC := $(CC) export VM_CC MAKEOVERRIDES := $(filter-out CC=%,$(MAKEOVERRIDES)) # # Define a setup target that gets built before the actual driver. # This target may not be used at all, but if it is then it will be defined # in Makefile.kernel # prebuild:: ; postbuild:: ; $(DRIVER_KO): prebuild $(MAKE) -C $(BUILD_DIR) SUBDIRS=$$PWD SRCROOT=$$PWD/$(SRCROOT) \ MODULEBUILDDIR=$(MODULEBUILDDIR) modules $(MAKE) -C $$PWD SRCROOT=$$PWD/$(SRCROOT) \ MODULEBUILDDIR=$(MODULEBUILDDIR) postbuild endif vm_check_build = $(shell if $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ $(CPPFLAGS) $(CFLAGS) $(CFLAGS_KERNEL) $(LINUXINCLUDE) \ $(EXTRA_CFLAGS) -Iinclude2/asm/mach-default \ -DKBUILD_BASENAME=\"$(DRIVER)\" \ -Werror -S -o /dev/null -xc $(1) \ > /dev/null 2>&1; then echo "$(2)"; else echo "$(3)"; fi) CC_WARNINGS := -Wall -Wstrict-prototypes CC_OPTS := $(GLOBAL_DEFS) $(CC_WARNINGS) -DVMW_USING_KBUILD ifdef VMX86_DEVEL CC_OPTS += -DVMX86_DEVEL endif ifdef VMX86_DEBUG CC_OPTS += -DVMX86_DEBUG endif include $(SRCROOT)/Makefile.kernel ifdef TOPDIR ifeq ($(VM_KBUILD), 24) O_TARGET := $(DRIVER).o obj-y := $($(DRIVER)-y) include $(TOPDIR)/Rules.make endif endif else include $(SRCROOT)/Makefile.normal endif #.SILENT: open-vm-tools-9.4.0-1280544/modules/linux/vmsync/0000755765153500003110000000000012220061556017565 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/linux/vmsync/Makefile.kernel0000644765153500003110000000307312220061556022507 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 1998 VMware, Inc. All rights reserved. # # 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 version 2 and no later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ########################################################## #### #### VMware vmsync Makefile to be distributed externally #### INCLUDE += -I. EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE) EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/cachecreate.c, -DVMW_KMEMCR_HAS_DTOR, ) EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/cachector.c, -DVMW_KMEMCR_CTOR_HAS_3_ARGS, ) EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/cachector1.c, -DVMW_KMEMCR_CTOR_HAS_2_ARGS, ) obj-m += $(DRIVER).o $(DRIVER)-y := $(subst $(SRCROOT)/, , $(patsubst %.c, %.o, $(wildcard $(SRCROOT)/*.c))) clean: rm -rf $(wildcard $(DRIVER).mod.c $(DRIVER).ko .tmp_versions \ Module.symvers Modules.symvers Module.markers modules.order \ $(foreach dir,./,$(addprefix $(dir),.*.cmd .*.o.flags *.o))) open-vm-tools-9.4.0-1280544/modules/linux/vmsync/vmsync_version.h0000644765153500003110000000222012220061556023016 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmsync_version.h -- * * Version definitions for the Linux vmsync driver. */ #ifndef _VMSYNC_VERSION_H_ #define _VMSYNC_VERSION_H_ #define VMSYNC_DRIVER_VERSION 1.1.0.1 #define VMSYNC_DRIVER_VERSION_COMMAS 1,1,0,1 #define VMSYNC_DRIVER_VERSION_STRING "1.1.0.1" #endif /* _VMSYNC_VERSION_H_ */ open-vm-tools-9.4.0-1280544/modules/linux/vmsync/COPYING0000644765153500003110000004310312220061556020621 0ustar dtormts GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. open-vm-tools-9.4.0-1280544/modules/linux/vmsync/sync.c0000644765153500003110000004441312220061556020713 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * sync.c -- * * Linux "sync driver" implementation. * * A typical user of vmsync will: * * - call ioctl() with the SYNC_IOC_FREEZE to freeze a list of paths. * The list should be a colon-separated list of paths to be frozen. * - call ioctl() with the SYNC_IOC_THAW command. * * The driver has an internal timer that is set up as soon as devices * are frozen (i.e., after a successful SYNC_IOC_FREEZE). Subsequent calls * to SYNC_IOC_FREEZE will not reset the timer. This timer is not designed * as a way to protect the driver from being an avenue for a DoS attack * (after all, if the user already has CAP_SYS_ADMIN privileges...), but * as a way to protect itself from faulty user level apps during testing. */ /* Must come before any kernel header file. */ #include "driver-config.h" #include #include #include #include #include #include "compat_fs.h" #include "compat_module.h" #include "compat_namei.h" #include "compat_mutex.h" #include "compat_slab.h" #include "compat_workqueue.h" #include "syncDriverIoc.h" #include "vmsync_version.h" /* * After a successful SYNC_IOC_FREEZE ioctl, a timer will be enabled to thaw * *all* frozen block devices after this delay. */ #define VMSYNC_THAW_TASK_DELAY (30 * HZ) /* Module information. */ MODULE_AUTHOR("VMware, Inc."); MODULE_DESCRIPTION("VMware Sync Driver"); MODULE_VERSION(VMSYNC_DRIVER_VERSION_STRING); MODULE_LICENSE("GPL v2"); /* * Starting with SLE10sp2, Novell requires that IHVs sign a support agreement * with them and mark their kernel modules as externally supported via a * change to the module header. If this isn't done, the module will not load * by default (i.e., neither mkinitrd nor modprobe will accept it). */ MODULE_INFO(supported, "external"); static int VmSyncRelease(struct inode* inode, struct file *file); static long VmSyncUnlockedIoctl(struct file *file, unsigned cmd, unsigned long arg); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) static int VmSyncIoctl(struct inode *inode, struct file *file, unsigned cmd, unsigned long arg); #endif static int VmSyncOpen(struct inode *inode, struct file *f); static struct file_operations VmSyncFileOps = { .owner = THIS_MODULE, .open = VmSyncOpen, .release = VmSyncRelease, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) .unlocked_ioctl = VmSyncUnlockedIoctl, #else .ioctl = VmSyncIoctl, #endif }; typedef struct VmSyncBlockDevice { struct list_head list; struct block_device *bdev; struct nameidata nd; struct super_block *sb; } VmSyncBlockDevice; typedef struct VmSyncState { struct list_head devices; compat_mutex_t lock; compat_delayed_work thawTask; } VmSyncState; /* * Serializes freeze operations. Used to make sure that two different * fds aren't allowed to freeze the same device. */ static compat_mutex_t gFreezeLock; /* A global count of how many devices are currently frozen by the driver. */ static atomic_t gFreezeCount; static compat_kmem_cache *gSyncStateCache; static compat_kmem_cache *gBlockDeviceCache; static compat_kmem_cache_ctor VmSyncBlockDeviceCtor; static compat_kmem_cache_ctor VmSyncStateCtor; /* *----------------------------------------------------------------------------- * * VmSyncThawDevices -- * * Thaws all currently frozen devices. * * Results: * None. * * Side effects: * Devices are thawed, thaw task is cancelled. * *----------------------------------------------------------------------------- */ static void VmSyncThawDevices(void *_state) // IN { struct list_head *cur, *tmp; VmSyncBlockDevice *dev; VmSyncState *state; state = (VmSyncState *) _state; compat_mutex_lock(&state->lock); cancel_delayed_work(&state->thawTask); list_for_each_safe(cur, tmp, &state->devices) { dev = list_entry(cur, VmSyncBlockDevice, list); if (dev->sb != NULL && dev->sb->s_frozen != SB_UNFROZEN) { thaw_bdev(dev->bdev, dev->sb); atomic_dec(&gFreezeCount); } list_del_init(&dev->list); kmem_cache_free(gBlockDeviceCache, dev); } compat_mutex_unlock(&state->lock); } /* *----------------------------------------------------------------------------- * * VmSyncThawDevicesCallback -- * * Wrapper around VmSyncThawDevices used by the work queue. * * Results: * None. * * Side effects: * See VmSyncThawDevices. * *----------------------------------------------------------------------------- */ static void VmSyncThawDevicesCallback(compat_delayed_work_arg data) // IN { VmSyncState *state = COMPAT_DELAYED_WORK_GET_DATA(data, VmSyncState, thawTask); VmSyncThawDevices(state); } /* *----------------------------------------------------------------------------- * * VmSyncAddPath -- * * Adds the block device associated with the path to the internal list * of devices to be frozen. * * Results: * 0 on success. * -EINVAL if path doesn't point to a freezable mount. * -EALREADY if path is already frozen. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int VmSyncAddPath(const VmSyncState *state, // IN const char *path, // IN struct list_head *pathList) // IN { int result; struct list_head *cur, *tmp; struct inode *inode; struct nameidata nd; VmSyncBlockDevice *dev; if ((result = compat_path_lookup(path, LOOKUP_FOLLOW, &nd)) != 0) { goto exit; } inode = compat_vmw_nd_to_dentry(nd)->d_inode; /* * Abort if the inode's superblock isn't backed by a block device, or if * the superblock is already frozen. */ if (inode->i_sb->s_bdev == NULL || inode->i_sb->s_frozen != SB_UNFROZEN) { result = (inode->i_sb->s_bdev == NULL) ? -EINVAL : -EALREADY; compat_path_release(&nd); goto exit; } /* * Check if we've already added the block device to the list. */ list_for_each_safe(cur, tmp, &state->devices) { dev = list_entry(cur, VmSyncBlockDevice, list); if (dev->bdev == inode->i_sb->s_bdev) { result = 0; compat_path_release(&nd); goto exit; } } /* * Allocate a new entry and add it to the list. */ dev = kmem_cache_alloc(gBlockDeviceCache, GFP_KERNEL); if (dev == NULL) { result = -ENOMEM; compat_path_release(&nd); goto exit; } /* * Whenever we add a device to the "freeze list", the reference to * the nameidata struct is retained until the device is actually * frozen; this ensures the kernel knows the path is being used. * Here we copy the nameidata struct so we can release our reference * at that time. */ dev->bdev = inode->i_sb->s_bdev; memcpy(&dev->nd, &nd, sizeof nd); list_add_tail(&dev->list, pathList); result = 0; exit: return result; } /* *----------------------------------------------------------------------------- * * VmSyncFreezeDevices -- * * Tries to freeze all the devices provided by the user. * * Results: * o on success, -errno on error. * * Side effects: * A task is scheduled to automatically thaw devices after a timeout. * *----------------------------------------------------------------------------- */ static int VmSyncFreezeDevices(VmSyncState *state, // IN const char __user *userPaths) // IN { int result = 0; char *paths; char *currPath; char *nextSep; struct list_head *cur, *tmp; struct list_head pathList; VmSyncBlockDevice *dev; INIT_LIST_HEAD(&pathList); /* * XXX: Using getname() will restrict the list of paths to PATH_MAX. * Although this is not ideal, it shouldn't be a problem. We need an * upper bound anyway. */ paths = getname(userPaths); if (IS_ERR(paths)) { return PTR_ERR(paths); } compat_mutex_lock(&gFreezeLock); compat_mutex_lock(&state->lock); /* * First, try to add all paths to the list of paths to be frozen. */ currPath = paths; do { nextSep = strchr(currPath, ':'); if (nextSep != NULL) { *nextSep = '\0'; } result = VmSyncAddPath(state, currPath, &pathList); /* * Due to the way our user level app decides which paths to freeze * now, we need to ignore EINVAL since there's no way to detect * from user-land which paths are freezable or not. */ if (result != 0 && result != -EINVAL) { break; } else { result = 0; } currPath = nextSep + 1; } while (nextSep != NULL); /* * If adding all the requested paths worked, then freeze them. * Otherwise, clean the list. Make sure we only touch the devices * added in the current call. */ list_for_each_safe(cur, tmp, &pathList) { dev = list_entry(cur, VmSyncBlockDevice, list); if (result == 0) { dev->sb = freeze_bdev(dev->bdev); compat_path_release(&dev->nd); if (dev->sb != NULL) { atomic_inc(&gFreezeCount); } list_move_tail(&dev->list, &state->devices); } else { list_del_init(&dev->list); kmem_cache_free(gBlockDeviceCache, dev); } } compat_mutex_unlock(&state->lock); compat_mutex_unlock(&gFreezeLock); if (result == 0) { compat_schedule_delayed_work(&state->thawTask, VMSYNC_THAW_TASK_DELAY); } return result; } /* *----------------------------------------------------------------------------- * * VmSyncQuery -- * * Writes the number of devices currently frozen by the driver to the * given address. The address should be in user space and be able to * hold an int32_t. * * Results: * 0 on success, -errno on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static inline int VmSyncQuery(void __user *dst) // OUT { int32_t active; int result = 0; active = (int32_t) atomic_read(&gFreezeCount); if (copy_to_user(dst, &active, sizeof active)) { result = -EFAULT; } return result; } /* *----------------------------------------------------------------------------- * * VmSyncUnlockedIoctl -- * * Handles the IOCTLs recognized by the driver. * * - SYNC_IOC_FREEZE: freezes the block device associated with the * path passed as a parameter. * * - SYNC_IOC_THAW: thaws all currently frozen block devices. * * - SYNC_IOC_QUERY: returns the number of block devices currently * frozen by the driver. This is a global view of the driver state * and doesn't reflect any fd-specific data. * * Results: * 0 on success, -errno otherwise. * * Side effects: * See ioctl descriptions above. * *----------------------------------------------------------------------------- */ static long VmSyncUnlockedIoctl(struct file *file, // IN unsigned cmd, // IN unsigned long arg) // IN/OUT { int result = -ENOTTY; VmSyncState *state; state = (VmSyncState *) file->private_data; switch (cmd) { case SYNC_IOC_FREEZE: if (!capable(CAP_SYS_ADMIN)) { result = -EPERM; break; } result = VmSyncFreezeDevices(state, (const char __user *) arg); break; case SYNC_IOC_THAW: if (!capable(CAP_SYS_ADMIN)) { result = -EPERM; break; } VmSyncThawDevices(state); result = 0; break; case SYNC_IOC_QUERY: result = VmSyncQuery((void __user *)arg); break; default: printk(KERN_DEBUG "vmsync: unknown ioctl %d\n", cmd); break; } return result; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) /* *----------------------------------------------------------------------------- * * VmSyncIoctl -- * * Wrapper around VmSyncUnlockedIoctl for kernels < 2.6.11, which don't * support unlocked_ioctl. * * Results: * See VmSyncUnlockedIoctl. * * Side effects: * See VmSyncUnlockedIoctl. * *----------------------------------------------------------------------------- */ static int VmSyncIoctl(struct inode *inode, // IN struct file *file, // IN unsigned cmd, // IN unsigned long arg) // IN/OUT { return (int) VmSyncUnlockedIoctl(file, cmd, arg); } #endif /* *----------------------------------------------------------------------------- * * VmSyncOpen -- * * Instantiates a new state object and attached it to the file struct. * * Results: * 0, or -ENOMEM if can't allocate memory. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int VmSyncOpen(struct inode *inode, // IN struct file *f) // IN { if (capable(CAP_SYS_ADMIN)) { f->private_data = kmem_cache_alloc(gSyncStateCache, GFP_KERNEL); if (f->private_data == NULL) { return -ENOMEM; } } return 0; } /* *----------------------------------------------------------------------------- * * VmSyncRelease -- * * If the fd was used to freeze devices, then thaw all frozen block devices. * * Results: * Returns 0. * * Side effects: * Calls VmSyncThawDevices. * *----------------------------------------------------------------------------- */ static int VmSyncRelease(struct inode *inode, // IN struct file *file) // IN { if (capable(CAP_SYS_ADMIN)) { VmSyncState *state = (VmSyncState *) file->private_data; if (!cancel_delayed_work(&state->thawTask)) { flush_scheduled_work(); } VmSyncThawDevices(state); kmem_cache_free(gSyncStateCache, state); } return 0; } /* *----------------------------------------------------------------------------- * * VmSyncBlockDeviceCtor -- * * Constructor for VmSyncBlockDevice objects. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VmSyncBlockDeviceCtor(COMPAT_KMEM_CACHE_CTOR_ARGS(slabelem)) // IN { VmSyncBlockDevice *dev = slabelem; INIT_LIST_HEAD(&dev->list); dev->bdev = NULL; dev->sb = NULL; } /* *----------------------------------------------------------------------------- * * VmSyncStateCtor -- * * Constructor for VmSyncState objects. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VmSyncStateCtor(COMPAT_KMEM_CACHE_CTOR_ARGS(slabelem)) // IN { VmSyncState *state = slabelem; INIT_LIST_HEAD(&state->devices); COMPAT_INIT_DELAYED_WORK(&state->thawTask, VmSyncThawDevicesCallback, state); compat_mutex_init(&state->lock); } /* *----------------------------------------------------------------------------- * * init_module -- * * Initializes the structures used by the driver, and creates the * proc file used by the driver to receive commands. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int init_module(void) { struct proc_dir_entry *controlProcEntry; atomic_set(&gFreezeCount, 0); compat_mutex_init(&gFreezeLock); /* Create the slab allocators for the module. */ gBlockDeviceCache = compat_kmem_cache_create("VmSyncBlockDeviceCache", sizeof (VmSyncBlockDevice), 0, SLAB_HWCACHE_ALIGN, VmSyncBlockDeviceCtor); if (gBlockDeviceCache == NULL) { printk(KERN_ERR "vmsync: no memory for block dev slab allocator\n"); return -ENOMEM; } gSyncStateCache = compat_kmem_cache_create("VmSyncStateCache", sizeof (VmSyncState), 0, SLAB_HWCACHE_ALIGN, VmSyncStateCtor); if (gSyncStateCache == NULL) { printk(KERN_ERR "vmsync: no memory for sync state slab allocator\n"); kmem_cache_destroy(gBlockDeviceCache); return -ENOMEM; } /* Create /proc/driver/vmware-sync */ controlProcEntry = create_proc_entry("driver/vmware-sync", S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, NULL); if (!controlProcEntry) { printk(KERN_ERR "vmsync: could not create /proc/driver/vmware-sync\n"); kmem_cache_destroy(gSyncStateCache); kmem_cache_destroy(gBlockDeviceCache); return -EINVAL; } controlProcEntry->proc_fops = &VmSyncFileOps; return 0; } /* *----------------------------------------------------------------------------- * * cleanup_module -- * * Unregisters the proc file used by the driver. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void cleanup_module(void) { remove_proc_entry("driver/vmware-sync", NULL); kmem_cache_destroy(gSyncStateCache); kmem_cache_destroy(gBlockDeviceCache); } open-vm-tools-9.4.0-1280544/modules/linux/vmsync/Makefile0000644765153500003110000001053212220061556021226 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 1998 VMware, Inc. All rights reserved. # # 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 version 2 and no later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ########################################################## #### #### VMware kernel module Makefile to be distributed externally #### #### #### SRCROOT _must_ be a relative path. #### SRCROOT = . # # open-vm-tools doesn't replicate shared source files for different modules; # instead, files are kept in shared locations. So define a few useful macros # to be able to handle both cases cleanly. # INCLUDE := ifdef OVT_SOURCE_DIR AUTOCONF_DIR := $(OVT_SOURCE_DIR)/modules/linux/shared/autoconf VMLIB_PATH = $(OVT_SOURCE_DIR)/lib/$(1) INCLUDE += -I$(OVT_SOURCE_DIR)/modules/linux/shared INCLUDE += -I$(OVT_SOURCE_DIR)/lib/include else AUTOCONF_DIR := $(SRCROOT)/shared/autoconf INCLUDE += -I$(SRCROOT)/shared endif VM_UNAME = $(shell uname -r) # Header directory for the running kernel ifdef LINUXINCLUDE HEADER_DIR = $(LINUXINCLUDE) else HEADER_DIR = /lib/modules/$(VM_UNAME)/build/include endif BUILD_DIR = $(HEADER_DIR)/.. DRIVER := vmsync PRODUCT := tools # Grep program GREP = /bin/grep vm_check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null \ > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) vm_check_file = $(shell if test -f $(1); then echo "yes"; else echo "no"; fi) ifndef VM_KBUILD VM_KBUILD := no ifeq ($(call vm_check_file,$(BUILD_DIR)/Makefile), yes) ifneq ($(call vm_check_file,$(BUILD_DIR)/Rules.make), yes) VM_KBUILD := 26 endif endif export VM_KBUILD endif ifndef VM_KBUILD_SHOWN ifeq ($(VM_KBUILD), no) VM_DUMMY := $(shell echo >&2 "Using standalone build system.") else ifeq ($(VM_KBUILD), 24) VM_DUMMY := $(shell echo >&2 "Using 2.4.x kernel build system.") else VM_DUMMY := $(shell echo >&2 "Using 2.6.x kernel build system.") endif endif VM_KBUILD_SHOWN := yes export VM_KBUILD_SHOWN endif ifneq ($(VM_KBUILD), no) VMCCVER := $(shell $(CC) -dumpversion) # If there is no version defined, we are in toplevel pass, not yet in kernel makefiles... ifeq ($(VERSION),) ifeq ($(VM_KBUILD), 24) DRIVER_KO := $(DRIVER).o else DRIVER_KO := $(DRIVER).ko endif .PHONY: $(DRIVER_KO) auto-build: $(DRIVER_KO) cp -f $< $(SRCROOT)/../$(DRIVER).o # $(DRIVER_KO) is a phony target, so compare file times explicitly $(DRIVER): $(DRIVER_KO) if [ $< -nt $@ ] || [ ! -e $@ ] ; then cp -f $< $@; fi # Pass gcc version down the chain, so we can detect if kernel attempts to use unapproved compiler VM_CCVER := $(VMCCVER) export VM_CCVER VM_CC := $(CC) export VM_CC MAKEOVERRIDES := $(filter-out CC=%,$(MAKEOVERRIDES)) # # Define a setup target that gets built before the actual driver. # This target may not be used at all, but if it is then it will be defined # in Makefile.kernel # prebuild:: ; postbuild:: ; $(DRIVER_KO): prebuild $(MAKE) -C $(BUILD_DIR) SUBDIRS=$$PWD SRCROOT=$$PWD/$(SRCROOT) \ MODULEBUILDDIR=$(MODULEBUILDDIR) modules $(MAKE) -C $$PWD SRCROOT=$$PWD/$(SRCROOT) \ MODULEBUILDDIR=$(MODULEBUILDDIR) postbuild endif vm_check_build = $(shell if $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ $(CPPFLAGS) $(CFLAGS) $(CFLAGS_KERNEL) $(LINUXINCLUDE) \ $(EXTRA_CFLAGS) -Iinclude2/asm/mach-default \ -DKBUILD_BASENAME=\"$(DRIVER)\" \ -Werror -S -o /dev/null -xc $(1) \ > /dev/null 2>&1; then echo "$(2)"; else echo "$(3)"; fi) CC_WARNINGS := -Wall -Wstrict-prototypes CC_OPTS := $(GLOBAL_DEFS) $(CC_WARNINGS) -DVMW_USING_KBUILD ifdef VMX86_DEVEL CC_OPTS += -DVMX86_DEVEL endif ifdef VMX86_DEBUG CC_OPTS += -DVMX86_DEBUG endif include $(SRCROOT)/Makefile.kernel ifdef TOPDIR ifeq ($(VM_KBUILD), 24) O_TARGET := $(DRIVER).o obj-y := $($(DRIVER)-y) include $(TOPDIR)/Rules.make endif endif else include $(SRCROOT)/Makefile.normal endif #.SILENT: open-vm-tools-9.4.0-1280544/modules/linux/shared/0000755765153500003110000000000012220061556017514 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/linux/shared/compat_namei.h0000644765153500003110000000341612220061556022325 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_NAMEI_H__ # define __COMPAT_NAMEI_H__ #include /* * In 2.6.25-rc2, dentry and mount objects were removed from the nameidata * struct. They were both replaced with a struct path. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) #define compat_vmw_nd_to_dentry(nd) (nd).path.dentry #else #define compat_vmw_nd_to_dentry(nd) (nd).dentry #endif /* In 2.6.25-rc2, path_release(&nd) was replaced with path_put(&nd.path). */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) #define compat_path_release(nd) path_put(&(nd)->path) #else #define compat_path_release(nd) path_release(nd) #endif /* path_lookup was removed in 2.6.39 merge window VFS merge */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) #define compat_path_lookup(name, flags, nd) kern_path(name, flags, &((nd)->path)) #else #define compat_path_lookup(name, flags, nd) path_lookup(name, flags, nd) #endif #endif /* __COMPAT_NAMEI_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_dcache.h0000644765153500003110000000400412220061556022435 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_DCACHE_H__ # define __COMPAT_DCACHE_H__ #include /* * per-dentry locking was born in 2.5.62. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 62) #define compat_lock_dentry(dentry) spin_lock(&dentry->d_lock) #define compat_unlock_dentry(dentry) spin_unlock(&dentry->d_lock) #else #define compat_lock_dentry(dentry) do {} while (0) #define compat_unlock_dentry(dentry) do {} while (0) #endif /* * d_alloc_name was born in 2.6.10. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) #define compat_d_alloc_name(parent, s) d_alloc_name(parent, s) #else #define compat_d_alloc_name(parent, s) \ ({ \ struct qstr q; \ q.name = s; \ q.len = strlen(s); \ q.hash = full_name_hash(q.name, q.len); \ d_alloc(parent, &q); \ }) #endif #endif /* __COMPAT_DCACHE_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_ioport.h0000644765153500003110000000404112220061556022543 0ustar dtormts/********************************************************* * Copyright (C) 2003 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_IOPORT_H__ # define __COMPAT_IOPORT_H__ #include #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) static inline void * compat_request_region(unsigned long start, unsigned long len, const char *name) { if (check_region(start, len)) { return NULL; } request_region(start, len, name); return (void*)1; } #else #define compat_request_region(start, len, name) request_region(start, len, name) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 7) /* mmap io support starts from 2.3.7, fail the call for kernel prior to that */ static inline void * compat_request_mem_region(unsigned long start, unsigned long len, const char *name) { return NULL; } static inline void compat_release_mem_region(unsigned long start, unsigned long len) { return; } #else #define compat_request_mem_region(start, len, name) request_mem_region(start, len, name) #define compat_release_mem_region(start, len) release_mem_region(start, len) #endif /* these two macro defs are needed by compat_pci_request_region */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 15) # define IORESOURCE_IO 0x00000100 # define IORESOURCE_MEM 0x00000200 #endif #endif /* __COMPAT_IOPORT_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/vmciKernelAPI1.h0000644765153500003110000001751412220061556022407 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciKernelAPI1.h -- * * Kernel API (v1) exported from the VMCI host and guest drivers. */ #ifndef __VMCI_KERNELAPI_1_H__ #define __VMCI_KERNELAPI_1_H__ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vmci_defs.h" #include "vmci_call_defs.h" /* VMCI module namespace on vmkernel. */ #define MOD_VMCI_NAMESPACE "com.vmware.vmci" /* Define version 1. */ #undef VMCI_KERNEL_API_VERSION #define VMCI_KERNEL_API_VERSION_1 1 #define VMCI_KERNEL_API_VERSION VMCI_KERNEL_API_VERSION_1 /* Macros to operate on the driver version number. */ #define VMCI_MAJOR_VERSION(v) (((v) >> 16) & 0xffff) #define VMCI_MINOR_VERSION(v) ((v) & 0xffff) #if defined(_WIN32) /* Path to callback object in object manager, for Windows only. */ #define VMCI_CALLBACK_OBJECT_PATH L"\\Callback\\VMCIDetachCB" #endif // _WIN32 /* VMCI Device Usage API. */ #if defined(linux) && !defined(VMKERNEL) #define vmci_device_get(_a, _b, _c, _d) 1 #define vmci_device_release(_x) #else // !linux typedef void (VMCI_DeviceShutdownFn)(void *deviceRegistration, void *userData); Bool vmci_device_get(uint32 *apiVersion, VMCI_DeviceShutdownFn *deviceShutdownCB, void *userData, void **deviceRegistration); void vmci_device_release(void *deviceRegistration); #endif // !linux #if defined(_WIN32) /* Called when the client is unloading, for Windows only. */ void vmci_exit(void); #endif // _WIN32 /* VMCI Datagram API. */ int vmci_datagram_create_handle(uint32 resourceId, uint32 flags, VMCIDatagramRecvCB recvCB, void *clientData, VMCIHandle *outHandle); int vmci_datagram_create_handle_priv(uint32 resourceID, uint32 flags, VMCIPrivilegeFlags privFlags, VMCIDatagramRecvCB recvCB, void *clientData, VMCIHandle *outHandle); int vmci_datagram_destroy_handle(VMCIHandle handle); int vmci_datagram_send(VMCIDatagram *msg); /* VMCI Utility API. */ VMCIId vmci_get_context_id(void); #if defined(linux) && !defined(VMKERNEL) /* Returned value is a bool, 0 for false, 1 for true. */ int vmci_is_context_owner(VMCIId contextID, uid_t uid); #else // !linux || VMKERNEL /* Returned value is a VMCI error code. */ int vmci_is_context_owner(VMCIId contextID, void *hostUser); #endif // !linux || VMKERNEL uint32 vmci_version(void); int vmci_cid_2_host_vm_id(VMCIId contextID, void *hostVmID, size_t hostVmIDLen); /* VMCI Event API. */ typedef void (*VMCI_EventCB)(VMCIId subID, VMCI_EventData *ed, void *clientData); int vmci_event_subscribe(VMCI_Event event, #if !defined(linux) || defined(VMKERNEL) uint32 flags, #endif // !linux || VMKERNEL VMCI_EventCB callback, void *callbackData, VMCIId *subID); int vmci_event_unsubscribe(VMCIId subID); /* VMCI Context API */ VMCIPrivilegeFlags vmci_context_get_priv_flags(VMCIId contextID); /* VMCI Queue Pair API. */ typedef struct VMCIQPair VMCIQPair; int vmci_qpair_alloc(VMCIQPair **qpair, VMCIHandle *handle, uint64 produceQSize, uint64 consumeQSize, VMCIId peer, uint32 flags, VMCIPrivilegeFlags privFlags); int vmci_qpair_detach(VMCIQPair **qpair); int vmci_qpair_get_produce_indexes(const VMCIQPair *qpair, uint64 *producerTail, uint64 *consumerHead); int vmci_qpair_get_consume_indexes(const VMCIQPair *qpair, uint64 *consumerTail, uint64 *producerHead); int64 vmci_qpair_produce_free_space(const VMCIQPair *qpair); int64 vmci_qpair_produce_buf_ready(const VMCIQPair *qpair); int64 vmci_qpair_consume_free_space(const VMCIQPair *qpair); int64 vmci_qpair_consume_buf_ready(const VMCIQPair *qpair); ssize_t vmci_qpair_enqueue(VMCIQPair *qpair, const void *buf, size_t bufSize, int mode); ssize_t vmci_qpair_dequeue(VMCIQPair *qpair, void *buf, size_t bufSize, int mode); ssize_t vmci_qpair_peek(VMCIQPair *qpair, void *buf, size_t bufSize, int mode); #if defined (SOLARIS) || (defined(__APPLE__) && !defined (VMX86_TOOLS)) || \ (defined(__linux__) && defined(__KERNEL__)) || \ (defined(_WIN32) && defined(WINNT_DDK)) /* * Environments that support struct iovec */ ssize_t vmci_qpair_enquev(VMCIQPair *qpair, void *iov, size_t iovSize, int mode); ssize_t vmci_qpair_dequev(VMCIQPair *qpair, void *iov, size_t iovSize, int mode); ssize_t vmci_qpair_peekv(VMCIQPair *qpair, void *iov, size_t iovSize, int mode); #endif /* Systems that support struct iovec */ /* Typedefs for all of the above, used by the IOCTLs and the kernel library. */ typedef void (VMCI_DeviceReleaseFct)(void *); typedef int (VMCIDatagram_CreateHndFct)(VMCIId, uint32, VMCIDatagramRecvCB, void *, VMCIHandle *); typedef int (VMCIDatagram_CreateHndPrivFct)(VMCIId, uint32, VMCIPrivilegeFlags, VMCIDatagramRecvCB, void *, VMCIHandle *); typedef int (VMCIDatagram_DestroyHndFct)(VMCIHandle); typedef int (VMCIDatagram_SendFct)(VMCIDatagram *); typedef VMCIId (VMCI_GetContextIDFct)(void); typedef uint32 (VMCI_VersionFct)(void); typedef int (VMCI_ContextID2HostVmIDFct)(VMCIId, void *, size_t); typedef int (VMCI_IsContextOwnerFct)(VMCIId, void *); typedef int (VMCIEvent_SubscribeFct)(VMCI_Event, uint32, VMCI_EventCB, void *, VMCIId *); typedef int (VMCIEvent_UnsubscribeFct)(VMCIId); typedef VMCIPrivilegeFlags (VMCIContext_GetPrivFlagsFct)(VMCIId); typedef int (VMCIQPair_AllocFct)(VMCIQPair **, VMCIHandle *, uint64, uint64, VMCIId, uint32, VMCIPrivilegeFlags); typedef int (VMCIQPair_DetachFct)(VMCIQPair **); typedef int (VMCIQPair_GetProduceIndexesFct)(const VMCIQPair *, uint64 *, uint64 *); typedef int (VMCIQPair_GetConsumeIndexesFct)(const VMCIQPair *, uint64 *, uint64 *); typedef int64 (VMCIQPair_ProduceFreeSpaceFct)(const VMCIQPair *); typedef int64 (VMCIQPair_ProduceBufReadyFct)(const VMCIQPair *); typedef int64 (VMCIQPair_ConsumeFreeSpaceFct)(const VMCIQPair *); typedef int64 (VMCIQPair_ConsumeBufReadyFct)(const VMCIQPair *); typedef ssize_t (VMCIQPair_EnqueueFct)(VMCIQPair *, const void *, size_t, int); typedef ssize_t (VMCIQPair_DequeueFct)(VMCIQPair *, void *, size_t, int); typedef ssize_t (VMCIQPair_PeekFct)(VMCIQPair *, void *, size_t, int); typedef ssize_t (VMCIQPair_EnqueueVFct)(VMCIQPair *qpair, void *, size_t, int); typedef ssize_t (VMCIQPair_DequeueVFct)(VMCIQPair *qpair, void *, size_t, int); typedef ssize_t (VMCIQPair_PeekVFct)(VMCIQPair *qpair, void *, size_t, int); #endif /* !__VMCI_KERNELAPI_1_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_sched.h0000644765153500003110000002423612220061556022325 0ustar dtormts/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_SCHED_H__ # define __COMPAT_SCHED_H__ #include /* CLONE_KERNEL available in 2.5.35 and higher. */ #ifndef CLONE_KERNEL #define CLONE_KERNEL CLONE_FILES | CLONE_FS | CLONE_SIGHAND #endif /* TASK_COMM_LEN become available in 2.6.11. */ #ifndef TASK_COMM_LEN #define TASK_COMM_LEN 16 #endif /* The capable() API appeared in 2.1.92 --hpreg */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 1, 92) # define capable(_capability) suser() #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0) # define need_resched() need_resched #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 3) # define need_resched() (current->need_resched) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 3) # define cond_resched() (need_resched() ? schedule() : (void) 0) #endif /* Oh well. We need yield... Happy us! */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 20) # ifdef __x86_64__ # define compat_yield() there_is_nothing_like_yield() # else # include # include /* * Used by _syscallX macros. Note that this is global variable, so * do not rely on its contents too much. As exit() is only function * we use, and we never check return value from exit(), we have * no problem... */ extern int errno; /* * compat_exit() provides an access to the exit() function. It must * be named compat_exit(), as exit() (with different signature) is * provided by x86-64, arm and other (but not by i386). */ # define __NR_compat_yield __NR_sched_yield static inline _syscall0(int, compat_yield); # endif #else # define compat_yield() yield() #endif /* * Since 2.5.34 there are two methods to enumerate tasks: * for_each_process(p) { ... } which enumerates only tasks and * do_each_thread(g,t) { ... } while_each_thread(g,t) which enumerates * also threads even if they share same pid. */ #ifndef for_each_process # define for_each_process(p) for_each_task(p) #endif #ifndef do_each_thread # define do_each_thread(g, t) for_each_task(g) { t = g; do # define while_each_thread(g, t) while (0) } #endif /* * Lock for signal mask is moving target... */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 40) && defined(CLONE_PID) /* 2.4.x without NPTL patches or early 2.5.x */ #define compat_sigmask_lock sigmask_lock #define compat_dequeue_signal_current(siginfo_ptr) \ dequeue_signal(¤t->blocked, (siginfo_ptr)) #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 60) && !defined(INIT_SIGHAND) /* RedHat's 2.4.x with first version of NPTL support, or 2.5.40 to 2.5.59 */ #define compat_sigmask_lock sig->siglock #define compat_dequeue_signal_current(siginfo_ptr) \ dequeue_signal(¤t->blocked, (siginfo_ptr)) #else /* RedHat's 2.4.x with second version of NPTL support, or 2.5.60+. */ #define compat_sigmask_lock sighand->siglock #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) #define compat_dequeue_signal_current(siginfo_ptr) \ dequeue_signal(¤t->blocked, (siginfo_ptr)) #else #define compat_dequeue_signal_current(siginfo_ptr) \ dequeue_signal(current, ¤t->blocked, (siginfo_ptr)) #endif #endif /* * recalc_sigpending() had task argument in the past */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 29) && defined(CLONE_PID) /* 2.4.x without NPTL patches or early 2.5.x */ #define compat_recalc_sigpending() recalc_sigpending(current) #else /* RedHat's 2.4.x with NPTL support, or 2.5.29+ */ #define compat_recalc_sigpending() recalc_sigpending() #endif /* * reparent_to_init() was introduced in 2.4.8. In 2.5.38 (or possibly * earlier, but later than 2.5.31) a call to it was added into * daemonize(), so compat_daemonize no longer needs to call it. * * In 2.4.x kernels reparent_to_init() forgets to do correct refcounting * on current->user. It is better to count one too many than one too few... */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 8) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 38) #define compat_reparent_to_init() do { \ reparent_to_init(); \ atomic_inc(¤t->user->__count); \ } while (0) #else #define compat_reparent_to_init() do {} while (0) #endif /* * daemonize appeared in 2.2.18. Except 2.2.17-4-RH7.0, which has it too. * Fortunately 2.2.17-4-RH7.0 uses versioned symbols, so we can check * its existence with defined(). */ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)) && !defined(daemonize) static inline void daemonize(void) { struct fs_struct *fs; exit_mm(current); current->session = 1; current->pgrp = 1; exit_fs(current); fs = init_task.fs; current->fs = fs; atomic_inc(&fs->count); } #endif /* * flush_signals acquires sighand->siglock since 2.5.61... Verify RH's kernels! */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 61) #define compat_flush_signals(task) do { \ spin_lock_irq(&task->compat_sigmask_lock); \ flush_signals(task); \ spin_unlock_irq(&task->compat_sigmask_lock); \ } while (0) #else #define compat_flush_signals(task) flush_signals(task) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 61) #define compat_allow_signal(signr) do { \ spin_lock_irq(¤t->compat_sigmask_lock); \ sigdelset(¤t->blocked, signr); \ compat_recalc_sigpending(); \ spin_unlock_irq(¤t->compat_sigmask_lock); \ } while (0) #else #define compat_allow_signal(signr) allow_signal(signr) #endif /* * daemonize can set process name since 2.5.61. Prior to 2.5.61, daemonize * didn't block signals on our behalf. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 61) #define compat_daemonize(x...) \ ({ \ /* Beware! No snprintf here, so verify arguments! */ \ sprintf(current->comm, x); \ \ /* Block all signals. */ \ spin_lock_irq(¤t->compat_sigmask_lock); \ sigfillset(¤t->blocked); \ compat_recalc_sigpending(); \ spin_unlock_irq(¤t->compat_sigmask_lock); \ compat_flush_signals(current); \ \ daemonize(); \ compat_reparent_to_init(); \ }) #else #define compat_daemonize(x...) daemonize(x) #endif /* * try to freeze a process. For kernels 2.6.11 or newer, we know how to choose * the interface. The problem is that the oldest interface, introduced in * 2.5.18, was backported to 2.4.x kernels. So if we're older than 2.6.11, * we'll decide what to do based on whether or not swsusp was configured * for the kernel. For kernels 2.6.20 and newer, we'll also need to include * freezer.h since the try_to_freeze definition was pulled out of sched.h. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) #include #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) || defined(VMW_TL10S64_WORKAROUND) #define compat_try_to_freeze() try_to_freeze() #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) #define compat_try_to_freeze() try_to_freeze(PF_FREEZE) #elif defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_SOFTWARE_SUSPEND2) #include "compat_mm.h" #include #include static inline int compat_try_to_freeze(void) { if (current->flags & PF_FREEZE) { refrigerator(PF_FREEZE); return 1; } else { return 0; } } #else static inline int compat_try_to_freeze(void) { return 0; } #endif /* * As of 2.6.23-rc1, kernel threads are no longer freezable by * default. Instead, kernel threads that need to be frozen must opt-in * by calling set_freezable() as soon as the thread is created. */ #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22) #define compat_set_freezable() do { set_freezable(); } while (0) #else #define compat_set_freezable() do {} while (0) #endif /* * Around 2.6.27 kernel stopped sending signals to kernel * threads being frozen, instead threads have to check * freezing() or use wait_event_freezable(). Unfortunately * wait_event_freezable() completely hides the fact that * thread was frozen from calling code and sometimes we do * want to know that. */ #ifdef PF_FREEZER_NOSIG #define compat_wait_check_freezing() freezing(current) #else #define compat_wait_check_freezing() (0) #endif /* * Since 2.6.27-rc2 kill_proc() is gone... Replacement (GPL-only!) * API is available since 2.6.19. Use them from 2.6.27-rc1 up. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) typedef int compat_pid; #define compat_find_get_pid(pid) (pid) #define compat_put_pid(pid) do { } while (0) #define compat_kill_pid(pid, sig, flag) kill_proc(pid, sig, flag) #else typedef struct pid * compat_pid; #define compat_find_get_pid(pid) find_get_pid(pid) #define compat_put_pid(pid) put_pid(pid) #define compat_kill_pid(pid, sig, flag) kill_pid(pid, sig, flag) #endif #endif /* __COMPAT_SCHED_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/vmci_call_defs.h0000644765153500003110000002406312220061556022624 0ustar dtormts/********************************************************* * Copyright (C) 2006-2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef _VMCI_CALL_DEFS_H_ #define _VMCI_CALL_DEFS_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKMOD #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_DISTRIBUTE #include "includeCheck.h" #include "vm_basic_types.h" #include "vmci_defs.h" /* * All structs here are an integral size of their largest member, ie. a struct * with at least one 8-byte member will have a size that is an integral of 8. * A struct which has a largest member of size 4 will have a size that is an * integral of 4. This is because Windows CL enforces this rule. 32 bit gcc * doesn't e.g. 32 bit gcc can misalign an 8 byte member if it is preceeded by * a 4 byte member. */ /* * Base struct for vmci datagrams. */ typedef struct VMCIDatagram { VMCIHandle dst; VMCIHandle src; uint64 payloadSize; } VMCIDatagram; /* * Second flag is for creating a well-known handle instead of a per context * handle. Next flag is for deferring datagram delivery, so that the * datagram callback is invoked in a delayed context (not interrupt context). */ #define VMCI_FLAG_DG_NONE 0 #define VMCI_FLAG_WELLKNOWN_DG_HND 0x1 #define VMCI_FLAG_ANYCID_DG_HND 0x2 #define VMCI_FLAG_DG_DELAYED_CB 0x4 /* Event callback should fire in a delayed context (not interrupt context.) */ #define VMCI_FLAG_EVENT_NONE 0 #define VMCI_FLAG_EVENT_DELAYED_CB 0x1 /* * Maximum supported size of a VMCI datagram for routable datagrams. * Datagrams going to the hypervisor are allowed to be larger. */ #define VMCI_MAX_DG_SIZE (17 * 4096) #define VMCI_MAX_DG_PAYLOAD_SIZE (VMCI_MAX_DG_SIZE - sizeof(VMCIDatagram)) #define VMCI_DG_PAYLOAD(_dg) (void *)((char *)(_dg) + sizeof(VMCIDatagram)) #define VMCI_DG_HEADERSIZE sizeof(VMCIDatagram) #define VMCI_DG_SIZE(_dg) (VMCI_DG_HEADERSIZE + (size_t)(_dg)->payloadSize) #define VMCI_DG_SIZE_ALIGNED(_dg) ((VMCI_DG_SIZE(_dg) + 7) & (size_t)CONST64U(0xfffffffffffffff8)) #define VMCI_MAX_DATAGRAM_QUEUE_SIZE (VMCI_MAX_DG_SIZE * 2) /* * We allow at least 1024 more event datagrams from the hypervisor past the * normally allowed datagrams pending for a given context. We define this * limit on event datagrams from the hypervisor to guard against DoS attack * from a malicious VM which could repeatedly attach to and detach from a queue * pair, causing events to be queued at the destination VM. However, the rate * at which such events can be generated is small since it requires a VM exit * and handling of queue pair attach/detach call at the hypervisor. Event * datagrams may be queued up at the destination VM if it has interrupts * disabled or if it is not draining events for some other reason. 1024 * datagrams is a grossly conservative estimate of the time for which * interrupts may be disabled in the destination VM, but at the same time does * not exacerbate the memory pressure problem on the host by much (size of each * event datagram is small). */ #define VMCI_MAX_DATAGRAM_AND_EVENT_QUEUE_SIZE \ (VMCI_MAX_DATAGRAM_QUEUE_SIZE + \ 1024 * (sizeof(VMCIDatagram) + sizeof(VMCIEventData_Max))) /* * Struct for sending VMCI_DATAGRAM_REQUEST_MAP and * VMCI_DATAGRAM_REMOVE_MAP datagrams. Struct size is 32 bytes. All * fields in struct are aligned to their natural alignment. These * datagrams are obsoleted by the removal of VM to VM communication. */ typedef struct VMCIDatagramWellKnownMapMsg { VMCIDatagram hdr; VMCIId wellKnownID; uint32 _pad; } VMCIDatagramWellKnownMapMsg; /* * Struct used for querying, via VMCI_RESOURCES_QUERY, the availability of * hypervisor resources. * Struct size is 16 bytes. All fields in struct are aligned to their natural * alignment. */ typedef struct VMCIResourcesQueryHdr { VMCIDatagram hdr; uint32 numResources; uint32 _padding; } VMCIResourcesQueryHdr; /* * Convenience struct for negotiating vectors. Must match layout of * VMCIResourceQueryHdr minus the VMCIDatagram header. */ typedef struct VMCIResourcesQueryMsg { uint32 numResources; uint32 _padding; VMCI_Resource resources[1]; } VMCIResourcesQueryMsg; /* * The maximum number of resources that can be queried using * VMCI_RESOURCE_QUERY is 31, as the result is encoded in the lower 31 * bits of a positive return value. Negative values are reserved for * errors. */ #define VMCI_RESOURCE_QUERY_MAX_NUM 31 /* Maximum size for the VMCI_RESOURCE_QUERY request. */ #define VMCI_RESOURCE_QUERY_MAX_SIZE sizeof(VMCIResourcesQueryHdr) \ + VMCI_RESOURCE_QUERY_MAX_NUM * sizeof(VMCI_Resource) /* * Struct used for setting the notification bitmap. All fields in * struct are aligned to their natural alignment. */ typedef struct VMCINotifyBitmapSetMsg { VMCIDatagram hdr; PPN bitmapPPN; uint32 _pad; } VMCINotifyBitmapSetMsg; /* * Struct used for linking a doorbell handle with an index in the * notify bitmap. All fields in struct are aligned to their natural * alignment. */ typedef struct VMCIDoorbellLinkMsg { VMCIDatagram hdr; VMCIHandle handle; uint64 notifyIdx; } VMCIDoorbellLinkMsg; /* * Struct used for unlinking a doorbell handle from an index in the * notify bitmap. All fields in struct are aligned to their natural * alignment. */ typedef struct VMCIDoorbellUnlinkMsg { VMCIDatagram hdr; VMCIHandle handle; } VMCIDoorbellUnlinkMsg; /* * Struct used for generating a notification on a doorbell handle. All * fields in struct are aligned to their natural alignment. */ typedef struct VMCIDoorbellNotifyMsg { VMCIDatagram hdr; VMCIHandle handle; } VMCIDoorbellNotifyMsg; /* * This struct is used to contain data for events. Size of this struct is a * multiple of 8 bytes, and all fields are aligned to their natural alignment. */ typedef struct VMCI_EventData { VMCI_Event event; /* 4 bytes. */ uint32 _pad; /* * Event payload is put here. */ } VMCI_EventData; /* Callback needed for correctly waiting on events. */ typedef int (*VMCIDatagramRecvCB)(void *clientData, // IN: client data for handler VMCIDatagram *msg); // IN: /* * We use the following inline function to access the payload data associated * with an event data. */ static INLINE void * VMCIEventDataPayload(VMCI_EventData *evData) // IN: { return (void *)((char *)evData + sizeof *evData); } /* * Define the different VMCI_EVENT payload data types here. All structs must * be a multiple of 8 bytes, and fields must be aligned to their natural * alignment. */ typedef struct VMCIEventPayload_Context { VMCIId contextID; /* 4 bytes. */ uint32 _pad; } VMCIEventPayload_Context; typedef struct VMCIEventPayload_QP { VMCIHandle handle; /* QueuePair handle. */ VMCIId peerId; /* Context id of attaching/detaching VM. */ uint32 _pad; } VMCIEventPayload_QP; /* * We define the following struct to get the size of the maximum event data * the hypervisor may send to the guest. If adding a new event payload type * above, add it to the following struct too (inside the union). */ typedef struct VMCIEventData_Max { VMCI_EventData eventData; union { VMCIEventPayload_Context contextPayload; VMCIEventPayload_QP qpPayload; } evDataPayload; } VMCIEventData_Max; /* * Struct used for VMCI_EVENT_SUBSCRIBE/UNSUBSCRIBE and VMCI_EVENT_HANDLER * messages. Struct size is 32 bytes. All fields in struct are aligned to * their natural alignment. */ typedef struct VMCIEventMsg { VMCIDatagram hdr; VMCI_EventData eventData; /* Has event type and payload. */ /* * Payload gets put here. */ } VMCIEventMsg; /* * We use the following inline function to access the payload data associated * with an event message. */ static INLINE void * VMCIEventMsgPayload(VMCIEventMsg *eMsg) // IN: { return VMCIEventDataPayload(&eMsg->eventData); } /* Flags for VMCI QueuePair API. */ #define VMCI_QPFLAG_ATTACH_ONLY 0x1 /* Fail alloc if QP not created by peer. */ #define VMCI_QPFLAG_LOCAL 0x2 /* Only allow attaches from local context. */ #define VMCI_QPFLAG_NONBLOCK 0x4 /* Host won't block when guest is quiesced. */ #define VMCI_QPFLAG_PINNED 0x8 /* Keep all data pages pinned. This flag */ /* must be combined with NONBLOCK. */ /* For asymmetric queuepairs, update as new flags are added. */ #define VMCI_QP_ASYMM (VMCI_QPFLAG_NONBLOCK | VMCI_QPFLAG_PINNED) #define VMCI_QP_ASYMM_PEER (VMCI_QPFLAG_ATTACH_ONLY | VMCI_QP_ASYMM) /* Update the following (bitwise OR flags) while adding new flags. */ #define VMCI_QP_ALL_FLAGS (VMCI_QPFLAG_ATTACH_ONLY | VMCI_QPFLAG_LOCAL | \ VMCI_QPFLAG_NONBLOCK | VMCI_QPFLAG_PINNED) /* * Structs used for QueuePair alloc and detach messages. We align fields of * these structs to 64bit boundaries. */ typedef struct VMCIQueuePairAllocMsg { VMCIDatagram hdr; VMCIHandle handle; VMCIId peer; /* 32bit field. */ uint32 flags; uint64 produceSize; uint64 consumeSize; uint64 numPPNs; /* List of PPNs placed here. */ } VMCIQueuePairAllocMsg; typedef struct VMCIQueuePairDetachMsg { VMCIDatagram hdr; VMCIHandle handle; } VMCIQueuePairDetachMsg; #endif open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_spinlock.h0000644765153500003110000000337712220061556023064 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_SPINLOCK_H__ # define __COMPAT_SPINLOCK_H__ #include /* * Preempt support was added during 2.5.x development cycle, and later * it was backported to 2.4.x. In 2.4.x backport these definitions * live in linux/spinlock.h, that's why we put them here (in 2.6.x they * are defined in linux/preempt.h which is included by linux/spinlock.h). */ #ifdef CONFIG_PREEMPT #define compat_preempt_disable() preempt_disable() #define compat_preempt_enable() preempt_enable() #else #define compat_preempt_disable() do { } while (0) #define compat_preempt_enable() do { } while (0) #endif /* Some older kernels - 2.6.10 and earlier - lack DEFINE_SPINLOCK */ #ifndef DEFINE_SPINLOCK #define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED #endif /* Same goes for DEFINE_RWLOCK */ #ifndef DEFINE_RWLOCK #define DEFINE_RWLOCK(x) rwlock_t x = RW_LOCK_UNLOCKED #endif #endif /* __COMPAT_SPINLOCK_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_string.h0000644765153500003110000000356312220061556022545 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_STRING_H__ # define __COMPAT_STRING_H__ #include /* * kstrdup was born in 2.6.13. This implementation is almost identical to the * one found there. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) #define compat_kstrdup(s, gfp) kstrdup(s, gfp) #else #define compat_kstrdup(s, gfp) \ ({ \ size_t len; \ char *buf; \ len = strlen(s) + 1; \ buf = kmalloc(len, gfp); \ memcpy(buf, s, len); \ buf; \ }) #endif #endif /* __COMPAT_STRING_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_mutex.h0000644765153500003110000000347512220061556022403 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_MUTEX_H__ # define __COMPAT_MUTEX_H__ /* Blocking mutexes were introduced in 2.6.16. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) #include "compat_semaphore.h" typedef struct semaphore compat_mutex_t; # define compat_define_mutex(_mx) DECLARE_MUTEX(_mx) # define compat_mutex_init(_mx) init_MUTEX(_mx) # define compat_mutex_lock(_mx) down(_mx) # define compat_mutex_lock_interruptible(_mx) down_interruptible(_mx) # define compat_mutex_unlock(_mx) up(_mx) #else #include typedef struct mutex compat_mutex_t; # define compat_define_mutex(_mx) DEFINE_MUTEX(_mx) # define compat_mutex_init(_mx) mutex_init(_mx) # define compat_mutex_lock(_mx) mutex_lock(_mx) # define compat_mutex_lock_interruptible(_mx) mutex_lock_interruptible(_mx) # define compat_mutex_unlock(_mx) mutex_unlock(_mx) #endif #endif /* __COMPAT_MUTEX_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_pgtable.h0000644765153500003110000001104412220061556022646 0ustar dtormts/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_PGTABLE_H__ # define __COMPAT_PGTABLE_H__ #if defined(CONFIG_PARAVIRT) && defined(CONFIG_HIGHPTE) # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21) # include # undef paravirt_map_pt_hook # define paravirt_map_pt_hook(type, va, pfn) do {} while (0) # endif #endif #include /* pte_page() API modified in 2.3.23 to return a struct page * --hpreg */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 23) # define compat_pte_page pte_page #else # include "compat_page.h" # define compat_pte_page(_pte) virt_to_page(pte_page(_pte)) #endif /* Appeared in 2.5.5 --hpreg */ #ifndef pte_offset_map /* Appeared in SuSE 8.0's 2.4.18 --hpreg */ # ifdef pte_offset_atomic # define pte_offset_map pte_offset_atomic # define pte_unmap pte_kunmap # else # define pte_offset_map pte_offset # define pte_unmap(_pte) # endif #endif /* Appeared in 2.5.74-mmX --petr */ #ifndef pmd_offset_map # define pmd_offset_map(pgd, address) pmd_offset(pgd, address) # define pmd_unmap(pmd) #endif /* * Appeared in 2.6.10-rc2-mm1. Older kernels did L4 page tables as * part of pgd_offset, or they did not have L4 page tables at all. * In 2.6.11 pml4 -> pgd -> pmd -> pte hierarchy was replaced by * pgd -> pud -> pmd -> pte hierarchy. */ #ifdef PUD_MASK # define compat_pgd_offset(mm, address) pgd_offset(mm, address) # define compat_pgd_present(pgd) pgd_present(pgd) # define compat_pud_offset(pgd, address) pud_offset(pgd, address) # define compat_pud_present(pud) pud_present(pud) typedef pgd_t compat_pgd_t; typedef pud_t compat_pud_t; #elif defined(pml4_offset) # define compat_pgd_offset(mm, address) pml4_offset(mm, address) # define compat_pgd_present(pml4) pml4_present(pml4) # define compat_pud_offset(pml4, address) pml4_pgd_offset(pml4, address) # define compat_pud_present(pgd) pgd_present(pgd) typedef pml4_t compat_pgd_t; typedef pgd_t compat_pud_t; #else # define compat_pgd_offset(mm, address) pgd_offset(mm, address) # define compat_pgd_present(pgd) pgd_present(pgd) # define compat_pud_offset(pgd, address) (pgd) # define compat_pud_present(pud) (1) typedef pgd_t compat_pgd_t; typedef pgd_t compat_pud_t; #endif #define compat_pgd_offset_k(mm, address) pgd_offset_k(address) /* Introduced somewhere in 2.6.0, + backported to some 2.4 RedHat kernels */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) && !defined(pte_pfn) # define pte_pfn(pte) page_to_pfn(compat_pte_page(pte)) #endif /* A page_table_lock field is added to struct mm_struct in 2.3.10 --hpreg */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 10) # define compat_get_page_table_lock(_mm) (&(_mm)->page_table_lock) #else # define compat_get_page_table_lock(_mm) NULL #endif /* * Define VM_PAGE_KERNEL_EXEC for vmapping executable pages. * * On ia32 PAGE_KERNEL_EXEC was introduced in 2.6.8.1. Unfortunately it accesses * __PAGE_KERNEL_EXEC which is not exported for modules. So we use * __PAGE_KERNEL and just cut _PAGE_NX bit from it. * * For ia32 kernels before 2.6.8.1 we use PAGE_KERNEL directly, these kernels * do not have noexec support. * * On x86-64 situation is a bit better: they always supported noexec, but * before 2.6.8.1 flag was named PAGE_KERNEL_EXECUTABLE, and it was renamed * to PAGE_KERNEL_EXEC when ia32 got noexec too (see above). */ #ifdef CONFIG_X86 #ifdef _PAGE_NX #define VM_PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL & ~_PAGE_NX) #else #define VM_PAGE_KERNEL_EXEC PAGE_KERNEL #endif #else #ifdef PAGE_KERNEL_EXECUTABLE #define VM_PAGE_KERNEL_EXEC PAGE_KERNEL_EXECUTABLE #else #define VM_PAGE_KERNEL_EXEC PAGE_KERNEL_EXEC #endif #endif #endif /* __COMPAT_PGTABLE_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_autoconf.h0000644765153500003110000000264112220061556023051 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_AUTOCONF_H__ # define __COMPAT_AUTOCONF_H__ #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_DISTRIBUTE #define INCLUDE_ALLOW_VMKDRIVERS #include "includeCheck.h" #ifndef LINUX_VERSION_CODE # error "Include compat_version.h before compat_autoconf.h" #endif /* autoconf.h moved from linux/autoconf.h to generated/autoconf.h in 2.6.33-rc1. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) # include #else # include #endif #endif /* __COMPAT_AUTOCONF_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_netdevice.h0000644765153500003110000002374412220061556023210 0ustar dtormts/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_NETDEVICE_H__ # define __COMPAT_NETDEVICE_H__ #include #include #include #include #include /* * The enet_statistics structure moved from linux/if_ether.h to * linux/netdevice.h and is renamed net_device_stats in 2.1.25 --hpreg */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 1, 25) # include # define net_device_stats enet_statistics #endif /* The netif_rx_ni() API appeared in 2.4.8 --hpreg */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 8) # define netif_rx_ni netif_rx #endif /* The device struct was renamed net_device in 2.3.14 --hpreg */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 14) # define net_device device #endif /* * SET_MODULE_OWNER appeared sometime during 2.3.x. It was setting * dev->owner = THIS_MODULE until 2.5.70, where netdevice refcounting * was completely changed. SET_MODULE_OWNER was nop for whole * 2.6.x series, and finally disappeared in 2.6.24. * * MOD_xxx_USE_COUNT wrappers are here, as they must be mutually * exclusive with SET_MODULE_OWNER call. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) # define COMPAT_SET_MODULE_OWNER(dev) do {} while (0) # define COMPAT_NETDEV_MOD_INC_USE_COUNT MOD_INC_USE_COUNT # define COMPAT_NETDEV_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT #else # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) # define COMPAT_SET_MODULE_OWNER(dev) SET_MODULE_OWNER(dev) # else # define COMPAT_SET_MODULE_OWNER(dev) do {} while (0) # endif # define COMPAT_NETDEV_MOD_INC_USE_COUNT do {} while (0) # define COMPAT_NETDEV_MOD_DEC_USE_COUNT do {} while (0) #endif /* * SET_NETDEV_DEV appeared sometime during 2.5.x, and later was * crossported to various 2.4.x kernels (as dummy macro). */ #ifdef SET_NETDEV_DEV # define COMPAT_SET_NETDEV_DEV(dev, pdev) SET_NETDEV_DEV(dev, pdev) #else # define COMPAT_SET_NETDEV_DEV(dev, pdev) do {} while (0) #endif /* * Build alloc_etherdev API on the top of init_etherdev. For 2.0.x kernels * we must provide dummy init method, otherwise register_netdev does * nothing. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3) #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0) int vmware_dummy_init(struct net_device *dev) { return 0; } #endif static inline struct net_device* compat_alloc_etherdev(int priv_size) { struct net_device* dev; int size = sizeof *dev + priv_size; /* * The name is dynamically allocated before 2.4.0, but * is an embedded array in later kernels. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) size += sizeof("ethXXXXXXX"); #endif dev = kmalloc(size, GFP_KERNEL); if (dev) { memset(dev, 0, size); if (priv_size) { dev->priv = dev + 1; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) dev->name = (char *)(dev + 1) + priv_size; #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0) dev->init = vmware_dummy_init; #endif if (init_etherdev(dev, 0) != dev) { kfree(dev); dev = NULL; } } return dev; } #else #define compat_alloc_etherdev(sz) alloc_etherdev(sz) #endif /* * alloc_netdev and free_netdev are there since 2.4.23. Their use is mandatory * since 2.6.24. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 23) static inline struct net_device * compat_alloc_netdev(int priv_size, const char *mask, void (*setup)(struct net_device *)) { struct net_device *dev; int netdev_size = sizeof *dev; int alloc_size; # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) netdev_size += IFNAMSIZ; # endif alloc_size = netdev_size + priv_size; dev = kmalloc(alloc_size, GFP_KERNEL); if (dev) { memset(dev, 0, alloc_size); dev->priv = (char*)dev + netdev_size; setup(dev); # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) dev->name = (char*)(dev + 1); # endif strcpy(dev->name, mask); } return dev; } # define compat_free_netdev(dev) kfree(dev) #else # define compat_alloc_netdev(size, mask, setup) alloc_netdev(size, mask, setup) # define compat_free_netdev(dev) free_netdev(dev) #endif /* netdev_priv() appeared in 2.6.3 */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 3) # define compat_netdev_priv(netdev) (netdev)->priv #else # define compat_netdev_priv(netdev) netdev_priv(netdev) #endif /* * In 3.1 merge window feature maros were removed from mainline, * so let's add back ones we care about. */ #if !defined(HAVE_NET_DEVICE_OPS) && \ LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) # define HAVE_NET_DEVICE_OPS 1 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9) # define COMPAT_NETDEV_TX_OK NETDEV_TX_OK # define COMPAT_NETDEV_TX_BUSY NETDEV_TX_BUSY #else # define COMPAT_NETDEV_TX_OK 0 # define COMPAT_NETDEV_TX_BUSY 1 #endif /* unregister_netdevice_notifier was not safe prior to 2.6.17 */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17) && \ !defined(ATOMIC_NOTIFIER_INIT) /* pre 2.6.17 and not patched */ static inline int compat_unregister_netdevice_notifier(struct notifier_block *nb) { int err; rtnl_lock(); err = unregister_netdevice_notifier(nb); rtnl_unlock(); return err; } #else /* post 2.6.17 or patched */ #define compat_unregister_netdevice_notifier(_nb) \ unregister_netdevice_notifier(_nb); #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) || defined(__VMKLNX__) # define compat_netif_napi_add(dev, napi, poll, quota) \ netif_napi_add(dev, napi, poll, quota) # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) || \ defined VMW_NETIF_SINGLE_NAPI_PARM # define compat_napi_complete(dev, napi) napi_complete(napi) # define compat_napi_schedule(dev, napi) napi_schedule(napi) # else # define compat_napi_complete(dev, napi) netif_rx_complete(dev, napi) # define compat_napi_schedule(dev, napi) netif_rx_schedule(dev, napi) # endif # define compat_napi_enable(dev, napi) napi_enable(napi) # define compat_napi_disable(dev, napi) napi_disable(napi) #else # define compat_napi_complete(dev, napi) netif_rx_complete(dev) # define compat_napi_schedule(dev, napi) netif_rx_schedule(dev) # define compat_napi_enable(dev, napi) netif_poll_enable(dev) # define compat_napi_disable(dev, napi) netif_poll_disable(dev) /* RedHat ported GRO to 2.6.18 bringing new napi_struct with it */ # if defined NETIF_F_GRO # define compat_netif_napi_add(netdev, napi, pollcb, quota) \ do { \ (netdev)->poll = (pollcb); \ (netdev)->weight = (quota);\ (napi)->dev = (netdev); \ } while (0) # else struct napi_struct { int dummy; }; # define compat_netif_napi_add(dev, napi, pollcb, quota) \ do { \ (dev)->poll = (pollcb); \ (dev)->weight = (quota);\ } while (0) # endif #endif #ifdef NETIF_F_TSO6 # define COMPAT_NETIF_F_TSO (NETIF_F_TSO6 | NETIF_F_TSO) #else # define COMPAT_NETIF_F_TSO (NETIF_F_TSO) #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) # define compat_netif_tx_lock(dev) netif_tx_lock(dev) # define compat_netif_tx_unlock(dev) netif_tx_unlock(dev) #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) # define compat_netif_tx_lock(dev) spin_lock(&dev->xmit_lock) # define compat_netif_tx_unlock(dev) spin_unlock(&dev->xmit_lock) #else /* Vendor backporting (SLES 10) has muddled the tx_lock situation. Pick whichever * of the above works for you. */ # define compat_netif_tx_lock(dev) do {} while (0) # define compat_netif_tx_unlock(dev) do {} while (0) #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) # define COMPAT_VLAN_GROUP_ARRAY_LEN VLAN_N_VID # define compat_flush_scheduled_work(work) cancel_work_sync(work) #else # define COMPAT_VLAN_GROUP_ARRAY_LEN VLAN_GROUP_ARRAY_LEN # define compat_flush_scheduled_work(work) flush_scheduled_work() #endif /* * For kernel versions older than 2.6.29, where pci_msi_enabled is not * available, check if * 1. CONFIG_PCI_MSI is present * 2. kernel version is newer than 2.6.25 (because multiqueue is not * supporter) in kernels older than that) * 3. msi can be enabled. If it fails it means that MSI is not available. * When all the above are true, return non-zero so that multiple queues will be * allowed in the driver. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) # define compat_multiqueue_allowed(dev) pci_msi_enabled() #else # if defined CONFIG_PCI_MSI && LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25) static inline int compat_multiqueue_allowed(struct pci_dev *dev) { int ret; if (!pci_enable_msi(dev)) ret = 1; else ret = 0; pci_disable_msi(dev); return ret; } # else # define compat_multiqueue_allowed(dev) (0) # endif #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) # define compat_vlan_get_protocol(skb) vlan_get_protocol(skb) #else # define compat_vlan_get_protocol(skb) (skb->protocol) #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0) typedef netdev_features_t compat_netdev_features_t; #else typedef u32 compat_netdev_features_t; #endif #endif /* __COMPAT_NETDEVICE_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_cred.h0000644765153500003110000000301312220061556022142 0ustar dtormts/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_CRED_H__ # define __COMPAT_CRED_H__ /* * Include linux/cred.h via linux/sched.h - it is not nice, but * as cpp does not have #ifexist... */ #include #if !defined(current_fsuid) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) #define current_uid() (current->uid) #define current_euid() (current->euid) #define current_fsuid() (current->fsuid) #define current_gid() (current->gid) #define current_egid() (current->egid) #define current_fsgid() (current->fsgid) #endif #if !defined(cap_set_full) /* cap_set_full was removed in kernel version 3.0-rc4. */ #define cap_set_full(_c) do { (_c) = CAP_FULL_SET; } while (0) #endif #endif /* __COMPAT_CRED_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/autoconf/0000755765153500003110000000000012220061556021332 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/linux/shared/autoconf/cachector1.c0000644765153500003110000000307512220061556023517 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #include "compat_version.h" #include "compat_autoconf.h" /* * Between 2.6.27-rc1 and 2.6.27-rc2 ctor prototype was changed from * ctor(cache, ptr) to ctor(ptr). Unfortunately there * is no typedef for ctor, so we have to redefine kmem_cache_create * to find out ctor prototype. If prototype matches, then this is old * kernel. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) #error "This test intentionally fails on 2.6.28 and newer kernels." #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) #include struct kmem_cache *kmem_cache_create(const char *, size_t, size_t, unsigned long, void (*)(struct kmem_cache *, void *)); #endif open-vm-tools-9.4.0-1280544/modules/linux/shared/autoconf/filldir1.c0000644765153500003110000000326012220061556023205 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #include "compat_version.h" #include "compat_autoconf.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) #include #include /* loff_t */ #include /* NULL */ /* * After 2.6.18, filldir and statfs were changed to send 64-bit inode * numbers to user space. Red Hat backported this behavior into a 2.6.17 * kernel. * * This test will fail on a kernel with such a patch. */ static int LinuxDriverFilldir(void *buf, const char *name, int namelen, loff_t offset, ino_t ino, unsigned int d_type) { return 0; } void test(void) { vfs_readdir(NULL, LinuxDriverFilldir, NULL); } #else #error "This test intentionally fails on 2.6.20 and newer kernels." #endif open-vm-tools-9.4.0-1280544/modules/linux/shared/autoconf/file_operations_fsync.c0000644765153500003110000000274612220061556026073 0ustar dtormts/********************************************************* * Copyright (C) 2011 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * Linux v3.1 added 2 params to fsync for fine-grained locking control. * But SLES11 SP2 has backported the change to its 3.0 kernel, * so we can't rely solely on kernel version to determine number of * arguments. */ #include "compat_version.h" #include "compat_autoconf.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0) # error This compile test intentionally fails. #else #include #include /* loff_t */ static int TestFsync(struct file *file, loff_t start, loff_t end, int datasync) { return 0; } struct file_operations testFO = { .fsync = TestFsync, }; #endif open-vm-tools-9.4.0-1280544/modules/linux/shared/autoconf/netcreate_num_params.c0000644765153500003110000000316012220061556025672 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * During 2.6.33 merge window net_proto_ops->create() method was changed - * a new 'kern' field, signalling whether socket is being created by kernel * or userspace application, was added to it. Unfortunately, some * distributions, such as RHEL 6, have backported the change to earlier * kernels, so we can't rely solely on kernel version to determine number of * arguments. */ #include "compat_version.h" #include "compat_autoconf.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) # error This compile test intentionally fails. #else #include static int TestCreate(struct net *net, struct socket *sock, int protocol, int kern) { return 0; } struct net_proto_family testFamily = { .create = TestCreate, }; #endif open-vm-tools-9.4.0-1280544/modules/linux/shared/autoconf/cachector.c0000644765153500003110000000327012220061556023433 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #include "compat_version.h" #include "compat_autoconf.h" /* * Between 2.6.23 and 2.6.24-rc1 ctor prototype was changed from * ctor(ptr, cache, flags) to ctor(cache, ptr). Unfortunately there * is no typedef for ctor, so we have to redefine kmem_cache_create * to find out ctor prototype. This assumes that kmem_cache_create * takes 5 arguments and not 6 - that change occured between * 2.6.22 and 2.6.23-rc1. If prototype matches, then this is old * kernel. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) #error "This test intentionally fails on 2.6.24 and newer kernels." #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) #include struct kmem_cache *kmem_cache_create(const char *, size_t, size_t, unsigned long, void (*)(void *, struct kmem_cache *, unsigned long)); #endif open-vm-tools-9.4.0-1280544/modules/linux/shared/autoconf/inode1.c0000644765153500003110000000270312220061556022657 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #include "compat_version.h" #include "compat_autoconf.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) #include #include /* NULL */ /* * After 2.6.18, inodes were "slimmed". This involved removing the union * that encapsulates inode private data (and using i_private instead), as well * as removing i_blksize. Red Hat backported this behavior into a 2.6.17 * kernel. * * This test will fail on a kernel with such a patch. */ void test(void) { struct inode inode; inode.u.generic_ip = NULL; } #else #error "This test intentionally fails on 2.6.20 and newer kernels." #endif open-vm-tools-9.4.0-1280544/modules/linux/shared/autoconf/cachecreate.c0000644765153500003110000000321012220061556023721 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #include "compat_version.h" #include "compat_autoconf.h" /* * All kernels before 2.6.22 take 6 arguments. All kernels since * 2.6.23-rc1 take 5 arguments. Only kernels between 2.6.22 and * 2.6.23-rc1 are questionable - we could ignore them if we wanted, * nobody cares about them even now. But unfortunately RedHat is * re-releasing 2.6.X-rc kernels under 2.6.(X-1) name, so they * are releasing 2.6.23-rc1 as 2.6.22-5055-something, so we have * to do autodetection for them. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) /* Success... */ #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) #error "This test intentionally fails on 2.6.23 and newer kernels." #else #include struct kmem_cache *kmemtest(void) { return kmem_cache_create("test", 12, 0, 0, NULL, NULL); } #endif open-vm-tools-9.4.0-1280544/modules/linux/shared/autoconf/skblin.c0000644765153500003110000000257212220061556022766 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * Detect whether skb_linearize takes one or two arguments. */ #include "compat_version.h" #include "compat_autoconf.h" #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 17) /* * Since 2.6.18 all kernels have single-argument skb_linearize. For * older kernels use autodetection. Not using autodetection on newer * kernels saves us from compile failure on some post 2.6.18 kernels * which do not have selfcontained skbuff.h. */ #include int test_skb_linearize(struct sk_buff *skb) { return skb_linearize(skb); } #endif open-vm-tools-9.4.0-1280544/modules/linux/shared/autoconf/geninclude.c0000644765153500003110000000232112220061556023611 0ustar dtormts/********************************************************* * Copyright (C) 2003 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #include "compat_version.h" #include "compat_autoconf.h" #ifdef CONFIG_X86_VOYAGER APATH/mach-voyager #endif #ifdef CONFIG_X86_VISWS APATH/mach-visws #endif #ifdef CONFIG_X86_NUMAQ APATH/mach-numaq #endif #ifdef CONFIG_X86_BIGSMP APATH/mach-bigsmp #endif #ifdef CONFIG_X86_SUMMIT APATH/mach-summit #endif #ifdef CONFIG_X86_GENERICARCH APATH/mach-generic #endif APATH/mach-default open-vm-tools-9.4.0-1280544/modules/linux/shared/autoconf/getsb1.c0000644765153500003110000000307612220061556022671 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #include "compat_version.h" #include "compat_autoconf.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) #include /* * Around 2.6.18, a pointer to a vfsmount was added to get_sb. Red Hat * backported this behavior into a 2.6.17 kernel. * * This test will fail on a kernel with such a patch. */ static struct super_block * LinuxDriverGetSb(struct file_system_type *fs_type, int flags, const char *dev_name, void *rawData) { return 0; } struct file_system_type fs_type = { .get_sb = LinuxDriverGetSb }; #else #error "This test intentionally fails on 2.6.19 or newer kernels." #endif open-vm-tools-9.4.0-1280544/modules/linux/shared/autoconf/netif_num_params.c0000644765153500003110000000335212220061556025030 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * Detect whether netif_rx_complete (and netif_rx_schedule) take a single * napi_struct argument. The foundation was laid whith introducing Generic * Receive Offload infrastructure but dropping unneeded net_device argument * did not happen till few commits later so we can't simply test for presence * of NETIF_F_GRO. * * Test succeeds if netif_rx_complete takes dev & napi arguments, or if it * takes dev argument only (kernels before 2.6.24). Test fails if netif_rx_complete * takes only single napi argument. */ #include "compat_version.h" #include "compat_autoconf.h" #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) # error This compile test intentionally fails. #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) #include #ifdef NETIF_F_GRO void test_netif_rx_complete(struct net_device *dev, struct napi_struct *napi) { netif_rx_complete(dev, napi); } #endif #endif open-vm-tools-9.4.0-1280544/modules/linux/shared/autoconf/statfs1.c0000644765153500003110000000267112220061556023071 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #include "compat_version.h" #include "compat_autoconf.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) #include /* * Around 2.6.18, the super_block pointer in statfs was changed to a dentry * pointer. Red Hat backported this behavior into a 2.6.17 kernel. * * This test will fail on a kernel with such a patch. */ static int LinuxDriverStatFs(struct super_block *sb, struct kstatfs *stat) { return 0; } struct super_operations super_ops = { .statfs = LinuxDriverStatFs }; #else #error "This test intentionally fails on 2.6.19 and newer kernels." #endif open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_skbuff.h0000644765153500003110000001557512220061556022525 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_SKBUFF_H__ # define __COMPAT_SKBUFF_H__ #include /* * When transition from mac/nh/h to skb_* accessors was made, also SKB_WITH_OVERHEAD * was introduced. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) || \ (LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 21) && defined(SKB_WITH_OVERHEAD)) #define compat_skb_mac_header(skb) skb_mac_header(skb) #define compat_skb_network_header(skb) skb_network_header(skb) #define compat_skb_network_offset(skb) skb_network_offset(skb) #define compat_skb_transport_header(skb) skb_transport_header(skb) #define compat_skb_transport_offset(skb) skb_transport_offset(skb) #define compat_skb_network_header_len(skb) skb_network_header_len(skb) #define compat_skb_tail_pointer(skb) skb_tail_pointer(skb) #define compat_skb_end_pointer(skb) skb_end_pointer(skb) #define compat_skb_ip_header(skb) ((struct iphdr *)skb_network_header(skb)) #define compat_skb_ipv6_header(skb) ((struct ipv6hdr *)skb_network_header(skb)) #define compat_skb_tcp_header(skb) ((struct tcphdr *)skb_transport_header(skb)) #define compat_skb_reset_mac_header(skb) skb_reset_mac_header(skb) #define compat_skb_reset_network_header(skb) skb_reset_network_header(skb) #define compat_skb_reset_transport_header(skb) skb_reset_transport_header(skb) #define compat_skb_set_network_header(skb, off) skb_set_network_header(skb, off) #define compat_skb_set_transport_header(skb, off) skb_set_transport_header(skb, off) #else #define compat_skb_mac_header(skb) (skb)->mac.raw #define compat_skb_network_header(skb) (skb)->nh.raw #define compat_skb_network_offset(skb) ((skb)->nh.raw - (skb)->data) #define compat_skb_transport_header(skb) (skb)->h.raw #define compat_skb_transport_offset(skb) ((skb)->h.raw - (skb)->data) #define compat_skb_network_header_len(skb) ((skb)->h.raw - (skb)->nh.raw) #define compat_skb_tail_pointer(skb) (skb)->tail #define compat_skb_end_pointer(skb) (skb)->end #define compat_skb_ip_header(skb) (skb)->nh.iph #define compat_skb_ipv6_header(skb) (skb)->nh.ipv6h #define compat_skb_tcp_header(skb) (skb)->h.th #define compat_skb_reset_mac_header(skb) ((skb)->mac.raw = (skb)->data) #define compat_skb_reset_network_header(skb) ((skb)->nh.raw = (skb)->data) #define compat_skb_reset_transport_header(skb) ((skb)->h.raw = (skb)->data) #define compat_skb_set_network_header(skb, off) ((skb)->nh.raw = (skb)->data + (off)) #define compat_skb_set_transport_header(skb, off) ((skb)->h.raw = (skb)->data + (off)) #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) || defined(VMW_SKB_LINEARIZE_2618) # define compat_skb_linearize(skb) skb_linearize((skb)) #else # if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 0) # define compat_skb_linearize(skb) __skb_linearize((skb), GFP_ATOMIC) # elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 4) # define compat_skb_linearize(skb) skb_linearize((skb), GFP_ATOMIC) # else static inline int compat_skb_linearize(struct sk_buff *skb) { return 0; } # endif #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) #define compat_skb_csum_offset(skb) (skb)->csum_offset #else #define compat_skb_csum_offset(skb) (skb)->csum #endif /* * Note that compat_skb_csum_start() has semantic different from kernel's csum_start: * kernel's skb->csum_start is offset between start of checksummed area and start of * complete skb buffer, while our compat_skb_csum_start(skb) is offset from start * of packet itself. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) #define compat_skb_csum_start(skb) ((skb)->csum_start - skb_headroom(skb)) #else #define compat_skb_csum_start(skb) compat_skb_transport_offset(skb) #endif #if defined(NETIF_F_GSO) /* 2.6.18 and upwards */ #define compat_skb_mss(skb) (skb_shinfo(skb)->gso_size) #else #define compat_skb_mss(skb) (skb_shinfo(skb)->tso_size) #endif /* used by both received pkts and outgoing ones */ #define VM_CHECKSUM_UNNECESSARY CHECKSUM_UNNECESSARY /* csum status of received pkts */ #if defined(CHECKSUM_COMPLETE) # define VM_RX_CHECKSUM_PARTIAL CHECKSUM_COMPLETE #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) && defined(CHECKSUM_HW) # define VM_RX_CHECKSUM_PARTIAL CHECKSUM_HW #else # define VM_RX_CHECKSUM_PARTIAL CHECKSUM_PARTIAL #endif /* csum status of outgoing pkts */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) && defined(CHECKSUM_HW) # define VM_TX_CHECKSUM_PARTIAL CHECKSUM_HW #else # define VM_TX_CHECKSUM_PARTIAL CHECKSUM_PARTIAL #endif #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)) # define compat_kfree_skb(skb, type) kfree_skb(skb, type) # define compat_dev_kfree_skb(skb, type) dev_kfree_skb(skb, type) # define compat_dev_kfree_skb_any(skb, type) dev_kfree_skb(skb, type) # define compat_dev_kfree_skb_irq(skb, type) dev_kfree_skb(skb, type) #else # define compat_kfree_skb(skb, type) kfree_skb(skb) # define compat_dev_kfree_skb(skb, type) dev_kfree_skb(skb) # if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)) # define compat_dev_kfree_skb_any(skb, type) dev_kfree_skb(skb) # define compat_dev_kfree_skb_irq(skb, type) dev_kfree_skb(skb) # else # define compat_dev_kfree_skb_any(skb, type) dev_kfree_skb_any(skb) # define compat_dev_kfree_skb_irq(skb, type) dev_kfree_skb_irq(skb) # endif #endif #ifndef NET_IP_ALIGN # define COMPAT_NET_IP_ALIGN 2 #else # define COMPAT_NET_IP_ALIGN NET_IP_ALIGN #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 4) # define compat_skb_headlen(skb) skb_headlen(skb) # define compat_pskb_may_pull(skb, len) pskb_may_pull(skb, len) # define compat_skb_is_nonlinear(skb) skb_is_nonlinear(skb) #else # define compat_skb_headlen(skb) (skb)->len # define compat_pskb_may_pull(skb, len) 1 # define compat_skb_is_nonlinear(skb) 0 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12) # define compat_skb_header_cloned(skb) skb_header_cloned(skb) #else # define compat_skb_header_cloned(skb) 0 #endif #endif /* __COMPAT_SKBUFF_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/kernelStubsLinux.c0000644765153500003110000002263512220061556023211 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * kernelStubsLinux.c * * This file contains implementations of common userspace functions in terms * that the Linux kernel can understand. */ /* Must come before any kernel header file */ #include "driver-config.h" #include "kernelStubs.h" #include "compat_kernel.h" #include "compat_page.h" #include "compat_sched.h" #include #include "vm_assert.h" /* *----------------------------------------------------------------------------- * * Panic -- * * Prints the debug message and stops the system. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ void Panic(const char *fmt, ...) // IN { va_list args; char *result; va_start(args, fmt); result = Str_Vasprintf(NULL, fmt, args); va_end(args); if (result) { printk(KERN_EMERG "%s", result); } BUG(); while (1); // Avoid compiler warning. } /* *---------------------------------------------------------------------- * * Str_Strcpy-- * * Wrapper for strcpy that checks for buffer overruns. * * Results: * Same as strcpy. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * Str_Strcpy(char *buf, // OUT const char *src, // IN size_t maxSize) // IN { unsigned int *stack = (unsigned int *)&buf; size_t len; len = strlen(src); if (len >= maxSize) { Panic("%s:%d Buffer too small 0x%x\n", __FILE__,__LINE__, stack[-1]); } return memcpy(buf, src, len + 1); } /* *---------------------------------------------------------------------- * * Str_Vsnprintf -- * * Compatability wrapper b/w different libc versions * * Results: * int - number of bytes written (not including NULL terminate character), * -1 on overflow (insufficient space for NULL terminate is considered * overflow) * * NB: on overflow the buffer WILL be null terminated * * Side effects: * None * *---------------------------------------------------------------------- */ int Str_Vsnprintf(char *str, // OUT size_t size, // IN const char *format, // IN va_list arguments) // IN { int retval; retval = vsnprintf(str, size, format, arguments); /* * Linux glibc 2.0.x returns -1 and null terminates (which we shouldn't * be linking against), but glibc 2.1.x follows c99 and returns * characters that would have been written. */ if (retval >= size) { return -1; } return retval; } /* *----------------------------------------------------------------------------- * * Str_Vasprintf -- * * Allocate and format a string, using the GNU libc way to specify the * format (i.e. optionally allow the use of positional parameters) * * Results: * The allocated string on success (if 'length' is not NULL, *length * is set to the length of the allocated string) * NULL on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ char * Str_Vasprintf(size_t *length, // OUT const char *format, // IN va_list arguments) // IN { /* * Simple implementation of Str_Vasprintf when userlevel libraries are not * available (e.g. for use in drivers). We just fallback to vsnprintf, * doubling if we didn't have enough space. */ unsigned int bufSize; char *buf; int retval; bufSize = strlen(format); buf = NULL; do { /* * Initial allocation of strlen(format) * 2. Should this be tunable? * XXX Yes, this could overflow and spin forever when you get near 2GB * allocations. I don't care. --rrdharan */ va_list args2; bufSize *= 2; buf = realloc(buf, bufSize); if (!buf) { return NULL; } va_copy(args2, arguments); retval = Str_Vsnprintf(buf, bufSize, format, args2); va_end(args2); } while (retval == -1); if (length) { *length = retval; } /* * Try to trim the buffer here to save memory? */ return buf; } /* *----------------------------------------------------------------------------- * * Str_Asprintf -- * * Same as Str_Vasprintf(), but parameters are passed inline --hpreg * * Results: * Same as Str_Vasprintf() * * Side effects: * Same as Str_Vasprintf() * *----------------------------------------------------------------------------- */ char * Str_Asprintf(size_t *length, // OUT const char *format, // IN ...) // IN { va_list arguments; char *result; va_start(arguments, format); result = Str_Vasprintf(length, format, arguments); va_end(arguments); return result; } /* *----------------------------------------------------------------------------- * * strdup -- * * Duplicates a string. * * Results: * A pointer to memory containing the duplicated string or NULL if no * memory was available. * * Side effects: * None * *----------------------------------------------------------------------------- */ char * strdup(const char *source) // IN { char *target = NULL; if (source) { /* * We call our special implementation of malloc() because the users of * strdup() will call free(), and that'll decrement the pointer before * freeing it. Thus, we need to make sure that the allocated block * also stores the block length before the block itself (see malloc() * below). */ unsigned int len = strlen(source); target = malloc(len + 1); if (target) { memcpy(target, source, len + 1); } } return target; } /* *---------------------------------------------------------------------------- * * malloc -- * * Allocate memory using kmalloc. There is no realloc * equivalent, so we roll our own by padding each allocation with * 4 (or 8 for 64 bit guests) extra bytes to store the block length. * * Results: * Pointer to driver heap memory, offset by 4 (or 8) * bytes from the real block pointer. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void * malloc(size_t size) // IN { size_t *ptr; ptr = kmalloc(size + sizeof size, GFP_KERNEL); if (ptr) { *ptr++ = size; } return ptr; } /* *--------------------------------------------------------------------------- * * free -- * * Free memory allocated by a previous call to malloc, calloc or realloc. * * Results: * None. * * Side effects: * Calls kfree to free the real (base) pointer. * *--------------------------------------------------------------------------- */ void free(void *mem) // IN { if (mem) { size_t *dataPtr = (size_t *)mem; kfree(--dataPtr); } } /* *---------------------------------------------------------------------------- * * calloc -- * * Malloc and zero. * * Results: * Pointer to driver heap memory (see malloc, above). * * Side effects: * None. * *---------------------------------------------------------------------------- */ void * calloc(size_t num, // IN size_t len) // IN { size_t size; void *ptr; size = num * len; ptr = malloc(size); if (ptr) { memset(ptr, 0, size); } return ptr; } /* *---------------------------------------------------------------------------- * * realloc -- * * Since the driver heap has no realloc equivalent, we have to roll our * own. Fortunately, we can retrieve the block size of every block we * hand out since we stashed it at allocation time (see malloc above). * * Results: * Pointer to memory block valid for 'newSize' bytes, or NULL if * allocation failed. * * Side effects: * Could copy memory around. * *---------------------------------------------------------------------------- */ void * realloc(void* ptr, // IN size_t newSize) // IN { void *newPtr; size_t *dataPtr; size_t length, lenUsed; dataPtr = (size_t *)ptr; length = ptr ? dataPtr[-1] : 0; if (newSize == 0) { if (ptr) { free(ptr); newPtr = NULL; } else { newPtr = malloc(newSize); } } else if (newSize == length) { newPtr = ptr; } else if ((newPtr = malloc(newSize))) { if (length < newSize) { lenUsed = length; } else { lenUsed = newSize; } memcpy(newPtr, ptr, lenUsed); free(ptr); } return newPtr; } open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_interrupt.h0000644765153500003110000000357312220061556023274 0ustar dtormts/********************************************************* * Copyright (C) 2003 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_INTERRUPT_H__ # define __COMPAT_INTERRUPT_H__ #include #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 69) /* * We cannot just define irqreturn_t, as some 2.4.x kernels have * typedef void irqreturn_t; for "increasing" backward compatibility. */ typedef void compat_irqreturn_t; #define COMPAT_IRQ_NONE #define COMPAT_IRQ_HANDLED #define COMPAT_IRQ_RETVAL(x) #else typedef irqreturn_t compat_irqreturn_t; #define COMPAT_IRQ_NONE IRQ_NONE #define COMPAT_IRQ_HANDLED IRQ_HANDLED #define COMPAT_IRQ_RETVAL(x) IRQ_RETVAL(x) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) #define COMPAT_IRQF_DISABLED SA_INTERRUPT #define COMPAT_IRQF_SHARED SA_SHIRQ #else #define COMPAT_IRQF_DISABLED IRQF_DISABLED #define COMPAT_IRQF_SHARED IRQF_SHARED #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) #define COMPAT_IRQ_HANDLER_ARGS(irq, devp) (int irq, void *devp, struct pt_regs *regs) #else #define COMPAT_IRQ_HANDLER_ARGS(irq, devp) (int irq, void *devp) #endif #endif /* __COMPAT_INTERRUPT_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/vmci_kernel_if.h0000644765153500003110000004265412220061556022654 0ustar dtormts/********************************************************* * Copyright (C) 2006-2011 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmci_kernel_if.h -- * * This file defines helper functions for VMCI host _and_ guest * kernel code. It must work for Windows, Mac OS, vmkernel, Linux and * Solaris kernels, i.e. using defines where necessary. */ #ifndef _VMCI_KERNEL_IF_H_ #define _VMCI_KERNEL_IF_H_ #if !defined(linux) && !defined(_WIN32) && !defined(__APPLE__) && \ !defined(VMKERNEL) && !defined(SOLARIS) # error "Platform not supported." #endif #if defined(_WIN32) # include #endif #if defined(linux) && !defined(VMKERNEL) # include "driver-config.h" # include "compat_cred.h" # include "compat_module.h" # include "compat_semaphore.h" # include "compat_spinlock.h" # include "compat_version.h" # include #endif // linux #ifdef __APPLE__ # include # include # include # include #endif #ifdef VMKERNEL # include "splock.h" # include "semaphore_ext.h" # include "vmkapi.h" # include "world_dist.h" #endif #ifdef SOLARIS # include # include # include # include # include # include # include #endif #include "vm_basic_types.h" #include "vmci_defs.h" #if defined(VMKERNEL) # include "list.h" #else # include "dbllnklst.h" #endif /* Flags for specifying memory type. */ #define VMCI_MEMORY_NORMAL 0x0 #define VMCI_MEMORY_ATOMIC 0x1 #define VMCI_MEMORY_NONPAGED 0x2 /* Platform specific type definitions. */ #if defined(VMKERNEL) # define VMCI_EXPORT_SYMBOL(_SYMBOL) VMK_MODULE_EXPORT_SYMBOL(_SYMBOL); #elif defined(linux) # define VMCI_EXPORT_SYMBOL(_symbol) EXPORT_SYMBOL(_symbol); #elif defined(__APPLE__) # define VMCI_EXPORT_SYMBOL(_symbol) __attribute__((visibility("default"))) #else # define VMCI_EXPORT_SYMBOL(_symbol) #endif #if defined(VMKERNEL) typedef SP_SpinLock VMCILock; typedef SP_IRQL VMCILockFlags; typedef Semaphore VMCIEvent; typedef Semaphore VMCIMutex; typedef World_ID VMCIHostVmID; typedef uint32 VMCIHostUser; typedef PPN *VMCIQPGuestMem; #elif defined(linux) typedef spinlock_t VMCILock; typedef unsigned long VMCILockFlags; typedef wait_queue_head_t VMCIEvent; typedef struct semaphore VMCIMutex; typedef PPN *VMCIPpnList; /* List of PPNs in produce/consume queue. */ typedef uid_t VMCIHostUser; typedef VA64 VMCIQPGuestMem; #elif defined(__APPLE__) typedef IOLock *VMCILock; typedef unsigned long VMCILockFlags; typedef struct { IOLock *lock; DblLnkLst_Links waiters; int buffered; } VMCIEvent; typedef IOLock *VMCIMutex; typedef void *VMCIPpnList; /* Actually a pointer to the C++ Object IOMemoryDescriptor */ typedef uid_t VMCIHostUser; typedef VA64 *VMCIQPGuestMem; #elif defined(_WIN32) typedef KSPIN_LOCK VMCILock; typedef KIRQL VMCILockFlags; typedef KEVENT VMCIEvent; typedef FAST_MUTEX VMCIMutex; typedef PMDL VMCIPpnList; /* MDL to map the produce/consume queue. */ typedef PSID VMCIHostUser; typedef VA64 *VMCIQPGuestMem; #elif defined(SOLARIS) typedef kmutex_t VMCILock; typedef unsigned long VMCILockFlags; typedef ksema_t VMCIEvent; typedef kmutex_t VMCIMutex; typedef PPN *VMCIPpnList; /* List of PPNs in produce/consume queue. */ typedef uid_t VMCIHostUser; typedef VA64 VMCIQPGuestMem; #endif // VMKERNEL /* Callback needed for correctly waiting on events. */ typedef int (*VMCIEventReleaseCB)(void *clientData); /* * Internal locking dependencies within VMCI: * * CONTEXTFIRE < CONTEXT, CONTEXTLIST, EVENT, HASHTABLE * * DOORBELL < HASHTABLE * * QPHIBERNATE < EVENT */ #ifdef VMKERNEL typedef Lock_Rank VMCILockRank; typedef SemaRank VMCISemaRank; #define VMCI_SEMA_RANK_QPHEADER (SEMA_RANK_FS - 1) #define VMCI_LOCK_RANK_MAX (MIN(SP_RANK_WAIT, \ SP_RANK_HEAPLOCK_DYNAMIC) - 1) #else typedef unsigned long VMCILockRank; typedef unsigned long VMCISemaRank; #define VMCI_LOCK_RANK_MAX 0x0fff #define VMCI_SEMA_RANK_QPHEADER 0x0fff #endif // VMKERNEL #define VMCI_LOCK_RANK_CONTEXT VMCI_LOCK_RANK_MAX #define VMCI_LOCK_RANK_CONTEXTLIST VMCI_LOCK_RANK_MAX #define VMCI_LOCK_RANK_DATAGRAMVMK VMCI_LOCK_RANK_MAX #define VMCI_LOCK_RANK_EVENT VMCI_LOCK_RANK_MAX #define VMCI_LOCK_RANK_HASHTABLE VMCI_LOCK_RANK_MAX #define VMCI_LOCK_RANK_RESOURCE VMCI_LOCK_RANK_MAX #define VMCI_LOCK_RANK_QPHEADER VMCI_LOCK_RANK_MAX #define VMCI_LOCK_RANK_DOORBELL (VMCI_LOCK_RANK_HASHTABLE - 1) #define VMCI_LOCK_RANK_CONTEXTFIRE (MIN(VMCI_LOCK_RANK_CONTEXT, \ MIN(VMCI_LOCK_RANK_CONTEXTLIST, \ MIN(VMCI_LOCK_RANK_EVENT, \ VMCI_LOCK_RANK_HASHTABLE))) - 1) #define VMCI_LOCK_RANK_QPHIBERNATE (VMCI_LOCK_RANK_EVENT - 1) #define VMCI_LOCK_RANK_PACKET_QP (VMCI_LOCK_RANK_QPHEADER - 1) //#define VMCI_LOCK_RANK_PACKET_QP 0xffd /* For vVol */ #define VMCI_SEMA_RANK_QUEUEPAIRLIST (VMCI_SEMA_RANK_QPHEADER - 1) #define VMCI_SEMA_RANK_GUESTMEM (VMCI_SEMA_RANK_QUEUEPAIRLIST - 1) /* * Host specific struct used for signalling. */ typedef struct VMCIHost { #if defined(VMKERNEL) World_ID vmmWorldID[2]; /* * First one is the active one and the second * one is shadow world during FSR. */ #elif defined(linux) wait_queue_head_t waitQueue; #elif defined(__APPLE__) struct Socket *socket; /* vmci Socket object on Mac OS. */ #elif defined(_WIN32) KEVENT *callEvent; /* Ptr to userlevel event used when signalling * new pending guestcalls in kernel. */ #elif defined(SOLARIS) struct pollhead pollhead; /* Per datagram handle pollhead structure to * be treated as a black-box. None of its * fields should be referenced. */ #endif } VMCIHost; /* * Guest device port I/O. */ #if defined(linux) typedef unsigned short int VMCIIoPort; typedef int VMCIIoHandle; #elif defined(_WIN32) typedef PUCHAR VMCIIoPort; typedef int VMCIIoHandle; #elif defined(SOLARIS) typedef uint8_t * VMCIIoPort; typedef ddi_acc_handle_t VMCIIoHandle; #elif defined(__APPLE__) typedef unsigned short int VMCIIoPort; typedef void *VMCIIoHandle; #endif // __APPLE__ void VMCI_ReadPortBytes(VMCIIoHandle handle, VMCIIoPort port, uint8 *buffer, size_t bufferLength); int VMCI_InitLock(VMCILock *lock, char *name, VMCILockRank rank); void VMCI_CleanupLock(VMCILock *lock); void VMCI_GrabLock(VMCILock *lock, VMCILockFlags *flags); void VMCI_ReleaseLock(VMCILock *lock, VMCILockFlags flags); void VMCI_GrabLock_BH(VMCILock *lock, VMCILockFlags *flags); void VMCI_ReleaseLock_BH(VMCILock *lock, VMCILockFlags flags); void VMCIHost_InitContext(VMCIHost *hostContext, uintptr_t eventHnd); void VMCIHost_ReleaseContext(VMCIHost *hostContext); void VMCIHost_SignalCall(VMCIHost *hostContext); void VMCIHost_ClearCall(VMCIHost *hostContext); Bool VMCIHost_WaitForCallLocked(VMCIHost *hostContext, VMCILock *lock, VMCILockFlags *flags, Bool useBH); #ifdef VMKERNEL int VMCIHost_ContextToHostVmID(VMCIHost *hostContext, VMCIHostVmID *hostVmID); int VMCIHost_ContextHasUuid(VMCIHost *hostContext, const char *uuid); void VMCIHost_SetActiveHnd(VMCIHost *hostContext, uintptr_t eventHnd); Bool VMCIHost_RemoveHnd(VMCIHost *hostContext, uintptr_t eventHnd); Bool VMCIHost_IsActiveHnd(VMCIHost *hostContext, uintptr_t eventHnd); void VMCIHost_SetInactiveHnd(VMCIHost *hostContext, uintptr_t eventHnd); uint32 VMCIHost_NumHnds(VMCIHost *hostContext); uintptr_t VMCIHost_GetActiveHnd(VMCIHost *hostContext); void VMCIHost_SignalBitmap(VMCIHost *hostContext); #endif #if defined(_WIN32) /* * On Windows, Driver Verifier will panic() if we leak memory when we are * unloaded. It dumps the leaked blocks for us along with callsites, which * it handily tracks, but if we embed ExAllocate() inside a function, then * the callsite is useless. So make this a macro on this platform only. */ # define VMCI_AllocKernelMem(_sz, _f) \ ExAllocatePoolWithTag((((_f) & VMCI_MEMORY_NONPAGED) ? \ NonPagedPool : PagedPool), \ (_sz), 'MMTC') #else // _WIN32 void *VMCI_AllocKernelMem(size_t size, int flags); #endif // _WIN32 void VMCI_FreeKernelMem(void *ptr, size_t size); int VMCI_CopyToUser(VA64 dst, const void *src, size_t len); Bool VMCIWellKnownID_AllowMap(VMCIId wellKnownID, VMCIPrivilegeFlags privFlags); int VMCIHost_CompareUser(VMCIHostUser *user1, VMCIHostUser *user2); void VMCI_CreateEvent(VMCIEvent *event); void VMCI_DestroyEvent(VMCIEvent *event); void VMCI_SignalEvent(VMCIEvent *event); void VMCI_WaitOnEvent(VMCIEvent *event, VMCIEventReleaseCB releaseCB, void *clientData); #if (defined(__APPLE__) || defined(__linux__) || defined(_WIN32)) && !defined(VMKERNEL) Bool VMCI_WaitOnEventInterruptible(VMCIEvent *event, VMCIEventReleaseCB releaseCB, void *clientData); #endif #if !defined(VMKERNEL) && (defined(__linux__) || defined(_WIN32) || \ defined(__APPLE__) || defined(SOLARIS)) int VMCI_CopyFromUser(void *dst, VA64 src, size_t len); #endif typedef void (VMCIWorkFn)(void *data); Bool VMCI_CanScheduleDelayedWork(void); int VMCI_ScheduleDelayedWork(VMCIWorkFn *workFn, void *data); int VMCIMutex_Init(VMCIMutex *mutex, char *name, VMCILockRank rank); void VMCIMutex_Destroy(VMCIMutex *mutex); void VMCIMutex_Acquire(VMCIMutex *mutex); void VMCIMutex_Release(VMCIMutex *mutex); #if defined(SOLARIS) || defined(_WIN32) || defined(__APPLE__) int VMCIKernelIf_Init(void); void VMCIKernelIf_Exit(void); #if defined(_WIN32) void VMCIKernelIf_DrainDelayedWork(void); #endif // _WIN32 #endif // SOLARIS || _WIN32 || __APPLE__ || VMKERNEL #if !defined(VMKERNEL) && (defined(__linux__) || defined(_WIN32) || \ defined(SOLARIS) || defined(__APPLE__)) void *VMCI_AllocQueue(uint64 size, uint32 flags); void VMCI_FreeQueue(void *q, uint64 size); typedef struct PPNSet { uint64 numProducePages; uint64 numConsumePages; VMCIPpnList producePPNs; VMCIPpnList consumePPNs; Bool initialized; } PPNSet; int VMCI_AllocPPNSet(void *produceQ, uint64 numProducePages, void *consumeQ, uint64 numConsumePages, PPNSet *ppnSet); void VMCI_FreePPNSet(PPNSet *ppnSet); int VMCI_PopulatePPNList(uint8 *callBuf, const PPNSet *ppnSet); #endif struct VMCIQueue; struct PageStoreAttachInfo; struct VMCIQueue *VMCIHost_AllocQueue(uint64 queueSize); void VMCIHost_FreeQueue(struct VMCIQueue *queue, uint64 queueSize); #if defined(VMKERNEL) typedef World_Handle *VMCIGuestMemID; #define INVALID_VMCI_GUEST_MEM_ID NULL #else typedef uint32 VMCIGuestMemID; #define INVALID_VMCI_GUEST_MEM_ID 0 #endif #if defined(VMKERNEL) || defined(__linux__) || defined(_WIN32) || \ defined(__APPLE__) struct QueuePairPageStore; int VMCIHost_RegisterUserMemory(unsigned int index, struct QueuePairPageStore *pageStore, struct VMCIQueue *produceQ, struct VMCIQueue *consumeQ); void VMCIHost_UnregisterUserMemory(unsigned int index, struct VMCIQueue *produceQ, struct VMCIQueue *consumeQ); int VMCIHost_MapQueues(unsigned int index, struct VMCIQueue *produceQ, struct VMCIQueue *consumeQ, uint32 flags); int VMCIHost_UnmapQueues(unsigned int index, VMCIGuestMemID gid, struct VMCIQueue *produceQ, struct VMCIQueue *consumeQ); void VMCI_InitQueueMutex(struct VMCIQueue *produceQ, struct VMCIQueue *consumeQ); void VMCI_CleanupQueueMutex(struct VMCIQueue *produceQ, struct VMCIQueue *consumeQ); int VMCI_AcquireQueueMutex(struct VMCIQueue *queue, Bool canBlock); void VMCI_ReleaseQueueMutex(struct VMCIQueue *queue); #else // Below are the guest OS'es without host side support. # define VMCI_InitQueueMutex(_pq, _cq) # define VMCI_CleanupQueueMutex(_pq, _cq) do { } while (0) # define VMCI_AcquireQueueMutex(_q, _cb) VMCI_SUCCESS # define VMCI_ReleaseQueueMutex(_q) do { } while (0) # define VMCIHost_RegisterUserMemory(_idx, _ps, _pq, _cq) VMCI_ERROR_UNAVAILABLE # define VMCIHost_UnregisterUserMemory(_idx, _pq, _cq) do { } while (0) # define VMCIHost_MapQueues(_idx, _pq, _cq, _f) VMCI_SUCCESS # define VMCIHost_UnmapQueues(_idx, _gid, _pq, _cq) VMCI_SUCCESS #endif #if defined(VMKERNEL) void VMCIHost_MarkQueuesAvailable(unsigned int index, struct VMCIQueue *produceQ, struct VMCIQueue *consumeQ); void VMCIHost_MarkQueuesUnavailable(unsigned int index, struct VMCIQueue *produceQ, struct VMCIQueue *consumeQ); #else # define VMCIHost_MarkQueuesAvailable(_idx, _q, _p) do { } while (0) # define VMCIHost_MarkQueuesUnavailable(_idx, _q, _p) do { } while(0) #endif #if defined(VMKERNEL) || defined(__linux__) void VMCI_LockQueueHeader(struct VMCIQueue *queue); void VMCI_UnlockQueueHeader(struct VMCIQueue *queue); #else # define VMCI_LockQueueHeader(_q) ASSERT_NOT_IMPLEMENTED(FALSE) # define VMCI_UnlockQueueHeader(_q) ASSERT_NOT_IMPLEMENTED(FALSE) #endif #if (!defined(VMKERNEL) && defined(__linux__)) || defined(_WIN32) || \ defined(__APPLE__) || defined(SOLARIS) int VMCIHost_GetUserMemory(unsigned int index, VA64 produceUVA, VA64 consumeUVA, struct VMCIQueue *produceQ, struct VMCIQueue *consumeQ); void VMCIHost_ReleaseUserMemory(unsigned int index, struct VMCIQueue *produceQ, struct VMCIQueue *consumeQ); #else # define VMCIHost_GetUserMemory(_idx, _puva, _cuva, _pq, _cq) VMCI_ERROR_UNAVAILABLE # define VMCIHost_ReleaseUserMemory(_idx, _pq, _cq) ASSERT_NOT_IMPLEMENTED(FALSE) #endif #if defined(_WIN32) Bool VMCI_EnqueueToDevNull(struct VMCIQueue *queue); int VMCI_ConvertToLocalQueue(struct VMCIQueue *queueInfo, struct VMCIQueue *otherQueueInfo, uint64 size, Bool keepContent, void **oldQueue); void VMCI_RevertToNonLocalQueue(struct VMCIQueue *queueInfo, void *nonLocalQueue, uint64 size); void VMCI_FreeQueueBuffer(void *queue, uint64 size); Bool VMCI_CanCreate(void); #else // _WIN32 # define VMCI_EnqueueToDevNull(_q) FALSE # define VMCI_ConvertToLocalQueue(_pq, _cq, _s, _oq, _kc) VMCI_ERROR_UNAVAILABLE # define VMCI_RevertToNonLocalQueue(_q, _nlq, _s) # define VMCI_FreeQueueBuffer(_q, _s) # define VMCI_CanCreate() TRUE #endif // !_WIN32 Bool VMCI_GuestPersonalityActive(void); Bool VMCI_HostPersonalityActive(void); #if defined(VMKERNEL) typedef List_Links VMCIListItem; typedef List_Links VMCIList; # define VMCIList_Init(_l) List_Init(_l) # define VMCIList_InitEntry(_e) List_InitElement(_e) # define VMCIList_Empty(_l) List_IsEmpty(_l) # define VMCIList_Insert(_e, _l) List_Insert(_e, LIST_ATREAR(_l)) # define VMCIList_Remove(_e) List_Remove(_e) # define VMCIList_Scan(_cur, _l) LIST_FORALL(_l, _cur) # define VMCIList_ScanSafe(_cur, _next, _l) LIST_FORALL_SAFE(_l, _cur, _next) # define VMCIList_Entry(_elem, _type, _field) List_Entry(_elem, _type, _field) # define VMCIList_First(_l) (VMCIList_Empty(_l)?NULL:List_First(_l)) #else typedef DblLnkLst_Links VMCIListItem; typedef DblLnkLst_Links VMCIList; # define VMCIList_Init(_l) DblLnkLst_Init(_l) # define VMCIList_InitEntry(_e) DblLnkLst_Init(_e) # define VMCIList_Empty(_l) (!DblLnkLst_IsLinked(_l)) # define VMCIList_Insert(_e, _l) DblLnkLst_LinkLast(_l, _e) # define VMCIList_Remove(_e) DblLnkLst_Unlink1(_e) # define VMCIList_Scan(_cur, _l) DblLnkLst_ForEach(_cur, _l) # define VMCIList_ScanSafe(_cur, _next, _l) DblLnkLst_ForEachSafe(_cur, _next, _l) # define VMCIList_Entry(_elem, _type, _field) DblLnkLst_Container(_elem, _type, _field) # define VMCIList_First(_l) (VMCIList_Empty(_l)?NULL:(_l)->next) #endif #endif // _VMCI_KERNEL_IF_H_ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_ethtool.h0000644765153500003110000000366212220061556022715 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef _COMPAT_ETHTOOL_H #define _COMPAT_ETHTOOL_H /* * ethtool is a userspace utility for getting and setting ethernet device * settings. Kernel support for it was first published in 2.4.0-test11, but * only in 2.4.15 were the ethtool_value struct and the ETHTOOL_GLINK ioctl * added to ethtool.h (together, because the ETHTOOL_GLINK ioctl expects a * single value response). * * Likewise, ioctls for getting and setting TSO were published in 2.4.22. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) # include # ifndef ETHTOOL_GLINK # define ETHTOOL_GLINK 0x0a typedef struct { __u32 cmd; __u32 data; } compat_ethtool_value; # else typedef struct ethtool_value compat_ethtool_value; # endif # ifndef ETHTOOL_GTSO # define ETHTOOL_GTSO 0x1E # define ETHTOOL_STSO 0x1F # endif #endif #if COMPAT_LINUX_VERSION_CHECK_LT(3, 3, 0) # define compat_ethtool_rxfh_indir_default(i, num_queues) (i % num_queues) #else # define compat_ethtool_rxfh_indir_default(i, num_queues) ethtool_rxfh_indir_default(i, num_queues) #endif #endif /* _COMPAT_ETHTOOL_H */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_workqueue.h0000644765153500003110000001436112220061556023264 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_WORKQUEUE_H__ # define __COMPAT_WORKQUEUE_H__ #include #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41) # include #endif /* * * Work queues and delayed work queues. * * Prior to 2.5.41, the notion of work queues did not exist. Taskqueues are * used for work queues and timers are used for delayed work queues. * * After 2.6.20, normal work structs ("work_struct") and delayed work * ("delayed_work") structs were separated so that the work_struct could be * slimmed down. The interface was also changed such that the address of the * work_struct itself is passed in as the argument to the work function. This * requires that one embed the work struct in the larger struct containing the * information necessary to complete the work and use container_of() to obtain * the address of the containing structure. * * Users of these macros should embed a compat_work or compat_delayed_work in * a larger structure, then specify the larger structure as the _data argument * for the initialization functions, specify the work function to take * a compat_work_arg or compat_delayed_work_arg, then use the appropriate * _GET_DATA macro to obtain the reference to the structure passed in as _data. * An example is below. * * * typedef struct WorkData { * int data; * compat_work work; * } WorkData; * * * void * WorkFunc(compat_work_arg data) * { * WorkData *workData = COMPAT_WORK_GET_DATA(data, WorkData, work); * * ... * } * * * { * WorkData *workData = kmalloc(sizeof *workData, GFP_EXAMPLE); * if (!workData) { * return -ENOMEM; * } * * COMPAT_INIT_WORK(&workData->work, WorkFunc, workData); * compat_schedule_work(&workData->work); * } */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 41) /* { */ typedef struct tq_struct compat_work; typedef struct compat_delayed_work { struct tq_struct work; struct timer_list timer; } compat_delayed_work; typedef void * compat_work_arg; typedef void * compat_delayed_work_arg; /* * Delayed work queues need to run at some point in the future in process * context, but task queues don't support delaying the task one is scheduling. * Timers allow us to delay the execution of our work queue until the future, * but timer handlers run in bottom-half context. As such, we use both a timer * and task queue and use the timer handler below to schedule the task in * process context immediately. The timer lets us delay execution, and the * task queue lets us run in process context. * * Note that this is similar to how delayed_work is implemented with work * queues in later kernel versions. */ static inline void __compat_delayed_work_timer(unsigned long arg) { compat_delayed_work *dwork = (compat_delayed_work *)arg; if (dwork) { schedule_task(&dwork->work); } } # define COMPAT_INIT_WORK(_work, _func, _data) \ INIT_LIST_HEAD(&(_work)->list); \ (_work)->sync = 0; \ (_work)->routine = _func; \ (_work)->data = _data # define COMPAT_INIT_DELAYED_WORK(_work, _func, _data) \ COMPAT_INIT_WORK(&(_work)->work, _func, _data); \ init_timer(&(_work)->timer); \ (_work)->timer.expires = 0; \ (_work)->timer.function = __compat_delayed_work_timer; \ (_work)->timer.data = (unsigned long)_work # define compat_schedule_work(_work) \ schedule_task(_work) # define compat_schedule_delayed_work(_work, _delay) \ (_work)->timer.expires = jiffies + _delay; \ add_timer(&(_work)->timer) # define COMPAT_WORK_GET_DATA(_p, _type, _member) \ (_type *)(_p) # define COMPAT_DELAYED_WORK_GET_DATA(_p, _type, _member) \ (_type *)(_p) #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) \ && !defined(__VMKLNX__) /* } { */ typedef struct work_struct compat_work; typedef struct work_struct compat_delayed_work; typedef void * compat_work_arg; typedef void * compat_delayed_work_arg; # define COMPAT_INIT_WORK(_work, _func, _data) \ INIT_WORK(_work, _func, _data) # define COMPAT_INIT_DELAYED_WORK(_work, _func, _data) \ INIT_WORK(_work, _func, _data) # define compat_schedule_work(_work) \ schedule_work(_work) # define compat_schedule_delayed_work(_work, _delay) \ schedule_delayed_work(_work, _delay) # define COMPAT_WORK_GET_DATA(_p, _type, _member) \ (_type *)(_p) # define COMPAT_DELAYED_WORK_GET_DATA(_p, _type, _member) \ (_type *)(_p) #else /* } Linux >= 2.6.20 { */ typedef struct work_struct compat_work; typedef struct delayed_work compat_delayed_work; typedef struct work_struct * compat_work_arg; typedef struct work_struct * compat_delayed_work_arg; # define COMPAT_INIT_WORK(_work, _func, _data) \ INIT_WORK(_work, _func) # define COMPAT_INIT_DELAYED_WORK(_work, _func, _data) \ INIT_DELAYED_WORK(_work, _func) # define compat_schedule_work(_work) \ schedule_work(_work) # define compat_schedule_delayed_work(_work, _delay) \ schedule_delayed_work(_work, _delay) # define COMPAT_WORK_GET_DATA(_p, _type, _member) \ container_of(_p, _type, _member) # define COMPAT_DELAYED_WORK_GET_DATA(_p, _type, _member) \ container_of(_p, _type, _member.work) #endif /* } */ #endif /* __COMPAT_WORKQUEUE_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_page-flags.h0000644765153500003110000000503712220061556023243 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_PAGE_FLAGS_H__ # define __COMPAT_PAGE_FLAGS_H__ /* No page-flags.h prior to 2.5.12. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 12) # include #endif /* * The pgoff_t type was introduced in 2.5.20, but we'll look for it by * definition since it's more convenient. Note that we want to avoid a * situation where, in the future, a #define is changed to a typedef, * so if pgoff_t is not defined in some future kernel, we won't define it. */ #if !defined(pgoff_t) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) #define pgoff_t unsigned long #endif /* * set_page_writeback() was introduced in 2.6.6. Prior to that, callers were * using the SetPageWriteback() macro directly, so that's what we'll use. * Prior to 2.5.12, the writeback bit didn't exist, so we don't need to do * anything. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 12) #define compat_set_page_writeback(page) #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6) #define compat_set_page_writeback(page) SetPageWriteback(page) #else #define compat_set_page_writeback(page) set_page_writeback(page) #endif /* * end_page_writeback() was introduced in 2.5.12. Prior to that, it looks like * there was no page writeback bit, and everything the function accomplished * was done by unlock_page(), so we'll define it out. * * Note that we could just #define end_page_writeback to nothing and avoid * needing the compat_ prefix, but this is more complete with respect to * compat_set_page_writeback. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 12) #define compat_end_page_writeback(page) #else #define compat_end_page_writeback(page) end_page_writeback(page) #endif #endif /* __COMPAT_PAGE_FLAGS_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_version.h0000644765153500003110000000736312220061556022726 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_VERSION_H__ # define __COMPAT_VERSION_H__ #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_DISTRIBUTE #define INCLUDE_ALLOW_VMKDRIVERS #include "includeCheck.h" #ifndef __linux__ # error "linux-version.h" #endif #include #ifndef KERNEL_VERSION # error KERNEL_VERSION macro is not defined, environment is busted #endif /* * Distinguish relevant classes of Linux kernels. * * The convention is that version X defines all * the KERNEL_Y symbols where Y <= X. * * XXX Do not add more definitions here. This way of doing things does not * scale, and we are going to phase it out soon --hpreg */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 0) # define KERNEL_2_1 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0) # define KERNEL_2_2 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 1) # define KERNEL_2_3_1 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 15) /* new networking */ # define KERNEL_2_3_15 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 25) /* new procfs */ # define KERNEL_2_3_25 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 29) /* even newer procfs */ # define KERNEL_2_3_29 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 43) /* softnet changes */ # define KERNEL_2_3_43 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 47) /* more softnet changes */ # define KERNEL_2_3_47 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 99) /* name in netdevice struct is array and not pointer */ # define KERNEL_2_3_99 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) /* New 'owner' member at the beginning of struct file_operations */ # define KERNEL_2_4_0 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 8) /* New netif_rx_ni() --hpreg */ # define KERNEL_2_4_8 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 2) /* New kdev_t, major()/minor() API --hpreg */ # define KERNEL_2_5_2 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5) /* New sk_alloc(), pte_offset_map()/pte_unmap() --hpreg */ # define KERNEL_2_5_5 #endif /* Linux kernel 3.0 can be called 2.6.40, and 3.1 can be 2.6.41... * Use COMPAT_LINUX_VERSION_CHECK_LT iff you need to compare running kernel to * versions 3.0 and above. * */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) /* Straight forward comparison if kernel version is 3.0.0 and beyond */ # define COMPAT_LINUX_VERSION_CHECK_LT(a, b, c) LINUX_VERSION_CODE < KERNEL_VERSION (a, b, c) #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 40) /* Use b of the check to calculate corresponding c of kernel * version to compare */ # define COMPAT_LINUX_VERSION_CHECK_LT(a, b, c) LINUX_VERSION_CODE < KERNEL_VERSION (2, 6, (b + 40)) #else /* This is anyways lesser than any 3.x versions */ # define COMPAT_LINUX_VERSION_CHECK_LT(a, b, c) 1 #endif #endif /* __COMPAT_VERSION_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/driver-config.h0000644765153500003110000000431412220061556022425 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * Sets the proper defines from the Linux header files * * This file must be included before the inclusion of any kernel header file, * with the exception of linux/autoconf.h and linux/version.h --hpreg */ #ifndef __VMX_CONFIG_H__ #define __VMX_CONFIG_H__ #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_DISTRIBUTE #define INCLUDE_ALLOW_VMKDRIVERS #include "includeCheck.h" #include "compat_version.h" #include "compat_autoconf.h" /* * We rely on Kernel Module support. Check here. */ #ifndef CONFIG_MODULES # error "No Module support in this kernel. Please configure with CONFIG_MODULES" #endif /* * 2.2 kernels still use __SMP__ (derived from CONFIG_SMP * in the main Makefile), so we do it here. */ #ifdef CONFIG_SMP # define __SMP__ 1 #endif #if defined(CONFIG_MODVERSIONS) && defined(KERNEL_2_1) # if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,60) /* * MODVERSIONS might be already defined when using kernel's Makefiles. */ # ifndef MODVERSIONS # define MODVERSIONS # endif # include # endif #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) /* * Force the uintptr_t definition to come from linux/types.h instead of vm_basic_types.h. */ # include # define _STDINT_H 1 #endif #ifndef __KERNEL__ # define __KERNEL__ #endif #endif open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_log2.h0000644765153500003110000000367212220061556022103 0ustar dtormts/********************************************************* * Copyright (C) 2011 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_LOG2_H__ # define __COMPAT_LOG2_H__ #ifndef LINUX_VERSION_CODE # error "Include compat_version.h before compat_log2.h" #endif /* linux/log2.h was introduced in 2.6.20. */ #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 19) # include #endif /* * is_power_of_2 was introduced in 2.6.21. This implementation is almost * identical to the one found there. */ #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) #define compat_is_power_of_2(n) is_power_of_2(n) #else static inline __attribute__((const)) int compat_is_power_of_2(unsigned long n) { return (n != 0 && ((n && (n - 1)) == 0)); } #endif /* * rounddown_power_of_two was introduced in 2.6.24. This implementation is * similar to the one in log2.h but with input of int instead of long to * avoid more version related checks for fls_long(). */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) #define compat_rounddown_pow_of_two(n) rounddown_pow_of_two(n) #else static inline __attribute__((const)) unsigned int compat_rounddown_pow_of_two(unsigned int n) { return 1U << (fls(n) -1); } #endif #endif /* __COMPAT_LOG2_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_module.h0000644765153500003110000000437212220061556022523 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * compat_module.h -- */ #ifndef __COMPAT_MODULE_H__ # define __COMPAT_MODULE_H__ #include /* * Modules wishing to use the GPL license are required to include a * MODULE_LICENSE definition in their module source as of 2.4.10. */ #ifndef MODULE_LICENSE #define MODULE_LICENSE(license) #endif /* * To make use of our own home-brewed MODULE_INFO, we need macros to * concatenate two expressions to "__mod_", and and to convert an * expression into a string. I'm sure we've got these in our codebase, * but I'd rather not introduce such a dependency in a compat header. */ #ifndef __module_cat #define __module_cat_1(a, b) __mod_ ## a ## b #define __module_cat(a, b) __module_cat_1(a, b) #endif #ifndef __stringify #define __stringify_1(x) #x #define __stringify(x) __stringify_1(x) #endif /* * MODULE_INFO was born in 2.5.69. */ #ifndef MODULE_INFO #define MODULE_INFO(tag, info) \ static const char __module_cat(tag, __LINE__)[] \ __attribute__((section(".modinfo"), unused)) = __stringify(tag) "=" info #endif /* * MODULE_VERSION was born in 2.6.4. The earlier form appends a long "\0xxx" * string to the module's version, but that was removed in 2.6.10, so we'll * ignore it in our wrapper. */ #ifndef MODULE_VERSION #define MODULE_VERSION(_version) MODULE_INFO(version, _version) #endif #endif /* __COMPAT_MODULE_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_slab.h0000644765153500003110000000665312220061556022163 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_SLAB_H__ # define __COMPAT_SLAB_H__ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0) # include #else # include #endif /* * Before 2.6.20, kmem_cache_t was the accepted way to refer to a kmem_cache * structure. Prior to 2.6.15, this structure was called kmem_cache_s, and * afterwards it was renamed to kmem_cache. Here we keep things simple and use * the accepted typedef until it became deprecated, at which point we switch * over to the kmem_cache name. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) # define compat_kmem_cache struct kmem_cache #else # define compat_kmem_cache kmem_cache_t #endif /* * Up to 2.6.22 kmem_cache_create has 6 arguments - name, size, alignment, flags, * constructor, and destructor. Then for some time kernel was asserting that * destructor is NULL, and since 2.6.23-pre1 kmem_cache_create takes only 5 * arguments - destructor is gone. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) || defined(VMW_KMEMCR_HAS_DTOR) #define compat_kmem_cache_create(name, size, align, flags, ctor) \ kmem_cache_create(name, size, align, flags, ctor, NULL) #else #define compat_kmem_cache_create(name, size, align, flags, ctor) \ kmem_cache_create(name, size, align, flags, ctor) #endif /* * Up to 2.6.23 kmem_cache constructor has three arguments - pointer to block to * prepare (aka "this"), from which cache it came, and some unused flags. After * 2.6.23 flags were removed, and order of "this" and cache parameters was swapped... * Since 2.6.27-rc2 everything is different again, and ctor has only one argument. * * HAS_3_ARGS has precedence over HAS_2_ARGS if both are defined. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) && !defined(VMW_KMEMCR_CTOR_HAS_3_ARGS) # define VMW_KMEMCR_CTOR_HAS_3_ARGS #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) && !defined(VMW_KMEMCR_CTOR_HAS_2_ARGS) # define VMW_KMEMCR_CTOR_HAS_2_ARGS #endif #if defined(VMW_KMEMCR_CTOR_HAS_3_ARGS) typedef void compat_kmem_cache_ctor(void *, compat_kmem_cache *, unsigned long); #define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) void *arg, \ compat_kmem_cache *cache, \ unsigned long flags #elif defined(VMW_KMEMCR_CTOR_HAS_2_ARGS) typedef void compat_kmem_cache_ctor(compat_kmem_cache *, void *); #define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) compat_kmem_cache *cache, \ void *arg #else typedef void compat_kmem_cache_ctor(void *); #define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) void *arg #endif #endif /* __COMPAT_SLAB_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_timer.h0000644765153500003110000000655112220061556022357 0ustar dtormts/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_TIMER_H__ # define __COMPAT_TIMER_H__ /* * The del_timer_sync() API appeared in 2.3.43 * It became reliable in 2.4.0-test3 * * --hpreg */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) # define compat_del_timer_sync(timer) del_timer_sync(timer) #else # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43) /* 2.3.43 removed asm/softirq.h's reference to bh_base. */ # include # endif # include static inline int compat_del_timer_sync(struct timer_list *timer) // IN { int wasPending; start_bh_atomic(); wasPending = del_timer(timer); end_bh_atomic(); return wasPending; } #endif /* * The msleep_interruptible() API appeared in 2.6.9. * It is based on the msleep() API, which appeared in 2.4.29. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9) # include # define compat_msleep_interruptible(msecs) msleep_interruptible(msecs) # define compat_msleep(msecs) msleep(msecs) #else # include /* * msecs_to_jiffies appeared in 2.6.7. For earlier kernels, * fall back to slow-case code (we don't use this operation * enough to need the performance). */ # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 7) # define msecs_to_jiffies(msecs) (((msecs) * HZ + 999) / 1000) # endif /* * set_current_state appeared in 2.2.18. */ # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) # define set_current_state(a) do { current->state = (a); } while(0) # endif static inline void compat_msleep_interruptible(unsigned long msecs) // IN { set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(msecs_to_jiffies(msecs) + 1); } static inline void compat_msleep(unsigned long msecs) // IN { set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(msecs_to_jiffies(msecs) + 1); } #endif /* * There is init_timer_deferrable() since 2.6.22. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) # define compat_init_timer_deferrable(timer) init_timer_deferrable(timer) #else # define compat_init_timer_deferrable(timer) init_timer(timer) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) static inline void compat_setup_timer(struct timer_list * timer, void (*function)(unsigned long), unsigned long data) { timer->function = function; timer->data = data; init_timer(timer); } #else # define compat_setup_timer(timer, function, data) \ setup_timer(timer, function, data) #endif #endif /* __COMPAT_TIMER_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_pagemap.h0000644765153500003110000000253512220061556022647 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_PAGEMAP_H__ # define __COMPAT_PAGEMAP_H__ #include /* * AOP_FLAG_NOFS was defined in the same changeset that * grab_cache_page_write_begin() was introduced. */ #ifdef AOP_FLAG_NOFS #define compat_grab_cache_page_write_begin(mapping, index, flags) \ grab_cache_page_write_begin((mapping), (index), (flags)) #else #define compat_grab_cache_page_write_begin(mapping, index, flags) \ __grab_cache_page((mapping), (index)); #endif #endif /* __COMPAT_PAGEMAP_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/vmci_iocontrols.h0000644765153500003110000006205712220061556023110 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmci_iocontrols.h * * The VMCI driver io controls. */ #ifndef _VMCI_IOCONTROLS_H_ #define _VMCI_IOCONTROLS_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vm_assert.h" #include "vmci_defs.h" #if defined(_WIN32) && defined(WINNT_DDK) /* We need to expose the API through an IOCTL on Windows. Use latest API. */ #include "vmciKernelAPI.h" #endif // _WIN32 && WINNT_DDK /* *----------------------------------------------------------------------------- * * VMCIVA64ToPtr -- * * Convert a VA64 to a pointer. * * Results: * Virtual address. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void * VMCIVA64ToPtr(VA64 va64) // IN { #ifdef VM_X86_64 ASSERT_ON_COMPILE(sizeof (void *) == 8); #else ASSERT_ON_COMPILE(sizeof (void *) == 4); // Check that nothing of value will be lost. ASSERT(!(va64 >> 32)); #endif return (void *)(uintptr_t)va64; } /* *----------------------------------------------------------------------------- * * VMCIPtrToVA64 -- * * Convert a pointer to a VA64. * * Results: * Virtual address. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE VA64 VMCIPtrToVA64(void const *ptr) // IN { ASSERT_ON_COMPILE(sizeof ptr <= sizeof (VA64)); return (VA64)(uintptr_t)ptr; } /* * Driver version. * * Increment major version when you make an incompatible change. * Compatibility goes both ways (old driver with new executable * as well as new driver with old executable). */ #define VMCI_VERSION_SHIFT_WIDTH 16 /* Never change this. */ #define VMCI_MAKE_VERSION(_major, _minor) ((_major) << \ VMCI_VERSION_SHIFT_WIDTH | \ (uint16) (_minor)) #define VMCI_VERSION_MAJOR(v) ((uint32) (v) >> VMCI_VERSION_SHIFT_WIDTH) #define VMCI_VERSION_MINOR(v) ((uint16) (v)) /* * VMCI_VERSION is always the current version. Subsequently listed * versions are ways of detecting previous versions of the connecting * application (i.e., VMX). * * VMCI_VERSION_NOVMVM: This version removed support for VM to VM * communication. * * VMCI_VERSION_NOTIFY: This version introduced doorbell notification * support. * * VMCI_VERSION_HOSTQP: This version introduced host end point support * for hosted products. * * VMCI_VERSION_PREHOSTQP: This is the version prior to the adoption of * support for host end-points. * * VMCI_VERSION_PREVERS2: This fictional version number is intended to * represent the version of a VMX which doesn't call into the driver * with ioctl VERSION2 and thus doesn't establish its version with the * driver. */ #define VMCI_VERSION VMCI_VERSION_NOVMVM #define VMCI_VERSION_NOVMVM VMCI_MAKE_VERSION(11, 0) #define VMCI_VERSION_NOTIFY VMCI_MAKE_VERSION(10, 0) #define VMCI_VERSION_HOSTQP VMCI_MAKE_VERSION(9, 0) #define VMCI_VERSION_PREHOSTQP VMCI_MAKE_VERSION(8, 0) #define VMCI_VERSION_PREVERS2 VMCI_MAKE_VERSION(1, 0) /* * VMCISockets driver version. The version is platform-dependent and is * embedded in vsock_version.h for each platform. It can be obtained via * VMCISock_Version() (which uses IOCTL_VMCI_SOCKETS_VERSION). The * following is simply for constructing an unsigned integer value from the * comma-separated version in the header. This must match the macros defined * in vmci_sockets.h. An example of using this is: * uint16 parts[4] = { VSOCK_DRIVER_VERSION_COMMAS }; * uint32 version = VMCI_SOCKETS_MAKE_VERSION(parts); */ #define VMCI_SOCKETS_MAKE_VERSION(_p) \ ((((_p)[0] & 0xFF) << 24) | (((_p)[1] & 0xFF) << 16) | ((_p)[2])) #if defined(__linux__) || defined(SOLARIS) || defined(VMKERNEL) /* * Linux defines _IO* macros, but the core kernel code ignore the encoded * ioctl value. It is up to individual drivers to decode the value (for * example to look at the size of a structure to determine which version * of a specific command should be used) or not (which is what we * currently do, so right now the ioctl value for a given command is the * command itself). * * Hence, we just define the IOCTL_VMCI_foo values directly, with no * intermediate IOCTLCMD_ representation. */ # define IOCTLCMD(_cmd) IOCTL_VMCI_ ## _cmd #elif defined (__APPLE__) #include #define IOCTLCMD(_cmd) IOCTL_VMCI_ ## _cmd #define IOCTLCMD_I(_cmd, _type) \ IOCTL_VMCI_MACOS_ ## _cmd = _IOW('V', IOCTL_VMCI_ ## _cmd, _type) #define IOCTLCMD_O(_cmd, _type) \ IOCTL_VMCI_MACOS_ ## _cmd = _IOR('V', IOCTL_VMCI_ ## _cmd, _type) #define IOCTLCMD_IO(_cmd, _type) \ IOCTL_VMCI_MACOS_ ## _cmd = _IOWR('V', IOCTL_VMCI_ ## _cmd, _type) #else // if defined(__linux__) /* * On platforms other than Linux, IOCTLCMD_foo values are just numbers, and * we build the IOCTL_VMCI_foo values around these using platform-specific * format for encoding arguments and sizes. */ # define IOCTLCMD(_cmd) IOCTLCMD_VMCI_ ## _cmd #endif enum IOCTLCmd_VMCI { /* * We need to bracket the range of values used for ioctls, because x86_64 * Linux forces us to explicitly register ioctl handlers by value for * handling 32 bit ioctl syscalls. Hence FIRST and LAST. Pick something * for FIRST that doesn't collide with vmmon (2001+). */ #if defined(__linux__) IOCTLCMD(FIRST) = 1951, #else /* Start at 0. */ IOCTLCMD(FIRST), #endif IOCTLCMD(VERSION) = IOCTLCMD(FIRST), /* BEGIN VMCI */ IOCTLCMD(INIT_CONTEXT), /* * The following two were used for process and datagram process creation. * They are not used anymore and reserved for future use. * They will fail if issued. */ IOCTLCMD(RESERVED1), IOCTLCMD(RESERVED2), /* * The following used to be for shared memory. It is now unused and and is * reserved for future use. It will fail if issued. */ IOCTLCMD(RESERVED3), /* * The follwoing three were also used to be for shared memory. An * old WS6 user-mode client might try to use them with the new * driver, but since we ensure that only contexts created by VMX'en * of the appropriate version (VMCI_VERSION_NOTIFY or * VMCI_VERSION_NEWQP) or higher use these ioctl, everything is * fine. */ IOCTLCMD(QUEUEPAIR_SETVA), IOCTLCMD(NOTIFY_RESOURCE), IOCTLCMD(NOTIFICATIONS_RECEIVE), IOCTLCMD(VERSION2), IOCTLCMD(QUEUEPAIR_ALLOC), IOCTLCMD(QUEUEPAIR_SETPAGEFILE), IOCTLCMD(QUEUEPAIR_DETACH), IOCTLCMD(DATAGRAM_SEND), IOCTLCMD(DATAGRAM_RECEIVE), IOCTLCMD(DATAGRAM_REQUEST_MAP), IOCTLCMD(DATAGRAM_REMOVE_MAP), IOCTLCMD(CTX_ADD_NOTIFICATION), IOCTLCMD(CTX_REMOVE_NOTIFICATION), IOCTLCMD(CTX_GET_CPT_STATE), IOCTLCMD(CTX_SET_CPT_STATE), IOCTLCMD(GET_CONTEXT_ID), /* END VMCI */ /* * BEGIN VMCI SOCKETS * * We mark the end of the vmci commands and the start of the vmci sockets * commands since they are used in separate modules on Linux. * */ IOCTLCMD(LAST), IOCTLCMD(SOCKETS_FIRST) = IOCTLCMD(LAST), /* * This used to be for accept() on Windows and Mac OS, which is now * redundant (since we now use real handles). It is used instead for * getting the version. This value is now public, so it cannot change. */ IOCTLCMD(SOCKETS_VERSION) = IOCTLCMD(SOCKETS_FIRST), IOCTLCMD(SOCKETS_BIND), /* * This used to be for close() on Windows and Mac OS, but is no longer * used for the same reason as accept() above. It is used instead for * sending private symbols to the Mac OS driver. */ IOCTLCMD(SOCKETS_SET_SYMBOLS), IOCTLCMD(SOCKETS_CONNECT), /* * The next two values are public (vmci_sockets.h) and cannot be changed. * That means the number of values above these cannot be changed either * unless the base index (specified below) is updated accordingly. */ IOCTLCMD(SOCKETS_GET_AF_VALUE), IOCTLCMD(SOCKETS_GET_LOCAL_CID), IOCTLCMD(SOCKETS_GET_SOCK_NAME), IOCTLCMD(SOCKETS_GET_SOCK_OPT), IOCTLCMD(SOCKETS_GET_VM_BY_NAME), IOCTLCMD(SOCKETS_IOCTL), IOCTLCMD(SOCKETS_LISTEN), IOCTLCMD(SOCKETS_RECV), IOCTLCMD(SOCKETS_RECV_FROM), IOCTLCMD(SOCKETS_SELECT), IOCTLCMD(SOCKETS_SEND), IOCTLCMD(SOCKETS_SEND_TO), IOCTLCMD(SOCKETS_SET_SOCK_OPT), IOCTLCMD(SOCKETS_SHUTDOWN), IOCTLCMD(SOCKETS_SOCKET), IOCTLCMD(SOCKETS_UUID_2_CID), /* 1991 on Linux. */ /* END VMCI SOCKETS */ /* * We reserve a range of 3 ioctls for VMCI Sockets to grow. We cannot * reserve many ioctls here since we are close to overlapping with vmmon * ioctls. Define a meta-ioctl if running out of this binary space. */ // Must be last. IOCTLCMD(SOCKETS_LAST) = IOCTLCMD(SOCKETS_UUID_2_CID) + 3, /* 1994 on Linux. */ /* * The VSockets ioctls occupy the block above. We define a new range of * VMCI ioctls to maintain binary compatibility between the user land and * the kernel driver. Careful, vmmon ioctls start from 2001, so this means * we can add only 4 new VMCI ioctls. Define a meta-ioctl if running out of * this binary space. */ IOCTLCMD(FIRST2), IOCTLCMD(SET_NOTIFY) = IOCTLCMD(FIRST2), /* 1995 on Linux. */ IOCTLCMD(LAST2), }; #if defined (__APPLE__) /* * The size of this must match the size of VSockIoctlPrivSyms in * modules/vsock/common/vsockIoctl.h. */ #include "vmware_pack_begin.h" struct IOCTLCmd_VMCIMacOS_PrivSyms { char data[344]; } #include "vmware_pack_end.h" ; enum IOCTLCmd_VMCIMacOS { IOCTLCMD_I(SOCKETS_SET_SYMBOLS, struct IOCTLCmd_VMCIMacOS_PrivSyms), IOCTLCMD_O(SOCKETS_VERSION, unsigned int), IOCTLCMD_O(SOCKETS_GET_AF_VALUE, int), IOCTLCMD_O(SOCKETS_GET_LOCAL_CID, unsigned int), }; #endif // __APPLE__ #if defined _WIN32 /* * Windows VMCI ioctl definitions. */ /* PUBLIC: For VMCISockets user-mode clients that use CreateFile(). */ #define VMCI_INTERFACE_VSOCK_PUBLIC_NAME TEXT("\\\\.\\VMCI") /* PUBLIC: For VMCISockets user-mode clients that use NtCreateFile(). */ #define VMCI_INTERFACE_VSOCK_PUBLIC_NAME_NT L"\\??\\VMCI" /* PUBLIC: For the VMX, which uses CreateFile(). */ #define VMCI_INTERFACE_VMX_PUBLIC_NAME TEXT("\\\\.\\VMCIDev\\VMX") /* PRIVATE NAMES */ #define VMCI_DEVICE_VMCI_LINK_PATH L"\\DosDevices\\VMCIDev" #define VMCI_DEVICE_VSOCK_LINK_PATH L"\\DosDevices\\vmci" #define VMCI_DEVICE_HOST_NAME_PATH L"\\Device\\VMCIHostDev" #define VMCI_DEVICE_GUEST_NAME_PATH L"\\Device\\VMCIGuestDev" /* PRIVATE NAMES */ /* These values cannot be changed since some of the ioctl values are public. */ #define FILE_DEVICE_VMCI 0x8103 #define VMCI_IOCTL_BASE_INDEX 0x801 #define VMCIIOCTL_BUFFERED(name) \ CTL_CODE(FILE_DEVICE_VMCI, \ VMCI_IOCTL_BASE_INDEX + IOCTLCMD_VMCI_ ## name, \ METHOD_BUFFERED, \ FILE_ANY_ACCESS) #define VMCIIOCTL_NEITHER(name) \ CTL_CODE(FILE_DEVICE_VMCI, \ VMCI_IOCTL_BASE_INDEX + IOCTLCMD_VMCI_ ## name, \ METHOD_NEITHER, \ FILE_ANY_ACCESS) enum IOCTLCmd_VMCIWin32 { IOCTLCMD(DEVICE_GET) = IOCTLCMD(LAST2) + 1, IOCTLCMD(SOCKETS_SERVICE_GET), IOCTLCMD(SOCKETS_STOP), }; #define IOCTL_VMCI_VERSION VMCIIOCTL_BUFFERED(VERSION) /* BEGIN VMCI */ #define IOCTL_VMCI_INIT_CONTEXT \ VMCIIOCTL_BUFFERED(INIT_CONTEXT) #define IOCTL_VMCI_HYPERCALL \ VMCIIOCTL_BUFFERED(HYPERCALL) #define IOCTL_VMCI_CREATE_DATAGRAM_HANDLE \ VMCIIOCTL_BUFFERED(CREATE_DATAGRAM_HANDLE) #define IOCTL_VMCI_DESTROY_DATAGRAM_HANDLE \ VMCIIOCTL_BUFFERED(DESTROY_DATAGRAM_HANDLE) #define IOCTL_VMCI_NOTIFY_RESOURCE \ VMCIIOCTL_BUFFERED(NOTIFY_RESOURCE) #define IOCTL_VMCI_NOTIFICATIONS_RECEIVE \ VMCIIOCTL_BUFFERED(NOTIFICATIONS_RECEIVE) #define IOCTL_VMCI_VERSION2 \ VMCIIOCTL_BUFFERED(VERSION2) #define IOCTL_VMCI_QUEUEPAIR_ALLOC \ VMCIIOCTL_BUFFERED(QUEUEPAIR_ALLOC) #define IOCTL_VMCI_QUEUEPAIR_SETVA \ VMCIIOCTL_BUFFERED(QUEUEPAIR_SETVA) #define IOCTL_VMCI_QUEUEPAIR_SETPAGEFILE \ VMCIIOCTL_BUFFERED(QUEUEPAIR_SETPAGEFILE) #define IOCTL_VMCI_QUEUEPAIR_DETACH \ VMCIIOCTL_BUFFERED(QUEUEPAIR_DETACH) #define IOCTL_VMCI_DATAGRAM_SEND \ VMCIIOCTL_BUFFERED(DATAGRAM_SEND) #define IOCTL_VMCI_DATAGRAM_RECEIVE \ VMCIIOCTL_NEITHER(DATAGRAM_RECEIVE) #define IOCTL_VMCI_DATAGRAM_REQUEST_MAP \ VMCIIOCTL_BUFFERED(DATAGRAM_REQUEST_MAP) #define IOCTL_VMCI_DATAGRAM_REMOVE_MAP \ VMCIIOCTL_BUFFERED(DATAGRAM_REMOVE_MAP) #define IOCTL_VMCI_CTX_ADD_NOTIFICATION \ VMCIIOCTL_BUFFERED(CTX_ADD_NOTIFICATION) #define IOCTL_VMCI_CTX_REMOVE_NOTIFICATION \ VMCIIOCTL_BUFFERED(CTX_REMOVE_NOTIFICATION) #define IOCTL_VMCI_CTX_GET_CPT_STATE \ VMCIIOCTL_BUFFERED(CTX_GET_CPT_STATE) #define IOCTL_VMCI_CTX_SET_CPT_STATE \ VMCIIOCTL_BUFFERED(CTX_SET_CPT_STATE) #define IOCTL_VMCI_GET_CONTEXT_ID \ VMCIIOCTL_BUFFERED(GET_CONTEXT_ID) #define IOCTL_VMCI_DEVICE_GET \ VMCIIOCTL_BUFFERED(DEVICE_GET) /* END VMCI */ /* BEGIN VMCI SOCKETS */ #define IOCTL_VMCI_SOCKETS_VERSION \ VMCIIOCTL_BUFFERED(SOCKETS_VERSION) #define IOCTL_VMCI_SOCKETS_BIND \ VMCIIOCTL_BUFFERED(SOCKETS_BIND) #define IOCTL_VMCI_SOCKETS_CONNECT \ VMCIIOCTL_BUFFERED(SOCKETS_CONNECT) #define IOCTL_VMCI_SOCKETS_GET_AF_VALUE \ VMCIIOCTL_BUFFERED(SOCKETS_GET_AF_VALUE) #define IOCTL_VMCI_SOCKETS_GET_LOCAL_CID \ VMCIIOCTL_BUFFERED(SOCKETS_GET_LOCAL_CID) #define IOCTL_VMCI_SOCKETS_GET_SOCK_NAME \ VMCIIOCTL_BUFFERED(SOCKETS_GET_SOCK_NAME) #define IOCTL_VMCI_SOCKETS_GET_SOCK_OPT \ VMCIIOCTL_BUFFERED(SOCKETS_GET_SOCK_OPT) #define IOCTL_VMCI_SOCKETS_GET_VM_BY_NAME \ VMCIIOCTL_BUFFERED(SOCKETS_GET_VM_BY_NAME) #define IOCTL_VMCI_SOCKETS_IOCTL \ VMCIIOCTL_BUFFERED(SOCKETS_IOCTL) #define IOCTL_VMCI_SOCKETS_LISTEN \ VMCIIOCTL_BUFFERED(SOCKETS_LISTEN) #define IOCTL_VMCI_SOCKETS_RECV_FROM \ VMCIIOCTL_BUFFERED(SOCKETS_RECV_FROM) #define IOCTL_VMCI_SOCKETS_SELECT \ VMCIIOCTL_BUFFERED(SOCKETS_SELECT) #define IOCTL_VMCI_SOCKETS_SEND_TO \ VMCIIOCTL_BUFFERED(SOCKETS_SEND_TO) #define IOCTL_VMCI_SOCKETS_SET_SOCK_OPT \ VMCIIOCTL_BUFFERED(SOCKETS_SET_SOCK_OPT) #define IOCTL_VMCI_SOCKETS_SHUTDOWN \ VMCIIOCTL_BUFFERED(SOCKETS_SHUTDOWN) #define IOCTL_VMCI_SOCKETS_SERVICE_GET \ VMCIIOCTL_BUFFERED(SOCKETS_SERVICE_GET) #define IOCTL_VMCI_SOCKETS_STOP \ VMCIIOCTL_NEITHER(SOCKETS_STOP) /* END VMCI SOCKETS */ #endif // _WIN32 /* * VMCI driver initialization. This block can also be used to * pass initial group membership etc. */ typedef struct VMCIInitBlock { VMCIId cid; VMCIPrivilegeFlags flags; #ifdef _WIN32 uint64 event; /* Handle for signalling vmci calls on windows. */ #endif // _WIN32 } VMCIInitBlock; typedef struct VMCISharedMemInfo { VMCIHandle handle; uint32 size; uint32 result; VA64 va; /* Currently only used in the guest. */ char pageFileName[VMCI_PATH_MAX]; } VMCISharedMemInfo; typedef struct VMCIQueuePairAllocInfo_VMToVM { VMCIHandle handle; VMCIId peer; uint32 flags; uint64 produceSize; uint64 consumeSize; #if !defined(VMX86_SERVER) && !defined(VMKERNEL) VA64 producePageFile; /* User VA. */ VA64 consumePageFile; /* User VA. */ uint64 producePageFileSize; /* Size of the file name array. */ uint64 consumePageFileSize; /* Size of the file name array. */ #else PPN * PPNs; uint64 numPPNs; #endif int32 result; uint32 _pad; } VMCIQueuePairAllocInfo_VMToVM; typedef struct VMCIQueuePairAllocInfo { VMCIHandle handle; VMCIId peer; uint32 flags; uint64 produceSize; uint64 consumeSize; #if !defined(VMX86_SERVER) && !defined(VMKERNEL) VA64 ppnVA; /* Start VA of queue pair PPNs. */ #else PPN * PPNs; #endif uint64 numPPNs; int32 result; uint32 version; } VMCIQueuePairAllocInfo; typedef struct VMCIQueuePairSetVAInfo { VMCIHandle handle; VA64 va; /* Start VA of queue pair PPNs. */ uint64 numPPNs; uint32 version; int32 result; } VMCIQueuePairSetVAInfo; /* * For backwards compatibility, here is a version of the * VMCIQueuePairPageFileInfo before host support end-points was added. * Note that the current version of that structure requires VMX to * pass down the VA of the mapped file. Before host support was added * there was nothing of the sort. So, when the driver sees the ioctl * with a parameter that is the sizeof * VMCIQueuePairPageFileInfo_NoHostQP then it can infer that the version * of VMX running can't attach to host end points because it doesn't * provide the VA of the mapped files. * * The Linux driver doesn't get an indication of the size of the * structure passed down from user space. So, to fix a long standing * but unfiled bug, the _pad field has been renamed to version. * Existing versions of VMX always initialize the PageFileInfo * structure so that _pad, er, version is set to 0. * * A version value of 1 indicates that the size of the structure has * been increased to include two UVA's: produceUVA and consumeUVA. * These UVA's are of the mmap()'d queue contents backing files. * * In addition, if when VMX is sending down the * VMCIQueuePairPageFileInfo structure it gets an error then it will * try again with the _NoHostQP version of the file to see if an older * VMCI kernel module is running. */ typedef struct VMCIQueuePairPageFileInfo_NoHostQP { VMCIHandle handle; VA64 producePageFile; /* User VA. */ VA64 consumePageFile; /* User VA. */ uint64 producePageFileSize; /* Size of the file name array. */ uint64 consumePageFileSize; /* Size of the file name array. */ int32 result; uint32 version; /* Was _pad. Must be 0. */ } VMCIQueuePairPageFileInfo_NoHostQP; typedef struct VMCIQueuePairPageFileInfo { VMCIHandle handle; #if !defined(VMX86_SERVER) && !defined(VMKERNEL) VA64 producePageFile; /* User VA. */ VA64 consumePageFile; /* User VA. */ uint64 producePageFileSize; /* Size of the file name array. */ uint64 consumePageFileSize; /* Size of the file name array. */ #endif int32 result; uint32 version; /* Was _pad. */ VA64 produceVA; /* User VA of the mapped file. */ VA64 consumeVA; /* User VA of the mapped file. */ } VMCIQueuePairPageFileInfo; typedef struct VMCIQueuePairDetachInfo { VMCIHandle handle; int32 result; uint32 _pad; } VMCIQueuePairDetachInfo; typedef struct VMCIDatagramSendRecvInfo { VA64 addr; uint32 len; int32 result; } VMCIDatagramSendRecvInfo; /* Used to add/remove well-known datagram mappings. */ typedef struct VMCIDatagramMapInfo { VMCIId wellKnownID; int result; } VMCIDatagramMapInfo; /* Used to add/remove remote context notifications. */ typedef struct VMCINotifyAddRemoveInfo { VMCIId remoteCID; int result; } VMCINotifyAddRemoveInfo; /* Used to set/get current context's checkpoint state. */ typedef struct VMCICptBufInfo { VA64 cptBuf; uint32 cptType; uint32 bufSize; int32 result; uint32 _pad; } VMCICptBufInfo; /* Used to pass notify flag's address to the host driver. */ typedef struct VMCISetNotifyInfo { VA64 notifyUVA; int32 result; uint32 _pad; } VMCISetNotifyInfo; #define VMCI_NOTIFY_RESOURCE_QUEUE_PAIR 0 #define VMCI_NOTIFY_RESOURCE_DOOR_BELL 1 #define VMCI_NOTIFY_RESOURCE_ACTION_NOTIFY 0 #define VMCI_NOTIFY_RESOURCE_ACTION_CREATE 1 #define VMCI_NOTIFY_RESOURCE_ACTION_DESTROY 2 /* * Used to create and destroy doorbells, and generate a notification * for a doorbell or queue pair. */ typedef struct VMCINotifyResourceInfo { VMCIHandle handle; uint16 resource; uint16 action; int32 result; } VMCINotifyResourceInfo; /* * Used to recieve pending notifications for doorbells and queue * pairs. */ typedef struct VMCINotificationReceiveInfo { VA64 dbHandleBufUVA; uint64 dbHandleBufSize; VA64 qpHandleBufUVA; uint64 qpHandleBufSize; int32 result; uint32 _pad; } VMCINotificationReceiveInfo; #if defined(_WIN32) && defined(WINNT_DDK) /* * Used on Windows to expose the API calls that are no longer exported. This * is kernel-mode only, and both sides will have the same bitness, so we can * use pointers directly. */ /* Version 1. */ typedef struct VMCIDeviceGetInfoVer1 { VMCI_DeviceReleaseFct *deviceRelease; VMCIDatagram_CreateHndFct *dgramCreateHnd; VMCIDatagram_CreateHndPrivFct *dgramCreateHndPriv; VMCIDatagram_DestroyHndFct *dgramDestroyHnd; VMCIDatagram_SendFct *dgramSend; VMCI_GetContextIDFct *getContextId; VMCI_VersionFct *version; VMCIEvent_SubscribeFct *eventSubscribe; VMCIEvent_UnsubscribeFct *eventUnsubscribe; VMCIQPair_AllocFct *qpairAlloc; VMCIQPair_DetachFct *qpairDetach; VMCIQPair_GetProduceIndexesFct *qpairGetProduceIndexes; VMCIQPair_GetConsumeIndexesFct *qpairGetConsumeIndexes; VMCIQPair_ProduceFreeSpaceFct *qpairProduceFreeSpace; VMCIQPair_ProduceBufReadyFct *qpairProduceBufReady; VMCIQPair_ConsumeFreeSpaceFct *qpairConsumeFreeSpace; VMCIQPair_ConsumeBufReadyFct *qpairConsumeBufReady; VMCIQPair_EnqueueFct *qpairEnqueue; VMCIQPair_DequeueFct *qpairDequeue; VMCIQPair_PeekFct *qpairPeek; VMCIQPair_EnqueueVFct *qpairEnqueueV; VMCIQPair_DequeueVFct *qpairDequeueV; VMCIQPair_PeekVFct *qpairPeekV; VMCI_ContextID2HostVmIDFct *contextID2HostVmID; VMCI_IsContextOwnerFct *isContextOwner; VMCIContext_GetPrivFlagsFct *contextGetPrivFlags; } VMCIDeviceGetInfoVer1; /* Version 2. */ typedef struct VMCIDeviceGetInfoVer2 { VMCIDoorbell_CreateFct *doorbellCreate; VMCIDoorbell_DestroyFct *doorbellDestroy; VMCIDoorbell_NotifyFct *doorbellNotify; } VMCIDeviceGetInfoVer2; typedef struct VMCIDeviceGetInfoHdr { /* Requested API version on input, supported version on output. */ uint32 apiVersion; VMCI_DeviceShutdownFn *deviceShutdownCB; void *userData; void *deviceRegistration; } VMCIDeviceGetInfoHdr; /* Combination of all versions. */ typedef struct VMCIDeviceGetInfo { VMCIDeviceGetInfoHdr hdr; VMCIDeviceGetInfoVer1 ver1; VMCIDeviceGetInfoVer2 ver2; } VMCIDeviceGetInfo; #endif // _WIN32 && WINNT_DDK #ifdef __APPLE__ /* * Mac OS ioctl definitions. * * Mac OS defines _IO* macros, and the core kernel code uses the size encoded * in the ioctl value to copy the memory back and forth (depending on the * direction encoded in the ioctl value) between the user and kernel address * spaces. * See iocontrolsMacOS.h for details on how this is done. We use sockets only * for vmci. */ #include enum VMCrossTalkSockOpt { VMCI_SO_VERSION = 0, VMCI_SO_CONTEXT = IOCTL_VMCI_INIT_CONTEXT, VMCI_SO_NOTIFY_RESOURCE = IOCTL_VMCI_NOTIFY_RESOURCE, VMCI_SO_NOTIFICATIONS_RECEIVE = IOCTL_VMCI_NOTIFICATIONS_RECEIVE, VMCI_SO_VERSION2 = IOCTL_VMCI_VERSION2, VMCI_SO_QUEUEPAIR_ALLOC = IOCTL_VMCI_QUEUEPAIR_ALLOC, VMCI_SO_QUEUEPAIR_SETVA = IOCTL_VMCI_QUEUEPAIR_SETVA, VMCI_SO_QUEUEPAIR_SETPAGEFILE = IOCTL_VMCI_QUEUEPAIR_SETPAGEFILE, VMCI_SO_QUEUEPAIR_DETACH = IOCTL_VMCI_QUEUEPAIR_DETACH, VMCI_SO_DATAGRAM_SEND = IOCTL_VMCI_DATAGRAM_SEND, VMCI_SO_DATAGRAM_RECEIVE = IOCTL_VMCI_DATAGRAM_RECEIVE, VMCI_SO_DATAGRAM_REQUEST_MAP = IOCTL_VMCI_DATAGRAM_REQUEST_MAP, VMCI_SO_DATAGRAM_REMOVE_MAP = IOCTL_VMCI_DATAGRAM_REMOVE_MAP, VMCI_SO_CTX_ADD_NOTIFICATION = IOCTL_VMCI_CTX_ADD_NOTIFICATION, VMCI_SO_CTX_REMOVE_NOTIFICATION = IOCTL_VMCI_CTX_REMOVE_NOTIFICATION, VMCI_SO_CTX_GET_CPT_STATE = IOCTL_VMCI_CTX_GET_CPT_STATE, VMCI_SO_CTX_SET_CPT_STATE = IOCTL_VMCI_CTX_SET_CPT_STATE, VMCI_SO_GET_CONTEXT_ID = IOCTL_VMCI_GET_CONTEXT_ID, VMCI_SO_USERFD, }; #define VMCI_MACOS_HOST_DEVICE "com.vmware.kext.vmci" #endif /* Clean up helper macros */ #undef IOCTLCMD #endif // ifndef _VMCI_IOCONTROLS_H_ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_scsi.h0000644765153500003110000000302412220061556022170 0ustar dtormts/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_SCSI_H__ # define __COMPAT_SCSI_H__ /* The scsi_bufflen() API appeared somewhere in time --hpreg */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) # define scsi_bufflen(cmd) ((cmd)->request_bufflen) # define scsi_sg_count(cmd) ((cmd)->use_sg) # define scsi_sglist(cmd) ((struct scatterlist *)(cmd)->request_buffer) # define scsi_set_resid(cmd, _resid) ((cmd)->resid = _resid) #endif /* * Using scsi_sglist to access the request buffer looks strange * so instead we define this macro. What happened is later kernel * put all SCSI data in sglists, since it simplifies passing buffers */ #define scsi_request_buffer(cmd) scsi_sglist(cmd) #endif /* __COMPAT_SCSI_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_pci.h0000644765153500003110000000515212220061556022006 0ustar dtormts/********************************************************* * Copyright (C) 1999 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * compat_pci.h: PCI compatibility wrappers. */ #ifndef __COMPAT_PCI_H__ #define __COMPAT_PCI_H__ #include "compat_ioport.h" #include #ifndef DMA_BIT_MASK # define DMA_BIT_MASK(n) DMA_##n##BIT_MASK #endif /* * Power Management related compat wrappers. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10) # define compat_pci_save_state(pdev) pci_save_state((pdev), NULL) # define compat_pci_restore_state(pdev) pci_restore_state((pdev), NULL) #else # define compat_pci_save_state(pdev) pci_save_state((pdev)) # define compat_pci_restore_state(pdev) pci_restore_state((pdev)) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) # define pm_message_t u32 # define compat_pci_choose_state(pdev, state) (state) # define PCI_D0 0 # define PCI_D3hot 3 #else # define compat_pci_choose_state(pdev, state) pci_choose_state((pdev), (state)) #endif /* 2.6.14 changed the PCI shutdown callback */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14) # define COMPAT_PCI_SHUTDOWN(func) .driver = { .shutdown = (func), } # define COMPAT_PCI_DECLARE_SHUTDOWN(func, var) (func)(struct device *(var)) # define COMPAT_PCI_TO_DEV(dev) (to_pci_dev(dev)) #else # define COMPAT_PCI_SHUTDOWN(func) .shutdown = (func) # define COMPAT_PCI_DECLARE_SHUTDOWN(func, var) (func)(struct pci_dev *(var)) # define COMPAT_PCI_TO_DEV(dev) (dev) #endif /* 2.6.26 introduced the device_set_wakeup_enable() function */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) # define compat_device_set_wakeup_enable(dev, val) do {} while(0) #else # define compat_device_set_wakeup_enable(dev, val) \ device_set_wakeup_enable(dev, val) #endif #endif /* __COMPAT_PCI_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_fs.h0000644765153500003110000002427712220061556021654 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_FS_H__ # define __COMPAT_FS_H__ #include /* * 2.6.5+ kernels define FS_BINARY_MOUNTDATA. Since it didn't exist and * wasn't used prior, it's safe to define it to zero. */ #ifndef FS_BINARY_MOUNTDATA #define FS_BINARY_MOUNTDATA 0 #endif /* * MAX_LFS_FILESIZE wasn't defined until 2.5.4. */ #ifndef MAX_LFS_FILESIZE # include # if BITS_PER_LONG == 32 # define MAX_LFS_FILESIZE (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG - 1)) - 1) # elif BITS_PER_LONG == 64 # define MAX_LFS_FILESIZE 0x7fffffffffffffffUL # endif #endif /* * sendfile as a VFS op was born in 2.5.30. Unfortunately, it also changed * signatures, first in 2.5.47, then again in 2.5.70, then again in 2.6.8. * Luckily, the 2.6.8+ signature is the same as the 2.5.47 signature. And * as of 2.6.23-rc1 sendfile is gone, replaced by splice_read... * * Let's not support sendfile from 2.5.30 to 2.5.47, because the 2.5.30 * signature is much different and file_send_actor isn't externed. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) #define VMW_SENDFILE_NONE #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8) #define VMW_SENDFILE_NEW #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 70) #define VMW_SENDFILE_OLD #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 47) #define VMW_SENDFILE_NEW #else #define VMW_SENDFILE_NONE #endif /* * splice_read is there since 2.6.17, but let's avoid 2.6.17-rcX kernels... * After all nobody is using splice system call until 2.6.23 using it to * implement sendfile. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) #define VMW_SPLICE_READ 1 #endif /* * Filesystems wishing to use generic page cache read/write routines are * supposed to implement aio_read and aio_write (calling into * generic_file_aio_read() and generic_file_aio_write() if necessary). * * The VFS exports do_sync_read() and do_sync_write() as the "new" * generic_file_read() and generic_file_write(), but filesystems need not * actually implement read and write- the VFS will automatically call * do_sync_write() and do_sync_read() when applications invoke the standard * read() and write() system calls. * * In 2.6.19, generic_file_read() and generic_file_write() were removed, * necessitating this change. AIO dates as far back as 2.5.42, but the API has * changed over time, so for simplicity, we'll only enable it from 2.6.19 and * on. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) # define VMW_USE_AIO #endif /* * The alloc_inode and destroy_inode VFS ops didn't exist prior to 2.4.21. * Without these functions, file systems can't embed inodes. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 21) # define VMW_EMBED_INODE #endif /* * iget() was removed from the VFS as of 2.6.25-rc1. The replacement for iget() * is iget_locked() which was added in 2.5.17. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 17) # define VMW_USE_IGET_LOCKED #endif /* * parent_ino was born in 2.5.5. For older kernels, let's use 2.5.5 * implementation. It uses the dcache lock which is OK because per-dentry * locking appeared after 2.5.5. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5) #define compat_parent_ino(dentry) parent_ino(dentry) #else #define compat_parent_ino(dentry) \ ({ \ ino_t res; \ spin_lock(&dcache_lock); \ res = dentry->d_parent->d_inode->i_ino; \ spin_unlock(&dcache_lock); \ res; \ }) #endif /* * putname changed to __putname in 2.6.6. */ #define compat___getname() __getname() #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6) #define compat___putname(name) putname(name) #else #define compat___putname(name) __putname(name) #endif /* * inc_nlink, drop_nlink, and clear_nlink were added in 2.6.19. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) #define compat_inc_nlink(inode) ((inode)->i_nlink++) #define compat_drop_nlink(inode) ((inode)->i_nlink--) #define compat_clear_nlink(inode) ((inode)->i_nlink = 0) #else #define compat_inc_nlink(inode) inc_nlink(inode) #define compat_drop_nlink(inode) drop_nlink(inode) #define compat_clear_nlink(inode) clear_nlink(inode) #endif /* * i_size_write and i_size_read were introduced in 2.6.0-test1 * (though we'll look for them as of 2.6.1). They employ slightly different * locking in order to guarantee atomicity, depending on the length of a long, * whether the kernel is SMP, or whether the kernel is preemptible. Prior to * i_size_write and i_size_read, there was no such locking, so that's the * behavior we'll emulate. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 1) #define compat_i_size_read(inode) ((inode)->i_size) #define compat_i_size_write(inode, size) ((inode)->i_size = size) #else #define compat_i_size_read(inode) i_size_read(inode) #define compat_i_size_write(inode, size) i_size_write(inode, size) #endif /* * filemap_fdatawrite was introduced in 2.5.12. Prior to that, modules used * filemap_fdatasync instead. In 2.4.18, both filemap_fdatawrite and * filemap_fdatawait began returning status codes. Prior to that, they were * void functions, so we'll just have them return 0. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 18) #define compat_filemap_fdatawrite(mapping) \ ({ \ int result = 0; \ filemap_fdatasync(mapping); \ result; \ }) #define compat_filemap_fdatawait(mapping) \ ({ \ int result = 0; \ filemap_fdatawait(mapping); \ result; \ }) #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 12) #define compat_filemap_fdatawrite(mapping) filemap_fdatasync(mapping) #define compat_filemap_fdatawait(mapping) filemap_fdatawait(mapping) #else #define compat_filemap_fdatawrite(mapping) filemap_fdatawrite(mapping) #define compat_filemap_fdatawait(mapping) filemap_fdatawait(mapping) #endif /* * filemap_write_and_wait was introduced in 2.6.6 and exported for module use * in 2.6.16. It's really just a simple wrapper around filemap_fdatawrite and * and filemap_fdatawait, which initiates a flush of all dirty pages, then * waits for the pages to flush. The implementation here is a simplified form * of the one found in 2.6.20-rc3. * * Unfortunately, it just isn't possible to implement this prior to 2.4.5, when * neither filemap_fdatawait nor filemap_fdatasync were exported for module * use. So we'll define it out and hope for the best. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 5) #define compat_filemap_write_and_wait(mapping) #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) #define compat_filemap_write_and_wait(mapping) \ ({ \ int result = 0; \ if (mapping->nrpages) { \ result = compat_filemap_fdatawrite(mapping); \ if (result != -EIO) { \ int result2 = compat_filemap_fdatawait(mapping); \ if (!result) { \ result = result2; \ } \ } \ } \ result; \ }) #else #define compat_filemap_write_and_wait(mapping) filemap_write_and_wait(mapping) #endif /* * invalidate_remote_inode was introduced in 2.6.0-test5. Prior to that, * filesystems wishing to invalidate pages belonging to an inode called * invalidate_inode_pages. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) #define compat_invalidate_remote_inode(inode) invalidate_inode_pages(inode) #else #define compat_invalidate_remote_inode(inode) invalidate_remote_inode(inode) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) #define VMW_FSYNC_OLD #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0) typedef umode_t compat_umode_t; #else typedef int compat_umode_t; #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) #define d_make_root(inode) ({ \ struct dentry * ____res = d_alloc_root(inode); \ if (!____res) { \ iput(inode); \ } \ ____res; \ }) #endif #endif /* __COMPAT_FS_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/vmci_infrastructure.h0000644765153500003110000000776612220061556024003 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmci_infrastructure.h -- * * This file implements the VMCI infrastructure. */ #ifndef _VMCI_INFRASTRUCTURE_H_ #define _VMCI_INFRASTRUCTURE_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_DISTRIBUTE #include "includeCheck.h" #include "vmware.h" #include "vmci_defs.h" typedef enum { VMCIOBJ_VMX_VM = 10, VMCIOBJ_CONTEXT, VMCIOBJ_SOCKET, VMCIOBJ_NOT_SET, } VMCIObjType; /* For storing VMCI structures in file handles. */ typedef struct VMCIObj { void *ptr; VMCIObjType type; } VMCIObj; /* Guestcalls currently support a maximum of 8 uint64 arguments. */ #define VMCI_GUESTCALL_MAX_ARGS_SIZE 64 /* * Structure used for checkpointing the doorbell mappings. It is * written to the checkpoint as is, so changing this structure will * break checkpoint compatibility. */ typedef struct VMCIDoorbellCptState { VMCIHandle handle; uint64 bitmapIdx; } VMCIDoorbellCptState; /* Used to determine what checkpoint state to get and set. */ #define VMCI_NOTIFICATION_CPT_STATE 0x1 #define VMCI_WELLKNOWN_CPT_STATE 0x2 #define VMCI_DG_OUT_STATE 0x3 #define VMCI_DG_IN_STATE 0x4 #define VMCI_DG_IN_SIZE_STATE 0x5 #define VMCI_DOORBELL_CPT_STATE 0x6 /* Used to control the VMCI device in the vmkernel */ #define VMCI_DEV_RESET 0x01 #define VMCI_DEV_QP_RESET 0x02 // DEPRECATED #define VMCI_DEV_QUIESCE 0x03 #define VMCI_DEV_UNQUIESCE 0x04 #define VMCI_DEV_QP_BREAK_SHARING 0x05 // DEPRECATED #define VMCI_DEV_RESTORE_SYNC 0x06 #define VMCI_DEV_BMASTER_OFF 0x07 #define VMCI_DEV_BMASTER_ON 0x08 /* *------------------------------------------------------------------------- * * VMCI_Hash -- * * Hash function used by the Simple Datagram API. Based on the djb2 * hash function by Dan Bernstein. * * Result: * Returns guest call size. * * Side effects: * None. * *------------------------------------------------------------------------- */ static INLINE int VMCI_Hash(VMCIHandle handle, // IN unsigned size) // IN { unsigned i; int hash = 5381; const uint64 handleValue = QWORD(handle.resource, handle.context); for (i = 0; i < sizeof handle; i++) { hash = ((hash << 5) + hash) + (uint8)(handleValue >> (i * 8)); } return hash & (size - 1); } /* *------------------------------------------------------------------------- * * VMCI_HashId -- * * Hash function used by the Simple Datagram API. Hashes only a VMCI id * (not the full VMCI handle) Based on the djb2 * hash function by Dan Bernstein. * * Result: * Returns guest call size. * * Side effects: * None. * *------------------------------------------------------------------------- */ static INLINE int VMCI_HashId(VMCIId id, // IN unsigned size) // IN { unsigned i; int hash = 5381; for (i = 0; i < sizeof id; i++) { hash = ((hash << 5) + hash) + (uint8)(id >> (i * 8)); } return hash & (size - 1); } #endif // _VMCI_INFRASTRUCTURE_H_ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_mm.h0000644765153500003110000000663012220061556021646 0ustar dtormts/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_MM_H__ # define __COMPAT_MM_H__ #include /* The get_page() API appeared in 2.3.7 --hpreg */ /* Sometime during development it became function instead of macro --petr */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) && !defined(get_page) # define get_page(_page) atomic_inc(&(_page)->count) /* The __free_page() API is exported in 2.1.67 --hpreg */ # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 67) # define put_page __free_page # else # include "compat_page.h" # define page_to_phys(_page) (page_to_pfn(_page) << PAGE_SHIFT) # define put_page(_page) free_page(page_to_phys(_page)) # endif #endif /* page_count() is 2.4.0 invention. Unfortunately unavailable in some RedHat * kernels (for example 2.4.21-4-RHEL3). */ /* It is function since 2.6.0, and hopefully RedHat will not play silly games * with mm_inline.h again... */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) && !defined(page_count) # define page_count(page) atomic_read(&(page)->count) #endif /* 2.2.x uses 0 instead of some define */ #ifndef NOPAGE_SIGBUS #define NOPAGE_SIGBUS (0) #endif /* 2.2.x does not have HIGHMEM support */ #ifndef GFP_HIGHUSER #define GFP_HIGHUSER (GFP_USER) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) #include "compat_page.h" static inline struct page * alloc_pages(unsigned int gfp_mask, unsigned int order) { unsigned long addr; addr = __get_free_pages(gfp_mask, order); if (!addr) { return NULL; } return virt_to_page(addr); } #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) #endif /* * In 2.4.14, the logic behind the UnlockPage macro was moved to the * unlock_page() function. Later (in 2.5.12), the UnlockPage macro was removed * altogether, and nowadays everyone uses unlock_page(). */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 14) #define compat_unlock_page(page) UnlockPage(page) #else #define compat_unlock_page(page) unlock_page(page) #endif /* * In 2.4.10, vmtruncate was changed from returning void to returning int. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 10) #define compat_vmtruncate(inode, size) \ ({ \ int result = 0; \ vmtruncate(inode, size); \ result; \ }) #else #define compat_vmtruncate(inode, size) vmtruncate(inode, size) #endif #endif /* __COMPAT_MM_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_pci_mapping.h0000644765153500003110000000474112220061556023524 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_PCI_MAPPING_H__ #define __COMPAT_PCI_MAPPING_H__ #include #include #include #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,41) typedef u32 dma_addr_t; static __inline__ int get_order(unsigned long size) { int order; size = (size - 1) >> (PAGE_SHIFT - 1); order = -1; do { size >>= 1; order++; } while (size); return order; } static inline void * compat_pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle) { void *ptr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size)); if (ptr) { memset(ptr, 0, size); *dma_handle = virt_to_phys(ptr); } return ptr; } static inline void compat_pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) { free_pages((unsigned long)vaddr, get_order(size)); } static inline dma_addr_t compat_pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction) { return virt_to_phys(ptr); } static inline void compat_pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction) { } #else #define compat_pci_alloc_consistent(hwdev, size, dma_handle) \ pci_alloc_consistent(hwdev, size, dma_handle) #define compat_pci_free_consistent(hwdev, size, vaddr, dma_handle) \ pci_free_consistent(hwdev, size, vaddr, dma_handle) #define compat_pci_map_single(hwdev, ptr, size, direction) \ pci_map_single(hwdev, ptr, size, direction) #define compat_pci_unmap_single(hwdev, dma_addr, size, direction) \ pci_unmap_single(hwdev, dma_addr, size, direction) #endif #endif open-vm-tools-9.4.0-1280544/modules/linux/shared/kernelStubs.h0000644765153500003110000001134012220061556022165 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * kernelStubs.h * * KernelStubs implements some userspace library functions in terms * of kernel functions to allow library userspace code to be used in a * kernel. */ #ifndef __KERNELSTUBS_H__ #define __KERNELSTUBS_H__ #ifdef linux # ifndef __KERNEL__ # error "__KERNEL__ is not defined" # endif # include "driver-config.h" // Must be included before any other header files # include "vm_basic_types.h" # include # include #elif defined(_WIN32) # include "vm_basic_types.h" # include /* kernel memory APIs */ # include /* for _vsnprintf, vsprintf */ # include /* for va_start stuff */ # include /* for min macro. */ # include "vm_assert.h" /* Our assert macros */ #elif defined(__FreeBSD__) # include "vm_basic_types.h" # ifndef _KERNEL # error "_KERNEL is not defined" # endif # include # include # include # include # include # include #elif defined(__APPLE__) # include "vm_basic_types.h" # ifndef KERNEL # error "KERNEL is not defined" # endif # include # include # elif defined(sun) # include "vm_basic_types.h" # include # include #endif /* * Function Prototypes */ #if defined(linux) || defined(__APPLE__) || defined (sun) # ifdef linux /* if (linux) { */ char *strdup(const char *source); # endif /* Shared between Linux and Apple kernel stubs. */ void *malloc(size_t size); void free(void *mem); void *calloc(size_t num, size_t len); void *realloc(void *ptr, size_t newSize); #elif defined(_WIN32) /* } else if (_WIN32) { */ #if (_WIN32_WINNT == 0x0400) /* The following declarations are missing on NT4. */ typedef unsigned int UINT_PTR; typedef unsigned int SIZE_T; /* No free with tag availaible on NT4 kernel! */ #define KRNL_STUBS_FREE(P,T) ExFreePool((P)) #else /* _WIN32_WINNT */ #define KRNL_STUBS_FREE(P,T) ExFreePoolWithTag((P),(T)) /* Win 2K and later useful kernel function, documented but not declared! */ NTKERNELAPI VOID ExFreePoolWithTag(IN PVOID P, IN ULONG Tag); #endif /* _WIN32_WINNT */ #elif defined(__FreeBSD__) /* } else if (FreeBSD) { */ /* Kernel memory on FreeBSD is tagged for statistics and sanity checking. */ MALLOC_DECLARE(M_VMWARE_TEMP); /* * On FreeBSD, the general memory allocator for both userland and the kernel is named * malloc, but the kernel malloc() takes more arguments. The following alias & macros * work around this, to provide the standard malloc() API for userspace code that is * being used in the kernel. */ # undef malloc static INLINE void * __compat_malloc(unsigned long size, struct malloc_type *type, int flags) { return malloc(size, type, flags); } # define malloc(size) __compat_malloc(size, M_VMWARE_TEMP, M_NOWAIT) # define calloc(count, size) __compat_malloc((count) * (size), \ M_VMWARE_TEMP, M_NOWAIT|M_ZERO) # define realloc(buf, size) realloc(buf, size, M_VMWARE_TEMP, M_NOWAIT) # define free(buf) free(buf, M_VMWARE_TEMP) # define strchr(s,c) index(s,c) # define strrchr(s,c) rindex(s,c) #endif /* } */ /* * Stub functions we provide. */ void Panic(const char *fmt, ...); char *Str_Strcpy(char *buf, const char *src, size_t maxSize); int Str_Vsnprintf(char *str, size_t size, const char *format, va_list arguments); char *Str_Vasprintf(size_t *length, const char *format, va_list arguments); char *Str_Asprintf(size_t *length, const char *Format, ...); /* * Functions the driver must implement for the stubs. */ EXTERN void Debug(const char *fmt, ...); #endif /* __KERNELSTUBS_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_statfs.h0000644765153500003110000000230612220061556022535 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_STATFS_H__ # define __COMPAT_STATFS_H__ /* vfs.h simply include statfs.h, but it knows what directory statfs.h is in. */ #include /* 2.5.74 renamed struct statfs to kstatfs. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 74) #define compat_kstatfs kstatfs #else #define compat_kstatfs statfs #endif #endif /* __COMPAT_STATFS_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/vmciKernelAPI2.h0000644765153500003110000000410412220061556022377 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciKernelAPI2.h -- * * Kernel API (v2) exported from the VMCI host and guest drivers. */ #ifndef __VMCI_KERNELAPI_2_H__ #define __VMCI_KERNELAPI_2_H__ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vmciKernelAPI1.h" /* Define version 2. */ #undef VMCI_KERNEL_API_VERSION #define VMCI_KERNEL_API_VERSION_2 2 #define VMCI_KERNEL_API_VERSION VMCI_KERNEL_API_VERSION_2 /* VMCI Doorbell API. */ #define VMCI_FLAG_DELAYED_CB 0x01 typedef void (*VMCICallback)(void *clientData); int vmci_doorbell_create(VMCIHandle *handle, uint32 flags, VMCIPrivilegeFlags privFlags, VMCICallback notifyCB, void *clientData); int vmci_doorbell_destroy(VMCIHandle handle); int vmci_doorbell_notify(VMCIHandle handle, VMCIPrivilegeFlags privFlags); /* Typedefs for all of the above, used by the IOCTLs and the kernel library. */ typedef int (VMCIDoorbell_CreateFct)(VMCIHandle *, uint32, VMCIPrivilegeFlags, VMCICallback, void *); typedef int (VMCIDoorbell_DestroyFct)(VMCIHandle); typedef int (VMCIDoorbell_NotifyFct)(VMCIHandle, VMCIPrivilegeFlags); #endif /* !__VMCI_KERNELAPI_2_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/driverLog.h0000644765153500003110000000223212220061556021621 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * driverLog.h -- * * Logging functions for Linux kernel modules. */ #ifndef __DRIVERLOG_H__ #define __DRIVERLOG_H__ /* * The definitions of Warning(), Log(), and Panic() come from vm_assert.h for * consistency. */ #include "vm_assert.h" void DriverLog_Init(const char *prefix); #endif /* __DRIVERLOG_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_semaphore.h0000644765153500003110000000314212220061556023213 0ustar dtormts/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_SEMAPHORE_H__ # define __COMPAT_SEMAPHORE_H__ /* <= 2.6.25 have asm only, 2.6.26 has both, and 2.6.27-rc2+ has linux only. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) # include #else # include #endif /* * The init_MUTEX_LOCKED() API appeared in 2.2.18, and is also in * 2.2.17-21mdk --hpreg */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) #ifndef init_MUTEX_LOCKED #define init_MUTEX_LOCKED(_sem) *(_sem) = MUTEX_LOCKED #endif #ifndef DECLARE_MUTEX #define DECLARE_MUTEX(name) struct semaphore name = MUTEX #endif #ifndef DECLARE_MUTEX_LOCKED #define DECLARE_MUTEX_LOCKED(name) struct semaphore name = MUTEX_LOCKED #endif #endif #endif /* __COMPAT_SEMAPHORE_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_sock.h0000644765153500003110000000600212220061556022165 0ustar dtormts/********************************************************* * Copyright (C) 2003 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_SOCK_H__ # define __COMPAT_SOCK_H__ #include /* for NULL */ #include #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) static inline wait_queue_head_t *sk_sleep(struct sock *sk) { return sk->sk_sleep; } #endif /* * Prior to 2.6.24, there was no sock network namespace member. In 2.6.26, it * was hidden behind accessor functions so that its behavior could vary * depending on the value of CONFIG_NET_NS. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) # define compat_sock_net(sk) sock_net(sk) #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) # define compat_sock_net(sk) sk->sk_net #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) #ifndef CONFIG_FILTER # define sk_filter(sk, skb, needlock) 0 #endif /* Taken from 2.6.16's sock.h and modified for macro. */ # define compat_sk_receive_skb(sk, skb, nested) \ ({ \ int rc = NET_RX_SUCCESS; \ \ if (sk_filter(sk, skb, 0)) { \ kfree_skb(skb); \ } else { \ skb->dev = NULL; \ bh_lock_sock(sk); \ if (!sock_owned_by_user(sk)) { \ rc = (sk)->sk_backlog_rcv(sk, skb); \ } else { \ sk_add_backlog(sk, skb); \ } \ bh_unlock_sock(sk); \ } \ \ sock_put(sk); \ rc; \ }) #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) # define compat_sk_receive_skb(sk, skb, nested) sk_receive_skb(sk, skb) #else # define compat_sk_receive_skb(sk, skb, nested) sk_receive_skb(sk, skb, nested) #endif #endif /* __COMPAT_SOCK_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_highmem.h0000644765153500003110000000242312220061556022647 0ustar dtormts/********************************************************* * Copyright (C) 2012 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_HIGHMEM_H__ # define __COMPAT_HIGHMEM_H__ #include #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0) # define compat_kmap_atomic(_page) kmap_atomic(_page) # define compat_kunmap_atomic(_page) kunmap_atomic(_page) #else # define compat_kmap_atomic(_page) kmap_atomic((_page), KM_USER0) # define compat_kunmap_atomic(_page) kunmap_atomic((_page), KM_USER0) #endif #endif /* __COMPAT_HIGHMEM_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_kernel.h0000644765153500003110000000273512220061556022517 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_KERNEL_H__ # define __COMPAT_KERNEL_H__ #include #include /* * container_of was introduced in 2.5.28 but it's easier to check like this. */ #ifndef container_of #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) #endif /* * vsnprintf became available in 2.4.10. For older kernels, just fall back on * vsprintf. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 10) #define vsnprintf(str, size, fmt, args) vsprintf(str, fmt, args) #endif #endif /* __COMPAT_KERNEL_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/vmci_defs.h0000644765153500003110000006544712220061556021644 0ustar dtormts/********************************************************* * Copyright (C) 2005-2012 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef _VMCI_DEF_H_ #define _VMCI_DEF_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMMEXT #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_DISTRIBUTE #include "includeCheck.h" #include "vm_basic_types.h" #include "vm_atomic.h" #include "vm_assert.h" /* Register offsets. */ #define VMCI_STATUS_ADDR 0x00 #define VMCI_CONTROL_ADDR 0x04 #define VMCI_ICR_ADDR 0x08 #define VMCI_IMR_ADDR 0x0c #define VMCI_DATA_OUT_ADDR 0x10 #define VMCI_DATA_IN_ADDR 0x14 #define VMCI_CAPS_ADDR 0x18 #define VMCI_RESULT_LOW_ADDR 0x1c #define VMCI_RESULT_HIGH_ADDR 0x20 /* Max number of devices. */ #define VMCI_MAX_DEVICES 1 /* Status register bits. */ #define VMCI_STATUS_INT_ON 0x1 /* Control register bits. */ #define VMCI_CONTROL_RESET 0x1 #define VMCI_CONTROL_INT_ENABLE 0x2 #define VMCI_CONTROL_INT_DISABLE 0x4 /* Capabilities register bits. */ #define VMCI_CAPS_HYPERCALL 0x1 #define VMCI_CAPS_GUESTCALL 0x2 #define VMCI_CAPS_DATAGRAM 0x4 #define VMCI_CAPS_NOTIFICATIONS 0x8 /* Interrupt Cause register bits. */ #define VMCI_ICR_DATAGRAM 0x1 #define VMCI_ICR_NOTIFICATION 0x2 /* Interrupt Mask register bits. */ #define VMCI_IMR_DATAGRAM 0x1 #define VMCI_IMR_NOTIFICATION 0x2 /* Interrupt type. */ typedef enum VMCIIntrType { VMCI_INTR_TYPE_INTX = 0, VMCI_INTR_TYPE_MSI = 1, VMCI_INTR_TYPE_MSIX = 2 } VMCIIntrType; /* * Maximum MSI/MSI-X interrupt vectors in the device. */ #define VMCI_MAX_INTRS 2 /* * Supported interrupt vectors. There is one for each ICR value above, * but here they indicate the position in the vector array/message ID. */ #define VMCI_INTR_DATAGRAM 0 #define VMCI_INTR_NOTIFICATION 1 /* * A single VMCI device has an upper limit of 128 MiB on the amount of * memory that can be used for queue pairs. */ #define VMCI_MAX_GUEST_QP_MEMORY (128 * 1024 * 1024) /* * Queues with pre-mapped data pages must be small, so that we don't pin * too much kernel memory (especially on vmkernel). We limit a queuepair to * 32 KB, or 16 KB per queue for symmetrical pairs. * * XXX, we are raising this limit to 4MB to support high-throughput workloads * with vioi-filter. Once we switch to rings instead of queuepairs for the * page channel, we will drop this limit again. See PR 852983. */ #define VMCI_MAX_PINNED_QP_MEMORY (4 * 1024 * 1024) /* * We have a fixed set of resource IDs available in the VMX. * This allows us to have a very simple implementation since we statically * know how many will create datagram handles. If a new caller arrives and * we have run out of slots we can manually increment the maximum size of * available resource IDs. */ typedef uint32 VMCI_Resource; /* VMCI reserved hypervisor datagram resource IDs. */ #define VMCI_RESOURCES_QUERY 0 #define VMCI_GET_CONTEXT_ID 1 #define VMCI_SET_NOTIFY_BITMAP 2 #define VMCI_DOORBELL_LINK 3 #define VMCI_DOORBELL_UNLINK 4 #define VMCI_DOORBELL_NOTIFY 5 /* * VMCI_DATAGRAM_REQUEST_MAP and VMCI_DATAGRAM_REMOVE_MAP are * obsoleted by the removal of VM to VM communication. */ #define VMCI_DATAGRAM_REQUEST_MAP 6 #define VMCI_DATAGRAM_REMOVE_MAP 7 #define VMCI_EVENT_SUBSCRIBE 8 #define VMCI_EVENT_UNSUBSCRIBE 9 #define VMCI_QUEUEPAIR_ALLOC 10 #define VMCI_QUEUEPAIR_DETACH 11 /* * VMCI_VSOCK_VMX_LOOKUP was assigned to 12 for Fusion 3.0/3.1, * WS 7.0/7.1 and ESX 4.1 */ #define VMCI_HGFS_TRANSPORT 13 #define VMCI_UNITY_PBRPC_REGISTER 14 /* * The next two resources are for RPC calls from guest Tools, to replace the * backdoor calls we used previously. Privileged is for admin/root RPCs, * unprivileged is for RPCs from any user. */ #define VMCI_RPC_PRIVILEGED 15 #define VMCI_RPC_UNPRIVILEGED 16 #define VMCI_RESOURCE_MAX 17 /* * The core VMCI device functionality only requires the resource IDs of * VMCI_QUEUEPAIR_DETACH and below. */ #define VMCI_CORE_DEVICE_RESOURCE_MAX VMCI_QUEUEPAIR_DETACH /* * VMCI reserved host datagram resource IDs. * vsock control channel has resource id 1. */ #define VMCI_DVFILTER_DATA_PATH_DATAGRAM 2 /* VMCI Ids. */ typedef uint32 VMCIId; typedef struct VMCIIdRange { int8 action; // VMCI_FA_X, for use in filters. VMCIId begin; // Beginning of range VMCIId end; // End of range } VMCIIdRange; typedef struct VMCIHandle { VMCIId context; VMCIId resource; } VMCIHandle; static INLINE VMCIHandle VMCI_MAKE_HANDLE(VMCIId cid, // IN: VMCIId rid) // IN: { VMCIHandle h; h.context = cid; h.resource = rid; return h; } /* *---------------------------------------------------------------------- * * VMCI_HANDLE_TO_UINT64 -- * * Helper for VMCI handle to uint64 conversion. * * Results: * The uint64 value. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE uint64 VMCI_HANDLE_TO_UINT64(VMCIHandle handle) // IN: { uint64 handle64; handle64 = handle.context; handle64 <<= 32; handle64 |= handle.resource; return handle64; } /* *---------------------------------------------------------------------- * * VMCI_UINT64_TO_HANDLE -- * * Helper for uint64 to VMCI handle conversion. * * Results: * The VMCI handle value. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE VMCIHandle VMCI_UINT64_TO_HANDLE(uint64 handle64) // IN: { VMCIId context = (VMCIId)(handle64 >> 32); VMCIId resource = (VMCIId)handle64; return VMCI_MAKE_HANDLE(context, resource); } #define VMCI_HANDLE_TO_CONTEXT_ID(_handle) ((_handle).context) #define VMCI_HANDLE_TO_RESOURCE_ID(_handle) ((_handle).resource) #define VMCI_HANDLE_EQUAL(_h1, _h2) ((_h1).context == (_h2).context && \ (_h1).resource == (_h2).resource) #define VMCI_INVALID_ID 0xFFFFFFFF static const VMCIHandle VMCI_INVALID_HANDLE = {VMCI_INVALID_ID, VMCI_INVALID_ID}; #define VMCI_HANDLE_INVALID(_handle) \ VMCI_HANDLE_EQUAL((_handle), VMCI_INVALID_HANDLE) /* * The below defines can be used to send anonymous requests. * This also indicates that no response is expected. */ #define VMCI_ANON_SRC_CONTEXT_ID VMCI_INVALID_ID #define VMCI_ANON_SRC_RESOURCE_ID VMCI_INVALID_ID #define VMCI_ANON_SRC_HANDLE VMCI_MAKE_HANDLE(VMCI_ANON_SRC_CONTEXT_ID, \ VMCI_ANON_SRC_RESOURCE_ID) /* The lowest 16 context ids are reserved for internal use. */ #define VMCI_RESERVED_CID_LIMIT 16 /* * Hypervisor context id, used for calling into hypervisor * supplied services from the VM. */ #define VMCI_HYPERVISOR_CONTEXT_ID 0 /* * Well-known context id, a logical context that contains a set of * well-known services. This context ID is now obsolete. */ #define VMCI_WELL_KNOWN_CONTEXT_ID 1 /* * Context ID used by host endpoints. */ #define VMCI_HOST_CONTEXT_ID 2 #define VMCI_CONTEXT_IS_VM(_cid) (VMCI_INVALID_ID != _cid && \ _cid > VMCI_HOST_CONTEXT_ID) /* * The VMCI_CONTEXT_RESOURCE_ID is used together with VMCI_MAKE_HANDLE to make * handles that refer to a specific context. */ #define VMCI_CONTEXT_RESOURCE_ID 0 /* *----------------------------------------------------------------------------- * * VMCI error codes. * *----------------------------------------------------------------------------- */ #define VMCI_SUCCESS_QUEUEPAIR_ATTACH 5 #define VMCI_SUCCESS_QUEUEPAIR_CREATE 4 #define VMCI_SUCCESS_LAST_DETACH 3 #define VMCI_SUCCESS_ACCESS_GRANTED 2 #define VMCI_SUCCESS_ENTRY_DEAD 1 #define VMCI_SUCCESS 0LL #define VMCI_ERROR_INVALID_RESOURCE (-1) #define VMCI_ERROR_INVALID_ARGS (-2) #define VMCI_ERROR_NO_MEM (-3) #define VMCI_ERROR_DATAGRAM_FAILED (-4) #define VMCI_ERROR_MORE_DATA (-5) #define VMCI_ERROR_NO_MORE_DATAGRAMS (-6) #define VMCI_ERROR_NO_ACCESS (-7) #define VMCI_ERROR_NO_HANDLE (-8) #define VMCI_ERROR_DUPLICATE_ENTRY (-9) #define VMCI_ERROR_DST_UNREACHABLE (-10) #define VMCI_ERROR_PAYLOAD_TOO_LARGE (-11) #define VMCI_ERROR_INVALID_PRIV (-12) #define VMCI_ERROR_GENERIC (-13) #define VMCI_ERROR_PAGE_ALREADY_SHARED (-14) #define VMCI_ERROR_CANNOT_SHARE_PAGE (-15) #define VMCI_ERROR_CANNOT_UNSHARE_PAGE (-16) #define VMCI_ERROR_NO_PROCESS (-17) #define VMCI_ERROR_NO_DATAGRAM (-18) #define VMCI_ERROR_NO_RESOURCES (-19) #define VMCI_ERROR_UNAVAILABLE (-20) #define VMCI_ERROR_NOT_FOUND (-21) #define VMCI_ERROR_ALREADY_EXISTS (-22) #define VMCI_ERROR_NOT_PAGE_ALIGNED (-23) #define VMCI_ERROR_INVALID_SIZE (-24) #define VMCI_ERROR_REGION_ALREADY_SHARED (-25) #define VMCI_ERROR_TIMEOUT (-26) #define VMCI_ERROR_DATAGRAM_INCOMPLETE (-27) #define VMCI_ERROR_INCORRECT_IRQL (-28) #define VMCI_ERROR_EVENT_UNKNOWN (-29) #define VMCI_ERROR_OBSOLETE (-30) #define VMCI_ERROR_QUEUEPAIR_MISMATCH (-31) #define VMCI_ERROR_QUEUEPAIR_NOTSET (-32) #define VMCI_ERROR_QUEUEPAIR_NOTOWNER (-33) #define VMCI_ERROR_QUEUEPAIR_NOTATTACHED (-34) #define VMCI_ERROR_QUEUEPAIR_NOSPACE (-35) #define VMCI_ERROR_QUEUEPAIR_NODATA (-36) #define VMCI_ERROR_BUSMEM_INVALIDATION (-37) #define VMCI_ERROR_MODULE_NOT_LOADED (-38) #define VMCI_ERROR_DEVICE_NOT_FOUND (-39) #define VMCI_ERROR_QUEUEPAIR_NOT_READY (-40) #define VMCI_ERROR_WOULD_BLOCK (-41) /* VMCI clients should return error code withing this range */ #define VMCI_ERROR_CLIENT_MIN (-500) #define VMCI_ERROR_CLIENT_MAX (-550) /* Internal error codes. */ #define VMCI_SHAREDMEM_ERROR_BAD_CONTEXT (-1000) #define VMCI_PATH_MAX 256 /* VMCI reserved events. */ typedef uint32 VMCI_Event; #define VMCI_EVENT_CTX_ID_UPDATE 0 // Only applicable to guest endpoints #define VMCI_EVENT_CTX_REMOVED 1 // Applicable to guest and host #define VMCI_EVENT_QP_RESUMED 2 // Only applicable to guest endpoints #define VMCI_EVENT_QP_PEER_ATTACH 3 // Applicable to guest and host #define VMCI_EVENT_QP_PEER_DETACH 4 // Applicable to guest and host #define VMCI_EVENT_MEM_ACCESS_ON 5 // Applicable to VMX and vmk. On vmk, // this event has the Context payload type. #define VMCI_EVENT_MEM_ACCESS_OFF 6 // Applicable to VMX and vmk. Same as // above for the payload type. #define VMCI_EVENT_MAX 7 /* * Of the above events, a few are reserved for use in the VMX, and * other endpoints (guest and host kernel) should not use them. For * the rest of the events, we allow both host and guest endpoints to * subscribe to them, to maintain the same API for host and guest * endpoints. */ #define VMCI_EVENT_VALID_VMX(_event) (_event == VMCI_EVENT_MEM_ACCESS_ON || \ _event == VMCI_EVENT_MEM_ACCESS_OFF) #if defined(VMX86_SERVER) #define VMCI_EVENT_VALID(_event) (_event < VMCI_EVENT_MAX) #else // VMX86_SERVER #define VMCI_EVENT_VALID(_event) (_event < VMCI_EVENT_MAX && \ !VMCI_EVENT_VALID_VMX(_event)) #endif // VMX86_SERVER /* Reserved guest datagram resource ids. */ #define VMCI_EVENT_HANDLER 0 /* VMCI privileges. */ typedef enum VMCIResourcePrivilegeType { VMCI_PRIV_CH_PRIV, VMCI_PRIV_DESTROY_RESOURCE, VMCI_PRIV_ASSIGN_CLIENT, VMCI_PRIV_DG_CREATE, VMCI_PRIV_DG_SEND, VMCI_PRIV_NOTIFY, VMCI_NUM_PRIVILEGES, } VMCIResourcePrivilegeType; /* * VMCI coarse-grained privileges (per context or host * process/endpoint. An entity with the restricted flag is only * allowed to interact with the hypervisor and trusted entities. */ typedef uint32 VMCIPrivilegeFlags; #define VMCI_PRIVILEGE_FLAG_RESTRICTED 0x01 #define VMCI_PRIVILEGE_FLAG_TRUSTED 0x02 #define VMCI_PRIVILEGE_ALL_FLAGS (VMCI_PRIVILEGE_FLAG_RESTRICTED | \ VMCI_PRIVILEGE_FLAG_TRUSTED) #define VMCI_NO_PRIVILEGE_FLAGS 0x00 #define VMCI_DEFAULT_PROC_PRIVILEGE_FLAGS VMCI_NO_PRIVILEGE_FLAGS #define VMCI_LEAST_PRIVILEGE_FLAGS VMCI_PRIVILEGE_FLAG_RESTRICTED #define VMCI_MAX_PRIVILEGE_FLAGS VMCI_PRIVILEGE_FLAG_TRUSTED #define VMCI_PUBLIC_GROUP_NAME "vmci public group" /* 0 through VMCI_RESERVED_RESOURCE_ID_MAX are reserved. */ #define VMCI_RESERVED_RESOURCE_ID_MAX 1023 #define VMCI_DOMAIN_NAME_MAXLEN 32 #define VMCI_LGPFX "VMCI: " /* * VMCIQueueHeader * * A Queue cannot stand by itself as designed. Each Queue's header * contains a pointer into itself (the producerTail) and into its peer * (consumerHead). The reason for the separation is one of * accessibility: Each end-point can modify two things: where the next * location to enqueue is within its produceQ (producerTail); and * where the next dequeue location is in its consumeQ (consumerHead). * * An end-point cannot modify the pointers of its peer (guest to * guest; NOTE that in the host both queue headers are mapped r/w). * But, each end-point needs read access to both Queue header * structures in order to determine how much space is used (or left) * in the Queue. This is because for an end-point to know how full * its produceQ is, it needs to use the consumerHead that points into * the produceQ but -that- consumerHead is in the Queue header for * that end-points consumeQ. * * Thoroughly confused? Sorry. * * producerTail: the point to enqueue new entrants. When you approach * a line in a store, for example, you walk up to the tail. * * consumerHead: the point in the queue from which the next element is * dequeued. In other words, who is next in line is he who is at the * head of the line. * * Also, producerTail points to an empty byte in the Queue, whereas * consumerHead points to a valid byte of data (unless producerTail == * consumerHead in which case consumerHead does not point to a valid * byte of data). * * For a queue of buffer 'size' bytes, the tail and head pointers will be in * the range [0, size-1]. * * If produceQHeader->producerTail == consumeQHeader->consumerHead * then the produceQ is empty. */ typedef struct VMCIQueueHeader { /* All fields are 64bit and aligned. */ VMCIHandle handle; /* Identifier. */ Atomic_uint64 producerTail; /* Offset in this queue. */ Atomic_uint64 consumerHead; /* Offset in peer queue. */ } VMCIQueueHeader; /* * If one client of a QueuePair is a 32bit entity, we restrict the QueuePair * size to be less than 4GB, and use 32bit atomic operations on the head and * tail pointers. 64bit atomic read on a 32bit entity involves cmpxchg8b which * is an atomic read-modify-write. This will cause traces to fire when a 32bit * consumer tries to read the producer's tail pointer, for example, because the * consumer has read-only access to the producer's tail pointer. * * We provide the following macros to invoke 32bit or 64bit atomic operations * based on the architecture the code is being compiled on. */ /* Architecture independent maximum queue size. */ #define QP_MAX_QUEUE_SIZE_ARCH_ANY CONST64U(0xffffffff) #ifdef __x86_64__ # define QP_MAX_QUEUE_SIZE_ARCH CONST64U(0xffffffffffffffff) # define QPAtomic_ReadOffset(x) Atomic_Read64(x) # define QPAtomic_WriteOffset(x, y) Atomic_Write64(x, y) #else /* * Wrappers below are being used to call Atomic_Read32 because of the * 'type punned' compilation warning received when Atomic_Read32 is * called with a Atomic_uint64 pointer typecasted to Atomic_uint32 * pointer from QPAtomic_ReadOffset. Ditto with QPAtomic_WriteOffset. */ static INLINE uint32 TypeSafe_Atomic_Read32(void *var) // IN: { return Atomic_Read32((Atomic_uint32 *)(var)); } static INLINE void TypeSafe_Atomic_Write32(void *var, uint32 val) // IN: { Atomic_Write32((Atomic_uint32 *)(var), (uint32)(val)); } # define QP_MAX_QUEUE_SIZE_ARCH CONST64U(0xffffffff) # define QPAtomic_ReadOffset(x) TypeSafe_Atomic_Read32((void *)(x)) # define QPAtomic_WriteOffset(x, y) \ TypeSafe_Atomic_Write32((void *)(x), (uint32)(y)) #endif /* __x86_64__ */ /* *----------------------------------------------------------------------------- * * QPAddPointer -- * * Helper to add a given offset to a head or tail pointer. Wraps the value * of the pointer around the max size of the queue. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE void QPAddPointer(Atomic_uint64 *var, // IN: size_t add, // IN: uint64 size) // IN: { uint64 newVal = QPAtomic_ReadOffset(var); if (newVal >= size - add) { newVal -= size; } newVal += add; QPAtomic_WriteOffset(var, newVal); } /* *----------------------------------------------------------------------------- * * VMCIQueueHeader_ProducerTail() -- * * Helper routine to get the Producer Tail from the supplied queue. * * Results: * The contents of the queue's producer tail. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE uint64 VMCIQueueHeader_ProducerTail(const VMCIQueueHeader *qHeader) // IN: { VMCIQueueHeader *qh = (VMCIQueueHeader *)qHeader; return QPAtomic_ReadOffset(&qh->producerTail); } /* *----------------------------------------------------------------------------- * * VMCIQueueHeader_ConsumerHead() -- * * Helper routine to get the Consumer Head from the supplied queue. * * Results: * The contents of the queue's consumer tail. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE uint64 VMCIQueueHeader_ConsumerHead(const VMCIQueueHeader *qHeader) // IN: { VMCIQueueHeader *qh = (VMCIQueueHeader *)qHeader; return QPAtomic_ReadOffset(&qh->consumerHead); } /* *----------------------------------------------------------------------------- * * VMCIQueueHeader_AddProducerTail() -- * * Helper routine to increment the Producer Tail. Fundamentally, * QPAddPointer() is used to manipulate the tail itself. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE void VMCIQueueHeader_AddProducerTail(VMCIQueueHeader *qHeader, // IN/OUT: size_t add, // IN: uint64 queueSize) // IN: { QPAddPointer(&qHeader->producerTail, add, queueSize); } /* *----------------------------------------------------------------------------- * * VMCIQueueHeader_AddConsumerHead() -- * * Helper routine to increment the Consumer Head. Fundamentally, * QPAddPointer() is used to manipulate the head itself. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE void VMCIQueueHeader_AddConsumerHead(VMCIQueueHeader *qHeader, // IN/OUT: size_t add, // IN: uint64 queueSize) // IN: { QPAddPointer(&qHeader->consumerHead, add, queueSize); } /* *----------------------------------------------------------------------------- * * VMCIQueueHeader_CheckAlignment -- * * Checks if the given queue is aligned to page boundary. Returns TRUE if * the alignment is good. * * Results: * TRUE or FALSE. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE Bool VMCIQueueHeader_CheckAlignment(const VMCIQueueHeader *qHeader) // IN: { uintptr_t hdr, offset; hdr = (uintptr_t) qHeader; offset = hdr & (PAGE_SIZE -1); return offset == 0; } /* *----------------------------------------------------------------------------- * * VMCIQueueHeader_GetPointers -- * * Helper routine for getting the head and the tail pointer for a queue. * Both the VMCIQueues are needed to get both the pointers for one queue. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE void VMCIQueueHeader_GetPointers(const VMCIQueueHeader *produceQHeader, // IN: const VMCIQueueHeader *consumeQHeader, // IN: uint64 *producerTail, // OUT: uint64 *consumerHead) // OUT: { if (producerTail) { *producerTail = VMCIQueueHeader_ProducerTail(produceQHeader); } if (consumerHead) { *consumerHead = VMCIQueueHeader_ConsumerHead(consumeQHeader); } } /* *----------------------------------------------------------------------------- * * VMCIQueueHeader_ResetPointers -- * * Reset the tail pointer (of "this" queue) and the head pointer (of * "peer" queue). * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE void VMCIQueueHeader_ResetPointers(VMCIQueueHeader *qHeader) // IN/OUT: { QPAtomic_WriteOffset(&qHeader->producerTail, CONST64U(0)); QPAtomic_WriteOffset(&qHeader->consumerHead, CONST64U(0)); } /* *----------------------------------------------------------------------------- * * VMCIQueueHeader_Init -- * * Initializes a queue's state (head & tail pointers). * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE void VMCIQueueHeader_Init(VMCIQueueHeader *qHeader, // IN/OUT: const VMCIHandle handle) // IN: { qHeader->handle = handle; VMCIQueueHeader_ResetPointers(qHeader); } /* *----------------------------------------------------------------------------- * * VMCIQueueHeader_FreeSpace -- * * Finds available free space in a produce queue to enqueue more * data or reports an error if queue pair corruption is detected. * * Results: * Free space size in bytes or an error code. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE int64 VMCIQueueHeader_FreeSpace(const VMCIQueueHeader *produceQHeader, // IN: const VMCIQueueHeader *consumeQHeader, // IN: const uint64 produceQSize) // IN: { uint64 tail; uint64 head; uint64 freeSpace; tail = VMCIQueueHeader_ProducerTail(produceQHeader); head = VMCIQueueHeader_ConsumerHead(consumeQHeader); if (tail >= produceQSize || head >= produceQSize) { return VMCI_ERROR_INVALID_SIZE; } /* * Deduct 1 to avoid tail becoming equal to head which causes ambiguity. If * head and tail are equal it means that the queue is empty. */ if (tail >= head) { freeSpace = produceQSize - (tail - head) - 1; } else { freeSpace = head - tail - 1; } return freeSpace; } /* *----------------------------------------------------------------------------- * * VMCIQueueHeader_BufReady -- * * VMCIQueueHeader_FreeSpace() does all the heavy lifting of * determing the number of free bytes in a Queue. This routine, * then subtracts that size from the full size of the Queue so * the caller knows how many bytes are ready to be dequeued. * * Results: * On success, available data size in bytes (up to MAX_INT64). * On failure, appropriate error code. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE int64 VMCIQueueHeader_BufReady(const VMCIQueueHeader *consumeQHeader, // IN: const VMCIQueueHeader *produceQHeader, // IN: const uint64 consumeQSize) // IN: { int64 freeSpace; freeSpace = VMCIQueueHeader_FreeSpace(consumeQHeader, produceQHeader, consumeQSize); if (freeSpace < VMCI_SUCCESS) { return freeSpace; } else { return consumeQSize - freeSpace - 1; } } /* * Defines for the VMCI traffic filter: * - VMCI_FA_ defines the filter action values * - VMCI_FP_ defines the filter protocol values * - VMCI_FD_ defines the direction values (guest or host) * - VMCI_FT_ are the type values (allow or deny) */ #define VMCI_FA_INVALID -1 #define VMCI_FA_ALLOW 0 #define VMCI_FA_DENY (VMCI_FA_ALLOW + 1) #define VMCI_FA_MAX (VMCI_FA_DENY + 1) #define VMCI_FP_INVALID -1 #define VMCI_FP_HYPERVISOR 0 #define VMCI_FP_QUEUEPAIR (VMCI_FP_HYPERVISOR + 1) #define VMCI_FP_DOORBELL (VMCI_FP_QUEUEPAIR + 1) #define VMCI_FP_DATAGRAM (VMCI_FP_DOORBELL + 1) #define VMCI_FP_STREAMSOCK (VMCI_FP_DATAGRAM + 1) #define VMCI_FP_ANY (VMCI_FP_STREAMSOCK + 1) #define VMCI_FP_MAX (VMCI_FP_ANY + 1) #define VMCI_FD_INVALID -1 #define VMCI_FD_GUEST 0 #define VMCI_FD_HOST (VMCI_FD_GUEST + 1) #define VMCI_FD_ANY (VMCI_FD_HOST + 1) #define VMCI_FD_MAX (VMCI_FD_ANY + 1) /* * The filter list tracks VMCI Id ranges for a given filter. */ typedef struct { uint32 len; VMCIIdRange *list; } VMCIFilterList; /* * The filter info is used to communicate the filter configuration * from the VMX to the host kernel. */ typedef struct { VA64 list; // List of VMCIIdRange uint32 len; // Length of list uint8 dir; // VMCI_FD_X uint8 proto; // VMCI_FP_X } VMCIFilterInfo; /* * In the host kernel, the ingoing and outgoing filters are * separated. The VMCIProtoFilters type captures all filters in one * direction. The VMCIFilters type captures all filters. */ typedef VMCIFilterList VMCIProtoFilters[VMCI_FP_MAX]; typedef VMCIProtoFilters VMCIFilters[VMCI_FD_MAX]; #endif // _VMCI_DEF_H_ open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_uaccess.h0000644765153500003110000000606212220061556022662 0ustar dtormts/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_UACCESS_H__ # define __COMPAT_UACCESS_H__ /* User space access functions moved in 2.1.7 to asm/uaccess.h --hpreg */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 7) # include #else # include #endif /* get_user() API modified in 2.1.4 to take 2 arguments --hpreg */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 4) # define compat_get_user get_user #else /* * We assign 0 to the variable in case of failure to prevent "`_var' might be * used uninitialized in this function" compiler warnings. I think it is OK, * because the hardware-based version in newer kernels probably has the same * semantics and does not guarantee that the value of _var will not be * modified, should the access fail --hpreg */ # define compat_get_user(_var, _uvAddr) ({ \ int _status; \ \ _status = verify_area(VERIFY_READ, _uvAddr, sizeof(*(_uvAddr))); \ if (_status == 0) { \ (_var) = get_user(_uvAddr); \ } else { \ (_var) = 0; \ } \ _status; \ }) #endif /* * The copy_from_user() API appeared in 2.1.4 * * The emulation is not perfect here, but it is conservative: on failure, we * always return the total size, instead of the potentially smaller faulty * size --hpreg * * Since 2.5.55 copy_from_user() is no longer macro. */ #if !defined(copy_from_user) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0) # define copy_from_user(_to, _from, _size) ( \ verify_area(VERIFY_READ, _from, _size) \ ? (_size) \ : (memcpy_fromfs(_to, _from, _size), 0) \ ) # define copy_to_user(_to, _from, _size) ( \ verify_area(VERIFY_WRITE, _to, _size) \ ? (_size) \ : (memcpy_tofs(_to, _from, _size), 0) \ ) #endif #endif /* __COMPAT_UACCESS_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/vmciKernelAPI.h0000644765153500003110000000241012220061556022313 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmciKernelAPI.h -- * * Kernel API (current) exported from the VMCI host and guest drivers. */ #ifndef __VMCI_KERNELAPI_H__ #define __VMCI_KERNELAPI_H__ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" /* With this file you always get the latest version. */ #include "vmciKernelAPI1.h" #include "vmciKernelAPI2.h" #endif /* !__VMCI_KERNELAPI_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/shared/driverLog.c0000644765153500003110000001111212220061556021611 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * driverLog.c -- * * Common logging functions for Linux kernel modules. */ #include "driver-config.h" #include "compat_kernel.h" #include "compat_sched.h" #include #include "driverLog.h" #define LINUXLOG_BUFFER_SIZE 1024 static const char *driverLogPrefix = ""; /* * vsnprintf was born in 2.4.10. Fall back on vsprintf if we're * an older kernel. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 10) # define vsnprintf(str, size, fmt, args) vsprintf(str, fmt, args) #endif /* *---------------------------------------------------------------------------- * * DriverLog_Init -- * * Initializes the Linux logging. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void DriverLog_Init(const char *prefix) // IN { driverLogPrefix = prefix ? prefix : ""; } /* *---------------------------------------------------------------------- * * DriverLogPrint -- * * Log error message from a Linux module. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void DriverLogPrint(const char *level, // IN: KERN_* constant const char *fmt, // IN: error format string va_list args) // IN: arguments for format string { static char staticBuf[LINUXLOG_BUFFER_SIZE]; char stackBuf[128]; va_list args2; const char *buf; /* * By default, use a small buffer on the stack (thread safe). If it is too * small, fall back to a larger static buffer (not thread safe). */ va_copy(args2, args); if (vsnprintf(stackBuf, sizeof stackBuf, fmt, args2) < sizeof stackBuf) { buf = stackBuf; } else { vsnprintf(staticBuf, sizeof staticBuf, fmt, args); buf = staticBuf; } va_end(args2); printk("%s%s[%d]: %s", level, driverLogPrefix, current->pid, buf); } /* *---------------------------------------------------------------------- * * Warning -- * * Warning messages from kernel module: logged into kernel log * as warnings. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void Warning(const char *fmt, ...) // IN: warning format string { va_list args; va_start(args, fmt); DriverLogPrint(KERN_WARNING, fmt, args); va_end(args); } /* *---------------------------------------------------------------------- * * Log -- * * Log messages from kernel module: logged into kernel log * as debug information. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void Log(const char *fmt, ...) // IN: log format string { va_list args; /* * Use the kernel log with at least a KERN_DEBUG level * so it doesn't garbage the screen at (re)boot time on RedHat 6.0. */ va_start(args, fmt); DriverLogPrint(KERN_DEBUG, fmt, args); va_end(args); } /* *---------------------------------------------------------------------- * * Panic -- * * ASSERTION failures and Panics from kernel module get here. * Message is logged to the kernel log and on console. * * Results: * None. * * Side effects: * Never returns * *---------------------------------------------------------------------- */ void Panic(const char *fmt, ...) // IN: panic format string { va_list args; va_start(args, fmt); DriverLogPrint(KERN_EMERG, fmt, args); va_end(args); #ifdef BUG BUG(); #else /* Should die with %cs unwritable, or at least with page fault. */ asm volatile("movb $0, %cs:(0)"); #endif while (1); } open-vm-tools-9.4.0-1280544/modules/linux/shared/compat_page.h0000644765153500003110000000466312220061556022155 0ustar dtormts/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_PAGE_H__ # define __COMPAT_PAGE_H__ #include #include /* The pfn_to_page() API appeared in 2.5.14 and changed to function during 2.6.x */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) && !defined(pfn_to_page) # define pfn_to_page(_pfn) (mem_map + (_pfn)) # define page_to_pfn(_page) ((_page) - mem_map) #endif /* The virt_to_page() API appeared in 2.4.0 --hpreg */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) && !defined(virt_to_page) # define virt_to_page(_kvAddr) pfn_to_page(MAP_NR(_kvAddr)) #endif /* * The get_order() API appeared at some point in 2.3.x, and was then backported * in 2.2.17-21mdk and in the stock 2.2.18. Because we can only detect its * definition through makefile tricks, we provide our own for now --hpreg */ static inline int compat_get_order(unsigned long size) // IN { int order; size = (size - 1) >> (PAGE_SHIFT - 1); order = -1; do { size >>= 1; order++; } while (size); return order; } /* * BUG() was added to in 2.2.18, and was moved to * in 2.5.58. * * XXX: Technically, this belongs in some sort of "compat_asm_page.h" file, but * since our compatibility wrappers don't distinguish between and * , putting it here is reasonable. */ #ifndef BUG #define BUG() do { \ printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ __asm__ __volatile__(".byte 0x0f,0x0b"); \ } while (0) #endif #endif /* __COMPAT_PAGE_H__ */ open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/0000755765153500003110000000000012220061556017540 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/module.h0000644765153500003110000001565112220061556021206 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * module.h -- * * Global module definitions for the entire vmhgfs driver. */ #ifndef _HGFS_DRIVER_MODULE_H_ #define _HGFS_DRIVER_MODULE_H_ /* Must come before any kernel header file. */ #include "driver-config.h" #include #include "compat_fs.h" #include "compat_semaphore.h" #include "compat_slab.h" #include "compat_spinlock.h" #include "compat_version.h" #include "rpcout.h" #include "hgfsProto.h" #ifndef __user #define __user #endif /* Logging stuff. */ #ifdef VMX86_DEVEL extern int LOGLEVEL_THRESHOLD; #define LOG(level, args) ((void) (LOGLEVEL_THRESHOLD >= (level) ? (printk args) : 0)) #else #define LOG(level, args) #endif /* Blocksize to be set in superblock. (XXX how is this used?) */ #define HGFS_BLOCKSIZE 1024 /* The amount of time we'll wait for the backdoor to process our request. */ #define HGFS_REQUEST_TIMEOUT (30 * HZ) /* * Inode number of the root inode. We set this to be non-zero because, * according to glibc source, when the returned inode number in a dirent * is zero, that entry has been deleted. This is presumably when you've done * an opendir, the file is deleted, and then you do a readdir. The point is * that if the root inode is zero, aliases to it (such as '.' and "..") won't * appear in a directory listing. */ #define HGFS_ROOT_INO 1 /* Leave HGFS_ROOT_INO and below out of inode number generation. */ #define HGFS_RESERVED_INO HGFS_ROOT_INO + 1 /* * Macros for accessing members that are private to this code in * sb/inode/file structs. */ #define HGFS_SET_SB_TO_COMMON(sb, common) do { (sb)->s_fs_info = (common); } while (0) #define HGFS_SB_TO_COMMON(sb) ((HgfsSuperInfo *)(sb)->s_fs_info) #define INODE_GET_II_P(_inode) container_of(_inode, HgfsInodeInfo, inode) #if defined VMW_INODE_2618 #define INODE_SET_II_P(inode, info) do { (inode)->i_private = (info); } while (0) #else #define INODE_SET_II_P(inode, info) do { (inode)->u.generic_ip = (info); } while (0) #endif #define HGFS_DECLARE_TIME(unixtm) struct timespec unixtm #define HGFS_EQUAL_TIME(unixtm1, unixtm2) timespec_equal(&unixtm1, &unixtm2) #define HGFS_SET_TIME(unixtm,nttime) HgfsConvertFromNtTimeNsec(&unixtm, nttime) #define HGFS_GET_TIME(unixtm) HgfsConvertTimeSpecToNtTime(&unixtm) #define HGFS_GET_CURRENT_TIME() ({ \ struct timespec ct = CURRENT_TIME; \ HGFS_GET_TIME(ct); \ }) /* * Beware! This macro returns list of two elements. Do not add braces around. */ #define HGFS_PRINT_TIME(unixtm) unixtm.tv_sec, unixtm.tv_nsec /* * For files opened in our actual Host/Guest filesystem, the * file->private_data field is used for storing the HgfsFileInfo of the * opened file. This macro is for accessing the file information from the * file *. */ #define FILE_SET_FI_P(file, info) do { (file)->private_data = info; } while (0) #define FILE_GET_FI_P(file) ((HgfsFileInfo *)(file)->private_data) /* Data kept in each superblock in sb->u. */ typedef struct HgfsSuperInfo { uid_t uid; /* UID of user who mounted this fs. */ Bool uidSet; /* Was the UID specified at mount-time? */ gid_t gid; /* GID of user who mounted this fs. */ Bool gidSet; /* Was the GID specified at mount-time? */ mode_t fmask; /* File permission mask. */ mode_t dmask; /* Directory permission mask. */ uint32 ttl; /* Maximum dentry age (in ticks). */ char *shareName; /* Mounted share name. */ size_t shareNameLen; /* To avoid repeated strlen() calls. */ } HgfsSuperInfo; /* * HGFS specific per-inode data. */ typedef struct HgfsInodeInfo { /* Embedded inode. */ struct inode inode; /* Inode number given by the host. */ uint64 hostFileId; /* Was the inode number for this inode generated via iunique()? */ Bool isFakeInodeNumber; /* Is this a fake inode created in HgfsCreate that has yet to be opened? */ Bool createdAndUnopened; /* Is this inode referenced by HGFS? (needed by HgfsInodeLookup()) */ Bool isReferencedInode; /* List of open files for this inode. */ struct list_head files; } HgfsInodeInfo; /* * HGFS specific per-file data. */ typedef struct HgfsFileInfo { /* Links to place this object on the inode's list of open files. */ struct list_head list; /* Handle to be sent to the server. Needed for writepage(). */ HgfsHandle handle; /* * Mode with which handle was opened. When we reuse a handle, we need to * choose one with appropriate permissions. */ HgfsOpenMode mode; /* * Do we need to reopen a directory ? Note that this is only used * for directories. */ Bool isStale; } HgfsFileInfo; /* * Global synchronization primitives. */ /* * We use hgfsBigLock to protect certain global structures that are locked for * a very short amount of time. */ extern spinlock_t hgfsBigLock; /* Hgfs filesystem structs. */ extern struct super_operations HgfsSuperOperations; extern struct dentry_operations HgfsDentryOperations; extern struct inode_operations HgfsFileInodeOperations; extern struct inode_operations HgfsDirInodeOperations; extern struct inode_operations HgfsLinkInodeOperations; extern struct file_operations HgfsFileFileOperations; extern struct file_operations HgfsDirFileOperations; extern struct address_space_operations HgfsAddressSpaceOperations; /* Other global state. */ extern compat_kmem_cache *hgfsInodeCache; extern HgfsOp hgfsVersionOpen; extern HgfsOp hgfsVersionRead; extern HgfsOp hgfsVersionWrite; extern HgfsOp hgfsVersionClose; extern HgfsOp hgfsVersionSearchOpen; extern HgfsOp hgfsVersionSearchRead; extern HgfsOp hgfsVersionSearchClose; extern HgfsOp hgfsVersionGetattr; extern HgfsOp hgfsVersionSetattr; extern HgfsOp hgfsVersionCreateDir; extern HgfsOp hgfsVersionDeleteFile; extern HgfsOp hgfsVersionDeleteDir; extern HgfsOp hgfsVersionRename; extern HgfsOp hgfsVersionQueryVolumeInfo; extern HgfsOp hgfsVersionCreateSymlink; #endif // _HGFS_DRIVER_MODULE_H_ open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/stubs.c0000644765153500003110000000370112220061556021045 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * stubs.c * * Contains stubs and helper functions. */ /* Must come before any kernel header file. */ #include "driver-config.h" #include "kernelStubs.h" #include "module.h" #include "vm_assert.h" /* *---------------------------------------------------------------------- * * Debug -- * * If debugging is enabled, output debug information. * * Result * None * * Side-effects * None * *---------------------------------------------------------------------- */ void Debug(char const *fmt, // IN: Format string ...) // IN: Arguments { va_list args; int numBytes; static char out[128]; va_start(args, fmt); numBytes = Str_Vsnprintf(out, sizeof out, fmt, args); va_end(args); if (numBytes > 0) { LOG(6, (KERN_DEBUG "VMware hgfs: %s", out)); } } /* *---------------------------------------------------------------------- * * Log -- * * Needs to be defined. * * Result * None * * Side-effects * None * *---------------------------------------------------------------------- */ void Log(const char *string, ...) { // do nothing. } open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/vmci.c0000644765153500003110000005512112220061556020646 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmci.c -- * * Provides VMCI transport channel to the HGFS client. */ /* Must come before any kernel header file. */ #include "driver-config.h" #include #include #include /* for spin_lock_bh */ #include #include "compat_mm.h" #include "hgfsProto.h" #include "hgfsTransport.h" #include "module.h" #include "request.h" #include "transport.h" #include "vm_assert.h" #include "vmci_call_defs.h" #include "vmci_defs.h" #include "vmciKernelAPI1.h" static Bool HgfsVmciChannelOpen(HgfsTransportChannel *channel); static void HgfsVmciChannelClose(HgfsTransportChannel *channel); static HgfsReq * HgfsVmciChannelAllocate(size_t payloadSize); void HgfsVmciChannelFree(HgfsReq *req); static int HgfsVmciChannelSend(HgfsTransportChannel *channel, HgfsReq *req); static void HgfsRequestAsyncDispatch(char *payload, uint32 size); int USE_VMCI = 0; module_param(USE_VMCI, int, 0444); static HgfsTransportChannel channel = { .name = "vmci", .ops.open = HgfsVmciChannelOpen, .ops.close = HgfsVmciChannelClose, .ops.allocate = HgfsVmciChannelAllocate, .ops.free = HgfsVmciChannelFree, .ops.send = HgfsVmciChannelSend, .priv = NULL, .status = HGFS_CHANNEL_NOTCONNECTED }; static spinlock_t vmciRequestProcessLock; typedef struct HgfsShmemPage { uint64 va; uint64 pa; Bool free; } HgfsShmemPage; typedef struct HgfsShmemPages { HgfsShmemPage *list; uint32 totalPageCount; uint32 freePageCount; } HgfsShmemPages; HgfsShmemPages gHgfsShmemPages; #define HGFS_VMCI_SHMEM_PAGES (16) /* *---------------------------------------------------------------------- * * HgfsRequestAsyncDispatch -- * * XXX Main dispatcher function. Currently just a stub. Needs to run * in atomic context. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ static void HgfsRequestAsyncDispatch(char *payload, // IN: request header uint32 size) // IN: size of payload { HgfsRequest *reqHeader = (HgfsRequest *)payload; LOG(4, (KERN_WARNING "Size in Dispatch %u\n", size)); switch (reqHeader->op) { case HGFS_OP_NOTIFY_V4: { LOG(4, (KERN_WARNING "Calling HGFS_OP_NOTIFY_V4 dispatch function\n")); break; } default: LOG(4, (KERN_WARNING "%s: Unknown opcode = %d", __func__, reqHeader->op)); } } /* *---------------------------------------------------------------------- * * HgfsRequestAsyncShmemDispatch -- * * Shared memory dispatcher. It extracts packets from the shared * memory and dispatches to the main hgfs dispatcher function. When * the buffer is larger than 4K, we may fail do deliver notifications. * Main dispatcher function should run in atomic context. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ static void HgfsRequestAsyncShmemDispatch(HgfsAsyncIov *iov, // IN: request vectors uint32 count) // IN: number of iovs { uint32 i; char *buf = NULL; uint32 size = 0; Bool chainStarted = FALSE; uint32 offset = 0; uint32 copySize; uint64 prevIndex = -1; uint64 currIndex; size_t va; LOG(10, (KERN_WARNING "%s count = %u\n",__FUNCTION__, count)); /* * When requests cross 4K boundary we have to chain pages together * since guest passes 4k pages to the host. Here is how chaining works * * - All the vectors except the last one in the chain sets iov[].chain * to TRUE. * - Every iov[].len field indicates remaining bytes. So the first * vector will contain total size of the request while the last vector * will contain only size of data present in last vector. */ for (i = 0; i < count; i++) { va = (size_t)iov[i].va; currIndex = iov[i].index; if (LIKELY(!iov[i].chain)) { /* When the chain ends we dispatch the datagram.*/ if (!chainStarted) { buf = (char *)va; LOG(8, (KERN_WARNING " Chain wasn't started...\n")); size = iov[i].len; } else { memcpy(buf + offset, (char *)va, iov[i].len); } ASSERT(buf && size); HgfsRequestAsyncDispatch(buf, size); if (chainStarted) { /* Well chain just ended, we shall free the buffer. */ chainStarted = FALSE; kfree(buf); } } else { if (!chainStarted) { LOG(8, (KERN_WARNING "Started chain ...\n")); size = iov[i].len; buf = kmalloc(size, GFP_ATOMIC); ASSERT_DEVEL(buf); if (!buf) { /* Skip this notification, move onto next. */ i += (size - 1) / PAGE_SIZE; continue; } chainStarted = TRUE; offset = 0; } copySize = MIN(iov[i].len, PAGE_SIZE); memcpy(buf + offset, (char *)va, copySize); offset += copySize; } if (currIndex != prevIndex) { /* This is new page. Mark is as free. */ gHgfsShmemPages.list[currIndex].free = TRUE; gHgfsShmemPages.freePageCount++; } prevIndex = currIndex; } ASSERT(gHgfsShmemPages.freePageCount <= gHgfsShmemPages.totalPageCount); LOG(8, (KERN_WARNING "Page count %u %u ...\n", gHgfsShmemPages.freePageCount, gHgfsShmemPages.totalPageCount)); } /* *----------------------------------------------------------------------------- * * HgfsVmciChannelPassGuestPages -- * * Passes down free pages to the hgfs Server. HgfsServer will use this pages * for sending change notification, oplock breaks etc. * * XXX It seems safe to call vmci_datagram_send in atomic context. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool HgfsVmciChannelPassGuestPages(HgfsTransportChannel *channel) // IN: { Bool retVal = TRUE; int ret; int i; int j = 0; size_t transportHeaderSize; HgfsVmciTransportHeader *transportHeader = NULL; VMCIDatagram *dg; if (!gHgfsShmemPages.freePageCount) { return TRUE; } transportHeaderSize = sizeof (HgfsVmciTransportHeader) + (gHgfsShmemPages.freePageCount - 1) * sizeof (HgfsAsyncIov); dg = kmalloc(sizeof *dg + transportHeaderSize, GFP_ATOMIC); if (!dg) { LOG(4, (KERN_WARNING "%s failed to allocate\n", __func__)); retVal = FALSE; goto exit; } transportHeader = VMCI_DG_PAYLOAD(dg); for (i = 0; i < gHgfsShmemPages.totalPageCount; i++) { if (gHgfsShmemPages.list[i].free) { transportHeader->asyncIov[j].index = i; transportHeader->asyncIov[j].va = gHgfsShmemPages.list[i].va; transportHeader->asyncIov[j].pa = gHgfsShmemPages.list[i].pa; transportHeader->asyncIov[j].len = PAGE_SIZE; j++; } } dg->src = *(VMCIHandle *)channel->priv; dg->dst = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_HGFS_TRANSPORT); dg->payloadSize = transportHeaderSize; transportHeader->version = HGFS_VMCI_VERSION_1; ASSERT(gHgfsShmemPages.freePageCount == j); transportHeader->iovCount = j; transportHeader->pktType = HGFS_TH_REP_GET_PAGES; LOG(10, (KERN_WARNING "Sending %d Guest pages \n", i)); if ((ret = vmci_datagram_send(dg)) < VMCI_SUCCESS) { if (ret == HGFS_VMCI_TRANSPORT_ERROR) { LOG(0, (KERN_WARNING "HGFS Transport error occured. Don't blame VMCI\n")); } retVal = FALSE; } exit: if (retVal) { /* We successfully sent pages the the host. Mark all pages as allocated */ for (i = 0; i < gHgfsShmemPages.totalPageCount; i++) { gHgfsShmemPages.list[i].free = FALSE; } gHgfsShmemPages.freePageCount = 0; } kfree(dg); return retVal; } /* *----------------------------------------------------------------------------- * * HgfsVmciChannelCompleteRequest -- * * Completes the request that was serviced asynchronously by the server. * * Results: * None * * Side effects: * Request may be removed from the queue and sleeping thread is woken up. * *----------------------------------------------------------------------------- */ void HgfsVmciChannelCompleteRequest(uint64 id) // IN: Request ID { HgfsVmciTransportStatus *transportStatus; HgfsReq *req; spin_lock_bh(&vmciRequestProcessLock); /* Reference is taken here */ req = HgfsTransportGetPendingRequest(id); if (!req) { LOG(0, (KERN_WARNING "No request with id %"FMT64"u \n", id)); goto exit; } transportStatus = (HgfsVmciTransportStatus *)req->buffer; if (transportStatus->status != HGFS_TS_IO_COMPLETE) { LOG(0, (KERN_WARNING "Request not completed with id %"FMT64"u \n", id)); goto exit; } /* Request is completed (yay!), let's remove it from the list */ HgfsTransportRemovePendingRequest(req); req->payloadSize = transportStatus->size; HgfsCompleteReq(req); exit: if (req) { /* Drop the reference taken in *GetPendingRequest */ HgfsRequestPutRef(req); } spin_unlock_bh(&vmciRequestProcessLock); } /* *----------------------------------------------------------------------------- * * HgfsVmciChannelCallback -- * * Called when VMCI datagram is received. Note: This function runs inside * tasklet. It means that this function cannot run concurrently with * itself, thus it is safe to manipulate gHgfsShmemPages without locks. If this * ever changes, please consider using appropriate locks. * * Results: * 0 on Success, < 0 on Failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ static int HgfsVmciChannelCallback(void *data, // IN: unused VMCIDatagram *dg) // IN: datagram { HgfsVmciAsyncReply *reply = (HgfsVmciAsyncReply *)VMCI_DG_PAYLOAD(dg); HgfsTransportChannel *channel; LOG(10, (KERN_WARNING "Received VMCI channel Callback \n")); if (reply->version != HGFS_VMCI_VERSION_1) { return HGFS_VMCI_VERSION_MISMATCH; } switch (reply->pktType) { case HGFS_ASYNC_IOREP: LOG(10, (KERN_WARNING "Received ID%"FMT64"x \n", reply->response.id)); HgfsVmciChannelCompleteRequest(reply->response.id); break; case HGFS_ASYNC_IOREQ_SHMEM: HgfsRequestAsyncShmemDispatch(reply->shmem.iov, reply->shmem.count); break; case HGFS_ASYNC_IOREQ_GET_PAGES: channel = HgfsGetVmciChannel(); LOG(10, (KERN_WARNING "Should send pages to the host\n")); HgfsVmciChannelPassGuestPages(channel); break; default: ASSERT(0); return HGFS_VMCI_TRANSPORT_ERROR; } return 0; } /* *----------------------------------------------------------------------------- * * HgfsVmciChannelOpen -- * * Opens VMCI channel and passes guest pages to the host. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool HgfsVmciChannelOpen(HgfsTransportChannel *channel) // IN: Channel { int ret; int i; ASSERT(channel->status == HGFS_CHANNEL_NOTCONNECTED); ASSERT(channel->priv == NULL); memset(&gHgfsShmemPages, 0, sizeof gHgfsShmemPages); if (USE_VMCI == 0) { goto error; } spin_lock_init(&vmciRequestProcessLock); channel->priv = kmalloc(sizeof(VMCIHandle), GFP_KERNEL); if (!channel->priv) { goto error; } ret = vmci_datagram_create_handle( VMCI_INVALID_ID, /* Resource ID */ VMCI_FLAG_DG_NONE, /* Flags */ HgfsVmciChannelCallback,/* Datagram Recv Callback */ NULL, /* Callback data */ channel->priv); /* VMCI outhandle */ if (ret != VMCI_SUCCESS) { LOG(1, (KERN_WARNING "Failed to create VMCI handle %d\n", ret)); goto error; } gHgfsShmemPages.list = kmalloc(sizeof *gHgfsShmemPages.list * HGFS_VMCI_SHMEM_PAGES, GFP_KERNEL); if (!gHgfsShmemPages.list) { goto error; } memset(gHgfsShmemPages.list, 0, sizeof *gHgfsShmemPages.list * HGFS_VMCI_SHMEM_PAGES); for (i = 0; i < HGFS_VMCI_SHMEM_PAGES; i++) { gHgfsShmemPages.list[i].va = __get_free_page(GFP_KERNEL); if (!gHgfsShmemPages.list[i].va) { LOG(1, (KERN_WARNING "__get_free_page returned error \n")); if (i == 0) { /* Ouch. We failed on first call to __get_free_page */ goto error; } /* It's ok. We can still send few pages to the host */ break; } gHgfsShmemPages.list[i].pa = virt_to_phys((void *)(size_t)gHgfsShmemPages.list[i].va); gHgfsShmemPages.list[i].free = TRUE; } gHgfsShmemPages.totalPageCount = i; gHgfsShmemPages.freePageCount = i; ret = HgfsVmciChannelPassGuestPages(channel); if (!ret) { for (i = 0; i < gHgfsShmemPages.totalPageCount; i++) { LOG(1, (KERN_WARNING "Freeing pages\n")); free_page(gHgfsShmemPages.list[i].va); } LOG(1, (KERN_WARNING "Failed to pass pages to the guest %d\n", ret)); goto error; } return TRUE; error: kfree(gHgfsShmemPages.list); kfree(channel->priv); return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsVmciChannelTerminateSession -- * * Terminate session with the server. * * Results: * 0 on success and < 0 on error. * * Side effects: * None * *----------------------------------------------------------------------------- */ static int HgfsVmciChannelTerminateSession(HgfsTransportChannel *channel) { int ret = 0; VMCIDatagram *dg; HgfsVmciTransportHeader *transportHeader; dg = kmalloc(sizeof *dg + sizeof *transportHeader, GFP_KERNEL); if (NULL == dg) { LOG(4, (KERN_WARNING "%s failed to allocate\n", __func__)); return -ENOMEM; } /* Initialize datagram */ dg->src = *(VMCIHandle *)channel->priv; dg->dst = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_HGFS_TRANSPORT); dg->payloadSize = sizeof *transportHeader; transportHeader = VMCI_DG_PAYLOAD(dg); transportHeader->version = HGFS_VMCI_VERSION_1; transportHeader->iovCount = 0; transportHeader->pktType = HGFS_TH_TERMINATE_SESSION; LOG(1, (KERN_WARNING "Terminating session with host \n")); if ((ret = vmci_datagram_send(dg)) < VMCI_SUCCESS) { if (ret == HGFS_VMCI_TRANSPORT_ERROR) { LOG(0, (KERN_WARNING "HGFS Transport error occured. Don't blame VMCI\n")); } LOG(0, (KERN_WARNING "Cannot communicate with Server.\n")); } else { int i; for (i = 0; i < gHgfsShmemPages.totalPageCount; i++) { free_page(gHgfsShmemPages.list[i].va); } } kfree(dg); return ret; } /* *----------------------------------------------------------------------------- * * HgfsVmciChannelClose -- * * Destroy vmci handle. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsVmciChannelClose(HgfsTransportChannel *channel) // IN: Channel { ASSERT(channel->priv != NULL); HgfsVmciChannelTerminateSession(channel); vmci_datagram_destroy_handle(*(VMCIHandle *)channel->priv); kfree(channel->priv); kfree(gHgfsShmemPages.list); channel->priv = NULL; LOG(8, ("VMware hgfs: %s: vmci closed.\n", __func__)); } /* *----------------------------------------------------------------------------- * * HgfsVmciChannelAllocate -- * * Allocate request in the way that is suitable for sending through * vmci. Today, we just allocate a page for the request and we ignore * payloadSize. We need this to support variable sized requests in future. * * Results: * NULL on failure; otherwise address of the new request. * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsReq * HgfsVmciChannelAllocate(size_t payloadSize) // IN: Ignored { HgfsReq *req = NULL; const size_t size = PAGE_SIZE; req = kmalloc(size, GFP_KERNEL); if (likely(req)) { req->payload = req->buffer + sizeof (HgfsVmciTransportStatus); req->bufferSize = size - sizeof (HgfsVmciTransportStatus) - sizeof *req; } LOG(10, (KERN_WARNING "%s: Allocated Request\n", __func__)); return req; } /* *----------------------------------------------------------------------------- * * HgfsVmciChannelFree -- * * Free previously allocated request. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void HgfsVmciChannelFree(HgfsReq *req) { ASSERT(req); kfree(req); } /* *---------------------------------------------------------------------- * * HgfsVmciChannelSend -- * * Send a request via vmci. * * Results: * 0 on success, negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsVmciChannelSend(HgfsTransportChannel *channel, // IN: Channel HgfsReq *req) // IN: request to send { int ret; int iovCount = 0; VMCIDatagram *dg; HgfsVmciTransportHeader *transportHeader; HgfsVmciTransportStatus *transportStatus; size_t transportHeaderSize; size_t bufferSize; size_t total; uint64 pa; uint64 len; uint64 id; int j; ASSERT(req); ASSERT(req->buffer); ASSERT(req->state == HGFS_REQ_STATE_UNSENT || req->state == HGFS_REQ_STATE_ALLOCATED); ASSERT(req->payloadSize <= req->bufferSize); /* Note that req->bufferSize does not include chunk used by the transport. */ total = req->bufferSize + sizeof (HgfsVmciTransportStatus); /* Calculate number of entries for metaPacket */ iovCount = (total + (size_t)req->buffer % PAGE_SIZE - 1)/ PAGE_SIZE + 1; ASSERT(total + (size_t)req->buffer % PAGE_SIZE <= PAGE_SIZE); transportHeaderSize = sizeof *transportHeader + (iovCount + req->numEntries - 1) * sizeof (HgfsIov); dg = kmalloc(sizeof *dg + transportHeaderSize, GFP_KERNEL); if (NULL == dg) { LOG(4, (KERN_WARNING "%s failed to allocate\n", __func__)); return -ENOMEM; } /* Initialize datagram */ dg->src = *(VMCIHandle *)channel->priv; dg->dst = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_HGFS_TRANSPORT); dg->payloadSize = transportHeaderSize; transportHeader = VMCI_DG_PAYLOAD(dg); transportHeader->version = HGFS_VMCI_VERSION_1; total = req->bufferSize + sizeof (HgfsVmciTransportStatus); bufferSize = 0; for (iovCount = 0; bufferSize < req->bufferSize; iovCount++) { /* * req->buffer should have been allocated by kmalloc()/ __get_free_pages(). * Specifically, it cannot be a buffer that is mapped from high memory. * virt_to_phys() does not work for those. */ pa = virt_to_phys(req->buffer + bufferSize); len = total < (PAGE_SIZE - pa % PAGE_SIZE) ? total : (PAGE_SIZE - pa % PAGE_SIZE); bufferSize += len; total -= len; transportHeader->iov[iovCount].pa = pa; transportHeader->iov[iovCount].len = len; LOG(8, ("iovCount = %u PA = %"FMT64"x len=%u\n", iovCount, transportHeader->iov[iovCount].pa, transportHeader->iov[iovCount].len)); } /* Right now we do not expect discontigous request packet */ ASSERT(iovCount == 1); ASSERT(total == 0); ASSERT(bufferSize == req->bufferSize + sizeof (HgfsVmciTransportStatus)); LOG(0, (KERN_WARNING "Size of request is %Zu\n", req->payloadSize)); for (j = 0; j < req->numEntries; j++, iovCount++) { /* I will have to probably do page table walk here, haven't figured it out yet */ ASSERT(req->dataPacket); transportHeader->iov[iovCount].pa = page_to_phys(req->dataPacket[j].page); transportHeader->iov[iovCount].pa += req->dataPacket[j].offset; transportHeader->iov[iovCount].len = req->dataPacket[j].len; LOG(8, ("iovCount = %u PA = %"FMT64"x len=%u\n", iovCount, transportHeader->iov[iovCount].pa, transportHeader->iov[iovCount].len)); } transportHeader->iovCount = iovCount; transportHeader->pktType = HGFS_TH_REQUEST; /* Initialize transport Status */ transportStatus = (HgfsVmciTransportStatus *)req->buffer; transportStatus->status = HGFS_TS_IO_PENDING; transportStatus->size = req->bufferSize + sizeof (HgfsVmciTransportStatus); /* * Don't try to set req->state after vmci_datagram_send(). * It may be too late then. We could have received a datagram by then and * datagram handler expects request's state to be submitted. */ req->state = HGFS_REQ_STATE_SUBMITTED; id = req->id; if ((ret = vmci_datagram_send(dg)) < VMCI_SUCCESS) { if (ret == HGFS_VMCI_TRANSPORT_ERROR) { LOG(0, (KERN_WARNING "HGFS Transport error occured. Don't blame VMCI\n")); } else if (ret == HGFS_VMCI_VERSION_MISMATCH) { LOG(0, (KERN_WARNING "Version mismatch\n")); } req->state = HGFS_REQ_STATE_UNSENT; kfree(dg); return -EIO; } LOG(0, (KERN_WARNING "Hgfs Received response\n")); HgfsVmciChannelCompleteRequest(id); kfree(dg); return 0; } /* *---------------------------------------------------------------------- * * HgfsGetVmciChannel -- * * Initialize Vmci channel. * * Results: * Always return pointer to Vmci channel. * * Side effects: * None * *---------------------------------------------------------------------- */ HgfsTransportChannel* HgfsGetVmciChannel(void) { return &channel; } open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/module.c0000644765153500003110000000560012220061556021172 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * module.c -- * * Module-specific components of the vmhgfs driver. */ /* Must come before any kernel header file. */ #include "driver-config.h" #include #include "compat_module.h" #include "filesystem.h" #include "module.h" #include "vmhgfs_version.h" #ifdef VMX86_DEVEL /* * Logging is available only in devel build. */ int LOGLEVEL_THRESHOLD = 4; module_param(LOGLEVEL_THRESHOLD, int, 0444); MODULE_PARM_DESC(LOGLEVEL_THRESHOLD, "Set verbosity (0 means no log, 10 means very verbose, 4 is default)"); #endif /* Module information. */ MODULE_AUTHOR("VMware, Inc."); MODULE_DESCRIPTION("VMware Host/Guest File System"); MODULE_VERSION(VMHGFS_DRIVER_VERSION_STRING); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("vmware_vmhgfs"); /* * Starting with SLE10sp2, Novell requires that IHVs sign a support agreement * with them and mark their kernel modules as externally supported via a * change to the module header. If this isn't done, the module will not load * by default (i.e., neither mkinitrd nor modprobe will accept it). */ MODULE_INFO(supported, "external"); /* *---------------------------------------------------------------------- * * init_module -- * * linux module entry point. Called by /sbin/insmod command. * Sets up internal state and registers the hgfs filesystem * with the kernel. * * Results: * Returns 0 on success, an error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ int init_module(void) { return HgfsInitFileSystem() ? 0 : -EBUSY; } /* *---------------------------------------------------------------------- * * cleanup_module -- * * Called by /sbin/rmmod. Unregisters filesystem with kernel, * cleans up internal state, and unloads module. * * Note: for true kernel 2.4 compliance, this should be * "module_exit". * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ void cleanup_module(void) { HgfsCleanupFileSystem(); } open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/filesystem.h0000644765153500003110000000232012220061556022072 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * filesystem.h -- * * High-level filesystem operations for the filesystem portion of * the vmhgfs driver. */ #ifndef _HGFS_DRIVER_FILESYSTEM_H_ #define _HGFS_DRIVER_FILESYSTEM_H_ #include "vm_basic_types.h" /* Public functions (with respect to the entire module). */ Bool HgfsInitFileSystem(void); Bool HgfsCleanupFileSystem(void); #endif // _HGFS_DRIVER_FILESYSTEM_H_ open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/request.c0000644765153500003110000001743212220061556021403 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * request.c -- * * Functions dealing with the creation, deletion, and sending of HGFS * requests are defined here. */ /* Must come before any kernel header file. */ #include "driver-config.h" #include #include #include #include "compat_kernel.h" #include "compat_sched.h" #include "compat_semaphore.h" #include "compat_slab.h" #include "compat_spinlock.h" #include "module.h" #include "request.h" #include "transport.h" #include "fsutil.h" #include "vm_assert.h" /* *---------------------------------------------------------------------- * * HgfsRequestInit -- * * Initializes new request structure. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ static void HgfsRequestInit(HgfsReq *req, // IN: request to initialize int requestId) // IN: ID assigned to the request { ASSERT(req); kref_init(&req->kref); INIT_LIST_HEAD(&req->list); init_waitqueue_head(&req->queue); req->id = requestId; req->payloadSize = 0; req->state = HGFS_REQ_STATE_ALLOCATED; req->numEntries = 0; } /* *---------------------------------------------------------------------- * * HgfsGetNewRequest -- * * Allocates and initializes new request structure. * * Results: * On success the new struct is returned with all fields * initialized. Returns NULL on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ HgfsReq * HgfsGetNewRequest(void) { static atomic_t hgfsIdCounter = ATOMIC_INIT(0); HgfsReq *req; req = HgfsTransportAllocateRequest(HGFS_PACKET_MAX); if (req == NULL) { LOG(4, (KERN_DEBUG "VMware hgfs: %s: can't allocate memory\n", __func__)); return NULL; } HgfsRequestInit(req, atomic_inc_return(&hgfsIdCounter) - 1); return req; } /* *---------------------------------------------------------------------- * * HgfsCopyRequest -- * * Allocates and initializes new request structure and copies * existing request into it. * * Results: * On success the new struct is returned with all fields * initialized. Returns NULL on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ HgfsReq * HgfsCopyRequest(HgfsReq *req) // IN: request to be copied { HgfsReq *newReq; ASSERT(req); newReq = HgfsTransportAllocateRequest(req->bufferSize); if (newReq == NULL) { LOG(4, (KERN_DEBUG "VMware hgfs: %s: can't allocate memory\n", __func__)); return NULL; } HgfsRequestInit(newReq, req->id); memcpy(newReq->dataPacket, req->dataPacket, req->numEntries * sizeof (req->dataPacket[0])); newReq->numEntries = req->numEntries; newReq->payloadSize = req->payloadSize; memcpy(newReq->payload, req->payload, req->payloadSize); return newReq; } /* *---------------------------------------------------------------------- * * HgfsSendRequest -- * * Send out an HGFS request via transport layer, and wait for the reply. * * Results: * Returns zero on success, negative number on error. * * Side effects: * None * *---------------------------------------------------------------------- */ int HgfsSendRequest(HgfsReq *req) // IN/OUT: Outgoing request { int ret; ASSERT(req); ASSERT(req->payloadSize <= req->bufferSize); LOG(4, (KERN_WARNING "Size of buffer %Zu\n", req->bufferSize)); req->state = HGFS_REQ_STATE_UNSENT; LOG(8, (KERN_DEBUG "VMware hgfs: HgfsSendRequest: Sending request id %d\n", req->id)); ret = HgfsTransportSendRequest(req); LOG(8, (KERN_DEBUG "VMware hgfs: HgfsSendRequest: request finished, " "return %d\n", ret)); return ret; } /* *---------------------------------------------------------------------- * * HgfsRequestFreeMemory -- * * Frees memory allocated for a request. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ static void HgfsRequestFreeMemory(struct kref *kref) { HgfsReq *req = container_of(kref, HgfsReq, kref); LOG(10, (KERN_DEBUG "VMware hgfs: %s: freeing request %d\n", __func__, req->id)); HgfsTransportFreeRequest(req); } /* *---------------------------------------------------------------------- * * HgfsRequestPutRef -- * * Decrease reference count of HGFS request. * * Results: * None * * Side effects: * May cause request to be destroyed. * *---------------------------------------------------------------------- */ void HgfsRequestPutRef(HgfsReq *req) // IN: Request { if (req) { LOG(10, (KERN_DEBUG "VMware hgfs: %s: request %d\n", __func__, req->id)); kref_put(&req->kref, HgfsRequestFreeMemory); } } /* *---------------------------------------------------------------------- * * HgfsRequestGetRef -- * * Increment reference count of HGFS request. * * Results: * Pointer to the same HGFS request. * * Side effects: * None * *---------------------------------------------------------------------- */ HgfsReq * HgfsRequestGetRef(HgfsReq *req) // IN: Request { if (req) { LOG(10, (KERN_DEBUG "VMware hgfs: %s: request %d\n", __func__, req->id)); kref_get(&req->kref); } return req; } /* *---------------------------------------------------------------------- * * HgfsReplyStatus -- * * Return reply status. * * Results: * Returns reply status as per the protocol. * XXX: Needs changes when vmci headers are added. * * Side effects: * None * *---------------------------------------------------------------------- */ HgfsStatus HgfsReplyStatus(HgfsReq *req) // IN { HgfsReply *rep; rep = (HgfsReply *)(HGFS_REQ_PAYLOAD(req)); return rep->status; } /* *---------------------------------------------------------------------- * * HgfsCompleteReq -- * * Marks request as completed and wakes up sender. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ void HgfsCompleteReq(HgfsReq *req) // IN: Request { ASSERT(req); req->state = HGFS_REQ_STATE_COMPLETED; /* Wake up the client process waiting for the reply to this request. */ wake_up(&req->queue); } /* *---------------------------------------------------------------------- * * HgfsFailReq -- * * Marks request as failed and calls HgfsCompleteReq to wake up * sender. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ void HgfsFailReq(HgfsReq *req, // IN: erequest to be marked failed int error) // IN: error code { HgfsReply *reply = req->payload; reply->id = req->id; reply->status = error; req->payloadSize = sizeof *reply; HgfsCompleteReq(req); } open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/Makefile.kernel0000644765153500003110000001057612220061556022470 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 1998 VMware, Inc. All rights reserved. # # 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 version 2 and no later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ########################################################## #### #### VMware vmhgfs Makefile to be distributed externally #### INCLUDE += -I. EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE) EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/cachector.c, -DVMW_KMEMCR_CTOR_HAS_3_ARGS, ) EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/cachector1.c, -DVMW_KMEMCR_CTOR_HAS_2_ARGS, ) EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/file_operations_fsync.c, -DVMW_FSYNC_31, ) # Note: These tests are inverted EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/getsb1.c,, -DVMW_GETSB_2618) EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/statfs1.c,, -DVMW_STATFS_2618) EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/inode1.c,, -DVMW_INODE_2618) MODPOST_VMCI_SYMVERS := $(wildcard $(MODULEBUILDDIR)/VMwareVMCIModule.symvers) obj-m += $(DRIVER).o $(DRIVER)-y := $(subst $(SRCROOT)/, , $(patsubst %.c, %.o, $(wildcard $(SRCROOT)/*.c))) # # In open-vm-tools, need to compile the common sources from the lib directory. # VMHGFS_PATH := $(shell cd $(SRCROOT) && pwd) ifdef OVT_SOURCE_DIR LIBBACKDOOR_PATH := $(call VMLIB_PATH,backdoor) LIBHGFS_PATH := $(call VMLIB_PATH,hgfs) LIBHGFSBD_PATH := $(call VMLIB_PATH,hgfsBd) LIBMESSAGE_PATH := $(call VMLIB_PATH,message) LIBRPCOUT_PATH := $(call VMLIB_PATH,rpcOut) STUBS_PATH := $(OVT_SOURCE_DIR)/modules/linux/shared INCLUDE += -I$(LIBBACKDOOR_PATH) INCLUDE += -I$(LIBHGFS_PATH) LIBBACKDOOR := backdoor.o LIBBACKDOOR += backdoorGcc32.o LIBBACKDOOR += backdoorGcc64.o LIBHGFS := cpName.o LIBHGFS += cpNameLinux.o LIBHGFS += cpNameLite.o LIBHGFS += hgfsEscape.o LIBHGFS += hgfsUtil.o LIBHGFSBD := hgfsBd.o LIBMESSAGE := message.o LIBRPCOUT := rpcout.o $(addprefix $(VMHGFS_PATH)/,$(LIBBACKDOOR)): $(VMHGFS_PATH)/%.o: $(LIBBACKDOOR_PATH)/%.c $(Q)$(rule_cc_o_c) $(addprefix $(VMHGFS_PATH)/,$(LIBHGFS)): $(VMHGFS_PATH)/%.o: $(LIBHGFS_PATH)/%.c $(Q)$(rule_cc_o_c) $(addprefix $(VMHGFS_PATH)/,$(LIBHGFSBD)): $(VMHGFS_PATH)/%.o: $(LIBHGFSBD_PATH)/%.c $(Q)$(rule_cc_o_c) $(addprefix $(VMHGFS_PATH)/,$(LIBMESSAGE)): $(VMHGFS_PATH)/%.o: $(LIBMESSAGE_PATH)/%.c $(Q)$(rule_cc_o_c) $(addprefix $(VMHGFS_PATH)/,$(LIBRPCOUT)): $(VMHGFS_PATH)/%.o: $(LIBRPCOUT_PATH)/%.c $(Q)$(rule_cc_o_c) $(DRIVER)-y += $(LIBBACKDOOR) $(DRIVER)-y += $(LIBHGFS) $(DRIVER)-y += $(LIBHGFSBD) $(DRIVER)-y += $(LIBMESSAGE) $(DRIVER)-y += $(LIBRPCOUT) else STUBS_PATH := $(VMHGFS_PATH)/shared endif STUBS := kernelStubsLinux.o $(DRIVER)-y += $(STUBS) $(addprefix $(VMHGFS_PATH)/,$(STUBS)): $(VMHGFS_PATH)/%.o: $(STUBS_PATH)/%.c $(Q)$(rule_cc_o_c) # # On a 32-bit machine, strip out 64-bit backdoor code, and vice versa. # ifeq ($(CONFIG_X86_64),y) $(DRIVER)-y := $(filter-out backdoorGcc32.o, $($(DRIVER)-y)) else $(DRIVER)-y := $(filter-out backdoorGcc64.o, $($(DRIVER)-y)) endif clean: rm -rf $(wildcard $(DRIVER).mod.c $(DRIVER).ko .tmp_versions \ Module.symvers Modules.symvers Module.markers modules.order \ $(foreach dir,./,$(addprefix $(dir),.*.cmd .*.o.flags *.o))) # # vmhgfs kernel module uses symbols from the VMCI kernel module. Copy the # Module.symvers file here so that the vmhgfs module knows about the VMCI version. # This is not done for tar builds because the tools install takes care of it. # prebuild:: ifneq ($(MODULEBUILDDIR),) ifeq ($(MODPOST_VMCI_SYMVERS),) $(shell echo >&2 "Building vmhgfs without VMCI module symbols.") else $(shell echo >&2 "Building vmhgfs with VMCI module symbols.") cp -f $(MODPOST_VMCI_SYMVERS) $(SRCROOT)/Module.symvers endif endif open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/fsutil.c0000644765153500003110000015136612220061556021226 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * fsutil.c -- * * Functions used in more than one type of filesystem operation will be * exported from this file. */ /* Must come before any kernel header file. */ #include "driver-config.h" #include /* Must come before compat_dcache. */ #include "compat_fs.h" #include "compat_dcache.h" #include "compat_kernel.h" #include "compat_sched.h" #include "compat_slab.h" #include "compat_spinlock.h" #include "vm_assert.h" #include "cpName.h" #include "cpNameLite.h" #include "hgfsUtil.h" #include "module.h" #include "request.h" #include "fsutil.h" #include "hgfsProto.h" #include "vm_basic_types.h" static void HgfsSetFileType(struct inode *inode, HgfsAttrInfo const *attr); static int HgfsUnpackGetattrReply(HgfsReq *req, HgfsAttrInfo *attr, char **fileName); static int HgfsPackGetattrRequest(HgfsReq *req, struct dentry *dentry, Bool allowHandleReuse, HgfsOp opUsed, HgfsAttrInfo *attr); /* * Private function implementations. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) /* *---------------------------------------------------------------------------- * * set_nlink -- * * Set an inode's link count. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------------- */ static inline void set_nlink(struct inode *inode, unsigned int nlink) { inode->i_nlink = nlink; } #endif /* *---------------------------------------------------------------------- * * HgfsSetFileType -- * * Set file type in inode according to the hgfs attributes. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ static void HgfsSetFileType(struct inode *inode, // IN/OUT: Inode to update HgfsAttrInfo const *attr) // IN: Attrs to use to update { ASSERT(inode); ASSERT(attr); switch (attr->type) { case HGFS_FILE_TYPE_DIRECTORY: inode->i_mode = S_IFDIR; inode->i_op = &HgfsDirInodeOperations; inode->i_fop = &HgfsDirFileOperations; break; case HGFS_FILE_TYPE_SYMLINK: inode->i_mode = S_IFLNK; inode->i_op = &HgfsLinkInodeOperations; break; case HGFS_FILE_TYPE_REGULAR: inode->i_mode = S_IFREG; inode->i_op = &HgfsFileInodeOperations; inode->i_fop = &HgfsFileFileOperations; inode->i_data.a_ops = &HgfsAddressSpaceOperations; break; default: /* * XXX Should never happen. I'd put NOT_IMPLEMENTED() here * but if the driver ever goes in the host it's probably not * a good idea for an attacker to be able to hang the host * simply by using a bogus file type in a reply. [bac] */ LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSetFileType: UNSUPPORTED " "inode type\n")); inode->i_mode = 0; // NOT_IMPLEMENTED(); break; } } /* *---------------------------------------------------------------------- * * HgfsUnpackGetattrReply -- * * This function abstracts the differences between a GetattrV1 and * a GetattrV2. The caller provides the packet containing the reply * and we populate the AttrInfo with version-independent information. * * Note that attr->requestType has already been populated so that we * know whether to expect a V1 or V2 reply. * * Results: * 0 on success, anything else on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsUnpackGetattrReply(HgfsReq *req, // IN: Reply packet HgfsAttrInfo *attr, // IN/OUT: Attributes char **fileName) // OUT: file name { int result; char *name = NULL; uint32 length = 0; ASSERT(req); ASSERT(attr); result = HgfsUnpackCommonAttr(req, attr); if (result != 0) { return result; } /* GetattrV2+ also wants a symlink target if it exists. */ if (attr->requestType == HGFS_OP_GETATTR_V3) { HgfsReplyGetattrV3 *replyV3 = (HgfsReplyGetattrV3 *)(HGFS_REP_PAYLOAD_V3(req)); name = replyV3->symlinkTarget.name; length = replyV3->symlinkTarget.length; /* Skip the symlinkTarget if it's too long. */ if (length > HGFS_NAME_BUFFER_SIZET(req->bufferSize, sizeof *replyV3 + sizeof(HgfsReply))) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsUnpackGetattrReply: symlink " "target name too long, ignoring\n")); return -ENAMETOOLONG; } } else if (attr->requestType == HGFS_OP_GETATTR_V2) { HgfsReplyGetattrV2 *replyV2 = (HgfsReplyGetattrV2 *) (HGFS_REQ_PAYLOAD(req)); name = replyV2->symlinkTarget.name; length = replyV2->symlinkTarget.length; /* Skip the symlinkTarget if it's too long. */ if (length > HGFS_NAME_BUFFER_SIZE(req->bufferSize, replyV2)) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsUnpackGetattrReply: symlink " "target name too long, ignoring\n")); return -ENAMETOOLONG; } } if (fileName) { if (length != 0) { *fileName = kmalloc(length + 1, GFP_KERNEL); if (*fileName == NULL) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsUnpackGetattrReply: out of " "memory allocating symlink target name, ignoring\n")); return -ENOMEM; } /* Copy and convert. From now on, the symlink target is in UTF8. */ memcpy(*fileName, name, length); CPNameLite_ConvertFrom(*fileName, length, '/'); (*fileName)[length] = '\0'; } else { *fileName = NULL; } } return 0; } /* *---------------------------------------------------------------------- * * HgfsPackGetattrRequest -- * * Setup the getattr request, depending on the op version. When possible, * we will issue the getattr using an existing open HGFS handle. * * Results: * Returns zero on success, or negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsPackGetattrRequest(HgfsReq *req, // IN/OUT: Request buffer struct dentry *dentry, // IN: Dentry containing name Bool allowHandleReuse, // IN: Can we use a handle? HgfsOp opUsed, // IN: Op to be used HgfsAttrInfo *attr) // OUT: Attrs to update { size_t reqBufferSize; size_t reqSize; int result = 0; HgfsHandle handle; char *fileName = NULL; uint32 *fileNameLength = NULL; ASSERT(attr); ASSERT(dentry); ASSERT(req); attr->requestType = opUsed; switch (opUsed) { case HGFS_OP_GETATTR_V3: { HgfsRequest *requestHeader; HgfsRequestGetattrV3 *requestV3; /* Fill out the request packet. */ requestHeader = (HgfsRequest *)(HGFS_REQ_PAYLOAD(req)); requestHeader->op = opUsed; requestHeader->id = req->id; requestV3 = (HgfsRequestGetattrV3 *)HGFS_REQ_PAYLOAD_V3(req); /* * When possible, issue a getattr using an existing handle. This will * give us slightly better performance on a Windows server, and is more * correct regardless. If we don't find a handle, fall back on getattr * by name. */ requestV3->hints = 0; if (allowHandleReuse && HgfsGetHandle(dentry->d_inode, 0, &handle) == 0) { requestV3->fileName.flags = HGFS_FILE_NAME_USE_FILE_DESC; requestV3->fileName.fid = handle; requestV3->fileName.length = 0; requestV3->fileName.caseType = HGFS_FILE_NAME_DEFAULT_CASE; fileName = NULL; } else { fileName = requestV3->fileName.name; fileNameLength = &requestV3->fileName.length; requestV3->fileName.flags = 0; requestV3->fileName.fid = HGFS_INVALID_HANDLE; requestV3->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; } requestV3->reserved = 0; reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(requestV3); reqBufferSize = HGFS_NAME_BUFFER_SIZET(req->bufferSize, reqSize); break; } case HGFS_OP_GETATTR_V2: { HgfsRequestGetattrV2 *requestV2; requestV2 = (HgfsRequestGetattrV2 *)(HGFS_REQ_PAYLOAD(req)); requestV2->header.op = opUsed; requestV2->header.id = req->id; /* * When possible, issue a getattr using an existing handle. This will * give us slightly better performance on a Windows server, and is more * correct regardless. If we don't find a handle, fall back on getattr * by name. */ if (allowHandleReuse && HgfsGetHandle(dentry->d_inode, 0, &handle) == 0) { requestV2->hints = HGFS_ATTR_HINT_USE_FILE_DESC; requestV2->file = handle; fileName = NULL; } else { requestV2->hints = 0; fileName = requestV2->fileName.name; fileNameLength = &requestV2->fileName.length; } reqSize = sizeof *requestV2; reqBufferSize = HGFS_NAME_BUFFER_SIZE(req->bufferSize, requestV2); break; } case HGFS_OP_GETATTR: { HgfsRequestGetattr *requestV1; requestV1 = (HgfsRequestGetattr *)(HGFS_REQ_PAYLOAD(req)); requestV1->header.op = opUsed; requestV1->header.id = req->id; fileName = requestV1->fileName.name; fileNameLength = &requestV1->fileName.length; reqSize = sizeof *requestV1; reqBufferSize = HGFS_NAME_BUFFER_SIZE(req->bufferSize, requestV1); break; } default: LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackGetattrRequest: unexpected " "OP type encountered\n")); result = -EPROTO; goto out; } /* Avoid all this extra work when we're doing a getattr by handle. */ if (fileName != NULL) { /* Build full name to send to server. */ if (HgfsBuildPath(fileName, reqBufferSize, dentry) < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackGetattrRequest: build path " "failed\n")); result = -EINVAL; goto out; } LOG(6, (KERN_DEBUG "VMware hgfs: HgfsPackGetattrRequest: getting attrs " "for \"%s\"\n", fileName)); /* Convert to CP name. */ result = CPName_ConvertTo(fileName, reqBufferSize, fileName); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackGetattrRequest: CP " "conversion failed\n")); result = -EINVAL; goto out; } *fileNameLength = result; } req->payloadSize = reqSize + result; result = 0; out: return result; } /* * Public function implementations. */ /* *---------------------------------------------------------------------- * * HgfsUnpackCommonAttr -- * * This function abstracts the HgfsAttr struct behind HgfsAttrInfo. * Callers can pass one of four replies into it and receive back the * attributes for those replies. * * Callers must populate attr->requestType so that we know whether to * expect a V1 or V2 Attr struct. * * Results: * Zero on success, non-zero otherwise. * * Side effects: * None * *---------------------------------------------------------------------- */ int HgfsUnpackCommonAttr(HgfsReq *req, // IN: Reply packet HgfsAttrInfo *attrInfo) // OUT: Attributes { HgfsReplyGetattrV3 *getattrReplyV3; HgfsReplyGetattrV2 *getattrReplyV2; HgfsReplyGetattr *getattrReplyV1; HgfsReplySearchReadV3 *searchReadReplyV3; HgfsReplySearchReadV2 *searchReadReplyV2; HgfsReplySearchRead *searchReadReplyV1; HgfsDirEntry *dirent; HgfsAttrV2 *attrV2 = NULL; HgfsAttr *attrV1 = NULL; ASSERT(req); ASSERT(attrInfo); switch (attrInfo->requestType) { case HGFS_OP_GETATTR_V3: getattrReplyV3 = (HgfsReplyGetattrV3 *)(HGFS_REP_PAYLOAD_V3(req)); attrV2 = &getattrReplyV3->attr; break; case HGFS_OP_GETATTR_V2: getattrReplyV2 = (HgfsReplyGetattrV2 *)(HGFS_REQ_PAYLOAD(req)); attrV2 = &getattrReplyV2->attr; break; case HGFS_OP_GETATTR: getattrReplyV1 = (HgfsReplyGetattr *)(HGFS_REQ_PAYLOAD(req)); attrV1 = &getattrReplyV1->attr; break; case HGFS_OP_SEARCH_READ_V3: searchReadReplyV3 = (HgfsReplySearchReadV3 *)(HGFS_REP_PAYLOAD_V3(req)); dirent = (HgfsDirEntry *)searchReadReplyV3->payload; attrV2 = &dirent->attr; break; case HGFS_OP_SEARCH_READ_V2: searchReadReplyV2 = (HgfsReplySearchReadV2 *)(HGFS_REQ_PAYLOAD(req)); attrV2 = &searchReadReplyV2->attr; break; case HGFS_OP_SEARCH_READ: searchReadReplyV1 = (HgfsReplySearchRead *)(HGFS_REQ_PAYLOAD(req)); attrV1 = &searchReadReplyV1->attr; break; default: LOG(4, (KERN_DEBUG "VMware hgfs: HgfsUnpackCommonAttr: unexpected op " "in reply packet\n")); return -EPROTO; } if (attrV2 != NULL) { attrInfo->mask = 0; if (attrV2->mask & HGFS_ATTR_VALID_TYPE) { attrInfo->type = attrV2->type; attrInfo->mask |= HGFS_ATTR_VALID_TYPE; } if (attrV2->mask & HGFS_ATTR_VALID_SIZE) { attrInfo->size = attrV2->size; attrInfo->mask |= HGFS_ATTR_VALID_SIZE; } if (attrV2->mask & HGFS_ATTR_VALID_ACCESS_TIME) { attrInfo->accessTime = attrV2->accessTime; attrInfo->mask |= HGFS_ATTR_VALID_ACCESS_TIME; } if (attrV2->mask & HGFS_ATTR_VALID_WRITE_TIME) { attrInfo->writeTime = attrV2->writeTime; attrInfo->mask |= HGFS_ATTR_VALID_WRITE_TIME; } if (attrV2->mask & HGFS_ATTR_VALID_CHANGE_TIME) { attrInfo->attrChangeTime = attrV2->attrChangeTime; attrInfo->mask |= HGFS_ATTR_VALID_CHANGE_TIME; } if (attrV2->mask & HGFS_ATTR_VALID_SPECIAL_PERMS) { attrInfo->specialPerms = attrV2->specialPerms; attrInfo->mask |= HGFS_ATTR_VALID_SPECIAL_PERMS; } if (attrV2->mask & HGFS_ATTR_VALID_OWNER_PERMS) { attrInfo->ownerPerms = attrV2->ownerPerms; attrInfo->mask |= HGFS_ATTR_VALID_OWNER_PERMS; } if (attrV2->mask & HGFS_ATTR_VALID_GROUP_PERMS) { attrInfo->groupPerms = attrV2->groupPerms; attrInfo->mask |= HGFS_ATTR_VALID_GROUP_PERMS; } if (attrV2->mask & HGFS_ATTR_VALID_OTHER_PERMS) { attrInfo->otherPerms = attrV2->otherPerms; attrInfo->mask |= HGFS_ATTR_VALID_OTHER_PERMS; } if (attrV2->mask & HGFS_ATTR_VALID_USERID) { attrInfo->userId = attrV2->userId; attrInfo->mask |= HGFS_ATTR_VALID_USERID; } if (attrV2->mask & HGFS_ATTR_VALID_GROUPID) { attrInfo->groupId = attrV2->groupId; attrInfo->mask |= HGFS_ATTR_VALID_GROUPID; } if (attrV2->mask & HGFS_ATTR_VALID_FILEID) { attrInfo->hostFileId = attrV2->hostFileId; attrInfo->mask |= HGFS_ATTR_VALID_FILEID; } if (attrV2->mask & HGFS_ATTR_VALID_EFFECTIVE_PERMS) { attrInfo->effectivePerms = attrV2->effectivePerms; attrInfo->mask |= HGFS_ATTR_VALID_EFFECTIVE_PERMS; } } else if (attrV1 != NULL) { /* Implicit mask for a Version 1 attr. */ attrInfo->mask = HGFS_ATTR_VALID_TYPE | HGFS_ATTR_VALID_SIZE | HGFS_ATTR_VALID_ACCESS_TIME | HGFS_ATTR_VALID_WRITE_TIME | HGFS_ATTR_VALID_CHANGE_TIME | HGFS_ATTR_VALID_OWNER_PERMS | HGFS_ATTR_VALID_EFFECTIVE_PERMS; attrInfo->type = attrV1->type; attrInfo->size = attrV1->size; attrInfo->accessTime = attrV1->accessTime; attrInfo->writeTime = attrV1->writeTime; attrInfo->attrChangeTime = attrV1->attrChangeTime; attrInfo->ownerPerms = attrV1->permissions; attrInfo->effectivePerms = attrV1->permissions; } return 0; } /* *---------------------------------------------------------------------- * * HgfsChangeFileAttributes -- * * Update an inode's attributes to match those of the HgfsAttr. May * cause dirty pages to be flushed, and may invalidate cached pages, * if there was a change in the file size or modification time in * the server. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ void HgfsChangeFileAttributes(struct inode *inode, // IN/OUT: Inode HgfsAttrInfo const *attr) // IN: New attrs { HgfsSuperInfo *si; Bool needInvalidate = FALSE; ASSERT(inode); ASSERT(inode->i_sb); ASSERT(attr); si = HGFS_SB_TO_COMMON(inode->i_sb); LOG(6, (KERN_DEBUG "VMware hgfs: HgfsChangeFileAttributes: entered\n")); HgfsSetFileType(inode, attr); /* * Set the access mode. For hosts that don't give us group or other * bits (Windows), we use the owner bits in their stead. */ inode->i_mode &= ~S_IALLUGO; if (attr->mask & HGFS_ATTR_VALID_SPECIAL_PERMS) { inode->i_mode |= (attr->specialPerms << 9); } if (attr->mask & HGFS_ATTR_VALID_OWNER_PERMS) { inode->i_mode |= (attr->ownerPerms << 6); } if (attr->mask & HGFS_ATTR_VALID_GROUP_PERMS) { inode->i_mode |= (attr->groupPerms << 3); } else { inode->i_mode |= ((inode->i_mode & S_IRWXU) >> 3); } if (attr->mask & HGFS_ATTR_VALID_OTHER_PERMS) { inode->i_mode |= (attr->otherPerms); } else { inode->i_mode |= ((inode->i_mode & S_IRWXU) >> 6); } /* Mask the access mode. */ switch (attr->type) { case HGFS_FILE_TYPE_REGULAR: inode->i_mode &= ~si->fmask; break; case HGFS_FILE_TYPE_DIRECTORY: inode->i_mode &= ~si->dmask; break; default: /* Nothing else gets masked. */ break; } /* * This field is used to represent the number of hard links. If the file is * really a file, this is easy; our filesystem doesn't support hard-linking, * so we just set it to 1. If the field is a directory, the number of links * represents the number of subdirectories, including '.' and "..". * * In either case, what we're doing isn't ideal. We've carefully tracked the * number of links through calls to HgfsMkdir and HgfsDelete, and now some * revalidate will make us trample on the number of links. But we have no * choice: someone on the server may have made our local view of the number * of links inconsistent (by, say, removing a directory) , and without the * ability to retrieve nlink via getattr, we have no way of knowing that. * * XXX: So in the future, adding nlink to getattr would be nice. At that * point we may as well just implement hard links anyway. Note that user * programs seem to have issues with a link count greater than 1 that isn't * accurate. I experimented with setting nlink to 2 for directories (to * account for '.' and ".."), and find printed a hard link error. So until * we have getattr support for nlink, everyone gets 1. */ set_nlink(inode, 1); /* * Use the stored uid and gid if we were given them at mount-time, or if * the server didn't give us a uid or gid. */ if (si->uidSet || (attr->mask & HGFS_ATTR_VALID_USERID) == 0) { inode->i_uid = si->uid; } else { inode->i_uid = attr->userId; } if (si->gidSet || (attr->mask & HGFS_ATTR_VALID_GROUPID) == 0) { inode->i_gid = si->gid; } else { inode->i_gid = attr->groupId; } inode->i_rdev = 0; /* Device nodes are not supported */ #if !defined VMW_INODE_2618 inode->i_blksize = HGFS_BLOCKSIZE; #endif /* * Invalidate cached pages if we didn't receive the file size, or if it has * changed on the server. */ if (attr->mask & HGFS_ATTR_VALID_SIZE) { loff_t oldSize = compat_i_size_read(inode); inode->i_blocks = (attr->size + HGFS_BLOCKSIZE - 1) / HGFS_BLOCKSIZE; if (oldSize != attr->size) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsChangeFileAttributes: new file " "size: %"FMT64"u, old file size: %Lu\n", attr->size, oldSize)); needInvalidate = TRUE; } compat_i_size_write(inode, attr->size); } else { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsChangeFileAttributes: did not " "get file size\n")); needInvalidate = TRUE; } if (attr->mask & HGFS_ATTR_VALID_ACCESS_TIME) { HGFS_SET_TIME(inode->i_atime, attr->accessTime); } else { HGFS_SET_TIME(inode->i_atime, HGFS_GET_CURRENT_TIME()); } /* * Invalidate cached pages if we didn't receive the modification time, or if * it has changed on the server. */ if (attr->mask & HGFS_ATTR_VALID_WRITE_TIME) { HGFS_DECLARE_TIME(newTime); HGFS_SET_TIME(newTime, attr->writeTime); if (!HGFS_EQUAL_TIME(newTime, inode->i_mtime)) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsChangeFileAttributes: new mod " "time: %ld:%lu, old mod time: %ld:%lu\n", HGFS_PRINT_TIME(newTime), HGFS_PRINT_TIME(inode->i_mtime))); needInvalidate = TRUE; } HGFS_SET_TIME(inode->i_mtime, attr->writeTime); } else { needInvalidate = TRUE; LOG(4, (KERN_DEBUG "VMware hgfs: HgfsChangeFileAttributes: did not " "get mod time\n")); HGFS_SET_TIME(inode->i_mtime, HGFS_GET_CURRENT_TIME()); } /* * Windows doesn't know about ctime, and might send us something * bogus; if the ctime is invalid, use the mtime instead. */ if (attr->mask & HGFS_ATTR_VALID_CHANGE_TIME) { if (HGFS_SET_TIME(inode->i_ctime, attr->attrChangeTime)) { inode->i_ctime = inode->i_mtime; } } else { HGFS_SET_TIME(inode->i_ctime, HGFS_GET_CURRENT_TIME()); } /* * Compare old size and write time with new size and write time. If there's * a difference (or if we didn't get a new size or write time), the file * must have been written to, and we need to invalidate our cached pages. */ if (S_ISREG(inode->i_mode) && needInvalidate) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsChangeFileAttributes: file has " "changed on the server, invalidating pages.\n")); compat_filemap_write_and_wait(inode->i_mapping); compat_invalidate_remote_inode(inode); } } /* *---------------------------------------------------------------------- * * HgfsPrivateGetattr -- * * Internal getattr routine. Send a getattr request to the server * for the indicated remote name, and if it succeeds copy the * results of the getattr into the provided HgfsAttrInfo. * * fileName (if supplied) will be set to a newly allocated string * if the file is a symlink; it's the caller's duty to free it. * * Results: * Returns zero on success, or a negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ int HgfsPrivateGetattr(struct dentry *dentry, // IN: Dentry containing name HgfsAttrInfo *attr, // OUT: Attr to copy into char **fileName) // OUT: pointer to allocated file name { HgfsReq *req; HgfsStatus replyStatus; HgfsOp opUsed; int result = 0; Bool allowHandleReuse = TRUE; ASSERT(dentry); ASSERT(dentry->d_sb); ASSERT(attr); req = HgfsGetNewRequest(); if (!req) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateGetattr: out of memory " "while getting new request\n")); result = -ENOMEM; goto out; } retry: opUsed = hgfsVersionGetattr; result = HgfsPackGetattrRequest(req, dentry, allowHandleReuse, opUsed, attr); if (result != 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateGetattr: no attrs\n")); goto out; } result = HgfsSendRequest(req); if (result == 0) { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsPrivateGetattr: got reply\n")); replyStatus = HgfsReplyStatus(req); result = HgfsStatusConvertToLinux(replyStatus); /* * If the getattr succeeded on the server, copy the stats * into the HgfsAttrInfo, otherwise return an error. */ switch (result) { case 0: result = HgfsUnpackGetattrReply(req, attr, fileName); break; case -EIO: /* * Fix for bug 548177. * When user deletes a share, we still show that share during directory * enumeration to minimize user's surprise. Now when we get getattr on * that share server returns EIO. Linux file manager doesn't like this, * and it doesn't display any valid shares too. So as a workaround, we * remap EIO to success and create minimal fake attributes. */ LOG(1, (KERN_DEBUG "Hgfs:Server returned EIO on unknown file\n")); /* Create fake attributes */ attr->mask = HGFS_ATTR_VALID_TYPE | HGFS_ATTR_VALID_SIZE; attr->type = HGFS_FILE_TYPE_DIRECTORY; attr->size = 0; result = 0; break; case -EBADF: /* * This can happen if we attempted a getattr by handle and the handle * was closed. Because we have no control over the backdoor, it's * possible that an attacker closed our handle, in which case the * driver still thinks the handle is open. So a straight-up * "goto retry" would cause an infinite loop. Instead, let's retry * with a getattr by name. */ if (allowHandleReuse) { allowHandleReuse = FALSE; goto retry; } /* * There's no reason why the server should have sent us this error * when we haven't used a handle. But to prevent an infinite loop in * the driver, let's make sure that we don't retry again. */ break; case -EPROTO: /* Retry with older version(s). Set globally. */ if (attr->requestType == HGFS_OP_GETATTR_V3) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateGetattr: Version 3 " "not supported. Falling back to version 2.\n")); hgfsVersionGetattr = HGFS_OP_GETATTR_V2; goto retry; } else if (attr->requestType == HGFS_OP_GETATTR_V2) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateGetattr: Version 2 " "not supported. Falling back to version 1.\n")); hgfsVersionGetattr = HGFS_OP_GETATTR; goto retry; } /* Fallthrough. */ default: break; } } else if (result == -EIO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateGetattr: timed out\n")); } else if (result == -EPROTO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateGetattr: server " "returned error: %d\n", result)); } else { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateGetattr: unknown error: " "%d\n", result)); } out: HgfsFreeRequest(req); return result; } /* *----------------------------------------------------------------------------- * * HgfsIget -- * * Lookup or create an inode with the given attributes and remote filename. * * If an inode number of zero is specified, we'll extract an inode number * either from the attributes, or from calling iunique(). * * Results: * The inode on success * NULL on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ struct inode * HgfsIget(struct super_block *sb, // IN: Superblock of this fs ino_t ino, // IN: Inode number (optional) HgfsAttrInfo const *attr) // IN: Attributes to create with { HgfsInodeInfo *iinfo; struct inode *inode; Bool isFakeInodeNumber = FALSE; ASSERT(sb); ASSERT(attr); LOG(6, (KERN_DEBUG "VMware hgfs: HgfsIget: entered\n")); /* No inode number? Use what's in the attributes, or call iunique(). */ if (ino == 0) { /* * Let's find out if the inode number the server gave us is already * in use. It's kind of lame that we have to do this, but that's what * we get when certain files have valid inode numbers and certain ones * don't. * * XXX: Is this worth the value? We're mixing server-provided inode * numbers with our own randomly chosen inode numbers. * * XXX: This logic is also racy. After our call to ilookup(), it's * possible another caller came in and grabbed that inode number, which * will cause us to collide in iget() and step on their inode. */ if (attr->mask & HGFS_ATTR_VALID_FILEID) { struct inode *oldInode; oldInode = ilookup(sb, attr->hostFileId); if (oldInode) { /* * If this inode's inode number was generated via iunique(), we * have a collision and cannot use the server's inode number. * Or, if the dentry is for a directory, we should not reuse the * inode in case there are two directory dentries referring to the * same inode. Otherwise, we should reuse this inode. * * Be careful of the following setting when resuing inodes: * host dir -> share name * C:/parent/ -> host1 * C:/parent/child/ -> host2 * /mnt/hgfs/host1/child and /mnt/hgfs/host2 are actually the * same directory in host. It also happens to the files in child. * Here, we should prevent the inode reusing because in Linux kernel * no inode can be pointed to by multiple directory entries; whereas * it is OK to do that for the files in /mnt/hgfs/child/. */ iinfo = INODE_GET_II_P(oldInode); if (iinfo->isFakeInodeNumber || attr->type == HGFS_FILE_TYPE_DIRECTORY) { LOG(6, ("VMware hgfs: %s: found existing iuniqued inode or " "directory inode %"FMT64"d, generating new one\n", __func__, attr->hostFileId)); ino = iunique(sb, HGFS_RESERVED_INO); isFakeInodeNumber = TRUE; } else { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsIget: found existing " "inode %"FMT64"d, reusing\n", attr->hostFileId)); ino = attr->hostFileId; } iput(oldInode); } else { ino = attr->hostFileId; } } else { /* * Get the next available inode number. There is a bit of a problem * with using iunique() in cases where HgfsIget was called to * instantiate an inode that's already in memory to a new dentry. In * such cases, we would like to get the old inode. But if we're * generating inode numbers with iunique(), we'll always have a new * inode number, thus we'll never get the old inode. This is * especially unfortunate when the old inode has some cached pages * attached to it that we won't be able to reuse. * * To mitigate this problem, whenever we use iunique() to generate an * inode number, we keep track of that fact in the inode. Then, when * we use ilookup() above to retrieve an inode, we only consider the * result a "collision" if the retrieved inode's inode number was set * via iunique(). Otherwise, we assume that we're reusing an inode * whose inode number was given to us by the server. */ ino = iunique(sb, HGFS_RESERVED_INO); isFakeInodeNumber = TRUE; } } LOG(6, (KERN_DEBUG "VMware hgfs: HgfsIget: calling iget on inode number " "%lu\n", ino)); /* Now we have a good inode number, get the inode itself. */ inode = HgfsGetInode(sb, ino); if (inode) { /* * On an allocation failure in read_super, the inode will have been * marked "bad". If it was, we certainly don't want to start playing with * the HgfsInodeInfo. So quietly put the inode back and fail. */ if (is_bad_inode(inode)) { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsIget: encountered bad inode\n")); iput(inode); return NULL; } iinfo = INODE_GET_II_P(inode); if (attr->mask & HGFS_ATTR_VALID_FILEID) { iinfo->hostFileId = attr->hostFileId; } iinfo->isFakeInodeNumber = isFakeInodeNumber; iinfo->isReferencedInode = TRUE; HgfsChangeFileAttributes(inode, attr); } LOG(6, (KERN_DEBUG "VMware hgfs: HgfsIget: done\n")); return inode; } /* *----------------------------------------------------------------------------- * * HgfsInstantiate -- * * Tie a dentry to a looked up or created inode. Callers may choose to * supply their own attributes, or may leave attr NULL in which case the * attributes will be queried from the server. Likewise, an inode number * of zero may be specified, in which case HgfsIget will get one from the * server or, barring that, from iunique(). * * Results: * Zero on success, negative error otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int HgfsInstantiate(struct dentry *dentry, // IN: Dentry to use ino_t ino, // IN: Inode number (optional) HgfsAttrInfo const *attr) // IN: Attributes to use (optional) { struct inode *inode; HgfsAttrInfo newAttr; ASSERT(dentry); LOG(8, (KERN_DEBUG "VMware hgfs: HgfsInstantiate: entered\n")); /* If no specified attributes, get them from the server. */ if (attr == NULL) { int error; LOG(6, (KERN_DEBUG "VMware hgfs: HgfsInstantiate: issuing getattr\n")); error = HgfsPrivateGetattr(dentry, &newAttr, NULL); if (error) { return error; } attr = &newAttr; } /* * Get the inode with this inode number and the attrs we got from * the server. */ inode = HgfsIget(dentry->d_sb, ino, attr); if (!inode) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsInstantiate: out of memory " "getting inode\n")); return -ENOMEM; } /* Everything worked out, instantiate the dentry. */ LOG(8, (KERN_DEBUG "VMware hgfs: HgfsInstantiate: instantiating dentry\n")); HgfsDentryAgeReset(dentry); dentry->d_op = &HgfsDentryOperations; d_instantiate(dentry, inode); return 0; } /* *----------------------------------------------------------------------------- * * HgfsBuildPath -- * * Constructs the full path given a dentry by walking the dentry and its * parents back to the root. Adapted from d_path(), smb_build_path(), and * build_path_from_dentry() implementations in Linux 2.6.16. * * Results: * If non-negative, the length of the buffer written. * Otherwise, an error code. * * Side effects: * None * *----------------------------------------------------------------------------- */ int HgfsBuildPath(char *buffer, // IN/OUT: Buffer to write into size_t bufferLen, // IN: Size of buffer struct dentry *dentry) // IN: First dentry to walk { int retval = 0; size_t shortestNameLength; HgfsSuperInfo *si; ASSERT(buffer); ASSERT(dentry); ASSERT(dentry->d_sb); si = HGFS_SB_TO_COMMON(dentry->d_sb); /* * Buffer must hold at least the share name (which is already prefixed with * a forward slash), and nul. */ shortestNameLength = si->shareNameLen + 1; if (bufferLen < shortestNameLength) { return -ENAMETOOLONG; } memcpy(buffer, si->shareName, shortestNameLength); /* Short-circuit if we're at the root already. */ if (IS_ROOT(dentry)) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsBuildPath: Sending root \"%s\"\n", buffer)); return shortestNameLength; } /* Skip the share name, but overwrite our previous nul. */ buffer += shortestNameLength - 1; bufferLen -= shortestNameLength - 1; /* * Build the path string walking the tree backward from end to ROOT * and store it in reversed order. */ dget(dentry); compat_lock_dentry(dentry); while (!IS_ROOT(dentry)) { struct dentry *parent; size_t nameLen; nameLen = dentry->d_name.len; bufferLen -= nameLen + 1; if (bufferLen < 0) { compat_unlock_dentry(dentry); dput(dentry); LOG(4, (KERN_DEBUG "VMware hgfs: HgfsBuildPath: Ran out of space " "while writing dentry name\n")); return -ENAMETOOLONG; } buffer[bufferLen] = '/'; memcpy(buffer + bufferLen + 1, dentry->d_name.name, nameLen); retval += nameLen + 1; parent = dentry->d_parent; dget(parent); compat_unlock_dentry(dentry); dput(dentry); dentry = parent; compat_lock_dentry(dentry); } compat_unlock_dentry(dentry); dput(dentry); if (bufferLen == 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsBuildPath: Ran out of space while " "writing nul\n")); return -ENAMETOOLONG; } /* Shift the constructed string down to just past the share name. */ memmove(buffer, buffer + bufferLen, retval); buffer[retval] = '\0'; /* Don't forget the share name length (which also accounts for the nul). */ retval += shortestNameLength; LOG(4, (KERN_DEBUG "VMware hgfs: HgfsBuildPath: Built \"%s\"\n", buffer)); return retval; } /* *----------------------------------------------------------------------------- * * HgfsDentryAgeReset -- * * Reset the age of this dentry by setting d_time to now. * * XXX: smb_renew_times from smbfs claims it is safe to reset the time of * all the parent dentries too, but how is that possible? If I stat a file * using a relative path, only that relative path will be validated. Sure, * it means that the parents still /exist/, but that doesn't mean their * attributes are up to date. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void HgfsDentryAgeReset(struct dentry *dentry) // IN: Dentry whose age to reset { ASSERT(dentry); LOG(8, (KERN_DEBUG "VMware hgfs: HgfsDentryAgeReset: entered\n")); dget(dentry); compat_lock_dentry(dentry); dentry->d_time = jiffies; compat_unlock_dentry(dentry); dput(dentry); } /* *----------------------------------------------------------------------------- * * HgfsDentryAgeReset -- * * Set the dentry's time to 0. This makes the dentry's age "too old" and * forces subsequent HgfsRevalidates to go to the server for attributes. * * Results: * None. * * Side effects: * Subsequent HgfsRevalidate will not use cached attributes. * *----------------------------------------------------------------------------- */ void HgfsDentryAgeForce(struct dentry *dentry) // IN: Dentry we want to force { ASSERT(dentry); LOG(8, (KERN_DEBUG "VMware hgfs: HgfsDentryAgeForce: entered\n")); dget(dentry); compat_lock_dentry(dentry); dentry->d_time = 0; compat_unlock_dentry(dentry); dput(dentry); } /* *---------------------------------------------------------------------- * * HgfsGetOpenMode -- * * Based on the flags requested by the process making the open() * syscall, determine which open mode (access type) to request from * the server. * * Results: * Returns the correct HgfsOpenMode enumeration to send to the * server, or -1 on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ int HgfsGetOpenMode(uint32 flags) // IN: Open flags { uint32 mask = O_RDONLY|O_WRONLY|O_RDWR; int result = -1; LOG(6, (KERN_DEBUG "VMware hgfs: HgfsGetOpenMode: entered\n")); /* * Mask the flags to only look at the access type. */ flags &= mask; /* Pick the correct HgfsOpenMode. */ switch (flags) { case O_RDONLY: result = HGFS_OPEN_MODE_READ_ONLY; break; case O_WRONLY: result = HGFS_OPEN_MODE_WRITE_ONLY; break; case O_RDWR: result = HGFS_OPEN_MODE_READ_WRITE; break; default: /* * This should never happen, but it could if a userlevel program * is behaving poorly. */ LOG(4, (KERN_DEBUG "VMware hgfs: HgfsGetOpenMode: invalid " "open flags %o\n", flags)); result = -1; break; } return result; } /* *----------------------------------------------------------------------------- * * HgfsCreateFileInfo -- * * Create the HGFS-specific file information struct and store a pointer to * it in the VFS file pointer. Also, link the file information struct in the * inode's file list, so that we may find it when all we have is an inode * (such as in writepage()). * * Results: * Zero if success, non-zero if error. * * Side effects: * None * *----------------------------------------------------------------------------- */ int HgfsCreateFileInfo(struct file *file, // IN: File pointer to attach to HgfsHandle handle) // IN: Handle returned from server { HgfsFileInfo *fileInfo; HgfsInodeInfo *inodeInfo; int mode; ASSERT(file); inodeInfo = INODE_GET_II_P(file->f_dentry->d_inode); ASSERT(inodeInfo); /* Get the mode of the opened file. */ mode = HgfsGetOpenMode(file->f_flags); if (mode < 0) { return -EINVAL; } /* * Store the file information for this open() in the file*. This needs * to be freed on a close(). Note that we trim all flags from the open * mode and increment it so that it is guaranteed to be non-zero, because * callers of HgfsGetHandle may pass in zero as the desired mode if they * don't care about the mode of the opened handle. * * XXX: Move this into a slab allocator once HgfsFileInfo is large. One day * soon, the kernel will allow us to embed the vfs file into our file info, * like we currently do for inodes. */ fileInfo = kmalloc(sizeof *fileInfo, GFP_KERNEL); if (!fileInfo) { return -ENOMEM; } fileInfo->handle = handle; fileInfo->mode = HGFS_OPEN_MODE_ACCMODE(mode) + 1; FILE_SET_FI_P(file, fileInfo); /* So that readdir() reissues open request */ fileInfo->isStale = TRUE; /* * I don't think we need any VFS locks since we're only touching the HGFS * specific state. But we should still acquire our own lock. * * XXX: Better granularity on locks, etc. */ spin_lock(&hgfsBigLock); list_add_tail(&fileInfo->list, &inodeInfo->files); spin_unlock(&hgfsBigLock); return 0; } /* *----------------------------------------------------------------------------- * * HgfsReleaseFileInfo -- * * Release HGFS-specific file information struct created in * HgfsCreateFileInfo. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsReleaseFileInfo(struct file *file) // IN: File pointer to detach from { HgfsFileInfo *fileInfo; ASSERT(file); fileInfo = FILE_GET_FI_P(file); ASSERT(fileInfo); spin_lock(&hgfsBigLock); list_del_init(&fileInfo->list); spin_unlock(&hgfsBigLock); kfree(fileInfo); FILE_SET_FI_P(file, NULL); } /* *----------------------------------------------------------------------------- * * HgfsGetHandle -- * * Retrieve an existing HGFS handle for this inode, assuming one exists. * The handle retrieved satisfies the mode desired by the client. * * The desired mode does not correspond directly to HgfsOpenMode. Callers * should either increment the desired HgfsOpenMode, or, if any mode will * do, pass zero instead. This is in line with the Linux kernel's behavior * (see do_filp_open() and open_namei() for details). * * Results: * Zero on success, non-zero on error. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int HgfsGetHandle(struct inode *inode, // IN: Inode to search for handles HgfsOpenMode mode, // IN: Mode to satisfy HgfsHandle *handle) // OUT: Retrieved HGFS handle { HgfsInodeInfo *iinfo; struct list_head *cur; Bool found = FALSE; ASSERT(handle); LOG(6, (KERN_DEBUG "VMware hgfs: HgfsGetHandle: desired mode %u\n", mode)); /* * We may have been called from a dentry without an associated inode. * HgfsReadSuper is one such caller. No inode means no open files, so * return an error. */ if (inode == NULL) { LOG(8, (KERN_DEBUG "VMware hgfs: HgfsGetHandle: NULL input\n")); return -EINVAL; } iinfo = INODE_GET_II_P(inode); /* * Unfortunately, we can't reuse handles belonging to directories. These * handles were created by a SearchOpen request, but the server itself * backed them with an artificial list of dentries populated via scandir. So * it can't actually use the handles for Getattr or Setattr requests, only * for subsequent SearchRead or SearchClose requests. */ if (S_ISDIR(inode->i_mode)) { LOG(8, (KERN_DEBUG "VMware hgfs: HgfsGetHandle: Called on directory\n")); return -EINVAL; } /* * Iterate over the open handles for this inode, and find one that allows * the given mode. A desired mode of zero means "any mode will do". * Otherwise return an error; */ spin_lock(&hgfsBigLock); list_for_each(cur, &iinfo->files) { HgfsFileInfo *finfo = list_entry(cur, HgfsFileInfo, list); if (mode == 0 || finfo->mode & mode) { *handle = finfo->handle; found = TRUE; break; } } spin_unlock(&hgfsBigLock); if (found) { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsGetHandle: Returning handle %d\n", *handle)); return 0; } else { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsGetHandle: Could not find matching " "handle\n")); return -ENOENT; } } /* *----------------------------------------------------------------------------- * * HgfsStatusConvertToLinux -- * * Convert a cross-platform HGFS status code to its Linux-kernel specific * counterpart. * * Rather than encapsulate the status codes within an array indexed by the * various HGFS status codes, we explicitly enumerate them in a switch * statement, saving the reader some time when matching HGFS status codes * against Linux status codes. * * Results: * Zero if the converted status code represents success, negative error * otherwise. Unknown status codes are converted to the more generic * "protocol error" status code to maintain forwards compatibility. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int HgfsStatusConvertToLinux(HgfsStatus hgfsStatus) // IN: Status code to convert { switch (hgfsStatus) { case HGFS_STATUS_SUCCESS: return 0; case HGFS_STATUS_NO_SUCH_FILE_OR_DIR: case HGFS_STATUS_INVALID_NAME: return -ENOENT; case HGFS_STATUS_INVALID_HANDLE: return -EBADF; case HGFS_STATUS_OPERATION_NOT_PERMITTED: return -EPERM; case HGFS_STATUS_FILE_EXISTS: return -EEXIST; case HGFS_STATUS_NOT_DIRECTORY: return -ENOTDIR; case HGFS_STATUS_DIR_NOT_EMPTY: return -ENOTEMPTY; case HGFS_STATUS_PROTOCOL_ERROR: return -EPROTO; case HGFS_STATUS_ACCESS_DENIED: case HGFS_STATUS_SHARING_VIOLATION: return -EACCES; case HGFS_STATUS_NO_SPACE: return -ENOSPC; case HGFS_STATUS_OPERATION_NOT_SUPPORTED: return -EOPNOTSUPP; case HGFS_STATUS_NAME_TOO_LONG: return -ENAMETOOLONG; case HGFS_STATUS_GENERIC_ERROR: return -EIO; case HGFS_STATUS_NOT_SAME_DEVICE: return -EXDEV; default: LOG(10, (KERN_DEBUG "VMware hgfs: HgfsStatusConvertToLinux: unknown " "error: %u\n", hgfsStatus)); return -EIO; } } /* *---------------------------------------------------------------------------- * * HgfsSetUidGid -- * * Sets the uid and gid of the host file represented by the provided * dentry. * * Note that this function assumes it is being called for a file that has * been created on the host with the correct gid if the sgid bit is set for * the parent directory. That is, we treat the presence of the sgid bit in * the parent direcory's mode as an indication not to set the gid manually * ourselves here. If we did, we would clobber the gid that the host file * system chose for us automatically when the file was created. * * Also note that the sgid bit itself would have been propagated to the new * file by the host file system as well. * * Results: * None. * * Side effects: * The host file's uid and gid are modified if the hgfs server has * permission to do so. * *---------------------------------------------------------------------------- */ void HgfsSetUidGid(struct inode *parent, // IN: parent inode struct dentry *dentry, // IN: dentry of file to update uid_t uid, // IN: uid to set gid_t gid) // IN: gid to set { struct iattr setUidGid; setUidGid.ia_valid = ATTR_UID; setUidGid.ia_uid = uid; /* * Only set the gid if the host file system wouldn't have for us. See the * comment in the function header. */ if (!parent || !(parent->i_mode & S_ISGID)) { setUidGid.ia_valid |= ATTR_GID; setUidGid.ia_gid = gid; } /* * After the setattr, we desperately want a revalidate so we can * get the true attributes from the server. However, the setattr * may have done that for us. To prevent a spurious revalidate, * reset the dentry's time before the setattr. That way, if setattr * ends up revalidating the dentry, the subsequent call to * revalidate will do nothing. */ HgfsDentryAgeForce(dentry); HgfsSetattr(dentry, &setUidGid); HgfsRevalidate(dentry); } /* *---------------------------------------------------------------------------- * * HgfsGetInode -- * * This function replaces iget() and should be called instead of it. * HgfsGetInode() obtains an inode and, if it is a new one, initializes * it calling HgfsDoReadInode(). * * Results: * A new inode object on success, NULL on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ struct inode * HgfsGetInode(struct super_block *sb, // IN: file system superblock object ino_t ino) // IN: inode number to assign to new inode { struct inode *inode; inode = iget_locked(sb, ino); if (inode && (inode->i_state & I_NEW)) { HgfsDoReadInode(inode); unlock_new_inode(inode); } return inode; } /* *---------------------------------------------------------------------------- * * HgfsDoReadInode -- * * A filesystem wide function that is called to initialize a new inode. * This is called from two different places depending on the kernel version. * In older kernels that provide the iget() interface, this function is * called by the kernel as part of inode initialization (from * HgfsDoReadInode). In newer kernels that call iget_locked(), this * function is called by filesystem code to initialize the new inode. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsDoReadInode(struct inode *inode) // IN: Inode to initialize { HgfsInodeInfo *iinfo = INODE_GET_II_P(inode); /* * If the vfs inode is not embedded within the HgfsInodeInfo, then we * haven't yet allocated the HgfsInodeInfo. Do so now. * * XXX: We could allocate with GFP_ATOMIC. But instead, we'll do a standard * allocation and mark the inode "bad" if the allocation fails. This'll * make all subsequent operations on the inode fail, which is what we want. */ INODE_SET_II_P(inode, iinfo); INIT_LIST_HEAD(&iinfo->files); iinfo->hostFileId = 0; iinfo->isReferencedInode = FALSE; iinfo->isFakeInodeNumber = FALSE; iinfo->createdAndUnopened = FALSE; } open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/super.c0000644765153500003110000002540312220061556021046 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * super.c -- * * Superblock operations for the filesystem portion of the vmhgfs driver. */ /* Must come before any kernel header file. */ #include "driver-config.h" #include #include "compat_fs.h" #include "compat_statfs.h" #include "compat_kernel.h" #include "compat_slab.h" #include "compat_sched.h" #include "compat_version.h" #include "hgfsProto.h" #include "escBitvector.h" #include "cpName.h" #include "hgfsUtil.h" #include "request.h" #include "fsutil.h" #include "hgfsDevLinux.h" #include "module.h" #include "vm_assert.h" /* Hgfs filesystem superblock operations */ static struct inode *HgfsAllocInode(struct super_block *sb); static void HgfsDestroyInode(struct inode *inode); static void HgfsPutSuper(struct super_block *sb); #if defined VMW_STATFS_2618 static int HgfsStatfs(struct dentry *dentry, struct compat_kstatfs *stat); #else static int HgfsStatfs(struct super_block *sb, struct compat_kstatfs *stat); #endif struct super_operations HgfsSuperOperations = { .alloc_inode = HgfsAllocInode, .destroy_inode = HgfsDestroyInode, .put_super = HgfsPutSuper, .statfs = HgfsStatfs, }; /* *----------------------------------------------------------------------------- * * HgfsAllocInode -- * * Hgfs superblock 'alloc_inode' method. Called by the kernel to allocate * a new inode struct. We use this VFS method instead of read_inode because * we want to control both how we allocate and how we fill in the inode. * * Results: * Non-null: A valid inode. * null: Error in inode allocation. * * Side effects: * Allocates memory. * *----------------------------------------------------------------------------- */ static struct inode * HgfsAllocInode(struct super_block *sb) // IN: Superblock for the inode { HgfsInodeInfo *iinfo; iinfo = kmem_cache_alloc(hgfsInodeCache, GFP_KERNEL); if (!iinfo) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsAllocInode: " "can't allocate memory\n")); return NULL; } return &iinfo->inode; } /* *----------------------------------------------------------------------------- * * HgfsDestroyInode -- * * Hgfs superblock 'destroy_inode' method. Called by the kernel when it * deallocates an inode. We use this method instead of clear_inode because * we want to control both how we deallocate and how we clear the inode. * * Results: * None * * Side effects: * Frees memory associated with inode. * *----------------------------------------------------------------------------- */ static void HgfsDestroyInode(struct inode *inode) // IN: The VFS inode { kmem_cache_free(hgfsInodeCache, INODE_GET_II_P(inode)); } /* *----------------------------------------------------------------------------- * * HgfsPutSuper -- * * Hgfs superblock 'put_super' method. Called after a umount(2) of the * filesystem succeeds. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsPutSuper(struct super_block *sb) // IN: The superblock { HgfsSuperInfo *si; ASSERT(sb); LOG(6, (KERN_DEBUG "VMware hgfs: HgfsPutSuper: was called\n")); si = HGFS_SB_TO_COMMON(sb); kfree(si->shareName); kfree(si); } /* *---------------------------------------------------------------------- * * HgfsPackQueryVolumeRequest -- * * Setup the query volume request, depending on the op version. * * Results: * Returns zero on success, or negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsPackQueryVolumeRequest(struct dentry *dentry, // IN: File pointer for this open HgfsOp opUsed, // IN: Op to be used. HgfsReq *req) // IN/OUT: Packet to write into { char *name; uint32 *nameLength; size_t requestSize; int result; ASSERT(dentry); ASSERT(req); switch (opUsed) { case HGFS_OP_QUERY_VOLUME_INFO_V3: { HgfsRequest *requestHeader; HgfsRequestQueryVolumeV3 *requestV3; requestHeader = (HgfsRequest *)(HGFS_REQ_PAYLOAD(req)); requestHeader->op = opUsed; requestHeader->id = req->id; requestV3 = (HgfsRequestQueryVolumeV3 *)HGFS_REQ_PAYLOAD_V3(req); /* We'll use these later. */ name = requestV3->fileName.name; nameLength = &requestV3->fileName.length; requestV3->fileName.flags = 0; requestV3->fileName.fid = HGFS_INVALID_HANDLE; requestV3->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; requestV3->reserved = 0; requestSize = HGFS_REQ_PAYLOAD_SIZE_V3(requestV3); break; } case HGFS_OP_QUERY_VOLUME_INFO: { HgfsRequestQueryVolume *request; request = (HgfsRequestQueryVolume *)(HGFS_REQ_PAYLOAD(req)); request->header.op = opUsed; request->header.id = req->id; /* We'll use these later. */ name = request->fileName.name; nameLength = &request->fileName.length; requestSize = sizeof *request; break; } default: LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackQueryVolumeRequest: unexpected " "OP type encountered\n")); return -EPROTO; } /* Build full name to send to server. */ if (HgfsBuildPath(name, req->bufferSize - (requestSize - 1), dentry) < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackQueryVolumeRequest: build path failed\n")); return -EINVAL; } LOG(6, (KERN_DEBUG "VMware hgfs: HgfsPackQueryVolumeRequest: opening \"%s\"\n", name)); /* Convert to CP name. */ result = CPName_ConvertTo(name, req->bufferSize - (requestSize - 1), name); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackQueryVolumeRequest: CP conversion failed\n")); return -EINVAL; } *nameLength = (uint32) result; req->payloadSize = requestSize + result; return 0; } /* *----------------------------------------------------------------------------- * * HgfsStatfs -- * * Hgfs superblock 'statfs' method. Called when statfs(2) is invoked on the * filesystem. * * Results: * 0 on success * error < 0 on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ #if defined VMW_STATFS_2618 static int HgfsStatfs(struct dentry *dentry, // IN : The directory entry struct compat_kstatfs *stat) // OUT: Stat to fill in #else static int HgfsStatfs(struct super_block *sb, // IN : The superblock struct compat_kstatfs *stat) // OUT: Stat to fill in #endif { HgfsReq *req; int result = 0; struct dentry *dentryToUse; struct super_block *sbToUse; HgfsOp opUsed; HgfsStatus replyStatus; uint64 freeBytes; uint64 totalBytes; ASSERT(stat); #if defined VMW_STATFS_2618 ASSERT(dentry); ASSERT(dentry->d_sb); dentryToUse = dentry; sbToUse = dentry->d_sb; #else ASSERT(sb); ASSERT(sb->s_root); dentryToUse = sb->s_root; sbToUse = sb; #endif LOG(6, (KERN_DEBUG "VMware hgfs: HgfsStatfs: was called\n")); memset(stat, 0, sizeof *stat); req = HgfsGetNewRequest(); if (!req) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsStatfs: out of memory while " "getting new request\n")); result = -ENOMEM; goto out; } retry: opUsed = hgfsVersionQueryVolumeInfo; result = HgfsPackQueryVolumeRequest(dentryToUse, opUsed, req); if (result != 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsStatfs: error packing request\n")); goto out; } result = HgfsSendRequest(req); if (result == 0) { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsStatfs: got reply\n")); replyStatus = HgfsReplyStatus(req); result = HgfsStatusConvertToLinux(replyStatus); /* * If the statfs succeeded on the server, copy the stats * into the kstatfs struct, otherwise return an error. */ switch (result) { case 0: stat->f_type = HGFS_SUPER_MAGIC; stat->f_bsize = sbToUse->s_blocksize; stat->f_namelen = PATH_MAX; if (opUsed == HGFS_OP_QUERY_VOLUME_INFO_V3) { totalBytes = ((HgfsReplyQueryVolumeV3 *)HGFS_REP_PAYLOAD_V3(req))->totalBytes; freeBytes = ((HgfsReplyQueryVolumeV3 *)HGFS_REP_PAYLOAD_V3(req))->freeBytes; } else { totalBytes = ((HgfsReplyQueryVolume *)HGFS_REQ_PAYLOAD(req))->totalBytes; freeBytes = ((HgfsReplyQueryVolume *)HGFS_REQ_PAYLOAD(req))->freeBytes; } stat->f_blocks = totalBytes >> sbToUse->s_blocksize_bits; stat->f_bfree = freeBytes >> sbToUse->s_blocksize_bits; stat->f_bavail = stat->f_bfree; break; case -EPERM: /* * We're cheating! This will cause statfs will return success. * We're doing this because an old server will complain when it gets * a statfs on a per-share mount. Rather than have 'df' spit an * error, let's just return all zeroes. */ result = 0; break; case -EPROTO: /* Retry with older version(s). Set globally. */ if (opUsed == HGFS_OP_QUERY_VOLUME_INFO_V3) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsStatfs: Version 3 not " "supported. Falling back to version 1.\n")); hgfsVersionQueryVolumeInfo = HGFS_OP_QUERY_VOLUME_INFO; goto retry; } break; default: break; } } else if (result == -EIO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsStatfs: timed out\n")); } else if (result == -EPROTO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsStatfs: server returned error: " "%d\n", result)); } else { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsStatfs: unknown error: %d\n", result)); } out: HgfsFreeRequest(req); return result; } open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/vmhgfs_version.h0000644765153500003110000000222012220061556022744 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmhgfs_version.h -- * * Version definitions for the Linux vmhgfs driver. */ #ifndef _VMHGFS_VERSION_H_ #define _VMHGFS_VERSION_H_ #define VMHGFS_DRIVER_VERSION 1.4.1.1 #define VMHGFS_DRIVER_VERSION_COMMAS 1,4,1,1 #define VMHGFS_DRIVER_VERSION_STRING "1.4.1.1" #endif /* _VMHGFS_VERSION_H_ */ open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/request.h0000644765153500003110000001144112220061556021402 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * request.h -- * * Functions dealing with the creation, deletion, and sending of HGFS * requests are defined here. */ #ifndef _HGFS_DRIVER_REQUEST_H_ #define _HGFS_DRIVER_REQUEST_H_ /* Must come before any kernel header file. */ #include "driver-config.h" #include #include #include #include "compat_sched.h" #include "compat_spinlock.h" #include "hgfs.h" /* For common HGFS definitions. */ #include "hgfsTransport.h" #include "vm_basic_types.h" /* Macros for accessing the payload portion of the HGFS request packet. */ #define HGFS_REQ_PAYLOAD(hgfsReq) ((hgfsReq)->payload) /* XXX: Needs change when VMCI is supported. */ #define HGFS_REQ_PAYLOAD_V3(hgfsReq) (HGFS_REQ_PAYLOAD(hgfsReq) + sizeof(HgfsRequest)) #define HGFS_REP_PAYLOAD_V3(hgfsRep) (HGFS_REQ_PAYLOAD(hgfsRep) + sizeof(HgfsReply)) /* * HGFS_REQ_STATE_ALLOCATED: * The filesystem half has allocated the request from the slab * allocator. The request is not on any list. * * HGFS_REQ_STATE_UNSENT: * The filesystem half of the driver has filled in the request fields * and placed the request in the global unsent list. It is now the * request handler's responsibility to submit this request to * the channel. Requests in this state are on the global unsent list. * * HGFS_REQ_STATE_SUBMITTED: * The packet has been sent, but the reply will arrive asynchronously. * The request will be on the hgfsRepPending list, and whenever * the reply arrives, the reply handler will remove the request from * the hgfsRepPending list and stuff the reply into the request's * packet buffer. * * This is only for asynchronous channel communication. * * HGFS_REQ_STATE_COMPLETED: * The request handler sent the request and received a reply. The reply * is stuffed in the request's packet buffer. Requests in this state * are not on any list. */ typedef enum { HGFS_REQ_STATE_ALLOCATED, HGFS_REQ_STATE_UNSENT, HGFS_REQ_STATE_SUBMITTED, HGFS_REQ_STATE_COMPLETED, /* Both header and payload were received. */ } HgfsState; /* * Each page that is sent from guest to host is described in the following * format. */ typedef struct HgfsDataPacket { struct page *page; uint32 offset; uint32 len; } HgfsDataPacket; /* * A request to be sent to the user process. */ typedef struct HgfsReq { /* Reference count */ struct kref kref; /* Links to place the object on various lists. */ struct list_head list; /* ID of the transport (its address) */ void *transportId; /* * When clients wait for the reply to a request, they'll wait on this * wait queue. */ wait_queue_head_t queue; /* Current state of the request. */ HgfsState state; /* ID of this request */ uint32 id; /* Pointer to payload in the buffer */ void *payload; /* Total size of the payload.*/ size_t payloadSize; /* * Size of the data buffer (below), not including size of chunk * used by transport. Must be enough to hold both request and * reply (but not at the same time). Initialized in channels. */ size_t bufferSize; /* * Used by read and write calls. Hgfs client passes in * pages to the vmci channel using datapackets and vmci channel * uses it to pass PA's to the host. */ HgfsDataPacket *dataPacket; /* Number of entries in data packet */ uint32 numEntries; /* * Packet of data, for both incoming and outgoing messages. * Include room for the command. */ unsigned char buffer[]; } HgfsReq; /* Public functions (with respect to the entire module). */ HgfsReq *HgfsGetNewRequest(void); HgfsReq *HgfsCopyRequest(HgfsReq *req); int HgfsSendRequest(HgfsReq *req); HgfsReq *HgfsRequestGetRef(HgfsReq *req); void HgfsRequestPutRef(HgfsReq *req); #define HgfsFreeRequest(req) HgfsRequestPutRef(req) HgfsStatus HgfsReplyStatus(HgfsReq *req); void HgfsCompleteReq(HgfsReq *req); void HgfsFailReq(HgfsReq *req, int error); #endif // _HGFS_DRIVER_REQUEST_H_ open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/COPYING0000644765153500003110000004310312220061556020574 0ustar dtormts GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/dentry.c0000644765153500003110000000644412220061556021221 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * dentry.c -- * * Dentry operations for the filesystem portion of the vmhgfs driver. */ /* Must come before any kernel header file. */ #include "driver-config.h" #include "compat_fs.h" #include "compat_kernel.h" #include "compat_namei.h" #include "compat_version.h" #include "inode.h" #include "module.h" #include "vm_assert.h" /* HGFS dentry operations. */ static int HgfsDentryRevalidate(struct dentry *dentry, #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) unsigned int flags #else struct nameidata *nd #endif ); /* HGFS dentry operations structure. */ struct dentry_operations HgfsDentryOperations = { .d_revalidate = HgfsDentryRevalidate, }; /* * HGFS dentry operations. */ /* *---------------------------------------------------------------------- * * HgfsDentryRevalidate -- * * Called by namei.c every time a dentry is looked up in the dcache * to determine if it is still valid. * * If the entry is found to be invalid, namei calls dput on it and * returns NULL, which causes a new lookup to be done in the actual * filesystem, which in our case means that HgfsLookup is called. * * Results: * Positive value if the entry IS valid. * Zero if the entry is NOT valid. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsDentryRevalidate(struct dentry *dentry, // IN: Dentry to revalidate #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) unsigned int flags // IN: Lookup flags & intent #else struct nameidata *nd // IN: Lookup flags & intent #endif ) { int error; LOG(6, (KERN_DEBUG "VMware hgfs: HgfsDentryRevalidate: calling " "HgfsRevalidate\n")); ASSERT(dentry); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) if (flags & LOOKUP_RCU) { return -ECHILD; } #elif defined(LOOKUP_RCU) /* Introduced in 2.6.38 */ if (nd && (nd->flags & LOOKUP_RCU)) { return -ECHILD; } #endif /* Just call HgfsRevaliate, which does the right thing. */ error = HgfsRevalidate(dentry); if (error) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDentryRevalidate: invalid\n")); if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) { shrink_dcache_parent(dentry); } d_drop(dentry); return 0; } LOG(6, (KERN_DEBUG "VMware hgfs: HgfsDentryRevalidate: valid\n")); return 1; } open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/transport.c0000644765153500003110000003352412220061556021747 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * transport.c -- * * This file handles the transport mechanisms available for HGFS. * This acts as a glue between the HGFS filesystem driver and the * actual transport channels (backdoor, tcp, vsock, ...). * * The sends happen in the process context, where as a kernel thread * handles the asynchronous replies. A queue of pending replies is * maintained and is protected by a spinlock. The channel opens and close * is protected by a mutex. */ /* Must come before any kernel header file. */ #include "driver-config.h" #include #include #include "compat_mutex.h" #include "compat_sched.h" #include "compat_spinlock.h" #include "compat_version.h" /* Must be included after semaphore.h. */ #include /* Must be included after sched.h. */ #include /* for spin_lock_bh */ #include "hgfsDevLinux.h" #include "hgfsProto.h" #include "module.h" #include "request.h" #include "transport.h" #include "vm_assert.h" extern int USE_VMCI; static HgfsTransportChannel *hgfsChannel; /* Current active channel. */ static compat_mutex_t hgfsChannelLock; /* Lock to protect hgfsChannel. */ static struct list_head hgfsRepPending; /* Reply pending queue. */ static spinlock_t hgfsRepQueueLock; /* Reply pending queue lock. */ /* *---------------------------------------------------------------------- * * HgfsTransportOpenChannel -- * * Opens given communication channel with HGFS server. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static Bool HgfsTransportOpenChannel(HgfsTransportChannel *channel) { Bool ret; switch (channel->status) { case HGFS_CHANNEL_UNINITIALIZED: case HGFS_CHANNEL_DEAD: ret = FALSE; break; case HGFS_CHANNEL_CONNECTED: ret = TRUE; break; case HGFS_CHANNEL_NOTCONNECTED: ret = channel->ops.open(channel); if (ret) { channel->status = HGFS_CHANNEL_CONNECTED; } break; default: ret = FALSE; ASSERT(0); /* Not reached. */ } return ret; } /* *---------------------------------------------------------------------- * * HgfsTransportCloseChannel -- * * Closes currently open communication channel. Has to be called * while holdingChannelLock. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ static void HgfsTransportCloseChannel(HgfsTransportChannel *channel) { if (channel->status == HGFS_CHANNEL_CONNECTED || channel->status == HGFS_CHANNEL_DEAD) { channel->ops.close(channel); channel->status = HGFS_CHANNEL_NOTCONNECTED; } } /* *---------------------------------------------------------------------- * * HgfsTransportSetupNewChannel -- * * Find a new workable channel. * * Results: * TRUE on success, otherwise FALSE. * * Side effects: * None * *---------------------------------------------------------------------- */ static Bool HgfsTransportSetupNewChannel(void) { HgfsTransportChannel *newChannel; newChannel = HgfsGetVmciChannel(); if (newChannel != NULL) { if (HgfsTransportOpenChannel(newChannel)) { hgfsChannel = newChannel; LOG(10, ("CHANNEL: Vmci channel\n")); return TRUE; } } USE_VMCI = 0; newChannel = HgfsGetVSocketChannel(); if (newChannel != NULL) { if (HgfsTransportOpenChannel(newChannel)) { hgfsChannel = newChannel; LOG(10, ("CHANNEL: Vsocket channel\n")); return TRUE; } } newChannel = HgfsGetTcpChannel(); if (newChannel != NULL) { if (HgfsTransportOpenChannel(newChannel)) { hgfsChannel = newChannel; LOG(10, ("CHANNEL: Tcp channel\n")); return TRUE; } } newChannel = HgfsGetBdChannel(); LOG(10, ("CHANNEL: Bd channel\n")); ASSERT(newChannel); hgfsChannel = newChannel; return HgfsTransportOpenChannel(newChannel); } /* *---------------------------------------------------------------------- * * HgfsTransporAddPendingRequest -- * * Adds a request to the hgfsRepPending queue. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ static void HgfsTransportAddPendingRequest(HgfsReq *req) // IN: Request to add { ASSERT(req); spin_lock_bh(&hgfsRepQueueLock); list_add_tail(&req->list, &hgfsRepPending); spin_unlock_bh(&hgfsRepQueueLock); } /* *---------------------------------------------------------------------- * * HgfsTransportRemovePendingRequest -- * * Dequeues the request from the hgfsRepPending queue. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ void HgfsTransportRemovePendingRequest(HgfsReq *req) // IN: Request to dequeue { ASSERT(req); spin_lock_bh(&hgfsRepQueueLock); list_del_init(&req->list); spin_unlock_bh(&hgfsRepQueueLock); } /* *---------------------------------------------------------------------- * * HgfsTransportFlushPendingRequests -- * * Complete all submitted requests with an error, called when * we are about to tear down communication channel. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ static void HgfsTransportFlushPendingRequests(void) { struct HgfsReq *req; spin_lock_bh(&hgfsRepQueueLock); list_for_each_entry(req, &hgfsRepPending, list) { if (req->state == HGFS_REQ_STATE_SUBMITTED) { LOG(6, ("VMware hgfs: %s: injecting error reply to req id: %d\n", __func__, req->id)); HgfsFailReq(req, -EIO); } } spin_unlock_bh(&hgfsRepQueueLock); } /* *---------------------------------------------------------------------- * * HgfsTransportGetPendingRequest -- * * Attempts to locate request with specified ID in the queue of * pending (waiting for server's reply) requests. * * Results: * NULL if request not found; otherwise address of the request * structure. * * Side effects: * Increments reference count of the request. * *---------------------------------------------------------------------- */ HgfsReq * HgfsTransportGetPendingRequest(HgfsHandle id) // IN: id of the request { HgfsReq *cur, *req = NULL; spin_lock_bh(&hgfsRepQueueLock); list_for_each_entry(cur, &hgfsRepPending, list) { if (cur->id == id) { ASSERT(cur->state == HGFS_REQ_STATE_SUBMITTED); req = HgfsRequestGetRef(cur); break; } } spin_unlock_bh(&hgfsRepQueueLock); return req; } /* *---------------------------------------------------------------------- * * HgfsTransportAllocateRequest -- * * Allocates HGFS request structre using channel-specific allocator. * * Results: * NULL on failure; otherwisepointer to newly allocated request. * * Side effects: * None * *---------------------------------------------------------------------- */ HgfsReq * HgfsTransportAllocateRequest(size_t bufferSize) // IN: size of the buffer { HgfsReq *req = NULL; /* * We use a temporary variable to make sure we stamp the request with * same channel as we used to make allocation since hgfsChannel can * be changed while we do allocation. */ HgfsTransportChannel *currentChannel = hgfsChannel; ASSERT(currentChannel); req = currentChannel->ops.allocate(bufferSize); if (req) { req->transportId = currentChannel; } return req; } /* *---------------------------------------------------------------------- * * HgfsTransportFreeRequest -- * * Free HGFS request structre using channel-specific free function. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void HgfsTransportFreeRequest(HgfsReq *req) // IN: size of the buffer { /* * We cannot use hgfsChannel structre because global channel could * changes in the meantime. We remember the channel when we do * allocation and call the same channel for de-allocation. Smart. */ HgfsTransportChannel *channel = (HgfsTransportChannel *)req->transportId; channel->ops.free(req); return; } /* *---------------------------------------------------------------------- * * HgfsTransportSendRequest -- * * Sends the request via channel communication. * * Results: * Zero on success, non-zero error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ int HgfsTransportSendRequest(HgfsReq *req) // IN: Request to send { HgfsReq *origReq = req; int ret = -EIO; ASSERT(req); ASSERT(req->state == HGFS_REQ_STATE_UNSENT); ASSERT(req->payloadSize <= req->bufferSize); compat_mutex_lock(&hgfsChannelLock); HgfsTransportAddPendingRequest(req); do { if (unlikely(hgfsChannel->status != HGFS_CHANNEL_CONNECTED)) { if (hgfsChannel->status == HGFS_CHANNEL_DEAD) { HgfsTransportCloseChannel(hgfsChannel); HgfsTransportFlushPendingRequests(); } if (!HgfsTransportSetupNewChannel()) { ret = -EIO; goto out; } } ASSERT(hgfsChannel->ops.send); /* If channel changed since we created request we need to adjust */ if (req->transportId != hgfsChannel) { HgfsTransportRemovePendingRequest(req); if (req != origReq) { HgfsRequestPutRef(req); } req = HgfsCopyRequest(origReq); if (req == NULL) { req = origReq; ret = -ENOMEM; goto out; } HgfsTransportAddPendingRequest(req); } ret = hgfsChannel->ops.send(hgfsChannel, req); if (likely(ret == 0)) break; LOG(4, (KERN_DEBUG "VMware hgfs: %s: send failed with error %d\n", __func__, ret)); if (ret == -EINTR) { /* Don't retry when we are interrupted by some signal. */ goto out; } hgfsChannel->status = HGFS_CHANNEL_DEAD; } while (1); ASSERT(req->state == HGFS_REQ_STATE_COMPLETED || req->state == HGFS_REQ_STATE_SUBMITTED); out: compat_mutex_unlock(&hgfsChannelLock); if (likely(ret == 0)) { /* * Send succeeded, wait for the reply. * Right now, we cannot cancel request once they * are dispatched to the host. */ wait_event(req->queue, req->state == HGFS_REQ_STATE_COMPLETED); } HgfsTransportRemovePendingRequest(req); /* * If we used a copy of request because we changed transport we * need to copy payload back into original request. */ if (req != origReq) { ASSERT(req->payloadSize <= origReq->bufferSize); origReq->payloadSize = req->payloadSize; memcpy(origReq->payload, req->payload, req->payloadSize); HgfsRequestPutRef(req); } return ret; } /* *---------------------------------------------------------------------- * * HgfsTransportInit -- * * Initialize the transport. * * Starts the reply thread, for handling incoming packets on the * connected socket. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ void HgfsTransportInit(void) { INIT_LIST_HEAD(&hgfsRepPending); spin_lock_init(&hgfsRepQueueLock); compat_mutex_init(&hgfsChannelLock); compat_mutex_lock(&hgfsChannelLock); hgfsChannel = HgfsGetBdChannel(); ASSERT(hgfsChannel); compat_mutex_unlock(&hgfsChannelLock); } /* *---------------------------------------------------------------------- * * HgfsTransportMarkDead -- * * Marks current channel as dead so it can be cleaned up and * fails all submitted requests. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ void HgfsTransportMarkDead(void) { LOG(8, ("VMware hgfs: %s entered.\n", __func__)); compat_mutex_lock(&hgfsChannelLock); if (hgfsChannel) { hgfsChannel->status = HGFS_CHANNEL_DEAD; } HgfsTransportFlushPendingRequests(); compat_mutex_unlock(&hgfsChannelLock); } /* *---------------------------------------------------------------------- * * HgfsTransportExit -- * * Teardown the transport. * * Results: * None * * Side effects: * Cleans up everything, frees queues, closes channel. * *---------------------------------------------------------------------- */ void HgfsTransportExit(void) { LOG(8, ("VMware hgfs: %s entered.\n", __func__)); compat_mutex_lock(&hgfsChannelLock); ASSERT(hgfsChannel); HgfsTransportCloseChannel(hgfsChannel); hgfsChannel = NULL; compat_mutex_unlock(&hgfsChannelLock); ASSERT(list_empty(&hgfsRepPending)); LOG(8, ("VMware hgfs: %s exited.\n", __func__)); } open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/Makefile0000644765153500003110000001053212220061556021201 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 1998 VMware, Inc. All rights reserved. # # 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 version 2 and no later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ########################################################## #### #### VMware kernel module Makefile to be distributed externally #### #### #### SRCROOT _must_ be a relative path. #### SRCROOT = . # # open-vm-tools doesn't replicate shared source files for different modules; # instead, files are kept in shared locations. So define a few useful macros # to be able to handle both cases cleanly. # INCLUDE := ifdef OVT_SOURCE_DIR AUTOCONF_DIR := $(OVT_SOURCE_DIR)/modules/linux/shared/autoconf VMLIB_PATH = $(OVT_SOURCE_DIR)/lib/$(1) INCLUDE += -I$(OVT_SOURCE_DIR)/modules/linux/shared INCLUDE += -I$(OVT_SOURCE_DIR)/lib/include else AUTOCONF_DIR := $(SRCROOT)/shared/autoconf INCLUDE += -I$(SRCROOT)/shared endif VM_UNAME = $(shell uname -r) # Header directory for the running kernel ifdef LINUXINCLUDE HEADER_DIR = $(LINUXINCLUDE) else HEADER_DIR = /lib/modules/$(VM_UNAME)/build/include endif BUILD_DIR = $(HEADER_DIR)/.. DRIVER := vmhgfs PRODUCT := tools # Grep program GREP = /bin/grep vm_check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null \ > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) vm_check_file = $(shell if test -f $(1); then echo "yes"; else echo "no"; fi) ifndef VM_KBUILD VM_KBUILD := no ifeq ($(call vm_check_file,$(BUILD_DIR)/Makefile), yes) ifneq ($(call vm_check_file,$(BUILD_DIR)/Rules.make), yes) VM_KBUILD := 26 endif endif export VM_KBUILD endif ifndef VM_KBUILD_SHOWN ifeq ($(VM_KBUILD), no) VM_DUMMY := $(shell echo >&2 "Using standalone build system.") else ifeq ($(VM_KBUILD), 24) VM_DUMMY := $(shell echo >&2 "Using 2.4.x kernel build system.") else VM_DUMMY := $(shell echo >&2 "Using 2.6.x kernel build system.") endif endif VM_KBUILD_SHOWN := yes export VM_KBUILD_SHOWN endif ifneq ($(VM_KBUILD), no) VMCCVER := $(shell $(CC) -dumpversion) # If there is no version defined, we are in toplevel pass, not yet in kernel makefiles... ifeq ($(VERSION),) ifeq ($(VM_KBUILD), 24) DRIVER_KO := $(DRIVER).o else DRIVER_KO := $(DRIVER).ko endif .PHONY: $(DRIVER_KO) auto-build: $(DRIVER_KO) cp -f $< $(SRCROOT)/../$(DRIVER).o # $(DRIVER_KO) is a phony target, so compare file times explicitly $(DRIVER): $(DRIVER_KO) if [ $< -nt $@ ] || [ ! -e $@ ] ; then cp -f $< $@; fi # Pass gcc version down the chain, so we can detect if kernel attempts to use unapproved compiler VM_CCVER := $(VMCCVER) export VM_CCVER VM_CC := $(CC) export VM_CC MAKEOVERRIDES := $(filter-out CC=%,$(MAKEOVERRIDES)) # # Define a setup target that gets built before the actual driver. # This target may not be used at all, but if it is then it will be defined # in Makefile.kernel # prebuild:: ; postbuild:: ; $(DRIVER_KO): prebuild $(MAKE) -C $(BUILD_DIR) SUBDIRS=$$PWD SRCROOT=$$PWD/$(SRCROOT) \ MODULEBUILDDIR=$(MODULEBUILDDIR) modules $(MAKE) -C $$PWD SRCROOT=$$PWD/$(SRCROOT) \ MODULEBUILDDIR=$(MODULEBUILDDIR) postbuild endif vm_check_build = $(shell if $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ $(CPPFLAGS) $(CFLAGS) $(CFLAGS_KERNEL) $(LINUXINCLUDE) \ $(EXTRA_CFLAGS) -Iinclude2/asm/mach-default \ -DKBUILD_BASENAME=\"$(DRIVER)\" \ -Werror -S -o /dev/null -xc $(1) \ > /dev/null 2>&1; then echo "$(2)"; else echo "$(3)"; fi) CC_WARNINGS := -Wall -Wstrict-prototypes CC_OPTS := $(GLOBAL_DEFS) $(CC_WARNINGS) -DVMW_USING_KBUILD ifdef VMX86_DEVEL CC_OPTS += -DVMX86_DEVEL endif ifdef VMX86_DEBUG CC_OPTS += -DVMX86_DEBUG endif include $(SRCROOT)/Makefile.kernel ifdef TOPDIR ifeq ($(VM_KBUILD), 24) O_TARGET := $(DRIVER).o obj-y := $($(DRIVER)-y) include $(TOPDIR)/Rules.make endif endif else include $(SRCROOT)/Makefile.normal endif #.SILENT: open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/file.c0000644765153500003110000011304212220061556020624 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * file.c -- * * File operations for the filesystem portion of the vmhgfs driver. */ /* Must come before any kernel header file. */ #include "driver-config.h" #include #include #include #include "compat_cred.h" #include "compat_fs.h" #include "compat_kernel.h" #include "compat_slab.h" /* Must be after compat_fs.h */ #if defined VMW_USE_AIO #include #endif #include "cpName.h" #include "hgfsProto.h" #include "module.h" #include "request.h" #include "hgfsUtil.h" #include "fsutil.h" #include "vm_assert.h" #include "vm_basic_types.h" /* Private functions. */ static int HgfsPackOpenRequest(struct inode *inode, struct file *file, HgfsOp opUsed, HgfsReq *req); static int HgfsUnpackOpenReply(HgfsReq *req, HgfsOp opUsed, HgfsHandle *file, HgfsServerLock *lock); static int HgfsGetOpenFlags(uint32 flags); /* HGFS file operations for files. */ static int HgfsOpen(struct inode *inode, struct file *file); #if defined VMW_USE_AIO static ssize_t HgfsAioRead(struct kiocb *iocb, const struct iovec *iov, unsigned long numSegs, loff_t offset); static ssize_t HgfsAioWrite(struct kiocb *iocb, const struct iovec *iov, unsigned long numSegs, loff_t offset); #else static ssize_t HgfsRead(struct file *file, char __user *buf, size_t count, loff_t *offset); static ssize_t HgfsWrite(struct file *file, const char __user *buf, size_t count, loff_t *offset); #endif static loff_t HgfsSeek(struct file *file, loff_t offset, int origin); static int HgfsFsync(struct file *file, #if defined VMW_FSYNC_OLD struct dentry *dentry, #elif defined VMW_FSYNC_31 loff_t start, loff_t end, #endif int datasync); static int HgfsMmap(struct file *file, struct vm_area_struct *vma); static int HgfsRelease(struct inode *inode, struct file *file); #ifndef VMW_SENDFILE_NONE #if defined VMW_SENDFILE_OLD static ssize_t HgfsSendfile(struct file *file, loff_t *offset, size_t count, read_actor_t actor, void __user *target); #else /* defined VMW_SENDFILE_NEW */ static ssize_t HgfsSendfile(struct file *file, loff_t *offset, size_t count, read_actor_t actor, void *target); #endif #endif #ifdef VMW_SPLICE_READ static ssize_t HgfsSpliceRead(struct file *file, loff_t *offset, struct pipe_inode_info *pipe, size_t len, unsigned int flags); #endif /* HGFS file operations structure for files. */ struct file_operations HgfsFileFileOperations = { .owner = THIS_MODULE, .open = HgfsOpen, .llseek = HgfsSeek, #if defined VMW_USE_AIO .aio_read = HgfsAioRead, .aio_write = HgfsAioWrite, #else .read = HgfsRead, .write = HgfsWrite, #endif .fsync = HgfsFsync, .mmap = HgfsMmap, .release = HgfsRelease, #ifndef VMW_SENDFILE_NONE .sendfile = HgfsSendfile, #endif #ifdef VMW_SPLICE_READ .splice_read = HgfsSpliceRead, #endif }; /* File open mask. */ #define HGFS_FILE_OPEN_MASK (HGFS_OPEN_VALID_MODE | \ HGFS_OPEN_VALID_FLAGS | \ HGFS_OPEN_VALID_SPECIAL_PERMS | \ HGFS_OPEN_VALID_OWNER_PERMS | \ HGFS_OPEN_VALID_GROUP_PERMS | \ HGFS_OPEN_VALID_OTHER_PERMS | \ HGFS_OPEN_VALID_FILE_NAME | \ HGFS_OPEN_VALID_SERVER_LOCK) /* * Private functions. */ /* *---------------------------------------------------------------------- * * HgfsPackOpenRequest -- * * Setup the Open request, depending on the op version. * * Results: * Returns zero on success, or negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsPackOpenRequest(struct inode *inode, // IN: Inode of the file to open struct file *file, // IN: File pointer for this open HgfsOp opUsed, // IN: Op to use HgfsReq *req) // IN/OUT: Packet to write into { char *name; uint32 *nameLength; size_t requestSize; int result; ASSERT(inode); ASSERT(file); ASSERT(req); switch (opUsed) { case HGFS_OP_OPEN_V3: { HgfsRequest *requestHeader; HgfsRequestOpenV3 *requestV3; requestHeader = (HgfsRequest *)HGFS_REQ_PAYLOAD(req); requestHeader->op = opUsed; requestHeader->id = req->id; requestV3 = (HgfsRequestOpenV3 *)HGFS_REQ_PAYLOAD_V3(req); requestSize = HGFS_REQ_PAYLOAD_SIZE_V3(requestV3); /* We'll use these later. */ name = requestV3->fileName.name; nameLength = &requestV3->fileName.length; requestV3->mask = HGFS_FILE_OPEN_MASK; /* Linux clients need case-sensitive lookups. */ requestV3->fileName.flags = 0; requestV3->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; requestV3->fileName.fid = HGFS_INVALID_HANDLE; /* Set mode. */ result = HgfsGetOpenMode(file->f_flags); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: failed to get " "open mode\n")); return -EINVAL; } requestV3->mode = result; /* Set flags. */ result = HgfsGetOpenFlags(file->f_flags); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: failed to get " "open flags\n")); return -EINVAL; } requestV3->flags = result; /* Set permissions. */ requestV3->specialPerms = (inode->i_mode & (S_ISUID | S_ISGID | S_ISVTX)) >> 9; requestV3->ownerPerms = (inode->i_mode & S_IRWXU) >> 6; requestV3->groupPerms = (inode->i_mode & S_IRWXG) >> 3; requestV3->otherPerms = (inode->i_mode & S_IRWXO); /* XXX: Request no lock for now. */ requestV3->desiredLock = HGFS_LOCK_NONE; requestV3->reserved1 = 0; requestV3->reserved2 = 0; break; } case HGFS_OP_OPEN_V2: { HgfsRequestOpenV2 *requestV2; requestV2 = (HgfsRequestOpenV2 *)(HGFS_REQ_PAYLOAD(req)); requestV2->header.op = opUsed; requestV2->header.id = req->id; /* We'll use these later. */ name = requestV2->fileName.name; nameLength = &requestV2->fileName.length; requestSize = sizeof *requestV2; requestV2->mask = HGFS_FILE_OPEN_MASK; /* Set mode. */ result = HgfsGetOpenMode(file->f_flags); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: failed to get " "open mode\n")); return -EINVAL; } requestV2->mode = result; /* Set flags. */ result = HgfsGetOpenFlags(file->f_flags); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: failed to get " "open flags\n")); return -EINVAL; } requestV2->flags = result; /* Set permissions. */ requestV2->specialPerms = (inode->i_mode & (S_ISUID | S_ISGID | S_ISVTX)) >> 9; requestV2->ownerPerms = (inode->i_mode & S_IRWXU) >> 6; requestV2->groupPerms = (inode->i_mode & S_IRWXG) >> 3; requestV2->otherPerms = (inode->i_mode & S_IRWXO); /* XXX: Request no lock for now. */ requestV2->desiredLock = HGFS_LOCK_NONE; break; } case HGFS_OP_OPEN: { HgfsRequestOpen *request; request = (HgfsRequestOpen *)(HGFS_REQ_PAYLOAD(req)); request->header.op = opUsed; request->header.id = req->id; /* We'll use these later. */ name = request->fileName.name; nameLength = &request->fileName.length; requestSize = sizeof *request; /* Set mode. */ result = HgfsGetOpenMode(file->f_flags); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: failed to get " "open mode\n")); return -EINVAL; } request->mode = result; /* Set flags. */ result = HgfsGetOpenFlags(file->f_flags); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: failed to get " "open flags\n")); return -EINVAL; } request->flags = result; /* Set permissions. */ request->permissions = (inode->i_mode & S_IRWXU) >> 6; break; } default: LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: unexpected " "OP type encountered\n")); return -EPROTO; } /* Build full name to send to server. */ if (HgfsBuildPath(name, req->bufferSize - (requestSize - 1), file->f_dentry) < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: build path " "failed\n")); return -EINVAL; } LOG(6, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: opening \"%s\", " "flags %o, create perms %o\n", name, file->f_flags, file->f_mode)); /* Convert to CP name. */ result = CPName_ConvertTo(name, req->bufferSize - (requestSize - 1), name); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: CP conversion " "failed\n")); return -EINVAL; } *nameLength = (uint32) result; req->payloadSize = requestSize + result; return 0; } /* *---------------------------------------------------------------------- * * HgfsUnpackOpenReply -- * * Get interesting fields out of the Open reply, depending on the op * version. * * Results: * Returns zero on success, or negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsUnpackOpenReply(HgfsReq *req, // IN: Packet with reply inside HgfsOp opUsed, // IN: What request op did we send HgfsHandle *file, // OUT: Handle in reply packet HgfsServerLock *lock) // OUT: The server lock we got { HgfsReplyOpenV3 *replyV3; HgfsReplyOpenV2 *replyV2; HgfsReplyOpen *replyV1; size_t replySize; ASSERT(req); ASSERT(file); ASSERT(lock); switch (opUsed) { case HGFS_OP_OPEN_V3: replyV3 = (HgfsReplyOpenV3 *)HGFS_REP_PAYLOAD_V3(req); replySize = HGFS_REP_PAYLOAD_SIZE_V3(replyV3); *file = replyV3->file; *lock = replyV3->acquiredLock; break; case HGFS_OP_OPEN_V2: replyV2 = (HgfsReplyOpenV2 *)(HGFS_REQ_PAYLOAD(req)); replySize = sizeof *replyV2; *file = replyV2->file; *lock = replyV2->acquiredLock; break; case HGFS_OP_OPEN: replyV1 = (HgfsReplyOpen *)(HGFS_REQ_PAYLOAD(req)); replySize = sizeof *replyV1; *file = replyV1->file; *lock = HGFS_LOCK_NONE; break; default: /* This really shouldn't happen since we set opUsed ourselves. */ LOG(4, (KERN_DEBUG "VMware hgfs: HgfsUnpackOpenReply: unexpected " "OP type encountered\n")); ASSERT(FALSE); return -EPROTO; } if (req->payloadSize != replySize) { /* * The reply to Open is a fixed size. So the size of the payload * really ought to match the expected size of an HgfsReplyOpen[V2]. */ LOG(4, (KERN_DEBUG "VMware hgfs: HgfsUnpackOpenReply: wrong packet " "size\n")); return -EPROTO; } return 0; } /* *---------------------------------------------------------------------- * * HgfsGetOpenFlags -- * * Based on the flags requested by the process making the open() * syscall, determine which flags to send to the server to open the * file. * * Results: * Returns the correct HgfsOpenFlags enumeration to send to the * server, or -1 on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsGetOpenFlags(uint32 flags) // IN: Open flags { uint32 mask = O_CREAT | O_TRUNC | O_EXCL; int result = -1; LOG(6, (KERN_DEBUG "VMware hgfs: HgfsGetOpenFlags: entered\n")); /* * Mask the flags to only look at O_CREAT, O_EXCL, and O_TRUNC. */ flags &= mask; /* O_EXCL has no meaning if O_CREAT is not set. */ if (!(flags & O_CREAT)) { flags &= ~O_EXCL; } /* Pick the right HgfsOpenFlags. */ switch (flags) { case 0: /* Regular open; fails if file nonexistant. */ result = HGFS_OPEN; break; case O_CREAT: /* Create file; if it exists already just open it. */ result = HGFS_OPEN_CREATE; break; case O_TRUNC: /* Truncate existing file; fails if nonexistant. */ result = HGFS_OPEN_EMPTY; break; case (O_CREAT | O_EXCL): /* Create file; fail if it exists already. */ result = HGFS_OPEN_CREATE_SAFE; break; case (O_CREAT | O_TRUNC): /* Create file; if it exists already, truncate it. */ result = HGFS_OPEN_CREATE_EMPTY; break; default: /* * This can only happen if all three flags are set, which * conceptually makes no sense because O_EXCL and O_TRUNC are * mutually exclusive if O_CREAT is set. * * However, the open(2) man page doesn't say you can't set all * three flags, and certain apps (*cough* Nautilus *cough*) do * so. To be friendly to those apps, we just silenty drop the * O_TRUNC flag on the assumption that it's safer to honor * O_EXCL. */ LOG(4, (KERN_DEBUG "VMware hgfs: HgfsGetOpenFlags: invalid open " "flags %o. Ignoring the O_TRUNC flag.\n", flags)); result = HGFS_OPEN_CREATE_SAFE; break; } return result; } /* * HGFS file operations for files. */ /* *---------------------------------------------------------------------- * * HgfsOpen -- * * Called whenever a process opens a file in our filesystem. * * We send an "Open" request to the server with the name stored in * this file's inode. If the Open succeeds, we store the filehandle * sent by the server in the file struct so it can be accessed by * read/write/close. * * Results: * Returns zero if on success, error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsOpen(struct inode *inode, // IN: Inode of the file to open struct file *file) // IN: File pointer for this open { HgfsReq *req; HgfsOp opUsed; HgfsStatus replyStatus; HgfsHandle replyFile; HgfsServerLock replyLock; HgfsInodeInfo *iinfo; int result = 0; ASSERT(inode); ASSERT(inode->i_sb); ASSERT(file); ASSERT(file->f_dentry); ASSERT(file->f_dentry->d_inode); iinfo = INODE_GET_II_P(inode); req = HgfsGetNewRequest(); if (!req) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsOpen: out of memory while " "getting new request\n")); result = -ENOMEM; goto out; } retry: /* * Set up pointers using the proper struct This lets us check the * version exactly once and use the pointers later. */ opUsed = hgfsVersionOpen; result = HgfsPackOpenRequest(inode, file, opUsed, req); if (result != 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsOpen: error packing request\n")); goto out; } /* Send the request and process the reply. */ result = HgfsSendRequest(req); if (result == 0) { /* Get the reply and check return status. */ replyStatus = HgfsReplyStatus(req); result = HgfsStatusConvertToLinux(replyStatus); switch (result) { case 0: iinfo->createdAndUnopened = FALSE; LOG(10, (KERN_DEBUG "VMware hgfs: HgfsOpen: old hostFileId = " "%"FMT64"u\n", iinfo->hostFileId)); /* * Invalidate the hostFileId as we need to retrieve it from * the server. */ iinfo->hostFileId = 0; result = HgfsUnpackOpenReply(req, opUsed, &replyFile, &replyLock); if (result != 0) { break; } result = HgfsCreateFileInfo(file, replyFile); if (result != 0) { break; } LOG(6, (KERN_DEBUG "VMware hgfs: HgfsOpen: set handle to %u\n", replyFile)); /* * HgfsCreate faked all of the inode's attributes, so by the time * we're done in HgfsOpen, we need to make sure that the attributes * in the inode are real. The following is only necessary when * O_CREAT is set, otherwise we got here after HgfsLookup (which sent * a getattr to the server and got the real attributes). * * In particular, we'd like to at least try and set the inode's * uid/gid to match the caller's. We don't expect this to work, * because Windows servers will ignore it, and Linux servers running * as non-root won't be able to change it, but we're forward thinking * people. * * Either way, we force a revalidate following the setattr so that * we'll get the actual uid/gid from the server. */ if (file->f_flags & O_CREAT) { struct dentry *dparent; struct inode *iparent; /* * This is not the root of our file system so there should always * be a parent. */ ASSERT(file->f_dentry->d_parent); /* * Here we obtain a reference on the parent to make sure it doesn't * go away. This might not be necessary, since the existence of * a child (which we hold a reference to in this call) should * account for a reference in the parent, but it's safe to do so. * Overly cautious and safe is better than risky and broken. * * XXX Note that this and a handful of other hacks wouldn't be * necessary if we actually created the file in our create * implementation (where references and locks are properly held). * We could do this if we were willing to give up support for * O_EXCL on 2.4 kernels. */ dparent = dget(file->f_dentry->d_parent); iparent = dparent->d_inode; HgfsSetUidGid(iparent, file->f_dentry, current_fsuid(), current_fsgid()); dput(dparent); } break; case -EPROTO: /* Retry with older version(s). Set globally. */ if (opUsed == HGFS_OP_OPEN_V3) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsOpen: Version 3 not " "supported. Falling back to version 2.\n")); hgfsVersionOpen = HGFS_OP_OPEN_V2; goto retry; } /* Retry with Version 1 of Open. Set globally. */ if (opUsed == HGFS_OP_OPEN_V2) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsOpen: Version 2 not " "supported. Falling back to version 1.\n")); hgfsVersionOpen = HGFS_OP_OPEN; goto retry; } /* Fallthrough. */ default: break; } } else if (result == -EIO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsOpen: timed out\n")); } else if (result == -EPROTO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsOpen: server " "returned error: %d\n", result)); } else { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsOpen: unknown error: " "%d\n", result)); } out: HgfsFreeRequest(req); /* * If the open failed (for any reason) and we tried to open a newly created * file, we must ensure that the next operation on this inode triggers a * revalidate to the server. This is because the file wasn't created on the * server, yet we currently believe that it was, because we created a fake * inode with a hashed dentry for it in HgfsCreate. We will continue to * believe this until the dentry's ttl expires, which will cause a * revalidate to the server that will reveal the truth. So in order to find * the truth as soon as possible, we'll reset the dentry's last revalidate * time now to force a revalidate the next time someone uses the dentry. * * We're using our own flag to track this case because using O_CREAT isn't * good enough: HgfsOpen will be called with O_CREAT even if the file exists * on the server, and if that's the case, there's no need to revalidate. * * XXX: Note that this will need to be reworked if/when we support hard * links, because multiple dentries will point to the same inode, and * forcing a revalidate on one will not force it on any others. */ if (result != 0 && iinfo->createdAndUnopened == TRUE) { HgfsDentryAgeForce(file->f_dentry); } return result; } #if defined VMW_USE_AIO /* *---------------------------------------------------------------------- * * HgfsAioRead -- * * Called when the kernel initiates an asynchronous read to a file in * our filesystem. Our function is just a thin wrapper around * generic_file_aio_read() that tries to validate the dentry first. * * Results: * Returns the number of bytes read on success, or an error on * failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static ssize_t HgfsAioRead(struct kiocb *iocb, // IN: I/O control block const struct iovec *iov, // OUT: Array of I/O buffers unsigned long numSegs, // IN: Number of buffers loff_t offset) // IN: Offset at which to read { int result; ASSERT(iocb); ASSERT(iocb->ki_filp); ASSERT(iocb->ki_filp->f_dentry); ASSERT(iov); LOG(6, (KERN_DEBUG "VMware hgfs: HgfsAioRead: was called\n")); result = HgfsRevalidate(iocb->ki_filp->f_dentry); if (result) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsAioRead: invalid dentry\n")); goto out; } result = generic_file_aio_read(iocb, iov, numSegs, offset); out: return result; } /* *---------------------------------------------------------------------- * * HgfsAioWrite -- * * Called when the kernel initiates an asynchronous write to a file in * our filesystem. Our function is just a thin wrapper around * generic_file_aio_write() that tries to validate the dentry first. * * Note that files opened with O_SYNC (or superblocks mounted with * "sync") are synchronously written to by the VFS. * * Results: * Returns the number of bytes written on success, or an error on * failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static ssize_t HgfsAioWrite(struct kiocb *iocb, // IN: I/O control block const struct iovec *iov, // IN: Array of I/O buffers unsigned long numSegs, // IN: Number of buffers loff_t offset) // IN: Offset at which to read { int result; ASSERT(iocb); ASSERT(iocb->ki_filp); ASSERT(iocb->ki_filp->f_dentry); ASSERT(iov); LOG(6, (KERN_DEBUG "VMware hgfs: HgfsAioWrite: was called\n")); result = HgfsRevalidate(iocb->ki_filp->f_dentry); if (result) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsAioWrite: invalid dentry\n")); goto out; } result = generic_file_aio_write(iocb, iov, numSegs, offset); out: return result; } #else /* *---------------------------------------------------------------------- * * HgfsRead -- * * Called whenever a process reads from a file in our filesystem. Our * function is just a thin wrapper around generic_read_file() that * tries to validate the dentry first. * * Results: * Returns the number of bytes read on success, or an error on * failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static ssize_t HgfsRead(struct file *file, // IN: File to read from char __user *buf, // OUT: User buffer to copy data into size_t count, // IN: Number of bytes to read loff_t *offset) // IN: Offset at which to read { int result; ASSERT(file); ASSERT(file->f_dentry); ASSERT(buf); ASSERT(offset); LOG(6, (KERN_DEBUG "VMware hgfs: HgfsRead: read %Zu bytes from fh %u " "at offset %Lu\n", count, FILE_GET_FI_P(file)->handle, *offset)); result = HgfsRevalidate(file->f_dentry); if (result) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRead: invalid dentry\n")); goto out; } result = generic_file_read(file, buf, count, offset); out: return result; } /* *---------------------------------------------------------------------- * * HgfsWrite -- * * Called whenever a process writes to a file in our filesystem. Our * function is just a thin wrapper around generic_write_file() that * tries to validate the dentry first. * * Note that files opened with O_SYNC (or superblocks mounted with * "sync") are synchronously written to by the VFS. * * Results: * Returns the number of bytes written on success, or an error on * failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static ssize_t HgfsWrite(struct file *file, // IN: File to write to const char __user *buf, // IN: User buffer where the data is size_t count, // IN: Number of bytes to write loff_t *offset) // IN: Offset to begin writing at { int result; ASSERT(file); ASSERT(file->f_dentry); ASSERT(file->f_dentry->d_inode); ASSERT(buf); ASSERT(offset); LOG(6, (KERN_DEBUG "VMware hgfs: HgfsWrite: write %Zu bytes to fh %u " "at offset %Lu\n", count, FILE_GET_FI_P(file)->handle, *offset)); result = HgfsRevalidate(file->f_dentry); if (result) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsWrite: invalid dentry\n")); goto out; } result = generic_file_write(file, buf, count, offset); out: return result; } #endif /* *---------------------------------------------------------------------- * * HgfsSeek -- * * Called whenever a process moves the file pointer for a file in our * filesystem. Our function is just a thin wrapper around * generic_file_llseek() that tries to validate the dentry first. * * Results: * Returns the new position of the file pointer on success, * or a negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static loff_t HgfsSeek(struct file *file, // IN: File to seek loff_t offset, // IN: Number of bytes to seek int origin) // IN: Position to seek from { loff_t result = -1; ASSERT(file); ASSERT(file->f_dentry); LOG(6, (KERN_DEBUG "VMware hgfs: HgfsSeek: seek to %Lu bytes from fh %u " "from position %d\n", offset, FILE_GET_FI_P(file)->handle, origin)); result = (loff_t) HgfsRevalidate(file->f_dentry); if (result) { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsSeek: invalid dentry\n")); goto out; } result = generic_file_llseek(file, offset, origin); out: return result; } /* *---------------------------------------------------------------------- * * HgfsFsync -- * * Called when user process calls fsync() on hgfs file. * * The hgfs protocol doesn't support fsync yet, so for now, we punt * and just return success. This is a little less sketchy than it * might sound, because hgfs skips the buffer cache in the guest * anyway (we always write to the host immediately). * * In the future we might want to try harder though, since * presumably the intent of an app calling fsync() is to get the * data onto persistent storage, and as things stand now we're at * the whim of the hgfs server code running on the host to fsync or * not if and when it pleases. * * Note that do_fsync will call filemap_fdatawrite() before us and * filemap_fdatawait() after us, so there's no need to do anything * here w.r.t. writing out dirty pages. * * Results: * Returns zero on success. (Currently always succeeds). * * Side effects: * None. * *---------------------------------------------------------------------- */ static int HgfsFsync(struct file *file, // IN: File we operate on #if defined VMW_FSYNC_OLD struct dentry *dentry, // IN: Dentry for this file #elif defined VMW_FSYNC_31 loff_t start, // IN: start of range to sync loff_t end, // IN: end of range to sync #endif int datasync) // IN: fdatasync or fsync { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsFsync: was called\n")); return 0; } /* *---------------------------------------------------------------------- * * HgfsMmap -- * * Called when user process calls mmap() on hgfs file. This is a very * thin wrapper function- we simply attempt to revalidate the * dentry prior to calling generic_file_mmap(). * * Results: * Returns zero on success. * Returns negative error value on failure * * Side effects: * None. * *---------------------------------------------------------------------- */ static int HgfsMmap(struct file *file, // IN: File we operate on struct vm_area_struct *vma) // IN/OUT: VM area information { int result; ASSERT(file); ASSERT(vma); ASSERT(file->f_dentry); LOG(6, (KERN_DEBUG "VMware hgfs: HgfsMmap: was called\n")); result = HgfsRevalidate(file->f_dentry); if (result) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsMmap: invalid dentry\n")); goto out; } result = generic_file_mmap(file, vma); out: return result; } /* *---------------------------------------------------------------------- * * HgfsRelease -- * * Called when the last user of a file closes it, i.e. when the * file's f_count becomes zero. * * Results: * Returns zero on success, or an error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsRelease(struct inode *inode, // IN: Inode that this file points to struct file *file) // IN: File that is getting released { HgfsReq *req; HgfsHandle handle; HgfsOp opUsed; HgfsStatus replyStatus; int result = 0; ASSERT(inode); ASSERT(file); ASSERT(file->f_dentry); ASSERT(file->f_dentry->d_sb); handle = FILE_GET_FI_P(file)->handle; LOG(6, (KERN_DEBUG "VMware hgfs: HgfsRelease: close fh %u\n", handle)); /* * This may be our last open handle to an inode, so we should flush our * dirty pages before closing it. */ compat_filemap_write_and_wait(inode->i_mapping); HgfsReleaseFileInfo(file); req = HgfsGetNewRequest(); if (!req) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRelease: out of memory while " "getting new request\n")); result = -ENOMEM; goto out; } retry: opUsed = hgfsVersionClose; if (opUsed == HGFS_OP_CLOSE_V3) { HgfsRequest *header; HgfsRequestCloseV3 *request; header = (HgfsRequest *)(HGFS_REQ_PAYLOAD(req)); header->id = req->id; header->op = opUsed; request = (HgfsRequestCloseV3 *)(HGFS_REQ_PAYLOAD_V3(req)); request->file = handle; request->reserved = 0; req->payloadSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); } else { HgfsRequestClose *request; request = (HgfsRequestClose *)(HGFS_REQ_PAYLOAD(req)); request->header.id = req->id; request->header.op = opUsed; request->file = handle; req->payloadSize = sizeof *request; } /* Send the request and process the reply. */ result = HgfsSendRequest(req); if (result == 0) { /* Get the reply. */ replyStatus = HgfsReplyStatus(req); result = HgfsStatusConvertToLinux(replyStatus); switch (result) { case 0: LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRelease: released handle %u\n", handle)); break; case -EPROTO: /* Retry with older version(s). Set globally. */ if (opUsed == HGFS_OP_CLOSE_V3) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRelease: Version 3 not " "supported. Falling back to version 1.\n")); hgfsVersionClose = HGFS_OP_CLOSE; goto retry; } break; default: LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRelease: failed handle %u\n", handle)); break; } } else if (result == -EIO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRelease: timed out\n")); } else if (result == -EPROTO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRelease: server " "returned error: %d\n", result)); } else { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRelease: unknown error: " "%d\n", result)); } out: HgfsFreeRequest(req); return result; } #ifndef VMW_SENDFILE_NONE /* *----------------------------------------------------------------------------- * * HgfsSendfile -- * * sendfile() wrapper for HGFS. Note that this is for sending a file * from HGFS to another filesystem (or socket). To use HGFS as the * destination file in a call to sendfile(), we must implement sendpage() * as well. * * Like mmap(), we're just interested in validating the dentry and then * calling into generic_file_sendfile(). * * Results: * Returns number of bytes written on success, or an error on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ #if defined VMW_SENDFILE_OLD static ssize_t HgfsSendfile(struct file *file, // IN: File to read from loff_t *offset, // IN/OUT: Where to start reading size_t count, // IN: How much to read read_actor_t actor, // IN: Routine to send a page of data void __user *target) // IN: Destination file/socket #elif defined VMW_SENDFILE_NEW static ssize_t HgfsSendfile(struct file *file, // IN: File to read from loff_t *offset, // IN/OUT: Where to start reading size_t count, // IN: How much to read read_actor_t actor, // IN: Routine to send a page of data void *target) // IN: Destination file/socket #endif { ssize_t result; ASSERT(file); ASSERT(file->f_dentry); ASSERT(target); ASSERT(offset); ASSERT(actor); LOG(6, (KERN_DEBUG "VMware hgfs: HgfsSendfile: was called\n")); result = HgfsRevalidate(file->f_dentry); if (result) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSendfile: invalid dentry\n")); goto out; } result = generic_file_sendfile (file, offset, count, actor, target); out: return result; } #endif #ifdef VMW_SPLICE_READ /* *----------------------------------------------------------------------------- * * HgfsSpliceRead -- * * splice_read() wrapper for HGFS. Note that this is for sending a file * from HGFS to another filesystem (or socket). To use HGFS as the * destination file in a call to splice, we must implement splice_write() * as well. * * Like mmap(), we're just interested in validating the dentry and then * calling into generic_file_splice_read(). * * Results: * Returns number of bytes written on success, or an error on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static ssize_t HgfsSpliceRead(struct file *file, // IN: File to read from loff_t *offset, // IN/OUT: Where to start reading struct pipe_inode_info *pipe, // IN: Pipe where to write data size_t len, // IN: How much to read unsigned int flags) // IN: Various flags { ssize_t result; ASSERT(file); ASSERT(file->f_dentry); LOG(6, (KERN_DEBUG "VMware hgfs: HgfsSpliceRead: was called\n")); result = HgfsRevalidate(file->f_dentry); if (result) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSpliceRead: invalid dentry\n")); goto out; } result = generic_file_splice_read(file, offset, pipe, len, flags); out: return result; } #endif open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/tcp.c0000644765153500003110000005761012220061556020503 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * tcp.c -- * * Provides TCP channel to the HGFS client. * * Compiled conditionally. * Need to specify host ip at module load to enable the channel. */ /* Must come before any kernel header file. */ #include "driver-config.h" #include #include #include #include #include #include #include #include "compat_kernel.h" #include "compat_mutex.h" #include "compat_version.h" #include "compat_sched.h" #include "compat_sock.h" #include "compat_timer.h" #include "vm_assert.h" #include "hgfsProto.h" #include "hgfsDevLinux.h" #include "module.h" #include "transport.h" static char *HOST_IP; module_param(HOST_IP, charp, 0444); static int HOST_PORT = 2000; /* Defaulted to 2000. */ module_param(HOST_PORT, int, 0444); static int HOST_VSOCKET_PORT = 0; /* Disabled by default. */ module_param(HOST_VSOCKET_PORT, int, 0444); #ifdef INCLUDE_VSOCKETS #include "vmci_defs.h" #include "vmci_sockets.h" #else /* * At the moment I can't check in HGFS that is dependent on vsock * because of unresolved installer problems. Installer need to properly handle * dependecies between vmhgfs and vsock modules. * Following stub functions must be removed when installer problems are resolved. * Stubs for undefined functions. */ void VMCISock_KernelDeregister(void) { } void VMCISock_KernelRegister(void) { } #endif /* Indicates that data is ready to be received */ #define HGFS_REQ_THREAD_RECV (1 << 0) /* Recv states for the recvBuffer. */ typedef enum { HGFS_CONN_RECV_SOCK_HDR, /* Waiting for socket header */ HGFS_CONN_RECV_REP_HDR, /* Waiting for HgfsReply header */ HGFS_CONN_RECV_REP_PAYLOAD, /* Waiting for reply payload */ } HgfsSocketRecvState; /* HGFS receive buffer. */ typedef struct HgfsSocketRecvBuffer { HgfsSocketHeader header; /* Buffer for receiving header. */ HgfsReply reply; /* Buffer for receiving reply */ HgfsReq *req; /* Request currently being received. */ char sink[HGFS_PACKET_MAX]; /* Buffer for data to be discarded. */ HgfsSocketRecvState state; /* Reply receive state. */ int len; /* Number of bytes to receive. */ char *buf; /* Pointer to the buffer. */ } HgfsSocketRecvBuffer; static HgfsSocketRecvBuffer recvBuffer; /* Accessed only by the recv thread. */ static struct task_struct *recvThread; /* The recv thread. */ static DECLARE_WAIT_QUEUE_HEAD(hgfsRecvThreadWait); /* Wait queue for recv thread. */ static unsigned long hgfsRecvThreadFlags; /* Used to signal recv data availability. */ static void (*oldSocketDataReady)(struct sock *, int); static Bool HgfsVSocketChannelOpen(HgfsTransportChannel *channel); static int HgfsSocketChannelSend(HgfsTransportChannel *channel, HgfsReq *req); static void HgfsVSocketChannelClose(HgfsTransportChannel *channel); static Bool HgfsTcpChannelOpen(HgfsTransportChannel *channel); static void HgfsTcpChannelClose(HgfsTransportChannel *channel); static HgfsReq * HgfsSocketChannelAllocate(size_t payloadSize); void HgfsSocketChannelFree(HgfsReq *req); static HgfsTransportChannel vsockChannel = { .name = "vsocket", .ops.close = HgfsVSocketChannelClose, .ops.send = HgfsSocketChannelSend, .ops.open = HgfsVSocketChannelOpen, .ops.allocate = NULL, .ops.free = NULL, .priv = NULL, .status = HGFS_CHANNEL_NOTCONNECTED }; static HgfsTransportChannel tcpChannel = { .name = "tcp", .ops.open = HgfsTcpChannelOpen, .ops.close = HgfsTcpChannelClose, .ops.allocate = HgfsSocketChannelAllocate, .ops.free = HgfsSocketChannelFree, .ops.send = HgfsSocketChannelSend, .priv = NULL, .status = HGFS_CHANNEL_NOTCONNECTED }; /* *---------------------------------------------------------------------- * * HgfsSocketDataReady -- * * Called when there is data to read on the connected socket. * * Results: * None. * * Side effects: * Wakes up the receiving thread. * *---------------------------------------------------------------------- */ static void HgfsSocketDataReady(struct sock *sk, // IN: Server socket int len) // IN: Data length { LOG(4, (KERN_DEBUG "VMware hgfs: %s: data ready\n", __func__)); /* Call the original data_ready function. */ oldSocketDataReady(sk, len); /* Wake up the recv thread. */ set_bit(HGFS_REQ_THREAD_RECV, &hgfsRecvThreadFlags); wake_up_interruptible(&hgfsRecvThreadWait); } /* *---------------------------------------------------------------------- * * HgfsSocketResetRecvBuffer -- * * Reset recv buffer. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ static void HgfsSocketResetRecvBuffer(void) { recvBuffer.state = HGFS_CONN_RECV_SOCK_HDR; recvBuffer.req = NULL; recvBuffer.len = sizeof recvBuffer.header; recvBuffer.buf = (char *)&recvBuffer.header; } /* *---------------------------------------------------------------------- * * HgfsSocketIsReceiverIdle -- * * Checks whether we are in the middle of receiving a packet. * * Results: * FALSE if receiving thread is in the middle of receiving packet, * otherwise TRUE. * * Side effects: * None * *---------------------------------------------------------------------- */ static Bool HgfsSocketIsReceiverIdle(void) { return recvBuffer.state == HGFS_CONN_RECV_SOCK_HDR && recvBuffer.len == sizeof recvBuffer.header; } /* *---------------------------------------------------------------------- * * HgfsSocketRecvMsg -- * * Receive the message on the socket. * * Results: * On success returns number of bytes received. * On failure returns the negative errno. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsSocketRecvMsg(struct socket *socket, // IN: TCP socket char *buffer, // IN: Buffer to recv the message size_t bufferLen) // IN: Buffer length { struct iovec iov; struct msghdr msg; int ret; int flags = MSG_DONTWAIT | MSG_NOSIGNAL; mm_segment_t oldfs = get_fs(); memset(&msg, 0, sizeof msg); msg.msg_flags = flags; msg.msg_iov = &iov; msg.msg_iovlen = 1; iov.iov_base = buffer; iov.iov_len = bufferLen; set_fs(KERNEL_DS); ret = sock_recvmsg(socket, &msg, bufferLen, flags); set_fs(oldfs); return ret; } /* *---------------------------------------------------------------------- * * HgfsSocketChannelRecvAsync -- * * Receive as much data from the socket as possible without blocking. * Note, that we may return early with just a part of the packet * received. * * Results: * On failure returns the negative errno, otherwise 0. * * Side effects: * Changes state of the receive buffer depending on what part of * the packet has been received so far. * *---------------------------------------------------------------------- */ static int HgfsSocketChannelRecvAsync(HgfsTransportChannel *channel) // IN: Channel { int ret; if (channel->status != HGFS_CHANNEL_CONNECTED) { LOG(6, (KERN_DEBUG "VMware hgfs: %s: Connection lost.\n", __func__)); return -ENOTCONN; } /* We want to read as much data as possible without blocking */ for (;;) { LOG(10, (KERN_DEBUG "VMware hgfs: %s: receiving %s\n", __func__, recvBuffer.state == HGFS_CONN_RECV_SOCK_HDR ? "header" : recvBuffer.state == HGFS_CONN_RECV_REP_HDR ? "reply" : "data")); ret = HgfsSocketRecvMsg(channel->priv, recvBuffer.buf, recvBuffer.len); LOG(10, (KERN_DEBUG "VMware hgfs: %s: sock_recvmsg returns: %d\n", __func__, ret)); if (ret <= 0) { break; } ASSERT(ret <= recvBuffer.len); recvBuffer.len -= ret; recvBuffer.buf += ret; if (recvBuffer.len != 0) { continue; } /* Complete segment received. */ switch (recvBuffer.state) { case HGFS_CONN_RECV_SOCK_HDR: LOG(10, (KERN_DEBUG "VMware hgfs: %s: received packet header\n", __func__)); ASSERT(recvBuffer.header.version == HGFS_SOCKET_VERSION1); ASSERT(recvBuffer.header.size == sizeof recvBuffer.header); ASSERT(recvBuffer.header.status == HGFS_SOCKET_STATUS_SUCCESS); recvBuffer.state = HGFS_CONN_RECV_REP_HDR; recvBuffer.len = sizeof recvBuffer.reply; recvBuffer.buf = (char *)&recvBuffer.reply; break; case HGFS_CONN_RECV_REP_HDR: LOG(10, (KERN_DEBUG "VMware hgfs: %s: received packet reply\n", __func__)); recvBuffer.req = HgfsTransportGetPendingRequest(recvBuffer.reply.id); if (recvBuffer.req) { ASSERT(recvBuffer.header.packetLen <= recvBuffer.req->bufferSize); recvBuffer.req->payloadSize = recvBuffer.header.packetLen; memcpy(recvBuffer.req->payload, &recvBuffer.reply, sizeof recvBuffer.reply); recvBuffer.buf = recvBuffer.req->payload + sizeof recvBuffer.reply; } else { recvBuffer.buf = recvBuffer.sink; } recvBuffer.state = HGFS_CONN_RECV_REP_PAYLOAD; recvBuffer.len = recvBuffer.header.packetLen - sizeof recvBuffer.reply; if (recvBuffer.len) break; /* There is no actual payload, fall through */ case HGFS_CONN_RECV_REP_PAYLOAD: LOG(10, (KERN_DEBUG "VMware hgfs: %s: received packet payload\n", __func__)); if (recvBuffer.req) { HgfsCompleteReq(recvBuffer.req); HgfsRequestPutRef(recvBuffer.req); recvBuffer.req = NULL; } HgfsSocketResetRecvBuffer(); break; default: ASSERT(0); } } return ret; } /* *---------------------------------------------------------------------- * * HgfsSocketReceiveHandler -- * * Function run in background thread and wait on the data in the * connected channel. * * Results: * Always returns zero. * * Side effects: * Can be many. * *---------------------------------------------------------------------- */ static int HgfsSocketReceiveHandler(void *data) { HgfsTransportChannel *channel = data; int ret; LOG(6, (KERN_DEBUG "VMware hgfs: %s: thread started\n", __func__)); compat_set_freezable(); for (;;) { /* Wait for data to become available */ wait_event_interruptible(hgfsRecvThreadWait, (HgfsSocketIsReceiverIdle() && kthread_should_stop()) || test_bit(HGFS_REQ_THREAD_RECV, &hgfsRecvThreadFlags)); /* Kill yourself if told so. */ if (kthread_should_stop()) { LOG(6, (KERN_DEBUG "VMware hgfs: %s: told to exit\n", __func__)); break; } /* Check for suspend. */ if (compat_try_to_freeze()) { LOG(6, (KERN_DEBUG "VMware hgfs: %s: continuing after resume.\n", __func__)); continue; } if (test_and_clear_bit(HGFS_REQ_THREAD_RECV, &hgfsRecvThreadFlags)) { /* There is some data witing for us, let's read it */ ret = HgfsSocketChannelRecvAsync(channel); if (ret < 0 && ret != -EINTR && ret != -ERESTARTSYS && ret != -EAGAIN) { if (recvBuffer.req) { HgfsFailReq(recvBuffer.req, -EIO); HgfsRequestPutRef(recvBuffer.req); recvBuffer.req = NULL; } /* The connection is broken, leave it to the senders to restore it. */ HgfsTransportMarkDead(); } } } LOG(6, (KERN_DEBUG "VMware hgfs: %s: thread exited\n", __func__)); recvThread = NULL; return 0; } /* *---------------------------------------------------------------------- * * HgfsCreateTcpSocket -- * * Connect to HGFS TCP server. * * Results: * NULL on failure; otherwise address of the newly created and * connected TCP socket. * * Side effects: * None * *---------------------------------------------------------------------- */ static struct socket * HgfsCreateTcpSocket(void) { struct socket *socket; struct sockaddr_in addr; int error; addr.sin_family = AF_INET; addr.sin_addr.s_addr = in_aton(HOST_IP); addr.sin_port = htons(HOST_PORT); error = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &socket); if (error < 0) { LOG(8, ("%s: sock_create_kern failed: %d.\n", __func__, error)); return NULL; } error = socket->ops->connect(socket, (struct sockaddr *)&addr, sizeof addr, 0); if (error < 0) { LOG(8, ("%s: connect failed: %d.\n", __func__, error)); sock_release(socket); return NULL; } return socket; } /* *---------------------------------------------------------------------- * * HgfsCreateVsockSocket -- * * Connect to HGFS VSocket server. * * Results: * NULL on failure; otherwise address of the newly created and * connected VSock socket. * * Side effects: * None * *---------------------------------------------------------------------- */ static struct socket * HgfsCreateVsockSocket(void) { #ifdef INCLUDE_VSOCKETS struct socket *socket; struct sockaddr_vm addr; int family = VMCISock_GetAFValue(); int error; memset(&addr, 0, sizeof addr); addr.svm_family = family; addr.svm_cid = VMCI_HOST_CONTEXT_ID; addr.svm_port = HOST_VSOCKET_PORT; error = sock_create_kern(family, SOCK_STREAM, IPPROTO_TCP, &socket); if (error < 0) { LOG(8, ("%s: sock_create_kern failed: %d.\n", __func__, error)); return NULL; } error = socket->ops->connect(socket, (struct sockaddr *)&addr, sizeof addr, 0); if (error < 0) { LOG(8, ("%s: connect failed: %d.\n", __func__, error)); sock_release(socket); return NULL; } return socket; #else return NULL; #endif } /* *---------------------------------------------------------------------- * * HgfsSocketChannelOpen -- * * Connect to HGFS TCP or VSocket server in an idempotent way. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static Bool HgfsSocketChannelOpen(HgfsTransportChannel *channel, struct socket *(*create_socket)(void)) { struct socket *socket; ASSERT(channel->status == HGFS_CHANNEL_NOTCONNECTED); ASSERT(!recvThread); socket = create_socket(); if (socket == NULL) return FALSE; /* * Install the new "data ready" handler that will wake up the * receiving thread. */ oldSocketDataReady = xchg(&socket->sk->sk_data_ready, HgfsSocketDataReady); /* Reset receive buffer when a new connection is connected. */ HgfsSocketResetRecvBuffer(); channel->priv = socket; LOG(8, ("%s: socket channel connected.\n", __func__)); /* Create the recv thread. */ recvThread = kthread_run(HgfsSocketReceiveHandler, channel, "vmhgfs-rep"); if (IS_ERR(recvThread)) { LOG(4, (KERN_ERR "VMware hgfs: %s: " "failed to create recv thread, err %ld\n", __func__, PTR_ERR(recvThread))); recvThread = NULL; sock_release(channel->priv); channel->priv = NULL; return FALSE; } return TRUE; } /* *---------------------------------------------------------------------- * * HgfsTcpChannelOpen -- * * Connect to HGFS TCP server in an idempotent way. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static Bool HgfsTcpChannelOpen(HgfsTransportChannel *channel) { return HgfsSocketChannelOpen(channel, HgfsCreateTcpSocket); } /* *---------------------------------------------------------------------- * * HgfsVSocketChannelOpen -- * * Connect to HGFS VSocket server in an idempotent way. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static Bool HgfsVSocketChannelOpen(HgfsTransportChannel *channel) { VMCISock_KernelRegister(); if (!HgfsSocketChannelOpen(channel, HgfsCreateVsockSocket)) { VMCISock_KernelDeregister(); return FALSE; } return TRUE; } /* *---------------------------------------------------------------------- * * HgfsSocketChannelClose -- * * Closes socket-based channel by closing socket and stopping the * receiving thread. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ static void HgfsSocketChannelClose(HgfsTransportChannel *channel) { /* Stop the recv thread before we change the channel status. */ ASSERT(recvThread != NULL); kthread_stop(recvThread); sock_release(channel->priv); channel->priv = NULL; LOG(8, ("VMware hgfs: %s: socket channel closed.\n", __func__)); } /* *---------------------------------------------------------------------- * * HgfsTcpChannelClose -- * * Closes TCP channel. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ static void HgfsTcpChannelClose(HgfsTransportChannel *channel) { HgfsSocketChannelClose(channel); LOG(8, ("VMware hgfs: %s: tcp channel closed.\n", __func__)); } /* *---------------------------------------------------------------------- * * HgfsVSocketChannelClose -- * * See above. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ static void HgfsVSocketChannelClose(HgfsTransportChannel *channel) { HgfsSocketChannelClose(channel); VMCISock_KernelDeregister(); LOG(8, ("VMware hgfs: %s: VSock channel closed.\n", __func__)); } /* *---------------------------------------------------------------------- * * HgfsSocketSendMsg -- * * Send the message via the socket. Add the header before sending. * * Results: * On success returns 0; * On failure returns the negative errno. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsSocketSendMsg(struct socket *socket, // IN: socket void *buffer, // IN: Buffer to send size_t bufferLen) // IN: Buffer length { struct iovec iov; struct msghdr msg; int ret = 0; int i = 0; mm_segment_t oldfs = get_fs(); memset(&msg, 0, sizeof msg); iov.iov_base = buffer; iov.iov_len = bufferLen; msg.msg_iov = &iov; msg.msg_iovlen = 1; while (bufferLen > 0) { set_fs(KERNEL_DS); ret = sock_sendmsg(socket, &msg, bufferLen); set_fs(oldfs); LOG(6, (KERN_DEBUG "VMware hgfs: %s: sock_sendmsg returns %d.\n", __func__, ret)); if (likely(ret == bufferLen)) { /* Common case. */ break; } else if (ret < 0) { if (ret == -ENOSPC || ret == -EAGAIN) { if (++i <= 12) { LOG(6, (KERN_DEBUG "VMware hgfs: %s: " "Sleep for %d milliseconds before retry.\n", __func__, (1 << i))); compat_msleep(1 << i); continue; } LOG(2, ("VMware hgfs: %s: send stuck for 8 seconds.\n", __func__)); ret = -EIO; } break; } else if (ret >= bufferLen) { LOG(2, ("VMware hgfs: %s: sent more than expected bytes. Sent: %d, " "expected: %d\n", __func__, ret, (int)bufferLen)); break; } else { i = 0; bufferLen -= ret; iov.iov_base += ret; iov.iov_len -= ret; } } if (ret > 0) { ret = 0; /* Indicate success. */ } return ret; } /* *---------------------------------------------------------------------- * * HgfsSocketChannelSend -- * * Send the request via a socket channel. * * Results: * 0 on success, negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsSocketChannelSend(HgfsTransportChannel *channel, // IN: Channel HgfsReq *req) // IN: request to send { int result; ASSERT(req); HgfsSocketHeaderInit((HgfsSocketHeader *)req->buffer, HGFS_SOCKET_VERSION1, sizeof(HgfsSocketHeader), HGFS_SOCKET_STATUS_SUCCESS, req->payloadSize, 0); req->state = HGFS_REQ_STATE_SUBMITTED; result = HgfsSocketSendMsg((struct socket *)channel->priv, req->buffer, sizeof(HgfsSocketHeader) + req->payloadSize); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: %s: sendmsg, err: %d.\n", __func__, result)); req->state = HGFS_REQ_STATE_UNSENT; } return result; } /* *---------------------------------------------------------------------- * * HgfsSocketChannelAllocate -- * * Allocates memory for HgfsReq, its payload plus additional memory * needed for the socket transport itself. * * Results: * NULL on failure otherwise address of allocated memory. * * Side effects: * None * *---------------------------------------------------------------------- */ static HgfsReq * HgfsSocketChannelAllocate(size_t payloadSize) // IN: size of the payload { HgfsReq *req; req = kmalloc(sizeof(*req) + sizeof(HgfsSocketHeader) + payloadSize, GFP_KERNEL); if (likely(req)) { req->payload = req->buffer + sizeof(HgfsSocketHeader); req->bufferSize = payloadSize; } return req; } /* *----------------------------------------------------------------------------- * * HgfsSocketChannelFree -- * * Free previously allocated request. * * Results: * none * * Side effects: * Object is freed * *----------------------------------------------------------------------------- */ void HgfsSocketChannelFree(HgfsReq *req) { ASSERT(req); kfree(req); } /* *---------------------------------------------------------------------- * * HgfsGetTcpChannel -- * * Initialize TCP channel. * * Results: * Pointer to a channel on success, otherwise NULL. * * Side effects: * None * *---------------------------------------------------------------------- */ HgfsTransportChannel * HgfsGetTcpChannel(void) { if (!HOST_IP) { return NULL; } return &tcpChannel; } /* *---------------------------------------------------------------------- * * HgfsGetVSocketChannel -- * * Initialize VSocket channel. * * Results: * Pointer to a channel on success, otherwise NULL. * * Side effects: * None * *---------------------------------------------------------------------- */ HgfsTransportChannel * HgfsGetVSocketChannel(void) { if (!HOST_VSOCKET_PORT) { return NULL; } return &vsockChannel; } open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/page.c0000644765153500003110000011076212220061556020627 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * page.c -- * * Address space operations for the filesystem portion of the vmhgfs driver. */ /* Must come before any kernel header file. */ #include "driver-config.h" #include #include "compat_mm.h" #include "compat_page-flags.h" #include "compat_fs.h" #include "compat_kernel.h" #include "compat_pagemap.h" #include "compat_highmem.h" #include #include "cpName.h" #include "hgfsProto.h" #include "module.h" #include "request.h" #include "hgfsUtil.h" #include "fsutil.h" #include "inode.h" #include "vm_assert.h" #include "vm_basic_types.h" #include "hgfsTransport.h" /* Private functions. */ static int HgfsDoWrite(HgfsHandle handle, HgfsDataPacket dataPacket[], uint32 numEntries, loff_t offset); static int HgfsDoRead(HgfsHandle handle, HgfsDataPacket dataPacket[], uint32 numEntries, loff_t offset); static int HgfsDoReadpage(HgfsHandle handle, struct page *page, unsigned pageFrom, unsigned pageTo); static int HgfsDoWritepage(HgfsHandle handle, struct page *page, unsigned pageFrom, unsigned pageTo); static void HgfsDoWriteBegin(struct page *page, unsigned pageFrom, unsigned pageTo); static int HgfsDoWriteEnd(struct file *file, struct page *page, unsigned pageFrom, unsigned pageTo, loff_t writeTo, unsigned copied); /* HGFS address space operations. */ static int HgfsReadpage(struct file *file, struct page *page); static int HgfsWritepage(struct page *page, struct writeback_control *wbc); /* * Write aop interface has changed in 2.6.28. Specifically, * the page locking semantics and requirement to handle * short writes. We already handle short writes, so no major * changes needed. write_begin is expected to return a locked * page and write_end is expected to unlock the page and drop * the reference before returning. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) static int HgfsWriteBegin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **page, void **clientData); static int HgfsWriteEnd(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, struct page *page, void *clientData); #else static int HgfsPrepareWrite(struct file *file, struct page *page, unsigned pageFrom, unsigned pageTo); static int HgfsCommitWrite(struct file *file, struct page *page, unsigned pageFrom, unsigned pageTo); #endif /* HGFS address space operations structure. */ struct address_space_operations HgfsAddressSpaceOperations = { .readpage = HgfsReadpage, .writepage = HgfsWritepage, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) .write_begin = HgfsWriteBegin, .write_end = HgfsWriteEnd, #else .prepare_write = HgfsPrepareWrite, .commit_write = HgfsCommitWrite, #endif .set_page_dirty = __set_page_dirty_nobuffers, }; /* * Private functions. */ /* *----------------------------------------------------------------------------- * * HgfsDoRead -- * * Do one read request. Called by HgfsReadpage, possibly multiple times * if the size of the read is too big to be handled by one server request. * * We send a "Read" request to the server with the given handle. * * It is assumed that this function is never called with a larger read than * what can be sent in one request. * * HgfsDataPacket is an array of pages into which data will be read. * * Results: * Returns the number of bytes read on success, or an error on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsDoRead(HgfsHandle handle, // IN: Handle for this file HgfsDataPacket dataPacket[], // IN/OUT: Data description uint32 numEntries, // IN: Number of entries in dataPacket loff_t offset) // IN: Offset at which to read { HgfsReq *req; HgfsOp opUsed; int result = 0; uint32 actualSize = 0; char *payload = NULL; HgfsStatus replyStatus; char *buf; uint32 count; ASSERT(numEntries == 1); count = dataPacket[0].len; req = HgfsGetNewRequest(); if (!req) { LOG(4, (KERN_WARNING "VMware hgfs: HgfsDoRead: out of memory while " "getting new request\n")); result = -ENOMEM; goto out; } retry: opUsed = hgfsVersionRead; if (opUsed == HGFS_OP_READ_FAST_V4) { HgfsRequest *header; HgfsRequestReadV3 *request; header = (HgfsRequest *)(HGFS_REQ_PAYLOAD(req)); header->id = req->id; header->op = opUsed; request = (HgfsRequestReadV3 *)(HGFS_REQ_PAYLOAD_V3(req)); request->file = handle; request->offset = offset; request->requiredSize = count; request->reserved = 0; req->dataPacket = kmalloc(numEntries * sizeof req->dataPacket[0], GFP_KERNEL); if (!req->dataPacket) { LOG(4, (KERN_WARNING "%s: Failed to allocate mem\n", __func__)); result = -ENOMEM; goto out; } memcpy(req->dataPacket, dataPacket, numEntries * sizeof req->dataPacket[0]); req->numEntries = numEntries; LOG(4, (KERN_WARNING "VMware hgfs: Fast Read V4\n")); } else if (opUsed == HGFS_OP_READ_V3) { HgfsRequest *header; HgfsRequestReadV3 *request; header = (HgfsRequest *)(HGFS_REQ_PAYLOAD(req)); header->id = req->id; header->op = opUsed; request = (HgfsRequestReadV3 *)(HGFS_REQ_PAYLOAD_V3(req)); request->file = handle; request->offset = offset; request->requiredSize = MIN(req->bufferSize - sizeof *request - sizeof *header, count); request->reserved = 0; req->dataPacket = NULL; req->numEntries = 0; req->payloadSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); } else { HgfsRequestRead *request; request = (HgfsRequestRead *)(HGFS_REQ_PAYLOAD(req)); request->header.id = req->id; request->header.op = opUsed; request->file = handle; request->offset = offset; request->requiredSize = MIN(req->bufferSize - sizeof *request, count); req->dataPacket = NULL; req->numEntries = 0; req->payloadSize = sizeof *request; } /* Send the request and process the reply. */ result = HgfsSendRequest(req); if (result == 0) { /* Get the reply. */ replyStatus = HgfsReplyStatus(req); result = HgfsStatusConvertToLinux(replyStatus); switch (result) { case 0: if (opUsed == HGFS_OP_READ_FAST_V4) { actualSize = ((HgfsReplyReadV3 *)HGFS_REP_PAYLOAD_V3(req))->actualSize; } else if (opUsed == HGFS_OP_READ_V3) { actualSize = ((HgfsReplyReadV3 *)HGFS_REP_PAYLOAD_V3(req))->actualSize; payload = ((HgfsReplyReadV3 *)HGFS_REP_PAYLOAD_V3(req))->payload; } else { actualSize = ((HgfsReplyRead *)HGFS_REQ_PAYLOAD(req))->actualSize; payload = ((HgfsReplyRead *)HGFS_REQ_PAYLOAD(req))->payload; } /* Sanity check on read size. */ if (actualSize > count) { LOG(4, (KERN_WARNING "VMware hgfs: HgfsDoRead: read too big!\n")); result = -EPROTO; goto out; } if (!actualSize) { /* We got no bytes. */ LOG(6, (KERN_WARNING "VMware hgfs: HgfsDoRead: server returned " "zero\n")); result = actualSize; goto out; } /* Return result. */ if (opUsed == HGFS_OP_READ_V3 || opUsed == HGFS_OP_READ) { buf = kmap(dataPacket[0].page) + dataPacket[0].offset; ASSERT(buf); memcpy(buf, payload, actualSize); LOG(6, (KERN_WARNING "VMware hgfs: HgfsDoRead: copied %u\n", actualSize)); kunmap(dataPacket[0].page); } result = actualSize; break; case -EPROTO: /* Retry with older version(s). Set globally. */ switch (opUsed) { case HGFS_OP_READ_FAST_V4: LOG(4, (KERN_WARNING "VMware hgfs: HgfsDoRead: Fast Read V4 not " "supported. Falling back to V3 Read.\n")); if (req->dataPacket) { kfree(req->dataPacket); req->dataPacket = NULL; } hgfsVersionRead = HGFS_OP_READ_V3; goto retry; case HGFS_OP_READ_V3: LOG(4, (KERN_WARNING "VMware hgfs: HgfsDoRead: Version 3 not " "supported. Falling back to version 1.\n")); hgfsVersionRead = HGFS_OP_READ; goto retry; default: break; } break; default: break; } } else if (result == -EIO) { LOG(4, (KERN_WARNING "VMware hgfs: HgfsDoRead: timed out\n")); } else if (result == -EPROTO) { LOG(4, (KERN_WARNING "VMware hgfs: HgfsDoRead: server " "returned error: %d\n", result)); } else { LOG(4, (KERN_WARNING "VMware hgfs: HgfsDoRead: unknown error: " "%d\n", result)); } out: if (req->dataPacket) { kfree(req->dataPacket); } HgfsFreeRequest(req); return result; } /* *----------------------------------------------------------------------------- * * HgfsDoWrite -- * * Do one write request. Called by HgfsDoWritepage, possibly multiple * times if the size of the write is too big to be handled by one server * request. * * We send a "Write" request to the server with the given handle. * * It is assumed that this function is never called with a larger write * than what can be sent in one request. * * HgfsDataPacket is an array of pages from which data will be written * to file. * * Results: * Returns the number of bytes written on success, or an error on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int HgfsDoWrite(HgfsHandle handle, // IN: Handle for this file HgfsDataPacket dataPacket[], // IN: Data description uint32 numEntries, // IN: Number of entries in dataPacket loff_t offset) // IN: Offset to begin writing at { HgfsReq *req; int result = 0; HgfsOp opUsed; uint32 requiredSize = 0; uint32 actualSize = 0; char *payload = NULL; uint32 reqSize; HgfsStatus replyStatus; char *buf; uint32 count; ASSERT(numEntries == 1); count = dataPacket[0].len; req = HgfsGetNewRequest(); if (!req) { LOG(4, (KERN_WARNING "VMware hgfs: HgfsDoWrite: out of memory while " "getting new request\n")); result = -ENOMEM; goto out; } retry: opUsed = hgfsVersionWrite; if (opUsed == HGFS_OP_WRITE_FAST_V4) { HgfsRequest *header; HgfsRequestWriteV3 *request; header = (HgfsRequest *)(HGFS_REQ_PAYLOAD(req)); header->id = req->id; header->op = opUsed; request = (HgfsRequestWriteV3 *)(HGFS_REQ_PAYLOAD_V3(req)); request->file = handle; request->flags = 0; request->offset = offset; request->requiredSize = count; request->reserved = 0; payload = request->payload; requiredSize = request->requiredSize; req->dataPacket = kmalloc(numEntries * sizeof req->dataPacket[0], GFP_KERNEL); if (!req->dataPacket) { LOG(4, (KERN_WARNING "%s: Failed to allocate mem\n", __func__)); result = -ENOMEM; goto out; } memcpy(req->dataPacket, dataPacket, numEntries * sizeof req->dataPacket[0]); req->numEntries = numEntries; reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); req->payloadSize = reqSize; LOG(4, (KERN_WARNING "VMware hgfs: Fast Write V4\n")); } else if (opUsed == HGFS_OP_WRITE_V3) { HgfsRequest *header; HgfsRequestWriteV3 *request; header = (HgfsRequest *)(HGFS_REQ_PAYLOAD(req)); header->id = req->id; header->op = opUsed; request = (HgfsRequestWriteV3 *)(HGFS_REQ_PAYLOAD_V3(req)); request->file = handle; request->flags = 0; request->offset = offset; request->requiredSize = MIN(req->bufferSize - sizeof *header - sizeof *request, count); LOG(4, (KERN_WARNING "VMware hgfs: Using write V3\n")); request->reserved = 0; payload = request->payload; requiredSize = request->requiredSize; reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); req->dataPacket = NULL; req->numEntries = 0; buf = kmap(dataPacket[0].page) + dataPacket[0].offset; memcpy(payload, buf, requiredSize); kunmap(dataPacket[0].page); req->payloadSize = reqSize + requiredSize - 1; } else { HgfsRequestWrite *request; request = (HgfsRequestWrite *)(HGFS_REQ_PAYLOAD(req)); request->header.id = req->id; request->header.op = opUsed; request->file = handle; request->flags = 0; request->offset = offset; request->requiredSize = MIN(req->bufferSize - sizeof *request, count); payload = request->payload; requiredSize = request->requiredSize; reqSize = sizeof *request; req->dataPacket = NULL; req->numEntries = 0; buf = kmap(dataPacket[0].page) + dataPacket[0].offset; memcpy(payload, buf, requiredSize); kunmap(dataPacket[0].page); req->payloadSize = reqSize + requiredSize - 1; } /* Send the request and process the reply. */ result = HgfsSendRequest(req); if (result == 0) { /* Get the reply. */ replyStatus = HgfsReplyStatus(req); result = HgfsStatusConvertToLinux(replyStatus); switch (result) { case 0: if (opUsed == HGFS_OP_WRITE_V3 || opUsed == HGFS_OP_WRITE_FAST_V4) { actualSize = ((HgfsReplyWriteV3 *)HGFS_REP_PAYLOAD_V3(req))->actualSize; } else { actualSize = ((HgfsReplyWrite *)HGFS_REQ_PAYLOAD(req))->actualSize; } /* Return result. */ LOG(6, (KERN_WARNING "VMware hgfs: HgfsDoWrite: wrote %u bytes\n", actualSize)); result = actualSize; break; case -EPROTO: /* Retry with older version(s). Set globally. */ switch (opUsed) { case HGFS_OP_WRITE_FAST_V4: LOG(4, (KERN_WARNING "VMware hgfs: HgfsDoWrite: Fast Write V4 not " "supported. Falling back to V3 write.\n")); if (req->dataPacket) { kfree(req->dataPacket); req->dataPacket = NULL; } hgfsVersionWrite = HGFS_OP_WRITE_V3; goto retry; case HGFS_OP_WRITE_V3: LOG(4, (KERN_WARNING "VMware hgfs: HgfsDoWrite: Version 3 not " "supported. Falling back to version 1.\n")); hgfsVersionWrite = HGFS_OP_WRITE; goto retry; default: break; } break; default: LOG(4, (KERN_WARNING "VMware hgfs: HgfsDoWrite: server " "returned error: %d\n", result)); break; } } else if (result == -EIO) { LOG(4, (KERN_WARNING "VMware hgfs: HgfsDoWrite: timed out\n")); } else if (result == -EPROTO) { LOG(4, (KERN_WARNING "VMware hgfs: HgfsDoWrite: server " "returned error: %d\n", result)); } else { LOG(4, (KERN_WARNING "VMware hgfs: HgfsDoWrite: unknown error: " "%d\n", result)); } out: if (req->dataPacket) { kfree(req->dataPacket); } HgfsFreeRequest(req); return result; } /* *----------------------------------------------------------------------------- * * HgfsDoReadpage -- * * Reads in a single page, using the specified handle and page offsets. * At the time of writing, HGFS_IO_MAX == PAGE_CACHE_SIZE, so we could * avoid the do {} while() and just read the page as is, but in case the * above assumption is ever broken, it's nice that this will continue to * "just work". * * Results: * Zero on success, non-zero on error. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int HgfsDoReadpage(HgfsHandle handle, // IN: Handle to use for reading struct page *page, // IN/OUT: Page to read into unsigned pageFrom, // IN: Where to start reading to unsigned pageTo) // IN: Where to stop reading { int result = 0; loff_t curOffset = ((loff_t)page->index << PAGE_CACHE_SHIFT) + pageFrom; size_t nextCount, remainingCount = pageTo - pageFrom; HgfsDataPacket dataPacket[1]; LOG(6, (KERN_WARNING "VMware hgfs: HgfsDoReadpage: read %Zu bytes from fh %u " "at offset %Lu\n", remainingCount, handle, curOffset)); /* * Call HgfsDoRead repeatedly until either * - HgfsDoRead returns an error, or * - HgfsDoRead returns 0 (end of file), or * - We have read the requested number of bytes. */ do { nextCount = (remainingCount > HGFS_IO_MAX) ? HGFS_IO_MAX : remainingCount; dataPacket[0].page = page; dataPacket[0].offset = pageFrom; dataPacket[0].len = nextCount; result = HgfsDoRead(handle, dataPacket, 1, curOffset); if (result < 0) { LOG(4, (KERN_WARNING "VMware hgfs: HgfsDoReadpage: read error %d\n", result)); goto out; } remainingCount -= result; curOffset += result; pageFrom += result; } while ((result > 0) && (remainingCount > 0)); /* * It's possible that despite being asked to read a full page, there is less * than a page in the file from this offset, so we should zero the rest of * the page's memory. */ if (remainingCount) { char *buffer = kmap(page) + pageTo; memset(buffer - remainingCount, 0, remainingCount); kunmap(page); } /* * We read a full page (or all of the page that actually belongs to the * file), so mark it up to date. Also, flush the old page data from the data * cache. */ flush_dcache_page(page); SetPageUptodate(page); result = 0; out: return result; } /* *----------------------------------------------------------------------------- * * HgfsDoWritepage -- * * Writes out a single page, using the specified handle and page offsets. * At the time of writing, HGFS_IO_MAX == PAGE_CACHE_SIZE, so we could * avoid the do {} while() and just write the page as is, but in case the * above assumption is ever broken, it's nice that this will continue to * "just work". * * A quick note about appending to files. Before HGFS used the page cache, * an HgfsWrite examined a file's f_flags and added HGFS_WRITE_APPEND to * the write packet if the file was opened with O_APPEND. This causes the * server to reopen the fd with O_APPEND so that writes will append to the * end. * * In the page cache world, this won't work because we may have arrived at * this function via writepage(), which doesn't give us a particular file * and thus we don't know if we should be appending or not. In fact, the * generic write path employed by the page cache handles files with O_APPEND * set by moving the file offset to the result of i_size_read(). So we * shouldn't ever need to set HGFS_WRITE_APPEND, as now we will handle all * write appends, instead of telling the server to do it for us. * * Results: * Zero on success, non-zero on error. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int HgfsDoWritepage(HgfsHandle handle, // IN: Handle to use for writing struct page *page, // IN: Page containing data to write unsigned pageFrom, // IN: Beginning page offset unsigned pageTo) // IN: Ending page offset { int result = 0; loff_t curOffset = ((loff_t)page->index << PAGE_CACHE_SHIFT) + pageFrom; size_t nextCount; size_t remainingCount = pageTo - pageFrom; struct inode *inode; HgfsDataPacket dataPacket[1]; ASSERT(page->mapping); ASSERT(page->mapping->host); inode = page->mapping->host; /* * Call HgfsDoWrite repeatedly until either * - HgfsDoWrite returns an error, or * - HgfsDoWrite returns 0 (XXX this probably rarely happens), or * - We have written the requested number of bytes. */ do { nextCount = (remainingCount > HGFS_IO_MAX) ? HGFS_IO_MAX : remainingCount; dataPacket[0].page = page; dataPacket[0].offset = pageFrom; dataPacket[0].len = nextCount; result = HgfsDoWrite(handle, dataPacket, 1, curOffset); if (result < 0) { LOG(4, (KERN_WARNING "VMware hgfs: HgfsDoWritepage: write error %d\n", result)); goto out; } remainingCount -= result; curOffset += result; pageFrom += result; /* Update the inode's size now rather than waiting for a revalidate. */ if (curOffset > compat_i_size_read(inode)) { compat_i_size_write(inode, curOffset); } } while ((result > 0) && (remainingCount > 0)); result = 0; out: return result; } /* * HGFS address space operations. */ /* *----------------------------------------------------------------------------- * * HgfsReadpage -- * * Read a page from an open file. Like HgfsWritepage, there are some * complicated locking rules governing this function. The page arrives from * the VFS locked, and we must unlock it before exiting. In addition, we * must acquire a reference to the page before mapping it, and we must * flush the page's data from the data cache (not to be confused with * dcache i.e. the dentry cache). * * Results: * Zero on success, non-zero on error. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int HgfsReadpage(struct file *file, // IN: File to read from struct page *page) // IN/OUT: Page to write to { int result = 0; HgfsHandle handle; ASSERT(file); ASSERT(file->f_dentry); ASSERT(file->f_dentry->d_inode); ASSERT(page); handle = FILE_GET_FI_P(file)->handle; LOG(6, (KERN_WARNING "VMware hgfs: HgfsReadPage: reading from handle %u\n", handle)); page_cache_get(page); result = HgfsDoReadpage(handle, page, 0, PAGE_CACHE_SIZE); page_cache_release(page); compat_unlock_page(page); return result; } /* *----------------------------------------------------------------------------- * * HgfsWritepage -- * * The "spontaneous" way to write a page, called when the kernel is under * memory pressure or is asked to sync a memory mapped file. Because * writepage() can be called from so many different places, we don't get a * filp with which to write, and we have to be very careful about races and * locking. * * Results: * Zero on success, non-zero on error. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int HgfsWritepage(struct page *page, // IN: Page to write from struct writeback_control *wbc) // IN: Ignored { struct inode *inode; HgfsHandle handle; int result; pgoff_t lastPageIndex; loff_t currentFileSize; unsigned to = PAGE_CACHE_SIZE; ASSERT(page); ASSERT(page->mapping); ASSERT(page->mapping->host); inode = page->mapping->host; /* We need a writable file handle. */ result = HgfsGetHandle(inode, HGFS_OPEN_MODE_WRITE_ONLY + 1, &handle); if (result) { LOG(4, (KERN_WARNING "VMware hgfs: HgfsWritepage: could not get writable " "file handle\n")); goto exit; } /* * We were given an entire page to write. In most cases this means "start * writing from the beginning of the page (byte 0) to the very end (byte * PAGE_CACHE_SIZE). But what if this is the last page of the file? Then * we don't want to write a full PAGE_CACHE_SIZE bytes, but just however * many bytes may remain in the page. * * XXX: Other filesystems check the page index to make sure that the page * we're being asked to write is within the size of the file. I guess * that's because writepage() can race with truncate(), and if we find * ourselves here after a truncate(), we can drop the write. */ currentFileSize = compat_i_size_read(inode); lastPageIndex = currentFileSize >> PAGE_CACHE_SHIFT; if (page->index > lastPageIndex) { goto exit; } else if (page->index == lastPageIndex) { to = currentFileSize & (PAGE_CACHE_SIZE - 1); if (to == 0) { goto exit; } } /* * This part is fairly intricate, so it deserves some explanation. We're * really interested in calling HgfsDoWritepage with our page and * handle, without having to then worry about locks or references. See * Documentation/filesystems/Locking in the kernel to see what rules we * must obey. * * Firstly, we acquire a reference to the page via page_cache_get() and call * compat_set_page_writeback(). The latter does a number of things: it sets * the writeback bit on the page, and if it wasn't already set, it sets the * writeback bit in the radix tree. Then, if the page isn't dirty, it clears * the dirty bit in the radix tree. The end result is that the radix tree's * notion of dirty and writeback is fully synced with the page itself. * * Secondly, we write the page itself. * * Thirdly, we end writeback of the page via compat_end_page_writeback(), * and release our reference on the page. * * Finally, we unlock the page, waking up its waiters and making it * available to anyone else. Note that this step must be performed * regardless of whether we wrote anything, as the VFS locked the page for * us. */ page_cache_get(page); compat_set_page_writeback(page); result = HgfsDoWritepage(handle, page, 0, to); compat_end_page_writeback(page); page_cache_release(page); exit: compat_unlock_page(page); return result; } /* *----------------------------------------------------------------------------- * * HgfsDoWriteBegin -- * * Helper function for HgfsWriteBegin / HgfsPrepareWrite. * * Initialize the page if the file is to be appended. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void HgfsDoWriteBegin(struct page *page, // IN: Page to be written unsigned pageFrom, // IN: Starting page offset unsigned pageTo) // IN: Ending page offset { loff_t offset; loff_t currentFileSize; ASSERT(page); offset = (loff_t)page->index << PAGE_CACHE_SHIFT; currentFileSize = compat_i_size_read(page->mapping->host); /* * If we are doing a partial write into a new page (beyond end of * file), then intialize it. This allows other writes to this page * to accumulate before we need to write it to the server. */ if ((offset >= currentFileSize) || ((pageFrom == 0) && (offset + pageTo) >= currentFileSize)) { void *kaddr = compat_kmap_atomic(page); if (pageFrom) { memset(kaddr, 0, pageFrom); } if (pageTo < PAGE_CACHE_SIZE) { memset(kaddr + pageTo, 0, PAGE_CACHE_SIZE - pageTo); } compat_kunmap_atomic(kaddr); flush_dcache_page(page); } } #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28) /* *----------------------------------------------------------------------------- * * HgfsPrepareWrite -- * * Called by the generic write path to set up a write request for a page. * We're expected to do any pre-allocation and housekeeping prior to * receiving the write. * * Results: * Always zero. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int HgfsPrepareWrite(struct file *file, // IN: Ignored struct page *page, // IN: Page to prepare unsigned pageFrom, // IN: Beginning page offset unsigned pageTo) // IN: Ending page offset { HgfsDoWriteBegin(page, pageFrom, pageTo); return 0; } #else /* *----------------------------------------------------------------------------- * * HgfsWriteBegin -- * * Called by the generic write path to set up a write request for a page. * We're expected to do any pre-allocation and housekeeping prior to * receiving the write. * * This function is expected to return a locked page. * * Results: * Zero on success, non-zero error otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int HgfsWriteBegin(struct file *file, // IN: File to be written struct address_space *mapping, // IN: Mapping loff_t pos, // IN: File position unsigned len, // IN: Bytes to be written unsigned flags, // IN: Write flags struct page **pagePtr, // OUT: Locked page void **clientData) // OUT: Opaque to pass to write_end, unused { pgoff_t index = pos >> PAGE_CACHE_SHIFT; unsigned pageFrom = pos & (PAGE_CACHE_SHIFT - 1); unsigned pageTo = pos + len; struct page *page; page = compat_grab_cache_page_write_begin(mapping, index, flags); if (page == NULL) { return -ENOMEM; } *pagePtr = page; HgfsDoWriteBegin(page, pageFrom, pageTo); return 0; } #endif /* *----------------------------------------------------------------------------- * * HgfsDoWriteEnd -- * * Helper function for HgfsWriteEnd. * * This function updates the inode->i_size, conditionally marks the page * updated and carries out the actual write in case of partial page writes. * * Results: * Zero on succes, non-zero on error. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int HgfsDoWriteEnd(struct file *file, // IN: File we're writing to struct page *page, // IN: Page we're writing from unsigned pageFrom, // IN: Starting page offset unsigned pageTo, // IN: Ending page offset loff_t writeTo, // IN: File position to write to unsigned copied) // IN: Number of bytes copied to the page { HgfsHandle handle; struct inode *inode; loff_t currentFileSize; loff_t offset; ASSERT(file); ASSERT(page); inode = page->mapping->host; currentFileSize = compat_i_size_read(inode); offset = (loff_t)page->index << PAGE_CACHE_SHIFT; if (writeTo > currentFileSize) { compat_i_size_write(inode, writeTo); } /* We wrote a complete page, so it is up to date. */ if (copied == PAGE_CACHE_SIZE) { SetPageUptodate(page); } /* * Check if this is a partial write to a new page, which was * initialized in HgfsDoWriteBegin. */ if ((offset >= currentFileSize) || ((pageFrom == 0) && (writeTo >= currentFileSize))) { SetPageUptodate(page); } /* * If the page is uptodate, then just mark it dirty and let * the page cache write it when it wants to. */ if (PageUptodate(page)) { set_page_dirty(page); return 0; } /* * We've recieved a partial write to page that is not uptodate, so * do the write now while the page is still locked. Another * alternative would be to read the page in HgfsDoWriteBegin, which * would make it uptodate (ie a complete cached page). */ handle = FILE_GET_FI_P(file)->handle; LOG(6, (KERN_WARNING "VMware hgfs: %s: writing to handle %u\n", __func__, handle)); return HgfsDoWritepage(handle, page, pageFrom, pageTo); } #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28) /* *----------------------------------------------------------------------------- * * HgfsCommitWrite -- * * This function is the more common write path for HGFS, called from * generic_file_buffered_write. It is much simpler for us than * HgfsWritepage above: the caller has obtained a reference to the page * and will unlock it when we're done. And we don't need to worry about * properly marking the writeback bit, either. See mm/filemap.c in the * kernel for details about how we are called. * * Results: * Zero on succes, non-zero on error. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int HgfsCommitWrite(struct file *file, // IN: File to write struct page *page, // IN: Page to write from unsigned pageFrom, // IN: Starting page offset unsigned pageTo) // IN: Ending page offset { loff_t offset; loff_t writeTo; unsigned copied; ASSERT(page); ASSERT(file); offset = (loff_t)page->index << PAGE_CACHE_SHIFT; writeTo = offset + pageTo; copied = pageTo - pageFrom; return HgfsDoWriteEnd(file, page, pageFrom, pageTo, writeTo, copied); } #else /* *----------------------------------------------------------------------------- * * HgfsWriteEnd -- * * This function is the more common write path for HGFS, called from * generic_file_buffered_write. It is much simpler for us than * HgfsWritepage above: write_begin has obtained a reference to the page * and we will unlock it when we're done. And we don't need to worry about * properly marking the writeback bit, either. See mm/filemap.c in the * kernel for details about how we are called. * * This function should unlock the page and reduce the refcount. * * Results: * Number of bytes written or negative error * * Side effects: * Unlocks the page and drops the reference. * *----------------------------------------------------------------------------- */ static int HgfsWriteEnd(struct file *file, // IN: File to write struct address_space *mapping, // IN: Mapping loff_t pos, // IN: File position unsigned len, // IN: len passed from write_begin unsigned copied, // IN: Number of actually copied bytes struct page *page, // IN: Page to write from void *clientData) // IN: From write_begin, unused. { unsigned pageFrom = pos & (PAGE_CACHE_SIZE - 1); unsigned pageTo = pageFrom + copied; loff_t writeTo = pos + copied; int ret; ASSERT(file); ASSERT(mapping); ASSERT(page); ret = HgfsDoWriteEnd(file, page, pageFrom, pageTo, writeTo, copied); if (ret == 0) { ret = copied; } compat_unlock_page(page); page_cache_release(page); return ret; } #endif open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/filesystem.c0000644765153500003110000005140012220061556022070 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * filesystem.c -- * * High-level filesystem operations for the filesystem portion of * the vmhgfs driver. */ /* Must come before any kernel header file. */ #include "driver-config.h" #include #include #include #include #include #include "compat_cred.h" #include "compat_dcache.h" #include "compat_fs.h" #include "compat_kernel.h" #include "compat_sched.h" #include "compat_semaphore.h" #include "compat_slab.h" #include "compat_spinlock.h" #include "compat_string.h" #include "compat_uaccess.h" #include "compat_version.h" #include "filesystem.h" #include "transport.h" #include "hgfsDevLinux.h" #include "hgfsProto.h" #include "hgfsUtil.h" #include "module.h" #include "request.h" #include "fsutil.h" #include "vm_assert.h" #include "vm_basic_types.h" #include "rpcout.h" #include "hgfs.h" /* Synchronization primitives. */ DEFINE_SPINLOCK(hgfsBigLock); /* Other variables. */ compat_kmem_cache *hgfsInodeCache; /* Global protocol version switch. */ HgfsOp hgfsVersionOpen; HgfsOp hgfsVersionRead; HgfsOp hgfsVersionWrite; HgfsOp hgfsVersionClose; HgfsOp hgfsVersionSearchOpen; HgfsOp hgfsVersionSearchRead; HgfsOp hgfsVersionSearchClose; HgfsOp hgfsVersionGetattr; HgfsOp hgfsVersionSetattr; HgfsOp hgfsVersionCreateDir; HgfsOp hgfsVersionDeleteFile; HgfsOp hgfsVersionDeleteDir; HgfsOp hgfsVersionRename; HgfsOp hgfsVersionQueryVolumeInfo; HgfsOp hgfsVersionCreateSymlink; /* Private functions. */ static inline unsigned long HgfsComputeBlockBits(unsigned long blockSize); static compat_kmem_cache_ctor HgfsInodeCacheCtor; static HgfsSuperInfo *HgfsInitSuperInfo(HgfsMountInfo *mountInfo); static int HgfsGetRootDentry(struct super_block *sb, struct dentry **rootDentry); static int HgfsReadSuper(struct super_block *sb, void *rawData, int flags); static void HgfsResetOps(void); /* HGFS filesystem high-level operations. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) static struct dentry *HgfsMount(struct file_system_type *fs_type, int flags, const char *dev_name, void *rawData); #elif defined(VMW_GETSB_2618) static int HgfsGetSb(struct file_system_type *fs_type, int flags, const char *dev_name, void *rawData, struct vfsmount *mnt); #else static struct super_block *HgfsGetSb(struct file_system_type *fs_type, int flags, const char *dev_name, void *rawData); #endif /* HGFS filesystem type structure. */ static struct file_system_type hgfsType = { .owner = THIS_MODULE, .name = HGFS_NAME, .fs_flags = FS_BINARY_MOUNTDATA, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) .mount = HgfsMount, #else .get_sb = HgfsGetSb, #endif .kill_sb = kill_anon_super, }; extern int USE_VMCI; /* * Private functions implementations. */ /* *----------------------------------------------------------------------------- * * HgfsComputeBlockBits -- * * Given a block size, returns the number of bits in the block, rounded * down. This approach of computing the number of bits per block and * saving it for later use is the same used in NFS. * * Results: * The number of bits in the block. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static inline unsigned long HgfsComputeBlockBits(unsigned long blockSize) { uint8 numBits; for (numBits = 31; numBits && !(blockSize & (1 << numBits)); numBits--); return numBits; } /* *----------------------------------------------------------------------------- * * HgfsInodeCacheCtor -- * * Constructor for HGFS inode structures that runs once at slab * allocation. It is called once for each piece of memory that * is used to satisfy HGFS inode allocations; it should only be * used to initialize items that will naturally return to their * initialized state before deallocation (such as locks, list_heads). * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void HgfsInodeCacheCtor(COMPAT_KMEM_CACHE_CTOR_ARGS(slabElem)) // IN: slab item to initialize { HgfsInodeInfo *iinfo = (HgfsInodeInfo *)slabElem; /* * VFS usually calls this as part of allocating inodes for us, but since * we're doing the allocation now, we need to call it. It'll set up * much of the VFS inode members. */ inode_init_once(&iinfo->inode); } /* *---------------------------------------------------------------------- * * HgfsInitSuperInfo -- * * Allocate and initialize a new HgfsSuperInfo object * * Results: * Returns a new HgfsSuperInfo object with all its fields initialized, * or an error code cast as a pointer. * * Side effects: * None * *---------------------------------------------------------------------- */ static HgfsSuperInfo * HgfsInitSuperInfo(HgfsMountInfo *mountInfo) // IN: Passed down from the user { HgfsSuperInfo *si = NULL; int result = 0; int len; char *tmpName; Bool hostValid; si = kmalloc(sizeof *si, GFP_KERNEL); if (!si) { result = -ENOMEM; goto out2; } /* * If the mounter specified a uid or gid, we will prefer them over any uid * or gid given to us by the server. */ si->uidSet = mountInfo->uidSet; if (si->uidSet) { si->uid = mountInfo->uid; } else { si->uid = current_uid(); } si->gidSet = mountInfo->gidSet; if (si->gidSet) { si->gid = mountInfo->gid; } else { si->gid = current_gid(); } si->fmask = mountInfo->fmask; si->dmask = mountInfo->dmask; si->ttl = mountInfo->ttl * HZ; // in ticks /* * We don't actually care about this field (though we may care in the * future). For now, just make sure it is set to ".host" as a sanity check. * * We can't call getname() directly because on certain kernels we can't call * putname() directly. For more details, see the change description of * change 464782 or the second comment in bug 159623, which fixed the same * problem for vmblock. */ tmpName = compat___getname(); if (!tmpName) { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsInitSuperInfo: could not obtain " "memory for filename\n")); result = -ENOMEM; goto out2; } len = strncpy_from_user(tmpName, mountInfo->shareNameHost, PATH_MAX); if (len < 0 || len >= PATH_MAX) { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsInitSuperInfo: strncpy_from_user " "on host string failed\n")); result = len < 0 ? len : -ENAMETOOLONG; goto out; } hostValid = strcmp(tmpName, ".host") == 0; if (!hostValid) { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsInitSuperInfo: host string is " "invalid\n")); result = -EINVAL; goto out; } /* * Perform a simple sanity check on the directory portion: it must begin * with forward slash. */ len = strncpy_from_user(tmpName, mountInfo->shareNameDir, PATH_MAX); if (len < 0 || len >= PATH_MAX) { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsInitSuperInfo: strncpy_from_user " "on dir string failed\n")); result = len < 0 ? len : -ENAMETOOLONG; goto out; } if (*tmpName != '/') { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsInitSuperInfo: dir string is " "invalid\n")); result = -EINVAL; goto out; } /* * The SELinux audit subsystem will delay the putname() of a string until * the end of a system call so that it may be audited at any point. At that * time, it also unconditionally calls putname() on every string allocated * by getname(). * * This means we can't safely retain strings allocated by getname() beyond * the syscall boundary. So after getting the string, use kstrdup() to * duplicate it, and store that (audit-safe) result in the SuperInfo struct. */ si->shareName = compat_kstrdup(tmpName, GFP_KERNEL); if (si->shareName == NULL) { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsInitSuperInfo: kstrdup on " "dir string failed\n")); result = -ENOMEM; goto out; } si->shareNameLen = strlen(si->shareName); out: compat___putname(tmpName); out2: if (result) { /* If we failed, si->shareName couldn't have been allocated. */ kfree(si); si = ERR_PTR(result); } return si; } /* *---------------------------------------------------------------------------- * * HgfsGetRootDentry -- * * Gets the root dentry for a given super block. * * Results: * zero and a valid root dentry on success * negative value on failure * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsGetRootDentry(struct super_block *sb, // IN: Super block object struct dentry **rootDentry) // OUT: Root dentry { int result = -ENOMEM; struct inode *rootInode; struct dentry *tempRootDentry = NULL; struct HgfsAttrInfo rootDentryAttr; HgfsInodeInfo *iinfo; ASSERT(sb); ASSERT(rootDentry); LOG(6, (KERN_DEBUG "VMware hgfs: %s: entered\n", __func__)); rootInode = HgfsGetInode(sb, HGFS_ROOT_INO); if (rootInode == NULL) { LOG(6, (KERN_DEBUG "VMware hgfs: %s: Could not get the root inode\n", __func__)); goto exit; } /* * On an allocation failure in read_super, the inode will have been * marked "bad". If it was, we certainly don't want to start playing with * the HgfsInodeInfo. So quietly put the inode back and fail. */ if (is_bad_inode(rootInode)) { LOG(6, (KERN_DEBUG "VMware hgfs: %s: encountered bad inode\n", __func__)); goto exit; } tempRootDentry = d_make_root(rootInode); /* * d_make_root() does iput() on failure; if d_make_root() completes * successfully then subsequent dput() will do iput() for us, so we * should just ignore root inode from now on. */ rootInode = NULL; if (tempRootDentry == NULL) { LOG(4, (KERN_WARNING "VMware hgfs: %s: Could not get " "root dentry\n", __func__)); goto exit; } result = HgfsPrivateGetattr(tempRootDentry, &rootDentryAttr, NULL); if (result) { LOG(4, (KERN_WARNING "VMware hgfs: HgfsReadSuper: Could not" "instantiate the root dentry\n")); goto exit; } iinfo = INODE_GET_II_P(tempRootDentry->d_inode); iinfo->isFakeInodeNumber = FALSE; iinfo->isReferencedInode = TRUE; if (rootDentryAttr.mask & HGFS_ATTR_VALID_FILEID) { iinfo->hostFileId = rootDentryAttr.hostFileId; } HgfsChangeFileAttributes(tempRootDentry->d_inode, &rootDentryAttr); HgfsDentryAgeReset(tempRootDentry); tempRootDentry->d_op = &HgfsDentryOperations; *rootDentry = tempRootDentry; result = 0; LOG(6, (KERN_DEBUG "VMware hgfs: %s: finished\n", __func__)); exit: if (result) { iput(rootInode); dput(tempRootDentry); *rootDentry = NULL; } return result; } /* *----------------------------------------------------------------------------- * * HgfsReadSuper -- * * The main entry point of the filesystem side of the driver. Called when * a userland process does a mount(2) of an hgfs filesystem. This makes the * whole driver transition from its initial state to state 1. Fill the * content of the uninitialized superblock provided by the kernel. * * 'rawData' is a pointer (that can be NULL) to a kernel buffer (whose * size is <= PAGE_SIZE) that corresponds to the filesystem-specific 'data' * argument passed to mount(2). * * Results: * zero and initialized superblock on success * negative value on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ static int HgfsReadSuper(struct super_block *sb, // OUT: Superblock object void *rawData, // IN: Fs-specific mount data int flags) // IN: Mount flags { int result = 0; HgfsSuperInfo *si; HgfsMountInfo *mountInfo; struct dentry *rootDentry = NULL; ASSERT(sb); LOG(6, (KERN_DEBUG "VMware hgfs: HgfsReadSuper: entered\n")); /* Sanity check the incoming user data. */ mountInfo = (HgfsMountInfo *)rawData; if (!mountInfo || mountInfo->magicNumber != HGFS_SUPER_MAGIC || mountInfo->version != HGFS_PROTOCOL_VERSION) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsReadSuper: bad mount data passed " "in by user, failing!\n")); return -EINVAL; } /* Setup both our superblock and the VFS superblock. */ si = HgfsInitSuperInfo(mountInfo); if (IS_ERR(si)) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsReadSuper: superinfo " "init failed\n")); return PTR_ERR(si); } HGFS_SET_SB_TO_COMMON(sb, si); sb->s_magic = HGFS_SUPER_MAGIC; sb->s_op = &HgfsSuperOperations; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) sb->s_d_op = &HgfsDentryOperations; #endif /* * If s_maxbytes isn't initialized, the generic write path may fail. In * most kernels, s_maxbytes is initialized by the kernel's superblock * allocation routines, but in some, it's up to the filesystem to initialize * it. Note that we'll initialize it anyway, because the default value is * MAX_NON_LFS, which caps our filesize at 2^32 bytes. */ sb->s_maxbytes = MAX_LFS_FILESIZE; /* * These two operations will make sure that our block size and the bits * per block match up, no matter what HGFS_BLOCKSIZE may be. Granted, * HGFS_BLOCKSIZE will always be a power of two, but you never know! */ sb->s_blocksize_bits = HgfsComputeBlockBits(HGFS_BLOCKSIZE); sb->s_blocksize = 1 << sb->s_blocksize_bits; result = HgfsGetRootDentry(sb, &rootDentry); if (result) { LOG(4, (KERN_WARNING "VMware hgfs: HgfsReadSuper: Could not instantiate " "root dentry\n")); goto exit; } sb->s_root = rootDentry; LOG(6, (KERN_DEBUG "VMware hgfs: HgfsReadSuper: finished %s\n", si->shareName)); exit: if (result) { dput(rootDentry); kfree(si->shareName); kfree(si); } return result; } /* * HGFS filesystem high-level operations. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) /* *----------------------------------------------------------------------------- * * HgfsMount -- * * Invokes generic kernel code to mount a deviceless filesystem. * * Results: * Mount's root dentry structure on success * ERR_PTR()-encoded negative error code on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ struct dentry * HgfsMount(struct file_system_type *fs_type, // IN: file system type of mount int flags, // IN: mount flags const char *dev_name, // IN: device mounting on void *rawData) // IN: mount arguments { return mount_nodev(fs_type, flags, rawData, HgfsReadSuper); } #elif defined VMW_GETSB_2618 /* *----------------------------------------------------------------------------- * * HgfsGetSb -- * * Invokes generic kernel code to prepare superblock for * deviceless filesystem. * * Results: * 0 on success * non-zero on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ static int HgfsGetSb(struct file_system_type *fs_type, int flags, const char *dev_name, void *rawData, struct vfsmount *mnt) { return get_sb_nodev(fs_type, flags, rawData, HgfsReadSuper, mnt); } #else /* *----------------------------------------------------------------------------- * * HgfsGetSb -- * * Invokes generic kernel code to prepare superblock for * deviceless filesystem. * * Results: * The initialized superblock on success * NULL on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ static struct super_block * HgfsGetSb(struct file_system_type *fs_type, int flags, const char *dev_name, void *rawData) { return get_sb_nodev(fs_type, flags, rawData, HgfsReadSuper); } #endif /* *----------------------------------------------------------------------------- * * HgfsResetOps -- * * Reset ops with more than one opcode back to the desired opcode. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void HgfsResetOps(void) { hgfsVersionOpen = HGFS_OP_OPEN_V3; hgfsVersionRead = HGFS_OP_READ_V3; hgfsVersionWrite = HGFS_OP_WRITE_V3; hgfsVersionClose = HGFS_OP_CLOSE_V3; hgfsVersionSearchOpen = HGFS_OP_SEARCH_OPEN_V3; hgfsVersionSearchRead = HGFS_OP_SEARCH_READ_V3; hgfsVersionSearchClose = HGFS_OP_SEARCH_CLOSE_V3; hgfsVersionGetattr = HGFS_OP_GETATTR_V3; hgfsVersionSetattr = HGFS_OP_SETATTR_V3; hgfsVersionCreateDir = HGFS_OP_CREATE_DIR_V3; hgfsVersionDeleteFile = HGFS_OP_DELETE_FILE_V3; hgfsVersionDeleteDir = HGFS_OP_DELETE_DIR_V3; hgfsVersionRename = HGFS_OP_RENAME_V3; hgfsVersionQueryVolumeInfo = HGFS_OP_QUERY_VOLUME_INFO_V3; hgfsVersionCreateSymlink = HGFS_OP_CREATE_SYMLINK_V3; if (USE_VMCI) { hgfsVersionRead = HGFS_OP_READ_FAST_V4; hgfsVersionWrite = HGFS_OP_WRITE_FAST_V4; } } /* * Public function implementations. */ /* *----------------------------------------------------------------------------- * * HgfsInitFileSystem -- * * Initializes the file system and registers it with the kernel. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsInitFileSystem(void) { /* Initialize primitives. */ HgfsResetOps(); /* Setup the inode slab allocator. */ hgfsInodeCache = compat_kmem_cache_create("hgfsInodeCache", sizeof (HgfsInodeInfo), 0, SLAB_HWCACHE_ALIGN, HgfsInodeCacheCtor); if (hgfsInodeCache == NULL) { printk(KERN_WARNING "VMware hgfs: failed to create inode allocator\n"); return FALSE; } /* Initialize the transport. */ HgfsTransportInit(); /* * Register the filesystem. This should be the last thing we do * in init_module. */ if (register_filesystem(&hgfsType)) { printk(KERN_WARNING "VMware hgfs: failed to register filesystem\n"); kmem_cache_destroy(hgfsInodeCache); return FALSE; } LOG(4, (KERN_DEBUG "VMware hgfs: Module Loaded\n")); return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsCleanupFileSystem -- * * Cleans up file system and unregisters it with the kernel. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsCleanupFileSystem(void) { Bool success = TRUE; /* * Unregister the filesystem. This should be the first thing we do in * the module cleanup code. */ if (unregister_filesystem(&hgfsType)) { printk(KERN_WARNING "VMware hgfs: failed to unregister filesystem\n"); success = FALSE; } /* Transport cleanup. */ HgfsTransportExit(); /* Destroy the inode and request slabs. */ kmem_cache_destroy(hgfsInodeCache); LOG(4, (KERN_DEBUG "VMware hgfs: Module Unloaded\n")); return success; } open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/inode.h0000644765153500003110000000244612220061556021015 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * inode.h -- * * Inode operations for the filesystem portion of the vmhgfs driver. */ #ifndef _HGFS_DRIVER_INODE_H_ #define _HGFS_DRIVER_INODE_H_ /* Must come before any kernel header file. */ #include "driver-config.h" #include "compat_fs.h" /* Public functions (with respect to the entire module). */ int HgfsSetattr(struct dentry *dentry, struct iattr *iattr); int HgfsRevalidate(struct dentry *dentry); #endif // _HGFS_DRIVER_INODE_H_ open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/inode.c0000644765153500003110000021066712220061556021016 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * inode.c -- * * Inode operations for the filesystem portion of the vmhgfs driver. */ /* Must come before any kernel header file. */ #include "driver-config.h" #include #include #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) #include #endif #include #include "compat_cred.h" #include "compat_fs.h" #include "compat_kernel.h" #include "compat_mm.h" #include "compat_page-flags.h" #include "compat_spinlock.h" #include "compat_version.h" #include "cpName.h" #include "cpNameLite.h" #include "hgfsProto.h" #include "hgfsUtil.h" #include "inode.h" #include "module.h" #include "request.h" #include "fsutil.h" #include "vm_assert.h" /* Private functions. */ static int HgfsDelete(struct inode *dir, struct dentry *dentry, HgfsOp op); static int HgfsPackSetattrRequest(struct iattr *iattr, struct dentry *dentry, Bool allowHandleReuse, HgfsOp opUsed, HgfsReq *req, Bool *changed); static int HgfsPackCreateDirRequest(struct dentry *dentry, compat_umode_t mode, HgfsOp opUsed, HgfsReq *req); static int HgfsTruncatePages(struct inode *inode, loff_t newSize); static int HgfsPackSymlinkCreateRequest(struct dentry *dentry, const char *symname, HgfsOp opUsed, HgfsReq *req); /* HGFS inode operations. */ static int HgfsCreate(struct inode *dir, struct dentry *dentry, compat_umode_t mode, #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) bool excl #else struct nameidata *nd #endif ); static struct dentry *HgfsLookup(struct inode *dir, struct dentry *dentry, #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) unsigned int flags #else struct nameidata *nd #endif ); static int HgfsMkdir(struct inode *dir, struct dentry *dentry, compat_umode_t mode); static int HgfsRmdir(struct inode *dir, struct dentry *dentry); static int HgfsUnlink(struct inode *dir, struct dentry *dentry); static int HgfsRename(struct inode *oldDir, struct dentry *oldDentry, struct inode *newDir, struct dentry *newDentry); static int HgfsSymlink(struct inode *dir, struct dentry *dentry, const char *symname); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) static int HgfsPermission(struct inode *inode, int mask, struct nameidata *nameidata); #elif defined(IPERM_FLAG_RCU) static int HgfsPermission(struct inode *inode, int mask, unsigned int flags); #else static int HgfsPermission(struct inode *inode, int mask); #endif static int HgfsGetattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); #define HGFS_CREATE_DIR_MASK (HGFS_CREATE_DIR_VALID_FILE_NAME | \ HGFS_CREATE_DIR_VALID_SPECIAL_PERMS | \ HGFS_CREATE_DIR_VALID_OWNER_PERMS | \ HGFS_CREATE_DIR_VALID_GROUP_PERMS | \ HGFS_CREATE_DIR_VALID_OTHER_PERMS) /* HGFS inode operations structure for directories. */ struct inode_operations HgfsDirInodeOperations = { /* Optional */ .create = HgfsCreate, /* Optional */ .mkdir = HgfsMkdir, .lookup = HgfsLookup, .rmdir = HgfsRmdir, .unlink = HgfsUnlink, .rename = HgfsRename, .symlink = HgfsSymlink, .permission = HgfsPermission, .setattr = HgfsSetattr, /* Optional */ .getattr = HgfsGetattr, }; /* HGFS inode operations structure for files. */ struct inode_operations HgfsFileInodeOperations = { .permission = HgfsPermission, .setattr = HgfsSetattr, /* Optional */ .getattr = HgfsGetattr, }; /* * Private functions implementations. */ /* *---------------------------------------------------------------------- * * HgfsDelete -- * * Handle both unlink and rmdir requests. * * Results: * Returns zero on success, or a negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsDelete(struct inode *dir, // IN: Parent dir of file/dir to delete struct dentry *dentry, // IN: Dentry of file/dir to delete HgfsOp op) // IN: Opcode for file type (file or dir) { HgfsReq *req = NULL; int result = 0; Bool secondAttempt = FALSE; HgfsStatus replyStatus; char *fileName = NULL; uint32 *fileNameLength; uint32 reqSize; HgfsOp opUsed; ASSERT(dir); ASSERT(dir->i_sb); ASSERT(dentry); ASSERT(dentry->d_inode); if (!dir || !dentry) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDelete: NULL input\n")); result = -EFAULT; goto out; } if ((op != HGFS_OP_DELETE_FILE) && (op != HGFS_OP_DELETE_DIR)) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDelete: Invalid opcode\n")); result = -EINVAL; goto out; } req = HgfsGetNewRequest(); if (!req) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDelete: out of memory while " "getting new request\n")); result = -ENOMEM; goto out; } retry: if (op == HGFS_OP_DELETE_FILE) { opUsed = hgfsVersionDeleteFile; } else { opUsed = hgfsVersionDeleteDir; } if (opUsed == HGFS_OP_DELETE_FILE_V3 || opUsed == HGFS_OP_DELETE_DIR_V3) { HgfsRequestDeleteV3 *request; HgfsRequest *header; header = (HgfsRequest *)(HGFS_REQ_PAYLOAD(req)); header->id = req->id; header->op = opUsed; request = (HgfsRequestDeleteV3 *)(HGFS_REQ_PAYLOAD_V3(req)); request->hints = 0; fileName = request->fileName.name; fileNameLength = &request->fileName.length; request->fileName.fid = HGFS_INVALID_HANDLE; request->fileName.flags = 0; request->fileName.caseType = HGFS_FILE_NAME_DEFAULT_CASE; request->reserved = 0; reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); } else { HgfsRequestDelete *request; request = (HgfsRequestDelete *)(HGFS_REQ_PAYLOAD(req)); /* Fill out the request packet. */ request->header.id = req->id; request->header.op = opUsed; fileName = request->fileName.name; fileNameLength = &request->fileName.length; reqSize = sizeof *request; } /* Build full name to send to server. */ if (HgfsBuildPath(fileName, HGFS_NAME_BUFFER_SIZET(req->bufferSize, reqSize), dentry) < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDelete: build path failed\n")); result = -EINVAL; goto out; } LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDelete: deleting \"%s\", opUsed %u\n", fileName, opUsed)); /* Convert to CP name. */ result = CPName_ConvertTo(fileName, HGFS_NAME_BUFFER_SIZET(req->bufferSize, reqSize), fileName); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDelete: CP conversion failed\n")); result = -EINVAL; goto out; } *fileNameLength = result; req->payloadSize = reqSize + result; result = HgfsSendRequest(req); if (result == 0) { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsDelete: got reply\n")); replyStatus = HgfsReplyStatus(req); result = HgfsStatusConvertToLinux(replyStatus); switch (result) { case 0: /* * Since we deleted the file, decrement its hard link count. As * we don't support hard links, this has the effect of making the * link count 0, which means that when the last reference to the * inode is dropped, the inode will be freed instead of moved to * the unused list. * * Also update the mtime/ctime of the parent directory, and the * ctime of the deleted file. */ compat_drop_nlink(dentry->d_inode); dentry->d_inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; break; case -EACCES: case -EPERM: /* * It's possible that we're talking to a Windows server with * a file marked read-only. Let's try again, after removing * the read-only bit from the file. * * XXX: I think old servers will send -EPERM here. Is this entirely * safe? */ if (!secondAttempt) { struct iattr enableWrite; secondAttempt = TRUE; LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDelete: access denied, " "attempting to work around read-only bit\n")); enableWrite.ia_mode = (dentry->d_inode->i_mode | S_IWUSR); enableWrite.ia_valid = ATTR_MODE; result = HgfsSetattr(dentry, &enableWrite); if (result == 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDelete: file is no " "longer read-only, retrying delete\n")); goto retry; } LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDelete: failed to remove " "read-only property\n")); } else { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDelete: second attempt at " "delete failed\n")); } break; case -EPROTO: /* Retry with older version(s). Set globally. */ if (opUsed == HGFS_OP_DELETE_DIR_V3) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDelete: Version 3 not " "supported. Falling back to version 1.\n")); hgfsVersionDeleteDir = HGFS_OP_DELETE_DIR; goto retry; } else if (opUsed == HGFS_OP_DELETE_FILE_V3) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDelete: Version 3 not " "supported. Falling back to version 1.\n")); hgfsVersionDeleteFile = HGFS_OP_DELETE_FILE; goto retry; } LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDelete: server " "returned error: %d\n", result)); break; default: break; } } else if (result == -EIO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDelete: timed out\n")); } else if (result == -EPROTO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDelete: server " "returned error: %d\n", result)); } else { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDelete: unknown error: " "%d\n", result)); } out: HgfsFreeRequest(req); return result; } /* *---------------------------------------------------------------------- * * HgfsPackSetattrRequest -- * * Setup the Setattr request, depending on the op version. When possible, * we will issue the setattr request using an existing open HGFS handle. * * Results: * Returns zero on success, or negative error on failure. * * On success, the changed argument is set indicating whether the * attributes have actually changed. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsPackSetattrRequest(struct iattr *iattr, // IN: Inode attrs to update from struct dentry *dentry, // IN: File to set attributes of Bool allowHandleReuse, // IN: Can we use a handle? HgfsOp opUsed, // IN: Op to be used HgfsReq *req, // IN/OUT: Packet to write into Bool *changed) // OUT: Have the attrs changed? { HgfsAttrV2 *attrV2; HgfsAttr *attr; HgfsAttrHint *hints; HgfsAttrChanges *update; HgfsHandle handle; char *fileName = NULL; uint32 *fileNameLength = NULL; unsigned int valid; size_t reqBufferSize; size_t reqSize; int result = 0; ASSERT(iattr); ASSERT(dentry); ASSERT(req); ASSERT(changed); valid = iattr->ia_valid; switch (opUsed) { case HGFS_OP_SETATTR_V3: { HgfsRequest *requestHeader; HgfsRequestSetattrV3 *requestV3; requestHeader = (HgfsRequest *)(HGFS_REQ_PAYLOAD(req)); requestHeader->op = opUsed; requestHeader->id = req->id; requestV3 = (HgfsRequestSetattrV3 *)HGFS_REQ_PAYLOAD_V3(req); attrV2 = &requestV3->attr; hints = &requestV3->hints; /* * Clear attributes, mask, and hints before touching them. * We can't rely on GetNewRequest() to zero our structures, so * make sure to zero them all here. */ memset(attrV2, 0, sizeof *attrV2); memset(hints, 0, sizeof *hints); /* * When possible, issue a setattr using an existing handle. This will * give us slightly better performance on a Windows server, and is more * correct regardless. If we don't find a handle, fall back on setattr * by name. * * Changing the size (via truncate) requires write permissions. Changing * the times also requires write permissions on Windows, so we require it * here too. Otherwise, any handle will do. */ if (allowHandleReuse && HgfsGetHandle(dentry->d_inode, (valid & ATTR_SIZE) || (valid & ATTR_ATIME) || (valid & ATTR_MTIME) ? HGFS_OPEN_MODE_WRITE_ONLY + 1 : 0, &handle) == 0) { requestV3->fileName.fid = handle; requestV3->fileName.flags = HGFS_FILE_NAME_USE_FILE_DESC; requestV3->fileName.caseType = HGFS_FILE_NAME_DEFAULT_CASE; requestV3->fileName.length = 0; LOG(6, (KERN_DEBUG "VMware hgfs: HgfsPackSetattrRequest: setting " "attributes of handle %u\n", handle)); } else { fileName = requestV3->fileName.name; fileNameLength = &requestV3->fileName.length; requestV3->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; requestV3->fileName.fid = HGFS_INVALID_HANDLE; requestV3->fileName.flags = 0; } requestV3->reserved = 0; reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(requestV3); reqBufferSize = HGFS_NAME_BUFFER_SIZET(req->bufferSize, reqSize); /* * We only support changing these attributes: * - all mode bits (i.e. all permissions) * - uid/gid * - size * - access/write times */ if (valid & ATTR_MODE) { attrV2->mask |= HGFS_ATTR_VALID_SPECIAL_PERMS | HGFS_ATTR_VALID_OWNER_PERMS | HGFS_ATTR_VALID_GROUP_PERMS | HGFS_ATTR_VALID_OTHER_PERMS; attrV2->specialPerms = ((iattr->ia_mode & (S_ISUID | S_ISGID | S_ISVTX)) >> 9); attrV2->ownerPerms = ((iattr->ia_mode & S_IRWXU) >> 6); attrV2->groupPerms = ((iattr->ia_mode & S_IRWXG) >> 3); attrV2->otherPerms = (iattr->ia_mode & S_IRWXO); *changed = TRUE; } if (valid & ATTR_UID) { attrV2->mask |= HGFS_ATTR_VALID_USERID; attrV2->userId = iattr->ia_uid; *changed = TRUE; } if (valid & ATTR_GID) { attrV2->mask |= HGFS_ATTR_VALID_GROUPID; attrV2->groupId = iattr->ia_gid; *changed = TRUE; } if (valid & ATTR_SIZE) { attrV2->mask |= HGFS_ATTR_VALID_SIZE; attrV2->size = iattr->ia_size; *changed = TRUE; } if (valid & ATTR_ATIME) { attrV2->mask |= HGFS_ATTR_VALID_ACCESS_TIME; attrV2->accessTime = HGFS_GET_TIME(iattr->ia_atime); if (valid & ATTR_ATIME_SET) { *hints |= HGFS_ATTR_HINT_SET_ACCESS_TIME; } *changed = TRUE; } if (valid & ATTR_MTIME) { attrV2->mask |= HGFS_ATTR_VALID_WRITE_TIME; attrV2->writeTime = HGFS_GET_TIME(iattr->ia_mtime); if (valid & ATTR_MTIME_SET) { *hints |= HGFS_ATTR_HINT_SET_WRITE_TIME; } *changed = TRUE; } break; } case HGFS_OP_SETATTR_V2: { HgfsRequestSetattrV2 *requestV2; requestV2 = (HgfsRequestSetattrV2 *)(HGFS_REQ_PAYLOAD(req)); requestV2->header.op = opUsed; requestV2->header.id = req->id; attrV2 = &requestV2->attr; hints = &requestV2->hints; /* * Clear attributes, mask, and hints before touching them. * We can't rely on GetNewRequest() to zero our structures, so * make sure to zero them all here. */ memset(attrV2, 0, sizeof *attrV2); memset(hints, 0, sizeof *hints); /* * When possible, issue a setattr using an existing handle. This will * give us slightly better performance on a Windows server, and is more * correct regardless. If we don't find a handle, fall back on setattr * by name. * * Changing the size (via truncate) requires write permissions. Changing * the times also requires write permissions on Windows, so we require it * here too. Otherwise, any handle will do. */ if (allowHandleReuse && HgfsGetHandle(dentry->d_inode, (valid & ATTR_SIZE) || (valid & ATTR_ATIME) || (valid & ATTR_MTIME) ? HGFS_OPEN_MODE_WRITE_ONLY + 1 : 0, &handle) == 0) { *hints = HGFS_ATTR_HINT_USE_FILE_DESC; requestV2->file = handle; LOG(6, (KERN_DEBUG "VMware hgfs: HgfsPackSetattrRequest: setting " "attributes of handle %u\n", handle)); } else { fileName = requestV2->fileName.name; fileNameLength = &requestV2->fileName.length; } reqSize = sizeof *requestV2; reqBufferSize = HGFS_NAME_BUFFER_SIZE(req->bufferSize, requestV2); /* * We only support changing these attributes: * - all mode bits (i.e. all permissions) * - uid/gid * - size * - access/write times */ if (valid & ATTR_MODE) { attrV2->mask |= HGFS_ATTR_VALID_SPECIAL_PERMS | HGFS_ATTR_VALID_OWNER_PERMS | HGFS_ATTR_VALID_GROUP_PERMS | HGFS_ATTR_VALID_OTHER_PERMS; attrV2->specialPerms = ((iattr->ia_mode & (S_ISUID | S_ISGID | S_ISVTX)) >> 9); attrV2->ownerPerms = ((iattr->ia_mode & S_IRWXU) >> 6); attrV2->groupPerms = ((iattr->ia_mode & S_IRWXG) >> 3); attrV2->otherPerms = (iattr->ia_mode & S_IRWXO); *changed = TRUE; } if (valid & ATTR_UID) { attrV2->mask |= HGFS_ATTR_VALID_USERID; attrV2->userId = iattr->ia_uid; *changed = TRUE; } if (valid & ATTR_GID) { attrV2->mask |= HGFS_ATTR_VALID_GROUPID; attrV2->groupId = iattr->ia_gid; *changed = TRUE; } if (valid & ATTR_SIZE) { attrV2->mask |= HGFS_ATTR_VALID_SIZE; attrV2->size = iattr->ia_size; *changed = TRUE; } if (valid & ATTR_ATIME) { attrV2->mask |= HGFS_ATTR_VALID_ACCESS_TIME; attrV2->accessTime = HGFS_GET_TIME(iattr->ia_atime); if (valid & ATTR_ATIME_SET) { *hints |= HGFS_ATTR_HINT_SET_ACCESS_TIME; } *changed = TRUE; } if (valid & ATTR_MTIME) { attrV2->mask |= HGFS_ATTR_VALID_WRITE_TIME; attrV2->writeTime = HGFS_GET_TIME(iattr->ia_mtime); if (valid & ATTR_MTIME_SET) { *hints |= HGFS_ATTR_HINT_SET_WRITE_TIME; } *changed = TRUE; } break; } case HGFS_OP_SETATTR: { HgfsRequestSetattr *request; request = (HgfsRequestSetattr *)(HGFS_REQ_PAYLOAD(req)); request->header.op = opUsed; request->header.id = req->id; attr = &request->attr; update = &request->update; /* We'll use these later. */ fileName = request->fileName.name; fileNameLength = &request->fileName.length; reqSize = sizeof *request; reqBufferSize = HGFS_NAME_BUFFER_SIZE(req->bufferSize, request); /* * Clear attributes before touching them. * We can't rely on GetNewRequest() to zero our structures, so * make sure to zero them all here. */ memset(attr, 0, sizeof *attr); memset(update, 0, sizeof *update); /* * We only support changing these attributes: * - owner mode bits (i.e. owner permissions) * - size * - access/write times */ if (valid & ATTR_MODE) { *update |= HGFS_ATTR_PERMISSIONS; attr->permissions = ((iattr->ia_mode & S_IRWXU) >> 6); *changed = TRUE; } if (valid & ATTR_SIZE) { *update |= HGFS_ATTR_SIZE; attr->size = iattr->ia_size; *changed = TRUE; } if (valid & ATTR_ATIME) { *update |= HGFS_ATTR_ACCESS_TIME | ((valid & ATTR_ATIME_SET) ? HGFS_ATTR_ACCESS_TIME_SET : 0); attr->accessTime = HGFS_GET_TIME(iattr->ia_atime); *changed = TRUE; } if (valid & ATTR_MTIME) { *update |= HGFS_ATTR_WRITE_TIME | ((valid & ATTR_MTIME_SET) ? HGFS_ATTR_WRITE_TIME_SET : 0); attr->writeTime = HGFS_GET_TIME(iattr->ia_mtime); *changed = TRUE; } break; } default: LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackSetattrRequest: unexpected " "OP type encountered\n")); return -EPROTO; } /* Avoid all this extra work when we're doing a setattr by handle. */ if (fileName != NULL) { /* Build full name to send to server. */ if (HgfsBuildPath(fileName, reqBufferSize, dentry) < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackSetattrRequest: build path " "failed\n")); return -EINVAL; } LOG(6, (KERN_DEBUG "VMware hgfs: HgfsPackSetattrRequest: setting " "attributes of \"%s\"\n", fileName)); /* Convert to CP name. */ result = CPName_ConvertTo(fileName, reqBufferSize, fileName); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackSetattrRequest: CP " "conversion failed\n")); return -EINVAL; } *fileNameLength = result; } req->payloadSize = reqSize + result; return 0; } /* *---------------------------------------------------------------------- * * HgfsPackCreateDirRequest -- * * Setup the CreateDir request, depending on the op version. * * Results: * Returns zero on success, or negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsPackCreateDirRequest(struct dentry *dentry, // IN: Directory to create compat_umode_t mode, // IN: Mode to assign dir HgfsOp opUsed, // IN: Op to be used. HgfsReq *req) // IN/OUT: Packet to write into { char *fileName = NULL; uint32 *fileNameLength; size_t requestSize; int result; ASSERT(dentry); ASSERT(req); switch (opUsed) { case HGFS_OP_CREATE_DIR_V3: { HgfsRequest *requestHeader; HgfsRequestCreateDirV3 *requestV3; requestHeader = (HgfsRequest *)(HGFS_REQ_PAYLOAD(req)); requestHeader->op = opUsed; requestHeader->id = req->id; requestV3 = (HgfsRequestCreateDirV3 *)(HGFS_REQ_PAYLOAD_V3(req)); /* We'll use these later. */ fileName = requestV3->fileName.name; fileNameLength = &requestV3->fileName.length; requestV3->fileName.flags = 0; requestV3->fileName.fid = HGFS_INVALID_HANDLE; requestV3->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; requestSize = HGFS_REQ_PAYLOAD_SIZE_V3(requestV3); requestV3->mask = HGFS_CREATE_DIR_MASK; /* Set permissions. */ requestV3->specialPerms = (mode & (S_ISUID | S_ISGID | S_ISVTX)) >> 9; requestV3->ownerPerms = (mode & S_IRWXU) >> 6; requestV3->groupPerms = (mode & S_IRWXG) >> 3; requestV3->otherPerms = (mode & S_IRWXO); requestV3->fileAttr = 0; break; } case HGFS_OP_CREATE_DIR_V2: { HgfsRequestCreateDirV2 *requestV2; requestV2 = (HgfsRequestCreateDirV2 *)(HGFS_REQ_PAYLOAD(req)); requestV2->header.op = opUsed; requestV2->header.id = req->id; /* We'll use these later. */ fileName = requestV2->fileName.name; fileNameLength = &requestV2->fileName.length; requestSize = sizeof *requestV2; requestV2->mask = HGFS_CREATE_DIR_MASK; /* Set permissions. */ requestV2->specialPerms = (mode & (S_ISUID | S_ISGID | S_ISVTX)) >> 9; requestV2->ownerPerms = (mode & S_IRWXU) >> 6; requestV2->groupPerms = (mode & S_IRWXG) >> 3; requestV2->otherPerms = (mode & S_IRWXO); break; } case HGFS_OP_CREATE_DIR: { HgfsRequestCreateDir *request; request = (HgfsRequestCreateDir *)(HGFS_REQ_PAYLOAD(req)); /* We'll use these later. */ fileName = request->fileName.name; fileNameLength = &request->fileName.length; requestSize = sizeof *request; requestSize = sizeof *request; /* Set permissions. */ request->permissions = (mode & S_IRWXU) >> 6; break; } default: LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackCreateDirRequest: unexpected " "OP type encountered\n")); return -EPROTO; } /* Build full name to send to server. */ if (HgfsBuildPath(fileName, req->bufferSize - (requestSize - 1), dentry) < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackCreateDirRequest: build path " "failed\n")); return -EINVAL; } LOG(6, (KERN_DEBUG "VMware hgfs: HgfsPackCreateDirRequest: create dir " "\"%s\", perms %o\n", fileName, mode)); /* Convert to CP name. */ result = CPName_ConvertTo(fileName, req->bufferSize - (requestSize - 1), fileName); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackCreateDirRequest: CP " "conversion failed\n")); return -EINVAL; } *fileNameLength = result; req->payloadSize = requestSize + result; return 0; } /* *---------------------------------------------------------------------- * * HgfsTruncatePages -- * * Following a truncate operation on the server, we must update the * page cache's view of the file by truncating some pages. This is a * two step procedure. First we call vmtruncate() to truncate all * whole pages. Then we get the boundary page from the page cache * ourselves, compute where the truncation began, and memset() the * rest of the page to zero. * * Results: * Returns zero on success, or negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsTruncatePages(struct inode *inode, // IN: Inode whose page to truncate loff_t newSize) // IN: New size of the file { int result; pgoff_t pageIndex = newSize >> PAGE_CACHE_SHIFT; unsigned pageOffset = newSize & (PAGE_CACHE_SIZE - 1); struct page *page; char *buffer; ASSERT(inode); LOG(4, (KERN_DEBUG "VMware hgfs: HgfsTruncatePages: entered\n")); /* * In 3.8.0, vmtruncate was removed and replaced by calling the check * size and set directly. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) result = vmtruncate(inode, newSize); #else result = inode_newsize_ok(inode, newSize); if (0 == result) { truncate_setsize(inode, newSize); } #endif if (result) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsTruncatePages: vmtruncate failed " "with error code %d\n", result)); return result; } /* * This is a bit complicated, so it merits an explanation. grab_cache_page() * will give us back the page with the specified index, after having locked * and incremented its reference count. We must first map it into memory so * we can modify it. After we're done modifying the page, we flush its data * from the data cache, unmap it, release our reference, and unlock it. */ page = grab_cache_page(inode->i_mapping, pageIndex); if (page == NULL) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsTruncatePages: could not get page " "with index %lu from page cache\n", pageIndex)); return -ENOMEM; } buffer = kmap(page); memset(buffer + pageOffset, 0, PAGE_CACHE_SIZE - pageOffset); flush_dcache_page(page); kunmap(page); page_cache_release(page); compat_unlock_page(page); return 0; } /* * HGFS inode operations. */ /* *---------------------------------------------------------------------- * * HgfsCreate -- * * Create inode for a new file. Called directly by vfs_create, * which is called by open_namei (both in fs/namei.c), as a result * of someone doing a creat(2) or an open(2) with O_CREAT. * * This gets called BEFORE f_op->open is called, so the file on the * remote end has not been created yet when we get here. So, we * just cheat and create a reasonable looking inode and instantiate * it. When this returns, our open routine will get called, which * will create the actual file on the server. If that fails for * some reason, dentry_open (which calls f_op->open) will cleanup * things and fput the dentry. * * XXX: Now that we do care about having valid inode numbers, it is * unfortunate but necessary that we "cheat" here. The problem is that * without the "intent" field from the nameidata struct (which we don't * get prior to 2.5.75), we have no way of knowing whether the file was * opened with O_EXCL or O_TRUNC. Knowing about O_TRUNC isn't crucial * because we can always create the file now and truncate it later, in * HgfsOpen. But without knowing about O_EXCL, we can't "fail if the file * exists on the server", which is the desired behavior for O_EXCL. The * source code for NFSv3 in 2.4.2 describes this shortcoming. The only * solution, barring massive architectural differences between the 2.4 and * 2.6 HGFS drivers, is to ignore O_EXCL, but we've supported it up until * now... * * Results: * Returns zero on success, negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsCreate(struct inode *dir, // IN: Parent dir to create in struct dentry *dentry, // IN: Dentry containing name to create compat_umode_t mode, // IN: Mode of file to be created #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) bool excl // IN: O_EXCL #else struct nameidata *nd // IN: Intent, vfsmount, ... #endif ) { HgfsAttrInfo attr; int result; ASSERT(dir); ASSERT(dentry); /* * We can call HgfsBuildPath and make the full path to this new entry, * but why bother if it's only for logging. */ LOG(6, (KERN_DEBUG "VMware hgfs: HgfsCreate: new entry \"%s\"\n", dentry->d_name.name)); /* Create appropriate attrs for this file. */ attr.type = HGFS_FILE_TYPE_REGULAR; attr.size = 0; /* just to be explicit */ attr.specialPerms = ((mode & (S_ISUID | S_ISGID | S_ISVTX)) >> 9); attr.ownerPerms = (mode & S_IRWXU) >> 6; attr.groupPerms = (mode & S_IRWXG) >> 3; attr.otherPerms = mode & S_IRWXO; attr.mask = HGFS_ATTR_VALID_TYPE | HGFS_ATTR_VALID_SIZE | HGFS_ATTR_VALID_SPECIAL_PERMS | HGFS_ATTR_VALID_OWNER_PERMS | HGFS_ATTR_VALID_GROUP_PERMS | HGFS_ATTR_VALID_OTHER_PERMS; result = HgfsInstantiate(dentry, 0, &attr); /* * Mark the inode as recently created but not yet opened so that if we do * fail to create the actual file in HgfsOpen, we know to force a * revalidate so that the next operation on this inode will fail. */ if (result == 0) { HgfsInodeInfo *iinfo = INODE_GET_II_P(dentry->d_inode); iinfo->createdAndUnopened = TRUE; } return result; } /* *---------------------------------------------------------------------- * * HgfsLookup -- * * Lookup a file in a directory. * * We do a getattr to see if the file exists on the server, and if * so we create a new inode and fill in the fields appropriately by * calling HgfsIget with the results of the getattr, and then * call d_add with the new dentry. * * For the curious, the way lookup in linux works (see fs/namei.c) * is roughly as follows: first a d_lookup is done to see if there * is an appropriate entry in the dcache already. If there is, it * is revalidated by calling d_op->d_revalidate, which calls our * HgfsDentryRevalidate (see above). If there is no dentry in the * cache or if the dentry is no longer valid, then namei calls * i_op->lookup, which calls HgfsLookup. * * Results: * Returns NULL on success, negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static struct dentry * HgfsLookup(struct inode *dir, // IN: Inode of parent directory struct dentry *dentry, // IN: Dentry containing name to look up #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) unsigned int flags #else struct nameidata *nd // IN: Intent, vfsmount, ... #endif ) { HgfsAttrInfo attr; struct inode *inode; int error = 0; ASSERT(dir); ASSERT(dentry); if (!dir || !dentry) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsLookup: NULL input\n")); error = -EFAULT; goto error; } LOG(6, (KERN_DEBUG "VMware hgfs: HgfsLookup: dir ino %lu, i_dev %u\n", dir->i_ino, dir->i_sb->s_dev)); LOG(6, (KERN_DEBUG "VMware hgfs: HgfsLookup: entry name is \"%s\"\n", dentry->d_name.name)); /* Do a getattr on the file to see if it exists on the server. */ inode = NULL; error = HgfsPrivateGetattr(dentry, &attr, NULL); if (!error) { /* File exists on the server. */ /* * Get the inode with this inode number and the attrs we got from * the server. */ inode = HgfsIget(dir->i_sb, 0, &attr); if (!inode) { error = -ENOMEM; LOG(4, (KERN_DEBUG "VMware hgfs: HgfsLookup: out of memory getting " "inode\n")); goto error; } } else if (error != -ENOENT) { /* * Either the file doesn't exist or there was a more serious * error; if it's the former, it's okay, we just do nothing. */ LOG(4, (KERN_DEBUG "VMware hgfs: HgfsLookup: error other " "than ENOENT: %d\n", error)); goto error; } /* * Set the dentry's time to NOW, set its operations pointer, add it * and the new (possibly NULL) inode to the dcache. */ HgfsDentryAgeReset(dentry); dentry->d_op = &HgfsDentryOperations; LOG(6, (KERN_DEBUG "VMware hgfs: HgfsLookup: adding new entry\n")); d_add(dentry, inode); return NULL; error: return ERR_PTR(error); } /* *---------------------------------------------------------------------- * * HgfsMkdir -- * * Handle a mkdir request * * Results: * Returns zero on success, or a negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsMkdir(struct inode *dir, // IN: Inode of parent directory struct dentry *dentry, // IN: Dentry with name to be created compat_umode_t mode) // IN: Mode of dir to be created { HgfsReq *req; HgfsStatus replyStatus; HgfsOp opUsed; int result = 0; ASSERT(dir); ASSERT(dir->i_sb); ASSERT(dentry); req = HgfsGetNewRequest(); if (!req) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsMkdir: out of memory while " "getting new request\n")); result = -ENOMEM; goto out; } retry: opUsed = hgfsVersionCreateDir; result = HgfsPackCreateDirRequest(dentry, mode, opUsed, req); if (result != 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsMkdir: error packing request\n")); goto out; } /* * Send the request and process the reply. Since HgfsReplyCreateDirV2 and * HgfsReplyCreateDir are identical, we need no special logic here. */ result = HgfsSendRequest(req); if (result == 0) { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsMkdir: got reply\n")); replyStatus = HgfsReplyStatus(req); result = HgfsStatusConvertToLinux(replyStatus); switch (result) { case 0: LOG(6, (KERN_DEBUG "VMware hgfs: HgfsMkdir: directory created " "successfully, instantiating dentry\n")); result = HgfsInstantiate(dentry, 0, NULL); if (result == 0) { /* * Attempt to set host directory's uid/gid to that of the * current user. As with the open(.., O_CREAT) case, this is * only expected to work when the hgfs server is running on * a Linux machine and as root, but we might as well give it * a go. */ HgfsSetUidGid(dir, dentry, current_fsuid(), current_fsgid()); } /* * XXX: When we support hard links, this is a good place to * increment link count of parent dir. */ break; case -EPROTO: /* Retry with older version(s). Set globally. */ if (opUsed == HGFS_OP_CREATE_DIR_V3) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsMkdir: Version 3 not " "supported. Falling back to version 2.\n")); hgfsVersionCreateDir = HGFS_OP_CREATE_DIR_V2; goto retry; } else if (opUsed == HGFS_OP_CREATE_DIR_V2) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsMkdir: Version 2 not " "supported. Falling back to version 1.\n")); hgfsVersionCreateDir = HGFS_OP_CREATE_DIR; goto retry; } /* Fallthrough. */ default: LOG(6, (KERN_DEBUG "VMware hgfs: HgfsMkdir: directory was not " "created, error %d\n", result)); break; } } else if (result == -EIO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsMkdir: timed out\n")); } else if (result == -EPROTO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsMkdir: server " "returned error: %d\n", result)); } else { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsMkdir: unknown error: " "%d\n", result)); } out: HgfsFreeRequest(req); return result; } /* *---------------------------------------------------------------------- * * HgfsRmdir -- * * Handle an rmdir request. Just calls HgfsDelete with the * correct opcode. * * Results: * Returns zero on success, or a negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsRmdir(struct inode *dir, // IN: Parent dir of dir to remove struct dentry *dentry) // IN: Dentry of dir to remove { int result; LOG(8, (KERN_DEBUG "VMware hgfs: HgfsRmdir: was called\n")); /* * XXX: CIFS also sets the size of the deleted directory to 0. Why? I don't * know...why not? * * XXX: When we support hardlinks, we should decrement the link count of * the parent directory. */ result = HgfsDelete(dir, dentry, HGFS_OP_DELETE_DIR); if (!result) { compat_i_size_write(dentry->d_inode, 0); } return result; } /* *---------------------------------------------------------------------- * * HgfsUnlink -- * * Handle an unlink request. Just calls HgfsDelete with the * correct opcode. * * Results: * Returns zero on success, or a negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsUnlink(struct inode *dir, // IN: Parent dir of file to unlink struct dentry *dentry) // IN: Dentry of file to unlink { LOG(8, (KERN_DEBUG "VMware hgfs: HgfsUnlink: was called\n")); return HgfsDelete(dir, dentry, HGFS_OP_DELETE_FILE); } /* *---------------------------------------------------------------------- * * HgfsRename -- * * Handle rename requests. * * Results: * Returns zero on success, or a negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsRename(struct inode *oldDir, // IN: Inode of original directory struct dentry *oldDentry, // IN: Dentry of file to rename struct inode *newDir, // IN: Inode of new directory struct dentry *newDentry) // IN: Dentry containing new name { HgfsReq *req = NULL; char *oldName; char *newName; uint32 *oldNameLength; uint32 *newNameLength; int result = 0; uint32 reqSize; HgfsOp opUsed; HgfsStatus replyStatus; ASSERT(oldDir); ASSERT(oldDir->i_sb); ASSERT(oldDentry); ASSERT(newDir); ASSERT(newDentry); if (!oldDir || !oldDentry || !newDir || !newDentry) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRename: NULL input\n")); result = -EFAULT; goto out; } if (oldDentry->d_inode && newDentry->d_inode) { HgfsInodeInfo *oldIinfo; HgfsInodeInfo *newIinfo; /* * Don't do rename if the source and target are identical (from the * viewpoint of the host). It is possible that multiple guest inodes * point to the same host inode under the case that both one folder * and its subfolder are mapped as hgfs sharese. Please also see the * comments at fsutil.c/HgfsIget. */ oldIinfo = INODE_GET_II_P(oldDentry->d_inode); newIinfo = INODE_GET_II_P(newDentry->d_inode); if (oldIinfo->hostFileId !=0 && newIinfo->hostFileId != 0 && oldIinfo->hostFileId == newIinfo->hostFileId) { LOG(4, ("VMware hgfs: %s: source and target are the same file.\n", __func__)); result = -EEXIST; goto out; } } req = HgfsGetNewRequest(); if (!req) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRename: out of memory while " "getting new request\n")); result = -ENOMEM; goto out; } retry: opUsed = hgfsVersionRename; if (opUsed == HGFS_OP_RENAME_V3) { HgfsRequestRenameV3 *request = (HgfsRequestRenameV3 *)HGFS_REQ_PAYLOAD_V3(req); HgfsRequest *header = (HgfsRequest *)HGFS_REQ_PAYLOAD(req); header->op = opUsed; header->id = req->id; oldName = request->oldName.name; oldNameLength = &request->oldName.length; request->hints = 0; request->oldName.flags = 0; request->oldName.fid = HGFS_INVALID_HANDLE; request->oldName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; request->reserved = 0; reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); } else { HgfsRequestRename *request = (HgfsRequestRename *)HGFS_REQ_PAYLOAD(req); request->header.op = opUsed; oldName = request->oldName.name; oldNameLength = &request->oldName.length; reqSize = sizeof *request; } /* Build full old name to send to server. */ if (HgfsBuildPath(oldName, HGFS_NAME_BUFFER_SIZET(req->bufferSize, reqSize), oldDentry) < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRename: build old path failed\n")); result = -EINVAL; goto out; } LOG(6, (KERN_DEBUG "VMware hgfs: HgfsRename: Old name: \"%s\"\n", oldName)); /* Convert old name to CP format. */ result = CPName_ConvertTo(oldName, HGFS_NAME_BUFFER_SIZET(req->bufferSize, reqSize), oldName); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRename: oldName CP " "conversion failed\n")); result = -EINVAL; goto out; } *oldNameLength = result; reqSize += result; /* * Build full new name to send to server. * Note the different buffer length. This is because HgfsRequestRename * contains two filenames, and once we place the first into the packet we * must account for it when determining the amount of buffer available for * the second. */ if (opUsed == HGFS_OP_RENAME_V3) { HgfsRequestRenameV3 *request = (HgfsRequestRenameV3 *)HGFS_REQ_PAYLOAD_V3(req); HgfsFileNameV3 *newNameP; newNameP = (HgfsFileNameV3 *)((char *)&request->oldName + sizeof request->oldName + result); newName = newNameP->name; newNameLength = &newNameP->length; newNameP->flags = 0; newNameP->fid = HGFS_INVALID_HANDLE; newNameP->caseType = HGFS_FILE_NAME_CASE_SENSITIVE; } else { HgfsRequestRename *request = (HgfsRequestRename *)HGFS_REQ_PAYLOAD(req); HgfsFileName *newNameP; newNameP = (HgfsFileName *)((char *)&request->oldName + sizeof request->oldName + result); newName = newNameP->name; newNameLength = &newNameP->length; } if (HgfsBuildPath(newName, HGFS_NAME_BUFFER_SIZET(req->bufferSize, reqSize) - result, newDentry) < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRename: build new path failed\n")); result = -EINVAL; goto out; } LOG(6, (KERN_DEBUG "VMware hgfs: HgfsRename: New name: \"%s\"\n", newName)); /* Convert new name to CP format. */ result = CPName_ConvertTo(newName, HGFS_NAME_BUFFER_SIZET(req->bufferSize, reqSize) - result, newName); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRename: newName CP " "conversion failed\n")); result = -EINVAL; goto out; } *newNameLength = result; reqSize += result; req->payloadSize = reqSize; result = HgfsSendRequest(req); if (result == 0) { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsRename: got reply\n")); replyStatus = HgfsReplyStatus(req); result = HgfsStatusConvertToLinux(replyStatus); if (result == -EPROTO) { /* Retry with older version(s). Set globally. */ if (opUsed == HGFS_OP_RENAME_V3) { hgfsVersionRename = HGFS_OP_RENAME; goto retry; } else { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRename: server " "returned error: %d\n", result)); goto out; } } } else if (result == -EIO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRename: timed out\n")); } else if (result == -EPROTO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRename: server " "returned error: %d\n", result)); } else { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRename: unknown error: " "%d\n", result)); } out: HgfsFreeRequest(req); return result; } /* *---------------------------------------------------------------------- * * HgfsPackSymlinkCreateRequest -- * * Setup the create symlink request, depending on the op version. * * Results: * Returns zero on success, or negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsPackSymlinkCreateRequest(struct dentry *dentry, // IN: File pointer for this open const char *symname, // IN: Target name HgfsOp opUsed, // IN: Op to be used HgfsReq *req) // IN/OUT: Packet to write into { HgfsRequestSymlinkCreateV3 *requestV3 = NULL; HgfsRequestSymlinkCreate *request = NULL; char *symlinkName; uint32 *symlinkNameLength; char *targetName; uint32 *targetNameLength; size_t targetNameBytes; size_t requestSize; int result; ASSERT(dentry); ASSERT(symname); ASSERT(req); switch (opUsed) { case HGFS_OP_CREATE_SYMLINK_V3: { HgfsRequest *requestHeader; requestHeader = (HgfsRequest *)(HGFS_REQ_PAYLOAD(req)); requestHeader->op = opUsed; requestHeader->id = req->id; requestV3 = (HgfsRequestSymlinkCreateV3 *)HGFS_REQ_PAYLOAD_V3(req); /* We'll use these later. */ symlinkName = requestV3->symlinkName.name; symlinkNameLength = &requestV3->symlinkName.length; requestV3->symlinkName.flags = 0; requestV3->symlinkName.fid = HGFS_INVALID_HANDLE; requestV3->symlinkName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; requestV3->reserved = 0; requestSize = HGFS_REQ_PAYLOAD_SIZE_V3(requestV3); break; } case HGFS_OP_CREATE_SYMLINK: { request = (HgfsRequestSymlinkCreate *)(HGFS_REQ_PAYLOAD(req)); request->header.op = opUsed; request->header.id = req->id; /* We'll use these later. */ symlinkName = request->symlinkName.name; symlinkNameLength = &request->symlinkName.length; requestSize = sizeof *request; break; } default: LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackSymlinkCreateRequest: unexpected " "OP type encountered\n")); return -EPROTO; } if (HgfsBuildPath(symlinkName, req->bufferSize - (requestSize - 1), dentry) < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackSymlinkCreateRequest: build symlink path " "failed\n")); return -EINVAL; } LOG(6, (KERN_DEBUG "VMware hgfs: HgfsPackSymlinkCreateRequest: Symlink name: \"%s\"\n", symlinkName)); /* Convert symlink name to CP format. */ result = CPName_ConvertTo(symlinkName, req->bufferSize - (requestSize - 1), symlinkName); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackSymlinkCreateRequest: symlinkName CP " "conversion failed\n")); return -EINVAL; } *symlinkNameLength = result; req->payloadSize = requestSize + result; /* * Note the different buffer length. This is because HgfsRequestSymlink * contains two filenames, and once we place the first into the packet we * must account for it when determining the amount of buffer available for * the second. * * Also note that targetNameBytes accounts for the NUL character. Once * we've converted it to CP name, it won't be NUL-terminated and the length * of the string in the packet itself won't account for it. */ if (opUsed == HGFS_OP_CREATE_SYMLINK_V3) { HgfsFileNameV3 *fileNameP; fileNameP = (HgfsFileNameV3 *)((char *)&requestV3->symlinkName + sizeof requestV3->symlinkName + result); targetName = fileNameP->name; targetNameLength = &fileNameP->length; fileNameP->flags = 0; fileNameP->fid = HGFS_INVALID_HANDLE; fileNameP->caseType = HGFS_FILE_NAME_CASE_SENSITIVE; } else { HgfsFileName *fileNameP; fileNameP = (HgfsFileName *)((char *)&request->symlinkName + sizeof request->symlinkName + result); targetName = fileNameP->name; targetNameLength = &fileNameP->length; } targetNameBytes = strlen(symname) + 1; /* Copy target name into request packet. */ if (targetNameBytes > req->bufferSize - (requestSize - 1)) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackSymlinkCreateRequest: target name is too " "big\n")); return -EINVAL; } memcpy(targetName, symname, targetNameBytes); LOG(6, (KERN_DEBUG "VMware hgfs: HgfsPackSymlinkCreateRequest: target name: \"%s\"\n", targetName)); /* Convert target name to CPName-lite format. */ CPNameLite_ConvertTo(targetName, targetNameBytes - 1, '/'); *targetNameLength = targetNameBytes - 1; req->payloadSize += targetNameBytes - 1; return 0; } /* *---------------------------------------------------------------------- * * HgfsSymlink -- * * Handle a symlink request * * Results: * Returns zero on success, or a negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsSymlink(struct inode *dir, // IN: Inode of parent directory struct dentry *dentry, // IN: Dentry of new symlink file const char *symname) // IN: Target name { HgfsReq *req; int result = 0; HgfsOp opUsed; HgfsStatus replyStatus; ASSERT(dir); ASSERT(dir->i_sb); ASSERT(dentry); ASSERT(symname); req = HgfsGetNewRequest(); if (!req) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSymlink: out of memory while " "getting new request\n")); result = -ENOMEM; goto out; } retry: opUsed = hgfsVersionCreateSymlink; result = HgfsPackSymlinkCreateRequest(dentry, symname, opUsed, req); if (result != 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSymlink: error packing request\n")); goto out; } result = HgfsSendRequest(req); if (result == 0) { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsSymlink: got reply\n")); replyStatus = HgfsReplyStatus(req); result = HgfsStatusConvertToLinux(replyStatus); if (result == 0) { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsSymlink: symlink created " "successfully, instantiating dentry\n")); result = HgfsInstantiate(dentry, 0, NULL); } else if (result == -EPROTO) { /* Retry with older version(s). Set globally. */ if (opUsed == HGFS_OP_CREATE_SYMLINK_V3) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSymlink: Version 3 " "not supported. Falling back to version 2.\n")); hgfsVersionCreateSymlink = HGFS_OP_CREATE_SYMLINK; goto retry; } else { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsSymlink: symlink was not " "created, error %d\n", result)); } } } else if (result == -EIO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSymlink: timed out\n")); } else if (result == -EPROTO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSymlink: server " "returned error: %d\n", result)); } else { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSymlink: unknown error: " "%d\n", result)); } out: HgfsFreeRequest(req); return result; } /* *---------------------------------------------------------------------------- * * HgfsAccessInt -- * * Check to ensure the user has the specified type of access to the file. * * Results: * Returns 0 if access is allowed and a non-zero error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsAccessInt(struct dentry *dentry, // IN: dentry to check access for int mask) // IN: access mode requested. { HgfsAttrInfo attr; int ret; if (!dentry) { return 0; } ret = HgfsPrivateGetattr(dentry, &attr, NULL); if (ret == 0) { uint32 effectivePermissions; if (attr.mask & HGFS_ATTR_VALID_EFFECTIVE_PERMS) { effectivePermissions = attr.effectivePerms; } else { /* * If the server did not return actual effective permissions then * need to calculate ourselves. However we should avoid unnecessary * denial of access so perform optimistic permissions calculation. * It is safe since host enforces necessary restrictions regardless of * the client's decisions. */ effectivePermissions = attr.ownerPerms | attr.groupPerms | attr.otherPerms; } if ((effectivePermissions & mask) != mask) { ret = -EACCES; } LOG(8, ("VMware Hgfs: %s: effectivePermissions: %d, ret: %d\n", __func__, effectivePermissions, ret)); } else { LOG(4, ("VMware Hgfs: %s: HgfsPrivateGetattr failed.\n", __func__)); } return ret; } /* *---------------------------------------------------------------------- * * HgfsPermission -- * * Check for access rights on Hgfs. Called from VFS layer for each * file access. * * Results: * Returns zero on success, or a negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) static int HgfsPermission(struct inode *inode, int mask) { LOG(8, ("VMware hgfs: %s: inode->mode: %8x mask: %8x\n", __func__, inode->i_mode, mask)); /* * For sys_access, we go to the host for permission checking; * otherwise return 0. */ if (mask & MAY_ACCESS) { /* For sys_access. */ struct dentry *dentry; #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0) struct hlist_node *p; #endif if (mask & MAY_NOT_BLOCK) return -ECHILD; /* Find a dentry with valid d_count. Refer bug 587879. */ hlist_for_each_entry(dentry, #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0) p, #endif &inode->i_dentry, d_alias) { int dcount = dentry->d_count; if (dcount) { LOG(4, ("Found %s %d \n", dentry->d_name.name, dcount)); return HgfsAccessInt(dentry, mask & (MAY_READ | MAY_WRITE | MAY_EXEC)); } } ASSERT(FALSE); } return 0; } #else static int HgfsPermission(struct inode *inode, int mask #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) , struct nameidata *nd #elif defined(IPERM_FLAG_RCU) , unsigned int flags #endif ) { LOG(8, ("VMware hgfs: %s: inode->mode: %8x mask: %8x\n", __func__, inode->i_mode, mask)); /* * For sys_access, we go to the host for permission checking; * otherwise return 0. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) if (nd != NULL && (nd->flags & LOOKUP_ACCESS)) { /* For sys_access. */ #else if (mask & MAY_ACCESS) { /* For sys_access. */ #endif struct list_head *pos; /* * In 2.6.38 path walk is done in 2 distinct modes: rcu-walk and * ref-walk. Ref-walk is the classic one; rcu is lockless and is * not allowed to sleep. We insist on using ref-walk since our * transports may sleep. In 3.1 IPERM_FLAG_RCU was replaced with * MAY_NOT_BLOCK. */ #if defined(MAY_NOT_BLOCK) if (mask & MAY_NOT_BLOCK) return -ECHILD; #elif defined(IPERM_FLAG_RCU) if (flags & IPERM_FLAG_RCU) return -ECHILD; #endif /* Find a dentry with valid d_count. Refer bug 587879. */ list_for_each(pos, &inode->i_dentry) { int dcount; struct dentry *dentry = list_entry(pos, struct dentry, d_alias); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 38) dcount = atomic_read(&dentry->d_count); #else dcount = dentry->d_count; #endif if (dcount) { LOG(4, ("Found %s %d \n", (dentry)->d_name.name, dcount)); return HgfsAccessInt(dentry, mask & (MAY_READ | MAY_WRITE | MAY_EXEC)); } } ASSERT(FALSE); } return 0; } #endif /* *----------------------------------------------------------------------------- * * HgfsGetattr -- * * Hgfs superblock 'getattr' method. * * Results: * 0 on success * error < 0 on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ static int HgfsGetattr(struct vfsmount *mnt, // Unused struct dentry *dentry, // IN struct kstat *stat) // OUT { int err; // XXX ASSERT(mnt); ? --hpreg ASSERT(dentry); ASSERT(stat); err = HgfsRevalidate(dentry); if (err) { return err; } /* Convert stats from the VFS inode format to the kernel format --hpreg */ generic_fillattr(dentry->d_inode, stat); // XXX Should we set stat->blocks and stat->blksize? --hpreg return 0; } /* * Public function implementations. */ /* *---------------------------------------------------------------------- * * HgfsSetattr -- * * Handle a setattr request. Call HgfsSetattrCopy to determine * which fields need updating and convert them to the HgfsAttr * format, then send the request to the server. * * Results: * Returns zero on success, or a negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ int HgfsSetattr(struct dentry *dentry, // IN: File to set attributes of struct iattr *iattr) // IN: Attributes to set { HgfsReq *req; HgfsStatus replyStatus; int result = 0; Bool changed = FALSE; Bool allowHandleReuse = TRUE; HgfsOp opUsed; ASSERT(dentry); ASSERT(dentry->d_inode); ASSERT(dentry->d_inode->i_mapping); ASSERT(dentry->d_sb); ASSERT(iattr); req = HgfsGetNewRequest(); if (!req) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSetattr: out of memory while " "getting new request\n")); result = -ENOMEM; goto out; } retry: /* Fill out the request packet. */ opUsed = hgfsVersionSetattr; result = HgfsPackSetattrRequest(iattr, dentry, allowHandleReuse, opUsed, req, &changed); if (result != 0 || !changed) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSetattr: no attrs changed\n")); goto out; } /* * Flush all dirty pages prior to sending the request if we're going to * modify the file size or change the last write time. */ if (iattr->ia_valid & ATTR_SIZE || iattr->ia_valid & ATTR_MTIME) { compat_filemap_write_and_wait(dentry->d_inode->i_mapping); } /* Send the request and process the reply. */ result = HgfsSendRequest(req); if (result == 0) { /* Get the reply. */ replyStatus = HgfsReplyStatus(req); result = HgfsStatusConvertToLinux(replyStatus); switch (result) { case 0: /* * If we modified the file size, we must truncate our pages from the * page cache. */ if (iattr->ia_valid & ATTR_SIZE) { result = HgfsTruncatePages(dentry->d_inode, iattr->ia_size); } /* Fallthrough to revalidate. */ case -EPERM: /* * Now that the server's attributes are updated, let's update our * local view of them. Unfortunately, we can't trust iattr, because * the server may have chosen to ignore certain attributes that we * asked it to set. For example, a Windows server will have ignored * the mode nearly entirely. Therefore, rather than calling * inode_setattr() to update the inode with the contents of iattr, * just force a revalidate. * * XXX: Note that EPERM gets similar treatment, as the server may * have updated some of the attributes and still sent us an error. */ HgfsDentryAgeForce(dentry); HgfsRevalidate(dentry); break; case -EBADF: /* * This can happen if we attempted a setattr by handle and the handle * was closed. Because we have no control over the backdoor, it's * possible that an attacker closed our handle, in which case the * driver still thinks the handle is open. So a straight-up * "goto retry" would cause an infinite loop. Instead, let's retry * with a setattr by name. */ if (allowHandleReuse) { allowHandleReuse = FALSE; goto retry; } /* * There's no reason why the server should have sent us this error * when we haven't used a handle. But to prevent an infinite loop in * the driver, let's make sure that we don't retry again. */ break; case -EPROTO: /* Retry with older version(s). Set globally. */ if (opUsed == HGFS_OP_SETATTR_V3) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSetattr: Version 3 " "not supported. Falling back to version 2.\n")); hgfsVersionSetattr = HGFS_OP_SETATTR_V2; goto retry; } else if (opUsed == HGFS_OP_SETATTR_V2) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSetattr: Version 2 " "not supported. Falling back to version 1.\n")); hgfsVersionSetattr = HGFS_OP_SETATTR; goto retry; } /* Fallthrough. */ default: break; } } else if (result == -EIO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSetattr: timed out\n")); } else if (result == -EPROTO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSetattr: server " "returned error: %d\n", result)); } else { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSetattr: unknown error: " "%d\n", result)); } out: HgfsFreeRequest(req); return result; } /* *---------------------------------------------------------------------- * * HgfsRevalidate -- * * Called when the kernel wants to check that an inode is still * valid. Called with the dentry that points to the inode we're * interested in. * * We call HgfsPrivateGetattr with the inode's remote name, and if * it succeeds we update the inode's attributes and return zero * (success). Otherwise, we return an error. * * Results: * Returns zero if inode is valid, negative error if not. * * Side effects: * None * *---------------------------------------------------------------------- */ int HgfsRevalidate(struct dentry *dentry) // IN: Dentry to revalidate { int error = 0; HgfsSuperInfo *si; unsigned long age; HgfsInodeInfo *iinfo; ASSERT(dentry); si = HGFS_SB_TO_COMMON(dentry->d_sb); if (!dentry->d_inode) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRevalidate: null input\n")); return -EINVAL; } LOG(6, (KERN_DEBUG "VMware hgfs: HgfsRevalidate: name %s, " "inum %lu\n", dentry->d_name.name, dentry->d_inode->i_ino)); age = jiffies - dentry->d_time; iinfo = INODE_GET_II_P(dentry->d_inode); if (age > si->ttl || iinfo->hostFileId == 0) { HgfsAttrInfo attr; LOG(6, (KERN_DEBUG "VMware hgfs: HgfsRevalidate: dentry is too old, " "getting new attributes\n")); /* * Sync unwritten file data so the file size on the server will * be current with our view of the file. */ compat_filemap_write_and_wait(dentry->d_inode->i_mapping); error = HgfsPrivateGetattr(dentry, &attr, NULL); if (!error) { /* * If server provides file ID, we need to check whether it has changed * since last revalidation. There might be a case that at server side * the same file name has been used for other file during the period. */ if (attr.mask & HGFS_ATTR_VALID_FILEID) { if (iinfo->hostFileId == 0) { /* hostFileId was invalidated, so update it here */ iinfo->hostFileId = attr.hostFileId; } else if (iinfo->hostFileId != attr.hostFileId) { LOG(4, ("VMware hgfs: %s: host file id mismatch. Expected " "%"FMT64"u, got %"FMT64"u.\n", __func__, iinfo->hostFileId, attr.hostFileId)); return -EINVAL; } } /* Update inode's attributes and reset the age. */ HgfsChangeFileAttributes(dentry->d_inode, &attr); HgfsDentryAgeReset(dentry); } } else { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsRevalidate: using cached dentry " "attributes\n")); } return error; } open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/bdhandler.c0000644765153500003110000001364412220061556021637 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * bdhandler.c -- * * Background thread for handling backdoor requests and replies. */ /* Must come before any kernel header file. */ #include "driver-config.h" #include #include "transport.h" #include "hgfsBd.h" #include "hgfsDevLinux.h" #include "hgfsProto.h" #include "module.h" #include "request.h" #include "rpcout.h" #include "vm_assert.h" static Bool HgfsBdChannelOpen(HgfsTransportChannel *channel); static void HgfsBdChannelClose(HgfsTransportChannel *channel); static HgfsReq * HgfsBdChannelAllocate(size_t payloadSize); void HgfsBdChannelFree(HgfsReq *req); static int HgfsBdChannelSend(HgfsTransportChannel *channel, HgfsReq *req); static HgfsTransportChannel channel = { .name = "backdoor", .ops.open = HgfsBdChannelOpen, .ops.close = HgfsBdChannelClose, .ops.allocate = HgfsBdChannelAllocate, .ops.free = HgfsBdChannelFree, .ops.send = HgfsBdChannelSend, .priv = NULL, .status = HGFS_CHANNEL_NOTCONNECTED }; /* *----------------------------------------------------------------------------- * * HgfsBdChannelOpen -- * * Open the backdoor in an idempotent way. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool HgfsBdChannelOpen(HgfsTransportChannel *channel) // IN: Channel { Bool ret = FALSE; ASSERT(channel->status == HGFS_CHANNEL_NOTCONNECTED); if (HgfsBd_OpenBackdoor((RpcOut **)&channel->priv)) { LOG(8, ("VMware hgfs: %s: backdoor opened.\n", __func__)); ret = TRUE; ASSERT(channel->priv != NULL); } return ret; } /* *----------------------------------------------------------------------------- * * HgfsBdChannelClose -- * * Close the backdoor in an idempotent way. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsBdChannelClose(HgfsTransportChannel *channel) // IN: Channel { ASSERT(channel->priv != NULL); HgfsBd_CloseBackdoor((RpcOut **)&channel->priv); ASSERT(channel->priv == NULL); LOG(8, ("VMware hgfs: %s: backdoor closed.\n", __func__)); } /* *----------------------------------------------------------------------------- * * HgfsBdChannelAllocate -- * * Allocate request in a way that is suitable for sending through * backdoor. * * Results: * NULL on failure; otherwise address of the new request. * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsReq * HgfsBdChannelAllocate(size_t payloadSize) // IN: size of requests payload { HgfsReq *req; req = kmalloc(sizeof(*req) + HGFS_SYNC_REQREP_CLIENT_CMD_LEN + payloadSize, GFP_KERNEL); if (likely(req)) { /* Setup the packet prefix. */ memcpy(req->buffer, HGFS_SYNC_REQREP_CLIENT_CMD, HGFS_SYNC_REQREP_CLIENT_CMD_LEN); req->payload = req->buffer + HGFS_SYNC_REQREP_CLIENT_CMD_LEN; req->bufferSize = payloadSize; } return req; } /* *----------------------------------------------------------------------------- * * HgfsBdChannelFree -- * * Free previously allocated request. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void HgfsBdChannelFree(HgfsReq *req) { ASSERT(req); kfree(req); } /* *---------------------------------------------------------------------- * * HgfsBdChannelSend -- * * Send a request via backdoor. * * Results: * 0 on success, negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsBdChannelSend(HgfsTransportChannel *channel, // IN: Channel HgfsReq *req) // IN: request to send { char const *replyPacket = NULL; size_t payloadSize; int ret; ASSERT(req); ASSERT(req->state == HGFS_REQ_STATE_UNSENT); ASSERT(req->payloadSize <= req->bufferSize); LOG(8, ("VMware hgfs: %s: backdoor sending.\n", __func__)); payloadSize = req->payloadSize; ret = HgfsBd_Dispatch(channel->priv, HGFS_REQ_PAYLOAD(req), &payloadSize, &replyPacket); if (ret == 0) { LOG(8, ("VMware hgfs: %s: Backdoor reply received.\n", __func__)); /* Request sent successfully. Copy the reply and wake the client. */ ASSERT(replyPacket); ASSERT(payloadSize <= req->bufferSize); memcpy(HGFS_REQ_PAYLOAD(req), replyPacket, payloadSize); req->payloadSize = payloadSize; HgfsCompleteReq(req); } return ret; } /* *---------------------------------------------------------------------- * * HgfsGetBdChannel -- * * Initialize backdoor channel. * * Results: * Always return pointer to back door channel. * * Side effects: * None * *---------------------------------------------------------------------- */ HgfsTransportChannel* HgfsGetBdChannel(void) { return &channel; } open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/dir.c0000644765153500003110000010173512220061556020471 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * dir.c -- * * Directory operations for the filesystem portion of the vmhgfs driver. */ /* Must come before any kernel header file. */ #include "driver-config.h" #include #include #include "compat_fs.h" #include "compat_kernel.h" #include "compat_slab.h" #include "compat_mutex.h" #include "cpName.h" #include "hgfsEscape.h" #include "hgfsProto.h" #include "hgfsUtil.h" #include "module.h" #include "request.h" #include "fsutil.h" #include "vm_assert.h" #include "vm_basic_types.h" /* Private functions. */ static int HgfsPrivateDirReOpen(struct file *file); static int HgfsPrivateDirOpen(struct file *file, HgfsHandle *handle); static int HgfsPrivateDirRelease(struct file *file, HgfsHandle handle); static int HgfsUnpackSearchReadReply(HgfsReq *req, HgfsAttrInfo *attr, char **entryName); static int HgfsGetNextDirEntry(HgfsSuperInfo *si, HgfsHandle searchHandle, uint32 offset, HgfsAttrInfo *attr, char **entryName, Bool *done); static int HgfsPackDirOpenRequest(struct file *file, HgfsOp opUsed, HgfsReq *req); /* HGFS file operations for directories. */ static int HgfsDirOpen(struct inode *inode, struct file *file); static int HgfsReaddir(struct file *file, void *dirent, filldir_t filldir); static int HgfsDirRelease(struct inode *inode, struct file *file); static loff_t HgfsDirLlseek(struct file *file, loff_t offset, int origin); /* HGFS file operations structure for directories. */ struct file_operations HgfsDirFileOperations = { .llseek = HgfsDirLlseek, .owner = THIS_MODULE, .open = HgfsDirOpen, .read = generic_read_dir, .readdir = HgfsReaddir, .release = HgfsDirRelease, }; /* * Private function implementations. */ /* *---------------------------------------------------------------------- * * HgfsUnpackSearchReadReply -- * * This function abstracts the differences between a SearchReadV1 and * a SearchReadV2. The caller provides the packet containing the reply * and we populate the AttrInfo with version-independent information. * * Note that attr->requestType has already been populated so that we * know whether to expect a V1 or V2 reply. * * Results: * 0 on success, anything else on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsUnpackSearchReadReply(HgfsReq *req, // IN: Reply packet HgfsAttrInfo *attr, // IN/OUT: Attributes char **entryName) // OUT: file name { char *fileName; uint32 fileNameLength; uint32 replySize; int result; ASSERT(req); ASSERT(attr); result = HgfsUnpackCommonAttr(req, attr); if (result != 0) { return result; } switch(attr->requestType) { case HGFS_OP_SEARCH_READ_V3: { HgfsReplySearchReadV3 *replyV3; HgfsDirEntry *dirent; /* Currently V3 returns only 1 entry. */ replyV3 = (HgfsReplySearchReadV3 *)(HGFS_REP_PAYLOAD_V3(req)); replyV3->count = 1; replySize = HGFS_REP_PAYLOAD_SIZE_V3(replyV3) + sizeof *dirent; dirent = (HgfsDirEntry *)replyV3->payload; fileName = dirent->fileName.name; fileNameLength = dirent->fileName.length; break; } case HGFS_OP_SEARCH_READ_V2: { HgfsReplySearchReadV2 *replyV2; replyV2 = (HgfsReplySearchReadV2 *)(HGFS_REQ_PAYLOAD(req)); replySize = sizeof *replyV2; fileName = replyV2->fileName.name; fileNameLength = replyV2->fileName.length; break; } case HGFS_OP_SEARCH_READ: { HgfsReplySearchRead *replyV1; replyV1 = (HgfsReplySearchRead *)(HGFS_REQ_PAYLOAD(req)); replySize = sizeof *replyV1; fileName = replyV1->fileName.name; fileNameLength = replyV1->fileName.length; break; } default: LOG(4, (KERN_DEBUG "VMware hgfs: HgfsUnpackSearchReadReply: unexpected " "OP type encountered\n")); return -EPROTO; } /* * Make sure name length is legal. */ if (fileNameLength > NAME_MAX || fileNameLength > req->bufferSize - replySize) { return -ENAMETOOLONG; } /* * If the size of the name is valid (meaning the end of the directory has * not yet been reached), copy the name to the AttrInfo struct. * * XXX: This operation happens often and the length of the filename is * bounded by NAME_MAX. Perhaps I should just put a statically-sized * array in HgfsAttrInfo and use a slab allocator to allocate the struct. */ if (fileNameLength > 0) { /* Sanity check on name length. */ if (fileNameLength != strlen(fileName)) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsUnpackSearchReadReply: name " "length mismatch %u/%Zu, name \"%s\"\n", fileNameLength, strlen(fileName), fileName)); return -EPROTO; } *entryName = kmalloc(fileNameLength + 1, GFP_KERNEL); if (*entryName == NULL) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsUnpackSearchReadReply: out of " "memory allocating filename, ignoring\n")); return -ENOMEM; } memcpy(*entryName, fileName, fileNameLength + 1); } else { *entryName = NULL; } return 0; } /* *---------------------------------------------------------------------- * * HgfsGetNextDirEntry -- * * Get the directory entry with the given offset from the server. * * fileName gets allocated and must be freed by the caller. * * Results: * Returns zero on success, negative error on failure. If the * dentry's name is too long, -ENAMETOOLONG is returned. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsGetNextDirEntry(HgfsSuperInfo *si, // IN: Superinfo for this SB HgfsHandle searchHandle, // IN: Handle of dir uint32 offset, // IN: Offset of next dentry to get HgfsAttrInfo *attr, // OUT: File attributes of dentry char **entryName, // OUT: File name Bool *done) // OUT: Set true when there are // no more dentries { HgfsReq *req; HgfsOp opUsed; HgfsStatus replyStatus; int result = 0; ASSERT(si); ASSERT(attr); ASSERT(done); req = HgfsGetNewRequest(); if (!req) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsGetNextDirEntry: out of memory " "while getting new request\n")); return -ENOMEM; } retry: opUsed = hgfsVersionSearchRead; if (opUsed == HGFS_OP_SEARCH_READ_V3) { HgfsRequest *header; HgfsRequestSearchReadV3 *request; header = (HgfsRequest *)(HGFS_REQ_PAYLOAD(req)); header->op = attr->requestType = opUsed; header->id = req->id; request = (HgfsRequestSearchReadV3 *)(HGFS_REQ_PAYLOAD_V3(req)); request->search = searchHandle; request->offset = offset; request->flags = 0; request->reserved = 0; req->payloadSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); } else { HgfsRequestSearchRead *request; request = (HgfsRequestSearchRead *)(HGFS_REQ_PAYLOAD(req)); request->header.op = attr->requestType = opUsed; request->header.id = req->id; request->search = searchHandle; request->offset = offset; req->payloadSize = sizeof *request; } /* Send the request and process the reply. */ result = HgfsSendRequest(req); if (result == 0) { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsGetNextDirEntry: got reply\n")); replyStatus = HgfsReplyStatus(req); result = HgfsStatusConvertToLinux(replyStatus); switch(result) { case 0: result = HgfsUnpackSearchReadReply(req, attr, entryName); if (result == 0 && *entryName == NULL) { /* We're at the end of the directory. */ LOG(6, (KERN_DEBUG "VMware hgfs: HgfsGetNextDirEntry: end of " "dir\n")); *done = TRUE; } break; case -EPROTO: /* Retry with older version(s). Set globally. */ if (attr->requestType == HGFS_OP_SEARCH_READ_V3) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsGetNextDirEntry: Version 3 " "not supported. Falling back to version 2.\n")); hgfsVersionSearchRead = HGFS_OP_SEARCH_READ_V2; goto retry; } else if (attr->requestType == HGFS_OP_SEARCH_READ_V2) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsGetNextDirEntry: Version 2 " "not supported. Falling back to version 1.\n")); hgfsVersionSearchRead = HGFS_OP_SEARCH_READ; goto retry; } /* Fallthrough. */ default: break; } } else if (result == -EIO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsGetNextDirEntry: timed out\n")); } else if (result == -EPROTO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsGetNextDirEntry: server " "returned error: %d\n", result)); } else { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsGetNextDirEntry: unknown error: " "%d\n", result)); } HgfsFreeRequest(req); return result; } /* *---------------------------------------------------------------------- * * HgfsPackDirOpenRequest -- * * Setup the directory open request, depending on the op version. * * Results: * Returns zero on success, or negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsPackDirOpenRequest(struct file *file, // IN: File pointer for this open HgfsOp opUsed, // IN: Op to be used HgfsReq *req) // IN/OUT: Packet to write into { char *name; uint32 *nameLength; size_t requestSize; int result; ASSERT(file); ASSERT(req); switch (opUsed) { case HGFS_OP_SEARCH_OPEN_V3: { HgfsRequest *requestHeader; HgfsRequestSearchOpenV3 *requestV3; requestHeader = (HgfsRequest *)(HGFS_REQ_PAYLOAD(req)); requestHeader->op = opUsed; requestHeader->id = req->id; requestV3 = (HgfsRequestSearchOpenV3 *)HGFS_REQ_PAYLOAD_V3(req); /* We'll use these later. */ name = requestV3->dirName.name; nameLength = &requestV3->dirName.length; requestV3->dirName.flags = 0; requestV3->dirName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; requestV3->dirName.fid = HGFS_INVALID_HANDLE; requestV3->reserved = 0; requestSize = HGFS_REQ_PAYLOAD_SIZE_V3(requestV3); break; } case HGFS_OP_SEARCH_OPEN: { HgfsRequestSearchOpen *request; request = (HgfsRequestSearchOpen *)(HGFS_REQ_PAYLOAD(req)); request->header.op = opUsed; request->header.id = req->id; /* We'll use these later. */ name = request->dirName.name; nameLength = &request->dirName.length; requestSize = sizeof *request; break; } default: LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackDirOpenRequest: unexpected " "OP type encountered\n")); return -EPROTO; } /* Build full name to send to server. */ if (HgfsBuildPath(name, req->bufferSize - (requestSize - 1), file->f_dentry) < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackDirOpenRequest: build path failed\n")); return -EINVAL; } LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackDirOpenRequest: opening \"%s\"\n", name)); /* Convert to CP name. */ result = CPName_ConvertTo(name, req->bufferSize - (requestSize - 1), name); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackDirOpenRequest: CP conversion failed\n")); return -EINVAL; } *nameLength = (uint32) result; req->payloadSize = requestSize + result; return 0; } /* *---------------------------------------------------------------------- * * HgfsPrivateDirOpen -- * * Called by HgfsDirOpen() and HgfsReaddir() routines. * * Results: * Returns zero if on success, error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsPrivateDirOpen(struct file *file, // IN: File pointer for this open HgfsHandle *handle) // IN: Hgfs handle { HgfsReq *req; int result; HgfsOp opUsed; HgfsStatus replyStatus; HgfsHandle *replySearch; ASSERT(file); req = HgfsGetNewRequest(); if (!req) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateDirOpen: out of memory while " "getting new request\n")); result = -ENOMEM; goto out; } retry: opUsed = hgfsVersionSearchOpen; if (opUsed == HGFS_OP_SEARCH_OPEN_V3) { replySearch = &((HgfsReplySearchOpenV3 *)HGFS_REP_PAYLOAD_V3(req))->search; } else { replySearch = &((HgfsReplySearchOpen *)HGFS_REQ_PAYLOAD(req))->search; } result = HgfsPackDirOpenRequest(file, opUsed, req); if (result != 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateDirOpen error packing request\n")); goto out; } /* Send the request and process the reply. */ result = HgfsSendRequest(req); if (result == 0) { /* Get the reply and check return status. */ replyStatus = HgfsReplyStatus(req); result = HgfsStatusConvertToLinux(replyStatus); switch (result) { case 0: /* Save the handle value */ *handle = *replySearch; LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateDirOpen: Handle returned = %u\n", *replySearch)); break; case -EPROTO: /* Retry with older version(s). Set globally. */ if (opUsed == HGFS_OP_SEARCH_OPEN_V3) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateDirOpen: Version 3 not " "supported. Falling back to version 1.\n")); hgfsVersionSearchOpen = HGFS_OP_SEARCH_OPEN; goto retry; } LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateDirOpen: server " "returned error: %d\n", result)); break; default: LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateDirOpen: server " "returned error: %d\n", result)); break; } } else if (result == -EIO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateDirOpen: timed out\n")); } else if (result == -EPROTO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateDirOpen: server " "returned error: %d\n", result)); } else { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateDirOpen: unknown error: " "%d\n", result)); } out: HgfsFreeRequest(req); return result; } /* *---------------------------------------------------------------------- * * HgfsPrivateDirRelease -- * * Called by HgfsDirRelease() and HgfsReaddir() routines. * * Results: * Returns zero on success, or an error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsPrivateDirRelease(struct file *file, // IN: File for the dir getting released HgfsHandle handle) // IN: Hgfs handle { HgfsReq *req; HgfsStatus replyStatus; HgfsOp opUsed; int result = 0; ASSERT(file); ASSERT(file->f_dentry); ASSERT(file->f_dentry->d_sb); LOG(6, (KERN_DEBUG "VMware hgfs: HgfsPrivateDirRelease: close fh %u\n", handle)); req = HgfsGetNewRequest(); if (!req) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateDirRelease: out of memory while " "getting new request\n")); result = -ENOMEM; goto out; } retry: opUsed = hgfsVersionSearchClose; if (opUsed == HGFS_OP_SEARCH_CLOSE_V3) { HgfsRequestSearchCloseV3 *request; HgfsRequest *header; header = (HgfsRequest *)(HGFS_REQ_PAYLOAD(req)); header->id = req->id; header->op = opUsed; request = (HgfsRequestSearchCloseV3 *)(HGFS_REQ_PAYLOAD_V3(req)); request->search = handle; request->reserved = 0; req->payloadSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); } else { HgfsRequestSearchClose *request; request = (HgfsRequestSearchClose *)(HGFS_REQ_PAYLOAD(req)); request->header.id = req->id; request->header.op = opUsed; request->search = handle; req->payloadSize = sizeof *request; } /* Send the request and process the reply. */ result = HgfsSendRequest(req); if (result == 0) { /* Get the reply. */ replyStatus = HgfsReplyStatus(req); result = HgfsStatusConvertToLinux(replyStatus); switch (result) { case 0: LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateDirRelease: release handle %u\n", handle)); break; case -EPROTO: /* Retry with older version(s). Set globally. */ if (opUsed == HGFS_OP_SEARCH_CLOSE_V3) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateDirRelease: Version 3 not " "supported. Falling back to version 1.\n")); hgfsVersionSearchClose = HGFS_OP_SEARCH_CLOSE; goto retry; } break; default: LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateDirRelease: failed handle %u\n", handle)); break; } } else if (result == -EIO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateDirRelease: timed out\n")); } else if (result == -EPROTO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateDirRelease: server " "returned error: %d\n", result)); } else { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateDirRelease: unknown error: " "%d\n", result)); } out: HgfsFreeRequest(req); return result; } /* *---------------------------------------------------------------------- * * HgfsPrivateDirReOpen -- * * Reopens the file. Called by HgfsReaddir() routine. * * Results: * Returns zero if on success, error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsPrivateDirReOpen(struct file *file) // IN: File pointer for this open { int result = 0; HgfsHandle *handle = &FILE_GET_FI_P(file)->handle; LOG(4, (KERN_DEBUG "HgfsPrivateDirReOpen: Directory handle in invalid;" "Reopening ...\n")); result = HgfsPrivateDirRelease(file, *handle); if (result) { return result; } result = HgfsPrivateDirOpen(file, handle); if (result) { return result; } FILE_GET_FI_P(file)->isStale = FALSE; return result; } /* * HGFS file operations for directories. */ /* *---------------------------------------------------------------------- * * HgfsDirLlseek -- * * Called whenever a process does rewinddir() or telldir()/seekdir(). * * Results: * Returns zero if on success, error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static loff_t HgfsDirLlseek(struct file *file, loff_t offset, int origin) { struct dentry *dentry = file->f_dentry; struct inode *inode = dentry->d_inode; compat_mutex_t *mtx; LOG(4, (KERN_DEBUG "Got llseek call with origin = %d, offset = %u," "pos = %u\n", origin, (uint32)offset, (uint32)file->f_pos)); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) mtx = &inode->i_sem; #else mtx = &inode->i_mutex; #endif compat_mutex_lock(mtx); switch(origin) { /* SEEK_CUR */ case 1: offset += file->f_pos; break; /* SEEK_SET */ case 0: break; /* SEEK_END */ case 2: default: offset = -EINVAL; break; } if (offset < 0) { offset = -EINVAL; goto out; } if (offset != file->f_pos) { file->f_pos = offset; } /* * rewinddir() semantics says that It causes the directory stream * to refer to the current state of the corresponding directory, * as a call to opendir would have done. So when rewinddir() happens, * we mark current directory as stale, so that subsequent readdir() * call will reopen() the directory. * * XXX telldir()/seekdir() semantics does not say that we need to refer * to the current state of a directory. However, an application that does * following: telldir() -> rmdir(current_entry) -> seekdir() and checking * whether entry was deleted or not, will break. I have no evidence of an * application relying on above behavior, so let's not incur extra cost * by reopening directory on telldir()/seekdir() combination. Note: A special * case of telldir()/seekdir() to offset 0 will behave same as rewinddir(). */ if (!file->f_pos) { FILE_GET_FI_P(file)->isStale = TRUE; } out: compat_mutex_unlock(mtx); return offset; } /* *---------------------------------------------------------------------- * * HgfsDirOpen -- * * Called whenever a process opens a directory in our filesystem. * * We send a "Search Open" request to the server with the name * stored in this file's inode. If the Open succeeds, we store the * search handle sent by the server in the file struct so it can be * accessed by readdir and close. * * Results: * Returns zero if on success, error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsDirOpen(struct inode *inode, // IN: Inode of the dir to open struct file *file) // IN: File pointer for this open { int result; HgfsHandle handle; ASSERT(inode); ASSERT(inode->i_sb); ASSERT(file); result = HgfsPrivateDirOpen(file, &handle); if (!result) { result = HgfsCreateFileInfo(file, handle); } return result; } /* *---------------------------------------------------------------------- * * HgfsReaddir -- * * Handle a readdir request. See details below if interested. * * Readdir is a bit complicated, and is best understood by reading * the code. For the impatient, here is an overview of the major * moving parts [bac]: * * - Getdents syscall calls readdir, which is supposed to call * filldir some number of times. * - Each time it's called, filldir updates a struct with the * number of bytes copied thus far, and sets an error code if * appropriate. * - When readdir returns, getdents checks the struct to see if * any dentries were copied, and if so returns the byte count. * Otherwise, it returns the error from the struct (which should * still be zero if filldir was never called). * * A consequence of this last fact is that if there are no more * dentries, then readdir should NOT call filldir, and should * return from readdir with a non-error. * * Other notes: * * - Passing an inum of zero to filldir doesn't work. At a minimum, * you have to make up a bogus inum for each dentry. * - Passing the correct d_type to filldir seems to be non-critical; * apparently most programs (such as ls) stat each file if they * really want to know what type it is. However, passing the * correct type means that ls doesn't bother calling stat on * directories, and that saves an entire round trip per dirctory * dentry. * * Results: * Returns zero if on success, negative error on failure. * (According to /fs/readdir.c, any non-negative return value * means it succeeded). * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsReaddir(struct file *file, // IN: Directory to read from void *dirent, // OUT: Buffer to copy dentries into filldir_t filldir) // IN: Filler function { HgfsSuperInfo *si; HgfsAttrInfo attr; uint32 d_type; // type of dirent char *fileName = NULL; char *escName = NULL; // buf for escaped version of name size_t escNameLength = NAME_MAX + 1; int nameLength = 0; int result = 0; Bool done = FALSE; Bool isStale = FALSE; ino_t ino; ASSERT(file); ASSERT(dirent); if (!file || !(file->f_dentry) || !(file->f_dentry->d_inode)) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsReaddir: null input\n")); return -EFAULT; } ASSERT(file->f_dentry->d_inode->i_sb); si = HGFS_SB_TO_COMMON(file->f_dentry->d_inode->i_sb); LOG(6, (KERN_DEBUG "VMware hgfs: HgfsReaddir: dir with name %s, " "inum %lu, f_pos %Lu\n", file->f_dentry->d_name.name, file->f_dentry->d_inode->i_ino, file->f_pos)); /* * rm -rf 6.10+ breaks because it does following: * an 'fd = open()' on a directory, followed by unlinkat() * which removes an entry from the directory it and then * fdopendir(fd). We get a call on open() but not on fdopendir(), * which means that we do not reflect the action of unlinkat(), * and thus rm -rf gets confused and marking entry as unremovable. * Note that this problem exists because hgfsServer reads all * the directory entries at open(). Interested reader may look at * coreutils/src/remove.c file. * * So as a workaround, we ask the server to populate entries on * first readdir() call rather than opendir(). This effect is * achieved by closing and reopening the directory. Grrr! * * XXX We should get rid of this code when/if we remove the above * behavior from hgfsServer. */ isStale = FILE_GET_FI_P(file)->isStale; if (isStale) { result = HgfsPrivateDirReOpen(file); if (result) { return result; } } /* * Some day when we're out of things to do we can move this to a slab * allocator. */ escName = kmalloc(escNameLength, GFP_KERNEL); if (!escName) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsReaddir: out of memory allocating " "escaped name buffer\n")); return -ENOMEM; } while (1) { /* * Nonzero result = we failed to get valid reply from server. * Zero result: * - done == TRUE means we hit the end of the directory * - Otherwise, fileName has the name of the next dirent * */ result = HgfsGetNextDirEntry(si, FILE_GET_FI_P(file)->handle, (uint32)file->f_pos, &attr, &fileName, &done); if (result == -ENAMETOOLONG) { /* * Skip dentry if its name is too long (see below). * * XXX: If a bad server sends us bad packets, we can loop here * forever, as I did while testing *grumble*. Maybe we should error * in that case. */ file->f_pos++; continue; } else if (result) { /* Error */ LOG(4, (KERN_DEBUG "VMware hgfs: HgfsReaddir: error " "getting dentry\n")); kfree(escName); return result; } if (done == TRUE) { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsReaddir: end of dir reached\n")); break; } /* * Escape all non-printable characters (which for linux is just * "/"). * * Note that normally we would first need to convert from the * CP name format, but that is done implicitely here since we * are guaranteed to have just one path component per dentry. */ result = HgfsEscape_Do(fileName, strlen(fileName), escNameLength, escName); kfree(fileName); fileName = NULL; /* * Check the filename length. * * If the name is too long to be represented in linux, we simply * skip it (i.e., that file is not visible to our filesystem) by * incrementing file->f_pos and repeating the loop to get the * next dentry. * * HgfsEscape_Do returns a negative value if the escaped * output didn't fit in the specified output size, so we can * just check its return value. */ if (result < 0) { /* * XXX: Another area where a bad server could cause us to loop * forever. */ file->f_pos++; continue; } nameLength = result; /* Assign the correct dentry type. */ switch (attr.type) { case HGFS_FILE_TYPE_SYMLINK: d_type = DT_LNK; break; case HGFS_FILE_TYPE_REGULAR: d_type = DT_REG; break; case HGFS_FILE_TYPE_DIRECTORY: d_type = DT_DIR; break; default: /* * XXX Should never happen. I'd put NOT_IMPLEMENTED() here * but if the driver ever goes in the host it's probably not * a good idea for an attacker to be able to hang the host * simply by using a bogus file type in a reply. [bac] * * Well it happens! Refer bug 548177 for details. In short, * when the user deletes a share, we hit this code path. * */ d_type = DT_UNKNOWN; break; } /* * It is unfortunate, but the HGFS server sends back '.' and ".." * when we do a SearchRead. In an ideal world, these would be faked * on the client, but it would be a real backwards-compatibility * hassle to change the behavior at this point. * * So instead, we'll take the '.' and ".." and modify their inode * numbers so they match what the client expects. */ if (!strncmp(escName, ".", sizeof ".")) { ino = file->f_dentry->d_inode->i_ino; } else if (!strncmp(escName, "..", sizeof "..")) { ino = compat_parent_ino(file->f_dentry); } else { if (attr.mask & HGFS_ATTR_VALID_FILEID) { ino = attr.hostFileId; } else { ino = iunique(file->f_dentry->d_inode->i_sb, HGFS_RESERVED_INO); } } /* * Call filldir for this dentry. */ LOG(6, (KERN_DEBUG "VMware hgfs: HgfsReaddir: calling filldir " "with \"%s\", %u, %Lu\n", escName, nameLength, file->f_pos)); result = filldir(dirent, /* filldir callback struct */ escName, /* name of dirent */ nameLength, /* length of name */ file->f_pos, /* offset of dirent */ ino, /* inode number (0 makes it not show) */ d_type); /* type of dirent */ if (result) { /* * This means that filldir ran out of room in the user buffer * it was copying into; we just break out and return, but * don't increment f_pos. So the next time the user calls * getdents, this dentry will be requested again, will get * retrieved again, and get copied properly to the user. */ break; } file->f_pos++; } LOG(6, (KERN_DEBUG "VMware hgfs: HgfsReaddir: finished\n")); kfree(escName); return 0; } /* *---------------------------------------------------------------------- * * HgfsDirRelease -- * * Called when the last reader of a directory closes it, i.e. when * the directory's file f_count field becomes zero. * * Results: * Returns zero on success, or an error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsDirRelease(struct inode *inode, // IN: Inode that the file* points to struct file *file) // IN: File for the dir getting released { HgfsHandle handle; ASSERT(inode); ASSERT(file); ASSERT(file->f_dentry); ASSERT(file->f_dentry->d_sb); handle = FILE_GET_FI_P(file)->handle; HgfsReleaseFileInfo(file); return HgfsPrivateDirRelease(file, handle); } open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/fsutil.h0000644765153500003110000000742612220061556021230 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * fsutil.h -- * * Functions used in more than one type of filesystem operation will be * exported from this file. */ #ifndef _HGFS_DRIVER_FSUTIL_H_ #define _HGFS_DRIVER_FSUTIL_H_ /* Must come before any kernel header file. */ #include "driver-config.h" #include #include "compat_fs.h" #include "inode.h" #include "request.h" #include "vm_basic_types.h" #include "hgfsProto.h" /* * Struct used to pass around attributes that Linux cares about. * These aren't just the attributes seen in HgfsAttr[V2]; we add a filename * pointer for convenience (used by SearchRead and Getattr). */ typedef struct HgfsAttrInfo { HgfsOp requestType; HgfsAttrValid mask; HgfsFileType type; /* File type */ uint64 size; /* File size (in bytes) */ uint64 accessTime; /* Time of last access */ uint64 writeTime; /* Time of last write */ uint64 attrChangeTime; /* Time file attributes were last changed */ HgfsPermissions specialPerms; /* Special permissions bits */ HgfsPermissions ownerPerms; /* Owner permissions bits */ HgfsPermissions groupPerms; /* Group permissions bits */ HgfsPermissions otherPerms; /* Other permissions bits */ HgfsPermissions effectivePerms; /* Permissions in effect for the user on the host. */ uint32 userId; /* UID */ uint32 groupId; /* GID */ uint64 hostFileId; /* Inode number */ } HgfsAttrInfo; /* Public functions (with respect to the entire module). */ int HgfsUnpackCommonAttr(HgfsReq *req, HgfsAttrInfo *attr); void HgfsChangeFileAttributes(struct inode *inode, HgfsAttrInfo const *attr); int HgfsPrivateGetattr(struct dentry *dentry, HgfsAttrInfo *attr, char **fileName); struct inode *HgfsIget(struct super_block *sb, ino_t ino, HgfsAttrInfo const *attr); int HgfsInstantiate(struct dentry *dentry, ino_t ino, HgfsAttrInfo const *attr); int HgfsBuildPath(char *buffer, size_t bufferLen, struct dentry *dentry); void HgfsDentryAgeReset(struct dentry *dentry); void HgfsDentryAgeForce(struct dentry *dentry); int HgfsGetOpenMode(uint32 flags); int HgfsCreateFileInfo(struct file *file, HgfsHandle handle); void HgfsReleaseFileInfo(struct file *file); int HgfsGetHandle(struct inode *inode, HgfsOpenMode mode, HgfsHandle *handle); int HgfsStatusConvertToLinux(HgfsStatus hgfsStatus); void HgfsSetUidGid(struct inode *parent, struct dentry *dentry, uid_t uid, gid_t gid); struct inode *HgfsGetInode(struct super_block *sb, ino_t ino); void HgfsDoReadInode(struct inode *inode); #endif // _HGFS_DRIVER_FSUTIL_H_ open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/transport.h0000644765153500003110000000524212220061556021750 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * transport.h -- */ #ifndef _HGFS_DRIVER_TRANSPORT_H_ #define _HGFS_DRIVER_TRANSPORT_H_ #include "request.h" #include "compat_mutex.h" #include "hgfsProto.h" /* * There are the operations a channel should implement. */ struct HgfsTransportChannel; typedef struct HgfsTransportChannelOps { Bool (*open)(struct HgfsTransportChannel *); void (*close)(struct HgfsTransportChannel *); HgfsReq* (*allocate)(size_t payloadSize); int (*send)(struct HgfsTransportChannel *, HgfsReq *); void (*free)(HgfsReq *); } HgfsTransportChannelOps; typedef enum { HGFS_CHANNEL_UNINITIALIZED, HGFS_CHANNEL_NOTCONNECTED, HGFS_CHANNEL_CONNECTED, HGFS_CHANNEL_DEAD, /* Error has been detected, need to shut it down. */ } HgfsChannelStatus; typedef struct HgfsTransportChannel { const char *name; /* Channel name. */ HgfsTransportChannelOps ops; /* Channel ops. */ HgfsChannelStatus status; /* Connection status. */ void *priv; /* Channel private data. */ compat_mutex_t connLock; /* Protect _this_ struct. */ } HgfsTransportChannel; /* Public functions (with respect to the entire module). */ void HgfsTransportInit(void); void HgfsTransportExit(void); HgfsReq *HgfsTransportAllocateRequest(size_t payloadSize); void HgfsTransportFreeRequest(HgfsReq *req); int HgfsTransportSendRequest(HgfsReq *req); HgfsReq *HgfsTransportGetPendingRequest(HgfsHandle id); void HgfsTransportRemovePendingRequest(HgfsReq *req); void HgfsTransportFinishRequest(HgfsReq *req, Bool success, Bool do_put); void HgfsTransportFlushRequests(void); void HgfsTransportMarkDead(void); HgfsTransportChannel* HgfsGetVmciChannel(void); HgfsTransportChannel* HgfsGetTcpChannel(void); HgfsTransportChannel* HgfsGetVSocketChannel(void); HgfsTransportChannel *HgfsGetBdChannel(void); #endif // _HGFS_DRIVER_TRANSPORT_H_ open-vm-tools-9.4.0-1280544/modules/linux/vmhgfs/link.c0000644765153500003110000001217212220061556020644 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * link.c -- * * Symlink-specific inode operations for the filesystem portion of the * vmhgfs driver. */ /* Must come before any kernel header file. */ #include "driver-config.h" #include "compat_fs.h" #include "compat_namei.h" #include "module.h" #include "hgfsProto.h" #include "fsutil.h" #include "vm_assert.h" /* HGFS symlink operations. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) static void *HgfsFollowlink(struct dentry *dentry, struct nameidata *nd); #else static int HgfsFollowlink(struct dentry *dentry, struct nameidata *nd); #endif static int HgfsReadlink(struct dentry *dentry, char __user *buffer, int buflen); /* HGFS inode operations structure for symlinks. */ struct inode_operations HgfsLinkInodeOperations = { .follow_link = HgfsFollowlink, .readlink = HgfsReadlink, }; /* * HGFS symlink operations. */ /* *---------------------------------------------------------------------- * * HgfsFollowlink -- * * Modeled after nfs_follow_link from a 2.4 kernel so it'll work * across all kernel revisions we care about. * * Results: * Returns zero on success, negative error on failure. * * On new kernels: The error is returned as void *. * On older kernels: The error is returned as is. * * Side effects: * None * *---------------------------------------------------------------------- */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) static void * HgfsFollowlink(struct dentry *dentry, // IN: Dentry containing link struct nameidata *nd) // OUT: Contains target dentry #else static int HgfsFollowlink(struct dentry *dentry, // IN: Dentry containing link struct nameidata *nd) // OUT: Contains target dentry #endif { HgfsAttrInfo attr; char *fileName = NULL; int error; ASSERT(dentry); ASSERT(nd); if (!dentry) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsFollowlink: null input\n")); error = -EINVAL; goto out; } LOG(6, (KERN_DEBUG "VMware hgfs: HgfsFollowlink: calling " "HgfsPrivateGetattr\n")); error = HgfsPrivateGetattr(dentry, &attr, &fileName); if (!error) { /* Let's make sure we got called on a symlink. */ if (attr.type != HGFS_FILE_TYPE_SYMLINK || fileName == NULL) { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsFollowlink: got called " "on something that wasn't a symlink\n")); error = -EINVAL; } else { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsFollowlink: calling " "vfs_follow_link\n")); error = vfs_follow_link(nd, fileName); } kfree(fileName); } out: #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) return ERR_PTR(error); #else return error; #endif } /* *---------------------------------------------------------------------- * * HgfsReadlink -- * * Modeled after nfs_read_link from a 2.4 kernel so it'll work * across all kernel revisions we care about. * * Results: * Returns zero on success, negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsReadlink(struct dentry *dentry, // IN: Dentry containing link char __user *buffer, // OUT: User buffer to copy link into int buflen) // IN: Length of user buffer { HgfsAttrInfo attr; char *fileName = NULL; int error; ASSERT(dentry); ASSERT(buffer); if (!dentry) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsReadlink: null input\n")); return -EINVAL; } LOG(6, (KERN_DEBUG "VMware hgfs: HgfsReadlink: calling " "HgfsPrivateGetattr\n")); error = HgfsPrivateGetattr(dentry, &attr, &fileName); if (!error) { /* Let's make sure we got called on a symlink. */ if (attr.type != HGFS_FILE_TYPE_SYMLINK || fileName == NULL) { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsReadlink: got called " "on something that wasn't a symlink\n")); error = -EINVAL; } else { LOG(6, (KERN_DEBUG "VMware hgfs: HgfsReadlink: calling " "vfs_readlink\n")); error = vfs_readlink(dentry, buffer, buflen, fileName); } kfree(fileName); } return error; } open-vm-tools-9.4.0-1280544/modules/freebsd/0000755765153500003110000000000012220061556016521 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/freebsd/vmxnet/0000755765153500003110000000000012220061556020042 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/freebsd/vmxnet/net_compat.h0000644765153500003110000001456312220061556022355 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * net_compat.h: * This file contains wrapper macros that abstract out * the differences between FreeBSD 4.x, 5.x and 6.x in * network related kernel calls used in if_vxn.c. */ #ifndef _VXN_NET_COMPAT_H_ #define _VXN_NET_COMPAT_H_ #if __FreeBSD_version < 500009 #define VXN_ETHER_IFATTACH(ifp, llc) (ether_ifattach(ifp, ETHER_BPF_SUPPORTED)) #define VXN_ETHER_IFDETACH(ifp) (ether_ifdetach(ifp, ETHER_BPF_SUPPORTED)) #else /* >= 500009 */ #define VXN_ETHER_IFATTACH(ifp, llc) (ether_ifattach(ifp, llc)) #define VXN_ETHER_IFDETACH(ifp) (ether_ifdetach(ifp)) #endif /* 500009 */ #if __FreeBSD_version < 500016 #define VXN_IFMULTI_FIRST LIST_FIRST #define VXN_IFMULTI_NEXT LIST_NEXT #else /* >= 500016 */ #define VXN_IFMULTI_FIRST TAILQ_FIRST #define VXN_IFMULTI_NEXT TAILQ_NEXT #endif /* 500016 */ #if __FreeBSD_version < 500043 /* * This code used to be in our if_vxn.c; it is now included in * FreeBSD's ether_input(). */ #define VXN_ETHER_INPUT(ifp, m) do { \ struct ether_header *eh = mtod((m), struct ether_header *); \ m_adj(m, sizeof(struct ether_header)); \ ether_input((ifp), eh, (m)); \ } while (0) #define VXN_BPF_MTAP(ifp, m) do { \ if ((ifp)->if_bpf) \ bpf_mtap((ifp), (m)); \ } while (0) #else /* >= 500043 */ #define VXN_ETHER_INPUT(ifp, m) ((*(ifp)->if_input)(ifp, m)) #define VXN_BPF_MTAP(ifp, m) BPF_MTAP(ifp, m) #endif /* 500043 */ #if __FreeBSD_version < 501113 #define VXN_IF_UNIT(ifp) ((ifp)->if_unit) #define VXN_IF_INITNAME(ifp, name, unit) do { \ (ifp)->if_name = (char *)(name); \ (ifp)->if_unit = (unit); \ } while (0) #else /* >= 501113 */ #define VXN_IF_UNIT(ifp) ((ifp)->if_dunit) #define VXN_IF_INITNAME(ifp, name, unit) (if_initname(ifp, name, unit)) #endif /* 501113 */ /* * In FreeBSD 6.x, ifnet struct handling has changed. * * On older releases, each NIC driver's softc structure * started with an ifnet struct, nested within an arpcom. * * struct vxn_softc { * struct arpcom { * struct ifnet { * void *if_softc; * ... * } ac_if; * u_char ac_enaddr[6]; * ... * } ; * ... * }; * * In FreeBSD 6.x, the ifnet struct is now a pointer * returned from if_alloc() and if_alloc() allocates * space for if_l2com. * * Accessing the link layer address via arpcom's ac_enaddr was deprecated as * of sys/net/if_var.h:1.98, and drivers are to instead get/set said address * through the embedded ifnet structure. So with FreeBSD 6 and above, we * instead define vxn_softc as follows and rely on FreeBSD's macro glue for * easy access to the LL-address. * * struct vxn_softc { * struct ifnet *vxn_ifp; * ... * }; */ #if __FreeBSD_version < 600000 /* Pre-FreeBSD 6.0-RELEASE */ #define VXN_NEEDARPCOM #define VXN_IF_ALLOC(softc) (&(softc)->arpcom.ac_if) #define VXN_IF_FREE(softc) #define VXN_SC2IFP(softc) (&(softc)->arpcom.ac_if) #define VXN_PCIR_MAPS PCIR_MAPS #define VXN_IFF_RUNNING IFF_RUNNING #define VXN_IFF_OACTIVE IFF_OACTIVE #define VXN_SET_IF_DRV_FLAGS(ifp, flags) \ ((ifp)->if_flags |= (flags)) #define VXN_CLR_IF_DRV_FLAGS(ifp, flags) \ ((ifp)->if_flags &= ~(flags)) #define VXN_GET_IF_DRV_FLAGS(ifp) \ ((ifp)->if_flags) #else /* FreeBSD 6.x+ */ #define VXN_IF_ALLOC(softc) ((softc)->vxn_ifp = if_alloc(IFT_ETHER)) #define VXN_IF_FREE(softc) if_free((softc)->vxn_ifp) #define VXN_SC2IFP(softc) ((softc)->vxn_ifp) #define VXN_PCIR_MAPS PCIR_BARS #define VXN_IFF_RUNNING IFF_DRV_RUNNING #define VXN_IFF_OACTIVE IFF_DRV_OACTIVE #define VXN_SET_IF_DRV_FLAGS(ifp, flags) \ ((ifp)->if_drv_flags |= (flags)) #define VXN_CLR_IF_DRV_FLAGS(ifp, flags) \ ((ifp)->if_drv_flags &= ~(flags)) #define VXN_GET_IF_DRV_FLAGS(ifp) \ ((ifp)->if_drv_flags) #endif #ifdef VXN_MPSAFE # define VXN_MTX_INIT(mtx, name, type, opts) \ mtx_init(mtx, name, type, opts) # define VXN_MTX_DESTROY(mtx) mtx_destroy(mtx) # define VXN_LOCK(_sc) mtx_lock(&(_sc)->vxn_mtx) # define VXN_UNLOCK(_sc) mtx_unlock(&(_sc)->vxn_mtx) # define VXN_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->vxn_mtx, MA_OWNED) # define VXN_IFQ_IS_EMPTY(_ifq) IFQ_DRV_IS_EMPTY((_ifq)) #else # define VXN_MTX_INIT(mtx, name, type, opts) # define VXN_MTX_DESTROY(mtx) # define VXN_LOCK(_sc) # define VXN_UNLOCK(_sc) # define VXN_LOCK_ASSERT(_sc) # define VXN_IFQ_IS_EMPTY(_ifq) ((_ifq)->ifq_head == NULL) #endif /* * sys/net/if_var.h ver 1.100 introduced struct ifnet::if_addr_mtx to protect * address lists. We're particularly concerned with the list of multicast * addresses, if_multiaddrs, as our driver traverses this list during mcast * filter setup. (MFC'd for RELENG_5_5.) */ #if __FreeBSD_version < 505000 # define VXN_IF_ADDR_LOCK(_ifp) # define VXN_IF_ADDR_UNLOCK(_ifp) #else # define VXN_IF_ADDR_LOCK(_ifp) IF_ADDR_LOCK((_ifp)) # define VXN_IF_ADDR_UNLOCK(_ifp) IF_ADDR_UNLOCK((_ifp)) #endif #endif /* _VXN_NET_COMPAT_H_ */ open-vm-tools-9.4.0-1280544/modules/freebsd/vmxnet/COPYING0000644765153500003110000004310312220061556021076 0ustar dtormts GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. open-vm-tools-9.4.0-1280544/modules/freebsd/vmxnet/Makefile0000644765153500003110000000254412220061556021507 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 2007 VMware, Inc. All rights reserved. # # 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 version 2 and no later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ########################################################## #### #### vmxnet Makefile (for FreeBSD guest OS) #### CSRCS = if_vxn.c HEADERS := opt_bdg.h HEADERS += device_if.h HEADERS += bus_if.h HEADERS += pci_if.h SRCS = $(CSRCS) $(HEADERS) KMOD = vmxnet PROG = ../$(KMOD).ko NOMAN = t NO_MAN = t KLDMOD = t # Don't print a warning that the object dir wasn't specified NOOBJ = 1 NO_OBJ = 1 .ifdef OVT_SOURCE_DIR CFLAGS += -I$(OVT_SOURCE_DIR)/lib/include CFLAGS += -I$(OVT_SOURCE_DIR)/modules/shared/vmxnet .else CFLAGS += -Ishared .endif .include open-vm-tools-9.4.0-1280544/modules/freebsd/vmxnet/if_vxn.c0000644765153500003110000011634312220061556021507 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #include #include #include #include #include #include #include #include /* * FreeBSD 5.3 introduced an MP-safe (multiprocessor-safe) network stack. * I.e., drivers must either request Giant's protection or handle locking * themselves. For performance reasons, the vmxnet driver is now MPSAFE. */ #if __FreeBSD_version >= 503000 # define VXN_MPSAFE # include # include #endif /* * FreeBSD 7.0-RELEASE changed the bus_setup_intr API to include a device_filter_t * parameter. */ #if __FreeBSD_version >= 700031 # define VXN_NEWNEWBUS #endif #if __FreeBSD_version < 600000 #include #else #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if __FreeBSD__ >= 5 #include #include #else #include #include #endif /* define INLINE the way gcc likes it */ #define INLINE __inline__ #ifndef VMX86_TOOLS #define VMX86_TOOLS #endif #include "vm_basic_types.h" #include "vmxnet_def.h" #include "vmxnet2_def.h" #include "vm_device_version.h" #include "net_compat.h" #define VMXNET_ID_STRING "VMware PCI Ethernet Adpater" #define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */ #define ETHER_ALIGN 2 /* number of milliseconds to wait for pending transmits to complete on stop */ #define MAX_TX_WAIT_ON_STOP 2000 static int vxn_probe (device_t); static int vxn_attach (device_t); static int vxn_detach (device_t); typedef struct vxn_softc { #ifdef VXN_NEEDARPCOM struct arpcom arpcom; #else struct ifnet *vxn_ifp; struct ifmedia media; #endif #ifdef VXN_MPSAFE struct mtx vxn_mtx; #endif struct resource *vxn_io; bus_space_handle_t vxn_iobhandle; bus_space_tag_t vxn_iobtag; struct resource *vxn_irq; void *vxn_intrhand; Vmxnet2_DriverData *vxn_dd; uint32 vxn_dd_phys; int vxn_num_rx_bufs; int vxn_num_tx_bufs; Vmxnet2_RxRingEntry *vxn_rx_ring; Vmxnet2_TxRingEntry *vxn_tx_ring; int vxn_tx_pending; int vxn_rings_allocated; uint32 vxn_max_tx_frags; struct mbuf *vxn_tx_buffptr[VMXNET2_MAX_NUM_TX_BUFFERS]; struct mbuf *vxn_rx_buffptr[VMXNET2_MAX_NUM_RX_BUFFERS]; } vxn_softc_t; /* * Driver entry points */ static void vxn_init(void *); static void vxn_start(struct ifnet *); static int vxn_ioctl(struct ifnet *, u_long, caddr_t); #if __FreeBSD_version < 900000 static void vxn_watchdog(struct ifnet *); #endif static void vxn_intr (void *); static void vxn_rx(vxn_softc_t *sc); static void vxn_tx_complete(vxn_softc_t *sc); static int vxn_init_rings(vxn_softc_t *sc); static void vxn_release_rings(vxn_softc_t *); static void vxn_stop(vxn_softc_t *); /* * Locked counterparts above functions */ static void vxn_initl(vxn_softc_t *); static void vxn_startl(struct ifnet *); static void vxn_stopl(vxn_softc_t *); static device_method_t vxn_methods[] = { DEVMETHOD(device_probe, vxn_probe), DEVMETHOD(device_attach, vxn_attach), DEVMETHOD(device_detach, vxn_detach), { 0, 0 } }; static driver_t vxn_driver = { "vxn", vxn_methods, sizeof(struct vxn_softc) }; static devclass_t vxn_devclass; MODULE_DEPEND(if_vxn, pci, 1, 1, 1); DRIVER_MODULE(if_vxn, pci, vxn_driver, vxn_devclass, 0, 0); /* *----------------------------------------------------------------------------- * vxn_probe -- * Probe device. Called when module is loaded * * Results: * Returns 0 for success, negative errno value otherwise. * * Side effects: * Register device name with OS *----------------------------------------------------------------------------- */ static int vxn_probe(device_t dev) { if ((pci_get_vendor(dev) == PCI_VENDOR_ID_VMWARE) && (pci_get_device(dev) == PCI_DEVICE_ID_VMWARE_NET)) { device_set_desc(dev, VMXNET_ID_STRING); return 0; } return ENXIO; } /* *----------------------------------------------------------------------------- * vxn_execute_4 -- * Execute command returing 4 bytes on vmxnet. Used to retrieve * number of TX/RX buffers and to get hardware capabilities and * features. * * Results: * Returns value reported by hardware. * * Side effects: * All commands supported are read-only, so no side effects. *----------------------------------------------------------------------------- */ static u_int32_t vxn_execute_4(const vxn_softc_t *sc, /* IN: adapter */ u_int32_t cmd) /* IN: command */ { bus_space_write_4(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_COMMAND_ADDR, cmd); return bus_space_read_4(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_COMMAND_ADDR); } static int vxn_check_link(vxn_softc_t *sc) { uint32 status; int ok; status = bus_space_read_4(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_STATUS_ADDR); ok = (status & VMXNET_STATUS_CONNECTED) != 0; return ok; } /* *----------------------------------------------------------------------------- * * vxn_media_status -- * * This routine is called when the user quries the status of interface * using ifconfig. Checks link state and updates media state accorgingly. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void vxn_media_status(struct ifnet * ifp, struct ifmediareq * ifmr) { vxn_softc_t *sc = ifp->if_softc; int connected = 0; VXN_LOCK((vxn_softc_t *)ifp->if_softc); connected = vxn_check_link(sc); ifmr->ifm_status = IFM_AVALID; ifmr->ifm_active = IFM_ETHER; if (!connected) { ifmr->ifm_status &= ~IFM_ACTIVE; VXN_UNLOCK((vxn_softc_t *)ifp->if_softc); return; } ifmr->ifm_status |= IFM_ACTIVE; VXN_UNLOCK((vxn_softc_t *)ifp->if_softc); return; } /* *----------------------------------------------------------------------------- * * vxn_media_change -- * * This routine is called when the user changes speed/duplex using * media/mediopt option with ifconfig. * * Results: * Returns 0 for success, error code otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int vxn_media_change(struct ifnet * ifp) { vxn_softc_t *sc = ifp->if_softc; struct ifmedia *ifm = &sc->media; if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) return (EINVAL); if (IFM_SUBTYPE(ifm->ifm_media) != IFM_AUTO) printf("Media subtype is not AUTO, it is : %d.\n", IFM_SUBTYPE(ifm->ifm_media)); return (0); } /* *----------------------------------------------------------------------------- * vxn_attach -- * Initialize data structures and attach driver to stack * * Results: * Returns 0 for success, negative errno value otherwise. * * Side effects: * Check device version number. Map interrupts. *----------------------------------------------------------------------------- */ static int vxn_attach(device_t dev) { struct ifnet *ifp = NULL; int error = 0; int s, i; vxn_softc_t *sc; int unit; int rid; u_int32_t r; u_int32_t vLow, vHigh; int driverDataSize; u_char mac[6]; s = splimp(); unit = device_get_unit(dev); sc = device_get_softc(dev); VXN_MTX_INIT(&sc->vxn_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF); sc->vxn_io = NULL; sc->vxn_irq = NULL; sc->vxn_intrhand = NULL; sc->vxn_dd = NULL; sc->vxn_tx_pending = 0; sc->vxn_rings_allocated = 0; sc->vxn_max_tx_frags = 1; pci_enable_busmaster(dev); /* * enable the I/O ports on the device */ pci_enable_io(dev, SYS_RES_IOPORT); r = pci_read_config(dev, PCIR_COMMAND, 4); if (!(r & PCIM_CMD_PORTEN)) { printf("vxn%d: failed to enable I/O ports\n", unit); error = ENXIO; goto fail; } rid = VXN_PCIR_MAPS; sc->vxn_io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); if (sc->vxn_io == NULL) { printf ("vxn%d: couldn't map I/O ports\n", unit); error = ENXIO; goto fail; } sc->vxn_iobtag = rman_get_bustag(sc->vxn_io); sc->vxn_iobhandle = rman_get_bushandle(sc->vxn_io); /* * check the version number of the device implementation */ vLow = bus_space_read_4(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_LOW_VERSION); vHigh = bus_space_read_4(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_HIGH_VERSION); if ((vLow & 0xffff0000) != (VMXNET2_MAGIC & 0xffff0000)) { printf("vxn%d: driver version 0x%08X doesn't match %s version 0x%08X\n", unit, VMXNET2_MAGIC, "VMware", rid); error = ENXIO; goto fail; } else { if ((VMXNET2_MAGIC < vLow) || (VMXNET2_MAGIC > vHigh)) { printf("vxn%d: driver version 0x%08X doesn't match %s version 0x%08X,0x%08X\n", unit, VMXNET2_MAGIC, "VMware", vLow, vHigh); error = ENXIO; goto fail; } } /* * map interrupt for the the device */ rid = 0; sc->vxn_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE); if (sc->vxn_irq == NULL) { printf("vxn%d: couldn't map interrupt\n", unit); error = ENXIO; goto fail; } #if defined(VXN_NEWNEWBUS) error = bus_setup_intr(dev, sc->vxn_irq, INTR_TYPE_NET | INTR_MPSAFE, NULL, vxn_intr, sc, &sc->vxn_intrhand); #elif defined(VXN_MPSAFE) error = bus_setup_intr(dev, sc->vxn_irq, INTR_TYPE_NET | INTR_MPSAFE, vxn_intr, sc, &sc->vxn_intrhand); #else error = bus_setup_intr(dev, sc->vxn_irq, INTR_TYPE_NET, vxn_intr, sc, &sc->vxn_intrhand); #endif if (error) { printf("vxn%d: couldn't set up irq\n", unit); error = ENXIO; goto fail; } /* * allocate and initialize our private and shared data structures */ r = vxn_execute_4(sc, VMXNET_CMD_GET_NUM_RX_BUFFERS); if (r == 0 || r > VMXNET2_MAX_NUM_RX_BUFFERS) { r = VMXNET2_DEFAULT_NUM_RX_BUFFERS; } sc->vxn_num_rx_bufs = r; r = vxn_execute_4(sc, VMXNET_CMD_GET_NUM_TX_BUFFERS); if (r == 0 || r > VMXNET2_MAX_NUM_TX_BUFFERS) { r = VMXNET2_DEFAULT_NUM_TX_BUFFERS; } sc->vxn_num_tx_bufs = r; driverDataSize = sizeof(Vmxnet2_DriverData) + /* numRxBuffers + 1 for the dummy rxRing2 (used only by Windows) */ (sc->vxn_num_rx_bufs + 1) * sizeof(Vmxnet2_RxRingEntry) + sc->vxn_num_tx_bufs * sizeof(Vmxnet2_TxRingEntry); sc->vxn_dd = contigmalloc(driverDataSize, M_DEVBUF, M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0); if (sc->vxn_dd == NULL) { printf("vxn%d: can't contigmalloc %d bytes for vxn_dd\n", unit, driverDataSize); error = ENOMEM; goto fail; } memset(sc->vxn_dd, 0, driverDataSize); /* So that the vmkernel can check it is compatible */ sc->vxn_dd->magic = VMXNET2_MAGIC; sc->vxn_dd->length = driverDataSize; /* This downcast is OK because we've asked for vxn_dd to fit in 32 bits */ sc->vxn_dd_phys = (uint32)vtophys(sc->vxn_dd); /* * set up entry points, data and defaults for the kernel */ ifp = VXN_IF_ALLOC(sc); if (ifp == NULL) { printf("vxn%d: if_alloc() failed\n", unit); error = ENOMEM; goto fail; } ifp->if_softc = sc; VXN_IF_INITNAME(ifp, device_get_name(dev), unit); ifp->if_mtu = ETHERMTU; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = vxn_ioctl; ifp->if_output = ether_output; ifp->if_start = vxn_start; #if __FreeBSD_version < 900000 ifp->if_watchdog = vxn_watchdog; #endif ifp->if_init = vxn_init; ifp->if_baudrate = 1000000000; ifp->if_snd.ifq_maxlen = sc->vxn_num_tx_bufs; ifp->if_capenable = ifp->if_capabilities; /* * read the MAC address from the device */ for (i = 0; i < 6; i++) { mac[i] = bus_space_read_1(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_MAC_ADDR + i); } #ifdef VXN_NEEDARPCOM /* * FreeBSD 4.x requires that we manually record the device's MAC address to * the attached arpcom structure prior to calling ether_ifattach(). */ bcopy(mac, sc->arpcom.ac_enaddr, 6); #endif /* * success */ VXN_ETHER_IFATTACH(ifp, mac); printf("vxn%d: attached [num_rx_bufs=(%d*%d) num_tx_bufs=(%d*%d) driverDataSize=%d]\n", unit, sc->vxn_num_rx_bufs, (int)sizeof(Vmxnet2_RxRingEntry), sc->vxn_num_tx_bufs, (int)sizeof(Vmxnet2_TxRingEntry), driverDataSize); /* * Specify the media types supported by this adapter and register * callbacks to update media and link information */ ifmedia_init(&sc->media, IFM_IMASK, vxn_media_change, vxn_media_status); ifmedia_add(&sc->media, IFM_ETHER | IFM_FDX, 0, NULL); ifmedia_add(&sc->media, IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL); ifmedia_add(&sc->media, IFM_ETHER | IFM_1000_T, 0, NULL); ifmedia_add(&sc->media, IFM_ETHER | IFM_AUTO, 0, NULL); ifmedia_set(&sc->media, IFM_ETHER | IFM_AUTO); goto done; fail: if (sc->vxn_intrhand != NULL) { bus_teardown_intr(dev, sc->vxn_irq, sc->vxn_intrhand); } if (sc->vxn_irq != NULL) { bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vxn_irq); } if (sc->vxn_io != NULL) { bus_release_resource(dev, SYS_RES_IOPORT, VXN_PCIR_MAPS, sc->vxn_io); } if (sc->vxn_dd != NULL) { contigfree(sc->vxn_dd, sc->vxn_dd->length, M_DEVBUF); } if (ifp != NULL) { VXN_IF_FREE(sc); } pci_disable_io(dev, SYS_RES_IOPORT); pci_disable_busmaster(dev); VXN_MTX_DESTROY(&sc->vxn_mtx); done: splx(s); return error; } /* *----------------------------------------------------------------------------- * vxn_detach -- * Free data structures and detach driver from stack * * Results: * Returns 0 for success (always) * * Side effects: * None *----------------------------------------------------------------------------- */ static int vxn_detach(device_t dev) { int s; vxn_softc_t *sc; struct ifnet *ifp; s = splimp(); sc = device_get_softc(dev); ifp = VXN_SC2IFP(sc); if (device_is_attached(dev)) { vxn_stop(sc); /* * detach from stack */ VXN_ETHER_IFDETACH(ifp); } /* * Cleanup - release resources and memory */ VXN_IF_FREE(sc); contigfree(sc->vxn_dd, sc->vxn_dd->length, M_DEVBUF); bus_teardown_intr(dev, sc->vxn_irq, sc->vxn_intrhand); bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vxn_irq); bus_release_resource(dev, SYS_RES_IOPORT, VXN_PCIR_MAPS, sc->vxn_io); pci_disable_io(dev, SYS_RES_IOPORT); pci_disable_busmaster(dev); VXN_MTX_DESTROY(&sc->vxn_mtx); splx(s); return 0; } /* *----------------------------------------------------------------------------- * vxn_stop -- * Called when the interface is brought down * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static void vxn_stop(vxn_softc_t *sc) { VXN_LOCK(sc); vxn_stopl(sc); VXN_UNLOCK(sc); } /* *----------------------------------------------------------------------------- * vxn_stopl -- * Called when the interface is brought down & is locked * * Results: * None * * Side effects: * Don't do anything if not running. Flush pending transmits. Release * private data structures. *----------------------------------------------------------------------------- */ static void vxn_stopl(vxn_softc_t *sc) { int i; struct ifnet *ifp = VXN_SC2IFP(sc); VXN_LOCK_ASSERT(sc); if (!(VXN_GET_IF_DRV_FLAGS(ifp) & VXN_IFF_RUNNING)) { return; } /* * Disable device interrupts */ bus_space_write_4(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_COMMAND_ADDR, VMXNET_CMD_INTR_DISABLE); /* * Try to flush pending transmits */ if (sc->vxn_tx_pending) { printf("vxn%d: waiting for %d pending transmits\n", VXN_IF_UNIT(ifp), sc->vxn_tx_pending); for (i = 0; i < MAX_TX_WAIT_ON_STOP && sc->vxn_tx_pending; i++) { DELAY(1000); bus_space_write_4(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_COMMAND_ADDR, VMXNET_CMD_CHECK_TX_DONE); vxn_tx_complete(sc); } if (sc->vxn_tx_pending) { printf("vxn%d: giving up on %d pending transmits\n", VXN_IF_UNIT(ifp), sc->vxn_tx_pending); } } /* * Stop hardware */ bus_space_write_4(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_INIT_ADDR, 0); VXN_CLR_IF_DRV_FLAGS(ifp, VXN_IFF_RUNNING); /* * Free ring */ vxn_release_rings(sc); } /* *----------------------------------------------------------------------------- * vxn_load_multicast -- * Called to change set of addresses to listen to. * * Results: * None * * Side effects: * Sets device multicast table *----------------------------------------------------------------------------- */ static int vxn_load_multicast(vxn_softc_t *sc) { struct ifmultiaddr *ifma; struct ifnet *ifp = VXN_SC2IFP(sc); Vmxnet2_DriverData *dd = sc->vxn_dd; volatile uint16 *mcast_table = (uint16 *)dd->LADRF; int i, bit, byte; uint32 crc, poly = CRC_POLYNOMIAL_LE; int any = 0; if (ifp->if_flags & IFF_ALLMULTI) { dd->LADRF[0] = 0xffffffff; dd->LADRF[1] = 0xffffffff; any++; goto done; } dd->LADRF[0] = 0; dd->LADRF[1] = 0; VXN_IF_ADDR_LOCK(ifp); for (ifma = VXN_IFMULTI_FIRST(&ifp->if_multiaddrs); ifma != NULL; ifma = VXN_IFMULTI_NEXT(ifma, ifma_link)) { char *addrs = LLADDR((struct sockaddr_dl *)ifma->ifma_addr); if (ifma->ifma_addr->sa_family != AF_LINK) continue; any++; crc = 0xffffffff; for (byte = 0; byte < 6; byte++) { for (bit = *addrs++, i = 0; i < 8; i++, bit >>= 1) { int test; test = ((bit ^ crc) & 0x01); crc >>= 1; if (test) { crc = crc ^ poly; } } } crc = crc >> 26; mcast_table[crc >> 4] |= 1 << (crc & 0xf); } VXN_IF_ADDR_UNLOCK(ifp); done: if (VXN_GET_IF_DRV_FLAGS(ifp) & VXN_IFF_RUNNING) { bus_space_write_4(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_COMMAND_ADDR, VMXNET_CMD_UPDATE_LADRF); } return any; } /* *----------------------------------------------------------------------------- * vxn_init -- * Called when the interface is brought up. * * Results: * None * * Side effects: * *----------------------------------------------------------------------------- */ static void vxn_init(void *v) { vxn_softc_t *sc = (vxn_softc_t *)v; VXN_LOCK(sc); vxn_initl(sc); VXN_UNLOCK(sc); } /* *----------------------------------------------------------------------------- * vxn_initl -- * Called by vxn_init() after lock acquired. * * Results: * None * * Side effects: * Initialize rings, Register driver data structures with device, * Enable interrupts on device. * *----------------------------------------------------------------------------- */ static void vxn_initl(vxn_softc_t *sc) { Vmxnet2_DriverData *dd = sc->vxn_dd; struct ifnet *ifp = VXN_SC2IFP(sc); uint32 r, i; u_char mac_addr[6]; VXN_LOCK_ASSERT(sc); if (!(VXN_GET_IF_DRV_FLAGS(ifp) & VXN_IFF_RUNNING)) { u_int32_t capabilities; u_int32_t features; if (vxn_init_rings(sc) != 0) { printf("vxn%d: ring intitialization failed\n", VXN_IF_UNIT(ifp)); return; } /* Get MAC address from interface and set it in hardware */ #if __FreeBSD_version >= 700000 printf("addrlen : %d. \n", ifp->if_addrlen); bcopy(LLADDR((struct sockaddr_dl *)ifp->if_addr->ifa_addr), mac_addr, ifp->if_addrlen > 6 ? 6 : ifp->if_addrlen); #else if (!ifaddr_byindex(ifp->if_index)) { printf("vxn:%d Invalid link address, interface index :%d.\n", VXN_IF_UNIT(ifp), ifp->if_index); } else { bcopy(LLADDR((struct sockaddr_dl *)ifaddr_byindex(ifp->if_index)->ifa_addr), mac_addr, ifp->if_addrlen); } #endif printf("vxn%d: MAC Address : %02x:%02x:%02x:%02x:%02x:%02x \n", VXN_IF_UNIT(ifp), mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); for (i = 0; i < 6; i++) { bus_space_write_1(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_MAC_ADDR + i, mac_addr[i]); } /* * Start hardware */ bus_space_write_4(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_INIT_ADDR, sc->vxn_dd_phys); bus_space_write_4(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_INIT_LENGTH, sc->vxn_dd->length); /* Make sure the initialization succeeded for the hardware. */ r = bus_space_read_4(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_INIT_LENGTH); if (!r) { vxn_release_rings(sc); printf("vxn%d: device intitialization failed: %x\n", VXN_IF_UNIT(ifp), r); return; } capabilities = vxn_execute_4(sc, VMXNET_CMD_GET_CAPABILITIES); features = vxn_execute_4(sc, VMXNET_CMD_GET_FEATURES); if ((capabilities & VMNET_CAP_SG) && (features & VMXNET_FEATURE_ZERO_COPY_TX)) { sc->vxn_max_tx_frags = VMXNET2_SG_DEFAULT_LENGTH; } else { sc->vxn_max_tx_frags = 1; } VXN_SET_IF_DRV_FLAGS(ifp, VXN_IFF_RUNNING); VXN_CLR_IF_DRV_FLAGS(ifp, VXN_IFF_OACTIVE); } dd->ifflags &= ~(VMXNET_IFF_PROMISC |VMXNET_IFF_BROADCAST |VMXNET_IFF_MULTICAST); if (ifp->if_flags & IFF_PROMISC) { printf("vxn%d: promiscuous mode enabled\n", VXN_IF_UNIT(ifp)); dd->ifflags |= VMXNET_IFF_PROMISC; } if (ifp->if_flags & IFF_BROADCAST) { dd->ifflags |= VMXNET_IFF_BROADCAST; } /* * vnx_load_multicast does the right thing for IFF_ALLMULTI */ if (vxn_load_multicast(sc)) { dd->ifflags |= VMXNET_IFF_MULTICAST; } /* * enable interrupts on the card */ bus_space_write_4(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_COMMAND_ADDR, VMXNET_CMD_INTR_ENABLE); bus_space_write_4(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_COMMAND_ADDR, VMXNET_CMD_UPDATE_IFF); } /* *----------------------------------------------------------------------------- * vxn_encap -- * Stick packet address and length in given ring entry * * Results: * 0 on success, 1 on error * * Side effects: * Allocate a new mbuf cluster and copy data, if mbuf chain is too * fragmented for us to include in our scatter/gather array * *----------------------------------------------------------------------------- */ static int vxn_encap(struct ifnet *ifp, Vmxnet2_TxRingEntry *xre, struct mbuf *m_head, struct mbuf **pbuffptr) { vxn_softc_t *sc = ifp->if_softc; int frag = 0; struct mbuf *m; xre->sg.length = 0; xre->flags = 0; /* * Go through mbuf chain and drop packet pointers into ring * scatter/gather array */ for (m = m_head; m != NULL; m = m->m_next) { if (m->m_len) { if (frag == sc->vxn_max_tx_frags) { break; } xre->sg.sg[frag].addrLow = (uint32)vtophys(mtod(m, vm_offset_t)); xre->sg.sg[frag].length = m->m_len; frag++; } } /* * Allocate a new mbuf cluster and copy data if we can't use the mbuf chain * as such */ if (m != NULL) { struct mbuf *m_new = NULL; MGETHDR(m_new, M_DONTWAIT, MT_DATA); if (m_new == NULL) { printf("vxn%d: no memory for tx list\n", VXN_IF_UNIT(ifp)); return 1; } if (m_head->m_pkthdr.len > MHLEN) { MCLGET(m_new, M_DONTWAIT); if (!(m_new->m_flags & M_EXT)) { m_freem(m_new); printf("vxn%d: no memory for tx list\n", VXN_IF_UNIT(ifp)); return 1; } } m_copydata(m_head, 0, m_head->m_pkthdr.len, mtod(m_new, caddr_t)); m_new->m_pkthdr.len = m_new->m_len = m_head->m_pkthdr.len; m_freem(m_head); m_head = m_new; xre->sg.sg[0].addrLow = (uint32)vtophys(mtod(m_head, vm_offset_t)); xre->sg.sg[0].length = m_head->m_pkthdr.len; frag = 1; } xre->sg.length = frag; /* * Mark ring entry as "NIC owned" */ if (frag > 0) { if (m_head->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP)) { xre->flags |= VMXNET2_TX_HW_XSUM; } xre->sg.addrType = NET_SG_PHYS_ADDR; *pbuffptr = m_head; xre->ownership = VMXNET2_OWNERSHIP_NIC; xre->flags |= VMXNET2_TX_CAN_KEEP; } return 0; } /* *----------------------------------------------------------------------------- * vxn_start -- * Called to transmit a packet. Acquires device mutex & hands off to * vxn_startl. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static void vxn_start(struct ifnet *ifp) { VXN_LOCK((vxn_softc_t *)ifp->if_softc); vxn_startl(ifp); VXN_UNLOCK((vxn_softc_t *)ifp->if_softc); } /* *----------------------------------------------------------------------------- * vxn_startl -- * Called to transmit a packet (lock acquired) * * Results: * None * * Side effects: * Bounces a copy to possible BPF listener. Sets RING_LOW flag * if ring is getting crowded. Starts device TX. Aggressively cleans * up tx ring after starting TX. * *----------------------------------------------------------------------------- */ static void vxn_startl(struct ifnet *ifp) { vxn_softc_t *sc = ifp->if_softc; Vmxnet2_DriverData *dd = sc->vxn_dd; VXN_LOCK_ASSERT(sc); if (VXN_GET_IF_DRV_FLAGS(ifp) & VXN_IFF_OACTIVE) { return; } /* * No room on ring */ if (sc->vxn_tx_buffptr[dd->txDriverNext]) { dd->txStopped = TRUE; } /* * Dequeue packets from send queue and drop them into tx ring */ while (sc->vxn_tx_buffptr[dd->txDriverNext] == NULL) { struct mbuf *m_head = NULL; Vmxnet2_TxRingEntry *xre; IF_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) { break; } xre = &sc->vxn_tx_ring[dd->txDriverNext]; if (vxn_encap(ifp, xre, m_head, &(sc->vxn_tx_buffptr[dd->txDriverNext]))) { IF_PREPEND(&ifp->if_snd, m_head); break; } /* * Bounce copy to (possible) BPF listener */ VXN_BPF_MTAP(ifp, sc->vxn_tx_buffptr[dd->txDriverNext]); if (sc->vxn_tx_pending > (dd->txRingLength - 5)) { xre->flags |= VMXNET2_TX_RING_LOW; } VMXNET_INC(dd->txDriverNext, dd->txRingLength); dd->txNumDeferred++; sc->vxn_tx_pending++; ifp->if_opackets++; } /* * Transmit, if number of pending packets > tx cluster length */ if (dd->txNumDeferred >= dd->txClusterLength) { dd->txNumDeferred = 0; /* * reading this port causes the implementation to transmit everything * in the ring */ bus_space_read_4(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_TX_ADDR); } /* * Clean up tx ring after calling into vmkernel, as TX completion intrs * are not guaranteed. */ vxn_tx_complete(sc); } /* *----------------------------------------------------------------------------- * vxn_ioctl -- * IOCTL * * Results: * Returns 0 for success, negative errno value otherwise. * * Side effects: * None *----------------------------------------------------------------------------- */ static int vxn_ioctl(struct ifnet *ifp, u_long command, caddr_t data) { int error = 0; int s; vxn_softc_t *sc = ifp->if_softc; s = splimp(); switch(command) { case SIOCSIFADDR: case SIOCGIFADDR: case SIOCSIFMTU: error = ether_ioctl(ifp, command, data); break; case SIOCSIFFLAGS: VXN_LOCK(sc); if (ifp->if_flags & IFF_UP) { vxn_initl(sc); } else { vxn_stopl(sc); } VXN_UNLOCK(sc); break; case SIOCADDMULTI: case SIOCDELMULTI: VXN_LOCK(sc); vxn_load_multicast(sc); VXN_UNLOCK(sc); error = 0; break; case SIOCSIFMEDIA: case SIOCGIFMEDIA: ifmedia_ioctl(ifp, (struct ifreq *)data, &sc->media, command); default: error = EINVAL; break; } splx(s); return error; } #if __FreeBSD_version < 900000 /* *----------------------------------------------------------------------------- * vxn_watchdog -- * Watchdog function * * Results: * None * * Side effects: * Not implemented. *----------------------------------------------------------------------------- */ static void vxn_watchdog(struct ifnet *ifp) { printf("vxn%d: watchdog\n", VXN_IF_UNIT(ifp)); } #endif /* *----------------------------------------------------------------------------- * vxn_intr -- * Interrupt handler * * Results: * None * * Side effects: * None *----------------------------------------------------------------------------- */ static void vxn_intr (void *v) { vxn_softc_t *sc = (vxn_softc_t *)v; struct ifnet *ifp = VXN_SC2IFP(sc); VXN_LOCK(sc); /* * Without rings being allocated we have nothing to do. We should not * need even this INTR_ACK, as our hardware should be disabled when * rings are not allocated, but on other side INTR_ACK should be noop * then, and this makes sure that some bug will not force IRQ line * active forever. */ bus_space_write_4(sc->vxn_iobtag, sc->vxn_iobhandle, VMXNET_COMMAND_ADDR, VMXNET_CMD_INTR_ACK); if (sc->vxn_rings_allocated) { vxn_rx(sc); vxn_tx_complete(sc); /* * After having freed some of the transmit ring, go ahead and refill * it, if possible, while we're here. (Idea stolen from if_sis.c.) */ if (!VXN_IFQ_IS_EMPTY(&ifp->if_snd)) { vxn_startl(ifp); } } VXN_UNLOCK(sc); } /* *----------------------------------------------------------------------------- * vxn_rx -- * RX handler * * Results: * None * * Side effects: * Scan RX ring and pass legit packets up to FreeBSD. Allocate a * new mbuf for each packet pulled out, stick it into the ring and * pass ownership back to NIC. *----------------------------------------------------------------------------- */ static void vxn_rx(vxn_softc_t *sc) { short pkt_len; struct ifnet *ifp = VXN_SC2IFP(sc); Vmxnet2_DriverData *dd = sc->vxn_dd; /* * receive packets from all the descriptors that the device implementation * has given back to us */ while (1) { Vmxnet2_RxRingEntry *rre; VXN_LOCK_ASSERT(sc); rre = &sc->vxn_rx_ring[dd->rxDriverNext]; if (rre->ownership != VMXNET2_OWNERSHIP_DRIVER) { break; } pkt_len = rre->actualLength; if (pkt_len < (60 - 4)) { /* * Ethernet header vlan tags are 4 bytes. Some vendors generate * 60byte frames including vlan tags. When vlan tag * is stripped, such frames become 60 - 4. (PR106153) */ if (pkt_len != 0) { printf("vxn%d: runt packet\n", VXN_IF_UNIT(ifp)); } } else { struct mbuf *m_new = NULL; /* * Allocate a new mbuf cluster to replace the current one */ MGETHDR(m_new, M_DONTWAIT, MT_DATA); if (m_new != NULL) { MCLGET(m_new, M_DONTWAIT); if (m_new->m_flags & M_EXT) { m_adj(m_new, ETHER_ALIGN); } else { m_freem(m_new); m_new = NULL; } } /* * replace the current mbuf in the descriptor with the new one * and pass the packet up to the kernel */ if (m_new != NULL) { struct mbuf *m = sc->vxn_rx_buffptr[dd->rxDriverNext]; sc->vxn_rx_buffptr[dd->rxDriverNext] = m_new; rre->paddr = (uint32)vtophys(mtod(m_new, caddr_t)); ifp->if_ipackets++; m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = pkt_len; if (rre->flags & VMXNET2_RX_HW_XSUM_OK) { m->m_pkthdr.csum_flags |= CSUM_DATA_VALID | CSUM_PSEUDO_HDR; m->m_pkthdr.csum_data = 0xffff; } /* * "Drop the driver lock around calls to if_input to avoid a LOR * when the packets are immediately returned for sending (e.g. when * bridging or packet forwarding). There are more efficient ways to * do this but for now use the least intrusive approach." * - Sam Leffler (sam@FreeBSD.org), if_sis.c rev 1.90 * * This function is only called by the interrupt handler, and said * handler isn't reentrant. (Interrupts are masked.) I.e., the * receive rings are still protected while we give up the mutex. */ VXN_UNLOCK(sc); VXN_ETHER_INPUT(ifp, m); VXN_LOCK(sc); } } /* * Give the descriptor back to the device implementation */ rre->ownership = VMXNET2_OWNERSHIP_NIC; VMXNET_INC(dd->rxDriverNext, dd->rxRingLength); } } /* *----------------------------------------------------------------------------- * vxn_tx_complete -- * Loop through the tx ring looking for completed transmits * * Results: * None * * Side effects: * None *----------------------------------------------------------------------------- */ static void vxn_tx_complete(vxn_softc_t *sc) { Vmxnet2_DriverData *dd = sc->vxn_dd; while (1) { Vmxnet2_TxRingEntry *xre = &sc->vxn_tx_ring[dd->txDriverCur]; if (xre->ownership != VMXNET2_OWNERSHIP_DRIVER || sc->vxn_tx_buffptr[dd->txDriverCur] == NULL) { break; } m_freem(sc->vxn_tx_buffptr[dd->txDriverCur]); sc->vxn_tx_buffptr[dd->txDriverCur] = NULL; sc->vxn_tx_pending--; VMXNET_INC(dd->txDriverCur, dd->txRingLength); dd->txStopped = FALSE; } } /* *----------------------------------------------------------------------------- * vxn_init_rings -- * Loop through the tx ring looking for completed transmits * * Results: * Returns 0 for success, negative errno value otherwise. * * Side effects: * None *----------------------------------------------------------------------------- */ static int vxn_init_rings(vxn_softc_t *sc) { Vmxnet2_DriverData *dd = sc->vxn_dd; /*struct ifnet *ifp = &sc->arpcom.ac_if;*/ int i; int32 offset; offset = sizeof(*dd); dd->rxRingLength = sc->vxn_num_rx_bufs; dd->rxRingOffset = offset; sc->vxn_rx_ring = (Vmxnet2_RxRingEntry *)((uintptr_t)dd + offset); offset += sc->vxn_num_rx_bufs * sizeof(Vmxnet2_RxRingEntry); /* dummy rxRing2, only used by windows */ dd->rxRingLength2 = 1; dd->rxRingOffset2 = offset; offset += sizeof(Vmxnet2_RxRingEntry); dd->txRingLength = sc->vxn_num_tx_bufs; dd->txRingOffset = offset; sc->vxn_tx_ring = (Vmxnet2_TxRingEntry *)((uintptr_t)dd + offset); offset += sc->vxn_num_tx_bufs * sizeof(Vmxnet2_TxRingEntry); /* * Allocate receive buffers */ for (i = 0; i < sc->vxn_num_rx_bufs; i++) { struct mbuf *m_new = NULL; /* * Allocate an mbuf and initialize it to contain a packet header and * internal data. */ MGETHDR(m_new, M_DONTWAIT, MT_DATA); if (m_new != NULL) { /* Allocate and attach an mbuf cluster to mbuf. */ MCLGET(m_new, M_DONTWAIT); if (m_new->m_flags & M_EXT) { m_adj(m_new, ETHER_ALIGN); sc->vxn_rx_ring[i].paddr = (uint32)vtophys(mtod(m_new, caddr_t)); sc->vxn_rx_ring[i].bufferLength = MCLBYTES; sc->vxn_rx_ring[i].actualLength = 0; sc->vxn_rx_buffptr[i] = m_new; sc->vxn_rx_ring[i].ownership = VMXNET2_OWNERSHIP_NIC; } else { /* * Allocation and attachment of mbuf clusters failed. */ m_freem(m_new); m_new = NULL; goto err_release_ring; } } else { /* Allocation of mbuf failed. */ goto err_release_ring; } } /* dummy rxRing2 tacked on to the end, with a single unusable entry */ sc->vxn_rx_ring[i].paddr = 0; sc->vxn_rx_ring[i].bufferLength = 0; sc->vxn_rx_ring[i].actualLength = 0; sc->vxn_rx_buffptr[i] = 0; sc->vxn_rx_ring[i].ownership = VMXNET2_OWNERSHIP_DRIVER; dd->rxDriverNext = 0; /* * Give tx ring ownership to DRIVER */ for (i = 0; i < sc->vxn_num_tx_bufs; i++) { sc->vxn_tx_ring[i].ownership = VMXNET2_OWNERSHIP_DRIVER; sc->vxn_tx_buffptr[i] = NULL; sc->vxn_tx_ring[i].sg.sg[0].addrHi = 0; } dd->txDriverCur = dd->txDriverNext = 0; dd->txStopped = FALSE; sc->vxn_rings_allocated = 1; return 0; err_release_ring: /* * Clearup already allocated mbufs and attached clusters. */ for (--i; i >= 0; i--) { m_freem(sc->vxn_rx_buffptr[i]); sc->vxn_rx_buffptr[i] = NULL; sc->vxn_rx_ring[i].paddr = 0; sc->vxn_rx_ring[i].bufferLength = 0; sc->vxn_rx_ring[i].ownership = 0; } return ENOMEM; } /* *----------------------------------------------------------------------------- * vxn_release_rings -- * Free tx and rx ring driverdata * * Results: * None * * Side effects: * None *----------------------------------------------------------------------------- */ static void vxn_release_rings(vxn_softc_t *sc) { int i; sc->vxn_rings_allocated = 0; /* * Free rx ring packets */ for (i = 0; i < sc->vxn_num_rx_bufs; i++) { if (sc->vxn_rx_buffptr[i] != NULL) { m_freem(sc->vxn_rx_buffptr[i]); sc->vxn_rx_buffptr[i] = NULL; } } /* * Free tx ring packets */ for (i = 0; i < sc->vxn_num_tx_bufs; i++) { if (sc->vxn_tx_buffptr[i] != NULL) { m_freem(sc->vxn_tx_buffptr[i]); sc->vxn_tx_buffptr[i] = NULL; } } } open-vm-tools-9.4.0-1280544/modules/freebsd/vmblock/0000755765153500003110000000000012220061556020156 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/freebsd/vmblock/subr.c0000644765153500003110000003310712220061556021301 0ustar dtormts/* ********************************************************** * Copyright 2007 VMware, Inc. All rights reserved. * **********************************************************/ /* * subr.c -- * * Subroutines for the VMBlock filesystem on FreeBSD. */ /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software donated to Berkeley by * Jan-Simon Pendry. * * 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. * * @(#)null_subr.c 8.7 (Berkeley) 5/14/95 * * $FreeBSD: src/sys/fs/nullfs/null_subr.c,v 1.48.2.1 2006/03/13 03:05:17 jeff Exp $ */ #include #include #include #include #include #include #include #include #include #include #include "compat_freebsd.h" #include "vmblock_k.h" #include "block.h" #define LOG2_SIZEVNODE 8 /* log2(sizeof struct vnode) */ #define NVMBLOCKCACHE 16 /* Number of hash buckets/chains */ /* * Local data */ /* * VMBlock layer cache: * Each cache entry holds a reference to the lower vnode along with a * pointer to the alias vnode. When an entry is added the lower vnode * is VREF'd. When the alias is removed the lower vnode is vrele'd. */ #define VMBLOCK_NHASH(vp) \ (&nodeHashTable[(((uintptr_t)vp)>>LOG2_SIZEVNODE) & nodeHashMask]) /* * See hashinit(9). */ static LIST_HEAD(nodeHashHead, VMBlockNode) *nodeHashTable; static u_long nodeHashMask; static struct mtx hashMutex; static MALLOC_DEFINE(M_VMBLOCKFSHASH, "VMBlockFS hash", "VMBlockFS hash table"); MALLOC_DEFINE(M_VMBLOCKFSNODE, "VMBlockFS node", "VMBlockFS vnode private part"); /* Defined for quick access to temporary pathname buffers. */ uma_zone_t VMBlockPathnameZone; /* * Local functions */ static struct vnode * VMBlockHashGet(struct mount *, struct vnode *); static struct vnode * VMBlockHashInsert(struct mount *, struct VMBlockNode *); /* *----------------------------------------------------------------------------- * * VMBlockInit -- * * Initialize VMBlock file system. Called when module first loaded into * the kernel. * * Results: * Zero. * * Side effects: * None. * * Original comments: * Initialise cache headers * *----------------------------------------------------------------------------- */ int VMBlockInit(struct vfsconf *vfsp) // ignored { VMBLOCKDEBUG("VMBlockInit\n"); /* printed during system boot */ nodeHashTable = hashinit(NVMBLOCKCACHE, M_VMBLOCKFSHASH, &nodeHashMask); mtx_init(&hashMutex, "vmblock-hs", NULL, MTX_DEF); VMBlockPathnameZone = uma_zcreate("VMBlock", MAXPATHLEN, NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); VMBlockSetupFileOps(); BlockInit(); return 0; } /* *----------------------------------------------------------------------------- * * VMBlockUninit -- * * Clean up when module is unloaded. * * Results: * Zero always. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int VMBlockUninit(struct vfsconf *vfsp) // ignored { mtx_destroy(&hashMutex); free(nodeHashTable, M_VMBLOCKFSHASH); BlockCleanup(); uma_zdestroy(VMBlockPathnameZone); return 0; } /* *----------------------------------------------------------------------------- * * VMBlockHashGet -- * * "Return a VREF'ed alias for lower vnode if already exists, else 0. * Lower vnode should be locked on entry and will be left locked on exit." * * Results: * Pointer to upper layer/alias vnode if lowervp found, otherwise NULL. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static struct vnode * VMBlockHashGet(struct mount *mp, // IN: vmblock file system information struct vnode *lowervp) // IN: lower vnode to search for { struct nodeHashHead *hd; struct VMBlockNode *a; struct vnode *vp; ASSERT_VOP_LOCKED(lowervp, "hashEntryget"); /* * Find hash base, and then search the (two-way) linked list looking * for a VMBlockNode structure which is referencing the lower vnode. * If found, the increment the VMBlockNode reference count (but NOT the * lower vnode's VREF counter). */ hd = VMBLOCK_NHASH(lowervp); mtx_lock(&hashMutex); LIST_FOREACH(a, hd, hashEntry) { if (a->lowerVnode == lowervp && VMBTOVP(a)->v_mount == mp) { /* * Since we have the lower node locked the nullfs node can not be * in the process of recycling. If it had been recycled before we * grabed the lower lock it would not have been found on the hash. */ vp = VMBTOVP(a); vref(vp); mtx_unlock(&hashMutex); return vp; } } mtx_unlock(&hashMutex); return NULLVP; } /* *----------------------------------------------------------------------------- * * VMBlockHashInsert -- * * "Act like VMBlockHashGet, but add passed VMBlockNode to hash if no * existing node found." * * Results: * Referenced, locked alias vnode if entry already in hash. Otherwise * NULLVP. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static struct vnode * VMBlockHashInsert(struct mount *mp, // IN: VMBlock file system info struct VMBlockNode *xp) // IN: node to insert into hash { struct nodeHashHead *hd; struct VMBlockNode *oxp; struct vnode *ovp; hd = VMBLOCK_NHASH(xp->lowerVnode); mtx_lock(&hashMutex); LIST_FOREACH(oxp, hd, hashEntry) { if (oxp->lowerVnode == xp->lowerVnode && VMBTOVP(oxp)->v_mount == mp) { /* * See hashEntryget for a description of this * operation. */ ovp = VMBTOVP(oxp); vref(ovp); mtx_unlock(&hashMutex); return ovp; } } LIST_INSERT_HEAD(hd, xp, hashEntry); mtx_unlock(&hashMutex); return NULLVP; } /* *----------------------------------------------------------------------------- * * VMBlockHashRem -- * * Remove a VMBlockNode from the hash. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMBlockHashRem(struct VMBlockNode *xp) // IN: node to remove { mtx_lock(&hashMutex); LIST_REMOVE(xp, hashEntry); mtx_unlock(&hashMutex); } /* *----------------------------------------------------------------------------- * * VMBlockInsMntQueDtr -- * * Do filesystem specific cleanup when recycling a vnode on a failed * insmntque1 call. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ #if __FreeBSD_version >= 700055 static void VMBlockInsMntQueDtr(struct vnode *vp, // IN: node to cleanup void *xp) // IN: FS private data { vp->v_data = NULL; vp->v_vnlock = &vp->v_lock; free(xp, M_VMBLOCKFSNODE); vp->v_op = &dead_vnodeops; (void) compat_vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread); vgone(vp); vput(vp); } #endif /* *----------------------------------------------------------------------------- * * VMBlockNodeGet -- * * Return a VMBlockNode mapped to the given lower layer vnode. * * Results: * Zero on success, an appropriate system error otherwise. * * Side effects: * In case of success takes over ownership of pathname thus caller * has to dispose of it only if error was signalled. * * Original function comment: * * Make a new or get existing nullfs node. Vp is the alias vnode, * lowervp is the lower vnode. * * The lowervp assumed to be locked and having "spare" reference. This * routine vrele lowervp if nullfs node was taken from hash. Otherwise it * "transfers" the caller's "spare" reference to created nullfs vnode. * *----------------------------------------------------------------------------- */ int VMBlockNodeGet(struct mount *mp, // IN: VMBlock fs info struct vnode *lowervp, // IN: lower layer vnode struct vnode **vpp, // OUT: upper layer/alias vnode char *pathname) // IN: Pointer to the path we took to // reach this vnode { struct VMBlockNode *xp; struct vnode *vp; int error; /* Lookup the hash firstly */ *vpp = VMBlockHashGet(mp, lowervp); if (*vpp != NULL) { vrele(lowervp); return 0; } /* * We do not serialize vnode creation, instead we will check for duplicates * later, when adding new vnode to hash. * * Note that duplicate can only appear in hash if the lowervp is locked * LK_SHARED. */ /* * Do the malloc before the getnewvnode since doing so afterward might * cause a bogus v_data pointer to get dereferenced elsewhere if malloc * should block. */ xp = malloc(sizeof *xp, M_VMBLOCKFSNODE, M_WAITOK|M_ZERO); error = getnewvnode("vmblock", mp, &VMBlockVnodeOps, &vp); if (error) { free(xp, M_VMBLOCKFSNODE); return error; } xp->name = pathname; xp->backVnode = vp; xp->lowerVnode = lowervp; vp->v_type = lowervp->v_type; vp->v_data = xp; vp->v_vnlock = lowervp->v_vnlock; if (vp->v_vnlock == NULL) { panic("VMBlockNodeGet: Passed a NULL vnlock.\n"); } /* Before FreeBSD 7, insmntque was called by getnewvnode. */ #if __FreeBSD_version >= 700055 error = insmntque1(vp, mp, VMBlockInsMntQueDtr, xp); if (error != 0) { return error; } #endif /* * Atomically insert our new node into the hash or vget existing if * someone else has beaten us to it. * * ETA: If a hash entry already exists, we'll be stuck with an orphaned * vnode and associated VMBlockNode. By vrele'ng this vp, it'll be reclaimed * by the OS later. That same process will take care of freeing the * VMBlockNode, too. */ *vpp = VMBlockHashInsert(mp, xp); if (*vpp != NULL) { vrele(lowervp); vp->v_vnlock = &vp->v_lock; xp->lowerVnode = NULL; vrele(vp); } else { *vpp = vp; } return 0; } #ifdef DIAGNOSTIC /* if (DIAGNOSTIC) { */ /* *----------------------------------------------------------------------------- * * VMBlockCheckVp -- * * Sanity-checking intermediary used for debugging. When module is * compiled with FreeBSD macro "DIAGNOSTIC", every instance of * VMBVPTOLOWERVP() calls this function to test vnodes' and VMBlockNodes' * values, printing diagnostic information before panicing. If the kernel * debugger (KDB) is enabled, then this function will break to the debugger * before a panic. * * Results: * Valid pointer to a VMBlockNode's lower vnode. * * Side effects: * None. * *----------------------------------------------------------------------------- */ struct vnode * VMBlockCheckVp(vp, fil, lno) struct vnode *vp; char *fil; int lno; { struct VMBlockNode *a = VPTOVMB(vp); #ifdef notyet /* * Can't do this check because vop_reclaim runs * with a funny vop vector. */ if (vp->v_op != null_vnodeop_p) { printf ("VMBlockCheckVp: on non-null-node\n"); panic("VMBlockCheckVp"); }; #endif if (a->lowerVnode == NULLVP) { /* Should never happen */ int i; u_long *p; printf("vp = %p, ZERO ptr\n", (void *)vp); for (p = (u_long *) a, i = 0; i < 8; i++) { printf(" %lx", p[i]); } printf("\n"); panic("VMBlockCheckVp"); } if (vrefcnt(a->lowerVnode) < 1) { int i; u_long *p; printf("vp = %p, unref'ed lowervp\n", (void *)vp); for (p = (u_long *) a, i = 0; i < 8; i++) { printf(" %lx", p[i]); } printf("\n"); panic ("null with unref'ed lowervp"); }; #ifdef notyet printf("null %x/%d -> %x/%d [%s, %d]\n", VMBTOVP(a), vrefcnt(VMBTOVP(a)), a->lowerVnode, vrefcnt(a->lowerVnode), fil, lno); #endif return a->lowerVnode; } #endif /* } [DIAGNOSTIC] */ open-vm-tools-9.4.0-1280544/modules/freebsd/vmblock/os_panic.c0000644765153500003110000000453112220061556022120 0ustar dtormts/********************************************************* * Copyright (C) 2011 VMware, Inc. 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. * 3. Neither the name of VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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. * *********************************************************/ /* * os_panic.c -- * * Vararg panic implementation for FreeBSD. */ #include #include #include #include "os.h" /* *---------------------------------------------------------------------------- * * os_panic -- * * FreeBSD panic implementation that takes va_list argument. * * Results: * None. * * Side effects: * We panic. * *---------------------------------------------------------------------------- */ void os_panic(const char *fmt, // IN va_list args) // IN { static char message[1024]; vsnprintf(message, sizeof message - 1, fmt, args); message[sizeof message - 1] = '\0'; panic("%s", message); } open-vm-tools-9.4.0-1280544/modules/freebsd/vmblock/vnops.c0000644765153500003110000013531112220061556021473 0ustar dtormts/* ********************************************************** * Copyright 2007 VMware, Inc. All rights reserved. * **********************************************************/ /* * vnops.c -- * * Vnode operations for the vmblock filesystem on FreeBSD. */ /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * John Heidemann of the UCLA Ficus project. * * 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. * * @(#)null_vnops.c 8.6 (Berkeley) 5/27/95 * * Ancestors: * @(#)lofs_vnops.c 1.2 (Berkeley) 6/18/92 * ...and... * @(#)nullfs_vnops.c 1.20 92/07/07 UCLA Ficus project * * $FreeBSD: src/sys/fs/nullfs/null_vnops.c,v 1.87.2.3 2006/03/13 03:05:26 jeff Exp $ */ /* * NB: The following is the introductory commentary from FreeBSD's * null_vnops.c, which VMBlockFS is heavily based on. It was kept intact in * order to provide a better conceptual introduction to FreeBSD's approach * to stackable file systems. */ /* * Null Layer * * (See mount_nullfs(8) for more information.) * * The null layer duplicates a portion of the filesystem name space under * a new name. In this respect, it is similar to the loopback filesystem. * It differs from the loopback fs in two respects: it is implemented * using a stackable layers techniques, and its "null-node"s stack above * all lower-layer vnodes, not just over directory vnodes. * * The null layer has two purposes. First, it serves as a demonstration * of layering by proving a layer which does nothing. (It actually * does everything the loopback filesystem does, which is slightly more * than nothing.) Second, the null layer can serve as a prototype layer. * Since it provides all necessary layer framework, new filesystem layers * can be created very easily be starting with a null layer. * * The remainder of this man page examines the null layer as a basis * for constructing new layers. * * * INSTANTIATING NEW NULL LAYERS * * New null layers are created with mount_nullfs(8). Mount_nullfs(8) * takes two arguments, the pathname of the lower vfs (target-pn) * and the pathname where the null layer will appear in the namespace * (alias-pn). After the null layer is put into place, the contents of * target-pn subtree will be aliased under alias-pn. * * * OPERATION OF A NULL LAYER * * The null layer is the minimum filesystem layer, simply bypassing * all possible operations to the lower layer for processing there. * The majority of its activity centers on the bypass routine, through * which nearly all vnode operations pass. * * The bypass routine accepts arbitrary vnode operations for handling by * the lower layer. It begins by examing vnode operation arguments and * replacing any null-nodes by their lower-layer equivlants. It then * invokes the operation on the lower layer. Finally, it replaces the * null-nodes in the arguments and, if a vnode is return by the operation, * stacks a null-node on top of the returned vnode. * * Although bypass handles most operations, vop_getattr, vop_lock, * vop_unlock, vop_inactive, vop_reclaim, and vop_print are * not bypassed. Vop_getattr must change the fsid being returned. * Vop_lock and vop_unlock must handle any locking for the current * vnode as well as pass the lock request down. Vop_inactive and * vop_reclaim are not bypassed so that they can handle freeing null-layer * specific data. Vop_print is not bypassed to avoid excessive debugging * information. Also, certain vnode operations change the locking state * within the operation (create, mknod, remove, link, rename, mkdir, * rmdir, and symlink). Ideally these operations should not change the * lock state, but should be changed to let the caller of the function * unlock them. Otherwise all intermediate vnode layers (such as union, * umapfs, etc) must catch these functions to do the necessary locking * at their layer. * * * INSTANTIATING VNODE STACKS * * Mounting associates the null layer with a lower layer, effect * stacking two VFSes. Vnode stacks are instead created on demand as * files are accessed. * * The initial mount creates a single vnode stack for the root of the * new null layer. All other vnode stacks are created as a result of * vnode operations on this or other null vnode stacks. * * New vnode stacks come into existance as a result of an operation * which returns a vnode. The bypass routine stacks a null-node above * the new vnode before returning it to the caller. * * For example, imagine mounting a null layer with "mount_nullfs * /usr/include /dev/layer/null". Changing directory to /dev/layer/null * will assign the root null-node (which was created when the null layer * was mounted). Now consider opening "sys". A vop_lookup would be * done on the root null-node. This operation would bypass through * to the lower layer which would return a vnode representing the UFS * "sys". Null_bypass then builds a null-node aliasing the UFS "sys" * and returns this to the caller. Later operations on the null-node * "sys" will repeat this process when constructing other vnode stacks. * * * CREATING OTHER FILE SYSTEM LAYERS * * One of the easiest ways to construct new filesystem layers is to make a * copy of the null layer, rename all files and variables, and then begin * modifing the copy. Sed can be used to easily rename all variables. * * The umap layer is an example of a layer descended from the null layer. * * * INVOKING OPERATIONS ON LOWER LAYERS * * There are two techniques to invoke operations on a lower layer when the * operation cannot be completely bypassed. Each method is appropriate * in different situations. In both cases, it is the responsibility of * the aliasing layer to make the operation arguments "correct" for the * lower layer by mapping a vnode arguments to the lower layer. * * The first approach is to call the aliasing layer's bypass routine. * This method is most suitable when you wish to invoke the operation * currently being handled on the lower layer. It has the advantage that * the bypass routine already must do argument mapping. An example of * this is vop_getattr in the null layer. * * A second approach is to directly invoke vnode operations on the * lower layer with the VOP_OPERATIONNAME interface. The advantage * of this method is that it is easy to invoke arbitrary operations on * the lower layer. The disadvantage is that vnode arguments must be * manualy mapped. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "compat_freebsd.h" #if __FreeBSD_version >= 700055 #include #endif #include "vmblock_k.h" #include "vmblock.h" #include "block.h" #include #include #include #include /* * Local functions */ static fo_ioctl_t VMBlockFileIoctl; static fo_close_t VMBlockFileClose; static vop_access_t VMBlockVopAccess; static vop_getattr_t VMBlockVopGetAttr; static vop_getwritemount_t VMBlockVopGetWriteMount; static vop_inactive_t VMBlockVopInactive; static vop_ioctl_t VMBlockVopIoctl; static vop_islocked_t VMBlockVopIsLocked; static compat_vop_lock_t VMBlockVopLock; static vop_lookup_t VMBlockVopLookup; static vop_open_t VMBlockVopOpen; static vop_print_t VMBlockVopPrint; static vop_reclaim_t VMBlockVopReclaim; static vop_rename_t VMBlockVopRename; static vop_setattr_t VMBlockVopSetAttr; static vop_unlock_t VMBlockVopUnlock; /* * Local data */ /* * The following is an ioctl(2) argument wrapper for VMBlockVopIoctl. * See the VMBlockFileOps blurb below for details. */ struct VMBlockIoctlArgs { struct file *fileDesc; // file descriptor receiving ioctl request void *data; // user's ioctl argument }; typedef struct VMBlockIoctlArgs VMBlockIoctlArgs; /* * VMBlockFS vnode operations vector -- * Following are the file system's entry points via VFS nodes (vnodes). * See vnode(9) and sys/vnode.h for more information. For details on * the locking protocol[1], have a look at kern/vnode_if.src. * * 1. Describes for which operations a vnode should be locked before * the operation is called or after it returns. */ struct vop_vector VMBlockVnodeOps = { .vop_bypass = VMBlockVopBypass, .vop_access = VMBlockVopAccess, #if __FreeBSD_version >= 900013 .vop_advlockpurge = vop_stdadvlockpurge, #endif .vop_bmap = VOP_EOPNOTSUPP, .vop_getattr = VMBlockVopGetAttr, .vop_getwritemount = VMBlockVopGetWriteMount, .vop_inactive = VMBlockVopInactive, .vop_ioctl = VMBlockVopIoctl, .vop_islocked = VMBlockVopIsLocked, .COMPAT_VOP_LOCK_OP_ELEMENT = VMBlockVopLock, .vop_lookup = VMBlockVopLookup, .vop_open = VMBlockVopOpen, .vop_print = VMBlockVopPrint, .vop_reclaim = VMBlockVopReclaim, .vop_rename = VMBlockVopRename, .vop_setattr = VMBlockVopSetAttr, .vop_strategy = VOP_EOPNOTSUPP, .vop_unlock = VMBlockVopUnlock, }; /* * VMBlockFS file descriptor operations vector -- * There are a few special cases where we need to control behavior beyond * the file system layer. For this we define our own fdesc op vector, * install our own handlers for these special cases, and fall back to the * badfileops vnode ops for everything else. * * VMBlock instances are keyed on/indexed by the file descriptor that received * the ioctl request[1]. Since the relationship between file descriptors and * vnodes is N:1, we need to intercept ioctl requests at the file descriptor * level, rather than at the vnode level, in order to have a record of which * descriptor received the request. Similarly, we need to remove VMBlocks * issued on a file descriptor when said descriptor is closed. * * NOTICE -- * This applies -only- when a user opens the FS mount point directly. All * other files'/directories' file descriptor operations vectors are left * untouched. * * 1. Keying on thread ID/process ID doesn't work because file descriptors * may be shared between threads/processes. Clients may find blocks * removed unintentionally when the original issuing thread or process * dies, even though the same descriptor is open. */ static struct fileops VMBlockFileOps; /* *----------------------------------------------------------------------------- * * VMBlockSetupFileOps -- * * Sets up secial file operations vector used for root vnode _only_ * (see the comment for VMBlockFileOps above). * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VMBlockSetupFileOps(void) { VMBlockFileOps = badfileops; VMBlockFileOps.fo_stat = vnops.fo_stat; VMBlockFileOps.fo_flags = vnops.fo_flags; VMBlockFileOps.fo_ioctl = VMBlockFileIoctl; VMBlockFileOps.fo_close = VMBlockFileClose; } /* *----------------------------------------------------------------------------- * * VMBlockFileIoctl -- * * Wrapper for VMBlockVopIoctl. This is done to provide VMBlockVopIoctl * with information about the file descriptor which received the user's * ioctl request. * * Results: * Zero on success, otherwise an appropriate system error. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int VMBlockFileIoctl(struct file *fp, // IN: user's file descriptor u_long command, // IN: encoded ioctl command void *data, // IN: opaque data argument struct ucred *cred, // IN: caller's credentials struct thread *td) // IN: caller's thread context { VMBlockIoctlArgs args; args.fileDesc = fp; args.data = data; return vnops.fo_ioctl(fp, command, &args, cred, td); } /* *----------------------------------------------------------------------------- * * VMBlockFileClose -- * * Called when a file descriptor is closed. Destroy all blocks opened * on this descriptor, then pass off to vn_closefile to handle any other * cleanup. * * Results: * Zero on success, an appropriate system error otherwise. * (See vn_closefile for more information.) * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int VMBlockFileClose(struct file *fp, // IN: user's file descriptor struct thread *td) // IN: caller's thread context { struct vnode *vp; int removed = 0; vp = MNTTOVMBLOCKMNT(fp->f_vnode->v_mount)->rootVnode; removed = BlockRemoveAllBlocks(fp); VI_LOCK(vp); vp->v_usecount -= removed; VI_UNLOCK(vp); return vnops.fo_close(fp, td); } /* *----------------------------------------------------------------------------- * * VMBlockVopBypass -- * * Default routine for bypassing the VMBlockFS file system layer. * * Results: * Zero on success, or an appropriate system error otherwise. * * Side effects: * Parameters passed in via ap->a_desc may be modified by the lower * layer's routines. * * Original function comment: * This is the 10-Apr-92 bypass routine. * This version has been optimized for speed, throwing away some * safety checks. It should still always work, but it's not as * robust to programmer errors. * * In general, we map all vnodes going down and unmap them on the way back. * As an exception to this, vnodes can be marked "unmapped" by setting * the Nth bit in operation's vdesc_flags. * * Also, some BSD vnode operations have the side effect of vrele'ing * their arguments. With stacking, the reference counts are held * by the upper node, not the lower one, so we must handle these * side-effects here. This is not of concern in Sun-derived systems * since there are no such side-effects. * * This makes the following assumptions: * - only one returned vpp * - no INOUT vpp's (Sun's vop_open has one of these) * - the vnode operation vector of the first vnode should be used * to determine what implementation of the op should be invoked * - all mapped vnodes are of our vnode-type (NEEDSWORK: * problems on rmdir'ing mount points and renaming?) * *----------------------------------------------------------------------------- */ int VMBlockVopBypass(struct vop_generic_args *ap) /* struct vop_generic_args { struct vnodeop_desc *a_desc; // IN/OUT: Vnode operation description; incl. // pointers to operand vnode(s), user // credentials, calling thread context, // etc. }; */ { struct vnode **this_vp_p; int error; struct vnode *old_vps[VDESC_MAX_VPS]; struct vnode **vps_p[VDESC_MAX_VPS]; struct vnode ***vppp; struct vnodeop_desc *descp = ap->a_desc; int reles, i; #ifdef DIAGNOSTIC /* * We require at least one vp. */ if (descp->vdesc_vp_offsets == NULL || descp->vdesc_vp_offsets[0] == VDESC_NO_OFFSET) { panic ("VMBlockVopBypass: no vp's in map"); } #endif /* * Map the vnodes going in. Later, we'll invoke the operation based on * the first mapped vnode's operation vector. */ reles = descp->vdesc_flags; for (i = 0; i < VDESC_MAX_VPS; reles >>= 1, i++) { if (descp->vdesc_vp_offsets[i] == VDESC_NO_OFFSET) { break; /* bail out at end of list */ } vps_p[i] = this_vp_p = VOPARG_OFFSETTO(struct vnode**,descp->vdesc_vp_offsets[i],ap); /* * We're not guaranteed that any but the first vnode are of our type. * Check for and don't map any that aren't. (We must always map first * vp or vclean fails.) */ if (i && (*this_vp_p == NULLVP || (*this_vp_p)->v_op != &VMBlockVnodeOps)) { old_vps[i] = NULLVP; } else { old_vps[i] = *this_vp_p; *(vps_p[i]) = VMBVPTOLOWERVP(*this_vp_p); /* * XXX - Several operations have the side effect of vrele'ing their * vp's. We must account for that. (This should go away in the * future.) */ if (reles & VDESC_VP0_WILLRELE) { VREF(*this_vp_p); } } } /* * Call the operation on the lower layer with the modified argument * structure. */ if (vps_p[0] && *vps_p[0]) { error = VCALL(ap); } else { printf("VMBlockVopBypass: no map for %s\n", descp->vdesc_name); error = EINVAL; } /* * Maintain the illusion of call-by-value by restoring vnodes in the * argument structure to their original value. */ reles = descp->vdesc_flags; for (i = 0; i < VDESC_MAX_VPS; reles >>= 1, i++) { if (descp->vdesc_vp_offsets[i] == VDESC_NO_OFFSET) { break; /* bail out at end of list */ } if (old_vps[i]) { *(vps_p[i]) = old_vps[i]; if (reles & VDESC_VP0_WILLRELE) { vrele(*(vps_p[i])); } } } /* * Map the possible out-going vpp (Assumes that the lower layer always * returns a VREF'ed vpp unless it gets an error.) */ if (descp->vdesc_vpp_offset != VDESC_NO_OFFSET && !(descp->vdesc_flags & VDESC_NOMAP_VPP) && !error) { /* * XXX - even though some ops have vpp returned vp's, several ops * actually vrele this before returning. We must avoid these ops. * (This should go away when these ops are regularized.) */ if (descp->vdesc_flags & VDESC_VPP_WILLRELE) { goto out; } vppp = VOPARG_OFFSETTO(struct vnode***, descp->vdesc_vpp_offset,ap); if (*vppp) { /* FIXME: set proper name for the vnode */ error = VMBlockNodeGet(old_vps[0]->v_mount, **vppp, *vppp, NULL); } } out: return error; } /* *----------------------------------------------------------------------------- * * VMBlockVopLookup -- * * "VOP_LOOKUP(9) -- lookup a component of a pathname" * * Results: * Zero if the component name is found. EJUSTRETURN if the namei * operation is CREATE or RENAME, we're looking up the final component * name, and said operation would succeed. Otherwise returns an * appropriate system error. * * Side effects: * Requested vnode is locked and returned in *ap->a_vpp. * * Original function comment: * We have to carry on the locking protocol on the null layer vnodes * as we progress through the tree. We also have to enforce read-only * if this layer is mounted read-only. * *----------------------------------------------------------------------------- */ static int VMBlockVopLookup(struct vop_lookup_args *ap) /* struct vop_lookup_args { struct vnode *dvp; // IN: pointer to searched directory struct vnode **vpp; // OUT: if found, points to requested // vnode; else NULL struct componentname *cnp; // IN: directory search context }; */ { struct componentname *cnp = ap->a_cnp; COMPAT_THREAD_VAR(td, cnp->cn_thread); struct vnode *dvp = ap->a_dvp; struct vnode *vp, *ldvp, *lvp; BlockHandle blockCookie; int flags = cnp->cn_flags; int error = 0; char *pathname; size_t pathname_len; /* * Fail attempts to modify a read-only filesystem w/o bothering with a * lower-layer lookup. */ if ((flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) && (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) { return EROFS; } /* * Before looking in the lower layer, determine whether the search path * should be blocked. If so, do the following: * 1. Make a copy of the block pathname. (BlockWaitOnFile may make * use of this, and our VMBlockNode may be destroyed while asleep * if user forcibly unmounts file system.) * 2. Bump up hold counts of current VMBlock directory vnode and its * lower layer counterpart. This makes sure that at least they * aren't purged from memory while we sleep. * 3. Unlock & relock directory vnodes around sleeping. This prevents * a cascading file system lookup deadlock. (E.g., we have dvp locked, * but another thread trying to look up dvp will block, holding /its/ * dvp's (dvp2) lock, and yet another thread would block looking up * dvp2 while holding its dvp (dvp3), etc. * * If we find we were forcibly unmounted, fail with EIO. */ pathname = uma_zalloc(VMBlockPathnameZone, M_WAITOK); if (pathname == NULL) { return ENOMEM; } /* * FIXME: we need to ensure that vnode always has name set up. * Currently VMBlockVopBypass() may produce vnodes without a name. */ pathname_len = strlcpy(pathname, VPTOVMB(dvp)->name ? VPTOVMB(dvp)->name : ".", MAXPATHLEN); /* * Make sure we have room in the buffer to add our component. * + 1 is for separator (slash). */ if (pathname_len + 1 + cnp->cn_namelen >= MAXPATHLEN) { error = ENAMETOOLONG; goto out; } if ((blockCookie = BlockLookup(pathname, OS_UNKNOWN_BLOCKER)) != NULL) { int lkflags = compat_lockstatus(dvp->v_vnlock, td) & LK_TYPE_MASK; lvp = VPTOVMB(dvp)->lowerVnode; vhold(dvp); vhold(lvp); COMPAT_VOP_UNLOCK(dvp, 0, td); error = BlockWaitOnFile(pathname, blockCookie); COMPAT_VOP_LOCK(dvp, lkflags, td); vdrop(lvp); vdrop(dvp); if (dvp->v_op != &VMBlockVnodeOps) { Debug("%s: vmblockfs forcibly unmounted?\n", __func__); error = EIO; } if (error) { goto out; } } /* We already verified that buffer is big enough. */ pathname[pathname_len] = '/'; bcopy(cnp->cn_nameptr, &pathname[pathname_len + 1], cnp->cn_namelen); pathname[pathname_len + 1 + cnp->cn_namelen] = 0; /* * Although it is possible to call VMBlockVopBypass(), we'll do a direct * call to reduce overhead */ ldvp = VMBVPTOLOWERVP(dvp); vp = lvp = NULL; error = VOP_LOOKUP(ldvp, &lvp, cnp); if (error == EJUSTRETURN && (flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) && (cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME)) { error = EROFS; } if ((error == 0 || error == EJUSTRETURN) && lvp != NULL) { /* * Per VOP_LOOKUP(9), if looking up the current directory ("."), we bump * our vnode's refcount. */ if (ldvp == lvp) { *ap->a_vpp = dvp; VREF(dvp); vrele(lvp); } else { error = VMBlockNodeGet(dvp->v_mount, lvp, &vp, pathname); if (error) { /* XXX Cleanup needed... */ panic("VMBlockNodeGet failed"); } *ap->a_vpp = vp; /* The vnode now owns pathname so don't try to free it below. */ pathname = NULL; } } out: if (pathname) { uma_zfree(VMBlockPathnameZone, pathname); } return error; } /* *---------------------------------------------------------------------------- * * VMBlockVopOpen -- * * "The VOP_OPEN() entry point is called before a file is accessed by a * process..." - VOP_OPEN(9). If the vnode in question is the file * system's root vnode, allow access only to the superuser. * * Results: * Zero on success, an appropriate system error otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VMBlockVopOpen(struct vop_open_args *ap) /* struct vop_open_args { struct vnode *vp; // IN: vnode which ioctl issued upon int fflag; // IN: fdesc flags (see fcntl(2)) struct ucred *cred; // IN: caller's credentials (usually real uid vs euid) struct thread *td; // IN: calling thread's context FreeBSD <= 6 -- int fdidx; // IN: file descriptor number alloc'd to this open() FreeBSD >= 7 -- struct file *fp // IN: struct associated with this particular open() }; */ { VMBlockMount *mp; VMBlockNode *mip; struct vnode *vp, *ldvp; struct file *fp; int retval; vp = ap->a_vp; ldvp = VMBVPTOLOWERVP(vp); mip = VPTOVMB(ap->a_vp); mp = MNTTOVMBLOCKMNT(ap->a_vp->v_mount); if (ap->a_vp == mp->rootVnode) { /* * Opening the mount point is a special case. First, only allow this * access to the superuser. Next, we install a custom fileops vector in * order to trap the ioctl() and close() operations. (See the *FileOps' * descriptions for more details.) * * NB: Allowing only the superuser to open this directory breaks * readdir() of the filesystem root for non-privileged users. * * Also, on FreeBSD 8.0 and newer we check for a specific module priv * because none of the existing privs seemed to match very well. */ if ((retval = compat_priv_check(ap->a_td, PRIV_DRIVER)) == 0) { #if __FreeBSD_version >= 700055 fp = ap->a_fp; #else fp = ap->a_td->td_proc->p_fd->fd_ofiles[ap->a_fdidx]; #endif fp->f_ops = &VMBlockFileOps; } } else { /* * Pass off to the lower layer. If lower layer mapped a VM object, copy * its reference. */ retval = VMBlockVopBypass(&ap->a_gen); if (retval == 0) { vp->v_object = ldvp->v_object; } } return retval; } /* *----------------------------------------------------------------------------- * * VMBlockVopSetAttr -- * * "VOP_SETATTR(9) -- set attributes on a file or directory." * * This version is simpler than the original null_setattr as it only * tests whether the user is attempting an operation in a read-only * file system. Beyond that, it defers judgment about the validity of * the request to the lower layer via vop_bypass. * * Results: * Zero on success, else an appropriate system error. * * Side effects: * None. * * Original function comment: * Setattr call. Disallow write attempts if the layer is mounted read- * only. * *----------------------------------------------------------------------------- */ static int VMBlockVopSetAttr(struct vop_setattr_args *ap) /* struct vop_setattr_args { struct vnode *vp; // IN: vnode operand struct vattr *vap; // IN: attributes struct ucred *cred; // IN: caller's credentials struct thread *td; // IN: caller's thread context }; */ { struct vnode *vp = ap->a_vp; if (vp->v_mount->mnt_flag & MNT_RDONLY) { return EROFS; } return VMBlockVopBypass((struct vop_generic_args *)ap); } /* *---------------------------------------------------------------------------- * * VMBlockVopIoctl -- * * Handle ioctl(2) requests to add and remove file blocks. Ioctl * commands are defined in public/vmblock.h. * * Results: * Zero on success, otherwise an appropriate error is returned. * * Side effects * A block may be placed on or removed from a file. The root vnode's * reference count will be incremented when a block is successfully added, * and it will be decremented when a block is removed. * *---------------------------------------------------------------------------- */ static int VMBlockVopIoctl(struct vop_ioctl_args *ap) // IN/OUT: ioctl parameters /* struct vop_ioctl_args { struct vnode *vp; // IN: vnode which ioctl issued upon u_long command; // IN: ioctl command caddr_t data; // IN: ioctl parameter (e.g., pathname) int fflag; // IN: fcntl style flags (no-op?) struct ucred *cred; // IN: caller's credentials (usually real uid vs euid) struct thread *td; // IN: calling thread's context }; */ { VMBlockIoctlArgs *ioctlArgs = (VMBlockIoctlArgs *)ap->a_data; VMBlockMount *mp; COMPAT_THREAD_VAR(td, ap->a_td); struct vnode *vp = ap->a_vp; char *pathbuf = NULL; int ret = 0, pathlen; Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockVopIoctl: entry\n"); /* * The operand vnode is passed in unlocked, so test a few things before * proceeding. * 1. Make sure we're still dealing with a VMBlock vnode. Note * that this test -must- come before the next one. Otherwise v_mount * may be invalid. * 2. Make sure the filesystem isn't being unmounted. */ COMPAT_VOP_LOCK(vp, LK_EXCLUSIVE|LK_RETRY, td); if (vp->v_op != &VMBlockVnodeOps || vp->v_mount->mnt_kern_flag & MNTK_UNMOUNT) { COMPAT_VOP_UNLOCK(vp, 0, td); return EBADF; } /* * At this layer/in this file system, only the root vnode handles ioctls, * and only the superuser may open the root vnode. If we're not given * the root vnode, simply bypass to the next lower layer. */ mp = MNTTOVMBLOCKMNT(vp->v_mount); if (vp != mp->rootVnode) { /* * VMBlockFileIoctl wraps the user's data in a special structure which * includes the user's file descriptor, so we must unwrap the data * argument before passing to the lower layer. */ ap->a_data = ioctlArgs->data; COMPAT_VOP_UNLOCK(vp, 0, td); return VMBlockVopBypass((struct vop_generic_args *)ap); } pathbuf = uma_zalloc(VMBlockPathnameZone, M_WAITOK); switch (ap->a_command) { case VMBLOCK_ADD_FILEBLOCK: case VMBLOCK_DEL_FILEBLOCK: { /* * Trim trailing slashes */ pathlen = strlcpy(pathbuf, ioctlArgs->data, MAXPATHLEN); pathlen = MIN(pathlen, MAXPATHLEN); while (pathlen > 0 && pathbuf[pathlen - 1] == '/') { pathbuf[pathlen - 1] = '\0'; pathlen--; } VMBLOCKDEBUG("%s: %s on %s\n", __func__, (ap->a_command == VMBLOCK_ADD_FILEBLOCK) ? "add" : "del", pathbuf); /* * Don't block the mount point! */ if (!strcmp(VPTOVMB(vp)->name, pathbuf)) { ret = EINVAL; } else { ret = (ap->a_command == VMBLOCK_ADD_FILEBLOCK) ? BlockAddFileBlock(pathbuf, ioctlArgs->fileDesc) : BlockRemoveFileBlock(pathbuf, ioctlArgs->fileDesc); /* * When adding a block, bump the reference count on the root vnode. If * removing a block, decrement the reference count. Of course, only do * so if the action succeeds! */ if (ret == 0) { VI_LOCK(vp); vp->v_usecount += (ap->a_command == VMBLOCK_ADD_FILEBLOCK) ? 1 : -1; VI_UNLOCK(vp); } } break; } #ifdef VMX86_DEVEL case VMBLOCK_LIST_FILEBLOCKS: BlockListFileBlocks(); ret = 0; break; case VMBLOCK_PURGE_FILEBLOCKS: { int removed = 0; removed = BlockRemoveAllBlocks(OS_UNKNOWN_BLOCKER); VI_LOCK(vp); vp->v_usecount -= removed; VI_UNLOCK(vp); } ret = 0; break; #endif default: Warning("VMBlockVopIoctl: unknown command (%lu) received.\n", ap->a_command); ret = EOPNOTSUPP; } COMPAT_VOP_UNLOCK(vp, 0, td); if (pathbuf) { uma_zfree(VMBlockPathnameZone, pathbuf); } return ret; } /* *---------------------------------------------------------------------------- * * VMBlockVopGetAttr -- * * Query the underlying filesystem for file/directory information. * Also fixup fsid to be ours rather than that of the underlying fs. * * Results: * Zero on success, an appropriate system error otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VMBlockVopGetAttr(struct vop_getattr_args *ap) /* struct vop_getattr_args { struct vnode *vp; // IN: operand vnode struct vattr *vap; // OUT: vnode's parameters struct ucred *ucred; // IN: caller's credentials struct thread *td; // IN: caller's thread context }; */ { int error; if ((error = VMBlockVopBypass((struct vop_generic_args *)ap)) != 0) { return error; } ap->a_vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0]; return 0; } /* *---------------------------------------------------------------------------- * * VMBlockVopAccess -- * * "VOP_ACCESS(9) -- check access permissions of a file or Unix domain * socket." We handle this to disallow write access if our layer is, * for whatever reason, mounted read-only. * * Results: * Zero on success, an appropriate system error otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int VMBlockVopAccess(struct vop_access_args *ap) /* struct vop_access_args { struct vnode *vp; // IN: operand vnode int mode; // IN: access(2) flags struct vattr *vap; // OUT: vnode's parameters struct ucred *ucred; // IN: caller's credentials struct thread *td; // IN: caller's thread context }; */ { struct vnode *vp = ap->a_vp; compat_accmode_t mode = ap->compat_a_accmode; /* * Disallow write attempts on read-only layers; unless the file is a * socket, fifo, or a block or character device resident on the filesystem. */ if (mode & VWRITE) { switch (vp->v_type) { case VDIR: case VLNK: case VREG: if (vp->v_mount->mnt_flag & MNT_RDONLY) { return EROFS; } break; default: break; } } return VMBlockVopBypass((struct vop_generic_args *)ap); } /* *---------------------------------------------------------------------------- * * VMBlockRename -- * * "VOP_RENAME(9) -- rename a file." * * Results: * Zero on success, an appropriate system error otherwise. * * Side effects: * None. * * Original function comment: * We handle this to eliminate null FS to lower FS file moving. Don't * know why we don't allow this, possibly we should. *---------------------------------------------------------------------------- */ static int VMBlockVopRename(struct vop_rename_args *ap) /* struct vop_rename_args { struct vnode *fdvp; // IN: source directory struct vnode *fvp; // IN: source file struct componentname *fcnp; // IN: source's path lookup state struct vnode *tdvp; // IN: destination directory struct vnode *tvp; // IN: destination file struct componentname *tcnp; // IN: destination's path lookup state }; */ { struct vnode *tdvp = ap->a_tdvp; struct vnode *fvp = ap->a_fvp; struct vnode *fdvp = ap->a_fdvp; struct vnode *tvp = ap->a_tvp; /* Check for cross-device rename. */ if ((fvp->v_mount != tdvp->v_mount) || (tvp && (fvp->v_mount != tvp->v_mount))) { if (tdvp == tvp) { vrele(tdvp); } else { vput(tdvp); } if (tvp) { vput(tvp); } vrele(fdvp); vrele(fvp); return EXDEV; } return VMBlockVopBypass((struct vop_generic_args *)ap); } /* *----------------------------------------------------------------------------- * * VMBlockVopLock -- * * Acquire a vnode lock. * * Results: * Zero on success, otherwise an error is returned. * * Side effects: * Upper & lower layers share a lock, so both vnodes will be considered * locked. * * Original function comment: * We need to process our own vnode lock and then clear the interlock flag * as it applies only to our vnode, not the vnodes below us on the stack. *----------------------------------------------------------------------------- */ static int VMBlockVopLock(compat_vop_lock_args *ap) /* struct vop_lock_args { struct vnode *vp; // IN: vnode operand int flags; // IN: lockmgr(9) flags struct thread *td; // IN: calling thread's context }; */ { struct vnode *vp = ap->a_vp; int flags = ap->a_flags; COMPAT_THREAD_VAR(td, ap->a_td); struct VMBlockNode *nn; struct vnode *lvp; int error; if ((flags & LK_INTERLOCK) == 0) { VI_LOCK(vp); ap->a_flags = flags |= LK_INTERLOCK; } nn = VPTOVMB(vp); /* * If we're still active we must ask the lower layer to lock as ffs * has special lock considerations in it's vop lock. -- FreeBSD */ if (nn != NULL && (lvp = VMBVPTOLOWERVP(vp)) != NULL) { VI_LOCK_FLAGS(lvp, MTX_DUPOK); VI_UNLOCK(vp); /* * We have to hold the vnode here to solve a potential reclaim race. * If we're forcibly vgone'd while we still have refs, a thread * could be sleeping inside the lowervp's vop_lock routine. When we * vgone we will drop our last ref to the lowervp, which would * allow it to be reclaimed. The lowervp could then be recycled, * in which case it is not legal to be sleeping in it's VOP. * We prevent it from being recycled by holding the vnode here. */ vholdl(lvp); error = COMPAT_VOP_LOCK(lvp, flags, td); /* * We might have slept to get the lock and someone might have clean * our vnode already, switching vnode lock from one in lowervp * to v_lock in our own vnode structure. Handle this case by * reacquiring correct lock in requested mode. */ if (VPTOVMB(vp) == NULL && error == 0) { ap->a_flags &= ~(LK_TYPE_MASK | LK_INTERLOCK); switch (flags & LK_TYPE_MASK) { case LK_SHARED: ap->a_flags |= LK_SHARED; break; case LK_UPGRADE: case LK_EXCLUSIVE: ap->a_flags |= LK_EXCLUSIVE; break; default: panic("Unsupported lock request %d\n", ap->a_flags); } COMPAT_VOP_UNLOCK(lvp, 0, td); error = vop_stdlock(ap); } vdrop(lvp); } else { error = vop_stdlock(ap); } return error; } /* *----------------------------------------------------------------------------- * * VMBlockVopUnlock -- * * Release a vnode lock. * * Results: * Zero on success, an appropriate system error otherwise. * * Side effects: * None. * * Original function comment: * We need to process our own vnode unlock and then clear the interlock * flag as it applies only to our vnode, not the vnodes below us on * the stack. *----------------------------------------------------------------------------- */ static int VMBlockVopUnlock(struct vop_unlock_args *ap) /* struct vop_unlock_args { struct vnode *vp; // IN: vnode operand int flags; // IN: lock request flags (see lockmgr(9)) struct thread *td; // IN: calling thread's context }; */ { struct vnode *vp = ap->a_vp; int flags = ap->a_flags; COMPAT_THREAD_VAR(td, ap->a_td); struct VMBlockNode *nn; struct vnode *lvp; int error; /* * If caller already holds interlock, drop it. (Per VOP_UNLOCK() API.) * Also strip LK_INTERLOCK from flags passed to lower layer. */ if ((flags & LK_INTERLOCK) != 0) { VI_UNLOCK(vp); ap->a_flags = flags &= ~LK_INTERLOCK; } nn = VPTOVMB(vp); if (nn != NULL && (lvp = VMBVPTOLOWERVP(vp)) != NULL) { error = COMPAT_VOP_UNLOCK(lvp, flags, td); } else { error = vop_stdunlock(ap); } return error; } /* *----------------------------------------------------------------------------- * * VMBlockVopIsLocked -- * * Test whether a vnode is locked. * * Results: * Zero if locked, non-zero otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int VMBlockVopIsLocked(struct vop_islocked_args *ap) /* struct vop_islocked_args { struct vnode *vp; // IN: vnode operand struct thread *td; // IN: calling thread's context }; */ { struct vnode *vp = ap->a_vp; COMPAT_THREAD_VAR(td, ap->a_td); return compat_lockstatus(vp->v_vnlock, td); } /* *----------------------------------------------------------------------------- * * VMBlockVopInactive -- * * "VOP_INACTIVE() is called when the kernel is no longer using the vnode. * This may be because the reference count reaches zero or it may be that * the file system is being forcibly unmounted while there are open files. * It can be used to reclaim space for `open but deleted' files." * * Results: * Zero. * * Side effects: * If this vnode's reference is zero, vrecycle() will handle induce * cleanup. * * Original function comment: * There is no way to tell that someone issued remove/rmdir operation * on the underlying filesystem. For now we just have to release lowevrp * as soon as possible. * * Note, we can't release any resources nor remove vnode from hash before * appropriate VXLOCK stuff is is done because other process can find * this vnode in hash during inactivation and may be sitting in vget() * and waiting for VMBlockVopInactive to unlock vnode. Thus we will do * all those in VOP_RECLAIM. * *----------------------------------------------------------------------------- */ static int VMBlockVopInactive(struct vop_inactive_args *ap) /* struct vop_inactive_args { struct vnode *vp; // IN: vnode operand struct thread *td; // IN: calling thread's context }; */ { struct vnode *vp = ap->a_vp; struct thread *td = ap->a_td; vp->v_object = NULL; /* * If this is the last reference, then free up the vnode so as not to * tie up the lower vnode. */ vrecycle(vp, td); return 0; } /* *----------------------------------------------------------------------------- * * VMBlockVopReclaim -- * * "VOP_RECLAIM() is called when a vnode is being reused for a * different file system. Any file system specific resources * associated with the vnode should be freed." * * Results: * Returns zero. * * Side effects: * If node is an associate VMBlockNode, it's removed from * the VMBlockNode hash and freed. Reference to the lower vnode, if * it exists, is also dropped. * * Original function comment: * Now, the VXLOCK is in force and we're free to destroy the null vnode. * *----------------------------------------------------------------------------- */ static int VMBlockVopReclaim(struct vop_reclaim_args *ap) /* struct vop_reclaim_args { struct vnode *vp; // IN: vnode operand struct thread *td; // IN: calling thread's context }; */ { struct vnode *vp = ap->a_vp; struct VMBlockNode *xp = VPTOVMB(vp); struct vnode *lowervp = xp->lowerVnode; struct lock *vnlock; KASSERT(lowervp != NULL, ("reclaiming node with no lower vnode")); VMBlockHashRem(xp); /* * Use the interlock to protect the clearing of v_data to * prevent faults in VMBlockVopLock(). */ VI_LOCK(vp); vp->v_data = NULL; vp->v_object = NULL; vnlock = vp->v_vnlock; /* * Reassign lock pointer to this vnode's lock. (Originally assigned * to the lower layer's lock.) */ vp->v_vnlock = &vp->v_lock; compat_lockmgr(vp->v_vnlock, LK_EXCLUSIVE|LK_INTERLOCK, VI_MTX(vp), curthread); vput(lowervp); /* * Clean up VMBlockNode attachment. */ if (xp->name) { uma_zfree(VMBlockPathnameZone, xp->name); } free(xp, M_VMBLOCKFSNODE); return 0; } /* *----------------------------------------------------------------------------- * * VMBlockVopPrint -- * * "VOP_PRINT -- print debugging information" * * Results: * Zero. Always. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int VMBlockVopPrint(struct vop_print_args *ap) /* struct vop_print_args { struct vnode *vp; // IN: vnode operand }; */ { struct vnode *vp = ap->a_vp; printf("\tvp=%p, lowervp=%p\n", vp, VMBVPTOLOWERVP(vp)); return 0; } /* *----------------------------------------------------------------------------- * * VMBlockVopGetWriteMount -- * * When the caller wishes to begin a write operation, we need to bump * the count of write operations on the destination file system. This * routine passes the request down. "Real" file systems will usually * call vop_stdgetwritemount(). * * Results: * Zero. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int VMBlockVopGetWriteMount(struct vop_getwritemount_args *ap) /* struct vop_getwritemount_args { struct vnode *vp; // IN: vnode operand struct mount **mpp; // OUT: pointer to filesystem where write operation // will actually occur }; */ { struct VMBlockNode *xp; struct vnode *lowervp; struct vnode *vp; vp = ap->a_vp; VI_LOCK(vp); xp = VPTOVMB(vp); if (xp && (lowervp = xp->lowerVnode)) { VI_LOCK_FLAGS(lowervp, MTX_DUPOK); VI_UNLOCK(vp); vholdl(lowervp); VI_UNLOCK(lowervp); VOP_GETWRITEMOUNT(lowervp, ap->a_mpp); vdrop(lowervp); } else { VI_UNLOCK(vp); *(ap->a_mpp) = NULL; } return 0; } open-vm-tools-9.4.0-1280544/modules/freebsd/vmblock/COPYING0000644765153500003110000000262612220061556021217 0ustar dtormtsRedistribution 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 VMware Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission of VMware Inc. 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. open-vm-tools-9.4.0-1280544/modules/freebsd/vmblock/vmblock_k.h0000644765153500003110000001113112220061556022273 0ustar dtormts/* ********************************************************** * Copyright (C) 2007 VMware, Inc. All Rights Reserved. * **********************************************************/ /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software donated to Berkeley by * Jan-Simon Pendry. * * 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. * * @(#)null.h 8.3 (Berkeley) 8/20/94 * * $FreeBSD: src/sys/fs/nullfs/null.h,v 1.23 2005/03/15 13:49:33 jeff Exp $ */ /* * vmblock_k.h -- * * Defnitions for entire vmblock module. */ #ifndef _VMBLOCK_K_H_ #define _VMBLOCK_K_H_ #ifdef _KERNEL #include #include #include #include #include #include "vm_basic_types.h" #include "vm_assert.h" #include "block.h" /* * Macros */ #ifdef VMBLOCKFS_DEBUG # define VMBLOCKFSDEBUG(format, args...) printf(format ,## args) #else # define VMBLOCKFSDEBUG(format, args...) #endif /* VMBLOCKFS_DEBUG */ #define MNTTOVMBLOCKMNT(mp) ((struct VMBlockMount *)((mp)->mnt_data)) #define VPTOVMB(vp) ((struct VMBlockNode *)(vp)->v_data) #define VMBTOVP(xp) ((xp)->backVnode) /* * Debug logging */ #define VMBLOCK_DEBUG LOG_DEBUG #define VMBLOCK_ERROR LOG_WARNING #define VMBLOCK_ENTRY_LOGLEVEL LOG_DEBUG #define Warning(fmt, args...) log(VMBLOCK_ERROR, fmt, ##args) #ifdef VMX86_DEVEL # define LOG(level, fmt, args...) printf(fmt, ##args) # define VMBLOCKDEBUG(fmt, args...) log(VMBLOCK_DEBUG, fmt, ##args) # define Debug(level, fmt, args...) log(VMBLOCK_DEBUG, fmt, ##args) #else # define LOG(level, fmt, args...) # define VMBLOCKDEBUG(fmt, args...) # define Debug(level, fmt, args...) #endif /* * Describes a single mount instance */ typedef struct VMBlockMount { struct mount *mountVFS; /* Reference to mount parameters */ struct vnode *rootVnode; /* Reference to root vnode */ } VMBlockMount; /* * A cache of vnode references */ typedef struct VMBlockNode { LIST_ENTRY(VMBlockNode) hashEntry; /* Hash chain element (contains ptr to next node, etc.) */ struct vnode *lowerVnode; /* VREFed once */ struct vnode *backVnode; /* Back pointer */ char *name; /* Looked up path to vnode */ } VMBlockNode; /* * Global variables */ extern struct vop_vector VMBlockVnodeOps; extern uma_zone_t VMBlockPathnameZone; /* * Global functions */ int VMBlockInit(struct vfsconf *vfsp); int VMBlockUninit(struct vfsconf *vfsp); int VMBlockNodeGet(struct mount *mp, struct vnode *target, struct vnode **vpp, char *pathname); void VMBlockHashRem(struct VMBlockNode *xp); void VMBlockSetupFileOps(void); int VMBlockVopBypass(struct vop_generic_args *ap); #ifdef DIAGNOSTIC struct vnode *VMBlockCheckVp(struct vnode *vp, char *fil, int lno); # define VMBVPTOLOWERVP(vp) VMBlockCheckVp((vp), __FILE__, __LINE__) #else # define VMBVPTOLOWERVP(vp) (VPTOVMB(vp)->lowerVnode) #endif #ifdef MALLOC_DECLARE MALLOC_DECLARE(M_VMBLOCKFSNODE); #endif #endif /* _KERNEL */ #endif /* _VMBLOCK_K_H_ */ open-vm-tools-9.4.0-1280544/modules/freebsd/vmblock/Makefile0000644765153500003110000000467612220061556021633 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 2006 VMware, Inc. 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. # 3. Neither the name of VMware Inc. nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission of VMware Inc. # # 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. # ########################################################## #### #### VMware vmblock Makefile to be distributed externally #### HEADERS := block.h HEADERS += vnode_if.h HEADERS += vmblock_k.h HEADERS += os.h CSRCS := block.c CSRCS += os_panic.c CSRCS += vfsops.c CSRCS += vnops.c CSRCS += subr.c CSRCS += stubs.c SRCS := $(HEADERS) $(CSRCS) KMOD = vmblock PROG = ../$(KMOD).ko NOMAN = t NO_MAN = t KLDMOD = t VMBLOCK := $(MAINSRCROOT)/modules/vmblock CFLAGS += $(INCLUDE) -Wall -Werror .ifdef OVT_SOURCE_DIR CFLAGS += -I$(OVT_SOURCE_DIR)/lib/include CFLAGS += -I$(OVT_SOURCE_DIR)/modules/freebsd/shared CFLAGS += -I$(OVT_SOURCE_DIR)/modules/freebsd/vmblock CFLAGS += -I$(OVT_SOURCE_DIR)/modules/shared/vmblock VPATH := $(OVT_SOURCE_DIR)/modules/shared/vmblock .else CFLAGS += -Ishared .endif EXPORT_SYMS = NO .include open-vm-tools-9.4.0-1280544/modules/freebsd/vmblock/vfsops.c0000644765153500003110000003366612220061556021660 0ustar dtormts/* ********************************************************** * Copyright 2007 VMware, Inc. All rights reserved. * **********************************************************/ /* * vfsops.c -- * * VFS operations for VMBlock file system on FreeBSD. */ /*- * Copyright (c) 1992, 1993, 1995 * The Regents of the University of California. All rights reserved. * * This code is derived from software donated to Berkeley by * Jan-Simon Pendry. * * 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. * * @(#)null_vfsops.c 8.2 (Berkeley) 1/21/94 * * @(#)lofs_vfsops.c 1.2 (Berkeley) 6/18/92 * $FreeBSD: src/sys/fs/nullfs/null_vfsops.c,v 1.72.2.5 2006/10/09 19:47:14 tegge Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include "vmblock_k.h" #include "compat_freebsd.h" static MALLOC_DEFINE(M_VMBLOCKFSMNT, "VMBlockFS mount", "VMBlockFS mount structure"); /* * Local data */ static vfs_mount_t VMBlockVFSMount; static vfs_root_t VMBlockVFSRoot; static vfs_sync_t VMBlockVFSSync; static vfs_statfs_t VMBlockVFSStatFS; static vfs_unmount_t VMBlockVFSUnmount; static vfs_vget_t VMBlockVFSVGet; /* * VFS operations vector */ static struct vfsops VMBlockVFSOps = { .vfs_init = VMBlockInit, .vfs_uninit = VMBlockUninit, .vfs_mount = VMBlockVFSMount, .vfs_root = VMBlockVFSRoot, .vfs_statfs = VMBlockVFSStatFS, .vfs_sync = VMBlockVFSSync, .vfs_unmount = VMBlockVFSUnmount, .vfs_vget = VMBlockVFSVGet, }; /* * The following generates a struct vfsconf for our filesystem & grafts us into * the kernel's list of known filesystems at module load. */ VFS_SET(VMBlockVFSOps, vmblock, VFCF_LOOPBACK); /* *----------------------------------------------------------------------------- * * VMBlockVFSMount -- * * Mount the vmblock file system. * * Results: * Zero on success, otherwise an appropriate system error. (See * VFS_MOUNT(9).) * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int #if __FreeBSD_version >= 800011 VMBlockVFSMount(struct mount *mp) // IN: mount(2) parameters #else VMBlockVFSMount(struct mount *mp, // IN: mount(2) parameters struct thread *td) // IN: caller's thread context #endif { struct VMBlockMount *xmp; struct nameidata nd, *ndp = &nd; struct vnode *lowerrootvp, *vp; char *target; char *pathname; int len, error = 0; VMBLOCKDEBUG("VMBlockVFSMount(mp = %p)\n", (void *)mp); /* * TODO: Strip out extraneous export & other misc cruft. */ /* * Disallow the following: * 1. Mounting over the system root. * 2. Mount updates/remounts. (Reconsider for rw->ro, ro->rw?) * 3. Mounting VMBlock on top of a VMBlock. */ if ((mp->mnt_flag & MNT_ROOTFS) || (mp->mnt_flag & MNT_UPDATE) || (mp->mnt_vnodecovered->v_op == &VMBlockVnodeOps)) { return EOPNOTSUPP; } /* * XXX Should only be unlocked if mnt_flag & MNT_UPDATE. */ ASSERT_VOP_UNLOCKED(mp->mnt_vnodecovered, "Covered vnode already locked!"); /* * Look up path to lower layer (VMBlock source / DnD staging area). * (E.g., in the command "mount /tmp/VMwareDnD /var/run/vmblock", * /tmp/VMwareDnD is the staging area.) */ error = vfs_getopt(mp->mnt_optnew, "target", (void **)&target, &len); if (error || target[len - 1] != '\0') { return EINVAL; } pathname = uma_zalloc(VMBlockPathnameZone, M_WAITOK); if (pathname == NULL) { return ENOMEM; } if (strlcpy(pathname, target, MAXPATHLEN) >= MAXPATHLEN) { uma_zfree(VMBlockPathnameZone, pathname); return ENAMETOOLONG; } /* * Find lower node and lock if not already locked. */ NDINIT(ndp, LOOKUP, FOLLOW|LOCKLEAF, UIO_SYSSPACE, target, compat_td); error = namei(ndp); if (error) { NDFREE(ndp, 0); uma_zfree(VMBlockPathnameZone, pathname); return error; } NDFREE(ndp, NDF_ONLY_PNBUF); /* * Check multi VMBlock mount to avoid `lock against myself' panic. */ lowerrootvp = ndp->ni_vp; if (lowerrootvp == VPTOVMB(mp->mnt_vnodecovered)->lowerVnode) { VMBLOCKDEBUG("VMBlockVFSMount: multi vmblock mount?\n"); vput(lowerrootvp); uma_zfree(VMBlockPathnameZone, pathname); return EDEADLK; } xmp = malloc(sizeof *xmp, M_VMBLOCKFSMNT, M_WAITOK); /* * Record pointer (mountVFS) to the staging area's file system. Follow up * by grabbing a VMBlockNode for our layer's root. */ xmp->mountVFS = lowerrootvp->v_mount; error = VMBlockNodeGet(mp, lowerrootvp, &vp, pathname); /* * Make sure the node alias worked */ if (error) { COMPAT_VOP_UNLOCK(vp, 0, compat_td); vrele(lowerrootvp); free(xmp, M_VMBLOCKFSMNT); /* XXX */ uma_zfree(VMBlockPathnameZone, pathname); return error; } /* * Record a reference to the new filesystem's root vnode & mark it as such. */ xmp->rootVnode = vp; xmp->rootVnode->v_vflag |= VV_ROOT; /* * Unlock the node (either the lower or the alias) */ COMPAT_VOP_UNLOCK(vp, 0, compat_td); /* * If the staging area is a local filesystem, reflect that here, too. (We * could potentially allow NFS staging areas.) */ MNT_ILOCK(mp); mp->mnt_flag |= lowerrootvp->v_mount->mnt_flag & MNT_LOCAL; #if __FreeBSD_version >= 600000 mp->mnt_kern_flag |= lowerrootvp->v_mount->mnt_kern_flag & MNTK_MPSAFE; #endif MNT_IUNLOCK(mp); mp->mnt_data = (qaddr_t) xmp; vfs_getnewfsid(mp); vfs_mountedfrom(mp, target); VMBLOCKDEBUG("VMBlockVFSMount: lower %s, alias at %s\n", mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname); return 0; } /* *----------------------------------------------------------------------------- * * VMBlockVFSUnmount -- * * "VFS_UNMOUNT(9) -- unmount a filesystem." * * Results: * Zero on success, else an appropriate system error. * * Side effects: * VMBlocks on all filesystems are removed. (Expecting vmblockfs to * be mounted only once.) * *----------------------------------------------------------------------------- */ static int #if __FreeBSD_version >= 800011 VMBlockVFSUnmount(struct mount *mp, // IN: filesystem to unmount int mntflags) // IN: unmount(2) flags (ex: MNT_FORCE) #else VMBlockVFSUnmount(struct mount *mp, // IN: filesystem to unmount int mntflags, // IN: unmount(2) flags (ex: MNT_FORCE) struct thread *td) // IN: caller's kernel thread context #endif { struct VMBlockMount *xmp; struct vnode *vp; void *mntdata; int error; int flags = 0, removed = 0; VMBLOCKDEBUG("VMBlockVFSUnmount: mp = %p\n", (void *)mp); xmp = MNTTOVMBLOCKMNT(mp); vp = xmp->rootVnode; VI_LOCK(vp); /* * VMBlocks reference the root vnode. This check returns EBUSY if * VMBlocks still exist & the user isn't forcing us out. */ if ((vp->v_usecount > 1) && !(mntflags & MNT_FORCE)) { VI_UNLOCK(vp); return EBUSY; } /* * FreeBSD forbids acquiring sleepable locks (ex: sx locks) while holding * non-sleepable locks (ex: mutexes). The vnode interlock acquired above * is a mutex, and the Block* routines involve sx locks, so we need to * yield the interlock. * * In order to do this safely, we trade up to locking the entire vnode, * and indicate to the lock routine that we hold the interlock. The lock * transfer will happen atomically. (Er, at least within the scope of * the vnode subsystem.) */ COMPAT_VOP_LOCK(vp, LK_EXCLUSIVE|LK_RETRY|LK_INTERLOCK, compat_td); removed = BlockRemoveAllBlocks(OS_UNKNOWN_BLOCKER); VI_LOCK(vp); vp->v_usecount -= removed; VI_UNLOCK(vp); COMPAT_VOP_UNLOCK(vp, 0, compat_td); if (mntflags & MNT_FORCE) { flags |= FORCECLOSE; } /* There is 1 extra root vnode reference (xmp->rootVnode). */ error = vflush(mp, 1, flags, compat_td); if (error) { return error; } /* * Finally, throw away the VMBlockMount structure */ mntdata = mp->mnt_data; mp->mnt_data = 0; free(mntdata, M_VMBLOCKFSMNT); return 0; } /* *----------------------------------------------------------------------------- * * VMBlockVFSRoot -- * * "VFS_ROOT -- return the root vnode of a file system." * * Results: * Zero. * * Side effects: * Root vnode is locked. * *----------------------------------------------------------------------------- */ static int #if __FreeBSD_version >= 800011 VMBlockVFSRoot(struct mount *mp, // IN: vmblock file system int flags, // IN: lockmgr(9) flags struct vnode **vpp) // OUT: root vnode #else VMBlockVFSRoot(struct mount *mp, // IN: vmblock file system int flags, // IN: lockmgr(9) flags struct vnode **vpp, // OUT: root vnode struct thread *td) // IN: caller's thread context #endif { struct vnode *vp; /* * Return locked reference to root. */ vp = MNTTOVMBLOCKMNT(mp)->rootVnode; VREF(vp); compat_vn_lock(vp, flags | LK_RETRY, compat_td); *vpp = vp; return 0; } /* *----------------------------------------------------------------------------- * * VMBlockVFSStatFS -- * * "VFS_STATFS -- return file system status." We pass the request to the * lower layer, but return only the "interesting" bits. (E.g., fs type, * sizes, usage, etc.) * * Results: * Zero on success, an appropriate system error otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int #if __FreeBSD_version >= 800011 VMBlockVFSStatFS(struct mount *mp, // IN: vmblock file system struct statfs *sbp) // OUT: statfs(2) arg container #else VMBlockVFSStatFS(struct mount *mp, // IN: vmblock file system struct statfs *sbp, // OUT: statfs(2) arg container struct thread *td) // IN: caller's thread context #endif { int error; struct statfs mstat; VMBLOCKDEBUG("VMBlockVFSStatFS(mp = %p, vp = %p->%p)\n", (void *)mp, (void *)MNTTOVMBLOCKMNT(mp)->rootVnode, (void *)VMBVPTOLOWERVP(MNTTOVMBLOCKMNT(mp)->rootVnode)); bzero(&mstat, sizeof mstat); error = COMPAT_VFS_STATFS(MNTTOVMBLOCKMNT(mp)->mountVFS, &mstat, compat_td); if (error) { return error; } /* now copy across the "interesting" information and fake the rest */ sbp->f_type = mstat.f_type; sbp->f_flags = mstat.f_flags; sbp->f_bsize = mstat.f_bsize; sbp->f_iosize = mstat.f_iosize; sbp->f_blocks = mstat.f_blocks; sbp->f_bfree = mstat.f_bfree; sbp->f_bavail = mstat.f_bavail; sbp->f_files = mstat.f_files; sbp->f_ffree = mstat.f_ffree; return 0; } /* *----------------------------------------------------------------------------- * * VMBlockVFSSync -- * * "VFS_SYNC -- flush unwritten data." Since there's no caching at our * layer, this is a no-op. * * Results: * Zero. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int #if __FreeBSD_version >= 800011 VMBlockVFSSync(struct mount *mp, // Ignored int waitfor) // Ignored #else VMBlockVFSSync(struct mount *mp, // Ignored int waitfor, // Ignored struct thread *td) // Ignored #endif { return 0; } /* *----------------------------------------------------------------------------- * * VMBlockVFSVGet -- * * "VFS_VGET -- convert an inode number to a vnode." * * Results: * Zero on success, otherwise an appropriate system error. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int VMBlockVFSVGet(struct mount *mp, // IN: vmblock file system ino_t ino, // IN: requested inode number int flags, // IN: vget(9) locking flags struct vnode **vpp) // OUT: located vnode { int error; error = VFS_VGET(MNTTOVMBLOCKMNT(mp)->mountVFS, ino, flags, vpp); if (error) { return error; } return VMBlockNodeGet(mp, *vpp, vpp, NULL); } open-vm-tools-9.4.0-1280544/modules/freebsd/vmblock/os.h0000644765153500003110000001357512220061556020763 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. 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. * 3. Neither the name of VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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. * *********************************************************/ /* * os.h -- * * FreeBSD-specific definitions. */ #ifndef __OS_H__ #define __OS_H__ #include #include #include #include #include #include #include #include #include #include "vm_basic_types.h" typedef struct sx os_rwlock_t; typedef struct uma_zone os_kmem_cache_t; typedef struct os_completion_t { Bool completed; struct mtx mutex; struct cv cv; } os_completion_t; /* * Changing the os_atomic_t type requires that the os_atomic_* macros below be * changed as well. */ typedef unsigned int os_atomic_t; typedef struct file * os_blocker_id_t; #define OS_UNKNOWN_BLOCKER NULL #define OS_ENOMEM ENOMEM #define OS_ENOENT ENOENT #define OS_EEXIST EEXIST #define OS_PATH_MAX MAXPATHLEN #define OS_KMEM_CACHE_FLAG_HWALIGN 0 // unused #define OS_FMTTID "p" #define os_threadid curthread extern NORETURN void os_panic(const char *fmt, va_list args); #define os_rwlock_init(lock) sx_init(lock, "vmblock-sx") #define os_rwlock_destroy(lock) sx_destroy(lock) #define os_assert_rwlock_held(lock) sx_assert(lock, SX_LOCKED) #define os_read_lock(lock) sx_slock(lock) #define os_write_lock(lock) sx_xlock(lock) #define os_read_unlock(lock) sx_sunlock(lock) #define os_write_unlock(lock) sx_xunlock(lock) /* * XXX linux/os.h requests alignment on HW cache lines. Is this of * serious concern? We can do that by using UMA_ALIGN_CACHE as the * 'align' parameter to uma_zalloc, but with slightly different * semantics, it sort of changes the name of the game. */ #define os_kmem_cache_create(name, size, align, ctor) \ uma_zcreate(name, size, ctor, NULL, NULL, NULL, align, 0) #define os_kmem_cache_destroy(cache) uma_zdestroy(cache) #define os_kmem_cache_alloc(cache) uma_zalloc(cache, M_WAITOK) #define os_kmem_cache_free(cache, elem) uma_zfree(cache, elem) #define os_completion_init(comp) \ do { \ (comp)->completed = FALSE; \ mtx_init(&(comp)->mutex, "vmblock-mtx", "vmblock-mtx", MTX_DEF); \ cv_init(&(comp)->cv, "vmblock-cv"); \ } while (0) #define os_completion_destroy(comp) \ do { \ mtx_destroy(&(comp)->mutex); \ cv_destroy(&(comp)->cv); \ } while (0) /* * This macro evaluates to non-zero only if cv_wait_sig is interrupted. */ #define os_wait_for_completion(comp) \ ({ \ int error = 0; \ mtx_lock(&(comp)->mutex); \ while (!(comp)->completed && !error) { \ error = cv_wait_sig(&(comp)->cv, &(comp)->mutex); \ } \ mtx_unlock(&(comp)->mutex); \ error; \ }) #define os_complete_all(comp) \ do { \ mtx_lock(&(comp)->mutex); \ (comp)->completed = TRUE; \ cv_broadcast(&(comp)->cv); \ mtx_unlock(&(comp)->mutex); \ } while (0) /* atomic_fetchadd_int returns the value of atomic before addition. */ #define os_atomic_dec_and_test(atomic) (atomic_fetchadd_int(atomic, -1) == 1) #define os_atomic_dec(atomic) atomic_subtract_int(atomic, 1) #define os_atomic_inc(atomic) atomic_add_int(atomic, 1) #define os_atomic_set(atomic, val) atomic_store_rel_int(atomic, val) #define os_atomic_read(atomic) atomic_load_acq_int(atomic) #endif /* __OS_H__ */ open-vm-tools-9.4.0-1280544/modules/freebsd/vmmemctl/0000755765153500003110000000000012220061556020345 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/freebsd/vmmemctl/os.c0000644765153500003110000004420012220061556021132 0ustar dtormts/********************************************************* * Copyright (C) 2000 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * os.c -- * * Wrappers for FreeBSD system functions required by "vmmemctl". */ /* * Compile-Time Options */ #define OS_DISABLE_UNLOAD 0 #define OS_DEBUG 1 /* * Includes */ #include "vm_basic_types.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "os.h" #include "vmballoon.h" /* * Types */ typedef struct { /* system structures */ struct callout_handle callout_handle; /* termination flag */ volatile int stop; } os_timer; typedef struct { unsigned long size; /* bitmap size in bytes */ unsigned long *bitmap; /* bitmap words */ unsigned int hint; /* start searching from this word */ } os_pmap; typedef struct { os_timer timer; os_pmap pmap; vm_object_t vmobject; /* vm backing object */ } os_state; MALLOC_DEFINE(M_VMMEMCTL, BALLOON_NAME, "vmmemctl metadata"); /* * Globals */ static os_state global_state; static void vmmemctl_init_sysctl(void); static void vmmemctl_deinit_sysctl(void); /* *----------------------------------------------------------------------------- * * OS_Malloc -- * * Allocates kernel memory. * * Results: * On success: Pointer to allocated memory * On failure: NULL * * Side effects: * None * *----------------------------------------------------------------------------- */ void * OS_Malloc(size_t size) // IN { return malloc(size, M_VMMEMCTL, M_NOWAIT); } /* *----------------------------------------------------------------------------- * * OS_Free -- * * Free allocated kernel memory. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void OS_Free(void *ptr, // IN size_t size) // IN { free(ptr, M_VMMEMCTL); } /* *----------------------------------------------------------------------------- * * OS_MemZero -- * * Fill a memory location with 0s. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void OS_MemZero(void *ptr, // OUT size_t size) // IN { bzero(ptr, size); } /* *----------------------------------------------------------------------------- * * OS_MemCopy -- * * Copy a memory portion into another location. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void OS_MemCopy(void *dest, // OUT const void *src, // IN size_t size) // IN { memcpy(dest, src, size); } /* find first zero bit */ static __inline__ unsigned long os_ffz(unsigned long word) { #ifdef __x86_64__ __asm__("bsfq %1,%0" :"=r" (word) :"r" (~word)); #else __asm__("bsfl %1,%0" :"=r" (word) :"r" (~word)); #endif return word; } /* *----------------------------------------------------------------------------- * * OS_ReservedPageGetLimit -- * * Predict the maximum achievable balloon size. * * Results: * Total memory pages. * * Side effects: * None * *----------------------------------------------------------------------------- */ unsigned long OS_ReservedPageGetLimit(void) { return cnt.v_page_count; } /* *----------------------------------------------------------------------------- * * OS_ReservedPageGetPA -- * * Convert a page handle (of a physical page previously reserved with * OS_ReservedPageAlloc()) to a pa. * * Results: * The pa. * * Side effects: * None. * *----------------------------------------------------------------------------- */ PA64 OS_ReservedPageGetPA(PageHandle handle) // IN: A valid page handle { return (((vm_page_t)handle)->phys_addr); } /* *----------------------------------------------------------------------------- * * OS_ReservedPageGetHandle -- * * Convert a pa (of a physical page previously reserved with * OS_ReservedPageAlloc()) to a page handle. * * Results: * The page handle. * * Side effects: * None. * *----------------------------------------------------------------------------- */ PageHandle OS_ReservedPageGetHandle(PA64 pa) // IN { return (PageHandle)PHYS_TO_VM_PAGE(pa); } /* *----------------------------------------------------------------------------- * * OS_MapPageHandle -- * * Map a page handle into kernel address space, and return the * mapping to that page handle. * * Results: * The mapping. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Mapping OS_MapPageHandle(PageHandle handle) // IN { vm_offset_t res = kmem_alloc_nofault(kernel_map, PAGE_SIZE); vm_page_t page = (vm_page_t)handle; if (!res) { return MAPPING_INVALID; } pmap_qenter(res, &page, 1); return (Mapping)res; } /* *----------------------------------------------------------------------------- * * OS_Mapping2Addr -- * * Return the address of a previously mapped page handle (with * OS_MapPageHandle). * * Results: * The mapping address. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void * OS_Mapping2Addr(Mapping mapping) // IN { return (void *)mapping; } /* *----------------------------------------------------------------------------- * * OS_UnmapPage -- * * Unmap a previously mapped page handle. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void OS_UnmapPage(Mapping mapping) // IN { pmap_qremove((vm_offset_t)mapping, 1); kmem_free(kernel_map, (vm_offset_t)mapping, PAGE_SIZE); } static void os_pmap_alloc(os_pmap *p) // IN { /* number of pages (div. 8) */ p->size = (cnt.v_page_count + 7) / 8; /* * expand to nearest word boundary * XXX: bitmap can be greater than total number of pages in system */ p->size = (p->size + sizeof(unsigned long) - 1) & ~(sizeof(unsigned long) - 1); p->bitmap = (unsigned long *)kmem_alloc(kernel_map, p->size); } static void os_pmap_free(os_pmap *p) // IN { kmem_free(kernel_map, (vm_offset_t)p->bitmap, p->size); p->size = 0; p->bitmap = NULL; } static void os_pmap_init(os_pmap *p) // IN { /* alloc bitmap for pages in system */ os_pmap_alloc(p); if (!p->bitmap) { p->size = 0; p->bitmap = NULL; return; } /* clear bitmap */ bzero(p->bitmap, p->size); p->hint = 0; } static vm_pindex_t os_pmap_getindex(os_pmap *p) // IN { int i; unsigned long bitidx, wordidx; /* start scanning from hint */ wordidx = p->hint; /* scan bitmap for unset bit */ for (i=0; i < p->size/sizeof (unsigned long); i++) { if (!p->bitmap[wordidx]) { p->bitmap[wordidx] = 1; p->hint = wordidx; return (wordidx * sizeof(unsigned long) * 8); } else if (p->bitmap[wordidx] != ~0UL) { /* find first zero bit */ bitidx = os_ffz(p->bitmap[wordidx]); p->bitmap[wordidx] |= (1<hint = wordidx; return (wordidx * sizeof(unsigned long) * 8) + bitidx; } wordidx = (wordidx+1) % (p->size/sizeof (unsigned long)); } /* failed */ return (vm_pindex_t)-1; } static void os_pmap_putindex(os_pmap *p, // IN vm_pindex_t pindex) // IN { /* unset bit */ p->bitmap[pindex / (8*sizeof(unsigned long))] &= ~(1<<(pindex % (8*sizeof(unsigned long)))); } static void os_kmem_free(vm_page_t page) // IN { os_state *state = &global_state; os_pmap *pmap = &state->pmap; if ( !vm_page_lookup(state->vmobject, page->pindex) ) { return; } os_pmap_putindex(pmap, page->pindex); vm_page_free(page); } static vm_page_t os_kmem_alloc(int alloc_normal_failed) // IN { vm_page_t page; vm_pindex_t pindex; os_state *state = &global_state; os_pmap *pmap = &state->pmap; pindex = os_pmap_getindex(pmap); if (pindex == (vm_pindex_t)-1) { return NULL; } /* * BSD's page allocator does not support flags that are similar to * KM_NOSLEEP and KM_SLEEP in Solaris. The main page allocation function * vm_page_alloc() does not sleep ever. It just returns NULL when it * cannot find a free (or cached-and-clean) page. Therefore, we use * VM_ALLOC_NORMAL and VM_ALLOC_SYSTEM loosely to mean KM_NOSLEEP * and KM_SLEEP respectively. */ if (alloc_normal_failed) { page = vm_page_alloc(state->vmobject, pindex, VM_ALLOC_SYSTEM); } else { page = vm_page_alloc(state->vmobject, pindex, VM_ALLOC_NORMAL); } if (!page) { os_pmap_putindex(pmap, pindex); } return page; } static void os_balloonobject_delete(void) { vm_object_deallocate(global_state.vmobject); } static void os_balloonobject_create(void) { global_state.vmobject = vm_object_allocate(OBJT_DEFAULT, OFF_TO_IDX(VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS)); } /* *----------------------------------------------------------------------------- * * OS_ReservedPageAlloc -- * * Reserve a physical page for the exclusive use of this driver. * * Results: * On success: A valid page handle that can be passed to OS_ReservedPageGetPA() * or OS_ReservedPageFree(). * On failure: PAGE_HANDLE_INVALID * * Side effects: * None. * *----------------------------------------------------------------------------- */ PageHandle OS_ReservedPageAlloc(int canSleep) // IN { vm_page_t page; page = os_kmem_alloc(canSleep); if (page == NULL) { return PAGE_HANDLE_INVALID; } return (PageHandle)page; } /* *----------------------------------------------------------------------------- * * OS_ReservedPageFree -- * * Unreserve a physical page previously reserved with OS_ReservedPageAlloc(). * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void OS_ReservedPageFree(PageHandle handle) // IN: A valid page handle { os_kmem_free((vm_page_t)handle); } /* *----------------------------------------------------------------------------- * * OS_Yield -- * * Yield the CPU, if needed. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void OS_Yield(void) { /* Do nothing. */ } /* * vmmemctl_poll - * * Calls Balloon_QueryAndExecute() to perform ballooning tasks and * then reschedules itself to be executed in BALLOON_POLL_PERIOD * seconds. * * Results: * None. * * Side effects: * None. */ static void vmmemctl_poll(void *data) // IN { os_timer *t = data; if (!t->stop) { /* invoke registered handler, rearm timer */ Balloon_QueryAndExecute(); t->callout_handle = timeout(vmmemctl_poll, t, BALLOON_POLL_PERIOD * hz); } } /* *----------------------------------------------------------------------------- * * vmmemctl_init -- * * Called at driver startup, initializes the balloon state and structures. * * Results: * On success: 0 * On failure: standard error code * * Side effects: * None * *----------------------------------------------------------------------------- */ static int vmmemctl_init(void) { os_state *state = &global_state; os_timer *t = &state->timer; os_pmap *pmap = &state->pmap; if (!Balloon_Init(BALLOON_GUEST_BSD)) { return EIO; } /* initialize timer state */ callout_handle_init(&state->timer.callout_handle); os_pmap_init(pmap); os_balloonobject_create(); /* Set up and start polling */ callout_handle_init(&t->callout_handle); t->stop = FALSE; t->callout_handle = timeout(vmmemctl_poll, t, BALLOON_POLL_PERIOD * hz); vmmemctl_init_sysctl(); /* log device load */ printf(BALLOON_NAME_VERBOSE " initialized\n"); return 0; } /* *----------------------------------------------------------------------------- * * vmmemctl_cleanup -- * * Called when the driver is terminating, cleanup initialized structures. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static void vmmemctl_cleanup(void) { os_state *state = &global_state; os_timer *t = &state->timer; os_pmap *pmap = &state->pmap; vmmemctl_deinit_sysctl(); Balloon_Cleanup(); /* Stop polling */ t->stop = TRUE; untimeout(vmmemctl_poll, t, t->callout_handle); os_balloonobject_delete(); os_pmap_free(pmap); /* log device unload */ printf(BALLOON_NAME_VERBOSE " unloaded\n"); } /* * Module Load/Unload Operations */ static int vmmemctl_load(module_t mod, // IN: Unused int cmd, // IN void *arg) // IN: Unused { int err = 0; switch (cmd) { case MOD_LOAD: err = vmmemctl_init(); break; case MOD_UNLOAD: if (OS_DISABLE_UNLOAD) { /* prevent module unload */ err = EBUSY; } else { vmmemctl_cleanup(); } break; default: err = EINVAL; break; } return err; } static struct sysctl_oid *oid; /* *----------------------------------------------------------------------------- * * vmmemctl_sysctl -- * * This gets called to provide the sysctl output when requested. * * Results: * Error, if any * * Side effects: * Data is written into user-provided buffer * *----------------------------------------------------------------------------- */ static int vmmemctl_sysctl(SYSCTL_HANDLER_ARGS) { char buf[PAGE_SIZE]; size_t len = 0; const BalloonStats *stats = Balloon_GetStats(); /* format size info */ len += snprintf(buf + len, sizeof(buf) - len, "target: %8d pages\n" "current: %8d pages\n", stats->nPagesTarget, stats->nPages); /* format rate info */ len += snprintf(buf + len, sizeof(buf) - len, "rateNoSleepAlloc: %8d pages/sec\n" "rateSleepAlloc: %8d pages/sec\n" "rateFree: %8d pages/sec\n", stats->rateNoSleepAlloc, stats->rateAlloc, stats->rateFree); len += snprintf(buf + len, sizeof(buf) - len, "\n" "timer: %8u\n" "start: %8u (%4u failed)\n" "guestType: %8u (%4u failed)\n" "lock: %8u (%4u failed)\n" "unlock: %8u (%4u failed)\n" "target: %8u (%4u failed)\n" "primNoSleepAlloc: %8u (%4u failed)\n" "primCanSleepAlloc: %8u (%4u failed)\n" "primFree: %8u\n" "errAlloc: %8u\n" "errFree: %8u\n", stats->timer, stats->start, stats->startFail, stats->guestType, stats->guestTypeFail, stats->lock, stats->lockFail, stats->unlock, stats->unlockFail, stats->target, stats->targetFail, stats->primAlloc[BALLOON_PAGE_ALLOC_NOSLEEP], stats->primAllocFail[BALLOON_PAGE_ALLOC_NOSLEEP], stats->primAlloc[BALLOON_PAGE_ALLOC_CANSLEEP], stats->primAllocFail[BALLOON_PAGE_ALLOC_CANSLEEP], stats->primFree, stats->primErrorPageAlloc, stats->primErrorPageFree); return SYSCTL_OUT(req, buf, len + 1); } /* *----------------------------------------------------------------------------- * * vmmemctl_init_sysctl -- * * Init out sysctl, to be used for providing driver state. * * Results: * none * * Side effects: * Sn OID for a sysctl is registered * *----------------------------------------------------------------------------- */ static void vmmemctl_init_sysctl(void) { oid = sysctl_add_oid(NULL, SYSCTL_STATIC_CHILDREN(_vm), OID_AUTO, BALLOON_NAME, CTLTYPE_STRING | CTLFLAG_RD, 0, 0, vmmemctl_sysctl, "A", BALLOON_NAME_VERBOSE); } /* *----------------------------------------------------------------------------- * * vmmemctl_deinit_sysctl -- * * Undo vmmemctl_init_sysctl(). Remove the sysctl we installed. * * Results: * none * * Side effects: * Sn OID for a sysctl is unregistered * *----------------------------------------------------------------------------- */ static void vmmemctl_deinit_sysctl(void) { if (oid) { sysctl_remove_oid(oid,1,0); } } DEV_MODULE(vmmemctl, vmmemctl_load, NULL); open-vm-tools-9.4.0-1280544/modules/freebsd/vmmemctl/README0000644765153500003110000000065612220061556021234 0ustar dtormtsThe files in this directory are the source files for the VMware Memory Control driver. The driver will be built automatically by the VMware Tools install script. If you wish to build the driver by hand, run the following commands: make make install from this directory. The module 'vmmemctl.ko' will be built and installed in /modules. If you have any problems or questions, send mail to support@vmware.com open-vm-tools-9.4.0-1280544/modules/freebsd/vmmemctl/COPYING0000644765153500003110000004310312220061556021401 0ustar dtormts GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. open-vm-tools-9.4.0-1280544/modules/freebsd/vmmemctl/Makefile0000644765153500003110000000322112220061556022003 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 2007 VMware, Inc. All rights reserved. # # 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 version 2 and no later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ########################################################## #### #### vmmemctl Makefile (for FreeBSD guest OS) #### SRCS := os.c SRCS += vmballoon.c SRCS += backdoor_balloon.c SRCS += kernelStubsBSD.c .if $(MACHINE_ARCH) == "amd64" SRCS += backdoorGcc64.c .else SRCS += backdoorGcc32.c .endif KMOD = vmmemctl PROG = ../$(KMOD).ko NOMAN = t NO_MAN = t KLDMOD = t # Don't print a warning that the object dir wasn't specified NOOBJ = 1 NO_OBJ = 1 .ifdef OVT_SOURCE_DIR CFLAGS += -I$(OVT_SOURCE_DIR)/lib/include CFLAGS += -I$(OVT_SOURCE_DIR)/lib/backdoor CFLAGS += -I$(OVT_SOURCE_DIR)/modules/freebsd/shared CFLAGS += -I$(OVT_SOURCE_DIR)/modules/shared/vmmemctl VPATH := $(OVT_SOURCE_DIR)/lib/backdoor VPATH := $(VPATH):$(OVT_SOURCE_DIR)/modules/shared/vmmemctl .else CFLAGS += -Ishared .endif .include .ifndef VERBOSE .SILENT: .endif open-vm-tools-9.4.0-1280544/modules/freebsd/vmmemctl/kernelStubsBSD.c0000644765153500003110000001375312220061556023354 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * kernelStubsBSD.c -- * * Stub functions for use by miscellaneous VMware code when brought into * the FreeBSD kernel. */ #include #include #include #include #include #include "kernelStubs.h" MALLOC_DEFINE(M_VMWARE_TEMP, "VMwareTemp", "VMware: Temporary Allocations"); void Log (const char *fmt, ...) __attribute__ ((alias ("Debug"))); /* *----------------------------------------------------------------------------- * * Debug -- * * Send a debugging message to the system log and/or console. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void Debug(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); } /* *----------------------------------------------------------------------------- * * Panic -- * * Print a panic message & induce a kernel panic. * * Results: * Does not return. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void Panic(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); panic(" "); } /* *----------------------------------------------------------------------------- * * Str_Strcpy -- * * Wrapper around strcpy that panics if the source is too long. * * Results: * Returns a pointer to buf. * * Side effects: * None. * *----------------------------------------------------------------------------- */ char * Str_Strcpy(char *buf, // OUT: destination buffer const char *src, // IN : source buffer size_t maxSize) // IN : size of buf { size_t srcLen = strlen(src); if (srcLen >= maxSize) { panic("%s:%d Buffer too small %p\n", __FILE__, __LINE__, buf); } return memcpy(buf, src, srcLen + 1); // Extra byte = terminator } /* *---------------------------------------------------------------------- * * Str_Vsnprintf -- * * Compatibility wrapper for vsnprintf(1). * * Results: * * int - number of bytes stored in 'str' (not including null * terminate character), -1 on overflow (insufficient space for * null terminate is considered overflow) * * NB: on overflow the buffer WILL be null terminated * * Side effects: * None * *---------------------------------------------------------------------- */ int Str_Vsnprintf(char *str, // OUT: destination buffer size_t size, // IN : size of str const char *format, // IN : format for vsnprintf va_list arguments) // IN : variadic args for vsnprintf { int retval; retval = vsnprintf(str, size, format, arguments); if (retval >= size) { retval = -1; } return retval; } /* *----------------------------------------------------------------------------- * * Str_Vasprintf -- * * Allocate and format a string, using the GNU libc way to specify the * format (i.e. optionally allow the use of positional parameters) * * Results: * The allocated string on success (if 'length' is not NULL, *length * is set to the length of the allocated string) * NULL on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ char * Str_Vasprintf(size_t *length, // OUT const char *format, // IN va_list arguments) // IN { /* * Simple implementation of Str_Vasprintf when userlevel libraries are not * available (e.g. for use in drivers). We just fallback to vsnprintf, * doubling if we didn't have enough space. */ unsigned int bufSize; char *buf; int retval; bufSize = strlen(format); buf = NULL; do { /* * Initial allocation of strlen(format) * 2. Should this be tunable? * XXX Yes, this could overflow and spin forever when you get near 2GB * allocations. I don't care. --rrdharan */ va_list tmpArgs; bufSize *= 2; buf = realloc(buf, bufSize); if (!buf) { return NULL; } va_copy(tmpArgs, arguments); retval = Str_Vsnprintf(buf, bufSize, format, tmpArgs); va_end(tmpArgs); } while (retval == -1); if (length) { *length = retval; } /* * Try to trim the buffer here to save memory? */ return buf; } /* *----------------------------------------------------------------------------- * * Str_Asprintf -- * * Same as Str_Vasprintf(), but parameters are passed inline --hpreg * * Results: * Same as Str_Vasprintf() * * Side effects: * Same as Str_Vasprintf() * *----------------------------------------------------------------------------- */ char * Str_Asprintf(size_t *length, // OUT const char *format, // IN ...) // IN { va_list arguments; char *result; va_start(arguments, format); result = Str_Vasprintf(length, format, arguments); va_end(arguments); return result; } open-vm-tools-9.4.0-1280544/modules/freebsd/shared/0000755765153500003110000000000012220061556017767 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/freebsd/shared/compat_vop.h0000644765153500003110000001005712220061556022312 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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 __COMPAT_VOP_H__ # define __COMPAT_VOP_H__ 1 #if __FreeBSD_version >= 800011 #define COMPAT_THREAD_VAR(varname, varval) #define COMPAT_VOP_LOCK(vop, flags, threadvar) VOP_LOCK((vop), (flags)) #define COMPAT_VOP_UNLOCK(vop, flags, threadvar) VOP_UNLOCK((vop), (flags)) #define compat_lockstatus(lock, threadvar) lockstatus((lock)) #define compat_lockmgr(lock, flags, randompointerparam, threadval) lockmgr((lock), (flags), (randompointerparam)) #define compat_vn_lock(vp, flags, threadval) vn_lock((vp), (flags)) #define compat_accmode_t accmode_t #define compat_a_accmode a_accmode #else #define COMPAT_THREAD_VAR(varname, varval) struct thread *varname = varval #define COMPAT_VOP_LOCK(vop, flags, threadvar) VOP_LOCK((vop), (flags), (threadvar)) #define COMPAT_VOP_UNLOCK(vop, flags, threadvar) VOP_UNLOCK((vop), (flags), (threadvar)) #define compat_lockstatus(lock, threadvar) lockstatus((lock), (threadvar)) #define compat_vn_lock(vp, flags, threadval) vn_lock((vp), (flags), (threadval)) #define compat_lockmgr(lock, flags, randompointerparam, threadval) lockmgr((lock), (flags), (randompointerparam), (threadval)) #define compat_accmode_t mode_t #define compat_a_accmode a_mode #endif /* * We use defines rather than typedefs here to avoid causing problems for files that * don't have a vnode_if.h available. */ #if __FreeBSD_version >= 700055 # define compat_vop_lock_t vop_lock1_t # define compat_vop_lock_args struct vop_lock1_args # define COMPAT_VOP_LOCK_OP_ELEMENT vop_lock1 #else # define compat_vop_lock_t vop_lock_t # define compat_vop_lock_args struct vop_lock_args # define COMPAT_VOP_LOCK_OP_ELEMENT vop_lock #endif #endif open-vm-tools-9.4.0-1280544/modules/freebsd/shared/compat_priv.h0000644765153500003110000000520412220061556022464 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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 __COMPAT_PRIV_H__ # define __COMPAT_PRIV_H__ 1 #if __FreeBSD_version >= 800011 #define compat_priv_check(td, priv) priv_check((td), (priv)) #else #define compat_priv_check(td, priv) suser(td) #endif #endif open-vm-tools-9.4.0-1280544/modules/freebsd/shared/compat_freebsd.h0000644765153500003110000000564412220061556023126 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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 __COMPAT_FREEBSD_H__ #define __COMPAT_FREEBSD_H__ 1 #include #include "compat_vop.h" #include "compat_mount.h" #include "compat_priv.h" /* * FreeBSD version 8 and above uses the kproc API instead of the kthread API in its * kernel. */ #if __FreeBSD_version > 800001 #define compat_kthread_create kproc_create #define compat_kthread_exit kproc_exit #else #define compat_kthread_create kthread_create #define compat_kthread_exit kthread_exit #endif #endif // __COMPAT_FREEBSD_H__ open-vm-tools-9.4.0-1280544/modules/freebsd/shared/compat_mount.h0000644765153500003110000000534512220061556022654 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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 __COMPAT_MOUNT_H__ # define __COMPAT_MOUNT_H__ 1 #if __FreeBSD_version >= 800011 #define COMPAT_VFS_STATFS(mp, sbp, threadvar) VFS_STATFS((mp), (sbp)) #define compat_td curthread #else #define COMPAT_VFS_STATFS(mp, sbp, threadvar) VFS_STATFS((mp), (sbp), (threadvar)) #define compat_td td #endif #endif open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/0000755765153500003110000000000012220061556020013 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/requestInt.h0000644765153500003110000001546012220061556022335 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * requestInt.h -- * * Internal declarations for the HgfsRequest module. Filesystem code * should not include this file. */ #ifndef _requestInt_H_ #define _requestInt_H_ #define INCLUDE_ALLOW_MODULE #include "includeCheck.h" #if defined __FreeBSD__ # include // common string, memcpy, etc userland routines # include // for the UMA (slab) allocator #elif defined __APPLE__ # include #endif #include "vm_assert.h" #include "os.h" #include "request.h" #include "debug.h" #if defined __APPLE__ #include "hgfsTransport.h" #define HGFS_REQUEST_PREFIX_LENGTH MAX(HGFS_CLIENT_CMD_LEN, sizeof (HgfsVmciTransportStatus)) #else #define HGFS_REQUEST_PREFIX_LENGTH HGFS_CLIENT_CMD_LEN #endif /* * Data types */ struct HgfsTransportChannel; /* * In-kernel representation of an Hgfs request. These objects are kept on zero, * one, or two lists at any time. * * (Ideal) Lifecycle of an Hgfs request: * - File system calls HgfsKReq_AllocateRequest to allocate a request. The * new request's reference count is initialized to one, and it is placed * in the filesystem's requests container. * - File system calls HgfsKReq_SubmitRequest to submit the request for * processing via the backdoor. At this point, request is inserted on a * global work item list and its reference count is bumped. * - Worker thread removes request from the work item list. Reference count is * unchanged as the reference is simply transferred from the work item list to * the worker thread itself. * - When the worker thread receives a reply, it updates the request's state, * copies in the reply data, and decrements the reference count. * * At any point, the file system may abort a request with * HgfsKReq_ReleaseRequest. Doing so will involve decrementing the object's * reference count, since the file system is giving up its reference. Whoever * reduces the reference count to zero is responsible for freeing it. * * Special case -- Forced unmount of a file system: * * If the user forcibly unmounts the file system, the following work is done. * - For each request object associated with a file system * - If the item is on the work item list, it is removed from that list. The * canceling thread is then responsible for decrementing the object's * reference count. * - The request's state is set to HGFS_REQ_ERROR, and a wakeup signal is * sent to the stateCv. (If the file system had not yet submitted the * request, it will immediately return as a failure at submission time.) * - Without anything left to do with this request, the cancellation thread * drops the reference count, and if it reaches zero, frees the object. */ typedef struct HgfsKReqObject { DblLnkLst_Links fsNode; // Link between object and its parent file system. DblLnkLst_Links pendingNode; // Link between object and pending request list. DblLnkLst_Links sentNode; // Link between object and sent request list. unsigned int refcnt; // Object reference count HgfsKReqState state; // Indicates state of request OS_MUTEX_T *stateLock; // Protects state: ... OS_CV_T stateCv; // Condition variable to wait for and signal // presence of reply. Used with the stateLock // above. uint32_t id; // The unique identifier of this request. // Typically just incremented sequentially // from zero. size_t payloadSize; // Total size of payload void *ioBuf; // Pointer to memory descriptor. // Used for MacOS over VMCI. /* On which channel was the request allocated/sent ?. */ struct HgfsTransportChannel *channel; /* * The file system is concerned only with the payload portion of an Hgfs * request packet, but the RPC message opens with the command string "f ". * * Strangely, the HgfsBd_Dispatch routine takes a pointer to the payload, but indexes * -backwards- from that pointer to get to the RPC command. (This was actually done * because we wanted to vary the command - async vs. sync - on the fly without * performing another allocation. So the buffer is sized for any command plus the * packet, and the command is varied by the transport layer.) So, anyway, effectively * all of __rpc_packet will be sent across the backdoor, but the file system will only * muck with _payload. * * VMCI: * Mac OS X is capable of using VMCI in which case _command will have * HgfsVmciTransportStatus. * */ struct { char _command[HGFS_REQUEST_PREFIX_LENGTH]; char _payload[HGFS_PACKET_MAX]; // Contains both the request and // its reply. } __rpc_packet; } HgfsKReqObject; #define command __rpc_packet._command #define payload __rpc_packet._payload /* * Opaque container for a file system's request objects. File system operates * only on a typedef'd handle. (See request.h.) */ typedef struct HgfsKReqContainer { OS_MUTEX_T *listLock; DblLnkLst_Links list; } HgfsKReqContainer; /* * Current state & instruction for the HgfsKReq worker thread. */ typedef struct HgfsKReqWState { Bool running; // Is worker running? Bool exit; // Set this to TRUE at module unload time. } HgfsKReqWState; /* * Module internal variables */ /* Workitem list anchor */ extern DblLnkLst_Links hgfsKReqWorkItemList; /* Workitem list lock. */ extern OS_MUTEX_T *hgfsKReqWorkItemLock; extern OS_CV_T hgfsKReqWorkItemCv; /* UMA zone (slab) for allocating HgfsKReqs. */ extern OS_ZONE_T *hgfsKReqZone; /* Process structure for the worker thread */ extern OS_THREAD_T hgfsKReqWorkerThread; extern HgfsKReqWState hgfsKReqWorkerState; /* * Function prototypes */ extern void HgfsKReqWorker(void *arg); #endif // ifndef _requestInt_H_ open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/state.c0000644765153500003110000013014612220061556021304 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * state.c -- * * Vnode and HgfsFile state manipulation routines. */ #include #include #include #include #if defined __FreeBSD__ # include # include # include "sha1.h" # include "compat_freebsd.h" #define vnode_get(vnode) vget(vnode, LK_SHARED, curthread) #define vnode_rele(vnode) vrele(vnode) #define vnode_ref(vnode) vref(vnode) #elif defined __APPLE__ # include /* * The Mac OS kernel includes the same exact SHA1 routines as those * provided by bora/lib/misc. Use the kernel ones under Mac OS. */ # include #endif #include "hgfs_kernel.h" #include "state.h" #include "debug.h" #include "os.h" /* * Macros */ #define HGFS_FILE_HT_HEAD(ht, index) (ht->hashTable[index]).next #define HGFS_FILE_HT_BUCKET(ht, index) (&ht->hashTable[index]) #define HGFS_IS_ROOT_FILE(sip, file) (HGFS_VP_TO_FP(sip->rootVnode) == file) #define LCK_MTX_ASSERT(mutex) #if defined __APPLE__ # define SHA1_HASH_LEN SHA_DIGEST_LENGTH #if defined VMX86_DEVEL #undef LCK_MTX_ASSERT #define LCK_MTX_ASSERT(mutex) lck_mtx_assert(mutex, LCK_MTX_ASSERT_OWNED) #endif #endif /* * Local functions (prototypes) */ static int HgfsVnodeGetInt(struct vnode **vpp, struct vnode *dvp, struct HgfsSuperInfo *sip, struct mount *vfsp, const char *fileName, HgfsFileType fileType, HgfsFileHashTable *htp, Bool rootVnode, Bool createFile, int permissions, off_t fileSize); /* Allocation/initialization/free of open file state */ static HgfsFile *HgfsAllocFile(const char *fileName, HgfsFileType fileType, struct vnode *dvp, HgfsFileHashTable *htp, int permissions, off_t fileSize); /* Acquiring/releasing file state */ static HgfsFile *HgfsInsertFile(const char *fileName, HgfsFile *fp, HgfsFileHashTable *htp); static void HgfsReleaseFile(HgfsFile *fp, HgfsFileHashTable *htp); static int HgfsInitFile(HgfsFile *fp, struct vnode *dvp, const char *fileName, HgfsFileType fileType, int permissions, off_t fileSize); static void HgfsFreeFile(HgfsFile *fp); /* Adding/finding/removing file state from hash table */ static void HgfsAddFile(HgfsFile *fp, HgfsFileHashTable *htp); static HgfsFile *HgfsFindFile(const char *fileName, HgfsFileHashTable *htp); /* Other utility functions */ static unsigned int HgfsFileNameHash(const char *fileName); static void HgfsNodeIdHash(const char *fileName, uint32_t fileNameLength, ino_t *outHash); static Bool HgfsIsModeCompatible(HgfsMode requestedMode, HgfsMode existingMode); /* * Global functions */ /* *---------------------------------------------------------------------------- * * HgfsVnodeGet -- * * Creates a vnode for the provided filename. * * This will always allocate a vnode and HgfsFile. If a HgfsFile * already exists for this filename then that is used, if a HgfsFile doesn't * exist, one is created. * * Results: * Returns 0 on success and a non-zero error code on failure. The new * vnode is returned locked. * * Side effects: * If the HgfsFile already exists and createFile is TRUE then the EEXIST error * is returned. Otherwise if the HgfsFile already exists its reference count * is incremented. * If HgfsFile with the given name does not exist then HgfsFile is created. * *---------------------------------------------------------------------------- */ int HgfsVnodeGet(struct vnode **vpp, // OUT: Filled with address of created vnode struct vnode *dvp, // IN: Parent directory vnode HgfsSuperInfo *sip, // IN: Superinfo struct mount *vfsp, // IN: Filesystem structure const char *fileName, // IN: Name of this file HgfsFileType fileType, // IN: Type of file HgfsFileHashTable *htp, // IN: File hash table Bool createFile, // IN: Creating a new file or open existing? int permissions, // IN: Permissions for the created file off_t fileSize) // IN: File size if the vnode is VREG { return HgfsVnodeGetInt(vpp, dvp, sip, vfsp, fileName, fileType, htp, FALSE, createFile, permissions, fileSize); } /* *---------------------------------------------------------------------------- * * HgfsVnodeGetRoot -- * * Creates a root vnode. This should only be called by the VFS mount * function when the filesystem is first being mounted. * * Results: * Returns 0 on success and a non-zero error code on failure. The new * vnode is returned locked on FreeBSD. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsVnodeGetRoot(struct vnode **vpp, // OUT: Filled with address of created vnode HgfsSuperInfo *sip, // IN: Superinfo struct mount *vfsp, // IN: Filesystem structure const char *fileName, // IN: Name of this file HgfsFileType fileType, // IN: Type of file HgfsFileHashTable *htp) // IN: File hash table { return HgfsVnodeGetInt(vpp, NULL, sip, vfsp, fileName, fileType, htp, TRUE, FALSE, 0, 0); } /* *---------------------------------------------------------------------------- * * HgfsReleaseVnodeContext -- * * Releases context for the provided vnode. * * This will free the context information associated vnode. * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * * *---------------------------------------------------------------------------- */ int HgfsReleaseVnodeContext(struct vnode *vp, // IN: Vnode to release HgfsFileHashTable *htp) // IN: Hash table pointer { HgfsFile *fp; ASSERT(vp); ASSERT(htp); DEBUG(VM_DEBUG_ENTRY, "Entering HgfsVnodePut\n"); /* Get our private open-file state. */ fp = HGFS_VP_TO_FP(vp); ASSERT(fp); /* We need to release private HGFS information asosiated with the vnode. */ HgfsReleaseFile(fp, htp); return 0; } /* *---------------------------------------------------------------------------- * * HgfsNodeIdGet -- * * Gets the node id for the provided file. This will only calculate the * node id again if a per-file state structure doesn't yet exist for this * file. (This situation exists on a readdir since dentries are filled in * rather than creating vnodes.) * * The Hgfs protocol does not provide us with unique identifiers for files * since it must support filesystems that do not have the concept of inode * numbers. Therefore, we must maintain a mapping from filename to node id/ * inode numbers. This is done in a stateless manner by calculating the * SHA-1 hash of the filename. All points in the Hgfs code that need a node * id/inode number obtain it by either calling this function or directly * referencing the saved node id value in the vnode, if one is available. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsNodeIdGet(HgfsFileHashTable *htp, // IN: File hash table const char *fileName, // IN: Filename to get node id for uint32_t fileNameLength, // IN: Length of filename ino_t *outNodeId) // OUT: Destination for nodeid { HgfsFile *fp; ASSERT(htp); ASSERT(fileName); ASSERT(outNodeId); os_mutex_lock(htp->mutex); fp = HgfsFindFile(fileName, htp); if (fp) { *outNodeId = fp->nodeId; } else { HgfsNodeIdHash(fileName, fileNameLength, outNodeId); } os_mutex_unlock(htp->mutex); } /* *---------------------------------------------------------------------------- * * HgfsInitFileHashTable -- * * Initializes the hash table used to track per-file state. * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsInitFileHashTable(HgfsFileHashTable *htp) // IN: Hash table to initialize { int i; ASSERT(htp); htp->mutex = os_mutex_alloc_init("HgfsHashChain"); if (!htp->mutex) { return HGFS_ERR; } for (i = 0; i < ARRAYSIZE(htp->hashTable); i++) { DblLnkLst_Init(&htp->hashTable[i]); } return 0; } /* *---------------------------------------------------------------------------- * * HgfsDestroyFileHashTable -- * * Cleanup the hash table used to track per-file state. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsDestroyFileHashTable(HgfsFileHashTable *htp) { ASSERT(htp); os_mutex_free(htp->mutex); } /* *---------------------------------------------------------------------------- * * HgfsFileHashTableIsEmpty -- * * Determines whether the hash table is in an acceptable state to unmount * the file system. * * Note that this is not strictly empty: if the only file in the table is * the root of the filesystem and its reference count is 1, this is * considered empty since this is part of the operation of unmounting the * filesystem. * * Results: * Returns TRUE if the hash table is empty and false otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool HgfsFileHashTableIsEmpty(HgfsSuperInfo *sip, // IN: Superinfo HgfsFileHashTable *htp) // IN: File hash table { int i; ASSERT(sip); ASSERT(htp); os_mutex_lock(htp->mutex); /* Traverse each bucket. */ for (i = 0; i < ARRAYSIZE(htp->hashTable); i++) { DblLnkLst_Links *currNode = HGFS_FILE_HT_HEAD(htp, i); /* Visit each file in this bucket */ while (currNode != HGFS_FILE_HT_BUCKET(htp, i)) { HgfsFile *currFile = DblLnkLst_Container(currNode, HgfsFile, listNode); /* * Here we special case the root of our filesystem. In a correct * unmount, the root vnode of the filesystem will have an entry in the * hash table and will have a reference count of 1. We check if the * current entry is the root file, and if so, make sure its vnode's * reference count is not > 1. Note that we are not mapping from file * to vnode here (which is not possible), we are using the root vnode * stored in the superinfo structure. This is the only vnode that * should have multiple references associated with it because whenever * someone calls HgfsRoot(), we return that vnode. */ if (HGFS_IS_ROOT_FILE(sip, currFile)) { HGFS_VP_VI_LOCK(sip->rootVnode); if (!HGFS_VP_ISINUSE(sip->rootVnode, 1)) { HGFS_VP_VI_UNLOCK(sip->rootVnode); /* This file is okay; skip to the next one. */ currNode = currNode->next; continue; } DEBUG(VM_DEBUG_FAIL, "HgfsFileHashTableIsEmpty: %s is in use.\n", currFile->fileName); HGFS_VP_VI_UNLOCK(sip->rootVnode); /* Fall through to failure case */ } /* Fail if a file is found. */ os_mutex_unlock(htp->mutex); DEBUG(VM_DEBUG_FAIL, "HgfsFileHashTableIsEmpty: %s still in use.\n", currFile->fileName); return FALSE; } } os_mutex_unlock(htp->mutex); return TRUE; } /* *---------------------------------------------------------------------------- * * HgfsCheckAndReferenceHandle -- * * Determines whether one of vnode's open file handles is currently set. * If the handle is set the function increments its reference count. * The function must be called while holding handleLock from the correspondent * HgfsFile structure. * * Results: * Returns 0 if the handle is set and had been referenced, * EACCES if the handle is set but has an incompatible open mode, * ENOENT if no handle is set for the vnode * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsCheckAndReferenceHandle(struct vnode *vp, // IN: Vnode to check handle of int requestedOpenMode, // IN: Requested open mode HgfsOpenType openType) // IN: Requested open type { HgfsFile *fp; int ret = 0; ASSERT(vp); fp = HGFS_VP_TO_FP(vp); ASSERT(fp); if (0 == fp->handleRefCount && 0 == fp->intHandleRefCount) { ret = ENOENT; DEBUG(VM_DEBUG_LOG, "No handle: mode %d type %d\n", requestedOpenMode, openType); goto exit; } if (!HgfsIsModeCompatible(requestedOpenMode, fp->mode)) { ret = EACCES; DEBUG(VM_DEBUG_LOG, "Incompatible modes: %d %d\n", requestedOpenMode, fp->mode); goto exit; } DEBUG(VM_DEBUG_LOG, "Compatible handle: type %d mapped %d count %d\n", openType, fp->mmapped, fp->handleRefCount); /* * Do nothing for subsequent mmap/read reference requests. * For mmap the OS layer invokes mnomap only once * for multiple mmap calls. * For read we only need to reference the first real need to open, i.e. ENOENT * is returned when there isn't a compatible handle. */ if (OPENREQ_MMAP == openType && fp->mmapped) { DEBUG(VM_DEBUG_LOG, "Mmapped: already referenced %d %d\n", requestedOpenMode, fp->mode); goto exit; } if (OPENREQ_READ == openType) { DEBUG(VM_DEBUG_LOG, "Open for Read: already referenced %d %d\n", requestedOpenMode, fp->mode); goto exit; } /* * Reference the handle for the open. * For the regular open and memory map calls we increment the normal * count, for all others (e.g. create) it is an internal increment. */ if (OPENREQ_OPEN != openType && OPENREQ_MMAP != openType) { fp->intHandleRefCount++; DEBUG(VM_DEBUG_LOG, "Internal Handle Ref Cnt %d\n", fp->intHandleRefCount); } else { fp->handleRefCount++; DEBUG(VM_DEBUG_LOG, "Handle Ref Cnt %d\n", fp->handleRefCount); } if (!(fp->mmapped) && OPENREQ_MMAP == openType) { fp->mmapped = TRUE; } exit: return ret; } /* *---------------------------------------------------------------------------- * * HgfsSetOpenFileHandle -- * * Sets the file handle for the provided vnode if it has reference count * equal to zero. The reference count of the handle must be increased when * the handle is set. This is done with HgfsCheckAndReferenceHandle. * Caller must hold handleLock when invoking the function. * * Results: * None. * * Side effects: * The handle may not be set again until it is cleared. * *---------------------------------------------------------------------------- */ void HgfsSetOpenFileHandle(struct vnode *vp, // IN: Vnode to set handle for HgfsHandle handle, // IN: Value of handle HgfsMode openMode, // IN: Mode assosiated with the handle HgfsOpenType openType) // IN: type of open for VNOP_ call { HgfsFile *fp; ASSERT(vp); fp = HGFS_VP_TO_FP(vp); ASSERT(fp); fp->handle = handle; fp->mode = openMode; fp->handleRefCount = 1; if (OPENREQ_OPEN == openType) { fp->handleRefCount = 1; } else { fp->intHandleRefCount = 1; } DEBUG(VM_DEBUG_STATE, "File %s handle %d ref Cnt %d Int Ref Cnt %d\n", HGFS_VP_TO_FILENAME(vp), fp->handle, fp->handleRefCount, fp->intHandleRefCount); } /* *---------------------------------------------------------------------------- * * HgfsGetOpenFileHandle -- * * Gets the file handle for the provided vnode. * * Results: * Returns 0 on success and a non-zero error code on failure. On success, * the value of the vnode's handle is placed in outHandle. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsGetOpenFileHandle(struct vnode *vp, // IN: Vnode to get handle for HgfsHandle *outHandle) // OUT: Filled with value of handle { HgfsFile *fp; int ret = 0; ASSERT(vp); ASSERT(outHandle); fp = HGFS_VP_TO_FP(vp); ASSERT(fp); os_rw_lock_lock_shared(fp->handleLock); if (fp->handleRefCount == 0) { ret = HGFS_ERR; } else { *outHandle = fp->handle; } os_rw_lock_unlock_shared(fp->handleLock); return ret; } /* *---------------------------------------------------------------------------- * * HgfsReleaseOpenFileHandle -- * * Decrements the reference count of one of the handles for the provided * vnode. If the reference count becomes zero, then the handle is cleared and * the original handle is retruned to the caller. * * Results: * Returns new handle reference count. * When the returned value is 0 returns the file handle which need to be closed * on the host. * Returns special value -1 if the handle had not been open. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsReleaseOpenFileHandle(struct vnode *vp, // IN: correspondent vnode HgfsOpenType openType, // IN: open type to release HgfsHandle *handleToClose) // OUT: Host handle to close { int ret = -1; HgfsFile *fp; ASSERT(vp); fp = HGFS_VP_TO_FP(vp); ASSERT(fp); os_rw_lock_lock_exclusive(fp->handleLock); /* Make sure the reference count is not going negative! */ ASSERT(fp->handleRefCount >= 0 || fp->intHandleRefCount > 0); if (fp->handleRefCount > 0 || fp->intHandleRefCount > 0) { if (fp->handleRefCount > 0) { --fp->handleRefCount; } /* * We don't issue explicit closes for internal opens (read/create), so * always decrement the internal count here. */ if (fp->intHandleRefCount > 0) { --fp->intHandleRefCount; } /* Return the real not internal count. */ ret = fp->handleRefCount; /* If unmapping clear our flag. */ if (OPENREQ_MMAP == openType) { fp->mmapped = FALSE; } /* If the reference count has gone to zero, clear the handle. */ if (ret == 0) { DEBUG(VM_DEBUG_LOG, "Last open closing handle %d\n", fp->handle); *handleToClose = fp->handle; fp->handle = 0; fp->intHandleRefCount = 0; } else { DEBUG(VM_DEBUG_LOG, "ReleaseOpenFileHandle: refCount: %d intRefCount %d\n", fp->handleRefCount, fp->intHandleRefCount); } } os_rw_lock_unlock_exclusive(fp->handleLock); return ret; } /* *---------------------------------------------------------------------------- * * HgfsLookupExistingVnode -- * * Locates existing vnode in the hash table that matches given file name. * If a vnode that corresponds the given name does not exists then the function * returns ENOENT. * If the vnode exists the function behavior depends on failIfExist parameter. * When failIfExist is true then the function return EEXIST, otherwise * function references the vnode, assigns vnode pointer to vpp and return 0. * * Results: * * Returns 0 if existing vnode is found and its address is returned in vpp or * an error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsLookupExistingVnode(const char* fileName, HgfsFileHashTable *htp, Bool failIfExist, struct vnode **vpp) { HgfsFile* existingFp; int err = ENOENT; os_mutex_lock(htp->mutex); /* First verify if a vnode for the filename is already allocated. */ existingFp = HgfsFindFile(fileName, htp); if (existingFp != NULL) { DEBUG(VM_DEBUG_LOG, "Found existing vnode for %s\n", fileName); if (failIfExist) { err = EEXIST; } else { err = vnode_get(existingFp->vnodep); if (err == 0) { *vpp = existingFp->vnodep; } else { /* vnode exists but unusable, remove HGFS context assosiated with it. */ DEBUG(VM_DEBUG_FAIL, "Removing HgfsFile assosiated with an unusable vnode\n"); DblLnkLst_Unlink1(&existingFp->listNode); err = ENOENT; } } } os_mutex_unlock(htp->mutex); return err; } /* * Local functions (definitions) */ /* Internal versions of public functions to allow bypassing htp locking */ /* *---------------------------------------------------------------------------- * * HgfsVnodeGetInt -- * * Creates a vnode for the provided filename. * * If a HgfsFile already exists for this filename then it is used and the associated * vnode is referenced and returned. * if a HgfsFile doesn't exist, a new vnode and HgfsFile structure is created. * * Results: * Returns 0 on success and a non-zero error code on failure. The new * vnode is returned locked. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #if defined __FreeBSD__ static int HgfsVnodeGetInt(struct vnode **vpp, // OUT: Filled with address of created vnode struct vnode *dvp, // IN: Parent directory vnode HgfsSuperInfo *sip, // IN: Superinfo struct mount *vfsp, // IN: Filesystem structure const char *fileName, // IN: Name of this file HgfsFileType fileType, // IN: Tyoe of file HgfsFileHashTable *htp, // IN: File hash Bool rootVnode, // IN: Is this a root vnode? Bool fileCreate, // IN: Is it a new file creation? int permissions, // IN: Permissions for new files off_t fileSize) // IN: Size of the file { struct vnode *vp; int ret; HgfsFile *fp; HgfsFile *existingFp; ASSERT(vpp); ASSERT(sip); ASSERT(vfsp); ASSERT(fileName); ASSERT(htp); ASSERT(dvp != NULL || rootVnode); /* First verify if a vnode for the filename is already allocated. */ ret = HgfsLookupExistingVnode(fileName, htp, fileCreate, vpp); if (ret != ENOENT) { return ret; } /* * Here we need to construct the vnode for the kernel as well as our * internal file system state. Our internal state described by * HgfsFile structure which is kept per-file. There is no state information assosiated * with file descriptor. The reason is that when OS invokes vnode methods * it does not provide information about file descriptor that was used to initiate the * IO. We have a one-to-one mapping between vnodes and HgfsFiles. */ if ((ret = getnewvnode(HGFS_FS_NAME, vfsp, &HgfsVnodeOps, &vp)) != 0) { return ret; } /* * Return a locked vnode to the caller. */ ret = compat_lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL, curthread); if (ret) { DEBUG(VM_DEBUG_FAIL, "Fatal: could not acquire lock on vnode\n"); goto destroyVnode; } /* * Now we'll initialize the vnode. We need to set the file type, vnode * operations, flags, filesystem pointer, reference count, and device. * After that we'll create our private structures and hang them from the * vnode's v_data pointer. */ switch (fileType) { case HGFS_FILE_TYPE_REGULAR: vp->v_type = VREG; break; case HGFS_FILE_TYPE_DIRECTORY: vp->v_type = VDIR; break; case HGFS_FILE_TYPE_SYMLINK: vp->v_type = VLNK; break; default: /* Hgfs only supports directories and regular files */ ret = EPERM; goto destroyOut; } /* We now allocate our private open file structure. */ fp = (void *)HgfsAllocFile(fileName, fileType, dvp, htp, permissions, fileSize); if (fp == NULL) { ret = ENOMEM; goto destroyOut; } fp->vnodep = vp; vp->v_data = fp; /* If this is going to be the root vnode, we have to mark it as such. */ if (rootVnode) { vp->v_vflag |= VV_ROOT; } existingFp = HgfsInsertFile(fileName, fp, htp); if (existingFp != NULL) { // Race occured, another thread inserted a node ahead of us if (fileCreate) { ret = EEXIST; goto destroyOut; } compat_lockmgr(vp->v_vnlock, LK_RELEASE, NULL, curthread); vput(vp); vp = existingFp->vnodep; /* * Return a locked vnode to the caller. */ ret = compat_lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL, curthread); if (ret) { DEBUG(VM_DEBUG_FAIL, "Fatal: could not acquire lock on vnode\n"); goto destroyVnode; } HgfsFreeFile(fp); } /* Fill in the provided address with the new vnode. */ *vpp = vp; /* Return success */ return 0; /* Cleanup points for errors. */ destroyOut: compat_lockmgr(vp->v_vnlock, LK_RELEASE, NULL, curthread); destroyVnode: vput(vp); return ret; } #elif defined __APPLE__ static int HgfsVnodeGetInt(struct vnode **vpp, // OUT struct vnode *dvp, // IN HgfsSuperInfo *sip, // IN struct mount *vfsp, // IN const char *fileName, // IN HgfsFileType fileType, // IN HgfsFileHashTable *htp, // IN Bool rootVnode, // IN Bool fileCreate, // IN int permissions, // IN off_t fileSize) // IN { struct vnode *vp; struct vnode_fsparam params; int ret; HgfsFile *fp = NULL; HgfsFile *existingFp; ASSERT(vpp); ASSERT(sip); ASSERT(vfsp); ASSERT(fileName); ASSERT(htp); /* First verify if a vnode for the filename is already allocated. */ ret = HgfsLookupExistingVnode(fileName, htp, fileCreate, vpp); if (ret != ENOENT) { return ret; } params.vnfs_mp = vfsp; params.vnfs_str = "hgfs"; params.vnfs_dvp = dvp; params.vnfs_fsnode = NULL; params.vnfs_vops = HgfsVnodeOps; params.vnfs_marksystem = FALSE; params.vnfs_rdev = 0; params.vnfs_filesize = fileSize; params.vnfs_cnp = NULL; /* Do not let Mac OS cache vnodes for us. */ params.vnfs_flags = VNFS_NOCACHE | VNFS_CANTCACHE; if (rootVnode) { params.vnfs_markroot = TRUE; } else { params.vnfs_markroot = FALSE; } /* * Now we'll initialize the vnode. We need to set the file type, vnode * operations, flags, filesystem pointer, reference count, and device. * After that we'll create our private structures and hang them from the * vnode's v_data pointer. */ switch (fileType) { case HGFS_FILE_TYPE_REGULAR: params.vnfs_vtype = VREG; break; case HGFS_FILE_TYPE_DIRECTORY: params.vnfs_vtype = VDIR; break; case HGFS_FILE_TYPE_SYMLINK: params.vnfs_vtype = VLNK; break; default: /* Hgfs only supports directories and regular files */ ret = EINVAL; goto out; } fp = HgfsAllocFile(fileName, fileType, dvp, htp, permissions, fileSize); params.vnfs_fsnode = (void *)fp; if (params.vnfs_fsnode == NULL) { ret = ENOMEM; goto out; } ret = vnode_create(VNCREATE_FLAVOR, sizeof(params), ¶ms, &vp); if (ret != 0) { DEBUG(VM_DEBUG_FAIL, "Failed to create vnode"); goto out; } fp->vnodep = vp; existingFp = HgfsInsertFile(fileName, fp, htp); if (existingFp != NULL) { // Race occured, another thread inserted a node ahead of us vnode_put(vp); if (fileCreate) { ret = EEXIST; goto out; } vp = existingFp->vnodep; HgfsFreeFile(fp); } else { /* Get a soft FS reference to the vnode. This tells the system that the vnode * has data associated with it. It is considered a weak reference though, in that * it does not prevent the system from reusing the vnode. */ vnode_addfsref(vp); } /* Fill in the provided address with the new vnode. */ *vpp = vp; /* Return success */ return 0; out: if (fp) { HgfsFreeFile(fp); } return ret; } #else NOT_IMPLEMENTED(); #endif /* Allocation/initialization/free of open file state */ /* *---------------------------------------------------------------------------- * * HgfsAllocFile -- * * Allocates and initializes a file structure. * * Results: * Returns a pointer to the open file on success, NULL on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static HgfsFile * HgfsAllocFile(const char *fileName, // IN: Name of file HgfsFileType fileType, // IN: Type of file struct vnode *dvp, // IN: Parent directory vnode HgfsFileHashTable *htp, // IN: Hash table int permissions, // IN: permissions for creating new files off_t fileSize) // IN: file size { HgfsFile *fp; fp = os_malloc(sizeof *fp, M_ZERO | M_WAITOK); if (fp != NULL) { DEBUG(VM_DEBUG_INFO, "HgfsGetFile: allocated HgfsFile for %s.\n", fileName); if (HgfsInitFile(fp, dvp, fileName, fileType, permissions, fileSize) != 0) { DEBUG(VM_DEBUG_FAIL, "Failed to initialize HgfsFile"); os_free(fp, sizeof(*fp)); fp = NULL; } } else { DEBUG(VM_DEBUG_FAIL, "Failed to allocate memory"); } return fp; } /* Acquiring/releasing file state */ /* *---------------------------------------------------------------------------- * * HgfsInsertFile -- * * Inserts a HgfsFile object into the hash table if the table does not * contain an object with the same name. * If an object with the same name already exists in the hash table * then does nothing and just returns pointer to the existing object. * * Results: * Returns a pointer to the file if there is a name collision, NULL otherwise. * * Side effects: * If there is a name collision adds reference to vnode IOrefcount. * *---------------------------------------------------------------------------- */ static HgfsFile * HgfsInsertFile(const char *fileName, // IN: Filename to get file for HgfsFile *fp, // IN: HgfsFile object to insert HgfsFileHashTable *htp) // IN: Hash table to look in { HgfsFile *existingFp = NULL; ASSERT(fileName); ASSERT(htp); /* * We try to find the file in the hash table. If it exists we increment its * reference count and return it. */ os_mutex_lock(htp->mutex); existingFp = HgfsFindFile(fileName, htp); if (existingFp) { // HgfsFile with this name already exists int ret = vnode_get(existingFp->vnodep); if (ret != 0) { /* * It is not clear why vnode_get may fail while there is HgfsFile in * our hash table. Most likely it will never happen. * However if this ever occur the safest approach is to remove * the HgfsFile structure from the hash table but do dont free it. * It should be freed later on when the vnode is recycled. */ DblLnkLst_Unlink1(&existingFp->listNode); existingFp = NULL; } } if (existingFp == NULL) { HgfsAddFile(fp, htp); } os_mutex_unlock(htp->mutex); return existingFp; } /* *---------------------------------------------------------------------------- * * HgfsReleaseFile -- * * Removes HgfsFile structure from the hash table and releases it. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void HgfsReleaseFile(HgfsFile *fp, // IN: File to release HgfsFileHashTable *htp) // IN: Hash table to look in/remove from { ASSERT(fp); ASSERT(htp); DEBUG(VM_DEBUG_INFO, "HgfsReleaseFile: freeing HgfsFile for %s.\n", fp->fileName); /* Take this file off its list */ os_mutex_lock(htp->mutex); DblLnkLst_Unlink1(&fp->listNode); os_mutex_unlock(htp->mutex); HgfsFreeFile(fp); } /* Allocation/initialization/free of file state */ /* *---------------------------------------------------------------------------- * * HgfsInitFile -- * * Initializes a file structure. * * This sets the filename of the file and initializes other structure * elements. * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsInitFile(HgfsFile *fp, // IN: File to initialize struct vnode *dvp, // IN: Paretn directory vnode const char *fileName, // IN: Name of file HgfsFileType fileType, // IN: Type of file int permissions, // IN: Permissions for new files off_t fileSize) // IN: File size { int len; ASSERT(fp); ASSERT(fileName); /* Make sure the filename will fit. */ len = strlen(fileName); if (len > sizeof fp->fileName - 1) { return HGFS_ERR; } fp->fileNameLength = len; memcpy(fp->fileName, fileName, len + 1); fp->fileName[fp->fileNameLength] = '\0'; /* * We save the file type so we can recreate a vnode for the HgfsFile without * sending a request to the Hgfs Server. */ fp->permissions = permissions; /* Initialize the links to place this file in our hash table. */ DblLnkLst_Init(&fp->listNode); /* * Fill in the node id. This serves as the inode number in directory * entries and the node id in vnode attributes. */ HgfsNodeIdHash(fp->fileName, fp->fileNameLength, &fp->nodeId); fp->mode = 0; fp->modeIsSet = FALSE; fp->handleRefCount = 0; fp->intHandleRefCount = 0; fp->handle = 0; fp->mmapped = FALSE; fp->fileSize = fileSize; fp->handleLock = os_rw_lock_alloc_init("hgfs_rw_handle_lock"); if (!fp->handleLock) { goto destroyOut; } fp->modeMutex = os_mutex_alloc_init("hgfs_mtx_mode"); if (!fp->modeMutex) { goto destroyOut; } #if defined __APPLE__ fp->rwFileLock = os_rw_lock_alloc_init("hgfs_rw_file_lock"); if (!fp->rwFileLock) { goto destroyOut; } DEBUG(VM_DEBUG_LOG, "fp = %p, Lock = %p .\n", fp, fp->rwFileLock); #endif fp->parent = dvp; if (dvp != NULL) { vnode_ref(dvp); } /* Success */ return 0; destroyOut: ASSERT(fp); if (fp->handleLock) { os_rw_lock_free(fp->handleLock); } if (fp->modeMutex) { os_mutex_free(fp->modeMutex); } #if defined __APPLE__ if (fp->rwFileLock) { os_rw_lock_free(fp->rwFileLock); } DEBUG(VM_DEBUG_LOG, "Destroying fp = %p, Lock = %p .\n", fp, fp->rwFileLock); #endif os_free(fp, sizeof *fp); return HGFS_ERR; } /* *---------------------------------------------------------------------------- * * HgfsFreeFile -- * * Preforms necessary cleanup and frees the memory allocated for HgfsFile. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsFreeFile(HgfsFile *fp) // IN: HgfsFile structure to free { ASSERT(fp); os_rw_lock_free(fp->handleLock); os_mutex_free(fp->modeMutex); #if defined __APPLE__ DEBUG(VM_DEBUG_LOG, "Trace enter, fp = %p, Lock = %p .\n", fp, fp->rwFileLock); os_rw_lock_free(fp->rwFileLock); #endif if (fp->parent != NULL) { vnode_rele(fp->parent); } os_free(fp, sizeof *fp); } /* Adding/finding/removing file state from hash table */ /* *---------------------------------------------------------------------------- * * HgfsAddFile -- * * Adds the file to the hash table. * * This function must be called with the hash table lock held. This is done * so adding the file in the hash table can be made with any other * operations (such as previously finding out that this file wasn't in the * hash table). * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void HgfsAddFile(HgfsFile *fp, // IN: File to add HgfsFileHashTable *htp) // IN: Hash table to add to { unsigned int index; ASSERT(fp); ASSERT(htp); LCK_MTX_ASSERT(htp->mutex); index = HgfsFileNameHash(fp->fileName); /* Add this file to the end of the bucket's list */ DblLnkLst_LinkLast(HGFS_FILE_HT_HEAD(htp, index), &fp->listNode); } /* *---------------------------------------------------------------------------- * * HgfsFindFile -- * * Looks for a filename in the hash table. * * This function must be called with the hash table lock held. This is done * so finding the file in the hash table and using it (after this function * returns) can be atomic. * * Results: * Returns a pointer to the file if found, NULL otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static HgfsFile * HgfsFindFile(const char *fileName, // IN: Filename to look for HgfsFileHashTable *htp) // IN: Hash table to look in { HgfsFile *found = NULL; DblLnkLst_Links *currNode; unsigned int index; ASSERT(fileName); ASSERT(htp); LCK_MTX_ASSERT(htp->mutex); /* Determine which bucket. */ index = HgfsFileNameHash(fileName); /* Traverse the bucket's list. */ for (currNode = HGFS_FILE_HT_HEAD(htp, index); currNode != HGFS_FILE_HT_BUCKET(htp, index); currNode = currNode->next) { HgfsFile *curr; curr = DblLnkLst_Container(currNode, HgfsFile, listNode); if (strcmp(curr->fileName, fileName) == 0) { /* We found the file we want. */ found = curr; break; } } /* Return file if found. */ return found; } /* Other utility functions */ /* *---------------------------------------------------------------------------- * * HgfsFileNameHash -- * * Hashes the filename to get an index into the hash table. This is known * as the PJW string hash function and it was taken from "Mastering * Algorithms in C". * * Results: * Returns an index between 0 and HGFS_HT_NR_BUCKETS. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static unsigned int HgfsFileNameHash(const char *fileName) // IN: Filename to hash { unsigned int val = 0; ASSERT(fileName); while (*fileName != '\0') { unsigned int tmp; val = (val << 4) + (*fileName); if ((tmp = (val & 0xf0000000))) { val = val ^ (tmp >> 24); val = val ^ tmp; } fileName++; } return val % HGFS_HT_NR_BUCKETS; } /* *---------------------------------------------------------------------------- * * HgfsNodeIdHash -- * * Hashes the provided filename to generate a node id. * * Results: * None. The value of the hash is filled into outHash. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void HgfsNodeIdHash(const char *fileName, // IN: Filename to hash uint32_t fileNameLength, // IN: Length of the filename ino_t *outHash) // OUT: Location to write hash to { SHA1_CTX hashContext; unsigned char digest[SHA1_HASH_LEN]; int i; ASSERT(fileName); ASSERT(outHash); /* Make sure we start at a consistent state. */ memset(&hashContext, 0, sizeof hashContext); memset(digest, 0, sizeof digest); memset(outHash, 0, sizeof *outHash); /* Generate a SHA1 hash of the filename */ SHA1Init(&hashContext); SHA1Update(&hashContext, (unsigned const char *)fileName, fileNameLength); SHA1Final(digest, &hashContext); /* * Fold the digest into the allowable size of our hash. * * For each group of bytes the same size as our output hash, xor the * contents of the digest together. If there are less than that many bytes * left in the digest, xor each byte that's left. */ for(i = 0; i < sizeof digest; i += sizeof *outHash) { int bytesLeft = sizeof digest - i; /* Do a byte-by-byte xor if there aren't enough bytes left in the digest */ if (bytesLeft < sizeof *outHash) { int j; for (j = 0; j < bytesLeft; j++) { uint8 *outByte = (uint8 *)outHash + j; uint8 *inByte = (uint8 *)((uint32_t *)(digest + i)) + j; *outByte ^= *inByte; } break; } /* Block xor */ *outHash ^= *((uint32_t *)(digest + i)); } /* * Clear the most significant byte so that user space apps depending on * a node id/inode number that's only 32 bits won't break. (For example, * gedit's call to stat(2) returns EOVERFLOW if we don't do this.) */ #if 0 # ifndef HGFS_BREAK_32BIT_USER_APPS *((uint32_t *)outHash) ^= *((uint32_t *)outHash + 1); *((uint32_t *)outHash + 1) = 0; # endif #endif DEBUG(VM_DEBUG_INFO, "Hash of: %s (%d) is %u\n", fileName, fileNameLength, *outHash); return; } /* *---------------------------------------------------------------------------- * * HgfsIsModeCompatible -- * * Verifies if the requested open mode for the file is compatible * with already assigned open mode. * * Results: * Returns zero on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static Bool HgfsIsModeCompatible(HgfsMode requestedMode, // IN: Requested open mode HgfsMode existingMode) // IN: Existing open mode { DEBUG(VM_DEBUG_LOG, "Compare mode %d with %d.\n", requestedMode, existingMode); return (existingMode == HGFS_OPEN_MODE_READ_WRITE || requestedMode == existingMode); } /* *---------------------------------------------------------------------------- * * HgfsSetFileSize -- * * Notifies virtual memory system that file size has changed. * Required for memory mapped files to work properly. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsSetFileSize(struct vnode *vp, // IN: vnode which file size has changed off_t newSize) // IN: new value for file size { HgfsFile *fp; ASSERT(vp); fp = HGFS_VP_TO_FP(vp); if (fp->fileSize != newSize) { fp->fileSize = newSize; os_SetSize(vp, newSize); } } open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/vmci.c0000644765153500003110000000245212220061556021120 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmci.c -- * * VMCI transport channel for the HGFS client is not currently implemented. */ #include "channel.h" /* *---------------------------------------------------------------------- * * HgfsGetVmciChannel -- * * Get Vmci channel. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ HgfsTransportChannel* HgfsGetVmciChannel(void) // IN: { return NULL; } open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/request.c0000644765153500003110000005424712220061556021663 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * request.c -- * * Implementation of routines used to initialize, allocate, and move * requests between lists. */ /* * Includes */ #include "hgfs_kernel.h" #include "requestInt.h" #include "channel.h" /* * Macros */ /* * Since the DblLnkLst_Links in the requests container is just an anchor, we want to * skip it (e.g., get the container for the next element) */ #define HGFS_SIP_LIST_HEAD(sip) \ (DblLnkLst_Container((sip)->reqs->list.next, HgfsKReqObject, fsNode)) #define HGFS_SIP_LIST_HEAD_NODE(sip) (sip->reqs->list.next) /* * Local data */ /* * See requestInt.h for details. */ DblLnkLst_Links hgfsKReqWorkItemList; OS_MUTEX_T *hgfsKReqWorkItemLock; OS_ZONE_T *hgfsKReqZone; OS_CV_T hgfsKReqWorkItemCv; /* * Local functions (prototypes) */ static int HgfsKReqZCtor(void *mem, int size, void *arg, int flags); static void HgfsKReqZDtor(void *mem, int size, void *arg); static int HgfsKReqZInit(void *mem, int size, int flags); static void HgfsKReqZFini(void *mem, int size); /* * Global functions (definitions) */ /* *----------------------------------------------------------------------------- * * HgfsKReq_SysInit -- * * This function simply initializes the hgfsKReqZone. This is done * separately from the VFS initialization routine, our caller, in order * to abstract away the request allocation & support code. * * Results: * Zero on success, HGFS_ERR on error. * * Side effects: * hgfsKReqZone is initialized. This routine may sleep. * *----------------------------------------------------------------------------- */ int HgfsKReq_SysInit(void) { int ret = 0; hgfsKReqZone = os_zone_create(HGFS_FS_NAME "_zone", sizeof (struct HgfsKReqObject), HgfsKReqZCtor, HgfsKReqZDtor, HgfsKReqZInit, HgfsKReqZFini, 0, 0); if (!hgfsKReqZone) { return HGFS_ERR; } hgfsKReqWorkItemLock = os_mutex_alloc_init(HGFS_FS_NAME "_workmtx"); if (!hgfsKReqWorkItemLock) { os_zone_destroy(hgfsKReqZone); return HGFS_ERR; } /* * This is a nop on Mac OS because we don't actually have a condition variable * to initialize. */ os_cv_init(&hgfsKReqWorkItemCv, HGFS_FS_NAME "_workcv"); DblLnkLst_Init(&hgfsKReqWorkItemList); /* Spawn the worker thread. */ ret = os_thread_create(HgfsKReqWorker, &hgfsKReqWorkerState, "HgfsKReqWorker", &hgfsKReqWorkerThread); if (ret != 0) { os_cv_destroy(&hgfsKReqWorkItemCv); os_zone_destroy(hgfsKReqZone); os_mutex_free(hgfsKReqWorkItemLock); return HGFS_ERR; } return 0; } /* *----------------------------------------------------------------------------- * * HgfsKReq_SysFini -- * * Hgfs request subsystem cleanup routine. This should be called when the * Hgfs client module is unloaded from the kernel. * * Results: * Zero on success or errno on failure. * * Side effects: * This routine may (will?) sleep. hgfsKReqZone is destroyed. * *----------------------------------------------------------------------------- */ int HgfsKReq_SysFini(void) { /* Signal the worker thread to exit. */ os_mutex_lock(hgfsKReqWorkItemLock); hgfsKReqWorkerState.exit = TRUE; os_cv_signal(&hgfsKReqWorkItemCv); /* * Sleep until the worker thread exits. hgfsKReqWorkItemLock is release by * by os_thread_join. */ os_thread_join(hgfsKReqWorkerThread, hgfsKReqWorkItemLock); /* * Destroy resources allocated during _SysInit(). */ os_thread_release(hgfsKReqWorkerThread); os_zone_destroy(hgfsKReqZone); os_cv_destroy(&hgfsKReqWorkItemCv); os_mutex_free(hgfsKReqWorkItemLock); return 0; } /* *---------------------------------------------------------------------------- * * HgfsKReq_AllocateContainer -- * * Allocate a request container for a single file system mount. * * Results: * Pointer to a new allocation container or NULL on failure. * * Side effects: * This routine may sleep. * *---------------------------------------------------------------------------- */ HgfsKReqContainerHandle HgfsKReq_AllocateContainer(void) { HgfsKReqContainer *container; container = os_malloc(sizeof (struct HgfsKReqContainer), M_WAITOK | M_ZERO); if (!container) { return NULL; } container->listLock = os_mutex_alloc_init("hgfs_reql_mtx"); if (!container->listLock) { os_free(container, sizeof *container); return NULL; } DblLnkLst_Init(&container->list); return container; } /* *---------------------------------------------------------------------------- * * HgfsKReq_FreeContainer -- * * Free a request container. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsKReq_FreeContainer(HgfsKReqContainerHandle container) // IN: file system's // container handle { ASSERT(container); ASSERT(DblLnkLst_IsLinked(&container->list) == FALSE); os_mutex_free(container->listLock); os_free(container, sizeof(*container)); } /* *---------------------------------------------------------------------------- * * HgfsKReq_CancelRequests -- * * Cancels all allocated requests by updating their status (set to * HGFS_REQ_ERROR) and waking up any waiting clients. Also, if linked, * removes any items from the work item list. * * Results: * None. * * Side effects: * This file system's entries are removed from the work item list are * removed. * *---------------------------------------------------------------------------- */ void HgfsKReq_CancelRequests(HgfsKReqContainerHandle container) // IN: request container { DblLnkLst_Links *currNode; DblLnkLst_Links *nextNode; DEBUG(VM_DEBUG_REQUEST, "HgfsCancelAllRequests().\n"); ASSERT(container); /* * 1. Lock this file system's request list. * 2. Lock the global pending request list. * 3. For each request in the file system's request list: * a. Remove from the global pending request list. * b. Lock the request. * c. Set the request's state to HGFS_REQ_ERROR. * d. Signal any waiters. * e. Drop our reference, destroying the object if ours was the last. * 4. Unlock the global pending request list. * 5. Unlock the file system's request list. */ os_mutex_lock(container->listLock); os_mutex_lock(hgfsKReqWorkItemLock); DEBUG(VM_DEBUG_REQUEST, "HgfsCancelAllRequests(): traversing pending request list.\n"); DblLnkLst_ForEachSafe(currNode, nextNode, &container->list) { HgfsKReqObject *req; Bool deref = FALSE; /* Get a pointer to the request represented by currNode. */ req = DblLnkLst_Container(currNode, HgfsKReqObject, fsNode); /* * If linked in the pending request list, remove it. Note that we're * transferring that list's reference to ourself. (I.e., we'll be * responsible for decrementing the reference count and freeing if it * reaches zero.) */ if (DblLnkLst_IsLinked(&req->pendingNode)) { deref = TRUE; DblLnkLst_Unlink1(&req->pendingNode); } /* Force this over to the error state & wake up any waiters. */ os_mutex_lock(req->stateLock); req->state = HGFS_REQ_ERROR; os_cv_signal(&req->stateCv); os_mutex_unlock(req->stateLock); if (deref) { if (os_add_atomic(&req->refcnt, -1) == 1) { os_zone_free(hgfsKReqZone, req); } } } os_mutex_unlock(hgfsKReqWorkItemLock); os_mutex_unlock(container->listLock); DEBUG(VM_DEBUG_REQUEST, "HgfsCancelAllRequests() done.\n"); } /* *---------------------------------------------------------------------------- * * HgfsKReq_ContainerIsEmpty -- * * Indicates whether a file system, represented by its superinfo, has any * outstanding HgfsKReqObjectuests. * * Results: * Returns zero if list is not empty, a positive integer if it is empty. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool HgfsKReq_ContainerIsEmpty(HgfsKReqContainerHandle container) // IN: { Bool result; ASSERT(container); os_mutex_lock(container->listLock); result = DblLnkLst_IsLinked(&container->list) ? FALSE : TRUE; os_mutex_unlock(container->listLock); DEBUG(VM_DEBUG_REQUEST, "Container empty value: %d\n", result); return result; } /* *---------------------------------------------------------------------------- * * HgfsKReq_AllocateRequest -- * * Allocates and initializes a new request structure from the request pool. * This function blocks until a request is available or it has been * interrupted by a signal. * * Results: * Pointer to fresh HgfsKReqHandle or NULL on failure. * * Side effects: * Request inserted into caller's requests container. This routine may * sleep. * *---------------------------------------------------------------------------- */ HgfsKReqHandle HgfsKReq_AllocateRequest(HgfsKReqContainerHandle container, // IN: int *errorRet) // OUT: { HgfsKReqObject *req; ASSERT(errorRet); ASSERT(container); *errorRet = 0; if (!gHgfsChannel) { *errorRet = EIO; return NULL; } /* * In case we don't have any channel currently, set up a new channel. * Note that we remember the channel from which request was allocated * and sent, thereby making sure that we free it via correct channel. */ if (gHgfsChannel->status != HGFS_CHANNEL_CONNECTED) { if (!HgfsSetupNewChannel()) { *errorRet = EIO; return NULL; } } req = os_zone_alloc(hgfsKReqZone, M_WAITOK); if (!req) { *errorRet = ENOMEM; return NULL; } os_mutex_lock(container->listLock); DblLnkLst_LinkLast(&container->list, &req->fsNode); os_mutex_unlock(container->listLock); return req; } /* *---------------------------------------------------------------------------- * * HgfsKReq_ReleaseReq -- * * Routine for file systems to return a request to the pool. * * Results: * None. * * Side effects: * oldReq->refcnt will be decremented, and oldReq may be freed. * *---------------------------------------------------------------------------- */ void HgfsKReq_ReleaseRequest(HgfsKReqContainerHandle container, // IN: HgfsKReqHandle oldRequest) // IN: { DEBUG(VM_DEBUG_ENTRY, "%s\n", __func__); ASSERT(container); ASSERT(oldRequest); /* Dissociate request from this file system. */ os_mutex_lock(container->listLock); DblLnkLst_Unlink1(&oldRequest->fsNode); os_mutex_unlock(container->listLock); /* State machine update */ os_mutex_lock(oldRequest->stateLock); switch (oldRequest->state) { case HGFS_REQ_ALLOCATED: case HGFS_REQ_SUBMITTED: oldRequest->state = HGFS_REQ_ABANDONED; break; case HGFS_REQ_ABANDONED: panic("%s: Request (%p) already abandoned!\n", __func__, oldRequest); break; case HGFS_REQ_ERROR: case HGFS_REQ_COMPLETED: break; default: NOT_REACHED(); } os_mutex_unlock(oldRequest->stateLock); /* Dereference file system from request. If refcnt goes to zero, free. */ if (os_add_atomic(&oldRequest->refcnt, -1) == 1) { os_zone_free(hgfsKReqZone, oldRequest); } DEBUG(VM_DEBUG_REQUEST, "%s done.\n", __func__); } /* *---------------------------------------------------------------------------- * * HgfsKReq_SubmitRequest -- * * Queues caller's request for Guest <-> Host processing and waits for * it to be processed. * * Results: * Zero on success, errno if interrupted. * * Side effects: * Request's state may change. * * Synchronization notes: * Assumes caller holds newReq->stateLock. (Implicit from _GetNewReq.) * *---------------------------------------------------------------------------- */ int HgfsKReq_SubmitRequest(HgfsKReqObject *newreq) // IN: Request to enqueue { int ret = 0; ASSERT(newreq); DEBUG(VM_DEBUG_REQUEST, "HgfsEnqueueRequest().\n"); /* * Insert request on pending request list, then alert of its arrival the * request processor. Since the list will also reference the request, be * sure to bump its count before unlocking the list! */ os_mutex_lock(hgfsKReqWorkItemLock); /* * With the work item list locked, lock our object and operate on its state. * Typically we expect it to be in the ALLOCATED state, but if the file * system asynchronously cancelled all requests, it may be in ERROR instead. */ os_mutex_lock(newreq->stateLock); switch (newreq->state) { case HGFS_REQ_ALLOCATED: /* * Update request's state, bump refcnt, and signal worker thread. */ newreq->state = HGFS_REQ_SUBMITTED; os_add_atomic(&newreq->refcnt, 1); DblLnkLst_LinkLast(&hgfsKReqWorkItemList, &newreq->pendingNode); os_cv_signal(&hgfsKReqWorkItemCv); os_mutex_unlock(hgfsKReqWorkItemLock); /* * NB: We're still holding this request's state lock for use with * cv_wait_sig. */ break; case HGFS_REQ_ERROR: /* * Bail ASAP. */ os_mutex_unlock(newreq->stateLock); os_mutex_unlock(hgfsKReqWorkItemLock); return EIO; break; case HGFS_REQ_UNUSED: case HGFS_REQ_SUBMITTED: case HGFS_REQ_ABANDONED: case HGFS_REQ_COMPLETED: panic("Cannot submit object (%p) in its current state: %u", newreq, newreq->state); break; default: panic("Request object (%p) in unknown state: %u", newreq, newreq->state); } /* Sleep until request is processed or we're interrupted. */ while (newreq->state == HGFS_REQ_SUBMITTED && ret == 0) { ret = os_cv_wait(&newreq->stateCv, newreq->stateLock); } /* Okay, we're finished with the state lock for now. */ os_mutex_unlock(newreq->stateLock); return ret; } /* *----------------------------------------------------------------------------- * * HgfsKReq_GetId -- * * Return this object's unique request ID. * * Results: * Object's unique request ID. * * Side effects: * None. * *----------------------------------------------------------------------------- */ uint32_t HgfsKReq_GetId(HgfsKReqHandle request) // IN: Request to get the ID for { ASSERT(request); return request->id; } /* *----------------------------------------------------------------------------- * * HgfsKReq_GetPayload -- * * Return a pointer to the payload area of a request. Callers may write * Hgfs packet data directly to this area. It's guaranteed to hold at * most HGFS_PACKET_MAX (6144) bytes. For Hgfs version 3, the caller should * explicitly write request header (HgfsRequest) into this area. * * Results: * Pointer to the payload area. * * Side effects: * None. * *----------------------------------------------------------------------------- */ char * HgfsKReq_GetPayload(HgfsKReqHandle request) // IN: Request to get pointer to payload { ASSERT(request); return request->payload; } /* *----------------------------------------------------------------------------- * * HgfsKReq_GetPayloadSize -- * * Returns the amount of data current stored in the payload. (Typically * used when the file system receives an Hgfs reply.) * * Results: * Size of current payload in bytes. * * Side effects: * None. * *----------------------------------------------------------------------------- */ size_t HgfsKReq_GetPayloadSize(HgfsKReqHandle request) // IN: Request to get the size of { ASSERT(request); return request->payloadSize; } /* *----------------------------------------------------------------------------- * * HgfsKReq_SetPayloadSize -- * * Record the amount of data currently stored in the payload. (Typically * used when the file system finishes composing its request.) * * Results: * None. * * Side effects: * Request object's payload size is modified. * *----------------------------------------------------------------------------- */ void HgfsKReq_SetPayloadSize(HgfsKReqHandle request, // IN: Request object size_t payloadSize) // IN: New payload size { ASSERT(request); ASSERT(payloadSize <= HGFS_PACKET_MAX); request->payloadSize = payloadSize; } /* *---------------------------------------------------------------------------- * * HgfsKReq_GetState -- * * Retrieves state of provided request. * * Results: * Returns state of request. * * Side effects: * None. * *---------------------------------------------------------------------------- */ HgfsKReqState HgfsKReq_GetState(HgfsKReqObject *req) // IN: Request to retrieve state of { HgfsKReqState state; ASSERT(req); os_mutex_lock(req->stateLock); state = req->state; os_mutex_unlock(req->stateLock); return state; } /* * Local functions (definitions) */ /* *----------------------------------------------------------------------------- * * HgfsKReqZInit -- * * "The initializer is called when the memory is cached in the uma zone. * this should be the same state that the destructor leaves the object in." * - sys/vm/uma.h * * Results: * Zero on success, errno on failure. * * Side effects: * A request's mutex and condvar are initialized, ID recorded, and status * set to HGFS_REQ_UNUSED. * *----------------------------------------------------------------------------- */ static int HgfsKReqZInit(void *mem, // IN: Pointer to the allocated object int size, // IN: Size of item being initialized [ignored] int flags) // IN: malloc(9) style flags { static unsigned int id = 0; HgfsKReqObject *req = (HgfsKReqObject *)mem; ASSERT(size == sizeof *req); os_add_atomic(&id, 1); req->id = id; req->state = HGFS_REQ_UNUSED; req->stateLock = os_mutex_alloc_init("hgfs_req_mtx"); if (!req->stateLock) { return ENOMEM; } os_cv_init(&req->stateCv, "hgfs_req_cv"); /* Reset list pointers. */ DblLnkLst_Init(&req->fsNode); DblLnkLst_Init(&req->pendingNode); DblLnkLst_Init(&req->sentNode); /* Clear packet of request before allocating to clients. */ bzero(&req->__rpc_packet, sizeof req->__rpc_packet); return 0; } /* *----------------------------------------------------------------------------- * * HgfsKReqZFini -- * * "This routine is called when memory leaves a zone and is returned * to the system for other uses. It is the counter part to the * init function." - sys/vm/uma.h * * Results: * None. * * Side effects: * A request's mutex and condvar are destroyed. * *----------------------------------------------------------------------------- */ static void HgfsKReqZFini(void *mem, // IN: Pointer to object leaving the UMA cache int size) // IN: Size of object [Ignored] { HgfsKReqObject *req = (HgfsKReqObject *)mem; ASSERT(size == sizeof *req); ASSERT(req->state == HGFS_REQ_UNUSED); os_mutex_free(req->stateLock); os_cv_destroy(&req->stateCv); } /* *----------------------------------------------------------------------------- * * HgfsKReqZCtor * * "The constructor is called just before the memory is returned * to the user. It may block if necessary." - sys/vm/uma.h * * Results: * Zero on success, errno on failure. * * Side effects: * Request's state is set to HGFS_REQ_ALLOCATED, its listNode is * initialized, and its packet is zeroed out. * *----------------------------------------------------------------------------- */ static int HgfsKReqZCtor(void *mem, // IN: Pointer to memory allocated to user int size, // IN: Size of allocated object [ignored] void *arg, // IN: Optional argument from uma_zalloc_arg [ignored] int flags) // IN: malloc(9) flags { HgfsKReqObject *req = (HgfsKReqObject *)mem; ASSERT(size == sizeof *req); ASSERT(req->state == HGFS_REQ_UNUSED); ASSERT(DblLnkLst_IsLinked(&req->fsNode) == FALSE); ASSERT(DblLnkLst_IsLinked(&req->pendingNode) == FALSE); /* Initialize state & reference count. */ req->state = HGFS_REQ_ALLOCATED; req->refcnt = 1; return 0; } /* *----------------------------------------------------------------------------- * * HgfsKReqZDtor * * "The destructor may perform operations that differ from those performed * by the initializer, but it must leave the object in the same state. * This IS type stable storage. This is called after EVERY zfree call." * - sys/vm/uma.h * * Results: * None. * * Side effects: * Object's state is set to HGFS_REQ_UNUSED. * *----------------------------------------------------------------------------- */ static void HgfsKReqZDtor(void *mem, // IN: Pointer to allocated object int size, // IN: Size of allocated object [ignored] void *arg) // IN: Argument for uma_zfree_arg [ignored] { HgfsKReqObject *req = (HgfsKReqObject *)mem; ASSERT(req->refcnt == 0); ASSERT(DblLnkLst_IsLinked(&req->fsNode) == FALSE); ASSERT(DblLnkLst_IsLinked(&req->pendingNode) == FALSE); req->state = HGFS_REQ_UNUSED; } open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/vnopscommon.c0000644765153500003110000031011712220061556022540 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vnopscommon.c -- * * Common VFS vnop implementations that are shared between both Mac OS and FreeBSD. */ #include // for everything #include // for struct vnode #include // for struct dirent #include "fsutil.h" #include "debug.h" #include "vnopscommon.h" #include "transport.h" #include "cpName.h" #include "os.h" /* Local function prototypes */ int HgfsGetNextDirEntry(HgfsSuperInfo *sip, HgfsHandle handle, uint32_t offset, char *nameOut, size_t nameSize, HgfsFileType *type, Bool *done); int HgfsDirOpen(HgfsSuperInfo *sip, struct vnode *vp, HgfsOpenType openType); int HgfsFileOpen(HgfsSuperInfo *sip, struct vnode *vp, int flag, int permissions, HgfsOpenType openType); int HgfsDirClose(HgfsSuperInfo *sip, struct vnode *vp); int HgfsFileClose(HgfsSuperInfo *sip, struct vnode *vp, int flag); int HgfsDoRead(HgfsSuperInfo *sip, HgfsHandle handle, uint64_t offset, uint32_t size, struct uio *uiop); int HgfsDoWrite(HgfsSuperInfo *sip, HgfsHandle handle, int ioflag, uint64_t offset, uint32_t size, struct uio *uiop); int HgfsDelete(HgfsSuperInfo *sip, const char *filename, HgfsOp op); static int HgfsDoGetattrInt(const char *path, const HgfsHandle handle, HgfsSuperInfo *sip, HgfsAttrV2 *hgfsAttrV2); static int HgfsDoGetattrByName(const char *path, HgfsSuperInfo *sip, HgfsAttrV2 *hgfsAttrV2); int HgfsReadlinkInt(struct vnode *vp, struct uio *uiop); static int HgfsQueryAttrInt(const char *path, HgfsHandle handle, HgfsSuperInfo *sip, HgfsKReqHandle req); static int HgfsRefreshHandle(struct vnode *vp, HgfsSuperInfo *sip, HgfsHandle *handle); #if 0 static int HgfsDoGetattrByHandle(HgfsHandle handle, HgfsSuperInfo *sip, HgfsAttrV2 *hgfsAttrV2); #endif #define HGFS_CREATE_DIR_MASK (HGFS_CREATE_DIR_VALID_FILE_NAME | \ HGFS_CREATE_DIR_VALID_SPECIAL_PERMS | \ HGFS_CREATE_DIR_VALID_OWNER_PERMS | \ HGFS_CREATE_DIR_VALID_GROUP_PERMS | \ HGFS_CREATE_DIR_VALID_OTHER_PERMS) /* *---------------------------------------------------------------------------- * * HgfsRenameInt -- * * Renames the provided source name in the source directory with the * destination name in the destination directory. A RENAME request is sent * to the Hgfs server. * * Results: * Returns 0 on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsRenameInt(struct vnode *fvp, // IN: "from" file struct vnode *tdvp, // IN: "to" parent directory struct vnode *tvp, // IN: "to" file struct componentname *tcnp) // IN: "to" pathname info { HgfsSuperInfo *sip = HGFS_VP_TO_SIP(fvp); HgfsKReqHandle req; HgfsRequest *requestHeader; HgfsRequestRenameV3 *request; HgfsReplyRenameV3 *reply; HgfsFileNameV3 *newNameP; char *srcFullPath = NULL; // will point to fvp's filename; don't free char *dstFullPath = NULL; // allocated from M_TEMP; free when done. uint32 srcFullPathLen; uint32 dstFullPathLen; uint32 reqBufferSize; uint32 reqSize; uint32 repSize; int ret; DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s -> %.*s/%.*s).\n", HGFS_VP_TO_FILENAME_LENGTH(fvp), HGFS_VP_TO_FILENAME(fvp), HGFS_VP_TO_FILENAME_LENGTH(tdvp), HGFS_VP_TO_FILENAME(tdvp), (int)tcnp->cn_namelen, tcnp->cn_nameptr); /* No cross-device renaming. */ if (HGFS_VP_TO_MP(fvp) != HGFS_VP_TO_MP(tdvp)) { ret = EXDEV; goto out; } req = HgfsKReq_AllocateRequest(sip->reqs, &ret); if (!req) { goto out; } requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req); request = (HgfsRequestRenameV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader); /* Initialize the request header */ HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_RENAME_V3); request->hints = 0; request->reserved = 0; reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); reqBufferSize = HGFS_PACKET_MAX - (reqSize - 2); /* Make the full path of the source. */ srcFullPath = HGFS_VP_TO_FILENAME(fvp); srcFullPathLen = HGFS_VP_TO_FILENAME_LENGTH(fvp); /* Make the full path of the destination. */ dstFullPath = os_malloc(MAXPATHLEN, M_WAITOK); if (!dstFullPath) { ret = ENOMEM; goto destroyOut; } ret = HgfsMakeFullName(HGFS_VP_TO_FILENAME(tdvp), HGFS_VP_TO_FILENAME_LENGTH(tdvp), tcnp->cn_nameptr, tcnp->cn_namelen, dstFullPath, MAXPATHLEN); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "could not construct full path of dest.\n"); ret = ENAMETOOLONG; goto destroyOut; } dstFullPathLen = ret; /* Ensure both names will fit in one request. */ if ((reqSize + srcFullPathLen + dstFullPathLen) > HGFS_PACKET_MAX) { DEBUG(VM_DEBUG_FAIL, "names too big for one request.\n"); ret = EPROTO; goto destroyOut; } request->oldName.flags = 0; request->oldName.fid = HGFS_INVALID_HANDLE; request->oldName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; /* * Convert an input string to utf8 precomposed form, convert it to * the cross platform name format and finally unescape any illegal * filesystem characters. */ ret = HgfsNameToWireEncoding(srcFullPath, srcFullPathLen + 1, request->oldName.name, reqBufferSize); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "Couldn't encode to wire format\n"); ret = -ret; goto destroyOut; } request->oldName.length = ret; reqSize += ret; reqBufferSize -= ret; /* * The new name is placed directly after the old name in the packet and we * access it through this pointer. */ newNameP = (HgfsFileNameV3 *)((char *)&request->oldName + sizeof request->oldName + request->oldName.length); newNameP->flags = 0; newNameP->fid = HGFS_INVALID_HANDLE; newNameP->caseType = HGFS_FILE_NAME_CASE_SENSITIVE; ret = HgfsNameToWireEncoding(dstFullPath, dstFullPathLen + 1, newNameP->name, reqBufferSize); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "Couldn't encode to wire format.\n"); ret = -ret; goto destroyOut; } newNameP->length = ret; reqSize += ret; /* The request's size includes the header, request and both filenames. */ HgfsKReq_SetPayloadSize(req, reqSize); ret = HgfsSubmitRequest(sip, req); if (ret) { /* HgfsSubmitRequest() destroys the request if necessary. */ goto out; } repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply); ret = HgfsGetStatus(req, repSize); if (ret) { DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret); goto destroyOut; } /* Successfully renamed file on the server. */ destroyOut: HgfsKReq_ReleaseRequest(sip->reqs, req); out: if (dstFullPath != NULL) { os_free(dstFullPath, MAXPATHLEN); } DEBUG(VM_DEBUG_EXIT, "Exit(%d).\n", ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsReaddirInt -- * * Reads as many entries from the directory as will fit in to the provided * buffer. Each directory entry is read by calling HgfsGetNextDirEntry(). * * "The vop_readdir() method reads chunks of the directory into a uio * structure. Each chunk can contain as many entries as will fit within * the size supplied by the uio structure. The uio_resid structure member * shows the size of the getdents request in bytes, which is divided by the * size of the directory entry made by the vop_readdir() method to * calculate how many directory entries to return." (Solaris Internals, * p555) * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsReaddirInt(struct vnode *vp, // IN : Directory vnode to get entries from. struct uio *uiop, // IN/OUT: Buffer to place dirents in. int *eofp) // IN/OUT: Have all entries been read? { HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp); HgfsHandle handle; uint64_t offset; Bool done; char *fullName = NULL; /* Hashed to generate inode number */ int ret = 0; DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp)); /* uio_offset is a signed quantity. */ if (HGFS_UIOP_TO_OFFSET(uiop) < 0) { DEBUG(VM_DEBUG_FAIL, "fed negative offset.\n"); ret = EINVAL; goto out; } /* * In order to fill the user's buffer with directory entries, we must * iterate on HGFS_OP_SEARCH_READ requests until either the user's buffer is * full or there are no more entries. Each call to HgfsGetNextDirEntry() * fills in the name and attribute structure for the next entry. We then * escape that name and place it in a kernel buffer that's the same size as * the user's buffer. Once there are no more entries or no more room in the * buffer, we copy it to user space. */ /* * We need to get the handle for this open directory to send to the Hgfs * server in our requests. */ ret = HgfsGetOpenFileHandle(vp, &handle); if (ret) { DEBUG(VM_DEBUG_FAIL, "could not get handle.\n"); ret = EINVAL; goto out; } /* * Allocate 1K (MAXPATHLEN) buffer for inode number generation. */ fullName = os_malloc(MAXPATHLEN, M_WAITOK); if (!fullName) { ret = ENOMEM; goto out; } /* * Loop until one of the following conditions is met: * o An error occurs while reading a directory entry * o There are no more directory entries to read * o The buffer is full and cannot hold the next entry * * We request dentries from the Hgfs server based on their index in the * directory. The offset value is initialized to the value specified in * the user's io request and is incremented each time through the loop. * * dirp is incremented by the record length each time through the loop and * is used to determine where in the kernel buffer we write to. */ for (offset = HGFS_UIOP_TO_OFFSET(uiop), done = 0; /* Nothing */ ; offset++) { struct dirent dirent, *dirp = &dirent; char nameBuf[sizeof dirp->d_name]; HgfsFileType fileType = HGFS_FILE_TYPE_REGULAR; DEBUG(VM_DEBUG_COMM, "HgfsReaddir: getting directory entry at offset %"FMT64"u.\n", offset); DEBUG(VM_DEBUG_HANDLE, "** handle=%d, file=%s\n", handle, HGFS_VP_TO_FILENAME(vp)); bzero(dirp, sizeof *dirp); ret = HgfsGetNextDirEntry(sip, handle, offset, nameBuf, sizeof nameBuf, &fileType, &done); /* If the filename was too long, we skip to the next entry ... */ if (ret == EOVERFLOW) { continue; } else if (ret == EBADF) { /* * If we got invalid handle from the server, this was because user * enabled/disabled the shared folders. We should get a new handle * from the server, now. */ ret = HgfsRefreshHandle(vp, sip, &handle); if (ret == 0) { /* * Now we have valid handle, let's try again from the same * offset. */ offset--; continue; } else { ret = EBADF; goto out; } } else if (ret) { if (ret != EPROTO) { ret = EINVAL; } DEBUG(VM_DEBUG_FAIL, "failure occurred in HgfsGetNextDirEntry\n"); goto out; /* * ... and if there are no more entries, we set the end of file pointer * and break out of the loop. */ } else if (done == TRUE) { DEBUG(VM_DEBUG_COMM, "Done reading directory entries.\n"); if (eofp != NULL) { *eofp = TRUE; } break; } /* * Convert an input string to utf8 decomposed form and then escape its * buffer. */ ret = HgfsNameFromWireEncoding(nameBuf, strlen(nameBuf), dirp->d_name, sizeof dirp->d_name); /* * If the name didn't fit in the buffer or illegal utf8 characters * were encountered, skip to the next entry. */ if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "HgfsNameFromWireEncoding failed.\n"); continue; } /* Fill in the directory entry. */ dirp->d_namlen = ret; dirp->d_reclen = sizeof(*dirp); // NB: d_namlen must be set first! dirp->d_type = (fileType == HGFS_FILE_TYPE_REGULAR) ? DT_REG : (fileType == HGFS_FILE_TYPE_DIRECTORY) ? DT_DIR : DT_UNKNOWN; /* * Make sure there is enough room in the buffer for the entire directory * entry. If not, we just break out of the loop and copy what we have an set * the return value to be 0. */ if (dirp->d_reclen > HGFS_UIOP_TO_RESID(uiop)) { DEBUG(VM_DEBUG_INFO, "ran out of room in the buffer.\n"); ret = 0; break; } ret = HgfsMakeFullName(HGFS_VP_TO_FILENAME(vp), // Directorie's name HGFS_VP_TO_FILENAME_LENGTH(vp), // Length dirp->d_name, // Name of file dirp->d_namlen, // Length of filename fullName, // Destination buffer MAXPATHLEN); // Size of this buffer /* Skip this entry if the full path was too long. */ if (ret < 0) { continue; } /* * Place the node id, which serves the purpose of inode number, for this * filename directory entry. As long as we are using a dirent64, this is * okay since ino_t is also a u_longlong_t. */ HgfsNodeIdGet(&sip->fileHashTable, fullName, (uint32_t)ret, &dirp->d_fileno); /* Copy out this directory entry. */ ret = uiomove((caddr_t)dirp, dirp->d_reclen, uiop); if (ret) { DEBUG(VM_DEBUG_FAIL, "uiomove failed.\n"); goto out; } } /* * uiomove(9) will have incremented the uio offset by the number of bytes * written. We reset it here to the fs-specific offset in our directory so * the next time we are called it is correct. (Note, this does not break * anything and /is/ how this field is intended to be used.) */ HGFS_UIOP_SET_OFFSET(uiop, offset); DEBUG(VM_DEBUG_EXIT, "done (ret=%d, *eofp=%d).\n", ret, *eofp); out: if (fullName != NULL) { os_free(fullName, MAXPATHLEN); } DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsGetattrInt -- * * "Gets the attributes for the supplied vnode." (Solaris Internals, p536) * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsGetattrInt(struct vnode *vp, // IN : vnode of the file HgfsVnodeAttr *vap) // OUT: attributes container { HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp); HgfsAttrV2 hgfsAttrV2; int ret = 0; DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp)); /* XXX It would be nice to do a GetattrByHandle when possible here. */ ret = HgfsDoGetattrByName(HGFS_VP_TO_FILENAME(vp), sip, &hgfsAttrV2); if (!ret) { /* * HgfsDoGetattr obtained attributes from the hgfs server so * map the attributes into BSD attributes. */ HgfsAttrToBSD(vp, &hgfsAttrV2, vap); } DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsSetattrInt -- * * Maps the Mac OS/FreeBsd attributes to Hgfs attributes (by calling * HgfsSetattrCopy()) and sends a set attribute request to the Hgfs server. * * Results: * Returns 0 on success and a non-zero error code on error. * * Side effects: * The file on the host will have new attributes. * *---------------------------------------------------------------------------- */ int HgfsSetattrInt(struct vnode *vp, // IN : vnode of the file HgfsVnodeAttr *vap) // IN : attributes container { HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp); HgfsKReqHandle req; HgfsRequest *requestHeader; HgfsRequestSetattrV3 *request; HgfsReplySetattrV3 *reply; uint32 reqSize; uint32 reqBufferSize; uint32 repSize; char *fullPath = NULL; uint32 fullPathLen; int ret; DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp)); ASSERT(vp); ASSERT(vap); req = HgfsKReq_AllocateRequest(sip->reqs, &ret); if (!req) { goto out; } requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req); request = (HgfsRequestSetattrV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader); HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_SETATTR_V3); request->reserved = 0; /* * Fill the attributes and hint fields of the request. If no updates are * needed then we will just return success without sending the request. */ if (HgfsSetattrCopy(vap, &request->attr, &request->hints) == FALSE) { DEBUG(VM_DEBUG_COMM, "don't need to update attributes.\n"); ret = 0; goto destroyOut; } fullPath = HGFS_VP_TO_FILENAME(vp); fullPathLen = HGFS_VP_TO_FILENAME_LENGTH(vp); reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); reqBufferSize = HGFS_NAME_BUFFER_SIZET(HGFS_PACKET_MAX, reqSize); /* * Convert an input string to utf8 precomposed form, convert it to * the cross platform name format and finally unescape any illegal * filesystem characters. */ ret = HgfsNameToWireEncoding(fullPath, fullPathLen + 1, request->fileName.name, reqBufferSize); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "Could not encode to wire format"); ret = -ret; goto destroyOut; } request->fileName.fid = HGFS_INVALID_HANDLE; request->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; request->fileName.flags = 0; request->fileName.length = ret; reqSize += ret; /* The request's size includes the header, request and filename. */ HgfsKReq_SetPayloadSize(req, reqSize); if (!request->attr.mask) { /* they were trying to set filerev or vaflags, which we ignore */ ret = 0; goto destroyOut; } ret = HgfsSubmitRequest(sip, req); if (ret) { /* HgfsSubmitRequest() destroys the request if necessary. */ goto out; } repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply); ret = HgfsGetStatus(req, repSize); if (ret) { if (ret == EPROTO) { DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret); } goto destroyOut; } else { if (HGFS_VATTR_SIZE_IS_ACTIVE(vap, HGFS_VA_DATA_SIZE)) { HgfsSetFileSize(vp, vap->HGFS_VA_DATA_SIZE); } } destroyOut: HgfsKReq_ReleaseRequest(sip->reqs, req); out: DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsVopRmdir -- * * Removes the specified name from the provided vnode. Sends a DELETE * request by calling HgfsDelete() with the filename and correct opcode to * indicate deletion of a directory. * * "Removes the directory pointed to by the supplied vnode." (Solaris * Internals, p537) * * Results: * Returns 0 on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsRmdirInt(struct vnode *dvp, // IN: parent directory struct vnode *vp, // IN: directory to remove struct componentname *cnp) // IN: Only used for debugging { int ret = 0; HgfsSuperInfo *sip = HGFS_VP_TO_SIP(dvp); DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s/%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp), HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp)); ret = HgfsDelete(sip, HGFS_VP_TO_FILENAME(vp), HGFS_OP_DELETE_DIR_V3); DEBUG(VM_DEBUG_EXIT, "Exit(%.*s/%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp), HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsRemoveInt -- * * Composes the full pathname of this file and sends a DELETE_FILE request * by calling HgfsDelete(). * * Results: * Returns 0 on success or a non-zero error code on error. * * Side effects: * If successful, the file specified will be deleted from the host's * filesystem. * *---------------------------------------------------------------------------- */ int HgfsRemoveInt(struct vnode *vp) // IN: Vnode to delete { int ret = 0; HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp); DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp)); /* Removing directories is a no-no; save that for VNOP_RMDIR. */ if (HGFS_VP_TO_VTYPE(vp) == VDIR) { DEBUG(VM_DEBUG_FAIL, "HgfsRemove(). on dir ret EPERM\n"); ret = EPERM; goto out; } os_FlushRange(vp, 0, HGFS_VP_TO_FILESIZE(vp)); os_SetSize(vp, 0); /* We can now send the delete request. */ ret = HgfsDelete(sip, HGFS_VP_TO_FILENAME(vp), HGFS_OP_DELETE_FILE_V3); out: DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsCloseInt -- * * Called by HgfsVnopClose under Mac OS or HgfsVopClose under FreeBSD to * close a file. * * "Closes the file given by the supplied vnode. When this is the last * close, some filesystems use vnop_close() to initiate a writeback of * outstanding dirty pages by checking the reference cound in the vnode." * (Solaris Internals, p536) * * Results: * Always returns 0 success. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsCloseInt(struct vnode *vp, // IN: Vnode to close. int mode) // IN: Mode of vnode being closed. { int ret = 0; HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp); DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s, %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), mode); /* * If we are closing a directory we need to send a SEARCH_CLOSE request, * but if we are closing a regular file we need to send a CLOSE request. * Other file types are not supported by the Hgfs protocol. */ switch (HGFS_VP_TO_VTYPE(vp)) { case VDIR: ret = HgfsDirClose(sip, vp); break; case VREG: ret = HgfsFileClose(sip, vp, mode); break; default: DEBUG(VM_DEBUG_FAIL, "unsupported filetype %d.\n", HGFS_VP_TO_VTYPE(vp)); ret = EINVAL; break; } DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d -> 0)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), ret); return 0; } /* *---------------------------------------------------------------------------- * * HgfsOpenInt -- * * Invoked when open(2) is called on a file in our filesystem. Sends an * OPEN request to the Hgfs server with the filename of this vnode. * * "Opens a file referenced by the supplied vnode. The open() system call * has already done a vnop_lookup() on the path name, which returned a vnode * pointer and then calls to vnop_open(). This function typically does very * little since most of the real work was performed by vnop_lookup()." * (Solaris Internals, p537) * * Results: * Returns 0 on success and an error code on error. * * Side effects: * If the HgfsFile for this file does not already have a handle, it is * given one that can be used for future read and write requests. * *---------------------------------------------------------------------------- */ int HgfsOpenInt(struct vnode *vp, // IN: Vnode to open. int mode, // IN: Mode of vnode being opened. HgfsOpenType openType) // IN: TRUE if called outside of VNOP_OPEN. { HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp); int ret = 0; DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s, %d, %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), mode, openType); switch(HGFS_VP_TO_VTYPE(vp)) { case VDIR: DEBUG(VM_DEBUG_LOG, "opening a directory\n"); ret = HgfsDirOpen(sip, vp, openType); break; case VREG: /* * If HgfsCreate() was called prior to this then is would set permissions * in HgfsFile that we need to pass to HgfsFileOpen. * If HgfsCreate has not been called then file already exists and permissions * are ignored by HgfsFileOpen. */ DEBUG(VM_DEBUG_LOG, "opening a file with flag %x\n", mode); ret = HgfsFileOpen(sip, vp, mode, HGFS_VP_TO_PERMISSIONS(vp), openType); break; default: DEBUG(VM_DEBUG_FAIL, "HgfsOpen: unrecognized file of type %d.\n", HGFS_VP_TO_VTYPE(vp)); ret = EINVAL; break; } DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsLookupInt -- * * Looks in the provided directory for the specified filename. If we cannot * determine the vnode locally (i.e, the vnode is not the root vnode of the * filesystem provided by dvp or in our hashtable), we send a getattr * request to the server and allocate a vnode and internal filesystem state * for this file. * * Results: * Returns zero on success and ENOENT if the file cannot be found * If file is found, a vnode representing the file is returned in vpp. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsLookupInt(struct vnode *dvp, // IN : directory vnode struct vnode **vpp, // OUT: ptr to vnode if it exists struct componentname *cnp) // IN : pathname to component { HgfsAttrV2 attrV2; HgfsSuperInfo *sip; char *path = NULL; int ret = 0; int len = 0; ASSERT(dvp); ASSERT(vpp); ASSERT(cnp); DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s, %.*s).\n", HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp), (int)cnp->cn_namelen, cnp->cn_nameptr); if (cnp->cn_flags & ISDOTDOT) { HgfsFile *fp = HGFS_VP_TO_FP(dvp); ASSERT(fp); if (fp->parent == NULL) { return EIO; // dvp is root directory } else { #if defined __FreeBSD__ vref(fp->parent); #else vnode_get(fp->parent); #endif *vpp = fp->parent; return 0; } } if (cnp->cn_namelen == 1 && *cnp->cn_nameptr == '.') { #if defined __FreeBSD__ vref(dvp); #else vnode_get(dvp); #endif *vpp = dvp; return 0; } /* * Get pointer to the superinfo. If the device is not attached, * hgfsInstance will not be valid and we immediately return an error. */ sip = HGFS_VP_TO_SIP(dvp); if (!sip) { DEBUG(VM_DEBUG_FAIL, "couldn't acquire superinfo.\n"); return ENOTSUP; } /* Snag a pathname buffer */ path = os_malloc(MAXPATHLEN, M_WAITOK); if (!path) { return ENOMEM; } /* Construct the full path for this lookup. */ len = HgfsMakeFullName(HGFS_VP_TO_FILENAME(dvp), // Path to this file HGFS_VP_TO_FILENAME_LENGTH(dvp), // Length of path cnp->cn_nameptr, // File's name cnp->cn_namelen, // Filename length path, // Destination buffer MAXPATHLEN); // Size of dest buffer if (len < 0) { DEBUG(VM_DEBUG_FAIL, "LookupInt length is less than zero\n"); ret = EINVAL; goto out; } DEBUG(VM_DEBUG_LOAD, "full path is \"%s\"\n", path); /* See if the lookup is really for the root vnode. */ if (strcmp(path, "/") == 0) { DEBUG(VM_DEBUG_INFO, "returning the root vnode.\n"); *vpp = sip->rootVnode; /* * If we are returning the root vnode, then we need to get a reference * to it. Under Mac OS this gets an I/O Count. */ HGFS_VPP_GET_IOCOUNT(vpp); goto out; }; /* Send a Getattr request to the Hgfs server. */ ret = HgfsDoGetattrByName(path, sip, &attrV2); /* * If this is the final pathname component & the user is attempt a CREATE * or RENAME, just return without a leaf vnode. (This differs from * Solaris where ENOENT would be returned in all cases.) */ if (ret == ENOENT) { if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) && cnp->cn_flags & ISLASTCN) { ret = EJUSTRETURN; DEBUG(VM_DEBUG_FAIL, "GetattrByName error %d for \"%s\".\n", ret, path); goto out; } } /* Got an error from HgfsDoGetattrByName, return it to the caller. */ if (ret) { DEBUG(VM_DEBUG_FAIL, "GetattrByName error %d for \"%s\".\n", ret, path); goto out; } ret = HgfsVnodeGet(vpp, // Location to write vnode's address dvp, // Parent vnode sip, // Superinfo HGFS_VP_TO_MP(dvp), // VFS for our filesystem path, // Full name of the file attrV2.type, // Type of file &sip->fileHashTable, // File hash table FALSE, // Not a new file creation 0, // No permissions - not a new file attrV2.size); // File size if (ret) { DEBUG(VM_DEBUG_FAIL, "couldn't create vnode for \"%s\".\n", path); goto out; } /* * Either we will have a cache hit or called HgfsVnodeGet. Both of these * paths guarantees that *vpp will be set to a vnode. */ ASSERT(*vpp); DEBUG(VM_DEBUG_LOAD, "assigned vnode %p to %s\n", *vpp, path); ret = 0; /* Return success */ out: if (path != NULL) { os_free(path, MAXPATHLEN); } DEBUG(VM_DEBUG_EXIT, "Exit(%.*s, %.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp), (int)cnp->cn_namelen, cnp->cn_nameptr, ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsCreateInt -- * * Called by either HgfsVnopCreate under Mac OS or HgfsVopCreate under * FreeBSD when the user is trying to create a file by calling open() with * the O_CREAT flag specified. * * The kernel calls the open entry point which calls (HgfsOpenInt()) after * calling this function, so here all we do is consruct the vnode and * save the filename and permission bits for the file to be created within * our filesystem internal state. * * Results: * Returns zero on success and an appropriate error code on error. * * Side effects: * If the file doesn't exist, a vnode will be created. * *---------------------------------------------------------------------------- */ int HgfsCreateInt(struct vnode *dvp, // IN : Directory vnode struct vnode **vpp, // OUT: Pointer to new vnode struct componentname *cnp, // IN : Location to create new vnode int mode) // IN : Mode of vnode being created. { HgfsSuperInfo *sip = HGFS_VP_TO_SIP(dvp); char *fullname = NULL; // allocated from M_TEMP; free when done. int ret = 0; DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s/%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp), (int)cnp->cn_namelen, cnp->cn_nameptr); if (*vpp != NULL) { DEBUG(VM_DEBUG_FAIL, "vpp (%p) not null\n", vpp); ret = EEXIST; goto out; } /* If we have gotten to this point then we know that we need to create a * new vnode. The actual file will be created on the HGFS server in the * HgfsOpenInt call should happen right after this call. */ fullname = os_malloc(MAXPATHLEN, M_WAITOK); if (!fullname) { ret = ENOMEM; goto out; } ret = HgfsMakeFullName(HGFS_VP_TO_FILENAME(dvp), // Name of directory to create in HGFS_VP_TO_FILENAME_LENGTH(dvp), // Length of name cnp->cn_nameptr, // Name of file to create cnp->cn_namelen, // Length of new filename fullname, // Buffer to write full name MAXPATHLEN); // Size of this buffer if (ret >= 0) { /* Create the vnode for this file. */ ret = HgfsVnodeGet(vpp, dvp, sip, HGFS_VP_TO_MP(dvp), fullname, HGFS_FILE_TYPE_REGULAR, &sip->fileHashTable, TRUE, mode, 0); /* HgfsVnodeGet() guarantees this. */ ASSERT(ret != 0 || *vpp); /* * NOTE: This is a temporary workaround. * This condition may occur because we look up vnodes by file name in the * vnode cache. * There is a race condition when file is already deleted but still referenced - * thus vnode still exist. If a new file with the same name is created I * can neither use the vnode of the deleted file nor insert a new vnode with * the same name - thus I fail the request. This behavior is not correct and will * be fixed after further restructuring if the source code. */ if (ret == EEXIST) { ret = EIO; } } else { DEBUG(VM_DEBUG_FAIL, "couldn't create full path name.\n"); ret = ENAMETOOLONG; } out: if (fullname != NULL) { os_free(fullname, MAXPATHLEN); } DEBUG(VM_DEBUG_EXIT, "Exit(%.*s/%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp), (int)cnp->cn_namelen, cnp->cn_nameptr, ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsReadInt -- * * Called by HgfsVnopRead under Mac OS or HgfsVopRead under FreeBSD to read * a file. * * We call HgfsDoRead() to fill the user's buffer until the request is met * or the file has no more data. This is done since we can only transfer * HGFS_IO_MAX bytes in any one request. * * "Reads the range supplied for the given vnode. vop_read() typically * maps the requested range of a file into kernel memory and then uses * vop_getpage() to do the real work." (Solaris Internals, p537) * * Results: * Returns zero on success and an error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsReadInt(struct vnode *vp, // IN : Vnode to read from struct uio *uiop, // IN/OUT: Buffer to write data into. Bool pagingIo) // IN: True if the read is a result of a page fault { HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp); HgfsHandle handle; uint64_t offset; int ret; DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp)); /* We can't read from directories, that's what readdir() is for. */ if (HGFS_VP_TO_VTYPE(vp) != VREG) { DEBUG(VM_DEBUG_FAIL, "Can only read regular files.\n"); ret = (HGFS_VP_TO_VTYPE(vp) == VDIR) ? EISDIR : EPERM; DEBUG(VM_DEBUG_FAIL, "Read not a reg file type %d ret %d.\n", HGFS_VP_TO_VTYPE(vp), ret); return ret; } /* off_t is a signed quantity */ if (HGFS_UIOP_TO_OFFSET(uiop) < 0) { DEBUG(VM_DEBUG_FAIL, "given negative offset.\n"); return EINVAL; } /* This is where the user wants to start reading from in the file. */ offset = HGFS_UIOP_TO_OFFSET(uiop); /* * We need to get the handle for the requests sent to the Hgfs server. Note * that this is guaranteed to not change until a close(2) is called on this * vnode, so it's safe and correct to acquire it outside the loop below. */ ret = HgfsGetOpenFileHandle(vp, &handle); if (ret) { DEBUG(VM_DEBUG_FAIL, "could not get handle.\n"); return EINVAL; } /* Flush mmaped data to maintain data coherence between mmap and read. */ if (!pagingIo) { ret = os_FlushRange(vp, offset, HGFS_UIOP_TO_RESID(uiop)); if (ret) { DEBUG(VM_DEBUG_FAIL, "could not flush data.\n"); return EINVAL; } } /* * Here we loop around HgfsDoRead with requests less than or equal to * HGFS_IO_MAX until one of the following conditions is met: * (1) All the requested data has been read * (2) The file has no more data * (3) An error occurred * * Since HgfsDoRead() calls uiomove(9), we know condition (1) is met when * the uio structure's uio_resid is decremented to zero. If HgfsDoRead() * returns 0 we know condition (2) was met, and if it returns less than 0 we * know condtion (3) was met. */ do { uint32_t size; /* Request at most HGFS_IO_MAX bytes */ size = (HGFS_UIOP_TO_RESID(uiop) > HGFS_IO_MAX) ? HGFS_IO_MAX : HGFS_UIOP_TO_RESID(uiop); DEBUG(VM_DEBUG_INFO, "offset=%"FMT64"d, uio_offset=%"FMT64"d\n", offset, HGFS_UIOP_TO_OFFSET(uiop)); DEBUG(VM_DEBUG_HANDLE, "** handle=%d, file=%s to read %u\n", handle, HGFS_VP_TO_FILENAME(vp), size); if (size == 0) { /* For a zero byte length read we return success. */ DEBUG(VM_DEBUG_EXIT, "size of 0 ret -> 0.\n"); return 0; } /* Send one read request. */ ret = HgfsDoRead(sip, handle, offset, size, uiop); if (ret == 0) { /* On end of file we return success */ DEBUG(VM_DEBUG_EXIT, "end of file reached.\n"); return 0; } else if (ret == -EBADF) { // Stale host handle ret = HgfsRefreshHandle(vp, sip, &handle); if (ret == 0) { ret = HgfsDoRead(sip, handle, offset, size, uiop); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "Failed to read from a fresh handle.\n"); return -ret; } } else { DEBUG(VM_DEBUG_FAIL, "Failed to get a fresh handle.\n"); return EBADF; } } else if (ret < 0) { /* * HgfsDoRead() returns the negative of an appropriate error code to * differentiate between success and error cases. We flip the sign * and return the appropriate error code. See the HgfsDoRead() * function header for a fuller explanation. */ DEBUG(VM_DEBUG_FAIL, "HgfsDoRead() failed, error %d.\n", ret); return -ret; } /* Bump the offset past where we have already read. */ offset += ret; } while (HGFS_UIOP_TO_RESID(uiop)); /* We fulfilled the user's read request, so return success. */ DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> 0)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp)); return 0; } /* *---------------------------------------------------------------------------- * * HgfsWriteInt -- * * Called by HgfsVnopWrite under Mac OS or HgfsVopWrite under FreeBSD. * * We call HgfsDoWrite() once with requests less than or equal to * HGFS_IO_MAX bytes until the user's write request has completed. * * Results: * Returns 0 on success and error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsWriteInt(struct vnode *vp, // IN : the vnode of the file struct uio *uiop, // IN/OUT: location of data to be written int ioflag, // IN : hints & other directives Bool pagingIo) // IN: True if the write is originated by memory manager { HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp); HgfsHandle handle; uint64_t offset; int ret = 0; int error = 0; DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp)); /* Skip write requests for 0 bytes. */ if (HGFS_UIOP_TO_RESID(uiop) == 0) { DEBUG(VM_DEBUG_INFO, "write of 0 bytes requested.\n"); error = 0; goto out; } DEBUG(VM_DEBUG_INFO, "file is %s\n", HGFS_VP_TO_FILENAME(vp)); /* Off_t is a signed type. */ if (HGFS_UIOP_TO_OFFSET(uiop) < 0) { DEBUG(VM_DEBUG_FAIL, "given negative offset.\n"); error = EINVAL; goto out; } /* This is where the user will begin writing into the file. */ offset = HGFS_UIOP_TO_OFFSET(uiop); /* Get the handle we need to supply the Hgfs server. */ ret = HgfsGetOpenFileHandle(vp, &handle); if (ret) { DEBUG(VM_DEBUG_FAIL, "could not get handle.\n"); error = EINVAL; goto out; } /* Flush mmaped data to maintain data coherence between mmap and read. */ if (!pagingIo && (ioflag & IO_APPEND) == 0) { ret = os_FlushRange(vp, offset, HGFS_UIOP_TO_RESID(uiop)); } /* * We loop around calls to HgfsDoWrite() until either (1) we have written all * of our data or (2) an error has occurred. HGFS_UIOP_TO_RESID(uiop) is decremented * by uiomove(9F) inside HgfsDoWrite(), so condition (1) is met when it * reaches zero. Condition (2) occurs when HgfsDoWrite() returns less than * zero. */ do { uint32_t size; DEBUG(VM_DEBUG_INFO, "** offset=%"FMT64"d, uio_offset=%"FMT64"d\n", offset, HGFS_UIOP_TO_OFFSET(uiop)); DEBUG(VM_DEBUG_HANDLE, "** handle=%d, file=%s\n", handle, HGFS_VP_TO_FILENAME(vp)); /* Write at most HGFS_IO_MAX bytes. */ size = (HGFS_UIOP_TO_RESID(uiop) > HGFS_IO_MAX) ? HGFS_IO_MAX : HGFS_UIOP_TO_RESID(uiop); /* Send one write request. */ ret = HgfsDoWrite(sip, handle, ioflag, offset, size, uiop); if (ret == -EBADF) { // Stale host handle ret = HgfsRefreshHandle(vp, sip, &handle); if (ret == 0) { ret = HgfsDoWrite(sip, handle, ioflag, offset, size, uiop); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "Failed to write to a fresh handle.\n"); error = -ret; break; } } else { DEBUG(VM_DEBUG_FAIL, "Failed to get a fresh handle, error %d.\n", ret); error = EBADF; break; } } else if (ret < 0) { /* * As in HgfsRead(), we need to flip the sign. See the comment in the * function header of HgfsDoWrite() for a more complete explanation. */ DEBUG(VM_DEBUG_INFO, "HgfsDoWrite failed, returning %d\n", -ret); error = -ret; break; } /* Increment the offest by the amount already written. */ offset += ret; } while (HGFS_UIOP_TO_RESID(uiop)); /* Need to notify memory manager if written data extended the file. */ if (!pagingIo && (offset > HGFS_VP_TO_FILESIZE(vp))) { if ((ioflag & IO_APPEND) == 0) { os_SetSize(vp, offset); } else { off_t oldSize = HGFS_VP_TO_FILESIZE(vp); off_t writtenData = offset - HGFS_UIOP_TO_OFFSET(uiop); os_SetSize(vp, oldSize + writtenData); } } out: /* We have completed the user's write request, so return. */ DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), error); return error; } /* *---------------------------------------------------------------------------- * * HgfsMkdirInt -- * * Makes a directory named dirname in the directory specified by the dvp * vnode by sending a CREATE_DIR request, then allocates a vnode for this * new directory and writes its address into vpp. * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * If successful, a directory is created on the host's filesystem. * *---------------------------------------------------------------------------- */ int HgfsMkdirInt(struct vnode *dvp, // IN : directory vnode struct vnode **vpp, // OUT: pointer to new directory vnode struct componentname *cnp, // IN : pathname to component int mode) // IN : mode to create dir { HgfsSuperInfo *sip = HGFS_VP_TO_SIP(dvp); HgfsKReqHandle req; HgfsRequest *requestHeader; HgfsRequestCreateDirV3 *request; HgfsReplyCreateDirV3 *reply; uint32 reqSize; uint32 repSize; uint32 reqBufferSize; char *fullName = NULL; // allocated from M_TEMP; free when done. uint32 fullNameLen; int ret; DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s/%.*s,%d)\n", HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp), (int)cnp->cn_namelen, cnp->cn_nameptr, mode); /* * We need to construct the full path of the directory to create then send * a CREATE_DIR request. If successful we will create a vnode and fill in * vpp with a pointer to it. * * Note that unlike in HgfsCreate(), *vpp is always NULL. */ /* Construct the complete path of the directory to create. */ fullName = os_malloc(MAXPATHLEN, M_WAITOK); if (!fullName) { ret = ENOMEM; goto out; } ret = HgfsMakeFullName(HGFS_VP_TO_FILENAME(dvp), // Parent directory HGFS_VP_TO_FILENAME_LENGTH(dvp), // Length of name cnp->cn_nameptr, // Name of file to create cnp->cn_namelen, // Length of filename fullName, // Buffer to write full name MAXPATHLEN); // Size of this buffer if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "couldn't create full path name.\n"); ret = ENAMETOOLONG; goto out; } fullNameLen = ret; req = HgfsKReq_AllocateRequest(sip->reqs, &ret); if (!req) { goto out; } /* Initialize the request's contents. */ requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req); request = (HgfsRequestCreateDirV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader); HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_CREATE_DIR_V3); request->fileAttr = 0; request->mask = HGFS_CREATE_DIR_MASK; request->specialPerms = (mode & (S_ISUID | S_ISGID | S_ISVTX)) >> HGFS_ATTR_SPECIAL_PERM_SHIFT; request->ownerPerms = (mode & S_IRWXU) >> HGFS_ATTR_OWNER_PERM_SHIFT; request->groupPerms = (mode & S_IRWXG) >> HGFS_ATTR_GROUP_PERM_SHIFT; request->otherPerms = mode & S_IRWXO; request->fileName.flags = 0; request->fileName.fid = HGFS_INVALID_HANDLE; request->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); reqBufferSize = HGFS_NAME_BUFFER_SIZET(HGFS_PACKET_MAX, reqSize); /* * Convert an input string to utf8 precomposed form, convert it to * the cross platform name format and finally unescape any illegal * filesystem characters. */ ret = HgfsNameToWireEncoding(fullName, fullNameLen + 1, request->fileName.name, reqBufferSize); if (ret < 0) { DEBUG(VM_DEBUG_FAIL,"Could not encode to wire format"); ret = -ret; goto destroyOut; } request->fileName.length = ret; reqSize += ret; /* Set the size of this request. */ HgfsKReq_SetPayloadSize(req, reqSize); /* Send the request to guestd. */ ret = HgfsSubmitRequest(sip, req); if (ret) { /* Request is destroyed in HgfsSubmitRequest() if necessary. */ goto out; } repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply); ret = HgfsGetStatus(req, repSize); if (ret) { DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret); goto destroyOut; } ret = HgfsVnodeGet(vpp, dvp, sip, HGFS_VP_TO_MP(dvp), fullName, HGFS_FILE_TYPE_DIRECTORY, &sip->fileHashTable, TRUE, mode, 0); if (ret) { ret = EIO; DEBUG(VM_DEBUG_FAIL, "Error encountered creating vnode ret = %d\n", ret); goto destroyOut; } ASSERT(*vpp); ret = 0; destroyOut: HgfsKReq_ReleaseRequest(sip->reqs, req); out: if (fullName != NULL) { os_free(fullName, MAXPATHLEN); } DEBUG(VM_DEBUG_EXIT, "Exit(%.*s/%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp), (int)cnp->cn_namelen, cnp->cn_nameptr, ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsDirOpen -- * * Invoked when HgfsOpen() is called with a vnode of type VDIR. * * Sends a SEARCH_OPEN request to the Hgfs server. * * Results: * Returns zero on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsDirOpen(HgfsSuperInfo *sip, // IN: Superinfo pointer struct vnode *vp, // IN: Vnode of directory to open HgfsOpenType openType) // IN: type of VNOP_OPEN. { char *fullPath; uint32 fullPathLen; int ret; HgfsFile *fp; HgfsHandle handle; ASSERT(sip); ASSERT(vp); fp = HGFS_VP_TO_FP(vp); ASSERT(fp); DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s,%d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), openType); /* * If the directory is already opened then we are done. * There is no different open modes for directories thus the handle is compatible. */ os_rw_lock_lock_exclusive(fp->handleLock); ret = HgfsCheckAndReferenceHandle(vp, 0, openType); if (ret == ENOENT) { // Handle is not set, need to get one from the host if (HGFS_IS_ROOT_VNODE(sip, vp)) { fullPath = ""; fullPathLen = 0; } else { fullPath = HGFS_VP_TO_FILENAME(vp); fullPathLen = HGFS_VP_TO_FILENAME_LENGTH(vp); } ret = HgfsSendOpenDirRequest(sip, fullPath, fullPathLen, &handle); if (ret == 0) { /* * We successfully received a reply, so we need to save the handle in * this file's HgfsOpenFile and return success. */ HgfsSetOpenFileHandle(vp, handle, HGFS_OPEN_MODE_READ_ONLY, openType); } } os_rw_lock_unlock_exclusive(fp->handleLock); DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsRequestHostFileHandle -- * * Sends a open request to the server to get a file handle. * If client needs a readonly handle the function first asks for * read-write handle since this handle may be shared between multiple * file descriptors. If getting read-write handle fails the function * sends another request for readonly handle. * * Results: * Returns zero on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsRequestHostFileHandle(HgfsSuperInfo *sip, // IN: Superinfo pointer struct vnode *vp, // IN: Vnode of file to open int *openMode, // IN OUT: open mode int openFlags, // IN: flags for the open request int permissions, // IN: Permissions for new files HgfsHandle *handle) // OUT: file handle { char *fullPath; uint32 fullPathLen; int ret; fullPath = HGFS_VP_TO_FILENAME(vp); fullPathLen = HGFS_VP_TO_FILENAME_LENGTH(vp); DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s, %d, %d, %o)\n", fullPathLen, fullPath, *openMode, openFlags, permissions); /* First see if we can get the most permissive read/write open mode */ ret = HgfsSendOpenRequest(sip, HGFS_OPEN_MODE_READ_WRITE, openFlags, permissions, fullPath, fullPathLen, handle); if (ret) { DEBUG(VM_DEBUG_FAIL, "Open failed %d, re-submitting original mode = %d.\n", ret, *openMode); if (ret == EACCES && HGFS_OPEN_MODE_READ_WRITE != *openMode) { /* * Failed to open in read/write open mode because of denied access. * It means file's permissions do not allow opening for read/write. * However caller does not need this mode and may be satisfied with * less permissive mode. * Try exact open mode now. */ DEBUG(VM_DEBUG_FAIL, "RW mode failed, re-submitting original mode = %d.\n", *openMode); ret = HgfsSendOpenRequest(sip, *openMode, openFlags, permissions, fullPath, fullPathLen, handle); } } else { *openMode = HGFS_OPEN_MODE_READ_WRITE; } DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", fullPathLen, fullPath, ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsFileOpen -- * * Invoked when HgfsOpen() is called with a vnode of type VREG. Sends * a OPEN request to the Hgfs server. * * Note that this function doesn't need to handle creations since the * HgfsCreate() entry point is called by the kernel for that. * * Results: * Returns zero on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsFileOpen(HgfsSuperInfo *sip, // IN: Superinfo pointer struct vnode *vp, // IN: Vnode of file to open int flag, // IN: Flags of open int permissions, // IN: Permissions of open (only when creating) HgfsOpenType openType) // IN: initiator type for the open { int ret; int openMode; int openFlags; HgfsHandle handle; HgfsFile *fp; ASSERT(sip); ASSERT(vp); fp = HGFS_VP_TO_FP(vp); ASSERT(fp); DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s,%d,%d,%o)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), flag, openType, permissions); /* * Check if the user is trying to create a new share. This check was * mainly implemented to address the issue with Mac OS. When the user * attempts to create a file in the root folder, the server returns ENOENT * error code. However, Mac OS specifically checks for this case. If Mac OS asks for * the creation of a new file and if it gets ENOENT as a return error code, * then it assumes that the error was because of some race condition and tries it * again. Thus, returning ENOENT to the Mac OS puts the guest kernel into infinite * loop. In order to resolve this issue, before passing on the request to the * server, we validate if user is attempting to create a new share. If yes, * we return EACCES as the error code. */ if (HgfsAttemptToCreateShare(HGFS_VP_TO_FILENAME(vp), flag)) { DEBUG (VM_DEBUG_LOG, "An attempt to create a new share was made.\n"); ret = EACCES; goto out; } /* Convert FreeBSD modes to Hgfs modes */ openMode = HgfsGetOpenMode((uint32_t)flag); if (openMode < 0) { DEBUG(VM_DEBUG_FAIL, "HgfsGetOpenMode failed.\n"); ret = EINVAL; goto out; } DEBUG(VM_DEBUG_COMM, "open mode is %x\n", openMode); /* Convert FreeBSD flags to Hgfs flags */ openFlags = HgfsGetOpenFlags((uint32_t)flag); if (openFlags < 0) { DEBUG(VM_DEBUG_FAIL, "HgfsGetOpenFlags failed.\n"); ret = EINVAL; goto out; } os_rw_lock_lock_exclusive(fp->handleLock); /* * If the file is already opened, verify that it is opened in a compatible mode. * If it is true then add reference to vnode and grant the access, otherwise * deny the access. */ ret = HgfsCheckAndReferenceHandle(vp, openMode, openType); if (ret == ENOENT) { // Handle is not set, need to get one from the host ret = HgfsRequestHostFileHandle(sip, vp, &openMode, openFlags, permissions, &handle); /* * We successfully received a reply, so we need to save the handle in * this file's HgfsOpenFile and return success. */ if (ret == 0) { HgfsSetOpenFileHandle(vp, handle, openMode, openType); } } os_rw_lock_unlock_exclusive(fp->handleLock); out: DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsRefreshHandle -- * * Request a new HgfsHandle for the vnode. Needed when original handle * become stale because HGFS has been disabled and re-enabled or VM * has been suspened and then resumed. * * Results: * Returns zero on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsRefreshHandle(struct vnode *vp, // IN: Vnode of file to open HgfsSuperInfo *sip, // IN: Superinfo pointer HgfsHandle *handle) // IN OUT: Pointer to the stale handle { int ret = 0; HgfsFile *fp; ASSERT(vp); fp = HGFS_VP_TO_FP(vp); ASSERT(fp); DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp)); os_rw_lock_lock_exclusive(fp->handleLock); if (fp->handle != *handle) { /* Handle has been refreshed in another thread. */ *handle = fp->handle; } else { /* Retrieve a new handle from the host. */ if (HGFS_VP_TO_VTYPE(vp) == VREG) { ret = HgfsRequestHostFileHandle(sip, vp, (int *)&fp->mode, HGFS_OPEN, 0, handle); } else if (HGFS_VP_TO_VTYPE(vp) == VDIR) { char *fullPath = HGFS_VP_TO_FILENAME(vp); uint32 fullPathLen = HGFS_VP_TO_FILENAME_LENGTH(vp); ret = HgfsSendOpenDirRequest(sip, fullPath, fullPathLen, handle); } else { goto out; } if (ret == 0) { fp->handle = *handle; } } out: os_rw_lock_unlock_exclusive(fp->handleLock); DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsDirClose -- * * Invoked when HgfsClose() is called with a vnode of type VDIR. * * Sends an SEARCH_CLOSE request to the Hgfs server. * * Results: * Returns zero on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsDirClose(HgfsSuperInfo *sip, // IN: Superinfo pointer struct vnode *vp) // IN: Vnode of directory to close { int ret = 0; HgfsHandle handleToClose; ASSERT(sip); ASSERT(vp); DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp)); /* * Check to see if we should close the file handle on the host ( which happen when * the reference count of the current handle become 0. */ if (HgfsReleaseOpenFileHandle(vp, OPENREQ_OPEN, &handleToClose) == 0) { ret = HgfsCloseServerDirHandle(sip, handleToClose); } DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsFileClose -- * * Invoked when HgfsClose() is called with a vnode of type VREG. * * Sends a CLOSE request to the Hgfs server. * * Results: * Returns zero on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsFileClose(HgfsSuperInfo *sip, // IN: Superinfo pointer struct vnode *vp, // IN: Vnode of file to close int flags) // IN: The mode flags for the close { int ret = 0; HgfsHandle handleToClose; ASSERT(sip); ASSERT(vp); DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s,%d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), flags); /* * Check to see if we should close the file handle on the host ( which happen when * the reference count of the current handle become 0. */ if (HgfsReleaseOpenFileHandle(vp, OPENREQ_OPEN, &handleToClose) == 0) { ret = HgfsCloseServerFileHandle(sip, handleToClose); } DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsDoRead -- * * Sends a single READ request to the Hgfs server and writes the contents * into the user's buffer if successful. * * This function is called repeatedly by HgfsRead() with requests of size * less than or equal to HGFS_IO_MAX. * * Note that we return the negative of an appropriate error code in this * function so we can differentiate between success and failure. On success * we need to return the number of bytes read, but FreeBSD's error codes are * positive so we negate them before returning. If callers want to return * these error codes to the Kernel, they will need to flip their sign. * * Results: * Returns number of bytes read on success and a negative value on error. * * Side effects: * On success, size bytes are written into the user's buffer. * *---------------------------------------------------------------------------- */ int HgfsDoRead(HgfsSuperInfo *sip, // IN: Superinfo pointer HgfsHandle handle, // IN: Server's handle to read from uint64_t offset, // IN: File offset to read at uint32_t size, // IN: Number of bytes to read struct uio *uiop) // IN: Defines user's read request { HgfsKReqHandle req; HgfsRequest *requestHeader; HgfsReply *replyHeader; HgfsRequestReadV3 *request; HgfsReplyReadV3 *reply; uint32 reqSize; int ret; ASSERT(sip); ASSERT(uiop); ASSERT(size <= HGFS_IO_MAX); // HgfsRead() should guarantee this DEBUG(VM_DEBUG_ENTRY, "Enter(%u,%"FMT64"u,%u)\n", handle, offset, size); req = HgfsKReq_AllocateRequest(sip->reqs, &ret); if (!req) { ret = -ret; goto out; } requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req); request = (HgfsRequestReadV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader); HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_READ_V3); /* Indicate which file, where in the file, and how much to read. */ request->file = handle; request->offset = offset; request->requiredSize = size; request->reserved = 0; reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); HgfsKReq_SetPayloadSize(req, reqSize); ret = HgfsSubmitRequest(sip, req); if (ret) { /* * We need to flip the sign of the return value to indicate error; see * the comment in the function header. HgfsSubmitRequest() handles * destroying the request if necessary, so we don't here. */ DEBUG(VM_DEBUG_FAIL, " hgfssubmitrequest failed\n"); ret = -ret; goto out; } replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req); reply = (HgfsReplyReadV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader); ret = HgfsGetStatus(req, sizeof *replyHeader); if (ret) { DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret); if (ret != EPROTO && ret != EBADF) { ret = EACCES; } ret = -ret; goto destroyOut; } /* * Now perform checks on the actualSize. There are three cases: * o actualSize is less than or equal to size, which indicates success * o actualSize is zero, which indicates the end of the file (and success) * o actualSize is greater than size, which indicates a server error */ if (reply->actualSize <= size) { /* If we didn't get any data, we don't need to copy to the user. */ if (reply->actualSize == 0) { goto success; } /* Perform the copy to the user */ ret = uiomove(reply->payload, reply->actualSize, uiop); if (ret) { ret = -EIO; goto destroyOut; } /* We successfully copied the payload to the user's buffer */ goto success; } else { /* We got too much data: server error. */ DEBUG(VM_DEBUG_FAIL, "received too much data in payload.\n"); ret = -EPROTO; goto destroyOut; } success: ret = reply->actualSize; destroyOut: HgfsKReq_ReleaseRequest(sip->reqs, req); out: DEBUG(VM_DEBUG_EXIT, "Exit(%u -> %d)\n", handle, ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsDoWrite -- * * Sends a single WRITE request to the Hgfs server with the contents of * the user's buffer. * * This function is called repeatedly by HgfsWrite() with requests of size * less than or equal to HGFS_IO_MAX. * * Note that we return the negative of an appropriate error code in this * function so we can differentiate between success and failure. On success * we need to return the number of bytes written, but FreeBSD's error codes are * positive so we negate them before returning. If callers want to return * these error codes to the kernel, they will need to flip their sign. * * Results: * Returns number of bytes written on success and a negative value on error. * * Side effects: * On success, size bytes are written to the file specified by the handle. * *---------------------------------------------------------------------------- */ int HgfsDoWrite(HgfsSuperInfo *sip, // IN: Superinfo pointer HgfsHandle handle, // IN: Handle representing file to write to int ioflag, // IN: Flags for write uint64_t offset, // IN: Where in the file to begin writing uint32_t size, // IN: How much data to write struct uio *uiop) // IN: Describes user's write request { HgfsKReqHandle req; HgfsRequest *requestHeader; HgfsReply *replyHeader; HgfsRequestWriteV3 *request; HgfsReplyWriteV3 *reply; uint32 reqSize; uint32 repSize; int ret; ASSERT(sip); ASSERT(uiop); ASSERT(size <= HGFS_IO_MAX); // HgfsWrite() guarantees this DEBUG(VM_DEBUG_ENTRY, "Enter(%u,%d,%"FMT64"u,%u)\n", handle, ioflag, offset, size); req = HgfsKReq_AllocateRequest(sip->reqs, &ret); if (!req) { ret = -ret; goto out; } requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req); request = (HgfsRequestWriteV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader); HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_WRITE_V3); request->file = handle; request->flags = 0; request->offset = offset; request->requiredSize = size; request->reserved = 0; reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); if (ioflag & IO_APPEND) { DEBUG(VM_DEBUG_COMM, "writing in append mode.\n"); request->flags |= HGFS_WRITE_APPEND; } DEBUG(VM_DEBUG_COMM, "requesting write of %d bytes.\n", size); /* Copy the data the user wants to write into the payload. */ ret = uiomove(request->payload, request->requiredSize, uiop); if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsDoWrite: uiomove(9F) failed copying data from user.\n"); ret = -EIO; goto destroyOut; } /* We subtract one so request's 'char payload[1]' member isn't double counted. */ HgfsKReq_SetPayloadSize(req, reqSize + request->requiredSize - 1); ret = HgfsSubmitRequest(sip, req); if (ret) { /* * As in HgfsDoRead(), we need to flip the sign of the error code * returned by HgfsSubmitRequest(). */ DEBUG(VM_DEBUG_FAIL, "HgfsSubmitRequest failed.\n"); ret = -ret; goto out; } replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req); ret = HgfsGetStatus(req, sizeof *replyHeader); if (ret) { DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret); if (ret != EPROTO && ret != EBADF) { ret = EACCES; } ret = -ret; goto destroyOut; } repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply); if (HgfsKReq_GetPayloadSize(req) != repSize) { DEBUG(VM_DEBUG_FAIL, "Error: invalid size of reply on successful reply.\n"); ret = -EPROTO; goto destroyOut; } reply = (HgfsReplyWriteV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader); /* The write was completed successfully, so return the amount written. */ ret = reply->actualSize; destroyOut: HgfsKReq_ReleaseRequest(sip->reqs, req); out: DEBUG(VM_DEBUG_EXIT, "Exit(%u -> %d)\n", handle, ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsDelete -- * * Sends a request to delete a file or directory. * * Results: * Returns 0 on success or an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsDelete(HgfsSuperInfo *sip, // IN: Superinfo const char *filename, // IN: Full name of file to remove HgfsOp op) // IN: Hgfs operation this delete is for { HgfsKReqHandle req; HgfsRequest *requestHeader; HgfsReply *replyHeader; HgfsRequestDeleteV3 *request; HgfsReplyDeleteV3 *reply; uint32 reqSize; uint32 repSize; uint32 reqBufferSize; int ret; ASSERT(sip); ASSERT(filename); ASSERT((op == HGFS_OP_DELETE_FILE_V3) || (op == HGFS_OP_DELETE_DIR_V3)); DEBUG(VM_DEBUG_ENTRY, "Enter(%s,%d)\n", filename, op); req = HgfsKReq_AllocateRequest(sip->reqs, &ret); if (!req) { goto out; } /* Initialize the request's contents. */ requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req); request = (HgfsRequestDeleteV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader); HGFS_INIT_REQUEST_HDR(requestHeader, req, op); request->hints = 0; request->fileName.fid = HGFS_INVALID_HANDLE; request->fileName.flags = 0; request->fileName.caseType = HGFS_FILE_NAME_DEFAULT_CASE; request->reserved = 0; reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); reqBufferSize = HGFS_NAME_BUFFER_SIZET(HGFS_PACKET_MAX, reqSize); /* * Convert an input string to utf8 precomposed form, convert it to * the cross platform name format and finally unescape any illegal * filesystem characters. */ ret = HgfsNameToWireEncoding(filename, strlen(filename) + 1, request->fileName.name, reqBufferSize); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "Could not encode to wire format"); ret = -ret; goto destroyOut; } request->fileName.length = ret; reqSize += ret; /* Set the size of our request. */ HgfsKReq_SetPayloadSize(req, reqSize); DEBUG(VM_DEBUG_COMM, "deleting \"%s\"\n", filename); /* Submit our request to guestd. */ ret = HgfsSubmitRequest(sip, req); if (ret) { /* HgfsSubmitRequest() handles destroying the request if necessary. */ goto out; } replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req); repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply); ret = HgfsGetStatus(req, repSize); if (ret) { DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret); goto destroyOut; } destroyOut: HgfsKReq_ReleaseRequest(sip->reqs, req); out: DEBUG(VM_DEBUG_EXIT, "Exit(%s -> %d)\n", filename, ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsGetNextDirEntry -- * * Writes the name of the directory entry matching the handle and offset to * nameOut. Also records the entry's type (file, directory) in type. This * requires sending a SEARCH_READ request. * * Results: * Returns zero on success and an error code on error. The done value is * set if there are no more directory entries. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsGetNextDirEntry(HgfsSuperInfo *sip, // IN: Superinfo pointer HgfsHandle handle, // IN: Handle for request uint32_t offset, // IN: Offset char *nameOut, // OUT: Location to write name size_t nameSize, // IN : Size of nameOut HgfsFileType *type, // OUT: Entry's type Bool *done) // OUT: Whether there are any more { HgfsKReqHandle req; HgfsRequest *requestHeader; HgfsReply *replyHeader; HgfsRequestSearchReadV3 *request; HgfsReplySearchReadV3 *reply; HgfsDirEntry *dirent; uint32 reqSize; uint32 repSize; int ret; DEBUG(VM_DEBUG_ENTRY, "Enter(%u,%u)\n", handle, offset); ASSERT(sip); ASSERT(nameOut); ASSERT(done); req = HgfsKReq_AllocateRequest(sip->reqs, &ret); if (!req) { DEBUG(VM_DEBUG_FAIL, "couldn't get req.\n"); goto out; } /* * Fill out the search read request that will return a single directory * entry for the provided handle at the given offset. */ requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req); request = (HgfsRequestSearchReadV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader); HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_SEARCH_READ_V3); request->search = handle; request->offset = offset; request->flags = 0; request->reserved = 0; reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); HgfsKReq_SetPayloadSize(req, reqSize); ret = HgfsSubmitRequest(sip, req); if (ret) { /* HgfsSubmitRequest will destroy the request if necessary. */ DEBUG(VM_DEBUG_FAIL, "HgfsSubmitRequest failed.\n"); goto out; } replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req); ret = HgfsGetStatus(req, sizeof *replyHeader); if (ret) { DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret); goto destroyOut; } DEBUG(VM_DEBUG_COMM, "received reply for ID %d\n", replyHeader->id); DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n", replyHeader->status); reply = (HgfsReplySearchReadV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader); reply->count = 1; repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply) + sizeof *dirent; dirent = (HgfsDirEntry *)reply->payload; /* Make sure we got an entire reply (excluding filename) */ if (HgfsKReq_GetPayloadSize(req) < repSize) { DEBUG(VM_DEBUG_FAIL, "server didn't provide entire reply.\n"); ret = EFAULT; goto destroyOut; } /* See if there are no more filenames to read */ if (dirent->fileName.length <= 0) { DEBUG(VM_DEBUG_LOG, "no more directory entries.\n"); *done = TRUE; ret = 0; /* return success */ goto destroyOut; } /* Make sure filename isn't too long */ if ((dirent->fileName.length >= nameSize) || (dirent->fileName.length > HGFS_PAYLOAD_MAX(repSize)) ) { DEBUG(VM_DEBUG_FAIL, "filename is too long.\n"); ret = EOVERFLOW; goto destroyOut; } /* * Everything is all right, copy filename to caller's buffer. Note that even though * the hgfs SearchRead reply holds lots of information about the file's attributes, * FreeBSD directory entries do not currently need any of that information except the * file type. */ memcpy(nameOut, dirent->fileName.name, dirent->fileName.length); nameOut[dirent->fileName.length] = '\0'; *type = dirent->attr.type; ret = 0; destroyOut: HgfsKReq_ReleaseRequest(sip->reqs, req); out: DEBUG(VM_DEBUG_EXIT, "Exit(%u -> %d)\n", handle, ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsReadlinkInt -- * * Reads a symbolic link target. * * Results: * Either 0 on success or a BSD error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsReadlinkInt(struct vnode *vp, // IN : File vnode struct uio *uiop) // OUT: Attributes from hgfs server { HgfsKReqHandle req = NULL; int ret = 0; HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp); HgfsReplyGetattrV3 *reply; HgfsReply *replyHeader; uint32 outLength; char* outBuffer = NULL; DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp)); /* This operation is valid only for symbolic links. */ if (HGFS_VP_TO_VTYPE(vp) != VLNK) { DEBUG(VM_DEBUG_FAIL, "Must be a symbolic link.\n"); ret = EINVAL; goto out; } req = HgfsKReq_AllocateRequest(sip->reqs, &ret); if (!req) { goto out; } ret = HgfsQueryAttrInt(HGFS_VP_TO_FILENAME(vp), 0, sip, req); if (ret != 0) { DEBUG(VM_DEBUG_FAIL, "Error %d reading symlink name.\n", ret); goto out; } outLength = HGFS_UIOP_TO_RESID(uiop); outBuffer = os_malloc(outLength, M_WAITOK); if (outBuffer != NULL) { DEBUG(VM_DEBUG_FAIL, "No memory for symlink name.\n"); ret = ENOMEM; goto out; } replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req); reply = (HgfsReplyGetattrV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader); if (reply->symlinkTarget.name[reply->symlinkTarget.length - 1] == '\0') { ret = EINVAL; // Not a well formed name goto out; } ret = HgfsNameFromWireEncoding(reply->symlinkTarget.name, reply->symlinkTarget.length, outBuffer, outLength); if (ret < 0) { ret = -ret; // HgfsNameFromWireEncoding returns negative error code DEBUG(VM_DEBUG_FAIL, "Error converting link wire format length is %d, name is %s\n", reply->symlinkTarget.length, reply->symlinkTarget.name); goto out; } ret = uiomove(outBuffer, MIN(ret, outLength), uiop); if (ret != 0) { DEBUG(VM_DEBUG_FAIL, "Failed %d copying into user buffer.\n", ret); } out: if (outBuffer != NULL) { os_free(outBuffer, outLength); } if (req != NULL) { HgfsKReq_ReleaseRequest(sip->reqs, req); } DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsSymlnikInt -- * * Creates symbolic link on the host. * * Results: * Either 0 on success or a BSD error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsSymlinkInt(struct vnode *dvp, // IN : directory vnode struct vnode **vpp, // OUT: pointer to new symlink vnode struct componentname *cnp, // IN : pathname to component char *targetName) // IN : Symbolic link target { HgfsSuperInfo *sip = HGFS_VP_TO_SIP(dvp); HgfsKReqHandle req = NULL; HgfsRequest *requestHeader; HgfsReply *replyHeader; HgfsRequestSymlinkCreateV3 *request; HgfsReplySymlinkCreateV3 *reply; uint32 reqSize; uint32 repSize; uint32 reqBufferSize; int ret; char *fullName = NULL; uint32 fullNameLen; HgfsFileNameV3 *fileNameP; int nameOffset; DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s/%.*s,%s)\n", HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp), (int)cnp->cn_namelen, cnp->cn_nameptr, targetName); fullName = os_malloc(MAXPATHLEN, M_WAITOK); if (!fullName) { ret = ENOMEM; goto out; } req = HgfsKReq_AllocateRequest(sip->reqs, &ret); if (!req) { goto out; } ret = HgfsMakeFullName(HGFS_VP_TO_FILENAME(dvp), // Parent directory HGFS_VP_TO_FILENAME_LENGTH(dvp), // Length of name cnp->cn_nameptr, // Name of file to create cnp->cn_namelen, // Length of filename fullName, // Buffer to write full name MAXPATHLEN); // Size of this buffer if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "couldn't create full path name.\n"); ret = ENAMETOOLONG; goto out; } fullNameLen = ret; /* Initialize the request's contents. */ requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req); request = (HgfsRequestSymlinkCreateV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader); HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_CREATE_SYMLINK_V3); request->reserved = 0; request->symlinkName.flags = 0; request->symlinkName.fid = HGFS_INVALID_HANDLE; request->symlinkName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); reqBufferSize = HGFS_NAME_BUFFER_SIZET(HGFS_PACKET_MAX, reqSize); /* * Convert an input string to utf8 precomposed form, convert it to * the cross platform name format and finally unescape any illegal * filesystem characters. */ ret = HgfsNameToWireEncoding(fullName, fullNameLen + 1, request->symlinkName.name, reqBufferSize); if (ret < 0) { DEBUG(VM_DEBUG_FAIL,"Could not encode file name to wire format"); ret = -ret; goto out; } request->symlinkName.length = ret; reqSize += ret; fileNameP = (HgfsFileNameV3 *)((char*)&request->symlinkName + sizeof request->symlinkName + request->symlinkName.length); fileNameP->flags = 0; fileNameP->fid = HGFS_INVALID_HANDLE; fileNameP->caseType = HGFS_FILE_NAME_CASE_SENSITIVE; /* * Currently we have different name formats for file names and for symbolic * link targets. Flie names are always absolute and on-wire representation does * not include leading path separator. HgfsNameToWireEncoding removes * leading path separator from the name. However symbolic link targets may be * either absolute or relative. To distinguish between them the leading path separator * must be preserved for absolute symbolic link target. * In the long term we should fix the protocol and have only one name * format which is suitable for all names. * The following code compensates for this problem before there is such * universal name representation. */ if (*targetName == '/') { fileNameP->length = 1; reqSize += 1; *fileNameP->name = '\0'; targetName++; } else { fileNameP->length = 0; } /* * Convert symbolic link target to utf8 precomposed form, convert it to * the cross platform name format and finally unescape any illegal * filesystem characters. */ nameOffset = fileNameP->name - (char*)requestHeader; ret = HgfsNameToWireEncoding(targetName, strlen(targetName) + 1, fileNameP->name + fileNameP->length, HGFS_PACKET_MAX - nameOffset - fileNameP->length); if (ret < 0) { DEBUG(VM_DEBUG_FAIL,"Could not encode file name to wire format"); ret = -ret; goto out; } fileNameP->length += ret; reqSize += ret; /* Set the size of this request. */ HgfsKReq_SetPayloadSize(req, reqSize); ret = HgfsSubmitRequest(sip, req); if (ret) { /* Request is destroyed in HgfsSubmitRequest() if necessary. */ req = NULL; goto out; } replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req); reply = (HgfsReplySymlinkCreateV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader); repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply); ret = HgfsGetStatus(req, repSize); if (ret == 0) { ret = HgfsVnodeGet(vpp, dvp, sip, HGFS_VP_TO_MP(dvp), fullName, HGFS_FILE_TYPE_SYMLINK, &sip->fileHashTable, TRUE, 0, 0); if (ret) { ret = EIO; } } else { DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret); } ASSERT(ret != 0 || *vpp != NULL); out: if (req) { HgfsKReq_ReleaseRequest(sip->reqs, req); } if (fullName != NULL) { os_free(fullName, MAXPATHLEN); } DEBUG(VM_DEBUG_EXIT, "Exit(%.*s/%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp), (int)cnp->cn_namelen, cnp->cn_nameptr, ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsDoGetattrByName -- * * Send a name getattr request to the hgfs server and put the result in * hgfsAttr. * * Results: * Either 0 on success or a BSD error code on failure. The hgfsAttr field * is only filled out on success. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsDoGetattrByName(const char *path, // IN : Path to get attributes for HgfsSuperInfo *sip, // IN : SuperInfo block of hgfs mount. HgfsAttrV2 *hgfsAttrV2) // OUT: Attributes from hgfs server { int ret; DEBUG(VM_DEBUG_ENTRY, "Enter(%s)\n", path); ret = HgfsDoGetattrInt(path, 0, sip, hgfsAttrV2); DEBUG(VM_DEBUG_EXIT, "Exit(%s -> %d)\n", path, ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsDoGetattrByName -- * * Send a handle getattr request to the hgfs server and put the result in * hgfsAttr. * * Results: * Either 0 on success or a BSD error code on failure. The hgfsAttr field * is only filled out on success. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #if 0 static int HgfsDoGetattrByHandle(HgfsHandle handle, // IN : Hgfs handle for attr request HgfsSuperInfo *sip, // IN : SuperInfo block for hgfs mount HgfsAttrV2 *hgfsAttrV2) // OUT: Attributes from hgfs server { int ret; DEBUG(VM_DEBUG_ENTRY, "Enter(%u)\n", handle); ret = HgfsDoGetattrInt(NULL, handle, sip, hgfsAttrV2); DEBUG(VM_DEBUG_EXIT, "Exit(%u -> %d)\n", handle, ret); } #endif /* *---------------------------------------------------------------------------- * * HgfsDoGetattrInt -- * * Internal function that actually sends a getattr request to the hgfs * server and puts the results in hgfsAttrV2. This function should only * be called by HgfsDoGetattrByName or HgfsDoGetattrByHandle and will do * a getattr by filename if path is non-NULL. Otherwise it does a getattr by * handle. * * * Results: * Either 0 on success or a BSD error code on failure. The hgfsAttr field * is only filled out on success. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsDoGetattrInt(const char *path, // IN : Path to get attributes for HgfsHandle handle, // IN : Handle to get attribues for HgfsSuperInfo *sip, // IN : SuperInfo block for hgfs mount HgfsAttrV2 *hgfsAttrV2) // OUT: Attributes from hgfs server { HgfsKReqHandle req; int ret = 0; DEBUG(VM_DEBUG_ENTRY, "Enter(%s,%u)\n", (path != NULL ? path : "null"), handle); ASSERT(hgfsAttrV2); req = HgfsKReq_AllocateRequest(sip->reqs, &ret); if (!req) { return ret; } ret = HgfsQueryAttrInt(path, handle, sip, req); if (ret == 0) { HgfsReplyGetattrV3 *reply; HgfsReply *replyHeader; replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req); reply = (HgfsReplyGetattrV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader); /* Fill out hgfsAttrV2 with the results from the server. */ memcpy(hgfsAttrV2, &reply->attr, sizeof *hgfsAttrV2); HgfsKReq_ReleaseRequest(sip->reqs, req); } DEBUG(VM_DEBUG_EXIT, "Exit(%s,%u -> %d)\n", (path != NULL ? path : "null"), handle, ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsQueryAttrInt -- * * Internal function that actually sends a getattr request to the hgfs * server and puts the results in hgfsAttrV2. This function does * a getattr by filename if path is non-NULL. Otherwise it does a getattr by * handle. * * * Results: * Either 0 on success or a BSD error code on failure. When function * succeeds a valid hgfs request is returned and it must be de-allocaed * by the caller. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsQueryAttrInt(const char *path, // IN : Path to get attributes for HgfsHandle handle, // IN : Handle to get attribues for HgfsSuperInfo *sip, // IN : SuperInfo block for hgfs mount HgfsKReqHandle req) // IN/OUT: preacllocated hgfs request { HgfsRequest *requestHeader; HgfsReply *replyHeader; HgfsRequestGetattrV3 *request; HgfsReplyGetattrV3 *reply; uint32 reqSize; uint32 repSize; uint32 reqBufferSize; int ret = 0; DEBUG(VM_DEBUG_ENTRY, "Enter(%s,%u)\n", (path != NULL ? path : "null"), handle); requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req); request = (HgfsRequestGetattrV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader); HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_GETATTR_V3); request->reserved = 0; reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); reqBufferSize = HGFS_NAME_BUFFER_SIZET(HGFS_PACKET_MAX, reqSize); /* * Per the calling conventions of this function, if the path is NULL then * this is a Getattr by handle. */ if (path == NULL) { request->hints = HGFS_ATTR_HINT_USE_FILE_DESC; request->fileName.fid = handle; request->fileName.flags = HGFS_FILE_NAME_USE_FILE_DESC; request->fileName.caseType = HGFS_FILE_NAME_DEFAULT_CASE; request->fileName.length = 0; } else { /* Do a Getattr by path. */ request->hints = 0; request->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; request->fileName.fid = HGFS_INVALID_HANDLE; request->fileName.flags = 0; /* * Convert an input string to utf8 precomposed form, convert it to * the cross platform name format and finally unescape any illegal * filesystem characters. */ ret = HgfsNameToWireEncoding(path, strlen(path) + 1, request->fileName.name, reqBufferSize); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "Could not encode to wire format"); ret = -ret; goto destroyOut; } request->fileName.length = ret; reqSize += ret; } /* Packet size includes the header, request and its payload. */ HgfsKReq_SetPayloadSize(req, reqSize); DEBUG(VM_DEBUG_COMM, "sending getattr request for ID %d\n", requestHeader->id); DEBUG(VM_DEBUG_COMM, " fileName.length: %d\n", request->fileName.length); DEBUG(VM_DEBUG_COMM, " fileName.name: \"%s\"\n", request->fileName.name); /* * Submit the request and wait for the reply. HgfsSubmitRequest handles * destroying the request on both error and interrupt cases. */ ret = HgfsSubmitRequest(sip, req); if (ret) { /* HgfsSubmitRequest destroys the request if necessary */ goto out; } replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req); ret = HgfsGetStatus(req, sizeof *replyHeader); if (ret) { if (ret == EPROTO) { DEBUG(VM_DEBUG_FAIL, "Error encountered for ID = %d\n" "with status %d.\n", replyHeader->id, replyHeader->status); } goto destroyOut; } reply = (HgfsReplyGetattrV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader); DEBUG(VM_DEBUG_COMM, "received reply for ID %d\n", replyHeader->id); DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n", replyHeader->status); DEBUG(VM_DEBUG_COMM, " file type: %d\n", reply->attr.type); DEBUG(VM_DEBUG_COMM, " file size: %llu\n", (long long unsigned)reply->attr.size); DEBUG(VM_DEBUG_COMM, " permissions: %o\n", reply->attr.ownerPerms); DEBUG(VM_DEBUG_COMM, " permissions: %o\n", reply->attr.groupPerms); DEBUG(VM_DEBUG_COMM, " permissions: %o\n", reply->attr.otherPerms); DEBUG(VM_DEBUG_COMM, " hostFileId: %llu\n", (long long unsigned)reply->attr.hostFileId); repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply) + reply->symlinkTarget.length; /* The GetAttr succeeded, ensure packet contains correct amount of data. */ if (HgfsKReq_GetPayloadSize(req) != repSize) { DEBUG(VM_DEBUG_COMM, "HgfsLookup: invalid packet size received for \"%s\".\n", path); ret = EFAULT; goto destroyOut; } destroyOut: if (ret != 0) { HgfsKReq_ReleaseRequest(sip->reqs, req); } out: DEBUG(VM_DEBUG_EXIT, "Exit(%s,%u -> %d)\n", (path != NULL ? path : "null"), handle, ret); return ret; } /* *---------------------------------------------------------------------------- * * IsModeCompatible -- * * Checks if the requested mode is compatible with permissions. * * Results: * Returns TRUE if the mode is compatible, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static Bool IsModeCompatible(HgfsAccessMode mode, // IN: Requested open mode uint32 permissions) // IN: Effective user permissions { if ((permissions & HGFS_PERM_READ) == 0) { if ((mode & (HGFS_MODE_GENERIC_READ | HGFS_MODE_READ_DATA | HGFS_MODE_LIST_DIRECTORY | HGFS_MODE_READ_ATTRIBUTES | HGFS_MODE_READ_EXTATTRIBUTES | HGFS_MODE_READ_SECURITY)) != 0) { return FALSE; } } if ((permissions & HGFS_PERM_WRITE) == 0) { if ((mode & (HGFS_MODE_GENERIC_WRITE | HGFS_MODE_WRITE_DATA | HGFS_MODE_APPEND_DATA | HGFS_MODE_DELETE | HGFS_MODE_ADD_SUBDIRECTORY | HGFS_MODE_DELETE_CHILD | HGFS_MODE_WRITE_ATTRIBUTES | HGFS_MODE_WRITE_EXTATTRIBUTES | HGFS_MODE_WRITE_SECURITY | HGFS_MODE_TAKE_OWNERSHIP | HGFS_MODE_ADD_FILE)) != 0) { return FALSE; } } if ((permissions & HGFS_PERM_EXEC) == 0) { if ((mode & (HGFS_MODE_GENERIC_EXECUTE | HGFS_MODE_TRAVERSE_DIRECTORY)) != 0) { return FALSE; } } return TRUE; } /* *---------------------------------------------------------------------------- * * HgfsAccessInt -- * * Check to ensure the user has the specified type of access to the file. * * Results: * Returns 0 if access is allowed and a non-zero error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsAccessInt(struct vnode *vp, // IN: Vnode to check access for HgfsAccessMode mode) // IN: Access mode requested. { int ret = 0; HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp); HgfsAttrV2 hgfsAttrV2; DEBUG(VM_DEBUG_ENTRY, "HgfsAccessInt(%.*s,%d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), mode); ret = HgfsDoGetattrByName(HGFS_VP_TO_FILENAME(vp), sip, &hgfsAttrV2); if (ret == 0) { uint32 effectivePermissions; if (hgfsAttrV2.mask & HGFS_ATTR_VALID_EFFECTIVE_PERMS) { effectivePermissions = hgfsAttrV2.effectivePerms; } else { /* * If the server did not return actual effective permissions then * need to calculate ourselves. However we should avoid unnecessary denial of * access so perform optimistic permissions calculation. * It is safe since host enforces necessary restrictions regardless of * the client's decisions. */ effectivePermissions = hgfsAttrV2.ownerPerms | hgfsAttrV2.groupPerms | hgfsAttrV2.otherPerms; } if (!IsModeCompatible(mode, effectivePermissions)) { ret = EACCES; DEBUG(VM_DEBUG_FAIL, "HgfsAccessInt denied access: %s (%d, %d)\n", HGFS_VP_TO_FILENAME(vp), mode, effectivePermissions); } } else { DEBUG(VM_DEBUG_FAIL, "HgfsAccessInt failed getting attrib: %s (%d)\n", HGFS_VP_TO_FILENAME(vp), ret); } DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsMmapInt -- * * HgfsMmapInt is invoked invoked from HgfsVnopMmap to verify parameters * and mark vnode as mmapped if necessary. * * Results: * Zero on success or non-zero error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsMmapInt(struct vnode *vp, int accessMode) { int ret; HgfsFile *fp; ASSERT(vp); fp = HGFS_VP_TO_FP(vp); ASSERT(fp); DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s,%d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), accessMode); /* * If the directory is already opened then we are done. * There is no different open modes for directories thus the handle is compatible. */ os_rw_lock_lock_exclusive(fp->handleLock); ret = HgfsCheckAndReferenceHandle(vp, accessMode, OPENREQ_MMAP); os_rw_lock_unlock_exclusive(fp->handleLock); DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d).\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), ret); return ret; } /* *---------------------------------------------------------------------------- * * HgfsMnomapInt -- * * HgfsMnomapInt is invoked invoked from HgfsVnopNomap to tear down memory * mapping and dereference file handle. * * Results: * Zero on success or non-zero error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsMnomapInt(struct vnode *vp) { int ret = 0; HgfsHandle handleToClose; HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp); ASSERT(vp); DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp)); /* * Check to see if we should close the file handle on the host, which happen when * the reference count of the current handle become 0. */ if (HgfsReleaseOpenFileHandle(vp, OPENREQ_MMAP, &handleToClose) == 0) { ret = HgfsCloseServerFileHandle(sip, handleToClose); } DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d).\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), ret); return ret; } open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/vfsopscommon.h0000644765153500003110000000264512220061556022724 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vfsopscommon.h -- * * Common VFS vfsop implementations that are shared between both Mac OS and FreeBSD. */ #ifndef _HGFS_VFSOPS_COMMON_H_ #define _HGFS_VFSOPS_COMMON_H_ #include #include /* * Macros */ #define HGFS_CONVERT_TO_BLOCKS(bytes) (bytes / HGFS_BLOCKSIZE) #define HGFS_IS_POWER_OF_TWO(val) (val && !(val & (val - 1))) #if defined __FreeBSD__ typedef struct statfs HgfsStatfs; #elif defined __APPLE__ typedef struct vfsstatfs HgfsStatfs; #endif int HgfsStatfsInt(struct vnode *vp, HgfsStatfs *stat); #endif // _HGFS_VFSOPS_COMMON_H_ open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/fsutil.c0000644765153500003110000007231612220061556021476 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * fsutil.c -- * * VFS helper functions that are shared between the FreeBSD and Mac OS * implementaitons of HGFS. */ #include #include #if defined __APPLE__ # include // for rindex #endif #include "fsutil.h" #include "cpName.h" #include "hgfsEscape.h" #include "cpNameLite.h" #include "os.h" #if defined __APPLE__ char *rindex(const char *ptr, int chr); #endif /* * Mac OS sets vnode attributes through the use of a VATTR_RETURN function. * FreeBSD sets vnode attributes directly in the structure. To enable a shared * implementation of HgfsAttrToBSD and HgfsSetattrCopy, we define VATTR_RETURN * for FreeBSD. */ #if defined __FreeBSD__ #define VATTR_RETURN(vn, attr, val) \ do { (vn)-> attr = (val); } while (0) #endif /* Local Function Prototypes */ /* *---------------------------------------------------------------------------- * * HgfsSubmitRequest -- * * Places a request on the queue for submission by the worker thread, * then waits for the response. * * Both submitting request and waiting for reply are in this function * because the signaling of the request list's condition variable and * waiting on the request's condition variable must be atomic. * * Results: * Returns zero on success, and an appropriate error code on error. * Note: EINTR is returned if cv_wait_sig() is interrupted. * * Side effects: * The request list's condition variable is signaled. * *---------------------------------------------------------------------------- */ int HgfsSubmitRequest(HgfsSuperInfo *sip, // IN: Superinfo containing request list, // condition variable, and mutex HgfsKReqHandle req) // IN: Request to submit { int ret = 0; ASSERT(sip); ASSERT(req); /* * The process of submitting the request involves putting it on the request * list, waking up the backdoor req thread if it is waiting for a request, * then atomically waiting for the reply. */ /* * Fail the request if a forcible unmount is in progress. */ if (HGFS_MP_IS_FORCEUNMOUNT(sip->vfsp)) { HgfsKReq_ReleaseRequest(sip->reqs, req); return EIO; } /* Submit the request & wait for a result. */ ret = HgfsKReq_SubmitRequest(req); if (ret == 0) { /* The reply should now be in HgfsKReq_GetPayload(req). */ DEBUG(VM_DEBUG_SIG, "awoken because reply received.\n"); } else { /* HgfsKReq_SubmitRequest was interrupted, so we'll abandon now. */ HgfsKReq_ReleaseRequest(sip->reqs, req); } return ret; } /* *---------------------------------------------------------------------------- * * HgfsGetStatus -- * * Gets the status of the reply packet. If the size of the reply packet * does not lie between the minimum expected size and maximum allowed packet * size, then EPROTO is returned. * * Results: * Returns zero on success, and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsGetStatus(HgfsKReqHandle req, // IN: Request that contains reply data uint32_t minSize) // IN: Minimum size expected for the reply { HgfsReply *replyHeader; size_t repSize = 0; int ret = 0; ASSERT(req); ASSERT(minSize <= HGFS_PACKET_MAX); /* we want to know if this fails */ switch (HgfsKReq_GetState(req)) { case HGFS_REQ_ERROR: DEBUG(VM_DEBUG_FAIL, "received reply with error.\n"); ret = EPROTO; break; case HGFS_REQ_COMPLETED: repSize = HgfsKReq_GetPayloadSize(req); /* * Server sets the packet size equal to size of HgfsReply when it * encounters an error. In order to return correct error code, * we should first check the status and then check if packet size * lies between minimum expected size and maximum allowed packet size. */ if (repSize >= sizeof *replyHeader) { replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req); ret = HgfsStatusToBSD(replyHeader->status); if (ret) { break; } } if (repSize < minSize || repSize > HGFS_PACKET_MAX) { DEBUG(VM_DEBUG_FAIL, "successfully " "completed reply is too small/big: !(%d < %" FMTSZ "d < %d).\n", minSize, repSize, HGFS_PACKET_MAX); ret = EPROTO; } break; /* * If we get here then there is a programming error in this module: * HGFS_REQ_UNUSED should be for requests in the free list * HGFS_REQ_SUBMITTED should be for requests only that are awaiting * a response * HGFS_REQ_ABANDONED should have returned an error to the client */ default: NOT_REACHED(); ret = EPROTO; /* avoid compiler warning */ } return ret; } /* * XXX * These were taken and slightly modified from hgfs/driver/solaris/vnode.c. * (Which, in turn, took them from hgfs/driver/linux/driver.c.) Should we * move them into a hgfs/driver/posix/driver.c? */ /* *---------------------------------------------------------------------- * * HgfsGetOpenMode -- * * Based on the flags requested by the process making the open() * syscall, determine which open mode (access type) to request from * the server. * * Results: * Returns the correct HgfsOpenMode enumeration to send to the * server, or -1 on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ int HgfsGetOpenMode(uint32 flags) // IN: Open flags { /* * Preprocessor wrapper kept for when this function is factored out * into a common file. */ #if defined _KERNEL || defined KERNEL /* * FreeBSD / Mac OS use different values from those in the linux kernel. These are defined in * . */ #undef O_RDONLY #undef O_WRONLY #undef O_RDWR #define O_RDONLY FREAD #define O_WRONLY FWRITE #define O_RDWR (FREAD | FWRITE) #endif uint32 mask = O_RDONLY | O_WRONLY | O_RDWR; int result = -1; DEBUG(VM_DEBUG_LOG, "entered\n"); /* * Mask the flags to only look at the access type. */ flags &= mask; /* Pick the correct HgfsOpenMode. */ switch (flags) { case O_RDONLY: DEBUG(VM_DEBUG_COMM, "O_RDONLY\n"); result = HGFS_OPEN_MODE_READ_ONLY; break; case O_WRONLY: DEBUG(VM_DEBUG_COMM, "O_WRONLY\n"); result = HGFS_OPEN_MODE_WRITE_ONLY; break; case O_RDWR: DEBUG(VM_DEBUG_COMM, "O_RDWR\n"); result = HGFS_OPEN_MODE_READ_WRITE; break; default: /* This should never happen. */ NOT_REACHED(); DEBUG(VM_DEBUG_LOG, "invalid open flags %o\n", flags); result = -1; break; } return result; } /* *---------------------------------------------------------------------- * * HgfsGetOpenFlags -- * * Based on the flags requested by the process making the open() * syscall, determine which flags to send to the server to open the * file. * * Results: * Returns the correct HgfsOpenFlags enumeration to send to the * server, or -1 on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ int HgfsGetOpenFlags(uint32 flags) // IN: Open flags { uint32 mask = O_CREAT | O_TRUNC | O_EXCL; int result = -1; DEBUG(VM_DEBUG_INFO, "entered\n"); /* * Mask the flags to only look at O_CREAT, O_EXCL, and O_TRUNC. */ flags &= mask; /* O_EXCL has no meaning if O_CREAT is not set. */ if (!(flags & O_CREAT)) { flags &= ~O_EXCL; } /* Pick the right HgfsOpenFlags. */ switch (flags) { case 0: /* Regular open; fails if file nonexistant. */ DEBUG(VM_DEBUG_COMM, "0\n"); result = HGFS_OPEN; break; case O_CREAT: /* Create file; if it exists already just open it. */ DEBUG(VM_DEBUG_COMM, "O_CREAT\n"); result = HGFS_OPEN_CREATE; break; case O_TRUNC: /* Truncate existing file; fails if nonexistant. */ DEBUG(VM_DEBUG_COMM, "O_TRUNC\n"); result = HGFS_OPEN_EMPTY; break; case (O_CREAT | O_EXCL): /* Create file; fail if it exists already. */ DEBUG(VM_DEBUG_COMM, "O_CREAT | O_EXCL\n"); result = HGFS_OPEN_CREATE_SAFE; break; case (O_CREAT | O_TRUNC): /* Create file; if it exists already, truncate it. */ DEBUG(VM_DEBUG_COMM, "O_CREAT | O_TRUNC\n"); result = HGFS_OPEN_CREATE_EMPTY; break; default: /* * This can only happen if all three flags are set, which * conceptually makes no sense because O_EXCL and O_TRUNC are * mutually exclusive if O_CREAT is set. * * However, the open(2) man page doesn't say you can't set all * three flags, and certain apps (*cough* Nautilus *cough*) do * so. To be friendly to those apps, we just silenty drop the * O_TRUNC flag on the assumption that it's safer to honor * O_EXCL. */ DEBUG(VM_DEBUG_INFO, "invalid open flags %o. " "Ignoring the O_TRUNC flag.\n", flags); result = HGFS_OPEN_CREATE_SAFE; break; } return result; } /* *---------------------------------------------------------------------------- * * HgfsMakeFullName -- * * Concatenates the path and filename to construct the full path. This * handles the special cases of . and .. filenames so the Hgfs server * doesn't return an error. * * Results: * Returns the length of the full path on success, and a negative value on * error. The full pathname is placed in outBuf. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsMakeFullName(const char *path, // IN: Path of directory containing file uint32_t pathLen, // IN: Length of path const char *file, // IN: Name of file size_t fileLen, // IN: Length of filename char *outBuf, // OUT: Location to write full path ssize_t bufSize) // IN: Size of the out buffer { uint32 pathSeparatorLen; ASSERT(path); ASSERT(file); ASSERT(outBuf); DEBUG(VM_DEBUG_INFO, "HgfsMakeFullName:\n" " path: \"%.*s\" (%d)\n" " file: \"%s\" (%zu)\n", pathLen, path, pathLen, file, fileLen); /* * Here there are three possibilities: * o file is ".", in which case we just place path in outBuf * o file is "..", in which case we strip the last component from path and * put that in outBuf * o for all other cases, we concatenate path, a path separator, file, and * a NUL terminator and place it in outBuf */ /* Make sure that the path and a NUL terminator will fit. */ if (bufSize < pathLen + 1) { return HGFS_ERR_INVAL; } /* * Copy path for this file into the caller's buffer. * The memset call is important here because it implicitly null terminates * outBuf so that rindex can be called in the second case below. */ memset(outBuf, 0, bufSize); memcpy(outBuf, path, pathLen); /* Handle three cases. */ if (fileLen == 1 && strncmp(file, ".", 1) == 0) { /* NUL terminate and return provided length. */ outBuf[pathLen] = '\0'; return pathLen; } else if (fileLen == 2 && strncmp(file, "..", 2) == 0) { /* * Replace the last path separator with a NUL terminator, then return the * size of the buffer. */ char *newEnd = rindex(outBuf, DIRSEPC); if (!newEnd) { /* * We should never get here since we name the root vnode "/" in * HgfsMount(). */ return HGFS_ERR_INVAL; } *newEnd = '\0'; return ((uintptr_t)newEnd - (uintptr_t)outBuf); } else { if (bufSize < pathLen + 1 + fileLen + 1) { return HGFS_ERR_INVAL; } /* * If the path consists of just a single path separator, then * do not add another path separator. This will ensure that * we have only single path separator at the beginning of the * filename. */ if (pathLen == 1 && *path == DIRSEPC) { pathSeparatorLen = 0; } else { outBuf[pathLen] = DIRSEPC; pathSeparatorLen = DIRSEPSLEN; } /* Now append the filename and NUL terminator. */ memcpy(outBuf + pathSeparatorLen + pathLen, file, fileLen); outBuf[pathLen + pathSeparatorLen + fileLen] = '\0'; return pathLen + pathSeparatorLen + fileLen; } } /* *---------------------------------------------------------------------------- * * HgfsSetattrCopy -- * * Sets the Hgfs attributes that need to be modified based on the provided * Solaris attribute structure. * * Results: * Returns TRUE if changes need to be made, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool HgfsSetattrCopy(HgfsVnodeAttr *vap, // IN: Attributes to change to HgfsAttrV2 *hgfsAttrV2, // OUT: Hgfs attributes to fill in HgfsAttrHint *hints) // OUT: Hgfs attribute hints { Bool ret = FALSE; ASSERT(vap); ASSERT(hgfsAttrV2); ASSERT(hints); memset(hgfsAttrV2, 0, sizeof *hgfsAttrV2); memset(hints, 0, sizeof *hints); /* * Hgfs supports changing these attributes: * o mode bits (permissions) * o uid/gid * o size * o access/write times */ if (HGFS_VATTR_MODE_IS_ACTIVE(vap, HGFS_VA_MODE)){ DEBUG(VM_DEBUG_COMM, "updating permissions.\n"); hgfsAttrV2->mask |= HGFS_ATTR_VALID_SPECIAL_PERMS | HGFS_ATTR_VALID_OWNER_PERMS | HGFS_ATTR_VALID_GROUP_PERMS | HGFS_ATTR_VALID_OTHER_PERMS; hgfsAttrV2->specialPerms = (vap->HGFS_VA_MODE & (S_ISUID | S_ISGID | S_ISVTX)) >> HGFS_ATTR_SPECIAL_PERM_SHIFT; hgfsAttrV2->ownerPerms = (vap->HGFS_VA_MODE & S_IRWXU) >> HGFS_ATTR_OWNER_PERM_SHIFT; hgfsAttrV2->groupPerms = (vap->HGFS_VA_MODE & S_IRWXG) >> HGFS_ATTR_GROUP_PERM_SHIFT; hgfsAttrV2->otherPerms = vap->HGFS_VA_MODE & S_IRWXO; ret = TRUE; } if (HGFS_VATTR_IS_ACTIVE(vap, HGFS_VA_UID)) { DEBUG(VM_DEBUG_COMM, "updating user id.\n"); hgfsAttrV2->mask |= HGFS_ATTR_VALID_USERID; hgfsAttrV2->userId = vap->HGFS_VA_UID; ret = TRUE; } if (HGFS_VATTR_IS_ACTIVE(vap, HGFS_VA_GID)) { DEBUG(VM_DEBUG_COMM, "updating group id.\n"); hgfsAttrV2->mask |= HGFS_ATTR_VALID_GROUPID; hgfsAttrV2->groupId = vap->HGFS_VA_GID; ret = TRUE; } if (HGFS_VATTR_IS_ACTIVE(vap, HGFS_VA_ACCESS_TIME_SEC)) { DEBUG(VM_DEBUG_COMM, "updating access time.\n"); *hints |= HGFS_ATTR_HINT_SET_ACCESS_TIME; hgfsAttrV2->mask |= HGFS_ATTR_VALID_ACCESS_TIME; hgfsAttrV2->accessTime = HGFS_GET_TIME(vap->HGFS_VA_ACCESS_TIME); ret = TRUE; } if (HGFS_VATTR_IS_ACTIVE(vap, HGFS_VA_MODIFY_TIME_SEC)) { DEBUG(VM_DEBUG_COMM, "updating write time.\n"); *hints |= HGFS_ATTR_HINT_SET_WRITE_TIME; hgfsAttrV2->mask |= HGFS_ATTR_VALID_WRITE_TIME; hgfsAttrV2->writeTime = HGFS_GET_TIME(vap->HGFS_VA_MODIFY_TIME); ret = TRUE; } if (HGFS_VATTR_SIZE_IS_ACTIVE(vap, HGFS_VA_DATA_SIZE)) { DEBUG(VM_DEBUG_COMM, "updating size.\n"); hgfsAttrV2->mask |= HGFS_ATTR_VALID_SIZE; hgfsAttrV2->size = vap->HGFS_VA_DATA_SIZE; ret = TRUE; } return ret; } /* *---------------------------------------------------------------------------- * * HgfsAttrToBSD -- * * Maps Hgfs attributes to Mac OS/BSD attributes, filling the provided BSD * attribute structure appropriately. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsAttrToBSD(struct vnode *vp, // IN: The vnode for this file const HgfsAttrV2 *hgfsAttrV2, // IN: Hgfs attributes to copy HgfsVnodeAttr *vap) // OUT: BSD attributes to fill { short mode = 0; HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp); ASSERT(vp); ASSERT(hgfsAttrV2); ASSERT(vap); /* XXX Update this function to support all V2 attributes. */ DEBUG(VM_DEBUG_ENTRY, "%p -> %p\n", hgfsAttrV2, vap); /* * Initialize all fields to zero. We don't need to do this for Mac OS * because the VATTR_RETURN macros take care of it for us. */ #if defined __FreeBSD__ VATTR_NULL(vap); #endif if ((hgfsAttrV2->mask & HGFS_ATTR_VALID_TYPE)) { /* Set the file type. */ switch (hgfsAttrV2->type) { case HGFS_FILE_TYPE_REGULAR: HGFS_VATTR_TYPE_RETURN(vap, VREG); DEBUG(VM_DEBUG_ATTR, " Type: VREG\n"); break; case HGFS_FILE_TYPE_DIRECTORY: HGFS_VATTR_TYPE_RETURN(vap, VDIR); DEBUG(VM_DEBUG_ATTR, " Type: VDIR\n"); break; case HGFS_FILE_TYPE_SYMLINK: HGFS_VATTR_TYPE_RETURN(vap, VLNK); DEBUG(VM_DEBUG_ATTR, " Type: VLNK\n"); break; default: /* * There are only the above three filetypes. If there is an error * elsewhere that provides another value, we set the Solaris type to * none and ASSERT in devel builds. */ HGFS_VATTR_TYPE_RETURN(vap, VNON); DEBUG(VM_DEBUG_FAIL, "invalid HgfsFileType provided.\n"); } } else { HGFS_VATTR_TYPE_RETURN(vap, VNON); DEBUG(VM_DEBUG_FAIL, "invalid HgfsFileType provided\n"); } if (hgfsAttrV2->mask & HGFS_ATTR_VALID_SPECIAL_PERMS) { mode |= hgfsAttrV2->specialPerms << HGFS_ATTR_SPECIAL_PERM_SHIFT; } if (hgfsAttrV2->mask & HGFS_ATTR_VALID_OWNER_PERMS) { mode |= hgfsAttrV2->ownerPerms << HGFS_ATTR_OWNER_PERM_SHIFT; } if (hgfsAttrV2->mask & HGFS_ATTR_VALID_GROUP_PERMS) { mode |= hgfsAttrV2->groupPerms << HGFS_ATTR_GROUP_PERM_SHIFT; } if (hgfsAttrV2->mask & HGFS_ATTR_VALID_OWNER_PERMS) { mode |= hgfsAttrV2->otherPerms; } HGFS_VATTR_MODE_RETURN(vap, mode); HGFS_VATTR_NLINK_RETURN(vap, 1); /* fake */ if (sip->uidSet || (hgfsAttrV2->mask & HGFS_ATTR_VALID_USERID) == 0) { HGFS_VATTR_UID_RETURN(vap, sip->uid); } else { HGFS_VATTR_UID_RETURN(vap, hgfsAttrV2->userId); } if (sip->gidSet || (hgfsAttrV2->mask & HGFS_ATTR_VALID_GROUPID) == 0) { HGFS_VATTR_GID_RETURN(vap, sip->gid); } else { HGFS_VATTR_GID_RETURN(vap, hgfsAttrV2->groupId); } HGFS_VATTR_FSID_RETURN(vap, HGFS_VP_TO_STATFS(vp)->f_fsid.val[0]); /* Get the node id calculated for this file in HgfsVnodeGet() */ HGFS_VATTR_FILEID_RETURN(vap, HGFS_VP_TO_NODEID(vp)); HGFS_VATTR_BLOCKSIZE_RETURN(vap, HGFS_BLOCKSIZE); if (hgfsAttrV2->mask & HGFS_ATTR_VALID_SIZE) { HGFS_VATTR_BYTES_RETURN(vap, hgfsAttrV2->size); HGFS_VATTR_SIZE_RETURN(vap, hgfsAttrV2->size); } /* * HGFS_SET_TIME does not mark the attribute as supported (unlike * VATTR_RETURN on Mac OS) so we have to do it explicitly with calls to * VATTR_SET_SUPPORTED. For FreeBSD, HGFS_VATTR_*_SET_SUPPORTED is just a NULL * macro. */ if (hgfsAttrV2->mask & HGFS_ATTR_VALID_ACCESS_TIME) { HGFS_SET_TIME(vap->HGFS_VA_ACCESS_TIME, hgfsAttrV2->accessTime); HGFS_VATTR_ACCESS_TIME_SET_SUPPORTED(vap); } if (hgfsAttrV2->mask & HGFS_ATTR_VALID_WRITE_TIME) { HGFS_SET_TIME(vap->HGFS_VA_MODIFY_TIME, hgfsAttrV2->writeTime); HGFS_VATTR_MODIFY_TIME_SET_SUPPORTED(vap); } if (hgfsAttrV2->mask & HGFS_ATTR_VALID_CHANGE_TIME) { HGFS_SET_TIME(vap->HGFS_VA_CHANGE_TIME, hgfsAttrV2->attrChangeTime); HGFS_VATTR_CHANGE_TIME_SET_SUPPORTED(vap); } if (hgfsAttrV2->mask & HGFS_ATTR_VALID_CREATE_TIME) { /* Since Windows doesn't keep ctime, we may need to use mtime instead. */ HGFS_SET_TIME(vap->HGFS_VA_CREATE_TIME, hgfsAttrV2->creationTime); HGFS_VATTR_CREATE_TIME_SET_SUPPORTED(vap); } else if (hgfsAttrV2->mask & HGFS_ATTR_VALID_WRITE_TIME) { DEBUG(VM_DEBUG_ATTR, "Set create time from write time\n"); vap->HGFS_VA_CREATE_TIME = vap->HGFS_VA_MODIFY_TIME; HGFS_VATTR_CREATE_TIME_SET_SUPPORTED(vap); } else { DEBUG(VM_DEBUG_ATTR, "Do not set create time\n"); } DEBUG(VM_DEBUG_ATTR, "Attrib mask %"FMT64"d\n", hgfsAttrV2->mask); #if defined __APPLE__ DEBUG(VM_DEBUG_ATTR, "Supported %lld, active %lld\n", vap->va_supported, vap->va_active); #endif HgfsDebugPrintVattr(vap); } /* *----------------------------------------------------------------------------- * * HgfsStatusToBSD -- * * Convert a cross-platform HGFS status code to its Linux-kernel specific * counterpart. * * Results: * Zero if the converted status code represents success, negative error * otherwise. Unknown status codes are converted to the more generic * "protocol error" status code to maintain forwards compatibility. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int HgfsStatusToBSD(HgfsStatus hgfsStatus) // IN: Hgfs status msg to be converted { switch (hgfsStatus) { case HGFS_STATUS_SUCCESS: return 0; case HGFS_STATUS_NO_SUCH_FILE_OR_DIR: case HGFS_STATUS_INVALID_NAME: return ENOENT; case HGFS_STATUS_INVALID_HANDLE: return EBADF; case HGFS_STATUS_OPERATION_NOT_PERMITTED: return EPERM; case HGFS_STATUS_FILE_EXISTS: return EEXIST; case HGFS_STATUS_NOT_DIRECTORY: return ENOTDIR; case HGFS_STATUS_DIR_NOT_EMPTY: return ENOTEMPTY; case HGFS_STATUS_PROTOCOL_ERROR: return EPROTO; case HGFS_STATUS_ACCESS_DENIED: case HGFS_STATUS_SHARING_VIOLATION: return EACCES; case HGFS_STATUS_NO_SPACE: return ENOSPC; case HGFS_STATUS_OPERATION_NOT_SUPPORTED: return EOPNOTSUPP; case HGFS_STATUS_NAME_TOO_LONG: return ENAMETOOLONG; case HGFS_STATUS_GENERIC_ERROR: return EIO; default: DEBUG(VM_DEBUG_LOG, "VMware hgfs: %s: unknown " "error: %u\n", __FUNCTION__, hgfsStatus); return EIO; } } /* *---------------------------------------------------------------------------- * * rindex -- * * Search a character string for the last instance of chr. This is only * implemented for Mac OS because it is not exported by the Mac OS kernel. * * Results: * Pointer to the last instance of chr in the string. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #if defined __APPLE__ char * rindex(const char *ptr, // IN: String to search. int chr) // IN: Char to look for. { char *result = NULL; ASSERT(ptr); for (; *ptr != '\0'; ptr++) { if (*ptr == chr) { result = (char *)ptr; } } return result; } #endif /* *---------------------------------------------------------------------------- * * HgfsAttemptToCreateShare -- * * Checks if an attempt to create a new share is made. * * Results: * Returns FALSE if not such attempt is made, TRUE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool HgfsAttemptToCreateShare(const char *path, // IN: Path int flag) // IN: flag { int ret = FALSE; ASSERT(path); /* * If the first character is the path seperator and * and there are no more path seperators present in the * path, then with the create flag (O_CREAT) set, we believe * that user has attempted to create new a share. This operation * is not permitted and hence EPERM error code is returned. */ if ((flag & O_CREAT) && path[0] == DIRSEPC && strchr(path + DIRSEPSLEN, DIRSEPC) == NULL) { ret = TRUE; } return ret; } /* *---------------------------------------------------------------------------- * * HgfsNameToWireEncoding -- * 1) Input string is converted into precomposed form. * 2) Precomposed string is then converted to cross platform string. * 3) Cross platform string is finally unescaped. * * Results: * Returns the size (excluding the NULL terminator) on success and * negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsNameToWireEncoding(const char *bufIn, // IN: Buffer to be normalized uint32 bufInSize, // IN: Size of input buffer char *bufOut, // OUT: Normalized string will be stored here uint32 bufOutSize) // IN: Size of output buffer { char *precomposedBuf = NULL; // allocated from M_TEMP; free when done. const char *utf8Buf; int ret = 0; if (os_utf8_conversion_needed()) { /* Allocating precomposed buffer to be equal to Output buffer. */ precomposedBuf = os_malloc(bufOutSize, M_WAITOK); if (!precomposedBuf) { return -ENOMEM; } ret = os_path_to_utf8_precomposed(bufIn, bufInSize, precomposedBuf, bufOutSize); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "os_path_to_utf8_precomposed failed."); ret = -EINVAL; goto out; } utf8Buf = precomposedBuf; } else { utf8Buf = bufIn; } ret = CPName_ConvertTo(utf8Buf, bufOutSize, bufOut); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "CPName_ConvertTo: Conversion to cross platform name failed.\n"); ret = -ENAMETOOLONG; goto out; } out: if (precomposedBuf != NULL) { os_free(precomposedBuf, bufOutSize); } return ret; } /* *---------------------------------------------------------------------------- * * HgfsNameFromWireEncoding -- * 1) Converts input from CPName form if necessary. * 2) Result is converted into decomposed form. * * Results: * Returns the size (excluding the NULL terminator) on success and * negative error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsNameFromWireEncoding(const char *bufIn, // IN: Buffer to be encoded uint32 inputLength, // IN: Number of characters in the input char *bufOut, // OUT: Encoded buffer will be stored here uint32 bufOutSize) // IN: Size of output buffer { size_t escapedLen; int ret = 0; /* Output buffer needs one additional byte for NUL terminator. */ if (inputLength >= bufOutSize) { return -ENOMEM; } escapedLen = HgfsEscape_GetSize(bufIn, inputLength); if (escapedLen != 0) { HgfsEscape_Do(bufIn, inputLength, bufOutSize, bufOut); } else { escapedLen = inputLength; memcpy(bufOut, bufIn, inputLength); } CPNameLite_ConvertFrom(bufOut, escapedLen, '/'); if (os_utf8_conversion_needed()) { size_t decomposedLen; char *decomposedBuf = NULL; /* * The decomposed form a string can be a lot bigger than the input * buffer size. We allocate a buffer equal to the output buffer. */ decomposedBuf = os_malloc(bufOutSize, M_WAITOK); if (!decomposedBuf) { DEBUG(VM_DEBUG_FAIL, "Not enough memory for decomposed buffer size %d.\n", bufOutSize); return -ENOMEM; } /* * Convert the input buffer into decomposed form. Higher layers in * Mac OS expects the name to be in decomposed form. */ ret = os_component_to_utf8_decomposed(bufOut, escapedLen, decomposedBuf, &decomposedLen, bufOutSize); /* * If the decomposed name didn't fit in the buffer or it contained * illegal utf8 characters, return back to the caller. * os_component_to_utf8_decomposed returns 0 on success or OS_ERR on failure. */ if (ret != 0){ DEBUG(VM_DEBUG_FAIL, "os_component_to_utf8_decomposed failed.\n"); ret = -EINVAL; } else { if (decomposedLen < bufOutSize) { ret = decomposedLen; memcpy(bufOut, decomposedBuf, decomposedLen + 1); } else { DEBUG(VM_DEBUG_FAIL, "Output buffer is too small.\n"); ret = -ENOMEM; } } os_free(decomposedBuf, bufOutSize); } else { ret = escapedLen; } return ret; } open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/os.c0000644765153500003110000005105712220061556020610 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * os.c -- * * FreeBSD specific implementations of the hgfs memory allocation * and thread synchronization routines. */ #if !defined _KERNEL # error "This os.c file can only be compiled for the FreeBSD kernel." #endif #include #include #include #include // for struct mtx #include #include // for uma_zone_t #include // for kthread_create() #include #include // for vnode_pager_setsize #include "vm_basic_types.h" #include "os.h" #include "debug.h" #include "channel.h" #include "compat_freebsd.h" /* * Malloc tag for statistics, debugging, etc. */ MALLOC_DEFINE(M_HGFS, HGFS_FS_NAME, HGFS_FS_NAME_LONG); /* * Since FreeBSD provides a zone allocator, just store a pointer to the FreeBSD * zone allocator. */ typedef struct os_zone_struct { struct uma_zone *umaZone; } os_zone_struct; /* *---------------------------------------------------------------------------- * * os_init -- * * Initialize the global memory allocation variables needed by other * functions in this file. Must be called before any other functions in this * file. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int os_init(void) { /* NOP */ return 0; } /* *---------------------------------------------------------------------------- * * os_cleanup -- * * Cleanup the global variables that were created in os_init. * Must be called if os_init was called. Other functions in this * file cannot be called after os_cleanup is called. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void os_cleanup(void) { /* NOP */ } /* *---------------------------------------------------------------------------- * * os_zone_create -- * * Creates a new zone (OS_ZONE_T) from which memory allocations can * be made. * * Results: * Either an uma zone or NULL (if no memory was available). * * Side effects: * None. * *---------------------------------------------------------------------------- */ OS_ZONE_T * os_zone_create(char *zoneName, // IN size_t objectSize, // IN os_zone_ctor ctor, // IN os_zone_dtor dtor, // IN os_zone_init init, // IN os_zone_finit finit, // IN int align, // IN uint32 flags) // IN { OS_ZONE_T *zone; zone = os_malloc(sizeof *zone, M_WAITOK); zone->umaZone = uma_zcreate(zoneName, objectSize, ctor, dtor, init, finit, align, flags); return zone; } /* *---------------------------------------------------------------------------- * * os_zone_destroy -- * * _destroys a zone created with os_zone_create. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void os_zone_destroy(OS_ZONE_T *zone) // IN { ASSERT(zone); uma_zdestroy(zone->umaZone); os_free(zone, sizeof *zone); } /* *---------------------------------------------------------------------------- * * os_zone_alloc -- * * Allocates an object from the specified zone and calls the the zone * initializer and constructor. * * Results: * Either an allocated and initizalized object or NULL. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void * os_zone_alloc(OS_ZONE_T *zone, // IN int flags) // IN { void *mem; HgfsTransportChannel *channel = gHgfsChannel; HgfsKReqObject *req; ASSERT(zone); ASSERT(zone->umaZone); mem = uma_zalloc(zone->umaZone, flags | M_ZERO); if (mem) { req = (HgfsKReqObject *)mem; req->channel = channel; } return mem; } /* *---------------------------------------------------------------------------- * * os_zone_free -- * * Calls the zone destructor and final initialization routine on the * specified object and then frees the object. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void os_zone_free(OS_ZONE_T *zone, // IN void *mem) // IN { ASSERT(zone); ASSERT(zone->umaZone); uma_zfree(zone->umaZone, mem); } /* *---------------------------------------------------------------------------- * * os_malloc -- * * Malloc some memory in a FreeBSD / Mac OS kernel independent manner. * This just calls the internal kernel malloc function. According to the * FreeBSD commments, if M_WAITOK is passed to the flags, malloc will never * return NULL. * * Results: * A pointer to allocated memory or NULL. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void * os_malloc(size_t size, // IN int flags) // IN { return malloc(size, M_HGFS, flags); } /* *---------------------------------------------------------------------------- * * os_free -- * * Free some memory in a FreeBSD / Mac OS kernel independent manner. * This just calls the internal kernel free function. * * Results: * None. * * Side effects: * The memory (mem) is freed. * *---------------------------------------------------------------------------- */ void os_free(void *mem, // IN size_t size) // IN { free(mem, M_HGFS); } /* *---------------------------------------------------------------------------- * * os_mutex_alloc_init -- * * Allocate and initialize a FreeBSD mutex in an OS independent way. * Mtx_name is not used on Mac OS. * * Results: * A new mtx which has been allocated and is ready for use. * * Side effects: * None. * *---------------------------------------------------------------------------- */ OS_MUTEX_T * os_mutex_alloc_init(const char *mtxName) // IN { OS_MUTEX_T *mtx; mtx = os_malloc(sizeof *mtx, M_ZERO | M_WAITOK); mtx_init(mtx, mtxName, NULL, MTX_DEF); return mtx; } /* *---------------------------------------------------------------------------- * * os_mutex_free -- * * Frees a FreeBSD mutex in an OS independent way. * * Results: * None. * * Side effects: * The mutex (mtx) is destroyed. * *---------------------------------------------------------------------------- */ void os_mutex_free(OS_MUTEX_T *mtx) // IN { mtx_destroy(mtx); os_free(mtx, sizeof *mtx); } /* *---------------------------------------------------------------------------- * * os_mutex_lock -- * * Lock a FreeBSD mutex in an OS independent way. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void os_mutex_lock(OS_MUTEX_T *mtx) // IN { mtx_lock(mtx); } /* *---------------------------------------------------------------------------- * * os_mutex_unlock -- * * Unlock a FreeBSD mutex in an OS independent way. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void os_mutex_unlock(OS_MUTEX_T *mtx) // IN { mtx_unlock(mtx); } /* *---------------------------------------------------------------------------- * * os_rw_lock_alloc_init -- * * Allocate and initialize a FreeBSD rwlock in an OS independent way. * * Results: * A new lock which has been allocated and is ready for use. * * Side effects: * None. * *---------------------------------------------------------------------------- */ OS_RWLOCK_T * os_rw_lock_alloc_init(const char *lckName) // IN { OS_RWLOCK_T *lck; lck = os_malloc(sizeof *lck, M_ZERO | M_WAITOK); sx_init(lck, lckName); return lck; } /* *---------------------------------------------------------------------------- * * os_rw_lock_free -- * * Frees a FreeBSD rwlock in an OS independent way. * * Results: * None. * * Side effects: * The rwlock (lck) is destroyed. * *---------------------------------------------------------------------------- */ void os_rw_lock_free(OS_RWLOCK_T *lck) // IN { sx_destroy(lck); os_free(lck, sizeof *lck); } /* *---------------------------------------------------------------------------- * * os_rw_lock_lock_shared -- * * Lock a FreeBSD rwlock for reads in an OS independent way. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void os_rw_lock_lock_shared(OS_RWLOCK_T *lck) // IN { sx_slock(lck); } /* *---------------------------------------------------------------------------- * * os_rw_lock_lock_exclusive -- * * Lock a FreeBSD rwlock for writes in an OS independent way. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void os_rw_lock_lock_exclusive(OS_RWLOCK_T *lck) // IN { sx_xlock(lck); } /* *---------------------------------------------------------------------------- * * os_rw_lock_unlock_shared -- * * Unlock FreeBSD rwlock in an OS independent way. Results are * undefined if the function caller has an exculsive lock on lck. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void os_rw_lock_unlock_shared(OS_RWLOCK_T *lck) // IN { sx_sunlock(lck); } /* *---------------------------------------------------------------------------- * * os_rw_lock_unlock_exclusive -- * * Unlock FreeBSD rwlock in an OS independent way. Results are * undefined if the function caller has an exculsive lock on lck. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void os_rw_lock_unlock_exclusive(OS_RWLOCK_T *lck) // IN { sx_xunlock(lck); } /* *---------------------------------------------------------------------------- * * os_cv_init -- * * Initialize a cv under FreeBSD. Under Mac OS, we are actually passed an * object address we will use in place of a cv in later functions. Here * we simply do nothing. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void os_cv_init(OS_CV_T *cv, // IN const char *name) // IN { cv_init(cv, name); } /* *---------------------------------------------------------------------------- * * os_cv_destroy -- * * Destroy a cv under FreeBSD. Under Mac OS, we are actually passed an * object address we will use in place of a cv in later functions. Here * we simply do nothing. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void os_cv_destroy(OS_CV_T *cv) // IN { cv_destroy(cv); } /* *---------------------------------------------------------------------------- * * os_cv_signal -- * * Signal a thread to wakeup in a FreeBSD/Mac OS independent way. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void os_cv_signal(OS_CV_T *cv) // IN { cv_signal(cv); } /* *---------------------------------------------------------------------------- * * os_cv_wait -- * * Have an XNU or FreeBSD kernel thread wait until the specified condition * is signaled. This function unlocks the mutex (mtx) before it goes to * sleep and reacquires it after the thread wakes up. Under FreeBSD it is a * standard condition variable. os_cv_wait will return immediately if the * thread was interrupted. It is the callers responsibility to determine * if a signal was delivered or the dependent condition actually occurred. * Under FreeBSD, it is illegal to sleep while holding a lock. Callers of * this function should not hold any locks other than the mutex (mtx) that * is passed into the function. * * Results: * Zero on success. On FreeBSD errno if interrupted. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int os_cv_wait(OS_CV_T *cv, // IN OS_MUTEX_T *mtx) // IN { return cv_wait_sig(cv, mtx); } /* *---------------------------------------------------------------------------- * * os_thread_create -- * * Create an Mac OS or FreeBSD kernel thread in an OS independent way. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int os_thread_create(void *function, // IN void *parameter, // IN const char *threadName, // IN OS_THREAD_T *newThread) // OUT { return compat_kthread_create(function, parameter, newThread, 0, 0, threadName); } /* *---------------------------------------------------------------------------- * * os_thread_join -- * * Wait until the specified kernel thread exits and then return. Mtx must * be held by the calling code and the thread (thread) is not allowed to * exit while mtx is held. This prevents (thread) from exiting before * the caller goes to sleep. * * Results: * Zero on success. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void os_thread_join(OS_THREAD_T thread, // IN OS_MUTEX_T *mtx) // IN { ASSERT(mtx); msleep(thread, mtx, PDROP, NULL, 0); } /* *---------------------------------------------------------------------------- * * os_thread_release -- * * Release the OS_THREAD_T reference that was acquired in os_thread_create. * This is a nop on FreeBSD. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void os_thread_release(OS_THREAD_T thread) // IN { /* NOP */ } /* *---------------------------------------------------------------------------- * * Hgfsthreadexit -- * * Called when a thread is exiting. ErrorCode is returned as the thread exit code * under FreeBSD and ignored under Mac OS. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void os_thread_exit(int errorCode) // IN { compat_kthread_exit(errorCode); } /* *---------------------------------------------------------------------------- * * os_add_atomic -- * * Atomically increment an integer at a given location (address) by a given * value (amount). * * Results: * The value before the addition.. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int os_add_atomic(unsigned *address, // IN int amount) // IN { return atomic_fetchadd_int(address, amount); } /* *---------------------------------------------------------------------------- * * os_utf8_conversion_needed -- * * It returns result depending upon whether a particular operating * system expects utf8 strings in a format (decomposed utf8) * different from wire format (precomposed utf8) or not. Since FreeBSD * does not expect decomposed utf8, we return FALSE. * * Results: * FALSE if conversion is not needed, TRUE if needed. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool os_utf8_conversion_needed(void) { return FALSE; } /* *---------------------------------------------------------------------------- * * os_component_to_utf8_decomposed -- * * Converts an input component into decomposed form and writes it into * output buffer. It simply returns OS_ERR for FreeBSD. * * Results: * 0 on success or OS_ERR on failure. Since this function is not * implemented, it always returns OS_ERR. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int os_component_to_utf8_decomposed(char const *bufIn, // IN uint32 bufSizeIn, // IN char *bufOut, // OUT size_t *sizeOut, // OUT uint32 bufSizeOut) // IN { NOT_IMPLEMENTED(); return OS_ERR; } /* *---------------------------------------------------------------------------- * * os_component_to_utf8_precomposed -- * * Converts an input component into precomposed form and writes it into * output buffer. It simply returns OS_ERR for FreeBSD. * * Results: * 0 on success or OS_ERR on failure. Since this function is not * implemented, it always returns OS_ERR. * * Side effects: * None. *---------------------------------------------------------------------------- */ int os_component_to_utf8_precomposed(char const *bufIn, // IN uint32 bufSizeIn, // IN char *bufOut, // OUT size_t *sizeOut, // OUT uint32 bufSizeOut) // IN { NOT_IMPLEMENTED(); return OS_ERR; } /* *---------------------------------------------------------------------------- * * os_path_to_utf8_precomposed -- * * Converts an input path into precomposed form and writes it into output * buffer. It simply returns OS_ERR for FreeBSD. * * Results: * 0 on success or OS_ERR on failure. Since this function is not * implemented, it always returns OS_ERR. * * Side effects: * None. *---------------------------------------------------------------------------- */ int os_path_to_utf8_precomposed(char const *bufIn, // IN uint32 bufSizeIn, // IN char *bufOut, // OUT uint32 bufSizeOut) // IN { NOT_IMPLEMENTED(); return OS_ERR; } /* *---------------------------------------------------------------------------- * * os_SetSize -- * * Notifies memory management system that file size has been changed. * * Results: * None. * * Side effects: * None. *---------------------------------------------------------------------------- */ void os_SetSize(struct vnode* vp, // IN: vnode which size has changed off_t newSize) // IN: new file size { vnode_pager_setsize(vp, newSize); } /* *---------------------------------------------------------------------------- * * os_FlushRange -- * * Flushes dirty pages associated with the file. * * Results: * Always retun 0 (success) for now since it is NOOP. * * Side effects: * None. *---------------------------------------------------------------------------- */ int os_FlushRange(struct vnode *vp, // IN: vnode which data needs flushing off_t start, // IN: starting offset in the file to flush uint32_t length) // IN: length of data to flush { /* * XXX: NOOP for now. This routine is needed to maintain coherence * between memory mapped data and data for read/write operations. * Will need to implement when adding support for memory mapped files to HGFS * for FreeBsd. */ return 0; } open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/vnops.c0000644765153500003110000005631112220061556021332 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vnops.c -- * * Vnode operations for FreeBSD HGFS client. */ #include // for everything #include // for struct vnode #include // for struct mount #include // for name lookup goodness #include // for string & other functions #include // for in-kernel file access flags (FREAD, etc) #include // for file flag bitmasks (S_IRWXU, etc) #include // for uiomove #include // for struct dirent #include "cpName.h" #include "hgfsUtil.h" #include "hgfs_kernel.h" #include "request.h" #include "state.h" #include "debug.h" #include "fsutil.h" #include "vnopscommon.h" /* * Local functions (prototypes) */ static vop_lookup_t HgfsVopLookup; static vop_create_t HgfsVopCreate; static vop_open_t HgfsVopOpen; static vop_close_t HgfsVopClose; static vop_access_t HgfsVopAccess; static vop_getattr_t HgfsVopGetattr; static vop_setattr_t HgfsVopSetattr; static vop_read_t HgfsVopRead; static vop_write_t HgfsVopWrite; static vop_remove_t HgfsVopRemove; static vop_rename_t HgfsVopRename; static vop_mkdir_t HgfsVopMkdir; static vop_rmdir_t HgfsVopRmdir; static vop_readdir_t HgfsVopReaddir; static vop_inactive_t HgfsVopInactive; static vop_reclaim_t HgfsVopReclaim; static vop_print_t HgfsVopPrint; static vop_readlink_t HgfsVopReadlink; static vop_symlink_t HgfsVopSymlink; /* * Global data */ /* * HGFS vnode operations vector */ struct vop_vector HgfsVnodeOps = { .vop_default = &default_vnodeops, .vop_lookup = HgfsVopLookup, .vop_create = HgfsVopCreate, .vop_open = HgfsVopOpen, .vop_close = HgfsVopClose, .vop_access = HgfsVopAccess, .vop_getattr = HgfsVopGetattr, .vop_setattr = HgfsVopSetattr, .vop_read = HgfsVopRead, .vop_write = HgfsVopWrite, .vop_remove = HgfsVopRemove, .vop_rename = HgfsVopRename, .vop_mkdir = HgfsVopMkdir, .vop_rmdir = HgfsVopRmdir, .vop_readdir = HgfsVopReaddir, .vop_inactive = HgfsVopInactive, .vop_reclaim = HgfsVopReclaim, .vop_print = HgfsVopPrint, .vop_readlink = HgfsVopReadlink, .vop_symlink = HgfsVopSymlink, }; /* * Local functions (definitions) */ /* *---------------------------------------------------------------------------- * * HgfsVopLookup -- * * Looks in the provided directory for the specified filename by calling * HgfsLookupInt. * * Results: * Returns zero on success and ENOENT if the file cannot be found * If file is found, a vnode representing the file is returned in vpp. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsVopLookup(struct vop_lookup_args *ap) /* struct vop_lookup_args { struct vnode *dvp; // IN : locked vnode of search directory struct vnode **vpp; // IN/OUT: addr to store located (locked) vnode struct componentname *cnp; // IN : pathname component to search for }; */ { struct vnode *dvp = ap->a_dvp; struct vnode **vpp = ap->a_vpp; struct componentname *cnp = ap->a_cnp; return HgfsLookupInt(dvp, vpp, cnp); } /* *---------------------------------------------------------------------------- * * HgfsVopCreate -- * * This entry point is invoked when a user calls open(2) with the O_CREAT * flag specified. We simply call HgfsCreateInt which does the file * creation work in a FreeBSD / Mac OS independent way. * * Results: * Returns zero on success and an appropriate error code on error. * * Side effects: * If the file doesn't exist, a vnode will be created. * *---------------------------------------------------------------------------- */ static int HgfsVopCreate(struct vop_create_args *ap) /* struct vop_create { struct vnode *dvp; // IN : locked directory vnode struct vnode **vp; // OUT: location to place resultant locked vnode struct componentname *cnp; // IN : pathname component created struct vattr *vap; // IN : attributes to create new object with */ { struct vnode *dvp = ap->a_dvp; struct vnode **vpp = ap->a_vpp; struct componentname *cnp = ap->a_cnp; struct vattr *vap = ap->a_vap; return HgfsCreateInt(dvp, vpp, cnp, vap->va_mode); } /* *---------------------------------------------------------------------------- * * HgfsVopOpen -- * * Invoked when open(2) is called on a file in our filesystem. Sends an * OPEN request to the Hgfs server with the filename of this vnode. * * "Opens a file referenced by the supplied vnode. The open() system call * has already done a vop_lookup() on the path name, which returned a vnode * pointer and then calls to vop_open(). This function typically does very * little since most of the real work was performed by vop_lookup()." * (Solaris Internals, p537) * * Results: * Returns 0 on success and an error code on error. * * Side effects: * The HgfsOpenFile for this file is given a handle that can be used on * future read and write requests. * *---------------------------------------------------------------------------- */ static int HgfsVopOpen(struct vop_open_args *ap) /* struct vop_open_args { struct vnode *vp; // IN: vnode of file to open int mode; // IN: access mode requested by calling process struct ucred *cred; // IN: calling process's user's credentials struct thread *td; // IN: thread accessing file int fdidx; // IN: file descriptor number }; */ { struct vnode *vp = ap->a_vp; int mode = ap->a_mode; return HgfsOpenInt(vp, mode, OPENREQ_OPEN); } /* *---------------------------------------------------------------------------- * * HgfsVopClose -- * * Invoked when a user calls close(2) on a file in our filesystem. * * Calls HgfsCloseInt which handles the close in a FreeBSD / Mac OS * independent way. * * Results: * Returns 0 on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsVopClose(struct vop_close_args *ap) /* struct vop_close_args { struct vnode *vp; // IN: vnode of object to close [exclusive lock held] int fflag; // IN: F* flags (FWRITE, etc) on object struct ucred *cred; // IN: calling process's user's credentials struct thread *td; // IN: thread accessing file }; */ { struct vnode *vp = ap->a_vp; int fflag = ap->a_fflag; struct vnode *rootVnode; int ret = 0; /* * According to the FreeBSD manpage, VOP_CLOSE can be called with or * without a lock held on vp. However, in the FreeBSD 6.2 source code, * the only place that VOP_CLOSE is called without a lock held is in * kern/vfs_subr.c::vgone1 and only if the vnode is not already doomed with the * VI_DOOMED flag. In addition, the VFS layer will not acquire a vnode lock * on a doomed vnode (kern/vfs_vnops.c::vn_lock). This means that there is no need * to do any locking here as this function will always be called in a serial manner. */ /* * A problem exists where vflush (on unmount) calls close on the root vnode without * first having calling open. * Here is the problematic sequence of events: * 1. HgfsVfsUnmount calls vflush with 1 v_usecount ref on the rootVnode (the one from mount). * 2. vflush calls vgone on the root vnode because rootrefs (in FreeBSD vflush code) * is > 0. * 3. vgone calls VOP_CLOSE because the root vnode has a v_usecount == 1. * The problem is that there was never an open to match the close. This means that when * HgfsCloseInt tries decrement the handle reference count, it will go negative (in addition * to sending a bad close to the hgfs server). To handle this situation, look for this * specific case (which only happens on FreeBSD) and do not call HgfsCloseInt. */ rootVnode = HGFS_VP_TO_SIP(vp)->rootVnode; if ((rootVnode == vp) && (rootVnode->v_usecount == 1)) { DEBUG(VM_DEBUG_LOG, "Skipping final close on rootVnode\n"); goto out; } ret = HgfsCloseInt(vp, fflag); out: return ret; } /* *---------------------------------------------------------------------------- * * HgfsVopAccess -- * * This function is invoked when the user calls access(2) on a file in our * filesystem. It checks to ensure the user has the specified type of * access to the file. * * We send a GET_ATTRIBUTE request by calling HgfsGetattr() to get the mode * (permissions) for the provided vnode. * * Results: * Returns 0 if access is allowed and a non-zero error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsVopAccess(struct vop_access_args *ap) /* struct vop_access_args { struct vnode *vp; // IN: vnode of file to check int mode; // IN: type of access required (mask of VREAD|VWRITE|VEXEC) struct ucred *cred; // IN: calling process's user's credentials struct thread *td; // IN: thread accessing file }; */ { struct vnode *vp = ap->a_vp; int mode = ap->a_mode; HgfsAccessMode accessMode = 0; Bool isDir = vp->v_type == VDIR; if (mode & VREAD) { accessMode |= isDir ? HGFS_MODE_LIST_DIRECTORY : HGFS_MODE_READ_DATA; accessMode |= HGFS_MODE_READ_ATTRIBUTES; } if (mode & VWRITE) { if (isDir) { accessMode |= HGFS_MODE_ADD_FILE | HGFS_MODE_ADD_SUBDIRECTORY | HGFS_MODE_DELETE | HGFS_MODE_DELETE_CHILD | HGFS_MODE_WRITE_ATTRIBUTES; } else { accessMode |= HGFS_MODE_WRITE_DATA | HGFS_MODE_ADD_SUBDIRECTORY | HGFS_MODE_DELETE | HGFS_MODE_WRITE_ATTRIBUTES; } } if (mode & VAPPEND) { accessMode |= isDir ? HGFS_MODE_ADD_SUBDIRECTORY : HGFS_MODE_APPEND_DATA; } if (mode & VEXEC) { accessMode |= isDir ? HGFS_MODE_TRAVERSE_DIRECTORY : HGFS_MODE_GENERIC_EXECUTE; } return HgfsAccessInt(vp, accessMode); } /* *---------------------------------------------------------------------------- * * HgfsVopGetattr -- * * "Gets the attributes for the supplied vnode." (Solaris Internals, p536) * * Results: * Zero if successful, an errno-type value otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsVopGetattr(struct vop_getattr_args *ap) /* struct vop_getattr_args { struct vnode *vp; // IN : vnode of file struct vattr *vap; // OUT: attribute container struct ucred *cred; // IN : calling process's user's credentials struct thread *td; // IN : thread accessing file }; */ { struct vnode *vp = ap->a_vp; struct vattr *vap = ap->a_vap; return HgfsGetattrInt(vp, vap); } /* *---------------------------------------------------------------------------- * * HgfsVopSetattr -- * * Maps the FreeBSD attributes to Hgfs attributes (by calling * HgfsSetattrCopy()) and sends a set attribute request to the Hgfs server. * * "Sets the attributes for the supplied vnode." (Solaris Internals, p537) * * Results: * Returns 0 on success and a non-zero error code on error. * * Side effects: * The file on the host will have new attributes. * *---------------------------------------------------------------------------- */ static int HgfsVopSetattr(struct vop_setattr_args *ap) /* struct vop_setattr_args { struct vnode *vp; // IN: vnode of file struct vattr *vap; // IN: attribute container struct ucred *cred; // IN: calling process's user's credentials struct thread *td; // IN: thread accessing file }; */ { struct vnode *vp = ap->a_vp; struct vattr *vap = ap->a_vap; return HgfsSetattrInt(vp, vap); } /* *---------------------------------------------------------------------------- * * HgfsVopRead -- * * Invoked when a user calls read(2) on a file in our filesystem. * * Results: * Returns zero on success and an error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsVopRead(struct vop_read_args *ap) /* struct vop_read_args { struct vnode *vp; // IN : the vnode of the file struct uio *uio; // INOUT: location of data to be read int ioflag; // IN : hints & other directives struct ucread *cred; // IN : caller's credentials }; */ { struct vnode *vp = ap->a_vp; struct uio *uiop = ap->a_uio; return HgfsReadInt(vp, uiop, FALSE); } /* *---------------------------------------------------------------------------- * * HgfsVopWrite -- * * This is invoked when a user calls write(2) on a file in our filesystem. * * * Results: * Returns 0 on success and error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsVopWrite(struct vop_write_args *ap) /* struct vop_write_args { struct vnode *vp; // IN : struct uio *uio; // INOUT: int ioflag; // IN : struct ucred *cred; // IN : }; */ { struct vnode *vp = ap->a_vp; struct uio *uiop = ap->a_uio; int ioflag = ap->a_ioflag; return HgfsWriteInt(vp, uiop, ioflag, FALSE); } /* *---------------------------------------------------------------------------- * * HgfsVopRemove -- * * Composes the full pathname of this file and sends a DELETE_FILE request * by calling HgfsDelete(). * * "Removes the file for the supplied vnode." (Solaris Internals, p537) * * Results: * Returns 0 on success or a non-zero error code on error. * * Side effects: * If successful, the file specified will be deleted from the host's * filesystem. * *---------------------------------------------------------------------------- */ static int HgfsVopRemove(struct vop_remove_args *ap) /* struct vop_remove_args { struct vnode *dvp; // IN: parent directory struct vnode *vp; // IN: vnode to remove struct componentname *cnp; // IN: file's pathname information */ { struct vnode *vp = ap->a_vp; return HgfsRemoveInt(vp); } /* *---------------------------------------------------------------------------- * * HgfsVopRename -- * * Renames the provided source name in the source directory with the * destination name in the destination directory. A RENAME request is sent * to the Hgfs server. * * Results: * Returns 0 on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsVopRename(struct vop_rename_args *ap) /* struct vop_rename_args { struct vnode *fdvp; // IN: "from" parent directory struct vnode *fvp; // IN: "from" file struct componentname *fcnp: // IN: "from" pathname info struct vnode *tdvp; // IN: "to" parent directory struct vnode *tvp; // IN: "to" file (if it exists) struct componentname *tcnp: // IN: "to" pathname info }; */ { struct vnode *fdvp = ap->a_fdvp; struct vnode *fvp = ap->a_fvp; struct vnode *tdvp = ap->a_tdvp; struct vnode *tvp = ap->a_tvp; struct componentname *tcnp = ap->a_tcnp; int ret; /* * Note that fvp and fdvp are not locked when called by the VFS layer. However, * this does not matter for the HgfsRenameInt implementaiton which does not use * the handle or mode from the HgfsOpenFile (the two things that can change in an * HgfsOpenFile struct). So while a normal VFS implementation would lock at least fvp * here, this one does not. */ ret = HgfsRenameInt(fvp, tdvp, tvp, tcnp); vrele(fdvp); vrele(fvp); vput(tdvp); if (tvp) { vput(tvp); } return ret; } /* *---------------------------------------------------------------------------- * * HgfsMkdir -- * * Calls HgfsMkdirInt which does all of the directory creation work in a * FreeBSD / Mac OS independent way. * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * If successful, a directory is created on the host's filesystem. * *---------------------------------------------------------------------------- */ static int HgfsVopMkdir(struct vop_mkdir_args *ap) /* struct vop_mkdir_args { struct vnode *dvp; // IN : directory vnode struct vnode **vpp; // OUT: pointer to new directory vnode struct componentname *cnp; // IN : pathname component created struct vattr *vap; // IN : attributes to create directory with }; */ { struct vnode *dvp = ap->a_dvp; struct vnode **vpp = ap->a_vpp; struct componentname *cnp = ap->a_cnp; struct vattr *vap = ap->a_vap; return HgfsMkdirInt(dvp, vpp, cnp, vap->va_mode); } /* *---------------------------------------------------------------------------- * * HgfsVopRmdir -- * * Removes the specified name from the provided vnode by calling * HgfsRmdirInt. * * Results: * Returns 0 on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsVopRmdir(struct vop_rmdir_args *ap) /* struct vop_rmdir_args { struct vnode *dvp; // IN: parent directory vnode struct vnode *vp; // IN: directory to remove struct componentname *cnp; // IN: pathname information }; */ { struct vnode *dvp = ap->a_dvp; struct vnode *vp = ap->a_vp; struct componentname *cnp = ap->a_cnp; return HgfsRmdirInt(dvp, vp, cnp); } /* *---------------------------------------------------------------------------- * * HgfsVopReaddir -- * * Reads as many entries from the directory as will fit in to the provided * buffer. Each directory entry is read by calling HgfsGetNextDirEntry(). * * The funciton simply calls HgfsReaddirInt to do all of the common * FreeBSD and Solaris work. * * Results: * Returns 0 on success and a non-zero error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsVopReaddir(struct vop_readdir_args *ap) /* struct vop_readdir_args { struct vnode *vp; // IN : directory to read from struct uio *uio; // INOUT: where to read contents struct ucred *cred; // IN : caller's credentials int *eofflag; // INOUT: end of file status int *ncookies; // OUT : used by NFS server only; ignored u_long **cookies; // INOUT: used by NFS server only; ignored }; */ { struct vnode *vp = ap->a_vp; struct uio *uiop = ap->a_uio; int *eofp = ap->a_eofflag; return HgfsReaddirInt(vp, uiop, eofp); } /* *---------------------------------------------------------------------------- * * HgfsVopInactive -- * * Called when vnode's use count reaches zero. * * Results: * Unconditionally zero. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsVopInactive(struct vop_inactive_args *ap) /* struct vop_inactive_args { struct vnode *vp; // IN: vnode to inactive struct thread *td; // IN: caller's thread context }; */ { return 0; } /* *---------------------------------------------------------------------------- * * HgfsVopReclaim -- * * Dissociates vnode from the underlying filesystem. * * Results: * Zero on success, or an appropriate system error otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsVopReclaim(struct vop_reclaim_args *ap) /* struct vop_reclaim_args { struct vnode *vp; // IN: vnode to reclaim struct thread *td; // IN: caller's thread context }; */ { struct vnode *vp = ap->a_vp; HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp); HgfsReleaseVnodeContext(vp, &sip->fileHashTable); vp->v_data = NULL; return 0; } /* *---------------------------------------------------------------------------- * * HgfsVopPrint -- * * This function is needed to fill in the HgfsVnodeOps structure. * Right now it does nothing. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsVopPrint(struct vop_print_args *ap) { return 0; } /* *---------------------------------------------------------------------------- * * HgfsVopReadlink -- * * Invoked when a user calls readlink(2) on a file in our filesystem. * * Results: * Returns zero on success and an error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsVopReadlink(struct vop_readlink_args *ap) /* struct vop_readlink_args { vnode *vp; // IN : vnode of file struct uio *uio; // OUT: location to copy symlink name. struct ucred *cred; // IN : caller's credentials }; */ { struct vnode *vp = ap->a_vp; struct uio *uiop = ap->a_uio; return HgfsReadlinkInt(vp, uiop); } /* *---------------------------------------------------------------------------- * * HgfsVopSymlink -- * * Invoked when a user calls symlink(2) to create a symbolic link. * * Results: * Returns zero on success and an error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsVopSymlink(struct vop_symlink_args *ap) /* struct vop_symlink_args { vnode *dvp; // IN : vnode of directory vnode **vp; // OUT: location to place resultant vnode struct componentname *cnp; // IN : symlink pathname info struct vatttr *vap; // IN : attributes to create new object with char *target; // IN : Target name }; */ { struct vnode **vp = ap->a_vpp; struct vnode *dvp = ap->a_dvp; struct componentname *cnp = ap->a_cnp; char *target = ap->a_target; return HgfsSymlinkInt(dvp, vp, cnp, target); } open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/request.h0000644765153500003110000000641712220061556021664 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * request.h -- * * Declarations for the HgfsRequest module. This interface abstracts Hgfs * request processing from the filesystem driver. */ #ifndef _REQUEST_H_ #define _REQUEST_H_ #define INCLUDE_ALLOW_MODULE #include "includeCheck.h" #include "dbllnklst.h" /* Double link list types */ /* * Each request will traverse through this set of states. File systems may * query the state of their request, but they may not update it. */ typedef enum { HGFS_REQ_UNUSED = 1, HGFS_REQ_ALLOCATED, HGFS_REQ_SUBMITTED, HGFS_REQ_ABANDONED, HGFS_REQ_ERROR, HGFS_REQ_COMPLETED } HgfsKReqState; /* * Opaque request handler used by the file system code. Allocated during * HgfsKReq_AllocRequest and released at HgfsKReq_ReleaseRequest. */ typedef struct HgfsKReqObject * HgfsKReqHandle; /* * Opaque request object container for the file system. File systems snag one * of these during HgfsKReq_InitSip & relinquish during HgfsKReq_UninitSip. */ typedef struct HgfsKReqContainer * HgfsKReqContainerHandle; /* * Global functions (prototypes) */ extern int HgfsKReq_SysInit(void); extern int HgfsKReq_SysFini(void); extern HgfsKReqContainerHandle HgfsKReq_AllocateContainer(void); extern void HgfsKReq_FreeContainer(HgfsKReqContainerHandle handle); extern void HgfsKReq_CancelRequests(HgfsKReqContainerHandle handle); extern Bool HgfsKReq_ContainerIsEmpty(HgfsKReqContainerHandle handle); extern HgfsKReqHandle HgfsKReq_AllocateRequest(HgfsKReqContainerHandle handle, int *ret); extern void HgfsKReq_ReleaseRequest(HgfsKReqContainerHandle container, HgfsKReqHandle oldRequest); extern int HgfsKReq_SubmitRequest(HgfsKReqHandle req); extern HgfsKReqState HgfsKReq_GetState(HgfsKReqHandle req); extern uint32_t HgfsKReq_GetId(HgfsKReqHandle req); extern char * HgfsKReq_GetPayload(HgfsKReqHandle req); extern char * HgfsKReq_GetPayload_V3(HgfsKReqHandle req); extern char * HgfsKRep_GetPayload_V3(HgfsKReqHandle req); extern size_t HgfsKReq_GetPayloadSize(HgfsKReqHandle req); extern void HgfsKReq_SetPayloadSize(HgfsKReqHandle req, size_t newSize); #endif /* _REQUEST_H_ */ open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/debug.c0000644765153500003110000002355512220061556021257 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * debug.c -- * * Routine(s) for debugging the FreeBSD / Mac OS Hgfs module. */ #if defined __APPLE__ #include // for proc_selfpid/name #include #include "kernelStubs.h" #endif // defined __APPLE__ #include "vm_basic_types.h" #include "debug.h" /* * Global functions */ static const char *gHgfsOperationNames[] = { "HGFS_OP_OPEN", "HGFS_OP_READ", "HGFS_OP_WRITE", "HGFS_OP_CLOSE", "HGFS_OP_SEARCH_OPEN", "HGFS_OP_SEARCH_READ", "HGFS_OP_SEARCH_CLOSE", "HGFS_OP_GETATTR", "HGFS_OP_SETATTR", "HGFS_OP_CREATE_DIR", "HGFS_OP_DELETE_FILE", "HGFS_OP_DELETE_DIR", "HGFS_OP_RENAME", "HGFS_OP_QUERY_VOLUME_INFO", "HGFS_OP_OPEN_V2", "HGFS_OP_GETATTR_V2", "HGFS_OP_SETATTR_V2", "HGFS_OP_SEARCH_READ_V2", "HGFS_OP_CREATE_SYMLINK", "HGFS_OP_SERVER_LOCK_CHANGE", "HGFS_OP_CREATE_DIR_V2", "HGFS_OP_DELETE_FILE_V2", "HGFS_OP_DELETE_DIR_V2", "HGFS_OP_RENAME_V2", "HGFS_OP_OPEN_V3", "HGFS_OP_READ_V3", "HGFS_OP_WRITE_V3", "HGFS_OP_CLOSE_V3", "HGFS_OP_SEARCH_OPEN_V3", "HGFS_OP_SEARCH_READ_V3", "HGFS_OP_SEARCH_CLOSE_V3", "HGFS_OP_GETATTR_V3", "HGFS_OP_SETATTR_V3", "HGFS_OP_CREATE_DIR_V3", "HGFS_OP_DELETE_FILE_V3", "HGFS_OP_DELETE_DIR_V3", "HGFS_OP_RENAME_V3", "HGFS_OP_QUERY_VOLUME_INFO_V3", "HGFS_OP_CREATE_SYMLINK_V3", "HGFS_OP_SERVER_LOCK_CHANGE_V3", "HGFS_OP_WRITE_WIN32_STREAM_V3", "HGFS_OP_CREATE_SESSION_V4", "HGFS_OP_DESTROY_SESSION_V4", "HGFS_OP_READ_FAST_V4", "HGFS_OP_WRITE_FAST_V4", "HGFS_OP_SET_WATCH_V4", "HGFS_OP_REMOVE_WATCH_V4", "HGFS_OP_NOTIFY_V4", "HGFS_OP_SEARCH_READ_V4", }; #if defined VMX86_DEVEL uint32_t gHgfsVmDebugLevel = VM_DEBUG_DEFAULT_LEV; static uint32 HgfsDebugGetSequenceNumber(void); static int HgfsDebugGetProcessInfo(char *pidName, size_t pidNameBufsize); static void *HgfsDebugGetCurrentThread(void); #endif // defined VMX86_DEVEL /* *---------------------------------------------------------------------------- * * HgfsDebugPrint -- * * Prints the operation of an request structure. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsDebugPrint(int type, const char *funcname, unsigned int linenum, const char *fmt, ...) { #if defined VMX86_DEVEL #if defined __APPLE__ if (0 != (type & gHgfsVmDebugLevel) || VM_DEBUG_ALWAYS == type) { char *fmsg; size_t fmsgLen; va_list args; va_start(args, fmt); fmsg = Str_Vasprintf(&fmsgLen, fmt, args); va_end(args); if (NULL != fmsg) { int pid; void *thrd; char pidname[64]; uint32 seqNo; thrd = HgfsDebugGetCurrentThread(); pid = HgfsDebugGetProcessInfo(pidname, sizeof pidname); seqNo = HgfsDebugGetSequenceNumber(); kprintf("|%08u|%p.%08d.%s| %s:%2.2u: %s", seqNo, thrd, pid, pidname, funcname, linenum, fmsg); free(fmsg); } } #endif // defined __APPLE__ #endif // defined VMX86_DEVEL } /* *---------------------------------------------------------------------------- * * HgfsDebugPrintOperation -- * * Prints the operation of an request structure. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsDebugPrintOperation(HgfsKReqHandle req) { HgfsRequest *requestHeader; ASSERT(NULL != req); requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req); if (requestHeader->op < ARRAYSIZE(gHgfsOperationNames)) { DEBUG(VM_DEBUG_STRUCT, " operation: %s\n", gHgfsOperationNames[requestHeader->op]); } else { DEBUG(VM_DEBUG_STRUCT, " operation: INVALID %d\n", requestHeader->op); } } #if defined VMX86_DEVEL /* *---------------------------------------------------------------------------- * * HgfsDebugGetProcessInfo -- * * Gets the process name and ID making a request. * * Results: * PID of current process, and name in the buffer. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int HgfsDebugGetProcessInfo(char *pidname, // OUT: buffer for name size_t pidNameBufsize) // IN: size of buffer { int curPid = -1; *pidname = '\0'; #if defined __APPLE__ curPid = proc_selfpid(); proc_name(curPid, pidname, pidNameBufsize); #endif // defined __APPLE__ return curPid; } /* *---------------------------------------------------------------------------- * * HgfsDebugGetCurrentThreadId -- * * Gets the current thread making a request. * * Results: * TID of current thread. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void * HgfsDebugGetCurrentThread(void) { void *thread = NULL; #if defined __APPLE__ thread = current_thread(); #endif // defined __APPLE__ return thread; } #endif // defined VMX86_DEVEL /* *---------------------------------------------------------------------------- * * HgfsDebugPrintVattr -- * * Prints the contents of an attributes structure. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsDebugPrintVattr(const HgfsVnodeAttr *vap) { DEBUG(VM_DEBUG_STRUCT, " va_type: %d\n", vap->va_type); DEBUG(VM_DEBUG_STRUCT, " va_mode: %o\n", vap->va_mode); DEBUG(VM_DEBUG_STRUCT, " va_uid: %u\n", vap->va_uid); DEBUG(VM_DEBUG_STRUCT, " va_gid: %u\n", vap->va_gid); DEBUG(VM_DEBUG_STRUCT, " va_fsid: %u\n", vap->va_fsid); DEBUG(VM_DEBUG_STRUCT, " va_rdev: %u\n", vap->va_rdev); DEBUG(VM_DEBUG_STRUCT, " va_filerev: %"FMT64"u\n", vap->va_filerev); DEBUG(VM_DEBUG_STRUCT, " va_vaflags: %x\n", vap->va_vaflags); #if defined __FreeBSD__ /* * The next group of attributes have the same name but different sizes on * xnu-1228 and FreeBSD 6.2. */ DEBUG(VM_DEBUG_STRUCT, " va_flags: %lx\n", vap->va_flags); DEBUG(VM_DEBUG_STRUCT, " va_gen: %lu\n", vap->va_gen); DEBUG(VM_DEBUG_STRUCT, " va_fileid: %ld\n", vap->va_fileid); DEBUG(VM_DEBUG_STRUCT, " va_nlink: %hd\n", vap->va_nlink); /* These attributes names changed have between xnu-1228 and FreeBSD 6.2. */ DEBUG(VM_DEBUG_STRUCT, " va_size: %ju\n", vap->va_size); DEBUG(VM_DEBUG_STRUCT, " va_blocksize: %ld\n", vap->va_blocksize); /* * XXX time_t is __int32_t on 32-bit architectures and __int64_t on 64-bit * architectures. Would this be better as add'l formats in vm_basic_types.h? */ DEBUG(VM_DEBUG_STRUCT, " va_atime.tv_sec: %jd\n", (intmax_t)vap->va_atime.tv_sec); DEBUG(VM_DEBUG_STRUCT, " va_atime.tv_nsec: %ld\n", vap->va_atime.tv_nsec); DEBUG(VM_DEBUG_STRUCT, " va_mtime.tv_sec: %jd\n", (intmax_t)vap->va_mtime.tv_sec); DEBUG(VM_DEBUG_STRUCT, " va_mtime.tv_nsec: %ld\n", vap->va_mtime.tv_nsec); DEBUG(VM_DEBUG_STRUCT, " va_ctime.tv_sec: %jd\n", (intmax_t)vap->va_ctime.tv_sec); DEBUG(VM_DEBUG_STRUCT, " va_ctime.tv_nsec: %ld\n", vap->va_ctime.tv_nsec); DEBUG(VM_DEBUG_STRUCT, " va_birthtime.tv_sec: %jd\n", (intmax_t)vap->va_birthtime.tv_sec); DEBUG(VM_DEBUG_STRUCT, " va_birthtime.tv_nsec: %ld\n", vap->va_birthtime.tv_nsec); DEBUG(VM_DEBUG_STRUCT, " va_bytes: %"FMT64"u\n", vap->va_bytes); #elif defined __APPLE__ /* * The next group of attributes have the same name but different sizes on * xnu-1228 and FreeBSD 6.2. */ DEBUG(VM_DEBUG_STRUCT, " va_flags: %x\n", vap->va_flags); DEBUG(VM_DEBUG_STRUCT, " va_gen: %u\n", vap->va_gen); DEBUG(VM_DEBUG_STRUCT, " va_fileid: %"FMT64"u\n", vap->va_fileid); DEBUG(VM_DEBUG_STRUCT, " va_nlink: %"FMT64"u\n", vap->va_nlink); /* These attribute names have changed between xnu-1228 and FreeBSD 6.2. */ DEBUG(VM_DEBUG_STRUCT, " va_size: %"FMT64"u\n", vap->va_data_size); DEBUG(VM_DEBUG_STRUCT, " va_iosize: %u\n", vap->va_iosize); DEBUG(VM_DEBUG_STRUCT, " va_access_time.tv_sec: %ld\n", vap->va_access_time.tv_sec); DEBUG(VM_DEBUG_STRUCT, " va_access_time.tv_nsec: %ld\n", vap->va_access_time.tv_nsec); DEBUG(VM_DEBUG_STRUCT, " va_modify_time.tv_sec: %ld\n", vap->va_modify_time.tv_sec); DEBUG(VM_DEBUG_STRUCT, " va_modify_time.tv_nsec: %ld\n", vap->va_modify_time.tv_nsec); DEBUG(VM_DEBUG_STRUCT, " va_create_time.tv_sec: %ld\n", vap->va_create_time.tv_sec); DEBUG(VM_DEBUG_STRUCT, " va_create_time.tv_nsec: %ld\n", vap->va_create_time.tv_nsec); #endif } #if defined VMX86_DEVEL /* *---------------------------------------------------------------------------- * * HgfsDebugGetSequenceNumber -- * * Log a sequence number in case we suspect log messages getting dropped * * Results: * The next sequence number. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static uint32 HgfsDebugGetSequenceNumber(void) { static uint32 ghgfsDebugLogSeq = 0; return ++ghgfsDebugLogSeq; } #endif // defined VMX86_DEVEL open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/COPYING0000644765153500003110000004310312220061556021047 0ustar dtormts GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/channel.h0000644765153500003110000000410012220061556021567 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * channel.h -- */ #ifndef _HGFS_CHANNEL_H_ #define _HGFS_CHANNEL__H_ #include "hgfs_kernel.h" #include "requestInt.h" /* * There are the operations a channel should implement. */ struct HgfsTransportChannel; typedef struct HgfsTransportChannelOps { Bool (*open)(struct HgfsTransportChannel *); void (*close)(struct HgfsTransportChannel *); HgfsKReqObject* (*allocate)(size_t payloadSize, int flags); int (*send)(struct HgfsTransportChannel *, HgfsKReqObject *); void (*free)(HgfsKReqObject *, size_t payloadSize); } HgfsTransportChannelOps; typedef enum { HGFS_CHANNEL_UNINITIALIZED, HGFS_CHANNEL_NOTCONNECTED, HGFS_CHANNEL_CONNECTED, HGFS_CHANNEL_DEAD, /* Error has been detected, need to shut it down. */ } HgfsChannelStatus; typedef struct HgfsTransportChannel { const char *name; /* Channel name. */ HgfsTransportChannelOps ops; /* Channel ops. */ HgfsChannelStatus status; /* Connection status. */ void *priv; /* Channel private data. */ } HgfsTransportChannel; HgfsTransportChannel *HgfsGetBdChannel(void); HgfsTransportChannel *HgfsGetVmciChannel(void); Bool HgfsSetupNewChannel(void); extern HgfsTransportChannel *gHgfsChannel; #endif // _HGFS_CHANNEL_H_ open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/transport.c0000644765153500003110000002777712220061556022237 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * transport.c -- * * Functions that prepare HGFS packages and send them to the host. * Implementations are shared between both Mac OS and FreeBSD. */ #include // for everything #include // for struct vnode #include // for struct dirent #include "fsutil.h" #include "debug.h" #include "transport.h" #include "cpName.h" #include "os.h" #define HGFS_FILE_OPEN_MASK (HGFS_OPEN_VALID_MODE | \ HGFS_OPEN_VALID_FLAGS | \ HGFS_OPEN_VALID_SPECIAL_PERMS | \ HGFS_OPEN_VALID_OWNER_PERMS | \ HGFS_OPEN_VALID_GROUP_PERMS | \ HGFS_OPEN_VALID_OTHER_PERMS | \ HGFS_OPEN_VALID_FILE_NAME) /* *---------------------------------------------------------------------------- * * HgfsSendOpenDirRequest -- * * Sends a SEARCH_OPEN request to the Hgfs server. * * Results: * Returns zero on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsSendOpenDirRequest(HgfsSuperInfo *sip, // IN: Superinfo pointer char *fullPath, // IN: Full path for the file uint32 fullPathLen, // IN: Length of the full path HgfsHandle *handle) // OUT: HGFS handle for the opened file { HgfsKReqHandle req; HgfsRequest *requestHeader; HgfsReply *replyHeader; HgfsRequestSearchOpenV3 *request; HgfsReplySearchOpenV3 *reply; uint32 reqSize; uint32 repSize; uint32 reqBufferSize; int ret; req = HgfsKReq_AllocateRequest(sip->reqs, &ret); if (!req) { return ret; } /* Set the correct header values */ requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req); request = (HgfsRequestSearchOpenV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader); HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_SEARCH_OPEN_V3); request->dirName.flags = 0; request->dirName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; request->dirName.fid = HGFS_INVALID_HANDLE; request->reserved = 0; reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); reqBufferSize = HGFS_NAME_BUFFER_SIZET(HGFS_PACKET_MAX, reqSize); /* * Convert an input string to utf8 precomposed form, convert it to * the cross platform name format and finally unescape any illegal * filesystem characters. */ ret = HgfsNameToWireEncoding(fullPath, fullPathLen + 1, request->dirName.name, reqBufferSize); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "Could not encode to wire format"); HgfsKReq_ReleaseRequest(sip->reqs, req); return -ret; } request->dirName.length = ret; reqSize += ret; HgfsKReq_SetPayloadSize(req, reqSize); /* Submit the request to the Hgfs server */ ret = HgfsSubmitRequest(sip, req); if (ret == 0) { /* Our reply is in the request packet */ replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req); reply = (HgfsReplySearchOpenV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader); repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply); ret = HgfsGetStatus(req, repSize); if (ret == 0) { *handle = reply->search; } else { DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret); } DEBUG(VM_DEBUG_COMM, "received reply for ID %d\n", replyHeader->id); DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n", replyHeader->status); DEBUG(VM_DEBUG_COMM, " handle: %d\n", reply->search); HgfsKReq_ReleaseRequest(sip->reqs, req); } return ret; } /* *---------------------------------------------------------------------------- * * HgfsSendOpenRequest -- * * Sends an OPEN request to the Hgfs server to open an existing file. * * Results: * Returns zero on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsSendOpenRequest(HgfsSuperInfo *sip, // IN: Superinfo pointer int openMode, // IN: HGFS mode of open int openFlags, // IN: HGFS open flags int permissions, // IN: Permissions of open (only when creating) char *fullPath, // IN: Full path for the file uint32 fullPathLen, // IN: Length of the full path HgfsHandle *handle) // OUT: HGFS handle for the opened file { HgfsKReqHandle req; HgfsRequest *requestHeader; HgfsReply *replyHeader; HgfsRequestOpenV3 *request; HgfsReplyOpenV3 *reply; int ret; uint32 reqSize; uint32 repSize; uint32 reqBufferSize; DEBUG(VM_DEBUG_LOG, "Trace enter.\n"); req = HgfsKReq_AllocateRequest(sip->reqs, &ret); if (!req) { DEBUG(VM_DEBUG_FAIL, "HgfsKReq_AllocateRequest failed.\n"); return ret; } requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req); request = (HgfsRequestOpenV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader); HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_OPEN_V3); request->mask = HGFS_FILE_OPEN_MASK; request->reserved1 = 0; request->reserved2 = 0; reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); reqBufferSize = HGFS_NAME_BUFFER_SIZET(HGFS_PACKET_MAX, reqSize); request->mode = openMode; request->flags = openFlags; DEBUG(VM_DEBUG_COMM, "open flags are %x\n", request->flags); request->specialPerms = (permissions & (S_ISUID | S_ISGID | S_ISVTX)) >> HGFS_ATTR_SPECIAL_PERM_SHIFT; request->ownerPerms = (permissions & S_IRWXU) >> HGFS_ATTR_OWNER_PERM_SHIFT; request->groupPerms = (permissions & S_IRWXG) >> HGFS_ATTR_GROUP_PERM_SHIFT; request->otherPerms = permissions & S_IRWXO; DEBUG(VM_DEBUG_COMM, "permissions are %o\n", permissions); request->fileName.flags = 0; request->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; request->fileName.fid = HGFS_INVALID_HANDLE; /* * Convert an input string to utf8 precomposed form, convert it to * the cross platform name format and finally unescape any illegal * filesystem characters. */ ret = HgfsNameToWireEncoding(fullPath, fullPathLen + 1, request->fileName.name, reqBufferSize); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "Could not encode to wire format"); ret = -ret; goto out; } request->fileName.length = ret; reqSize += ret; /* Packet size includes the request and its payload. */ HgfsKReq_SetPayloadSize(req, reqSize); ret = HgfsSubmitRequest(sip, req); if (ret) { /* HgfsSubmitRequest will destroy the request if necessary. */ DEBUG(VM_DEBUG_FAIL, "could not submit request.\n"); req = NULL; // Request has been deallocated by SubmitRequest } else { replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req); reply = (HgfsReplyOpenV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader); repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply); ret = HgfsGetStatus(req, repSize); if (ret == 0) { *handle = reply->file; } } out: if (req != NULL) { HgfsKReq_ReleaseRequest(sip->reqs, req); } return ret; } /* *---------------------------------------------------------------------------- * * HgfsCloseServerDirHandle -- * * Prepares close handle request and sends it to the HGFS server * * Results: * Returns zero on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsCloseServerDirHandle(HgfsSuperInfo *sip, // IN: Superinfo pointer HgfsHandle handle) // IN: Handle to close { HgfsKReqHandle req; HgfsRequest *requestHeader; HgfsReply *replyHeader; HgfsRequestSearchCloseV3 *request; HgfsReplySearchCloseV3 *reply; uint32 reqSize; uint32 repSize; int ret; req = HgfsKReq_AllocateRequest(sip->reqs, &ret); if (!req) { return ret; } /* * Prepare the request structure. Of note here is that the request is * always the same size so we just set the packetSize to that. */ requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req); request = (HgfsRequestSearchCloseV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader); HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_SEARCH_CLOSE_V3); request->search = handle; request->reserved = 0; reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); HgfsKReq_SetPayloadSize(req, reqSize); /* Submit the request to the Hgfs server */ ret = HgfsSubmitRequest(sip, req); if (ret == 0) { replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req); repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply); DEBUG(VM_DEBUG_COMM, "received reply for ID %d\n", replyHeader->id); DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n", replyHeader->status); ret = HgfsGetStatus(req, repSize); if (ret) { DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret); if (ret != EPROTO) { ret = EFAULT; } } HgfsKReq_ReleaseRequest(sip->reqs, req); } return ret; } /* *---------------------------------------------------------------------------- * * HgfsCloseServerFileHandle -- * * Prepares close handle request and sends it to the HGFS server * * Results: * Returns zero on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsCloseServerFileHandle(HgfsSuperInfo *sip, // IN: Superinfo pointer HgfsHandle handle) // IN: Handle to close { HgfsKReqHandle req; HgfsRequest *requestHeader; HgfsReply *replyHeader; HgfsRequestCloseV3 *request; HgfsReplyCloseV3 *reply; uint32 reqSize; uint32 repSize; int ret; req = HgfsKReq_AllocateRequest(sip->reqs, &ret); if (!req) { return ret; } /* * Prepare the request structure. Of note here is that the request is * always the same size so we just set the packetSize to that. */ requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req); request = (HgfsRequestCloseV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader); HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_CLOSE_V3); request->file = handle; request->reserved = 0; reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); HgfsKReq_SetPayloadSize(req, reqSize); /* Submit the request to the Hgfs server */ ret = HgfsSubmitRequest(sip, req); if (ret == 0) { replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req); repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply); DEBUG(VM_DEBUG_COMM, "received reply for ID %d\n", replyHeader->id); DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n", replyHeader->status); ret = HgfsGetStatus(req, repSize); if (ret) { DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret); if (ret != EPROTO) { ret = EFAULT; } } HgfsKReq_ReleaseRequest(sip->reqs, req); } return ret; } open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/Makefile0000644765153500003110000000647412220061556021466 0ustar dtormts#!/usr/bin/make -f ########################################################## # Copyright (C) 2007 VMware, Inc. All rights reserved. # # 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 version 2 and no later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ########################################################## HEADERS := vnode_if.h HEADERS += hgfs_kernel.h HEADERS += request.h HEADERS += requestInt.h HEADERS += debug.h HEADERS += state.h HEADERS += kernelStubs.h HEADERS += fsutil.h HEADERS += vnopscommon.h HEADERS += os.h HEADERS += vfsopscommon.h HEADERS += transport.h HEADERS += channel.h COMMON_SRCS := cpName.c COMMON_SRCS += cpNameLinux.c COMMON_SRCS += cpNameLite.c COMMON_SRCS += sha1.c COMMON_SRCS += hgfsEscape.c COMMON_SRCS += hgfsBd.c COMMON_SRCS += rpcout.c COMMON_SRCS += message.c COMMON_SRCS += backdoor.c .if $(MACHINE_ARCH) == "amd64" COMMON_SRCS += backdoorGcc64.c .else COMMON_SRCS += backdoorGcc32.c .endif COMMON_HGFS_SRCS := debug.c COMMON_HGFS_SRCS := bdhandler.c COMMON_HGFS_SRCS += request.c COMMON_HGFS_SRCS += worker.c COMMON_HGFS_SRCS += fsutil.c COMMON_HGFS_SRCS += vnopscommon.c COMMON_HGFS_SRCS += state.c COMMON_HGFS_SRCS += vfsopscommon.c COMMON_HGFS_SRCS += transport.c MODULE_SRCS := vnops.c MODULE_SRCS += vfsops.c MODULE_SRCS += os.c MODULE_SRCS += vmci.c MODULE_SRCS += hgfsUtil.c MODULE_SRCS += kernelStubsBSD.c # # The FreeBSD kernel module build tree iterates over the following variable # for build targets. C files will be compiled, and headers will just be # tested for presence. # SRCS = $(MODULE_SRCS) $(COMMON_SRCS) $(COMMON_HGFS_SRCS) $(HEADERS) KMOD = vmhgfs PROG = ../$(KMOD).ko NOMAN = t NO_MAN = t KLDMOD = t NOOBJ = 1 NO_OBJ = 1 .ifdef OVT_SOURCE_DIR CFLAGS += -I$(OVT_SOURCE_DIR)/lib/include CFLAGS += -I$(OVT_SOURCE_DIR)/lib/backdoor CFLAGS += -I$(OVT_SOURCE_DIR)/lib/hgfs CFLAGS += -I$(OVT_SOURCE_DIR)/modules/freebsd/shared VPATH := $(OVT_SOURCE_DIR)/lib/backdoor VPATH := $(VPATH):$(OVT_SOURCE_DIR)/lib/hgfs VPATH := $(VPATH):$(OVT_SOURCE_DIR)/lib/hgfsBd VPATH := $(VPATH):$(OVT_SOURCE_DIR)/lib/message VPATH := $(VPATH):$(OVT_SOURCE_DIR)/lib/misc VPATH := $(VPATH):$(OVT_SOURCE_DIR)/lib/rpcOut .else CFLAGS += -Ishared .endif # # FreeBSD's kernel module build system defines a bunch of additional warning # flags for the compiler in addition to -Wall -Werror. However, some of these, # like -Wredundant-decls, are overkill. To get around this, I copied their list # of warning flags, but explicitly disabled a few. # CWARNFLAGS := -Wall CWARNFLAGS += -Werror CWARNFLAGS += -Wno-redundant-decls CWARNFLAGS += -Wnested-externs CWARNFLAGS += -Wstrict-prototypes CWARNFLAGS += -Wno-missing-prototypes CWARNFLAGS += -Wpointer-arith CWARNFLAGS += -Winline CWARNFLAGS += -Wcast-qual EXPORT_SYMS = NO .include open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/hgfs_kernel.h0000644765153500003110000001307012220061556022454 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * hgfs_kernel.h -- * * Declarations for the FreeBSD Hgfs client kernel module. All * FreeBSD-specifc source files will include this. */ #ifndef _HGFSKERNEL_H_ #define _HGFSKERNEL_H_ /* * Intended for the Hgfs client kernel module only. */ #define INCLUDE_ALLOW_MODULE #include "includeCheck.h" /* * System includes */ #include // for #include // for struct vnode /* * VMware includes */ #include "dbllnklst.h" #include "request.h" #include "state.h" #include "hgfs.h" #include "hgfsProto.h" #include "vm_basic_types.h" #include "vm_assert.h" /* * Macros */ #define HGFS_PAYLOAD_MAX(size) (HGFS_PACKET_MAX - size) #define HGFS_FS_NAME "vmhgfs" #define HGFS_FS_NAME_LONG "VMware Hgfs client" /* * NB: Used only to provide a value for struct vattr::va_blocksize, "blocksize * preferred for i/o". */ #define HGFS_BLOCKSIZE 1024 /* Internal error code(s) */ #define HGFS_ERR (-1) #define HGFS_ERR_NULL_INPUT (-50) #define HGFS_ERR_NODEV (-51) #define HGFS_ERR_INVAL (-52) #if defined __FreeBSD__ # define HGFS_MP_TO_MNTFLAGS(mp) \ ((mp)->mnt_flag) # define HGFS_MP_SET_SIP(mp, sip) \ ((mp)->mnt_data = (sip)) # define HGFS_VP_TO_MP(vp) ((vp)->v_mount) /* Return a pointer to mnt_stat to preserve the interface between Mac OS and FreeBSD. */ # define HGFS_MP_TO_STATFS(mp) (&(mp)->mnt_stat) /* Getting to sip via any vnode */ # define HGFS_VP_TO_SIP(vp) \ ((HgfsSuperInfo*)HGFS_VP_TO_MP(vp)->mnt_data) # define HGFS_VP_VI_LOCK(vp) \ (VI_LOCK(vp)) # define HGFS_VP_VI_UNLOCK(vp) \ (VI_UNLOCK(vp)) # define HGFS_VP_ISINUSE(vp, usecount) \ ((vp)->v_usecount > usecount) # define HGFS_MP_IS_FORCEUNMOUNT(mp) \ (mp->mnt_kern_flag & MNTK_UNMOUNTF) #elif defined __APPLE__ # define HGFS_MP_TO_MNTFLAGS(mp) \ (vfs_flags(mp)) # define HGFS_MP_SET_SIP(mp, sip) \ (vfs_setfsprivate(mp, sip)) # define HGFS_VP_TO_MP(vp) (vnode_mount(vp)) # define HGFS_MP_TO_STATFS(mp) (vfs_statfs(mp)) # define HGFS_VP_TO_SIP(vp) \ ((HgfsSuperInfo*)vfs_fsprivate(HGFS_VP_TO_MP(vp))) /* * No concept of vnode locks are exposed to the Mac OS VFS layer, so do nothing here for * VI_LOCK AND VI_UNLOCK. However, make sure to call the lock functions before using * HGFS_VP_ISINUSE to preserve compatability with FreeBSD. */ # define HGFS_VP_VI_LOCK(vp) # define HGFS_VP_VI_UNLOCK(vp) # define HGFS_VP_ISINUSE(vp, usecount) \ (vnode_isinuse(vp, usecount)) # define HGFS_MP_IS_FORCEUNMOUNT(mp) \ (vfs_isforce(mp)) #endif #define HGFS_VP_TO_STATFS(vp) (HGFS_MP_TO_STATFS(HGFS_VP_TO_MP(vp))) /* * Types */ /* We call them *Header in the kernel code for clarity. */ typedef HgfsReply HgfsReplyHeader; typedef HgfsRequest HgfsRequestHeader; /* * The global state structure for a single filesystem mount. This is allocated * in HgfsVfsMount() and destroyed in HgfsVfsUnmount(). */ typedef struct HgfsSuperInfo { Bool uidSet; uid_t uid; Bool gidSet; gid_t gid; /* Request container */ HgfsKReqContainerHandle reqs; /* See request.h. */ /* For filesystem */ struct mount *vfsp; /* Our filesystem structure */ struct vnode *rootVnode; /* Root vnode of the filesystem */ HgfsFileHashTable fileHashTable; /* File hash table */ char volumeName[MAXPATHLEN]; /* Name of the volume or share. */ } HgfsSuperInfo; /* * Global variables */ /* * The vnode attributes between Mac OS and FreeBSD are very similar but not exactly the * same. Fields have names have changed. However, only HgfsAttrToBSD and * HgfsSetattrCopy care about the differences so we mash the types together to enable * single function signatures. */ #if defined __FreeBSD__ typedef struct vattr HgfsVnodeAttr; #elif defined __APPLE__ typedef struct vnode_attr HgfsVnodeAttr; #endif #if defined __FreeBSD__ /* Defined in vnops.c. */ extern struct vop_vector HgfsVnodeOps; #elif defined __APPLE__ /* Export vnops.c file operations. */ extern errno_t (**HgfsVnodeOps)(void *); extern struct vnodeopv_desc *HgfsVnodeOperationVectorDescList[1]; #endif #endif // ifndef _HGFSKERNEL_H_ open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/kernelStubs.h0000644765153500003110000001134012220061556022464 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * kernelStubs.h * * KernelStubs implements some userspace library functions in terms * of kernel functions to allow library userspace code to be used in a * kernel. */ #ifndef __KERNELSTUBS_H__ #define __KERNELSTUBS_H__ #ifdef linux # ifndef __KERNEL__ # error "__KERNEL__ is not defined" # endif # include "driver-config.h" // Must be included before any other header files # include "vm_basic_types.h" # include # include #elif defined(_WIN32) # include "vm_basic_types.h" # include /* kernel memory APIs */ # include /* for _vsnprintf, vsprintf */ # include /* for va_start stuff */ # include /* for min macro. */ # include "vm_assert.h" /* Our assert macros */ #elif defined(__FreeBSD__) # include "vm_basic_types.h" # ifndef _KERNEL # error "_KERNEL is not defined" # endif # include # include # include # include # include # include #elif defined(__APPLE__) # include "vm_basic_types.h" # ifndef KERNEL # error "KERNEL is not defined" # endif # include # include # elif defined(sun) # include "vm_basic_types.h" # include # include #endif /* * Function Prototypes */ #if defined(linux) || defined(__APPLE__) || defined (sun) # ifdef linux /* if (linux) { */ char *strdup(const char *source); # endif /* Shared between Linux and Apple kernel stubs. */ void *malloc(size_t size); void free(void *mem); void *calloc(size_t num, size_t len); void *realloc(void *ptr, size_t newSize); #elif defined(_WIN32) /* } else if (_WIN32) { */ #if (_WIN32_WINNT == 0x0400) /* The following declarations are missing on NT4. */ typedef unsigned int UINT_PTR; typedef unsigned int SIZE_T; /* No free with tag availaible on NT4 kernel! */ #define KRNL_STUBS_FREE(P,T) ExFreePool((P)) #else /* _WIN32_WINNT */ #define KRNL_STUBS_FREE(P,T) ExFreePoolWithTag((P),(T)) /* Win 2K and later useful kernel function, documented but not declared! */ NTKERNELAPI VOID ExFreePoolWithTag(IN PVOID P, IN ULONG Tag); #endif /* _WIN32_WINNT */ #elif defined(__FreeBSD__) /* } else if (FreeBSD) { */ /* Kernel memory on FreeBSD is tagged for statistics and sanity checking. */ MALLOC_DECLARE(M_VMWARE_TEMP); /* * On FreeBSD, the general memory allocator for both userland and the kernel is named * malloc, but the kernel malloc() takes more arguments. The following alias & macros * work around this, to provide the standard malloc() API for userspace code that is * being used in the kernel. */ # undef malloc static INLINE void * __compat_malloc(unsigned long size, struct malloc_type *type, int flags) { return malloc(size, type, flags); } # define malloc(size) __compat_malloc(size, M_VMWARE_TEMP, M_NOWAIT) # define calloc(count, size) __compat_malloc((count) * (size), \ M_VMWARE_TEMP, M_NOWAIT|M_ZERO) # define realloc(buf, size) realloc(buf, size, M_VMWARE_TEMP, M_NOWAIT) # define free(buf) free(buf, M_VMWARE_TEMP) # define strchr(s,c) index(s,c) # define strrchr(s,c) rindex(s,c) #endif /* } */ /* * Stub functions we provide. */ void Panic(const char *fmt, ...); char *Str_Strcpy(char *buf, const char *src, size_t maxSize); int Str_Vsnprintf(char *str, size_t size, const char *format, va_list arguments); char *Str_Vasprintf(size_t *length, const char *format, va_list arguments); char *Str_Asprintf(size_t *length, const char *Format, ...); /* * Functions the driver must implement for the stubs. */ EXTERN void Debug(const char *fmt, ...); #endif /* __KERNELSTUBS_H__ */ open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/worker.c0000644765153500003110000001703012220061556021471 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * worker.c -- * * Worker thread to process issue Guest -> Host Hgfs requests. */ #if defined __FreeBSD__ # include #endif #include "hgfs_kernel.h" #include "request.h" #include "requestInt.h" #include "os.h" #include "channel.h" /* * Local data */ /* * Process structure filled in when the worker thread is created. */ OS_THREAD_T hgfsKReqWorkerThread; /* * See requestInt.h. */ HgfsKReqWState hgfsKReqWorkerState; HgfsTransportChannel *gHgfsChannel = NULL; OS_MUTEX_T *gHgfsChannelLock = NULL; /* * Global (module) functions */ /* *---------------------------------------------------------------------- * * HgfsTransportSetupNewChannel -- * * Find a new workable channel. * * Results: * TRUE on success, otherwise FALSE. * * Side effects: * None * *---------------------------------------------------------------------- */ Bool HgfsSetupNewChannel(void) { Bool ret; os_mutex_lock(gHgfsChannelLock); if (gHgfsChannel && gHgfsChannel->status == HGFS_CHANNEL_CONNECTED) { ret = TRUE; goto exit; } gHgfsChannel = HgfsGetVmciChannel(); if (gHgfsChannel) { if ((ret = gHgfsChannel->ops.open(gHgfsChannel))) { goto exit; } } /* Every client using this code is expected to have backdoor enabled. */ gHgfsChannel = HgfsGetBdChannel(); ret = gHgfsChannel->ops.open(gHgfsChannel); exit: if (ret) { gHgfsChannel->status = HGFS_CHANNEL_CONNECTED; DEBUG(VM_DEBUG_ALWAYS, "Channel: %s\n", gHgfsChannel->name); } else { gHgfsChannel->status = HGFS_CHANNEL_NOTCONNECTED; } os_mutex_unlock(gHgfsChannelLock); return ret; } /* *----------------------------------------------------------------------------- * * HgfsKReqWorker -- * * Main routine for Hgfs client worker thread. This thread is responsible * for all Hgfs communication with the host via the backdoor. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void HgfsKReqWorker(void *arg) { DblLnkLst_Links *currNode, *nextNode; HgfsKReqWState *ws = (HgfsKReqWState *)arg; HgfsKReqObject *req; int ret = 0; HgfsTransportChannel *channel; ws->running = TRUE; gHgfsChannelLock = os_mutex_alloc_init(HGFS_FS_NAME "_channellck"); if (!gHgfsChannelLock) { goto exit; } ret = HgfsSetupNewChannel(); if (!ret) { DEBUG(VM_DEBUG_INFO, "VMware hgfs: %s: ohoh no channel yet.\n", __func__); } for (;;) { /* * This loop spends most of its time sleeping until signalled by another * thread. We expect to be signalled only if either there is work to do * or if the module is being unloaded. */ os_mutex_lock(hgfsKReqWorkItemLock); while (!ws->exit && !DblLnkLst_IsLinked(&hgfsKReqWorkItemList)) { os_cv_wait(&hgfsKReqWorkItemCv, hgfsKReqWorkItemLock); } if (ws->exit) { /* Note that the list lock is still held. */ break; } /* * We have work to do! Hooray! Start by locking the request and pulling * it from the work item list. (The list's reference is transferred to * us, so we'll decrement the request's reference count when we're * finished with it.) * * With the request locked, make a decision based on the request's state. * Typically a request will be in the SUBMITTED state, but if its owner * aborted an operation or the file system cancelled it, it may be listed * as ABANDONED. If either of the latter are true, then we don't bother * with any further processing. * * Because we're not sure how long the backdoor operation will take, we * yield the request's state lock before calling HgfsBd_Dispatch. Upon * return, we must test the state again (see above re: cancellation), * and then we finally update the state & signal any waiters. */ currNode = hgfsKReqWorkItemList.next; DblLnkLst_Unlink1(currNode); req = DblLnkLst_Container(currNode, HgfsKReqObject, pendingNode); os_mutex_lock(req->stateLock); channel = req->channel; switch (req->state) { case HGFS_REQ_SUBMITTED: if (channel->status != HGFS_CHANNEL_CONNECTED) { req->state = HGFS_REQ_ERROR; os_cv_signal(&req->stateCv); os_mutex_unlock(req->stateLock); os_mutex_unlock(hgfsKReqWorkItemLock); goto done; } break; case HGFS_REQ_ABANDONED: case HGFS_REQ_ERROR: os_mutex_unlock(req->stateLock); os_mutex_unlock(hgfsKReqWorkItemLock); goto done; default: panic("Request object (%p) in unknown state: %u", req, req->state); } os_mutex_unlock(req->stateLock); /* * We're done with the work item list for now. Unlock it and let the file * system add requests while we're busy. */ os_mutex_unlock(hgfsKReqWorkItemLock); ret = channel->ops.send(gHgfsChannel, req); if (ret != 0) { /* * If the channel was previously open, make sure it's dead and gone * now. We do this because subsequent requests deserve a chance to * reopen it. */ os_mutex_lock(gHgfsChannelLock); gHgfsChannel->ops.close(gHgfsChannel); os_mutex_unlock(gHgfsChannelLock); } done: /* * If transport wants to process request async then it should have * taken reference for itself. If not we free it. */ if (os_add_atomic(&req->refcnt, -1) == 1) { os_zone_free(hgfsKReqZone, req); } } /* * NB: The work item lock is still held. * * XXX There may be some request on the sentList. what should we do about them ? */ /* * We're signaled to exit. Remove any items from the pending request list * before exiting. */ DblLnkLst_ForEachSafe(currNode, nextNode, &hgfsKReqWorkItemList) { req = DblLnkLst_Container(currNode, HgfsKReqObject, pendingNode); DblLnkLst_Unlink1(currNode); os_mutex_lock(req->stateLock); req->state = HGFS_REQ_ERROR; os_cv_signal(&req->stateCv); os_mutex_unlock(req->stateLock); /* * If we held the final reference to a request, free it. */ if (os_add_atomic(&req->refcnt, -1) == 1) { os_zone_free(hgfsKReqZone, req); } } os_mutex_unlock(hgfsKReqWorkItemLock); ws->running = FALSE; if (gHgfsChannel && gHgfsChannel->status == HGFS_CHANNEL_CONNECTED) { gHgfsChannel->ops.close(gHgfsChannel); } if (gHgfsChannelLock) { os_mutex_free(gHgfsChannelLock); } exit: os_thread_exit(0); } open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/debug.h0000644765153500003110000000662712220061556021265 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * debug.h -- * * Macros and includes for debugging. */ #ifndef _DEBUG_H_ #define _DEBUG_H_ #include #if defined __FreeBSD__ # include // for log(9) # include // for log(9) # include // for log(9), LOG_* macros #elif defined __APPLE__ # include // for panic # if defined VMX86_DEVEL # include // for kprintf # endif #endif #include // for struct vattr #include "hgfs_kernel.h" /* * Macros */ #define Panic(fmt, ...) panic(fmt, ##__VA_ARGS__) #define VM_DEBUG_ALWAYS (1) #define VM_DEBUG_FAIL VM_DEBUG_ALWAYS #define VM_DEBUG_NOTSUP VM_DEBUG_ALWAYS #define VM_DEBUG_ENTRY (1 << 1) #define VM_DEBUG_EXIT (1 << 2) #define VM_DEBUG_LOAD (1 << 3) #define VM_DEBUG_INFO (1 << 4) #define VM_DEBUG_STRUCT (1 << 5) #define VM_DEBUG_LIST (1 << 6) #define VM_DEBUG_CHPOLL (1 << 7) #define VM_DEBUG_RARE (1 << 8) #define VM_DEBUG_COMM (1 << 9) #define VM_DEBUG_REQUEST (1 << 10) #define VM_DEBUG_LOG (1 << 11) #define VM_DEBUG_ATTR (1 << 12) #define VM_DEBUG_DEVENTRY (1 << 13) #define VM_DEBUG_DEVDONE (1 << 14) #define VM_DEBUG_SIG (1 << 15) #define VM_DEBUG_ERROR (1 << 16) #define VM_DEBUG_HSHTBL (1 << 17) #define VM_DEBUG_HANDLE (1 << 18) #define VM_DEBUG_STATE (1 << 19) #define VM_DEBUG_VNODE (1 << 20) #define VM_DEBUG_ALL (~0) #if defined VMX86_DEVEL extern uint32_t gHgfsVmDebugLevel; #define VM_DEBUG_DEFAULT_LEV (VM_DEBUG_ALWAYS | VM_DEBUG_ENTRY | VM_DEBUG_EXIT | VM_DEBUG_FAIL) #endif #ifdef VMX86_DEVEL # if defined __FreeBSD__ # define DEBUG(type, fmt, ...) \ ((type & gHgfsVmDebugLevel) ? \ (log(LOG_NOTICE, "%s:%u: " fmt, \ __func__, __LINE__, ##__VA_ARGS__)) \ : 0) # elif defined __APPLE__ # define DEBUG(type, fmt, ...) \ HgfsDebugPrint(type, __func__, __LINE__, fmt, ##__VA_ARGS__) # endif #else # define DEBUG(type, ...) #endif /* * Global functions */ void HgfsDebugPrint(int type, const char *funcname, unsigned int linenum, const char *fmt, ...); void HgfsDebugPrintVattr(const HgfsVnodeAttr *vap); void HgfsDebugPrintOperation(HgfsKReqHandle req); #endif // _DEBUG_H_ open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/state.h0000644765153500003110000001576012220061556021315 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * state.h -- * * Public functions, types, and macros for Hgfs state that is attached to * vnodes. */ #ifndef _STATE_H_ #define _STATE_H_ /* * Includes */ #include /* MAXPATHLEN */ #include #include /* struct vnode */ #include "hgfsProto.h" #include "dbllnklst.h" #include "os.h" /* * Macros */ /* Number of buckets for the HgfsInode hash table */ #define HGFS_HT_NR_BUCKETS 5 /* Conversion between different state structures */ #if defined __FreeBSD__ # define HGFS_VP_TO_FP(vp) \ ((HgfsFile *)(vp)->v_data) #elif defined __APPLE__ # define HGFS_VP_TO_FP(vp) \ ((HgfsFile *)vnode_fsnode(vp)) #endif #define HGFS_FP_TO_VP(fp) \ (fp)->vnodep #define HGFS_VP_TO_FILENAME(vp) \ HGFS_VP_TO_FP(vp)->fileName #define HGFS_VP_TO_FILENAME_LENGTH(vp) \ HGFS_VP_TO_FP(vp)->fileNameLength #define HGFS_VP_TO_NODEID(vp) \ HGFS_VP_TO_FP(vp)->nodeId #define HGFS_VP_TO_RWLOCK(vp) \ HGFS_VP_TO_FP(vp)->rwlock #define HGFS_VP_TO_RWLOCKP(vp) \ &(HGFS_VP_TO_RWLOCK(vp)) #define HGFS_VP_TO_PERMISSIONS(vp) \ HGFS_VP_TO_FP(vp)->permissions #define HGFS_VP_TO_MMAPPED(vp) \ HGFS_VP_TO_FP(vp)->mmapped #define HGFS_VP_TO_FILESIZE(vp) \ HGFS_VP_TO_FP(vp)->fileSize /* * Types */ typedef uint32_t HgfsMode; typedef enum HgfsLockType { HGFS_WRITER_LOCK = 0, HGFS_READER_LOCK = 1 } HgfsLockType; typedef enum HgfsOpenType { OPENREQ_OPEN, /* A referenced handle in response to a vnode_open. */ OPENREQ_CREATE, /* A referenced handle in response to a vnode_create. */ OPENREQ_READ, /* A referenced handle in response to a vnode_read. */ OPENREQ_MMAP, /* A referenced handle in response to a vnode_mmap. */ } HgfsOpenType; /* * State kept per shared file from the host. * * All fields are read-only after initialization except reference count, which * is protected by the mutex. */ typedef struct HgfsFile { /* Link to place this state on the file state hash table */ DblLnkLst_Links listNode; /* * Full path of file within the filesystem (that is, taking /mnt/hgfs as /). * These are built from / in HgfsMount() and appending names as provided to * HgfsLookup(). Saving the length in HgfsIget() saves having to calculate * it in each HgfsMakeFullName(). */ char fileName[MAXPATHLEN + 1]; uint32_t fileNameLength; ino_t nodeId; /* * A pointer back to the vnode this HgfsFile is for. */ struct vnode *vnodep; /* * A pointer back to the parent directory vnode. */ struct vnode *parent; /* * Mode (permissions) specified for this file to be created with. This is necessary * because create is called with the mode then open is called without it. * We save this value in create and access it in open. * This field is set during initialization of HGFS and is never changed. */ int permissions; /* Mode that was used to open the handle on the host */ HgfsMode mode; Bool modeIsSet; OS_MUTEX_T *modeMutex; /* * Handle provided by reply to a request. If the reference count is > 0, the * the handle is valid. */ uint32_t handleRefCount; HgfsHandle handle; OS_RWLOCK_T *handleLock; /* * Locked along with the above, the additional reference which is the * internal references for opening which occurs alongside the actual open. */ uint32_t intHandleRefCount; /* * Indicates that memory mapping has been established for the file. * Used with the reference counting above. */ Bool mmapped; /* * One big difference between the Mac OS and FreeBSD VFS layers is that the * XNU kernel does not lock a vnode before it calls our VFS functions. As a * result, we have to provide our RwLock which is locked in macos/vnops.c * before any common functions are called. */ #if defined __APPLE__ OS_RWLOCK_T *rwFileLock; #endif /* * File size. HGFS must tell memory management system when file size is changed. * It implies that HGFS has to know if a write request writes data beyond EOF thus * it has to maintain local copy of file size that is kept in sync with the size * reported to memory manager/pager. */ off_t fileSize; } HgfsFile; /* The hash table for file state. */ typedef struct HgfsFileHashTable { OS_MUTEX_T *mutex; DblLnkLst_Links hashTable[HGFS_HT_NR_BUCKETS]; } HgfsFileHashTable; /* Forward declaration to prevent circular dependency between this and hgfsbsd.h. */ struct HgfsSuperInfo; int HgfsVnodeGet(struct vnode **vpp, struct vnode *dp, struct HgfsSuperInfo *sip, struct mount *vfsp, const char *fileName, HgfsFileType fileType, HgfsFileHashTable *htp, Bool createFile, int permissions, off_t fileSize); int HgfsVnodeGetRoot(struct vnode **vpp, struct HgfsSuperInfo *sip, struct mount *vfsp, const char *fileName, HgfsFileType fileType, HgfsFileHashTable *htp); int HgfsReleaseVnodeContext(struct vnode *vp, HgfsFileHashTable *htp); void HgfsNodeIdGet(HgfsFileHashTable *ht, const char *fileName, uint32_t fileNameLength, ino_t *outNodeId); int HgfsInitFileHashTable(HgfsFileHashTable *htp); void HgfsDestroyFileHashTable(HgfsFileHashTable *htp); Bool HgfsFileHashTableIsEmpty(struct HgfsSuperInfo *sip, HgfsFileHashTable *htp); /* Handle get/set/clear functions */ void HgfsSetOpenFileHandle(struct vnode *vp, HgfsHandle handle, HgfsMode openMode, HgfsOpenType openType); int HgfsGetOpenFileHandle(struct vnode *vp, HgfsHandle *outHandle); int HgfsReleaseOpenFileHandle(struct vnode *vp, HgfsOpenType openType, HgfsHandle *handleToClose); int HgfsCheckAndReferenceHandle(struct vnode *vp, int requestedOpenMode, HgfsOpenType openType); int HgfsHandleIncrementRefCount(struct vnode *vp); void HgfsSetFileSize(struct vnode *vp, off_t newSize); #endif /* _STATE_H_ */ open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/kernelStubsBSD.c0000644765153500003110000001375312220061556023022 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * kernelStubsBSD.c -- * * Stub functions for use by miscellaneous VMware code when brought into * the FreeBSD kernel. */ #include #include #include #include #include #include "kernelStubs.h" MALLOC_DEFINE(M_VMWARE_TEMP, "VMwareTemp", "VMware: Temporary Allocations"); void Log (const char *fmt, ...) __attribute__ ((alias ("Debug"))); /* *----------------------------------------------------------------------------- * * Debug -- * * Send a debugging message to the system log and/or console. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void Debug(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); } /* *----------------------------------------------------------------------------- * * Panic -- * * Print a panic message & induce a kernel panic. * * Results: * Does not return. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void Panic(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); panic(" "); } /* *----------------------------------------------------------------------------- * * Str_Strcpy -- * * Wrapper around strcpy that panics if the source is too long. * * Results: * Returns a pointer to buf. * * Side effects: * None. * *----------------------------------------------------------------------------- */ char * Str_Strcpy(char *buf, // OUT: destination buffer const char *src, // IN : source buffer size_t maxSize) // IN : size of buf { size_t srcLen = strlen(src); if (srcLen >= maxSize) { panic("%s:%d Buffer too small %p\n", __FILE__, __LINE__, buf); } return memcpy(buf, src, srcLen + 1); // Extra byte = terminator } /* *---------------------------------------------------------------------- * * Str_Vsnprintf -- * * Compatibility wrapper for vsnprintf(1). * * Results: * * int - number of bytes stored in 'str' (not including null * terminate character), -1 on overflow (insufficient space for * null terminate is considered overflow) * * NB: on overflow the buffer WILL be null terminated * * Side effects: * None * *---------------------------------------------------------------------- */ int Str_Vsnprintf(char *str, // OUT: destination buffer size_t size, // IN : size of str const char *format, // IN : format for vsnprintf va_list arguments) // IN : variadic args for vsnprintf { int retval; retval = vsnprintf(str, size, format, arguments); if (retval >= size) { retval = -1; } return retval; } /* *----------------------------------------------------------------------------- * * Str_Vasprintf -- * * Allocate and format a string, using the GNU libc way to specify the * format (i.e. optionally allow the use of positional parameters) * * Results: * The allocated string on success (if 'length' is not NULL, *length * is set to the length of the allocated string) * NULL on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ char * Str_Vasprintf(size_t *length, // OUT const char *format, // IN va_list arguments) // IN { /* * Simple implementation of Str_Vasprintf when userlevel libraries are not * available (e.g. for use in drivers). We just fallback to vsnprintf, * doubling if we didn't have enough space. */ unsigned int bufSize; char *buf; int retval; bufSize = strlen(format); buf = NULL; do { /* * Initial allocation of strlen(format) * 2. Should this be tunable? * XXX Yes, this could overflow and spin forever when you get near 2GB * allocations. I don't care. --rrdharan */ va_list tmpArgs; bufSize *= 2; buf = realloc(buf, bufSize); if (!buf) { return NULL; } va_copy(tmpArgs, arguments); retval = Str_Vsnprintf(buf, bufSize, format, tmpArgs); va_end(tmpArgs); } while (retval == -1); if (length) { *length = retval; } /* * Try to trim the buffer here to save memory? */ return buf; } /* *----------------------------------------------------------------------------- * * Str_Asprintf -- * * Same as Str_Vasprintf(), but parameters are passed inline --hpreg * * Results: * Same as Str_Vasprintf() * * Side effects: * Same as Str_Vasprintf() * *----------------------------------------------------------------------------- */ char * Str_Asprintf(size_t *length, // OUT const char *format, // IN ...) // IN { va_list arguments; char *result; va_start(arguments, format); result = Str_Vasprintf(length, format, arguments); va_end(arguments); return result; } open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/bdhandler.c0000644765153500003110000001342012220061556022102 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * bdhandler.c -- * */ #include "hgfsBd.h" #include "rpcout.h" #include "channel.h" static Bool HgfsBdChannelOpen(HgfsTransportChannel *channel); static void HgfsBdChannelClose(HgfsTransportChannel *channel); static HgfsKReqObject * HgfsBdChannelAllocate(size_t payloadSize, int flags); void HgfsBdChannelFree(HgfsKReqObject *req, size_t payloadSize); static int HgfsBdChannelSend(HgfsTransportChannel *channel, HgfsKReqObject *req); static HgfsTransportChannel gBdChannel = { .name = "backdoor", .ops.open = HgfsBdChannelOpen, .ops.close = HgfsBdChannelClose, .ops.allocate = HgfsBdChannelAllocate, .ops.free = HgfsBdChannelFree, .ops.send = HgfsBdChannelSend, .priv = NULL, .status = HGFS_CHANNEL_NOTCONNECTED }; /* *----------------------------------------------------------------------------- * * HgfsBdChannelOpen -- * * Open the backdoor in an idempotent way. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool HgfsBdChannelOpen(HgfsTransportChannel *channel) // IN: Channel { Bool ret; if ((ret = HgfsBd_OpenBackdoor((RpcOut **)&channel->priv))) { DEBUG(VM_DEBUG_INFO, "VMware hgfs: %s: backdoor opened.\n", __func__); ASSERT(channel->priv != NULL); channel->status = HGFS_CHANNEL_CONNECTED; } return ret; } /* *----------------------------------------------------------------------------- * * HgfsBdChannelClose -- * * Close the backdoor in an idempotent way. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsBdChannelClose(HgfsTransportChannel *channel) // IN: Channel { int ret; if (channel->priv == NULL) { return; } ret = HgfsBd_CloseBackdoor((RpcOut **)&channel->priv); if (!ret) { DEBUG(VM_DEBUG_FAIL, "VMware hgfs: %s: Failed to close backdoor.\n", __func__); } else { DEBUG(VM_DEBUG_INFO, "VMware hgfs: %s: backdoor closed.\n", __func__); } channel->status = HGFS_CHANNEL_NOTCONNECTED; } /* *----------------------------------------------------------------------------- * * HgfsBdChannelAllocate -- * * Allocate request in a way that is suitable for sending through * backdoor. * * Results: * NULL on failure; otherwise address of the new request. * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsKReqObject * HgfsBdChannelAllocate(size_t payloadSize, // IN: Size of allocation int flags) // IN: { return os_malloc(payloadSize, flags); } /* *----------------------------------------------------------------------------- * * HgfsBdChannelFree -- * * Free previously allocated request. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void HgfsBdChannelFree(HgfsKReqObject *req, // IN: size_t payloadSize) // IN: { ASSERT(req); os_free(req, payloadSize); } /* *---------------------------------------------------------------------- * * HgfsBdChannelSend -- * * Send a request via backdoor. * * Results: * 0 on success, negative error on failure. * * Side effects: * None * *---------------------------------------------------------------------- */ static int HgfsBdChannelSend(HgfsTransportChannel *channel, // IN: Channel HgfsKReqObject *req) // IN: request to send { char const *replyPacket = NULL; int ret; ASSERT(req); DEBUG(VM_DEBUG_INFO, "VMware hgfs: %s: backdoor sending.\n", __func__); bcopy(HGFS_SYNC_REQREP_CLIENT_CMD, req->__rpc_packet._command, HGFS_SYNC_REQREP_CLIENT_CMD_LEN); ret = HgfsBd_Dispatch(channel->priv, req->payload, &req->payloadSize, &replyPacket); os_mutex_lock(req->stateLock); /* * We have a response. (Maybe.) Re-lock the request, update its state, * etc. */ if ((ret == 0) && (req->state == HGFS_REQ_SUBMITTED)) { DEBUG(VM_DEBUG_INFO, "VMware hgfs: %s: Success in backdoor.\n", __func__); bcopy(replyPacket, req->payload, req->payloadSize); req->state = HGFS_REQ_COMPLETED; } else { DEBUG(VM_DEBUG_INFO, "hgfs: %s: Error in backdoor.\n", __func__); req->state = HGFS_REQ_ERROR; } os_cv_signal(&req->stateCv); os_mutex_unlock(req->stateLock); return ret; } /* *---------------------------------------------------------------------- * * HgfsGetBdChannel -- * * Get backdoor channel. * * Results: * Always return pointer to back door channel. * * Side effects: * None * *---------------------------------------------------------------------- */ HgfsTransportChannel* HgfsGetBdChannel(void) { return &gBdChannel; } open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/fsutil.h0000644765153500003110000001721412220061556021477 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * fsutil.h -- * * VFS helper functions that are shared between the FreeBSD and Mac OS * implementations of HGFS. */ #ifndef _HGFS_FSUTIL_H_ #define _HGFS_FSUTIL_H_ #include // for everything #include // for struct vnode #include // for struct mount #include // for name lookup goodness #include // for in-kernel file access flags (FREAD, etc) #include // for file flag bitmasks (S_IRWXU, etc) #include // for uiomove #include "debug.h" #include "hgfsUtil.h" #include "hgfs_kernel.h" #include "request.h" /* * Macros */ /* Sets the values of request headers properly */ #define HGFS_INIT_REQUEST_HDR(header, req, _op) \ do { \ header->id = HgfsKReq_GetId(req); \ header->op = _op; \ } while(0) /* Determine if this is the root vnode. */ #define HGFS_IS_ROOT_VNODE(sip, vp) \ (sip->rootVnode == vp) #define DIRSEPC '/' #define DIRSEPS "/" #define DIRSEPSLEN 1 #define HGFS_VA_MODE va_mode #define HGFS_VA_UID va_uid #define HGFS_VA_GID va_gid #define HGFS_VA_TYPE va_type #define HGFS_VA_NLINK va_nlink #define HGFS_VA_FSID va_fsid #define HGFS_VA_FILEID va_fileid #define HGFS_VATTR_TYPE_RETURN(vap, val) \ VATTR_RETURN(vap, va_type, val) #define HGFS_VATTR_MODE_RETURN(vap, val) \ VATTR_RETURN(vap, va_mode, val) #define HGFS_VATTR_NLINK_RETURN(vap, val) \ VATTR_RETURN(vap, va_nlink, val) #define HGFS_VATTR_UID_RETURN(vap, val) \ VATTR_RETURN(vap, va_uid, val) #define HGFS_VATTR_GID_RETURN(vap, val) \ VATTR_RETURN(vap, va_gid, val) #define HGFS_VATTR_FSID_RETURN(vap, val) \ VATTR_RETURN(vap, va_fsid, val) #define HGFS_VATTR_FILEID_RETURN(vap, val) \ VATTR_RETURN(vap, va_fileid, val) #if defined __APPLE__ #define HGFS_VA_DATA_SIZE va_data_size #define HGFS_VA_DATA_BYTES va_data_size #define HGFS_VA_ACCESS_TIME_SEC va_access_time #define HGFS_VA_ACCESS_TIME va_access_time #define HGFS_VA_MODIFY_TIME_SEC va_modify_time #define HGFS_VA_MODIFY_TIME va_modify_time #define HGFS_VA_CREATE_TIME_SEC va_create_time #define HGFS_VA_CREATE_TIME va_create_time #define HGFS_VA_CHANGE_TIME_SEC va_change_time #define HGFS_VA_CHANGE_TIME va_change_time #define HGFS_VA_BLOCK_SIZE va_iosize #define HGFS_VATTR_IS_ACTIVE(vap, attr) \ VATTR_IS_ACTIVE(vap, attr) #define HGFS_VATTR_MODE_IS_ACTIVE(vap, mode) \ VATTR_IS_ACTIVE(vap, mode) #define HGFS_VATTR_SIZE_IS_ACTIVE(vap, size) \ VATTR_IS_ACTIVE(vap, size) #define HGFS_VATTR_BLOCKSIZE_RETURN(vap, val) \ VATTR_RETURN(vap, va_iosize, val) #define HGFS_VATTR_BYTES_RETURN(vap, val) #define HGFS_VATTR_SIZE_RETURN(vap, val) \ VATTR_RETURN(vap, va_data_size, val) #define HGFS_VATTR_ACCESS_TIME_SET_SUPPORTED(vap) \ VATTR_SET_SUPPORTED(vap, va_access_time) #define HGFS_VATTR_MODIFY_TIME_SET_SUPPORTED(vap) \ VATTR_SET_SUPPORTED(vap, va_modify_time) #define HGFS_VATTR_CREATE_TIME_SET_SUPPORTED(vap) \ VATTR_SET_SUPPORTED(vap, va_create_time) #define HGFS_VATTR_CHANGE_TIME_SET_SUPPORTED(vap) \ VATTR_SET_SUPPORTED(vap, va_change_time) #elif defined __FreeBSD__ #define HGFS_VA_DATA_SIZE va_size #define HGFS_VA_DATA_BYTES va_bytes #define HGFS_VA_ACCESS_TIME_SEC va_atime.tv_sec #define HGFS_VA_ACCESS_TIME va_atime #define HGFS_VA_MODIFY_TIME_SEC va_mtime.tv_sec #define HGFS_VA_MODIFY_TIME va_mtime #define HGFS_VA_CHANGE_TIME_SEC va_ctime.tv_sec #define HGFS_VA_CHANGE_TIME va_ctime #define HGFS_VA_CREATE_TIME_SEC va_birthtime.tv_sec #define HGFS_VA_CREATE_TIME va_birthtime #define HGFS_VA_BLOCK_SIZE va_blocksize #define HGFS_VATTR_IS_ACTIVE(vap, attr) \ (vap->attr != VNOVAL) #define HGFS_VATTR_MODE_IS_ACTIVE(vap, mode) \ (vap->mode != (mode_t)VNOVAL) #define HGFS_VATTR_SIZE_IS_ACTIVE(vap, size) \ (vap->size != (u_quad_t)VNOVAL) #define VATTR_SET_SUPPORTED(vap, time) #define HGFS_VATTR_BLOCKSIZE_RETURN(vap, val) \ VATTR_RETURN(vap, va_blocksize, val) #define HGFS_VATTR_BYTES_RETURN(vap, val) \ VATTR_RETURN(vap, va_bytes, val) #define HGFS_VATTR_SIZE_RETURN(vap, val) \ VATTR_RETURN(vap, va_size, val) /* NULL macros */ #define HGFS_VATTR_ACCESS_TIME_SET_SUPPORTED(vap) #define HGFS_VATTR_MODIFY_TIME_SET_SUPPORTED(vap) #define HGFS_VATTR_CREATE_TIME_SET_SUPPORTED(vap) #define HGFS_VATTR_CHANGE_TIME_SET_SUPPORTED(vap) #endif /* * Types */ /* * Hgfs permissions are similar to Unix permissions in that they both include * bits for read vs. write vs. execute permissions. Since permissions of * owner, groups and others are passed as individual components by Hgfs, * we need simple bit shift operations for translation between Hgfs and Unix * permissions. */ #define HGFS_ATTR_SPECIAL_PERM_SHIFT 9 #define HGFS_ATTR_OWNER_PERM_SHIFT 6 #define HGFS_ATTR_GROUP_PERM_SHIFT 3 /* Solaris times support nsecs, so only use these functions directly */ #define HGFS_SET_TIME(unixtm, nttime) \ HgfsConvertFromNtTimeNsec(&unixtm, nttime) #define HGFS_GET_TIME(unixtm) \ HgfsConvertTimeSpecToNtTime(&unixtm) /* Utility functions */ int HgfsSubmitRequest(HgfsSuperInfo *sip, HgfsKReqHandle req); int HgfsGetStatus(HgfsKReqHandle req, uint32_t minSize); int HgfsEscapeBuffer(char const *bufIn, uint32 sizeIn, uint32 sizeBufOut, char *bufOut); int HgfsUnescapeBuffer(char *bufIn, uint32 sizeIn); int HgfsGetOpenMode(uint32 flags); int HgfsGetOpenFlags(uint32 flags); int HgfsMakeFullName(const char *path, uint32_t pathLen, const char *file, size_t fileLen, char *outBuf, ssize_t bufSize); void HgfsAttrToBSD(struct vnode *vp, const HgfsAttrV2 *hgfsAttrV2, HgfsVnodeAttr *vap); Bool HgfsSetattrCopy(HgfsVnodeAttr *vap, HgfsAttrV2 *hgfsAttrV2, HgfsAttrHint *hints); int HgfsStatusToBSD(HgfsStatus hgfsStatus); Bool HgfsAttemptToCreateShare(const char *path, int flag); int HgfsNameFromWireEncoding(const char *bufIn, uint32 bufInSize, char *bufOut, uint32 bufOutSize); int HgfsNameToWireEncoding(const char *bufIn, uint32 bufInSize, char *bufOut, uint32 bufOutSize); #endif // _HGFS_FSUTIL_H_ open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/transport.h0000644765153500003110000000307112220061556022221 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * transport.h -- * * Communication with HGFS server. */ #ifndef _HGFS_TRANSPORT_COMMON_H_ #define _HGFS_TRANSPORT_COMMON_H_ #include "hgfs_kernel.h" /* Internal transport functions used by both FreeBSD and Mac OS */ int HgfsSendOpenRequest(HgfsSuperInfo *sip, int openMode, int openFlags, int permissions, char *fullPath, uint32 fullPathLen, HgfsHandle *handle); int HgfsSendOpenDirRequest(HgfsSuperInfo *sip, char *fullPath, uint32 fullPathLen, HgfsHandle *handle); int HgfsCloseServerDirHandle(HgfsSuperInfo *sip, HgfsHandle handleToClose); int HgfsCloseServerFileHandle(HgfsSuperInfo *sip, HgfsHandle handleToClose); #endif // _HGFS_TRANSPORT_COMMON_H_ open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/vfsops.c0000644765153500003110000002672012220061556021506 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vfsops.c -- * * VFS operations for the FreeBSD Hgfs client. */ #include #include #include #include #include #include #if __FreeBSD_version >= 700000 #include #endif #include "hgfs_kernel.h" #include "request.h" #include "debug.h" #include "hgfsDevLinux.h" #include "os.h" #include "compat_freebsd.h" #include "vfsopscommon.h" /* * Local functions (prototypes) */ static vfs_mount_t HgfsVfsMount; static vfs_unmount_t HgfsVfsUnmount; static vfs_root_t HgfsVfsRoot; static vfs_statfs_t HgfsVfsStatfs; static vfs_init_t HgfsVfsInit; static vfs_uninit_t HgfsVfsUninit; /* * Global data */ /* * Hgfs VFS operations vector */ static struct vfsops HgfsVfsOps = { .vfs_mount = HgfsVfsMount, .vfs_unmount = HgfsVfsUnmount, .vfs_root = HgfsVfsRoot, .vfs_quotactl = vfs_stdquotactl, .vfs_statfs = HgfsVfsStatfs, .vfs_sync = vfs_stdsync, .vfs_vget = vfs_stdvget, .vfs_fhtovp = vfs_stdfhtovp, .vfs_checkexp = vfs_stdcheckexp, #if __FreeBSD_version < 700000 .vfs_vptofh = vfs_stdvptofh, #endif .vfs_init = HgfsVfsInit, .vfs_uninit = HgfsVfsUninit, .vfs_extattrctl = vfs_stdextattrctl, .vfs_sysctl = vfs_stdsysctl, }; /* * Kernel module glue to execute init/uninit at load/unload. */ VFS_SET(HgfsVfsOps, vmhgfs, 0); /* * Local functions (definitions) */ /* *----------------------------------------------------------------------------- * * HgfsVfsMount * * "The VFS_MOUNT() macro mounts a file system into the system's * namespace or updates the attributes of an already mounted file * system." (VFS_MOUNT(9).) * * Results: * Zero on success, an appropriate system error on failure. * * Side effects: * Done. * *----------------------------------------------------------------------------- */ static int HgfsVfsMount(struct mount *mp, // IN: structure representing the file system struct thread *td) // IN: thread which is mounting the file system { HgfsSuperInfo *sip; struct vnode *vp; int ret = 0; char *target; int error; int size; Bool *uidSet = NULL; int *uid = NULL; Bool *gidSet = NULL; int *gid = NULL; /* * - Examine/validate mount flags from userland. * - Grab mount options from userland, validate. (Paths, etc.) * - Allocate HgfsSuperInfo, root vnode; bind the two. * - Update mnt_flag/mnt_kern_flags (ex: MPSAFE?) * - vfs_getnewfsid * - vfs_mountedfrom */ /* * We do not support any of the user's mount options, so fail any mount * attempt with a non-zero mnt_flag. (It'd be quite a shock to find out * that a share successfully mounted read-only is really writeable!) */ if (mp->mnt_flag != 0) { return EOPNOTSUPP; } /* * Since Hgfs requires the caller to be root, only allow mount attempts made * by the superuser. */ if ((ret = suser(td)) != 0) { return ret; } /* * Allocate a new HgfsSuperInfo structure. This is the super structure * maintained for each file system. (With M_WAITOK, this call cannot fail.) */ sip = os_malloc(sizeof *sip, M_WAITOK | M_ZERO); mp->mnt_data = sip; error = HgfsInitFileHashTable(&sip->fileHashTable); if (error) { goto out; } /* * Allocate the root vnode, then record it and the file system information * in our superinfo. */ error = HgfsVnodeGetRoot(&vp, sip, mp, "/", HGFS_FILE_TYPE_DIRECTORY, &sip->fileHashTable); if (error) { HgfsDestroyFileHashTable(&sip->fileHashTable); goto out; } sip->vfsp = mp; sip->rootVnode = vp; /* We're finished with the root vnode, so unlock it. */ COMPAT_VOP_UNLOCK(vp, 0, td); /* * Initialize this file system's Hgfs requests container. */ sip->reqs = HgfsKReq_AllocateContainer(); /* * Since this implementation supports fine-grained locking, inform the kernel * that we're MPSAFE. (This is in the context of protecting its own data * structures, not oplocks/leases with the VM's host.) */ MNT_ILOCK(mp); mp->mnt_kern_flag |= MNTK_MPSAFE; MNT_IUNLOCK(mp); /* Get a new unique filesystem ID */ vfs_getnewfsid(mp); error = vfs_getopt(mp->mnt_optnew, "target", (void **)&target, &size); if (error || target[size - 1] != '\0') { target = "host:hgfs"; } /* Get uidSet */ error = vfs_getopt(mp->mnt_optnew, "uidSet", (void**)&uidSet, &size); if (!error && size == sizeof(Bool) && uidSet) { sip->uidSet = *uidSet; } else { sip->uidSet = FALSE; } /* Get uid */ error = vfs_getopt(mp->mnt_optnew, "uid", (void**)&uid, &size); if (!error && size == sizeof(int) && uid) { sip->uid = *uid; } else { sip->uidSet = FALSE; } /* Get gidSet */ error = vfs_getopt(mp->mnt_optnew, "gidSet", (void**)&gidSet, &size); if (!error && size == sizeof(Bool) && gidSet) { sip->gidSet = *gidSet; } else { sip->gidSet = FALSE; } /* Get gid */ error = vfs_getopt(mp->mnt_optnew, "gid", (void**)&gid, &size); if (!error && size == sizeof(int) && gid) { sip->gid = *gid; } else { sip->gidSet = FALSE; } vfs_mountedfrom(mp, target); /* * Fill in the statfs structure. Note that even if HgfsStatfsInt * fails, we shall just log the error and move on, since it is * not a critical operation. */ error = HgfsStatfsInt(vp, &mp->mnt_stat); if (error) { DEBUG(VM_DEBUG_FAIL, "HgfsStatfsInt failed with ret = %d\n", ret); error = 0; } DEBUG(VM_DEBUG_LOAD, "Exit\n"); out: if (error) { os_free(sip, sizeof *sip); } return error; } /* *----------------------------------------------------------------------------- * * HgfsVfsUnmount -- * * "VFS_UNMOUNT -- unmount a file system", VFS_UNMOUNT(9). * * Results: * Zero if filesystem unmounted, otherwise errno. * * Side effects: * This call may fail if the filesystem is busy & MNT_FORCE not set. * *----------------------------------------------------------------------------- */ static int HgfsVfsUnmount(struct mount *mp, int mntflags, struct thread *td) { HgfsSuperInfo *sip; int ret = 0; int flags = 0; sip = (HgfsSuperInfo *)mp->mnt_data; ASSERT(sip); /* * If there are pending requests & we're not being forced out, tell the user * that we're still busy. */ if (((mntflags & MNT_FORCE) == 0) && ((HgfsKReq_ContainerIsEmpty(sip->reqs) == FALSE) || (HgfsFileHashTableIsEmpty(sip, &sip->fileHashTable) == FALSE))) { return EBUSY; } /* * If the user wants us out, cancel all pending Hgfs requests and fail all * existing vnode operations. */ if (mntflags & MNT_FORCE) { HgfsKReq_CancelRequests(sip->reqs); flags |= FORCECLOSE; } /* * Vflush will wait until all pending vnode operations are complete. */ ret = vflush(mp, 1, flags, td); if (ret != 0) { return ret; } HgfsDestroyFileHashTable(&sip->fileHashTable); /* * Now we can throw away our superinfo. Let's reclaim everything allocated * during HgfsVfsMount. */ HgfsKReq_FreeContainer(sip->reqs); mp->mnt_data = NULL; os_free(sip, sizeof *sip); DEBUG(VM_DEBUG_LOAD, "Exit\n"); return 0; } /* *----------------------------------------------------------------------------- * * HgfsVfsStatvs -- * * "VFS_STATFS(9) - return file system status." * * Results: * Zero on success and non-zero error code on failure. * * Side effects: * Caller's statfs structure is populated. * *----------------------------------------------------------------------------- */ static int HgfsVfsStatfs(struct mount *mp, struct statfs *sbp, struct thread *td) { int ret = 0; struct vnode *vp; /* We always want HGFS_BLOCKSIZE to be a power of two */ ASSERT_ON_COMPILE(HGFS_IS_POWER_OF_TWO(HGFS_BLOCKSIZE)); /* * This fills in file system ID and the type number that * we got from a call to vfs_getnewfsid() in HgfsVfsMount() */ bcopy(&mp->mnt_stat, sbp, sizeof mp->mnt_stat); ret = HgfsVfsRoot(mp, LK_SHARED, &vp, td); if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsVfsRoot failed\n"); return ret; } ret = HgfsStatfsInt(vp, sbp); if (ret) { DEBUG(VM_DEBUG_FAIL, "HgfsStatfsInt failed with ret = %d\n", ret); goto out; } out: /* Drop the reference and shared lock that we acquired in HgfsVfsRoot */ vput(vp); return ret; } /* *----------------------------------------------------------------------------- * * HgfsVfsRoot -- * * Retrieves the root Vnode of the specified filesystem. * * Results: * Zero if successful, non-zero otherwise. * * Side effects: * Sets *vpp. * *----------------------------------------------------------------------------- */ static int HgfsVfsRoot(struct mount *mp, // IN: Filesystem structure int flags, // IN: Flags to vget struct vnode **vpp, // OUT: Address of root vnode struct thread *td) // IN: Thread structure { HgfsSuperInfo *sip = (HgfsSuperInfo *)mp->mnt_data; int ret = 0; *vpp = NULL; ret = vget(sip->rootVnode, flags, td); if (ret == 0) { *vpp = sip->rootVnode; } return ret; } /* *----------------------------------------------------------------------------- * * HgfsVfsInit -- * * Initializes the Hgfs filesystem implementation * * Results: * Zero if successful, an errno-type value otherwise. * * Side effects: * Initializes the hgfs request processing system. * *----------------------------------------------------------------------------- */ static int HgfsVfsInit(struct vfsconf *vfsconf) { int ret = 0; /* Initialize the os memory allocation and thread synchronization subsystem. */ if ((ret = os_init()) != 0) { return ret; } ret = HgfsKReq_SysInit(); DEBUG(VM_DEBUG_LOAD, "Hgfs filesystem loaded"); return ret; } /* *----------------------------------------------------------------------------- * * HgfsVfsUninit -- * * Tears down the Hgfs filesystem module state * * Results: * Zero if successful, an errno-type value otherwise. * * Side effects: * Can no longer use any hgfs file systems. * *----------------------------------------------------------------------------- */ static int HgfsVfsUninit(struct vfsconf *vfsconf) { int ret = 0; ret = HgfsKReq_SysFini(); os_cleanup(); DEBUG(VM_DEBUG_LOAD, "Hgfs filesystem unloaded"); return ret; } open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/vnopscommon.h0000644765153500003110000000733012220061556022545 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vnopscommon.h -- * * Common VFS vnop implementations that are shared between both Mac OS and FreeBSD. */ #ifndef _HGFS_VNOPS_COMMON_H_ #define _HGFS_VNOPS_COMMON_H_ #include "hgfs_kernel.h" /* * Macros */ /* Access uio struct information in a Mac OS / FreeBSD independent manner. */ #if defined __FreeBSD__ #define HGFS_UIOP_TO_RESID(uiop) \ ((uiop)->uio_resid) #define HGFS_UIOP_TO_OFFSET(uiop) \ ((uiop)->uio_offset) #define HGFS_UIOP_SET_OFFSET(uiop, offset) \ ((uiop)->uio_offset = (offset)) #elif defined __APPLE__ #define HGFS_UIOP_TO_RESID(uiop) \ (uio_resid(uiop)) #define HGFS_UIOP_TO_OFFSET(uiop) \ (uio_offset(uiop)) #define HGFS_UIOP_SET_OFFSET(uiop, offset) \ (uio_setoffset(uiop, offset)) #endif /* Access vnode struct information in a Mac OS / FreeBSD independent manner. */ #if defined __FreeBSD__ #define HGFS_VP_TO_VTYPE(vp) \ (vp->v_type) #define HGFS_VPP_GET_IOCOUNT(vpp) \ (vref(*vpp)) #elif defined __APPLE__ #define HGFS_VP_TO_VTYPE(vp) \ (vnode_vtype(vp)) #define HGFS_VPP_GET_IOCOUNT(vpp) \ (vnode_get(*vpp)) #endif /* Internal Vnops functions used by both FreeBSD and Mac OS */ int HgfsReaddirInt(struct vnode *vp, struct uio *uiop, int *eofp); int HgfsSetattrInt(struct vnode *vp, HgfsVnodeAttr *vap); int HgfsGetattrInt(struct vnode *vp, HgfsVnodeAttr *vap); int HgfsRmdirInt(struct vnode *dvp, struct vnode *vp, struct componentname *cnp); int HgfsRemoveInt(struct vnode *vp); int HgfsCloseInt(struct vnode *vp, int mode); int HgfsOpenInt(struct vnode *vp, int fflag, HgfsOpenType openType); int HgfsLookupInt(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp); int HgfsCreateInt(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, int mode); int HgfsReadInt(struct vnode *vp, struct uio *uiop, Bool pagingIo); int HgfsReadlinkInt(struct vnode *vp, struct uio *uiop); int HgfsWriteInt(struct vnode *vp, struct uio *uiop, int ioflag, Bool pagingIo); int HgfsMkdirInt(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, int mode); int HgfsRenameInt(struct vnode *fvp, struct vnode *tdvp, struct vnode *tvp, struct componentname *tcnp); int HgfsAccessInt(struct vnode *vp, HgfsAccessMode mode); int HgfsSymlinkInt(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, char *targetName); int HgfsMmapInt(struct vnode *vp, int accessMode); int HgfsMnomapInt(struct vnode *vp); #endif // _HGFS_VNOPS_COMMON_H_ open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/os.h0000644765153500003110000001176612220061556020620 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * os.h -- * * Wrappers for OS specific functions that are different between Mac OS and FreeBsd. * 1. Implementation Mac OS / FreeBSD independent memory allocation and * thread synchronization routines. * 2. Interaction with memory manager/pager. */ #ifndef _OS_H_ #define _OS_H_ #if defined __FreeBSD__ # include // for # include # include # include // for struct mtx # include // for struct mtx # include #elif defined __APPLE__ # include # include #endif #include #include "vm_basic_types.h" #if defined __FreeBSD__ typedef struct proc *OS_THREAD_T; typedef struct mtx OS_MUTEX_T; typedef struct sx OS_RWLOCK_T; typedef struct cv OS_CV_T; #elif defined __APPLE__ typedef thread_t OS_THREAD_T; typedef lck_mtx_t OS_MUTEX_T; typedef lck_rw_t OS_RWLOCK_T; /* * In Mac OS, a kernel thread waits on a 32-bit integer. To avoid collision, * Apple recommends that threads wait on the address of an object. */ typedef void *OS_CV_T; #endif /* OS_ERR is the error code returned by os_* functions on error. */ #define OS_ERR (-1) int os_init(void); void os_cleanup(void); /* * There does not seem to be a public zone allocator exposed in Mac OS. We create * a zone wrapper around the FreeBSD zone allocator so that we can keep the * FreeBSD zone allocator and support Mac OS at the same time. */ struct os_zone_struct; typedef struct os_zone_struct OS_ZONE_T; /* * Provide zone allocator function prototypes with the same signature as * the ones used in the FreeBSD kernel. This way they can be used both with * the FreeBSD uma allocator and the custom Mac OS allocation functions. */ typedef int (*os_zone_ctor)(void *mem, int size, void *arg, int flags); typedef void (*os_zone_dtor)(void *mem, int size, void *arg); typedef int (*os_zone_init)(void *mem, int size, int flags); typedef void (*os_zone_finit)(void *mem, int size); OS_ZONE_T *os_zone_create(char *zoneName, size_t objectSize, os_zone_ctor ctor, os_zone_dtor dtor, os_zone_init init, os_zone_finit finit, int align, uint32 flags); void os_zone_destroy(OS_ZONE_T *zone); void *os_zone_alloc(OS_ZONE_T *zone, int flags); void os_zone_free(OS_ZONE_T *zone, void *mem); void *os_malloc(size_t size, int flags); void os_free(void *mem, size_t size); extern OS_MUTEX_T *os_mutex_alloc_init(const char *mtxName); extern void os_mutex_free(OS_MUTEX_T *mtx); extern void os_mutex_lock(OS_MUTEX_T *mtx); extern void os_mutex_unlock(OS_MUTEX_T *mtx); extern OS_RWLOCK_T *os_rw_lock_alloc_init(const char *lckName); extern void os_rw_lock_free(OS_RWLOCK_T *lck); extern void os_rw_lock_lock_shared(OS_RWLOCK_T *lck); extern void os_rw_lock_lock_exclusive(OS_RWLOCK_T *lck); extern void os_rw_lock_unlock_shared(OS_RWLOCK_T *lck); extern void os_rw_lock_unlock_exclusive(OS_RWLOCK_T *lck); extern void os_cv_init(OS_CV_T *cv, const char *name); extern void os_cv_destroy(OS_CV_T *cv); extern void os_cv_signal(OS_CV_T *cv); extern int os_cv_wait(OS_CV_T *cv, OS_MUTEX_T *mtx); extern int os_thread_create(void *function, void *parameter, const char *threadName, OS_THREAD_T *newThread); extern void os_thread_join(OS_THREAD_T thread, OS_MUTEX_T *mtx); extern void os_thread_release(OS_THREAD_T thread); extern void os_thread_exit(int errorCode); extern int os_add_atomic(unsigned int *address, int amount); extern int os_component_to_utf8_decomposed(const char *bufIn, uint32 bufInSize, char *bufOut, size_t *sizeOut, uint32 bufOutSize); extern int os_component_to_utf8_precomposed(const char *bufIn, uint32 bufInSize, char *bufOut, size_t *sizeOut, uint32 bufOutSize); extern int os_path_to_utf8_precomposed(const char *bufIn, uint32 bufInSize, char *bufOut, uint32 bufOutSize); extern Bool os_utf8_conversion_needed(void); // Memory manager/pager functions void os_SetSize(struct vnode *vp, off_t newSize); int os_FlushRange(struct vnode *vp, off_t start, uint32_t length); #endif // ifndef _OS_H_ open-vm-tools-9.4.0-1280544/modules/freebsd/vmhgfs/vfsopscommon.c0000644765153500003110000001031112220061556022704 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vnopscommon.h -- * * Common VFS vfsop implementations that are shared between both Mac OS and FreeBSD. */ #include // for everything #include // for struct vnode #include "fsutil.h" #include "state.h" #include "debug.h" #include "request.h" #include "vnopscommon.h" #include "vfsopscommon.h" /* *---------------------------------------------------------------------------- * * HgfsStatfsInt -- * * Hgfs statfs method. Called by HgfsVfsStatfs on FreeBSD and * HgfsVfsGetattr on Mac OS. * * Results: * Returns 0 on success and an error code on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int HgfsStatfsInt(struct vnode *vp, // IN: vnode HgfsStatfs *stat) // IN: statfs structure to fill in { HgfsSuperInfo *sip; HgfsKReqHandle req; HgfsRequest *requestHeader; HgfsReply *replyHeader; HgfsRequestQueryVolumeV3 *request; HgfsReplyQueryVolumeV3 *reply; uint32 reqSize; uint32 reqBufferSize; uint32 repSize; char *fullPath = NULL; uint32 fullPathLen; int ret = 0; /* Get pointer to the superinfo. */ sip = HGFS_VP_TO_SIP(vp); if (!sip) { DEBUG(VM_DEBUG_FAIL, "couldn't acquire superinfo\n"); return ENOTSUP; } /* Prepare the request */ req = HgfsKReq_AllocateRequest(sip->reqs, &ret); if (!req) { return ret; } requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req); request = (HgfsRequestQueryVolumeV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader); /* Initialize the request header */ requestHeader->id = HgfsKReq_GetId(req); requestHeader->op = HGFS_OP_QUERY_VOLUME_INFO_V3; request->fileName.flags = 0; request->fileName.fid = HGFS_INVALID_HANDLE; request->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; request->reserved = 0; reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); reqBufferSize = HGFS_NAME_BUFFER_SIZET(HGFS_PACKET_MAX, reqSize); fullPath = HGFS_VP_TO_FILENAME(vp); fullPathLen = HGFS_VP_TO_FILENAME_LENGTH(vp); ret = HgfsNameToWireEncoding(fullPath, fullPathLen + 1, request->fileName.name, reqBufferSize); if (ret < 0) { DEBUG(VM_DEBUG_FAIL, "Could not encode to wire format"); ret = -ret; goto destroyOut; } request->fileName.length = ret; reqSize += ret; /* The request size includes header, request and file length */ HgfsKReq_SetPayloadSize(req, reqSize); ret = HgfsSubmitRequest(sip, req); if (ret) { /* HgfsSubmitRequest() destroys the request if necessary */ goto out; } replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req); reply = (HgfsReplyQueryVolumeV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader); repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply); ret = HgfsGetStatus(req, repSize); if (ret) { DEBUG(VM_DEBUG_FAIL, "reply was invalid"); goto destroyOut; } ret = HgfsStatusToBSD(replyHeader->status); if (ret) { goto destroyOut; } stat->f_bsize = HGFS_BLOCKSIZE; stat->f_iosize = HGFS_BLOCKSIZE; stat->f_blocks = HGFS_CONVERT_TO_BLOCKS(reply->totalBytes); stat->f_bfree = HGFS_CONVERT_TO_BLOCKS(reply->freeBytes); stat->f_bavail = stat->f_bfree; destroyOut: HgfsKReq_ReleaseRequest(sip->reqs, req); out: return ret; } open-vm-tools-9.4.0-1280544/modules/Makefile.am0000644765153500003110000000562712220061556017155 0ustar dtormtsall: modules .PHONY: modules $(MODULES) modules: $(MODULES) modulesrc = $(abs_top_srcdir)/modules $(MODULES): $(MAKE) VM_UNAME=$(KERNEL_RELEASE) MV=mv RM=rm \ OVT_SOURCE_DIR=$(abs_top_srcdir) \ MODULEBUILDDIR=$(modulesrc)/$(MODULES_OS) \ $(EXTRA_ARGS) -C "$(modulesrc)/$(MODULES_OS)/$@" if FREEBSD_CUSTOM_SYSDIR EXTRA_ARGS = EXTRA_ARGS += "SYSDIR=@SYSDIR@" endif if LINUX export LINUXINCLUDE := @LINUXINCLUDE@ export vmblockdir := $(MODULES_DIR)/fs/vmblock export vmcidir := $(MODULES_DIR)/drivers/misc export vmhgfsdir := $(MODULES_DIR)/fs/vmhgfs export vmsyncdir := $(MODULES_DIR)/drivers/misc export vmxnetdir := $(MODULES_DIR)/drivers/net export vsockdir := $(MODULES_DIR)/net/vsock if WITH_ROOT_PRIVILEGES export DEPMOD := depmod -a $(KERNEL_RELEASE) endif WITH_ROOT_PRIVILEGES include_HEADERS = $(top_srcdir)/lib/include/vmci_sockets.h endif LINUX if SOLARIS export vmhgfsdir := $(MODULES_DIR) # Solaris does not have Kbuild-like system so we need to supply # compiler and linker and other items discovered by configure # script. EXTRA_ARGS = EXTRA_ARGS += "CC=$(CC)" EXTRA_ARGS += "CC_WARNINGS=$(CC_WARNINGS)" EXTRA_ARGS += "GLOBAL_DEFS=$(GLOBAL_DEFS)" EXTRA_ARGS += "LD=$(LD)" EXTRA_ARGS += "HAVE_GNU_LD=$(HAVE_GNU_LD)" endif ## Automake will supplement its own "clean" targets with this. clean-local: for MOD in $(MODULES); do \ if [ -d "$(modulesrc)/$(MODULES_OS)/$$MOD" ]; then \ $(MAKE) VM_UNAME=$(KERNEL_RELEASE) MV=mv RM=rm \ -C "$(modulesrc)/$(MODULES_OS)/$$MOD" clean || exit 1; \ fi \ done rm -f $(modulesrc)/$(MODULES_OS)/*.o $(modulesrc)/$(MODULES_OS)/*.ko rm -f $(modulesrc)/$(MODULES_OS)/VMwareVMCIModule.symvers install-exec-hook: if SOLARIS for MOD in $(MODULES); do \ $(MAKE) VM_UNAME=$(KERNEL_RELEASE) MV=mv RM=rm \ -C "$(modulesrc)/$(MODULES_OS)/$$MOD" install || exit 1; \ done endif if FREEBSD for MOD in $(MODULES); do \ $(INSTALL) -d $(DESTDIR)$(MODULES_DIR); \ $(INSTALL) -m644 $(modulesrc)/$(MODULES_OS)/$$MOD.ko \ $(DESTDIR)$(MODULES_DIR); \ done endif if LINUX for MOD in $(MODULES); do \ $(INSTALL) -d $(DESTDIR)`eval echo '$$'$${MOD}dir`; \ $(INSTALL) -m644 $(modulesrc)/$(MODULES_OS)/$$MOD/$$MOD.ko \ $(DESTDIR)`eval echo '$$'$${MOD}dir`; \ done eval "$$DEPMOD" endif uninstall-hook: for MOD in $(MODULES); do \ rm -f $(DESTDIR)`eval echo '$$'$${MOD}dir`/$$MOD.ko &> /dev/null;\ done eval "$$DEPMOD" open-vm-tools-9.4.0-1280544/modules/Makefile.in0000644765153500003110000004726312220061624017164 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = modules DIST_COMMON = $(am__include_HEADERS_DIST) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__include_HEADERS_DIST = $(top_srcdir)/lib/include/vmci_sockets.h am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(includedir)" HEADERS = $(include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ modulesrc = $(abs_top_srcdir)/modules @FREEBSD_CUSTOM_SYSDIR_TRUE@EXTRA_ARGS = "SYSDIR=@SYSDIR@" # Solaris does not have Kbuild-like system so we need to supply # compiler and linker and other items discovered by configure # script. @SOLARIS_TRUE@EXTRA_ARGS = "CC=$(CC)" "CC_WARNINGS=$(CC_WARNINGS)" \ @SOLARIS_TRUE@ "GLOBAL_DEFS=$(GLOBAL_DEFS)" "LD=$(LD)" \ @SOLARIS_TRUE@ "HAVE_GNU_LD=$(HAVE_GNU_LD)" @LINUX_TRUE@include_HEADERS = $(top_srcdir)/lib/include/vmci_sockets.h all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu modules/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(HEADERS) installdirs: for dir in "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-includeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-includeHEADERS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-hook .MAKE: install-am install-exec-am install-strip uninstall-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-local cscopelist ctags distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-exec-hook install-html \ install-html-am install-includeHEADERS install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-hook uninstall-includeHEADERS all: modules .PHONY: modules $(MODULES) modules: $(MODULES) $(MODULES): $(MAKE) VM_UNAME=$(KERNEL_RELEASE) MV=mv RM=rm \ OVT_SOURCE_DIR=$(abs_top_srcdir) \ MODULEBUILDDIR=$(modulesrc)/$(MODULES_OS) \ $(EXTRA_ARGS) -C "$(modulesrc)/$(MODULES_OS)/$@" @LINUX_TRUE@export LINUXINCLUDE := @LINUXINCLUDE@ @LINUX_TRUE@export vmblockdir := $(MODULES_DIR)/fs/vmblock @LINUX_TRUE@export vmcidir := $(MODULES_DIR)/drivers/misc @LINUX_TRUE@export vmhgfsdir := $(MODULES_DIR)/fs/vmhgfs @LINUX_TRUE@export vmsyncdir := $(MODULES_DIR)/drivers/misc @LINUX_TRUE@export vmxnetdir := $(MODULES_DIR)/drivers/net @LINUX_TRUE@export vsockdir := $(MODULES_DIR)/net/vsock @LINUX_TRUE@@WITH_ROOT_PRIVILEGES_TRUE@export DEPMOD := depmod -a $(KERNEL_RELEASE) @SOLARIS_TRUE@export vmhgfsdir := $(MODULES_DIR) clean-local: for MOD in $(MODULES); do \ if [ -d "$(modulesrc)/$(MODULES_OS)/$$MOD" ]; then \ $(MAKE) VM_UNAME=$(KERNEL_RELEASE) MV=mv RM=rm \ -C "$(modulesrc)/$(MODULES_OS)/$$MOD" clean || exit 1; \ fi \ done rm -f $(modulesrc)/$(MODULES_OS)/*.o $(modulesrc)/$(MODULES_OS)/*.ko rm -f $(modulesrc)/$(MODULES_OS)/VMwareVMCIModule.symvers install-exec-hook: @SOLARIS_TRUE@ for MOD in $(MODULES); do \ @SOLARIS_TRUE@ $(MAKE) VM_UNAME=$(KERNEL_RELEASE) MV=mv RM=rm \ @SOLARIS_TRUE@ -C "$(modulesrc)/$(MODULES_OS)/$$MOD" install || exit 1; \ @SOLARIS_TRUE@ done @FREEBSD_TRUE@ for MOD in $(MODULES); do \ @FREEBSD_TRUE@ $(INSTALL) -d $(DESTDIR)$(MODULES_DIR); \ @FREEBSD_TRUE@ $(INSTALL) -m644 $(modulesrc)/$(MODULES_OS)/$$MOD.ko \ @FREEBSD_TRUE@ $(DESTDIR)$(MODULES_DIR); \ @FREEBSD_TRUE@ done @LINUX_TRUE@ for MOD in $(MODULES); do \ @LINUX_TRUE@ $(INSTALL) -d $(DESTDIR)`eval echo '$$'$${MOD}dir`; \ @LINUX_TRUE@ $(INSTALL) -m644 $(modulesrc)/$(MODULES_OS)/$$MOD/$$MOD.ko \ @LINUX_TRUE@ $(DESTDIR)`eval echo '$$'$${MOD}dir`; \ @LINUX_TRUE@ done @LINUX_TRUE@ eval "$$DEPMOD" uninstall-hook: for MOD in $(MODULES); do \ rm -f $(DESTDIR)`eval echo '$$'$${MOD}dir`/$$MOD.ko &> /dev/null;\ done eval "$$DEPMOD" # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/modules/shared/0000755765153500003110000000000012220061556016355 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/shared/vmxnet/0000755765153500003110000000000012220061556017676 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/shared/vmxnet/upt1_defs.h0000644765153500003110000000742412220061556021750 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* upt1_defs.h * * Definitions for UPTv1 * * Some of the defs are duplicated in vmkapi_net_upt.h, because * vmkapi_net_upt.h cannot distribute with OSS yet and vmkapi headers can * only include vmkapi headers. Make sure they are kept in sync! */ #ifndef _UPT1_DEFS_H #define _UPT1_DEFS_H #define UPT1_MAX_TX_QUEUES 64 #define UPT1_MAX_RX_QUEUES 64 #define UPT1_MAX_INTRS (UPT1_MAX_TX_QUEUES + UPT1_MAX_RX_QUEUES) typedef #include "vmware_pack_begin.h" struct UPT1_TxStats { uint64 TSOPktsTxOK; /* TSO pkts post-segmentation */ uint64 TSOBytesTxOK; uint64 ucastPktsTxOK; uint64 ucastBytesTxOK; uint64 mcastPktsTxOK; uint64 mcastBytesTxOK; uint64 bcastPktsTxOK; uint64 bcastBytesTxOK; uint64 pktsTxError; uint64 pktsTxDiscard; } #include "vmware_pack_end.h" UPT1_TxStats; typedef #include "vmware_pack_begin.h" struct UPT1_RxStats { uint64 LROPktsRxOK; /* LRO pkts */ uint64 LROBytesRxOK; /* bytes from LRO pkts */ /* the following counters are for pkts from the wire, i.e., pre-LRO */ uint64 ucastPktsRxOK; uint64 ucastBytesRxOK; uint64 mcastPktsRxOK; uint64 mcastBytesRxOK; uint64 bcastPktsRxOK; uint64 bcastBytesRxOK; uint64 pktsRxOutOfBuf; uint64 pktsRxError; } #include "vmware_pack_end.h" UPT1_RxStats; /* interrupt moderation level */ #define UPT1_IML_NONE 0 /* no interrupt moderation */ #define UPT1_IML_HIGHEST 7 /* least intr generated */ #define UPT1_IML_ADAPTIVE 8 /* adpative intr moderation */ /* values for UPT1_RSSConf.hashFunc */ #define UPT1_RSS_HASH_TYPE_NONE 0x0 #define UPT1_RSS_HASH_TYPE_IPV4 0x01 #define UPT1_RSS_HASH_TYPE_TCP_IPV4 0x02 #define UPT1_RSS_HASH_TYPE_IPV6 0x04 #define UPT1_RSS_HASH_TYPE_TCP_IPV6 0x08 #define UPT1_RSS_HASH_FUNC_NONE 0x0 #define UPT1_RSS_HASH_FUNC_TOEPLITZ 0x01 #define UPT1_RSS_MAX_KEY_SIZE 40 #define UPT1_RSS_MAX_IND_TABLE_SIZE 128 typedef #include "vmware_pack_begin.h" struct UPT1_RSSConf { uint16 hashType; uint16 hashFunc; uint16 hashKeySize; uint16 indTableSize; uint8 hashKey[UPT1_RSS_MAX_KEY_SIZE]; uint8 indTable[UPT1_RSS_MAX_IND_TABLE_SIZE]; } #include "vmware_pack_end.h" UPT1_RSSConf; /* features */ #define UPT1_F_RXCSUM 0x0001 /* rx csum verification */ #define UPT1_F_RSS 0x0002 #define UPT1_F_RXVLAN 0x0004 /* VLAN tag stripping */ #define UPT1_F_LRO 0x0008 #endif open-vm-tools-9.4.0-1280544/modules/shared/vmxnet/eth_public.h0000644765153500003110000010044712220061556022173 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * eth.h -- * * Virtual ethernet. */ #ifndef _ETH_PUBLIC_H_ #define _ETH_PUBLIC_H_ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_DISTRIBUTE #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #define ETH_LADRF_LEN 2 #define ETH_ADDR_LENGTH 6 typedef uint8 Eth_Address[ETH_ADDR_LENGTH]; // printf helpers #define ETH_ADDR_FMT_STR "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx" #define ETH_ADDR_FMT_ARGS(a) ((uint8 *)a)[0], ((uint8 *)a)[1], ((uint8 *)a)[2], \ ((uint8 *)a)[3], ((uint8 *)a)[4], ((uint8 *)a)[5] #define ETH_ADDR_PTR_FMT_ARGS(a) &((uint8 *)a)[0], &((uint8 *)a)[1], \ &((uint8 *)a)[2], &((uint8 *)a)[3], \ &((uint8 *)a)[4], &((uint8 *)a)[5] #define ETH_MAX_EXACT_MULTICAST_ADDRS 32 typedef enum Eth_RxMode { ETH_FILTER_UNICAST = 0x0001, // pass unicast (directed) frames ETH_FILTER_MULTICAST = 0x0002, // pass some multicast frames ETH_FILTER_ALLMULTI = 0x0004, // pass *all* multicast frames ETH_FILTER_BROADCAST = 0x0008, // pass broadcast frames ETH_FILTER_PROMISC = 0x0010, // pass all frames (ie no filter) ETH_FILTER_USE_LADRF = 0x0020, // use the LADRF for multicast filtering ETH_FILTER_SINK = 0x10000 // pass not-matched unicast frames } Eth_RxMode; // filter flags printf helpers #define ETH_FILTER_FLAG_FMT_STR "%s%s%s%s%s%s%s" #define ETH_FILTER_FLAG_FMT_ARGS(f) (f) & ETH_FILTER_UNICAST ? " UNICAST" : "", \ (f) & ETH_FILTER_MULTICAST ? " MULTICAST" : "", \ (f) & ETH_FILTER_ALLMULTI ? " ALLMULTI" : "", \ (f) & ETH_FILTER_BROADCAST ? " BROADCAST" : "", \ (f) & ETH_FILTER_PROMISC ? " PROMISC" : "", \ (f) & ETH_FILTER_USE_LADRF ? " USE_LADRF" : "", \ (f) & ETH_FILTER_SINK ? " SINK" : "" // Ethernet header type typedef enum { ETH_HEADER_TYPE_DIX, ETH_HEADER_TYPE_802_1PQ, ETH_HEADER_TYPE_802_3, ETH_HEADER_TYPE_802_1PQ_802_3, } Eth_HdrType; // DIX type fields we care about typedef enum { ETH_TYPE_IPV4 = 0x0800, ETH_TYPE_IPV6 = 0x86DD, ETH_TYPE_ARP = 0x0806, ETH_TYPE_RARP = 0x8035, ETH_TYPE_LLDP = 0x88CC, ETH_TYPE_CDP = 0x2000, ETH_TYPE_AKIMBI = 0x88DE, ETH_TYPE_VMWARE = 0x8922, ETH_TYPE_802_1PQ = 0x8100, // not really a DIX type, but used as such ETH_TYPE_LLC = 0xFFFF, // 0xFFFF is IANA reserved, used to mark LLC } Eth_DixType; typedef enum { ETH_TYPE_IPV4_NBO = 0x0008, ETH_TYPE_IPV6_NBO = 0xDD86, ETH_TYPE_ARP_NBO = 0x0608, ETH_TYPE_RARP_NBO = 0x3580, ETH_TYPE_LLDP_NBO = 0xCC88, ETH_TYPE_CDP_NBO = 0x0020, ETH_TYPE_AKIMBI_NBO = 0xDE88, ETH_TYPE_VMWARE_NBO = 0x2289, ETH_TYPE_802_1PQ_NBO = 0x0081, // not really a DIX type, but used as such } Eth_DixTypeNBO; // low two bits of the LLC control byte typedef enum { ETH_LLC_CONTROL_IFRAME = 0x0, // both 0x0 and 0x2, only low bit of 0 needed ETH_LLC_CONTROL_SFRAME = 0x1, ETH_LLC_CONTROL_UFRAME = 0x3, } Eth_LLCControlBits; #define ETH_LLC_CONTROL_UFRAME_MASK (0x3) typedef #include "vmware_pack_begin.h" struct Eth_DIX { uint16 typeNBO; // indicates the higher level protocol } #include "vmware_pack_end.h" Eth_DIX; /* * LLC header come in two varieties: 8 bit control and 16 bit control. * when the lower two bits of the first byte's control are '11', this * indicated the 8 bit control field. */ typedef #include "vmware_pack_begin.h" struct Eth_LLC8 { uint8 dsap; uint8 ssap; uint8 control; } #include "vmware_pack_end.h" Eth_LLC8; typedef #include "vmware_pack_begin.h" struct Eth_LLC16 { uint8 dsap; uint8 ssap; uint16 control; } #include "vmware_pack_end.h" Eth_LLC16; typedef #include "vmware_pack_begin.h" struct Eth_SNAP { uint8 snapOrg[3]; Eth_DIX snapType; } #include "vmware_pack_end.h" Eth_SNAP; typedef #include "vmware_pack_begin.h" struct Eth_802_3 { uint16 lenNBO; // length of the frame Eth_LLC8 llc; // LLC header Eth_SNAP snap; // SNAP header } #include "vmware_pack_end.h" Eth_802_3; // 802.1p QOS/priority tags // enum { ETH_802_1_P_BEST_EFFORT = 0, ETH_802_1_P_BACKGROUND = 1, ETH_802_1_P_EXCELLENT_EFFORT = 2, ETH_802_1_P_CRITICAL_APPS = 3, ETH_802_1_P_VIDEO = 4, ETH_802_1_P_VOICE = 5, ETH_802_1_P_INTERNETWORK_CONROL = 6, ETH_802_1_P_NETWORK_CONTROL = 7 }; typedef #include "vmware_pack_begin.h" struct Eth_802_1pq_Tag { uint16 typeNBO; // always ETH_TYPE_802_1PQ uint16 vidHi:4, // 802.1q vlan ID high nibble canonical:1, // bit order? (should always be 0) priority:3, // 802.1p priority tag vidLo:8; // 802.1q vlan ID low byte } #include "vmware_pack_end.h" Eth_802_1pq_Tag; typedef #include "vmware_pack_begin.h" struct Eth_802_1pq { Eth_802_1pq_Tag tag; // VLAN/QOS tag union { Eth_DIX dix; // DIX header follows Eth_802_3 e802_3; // or 802.3 header follows }; } #include "vmware_pack_end.h" Eth_802_1pq; typedef #include "vmware_pack_begin.h" struct Eth_Header { Eth_Address dst; // all types of ethernet frame have dst first Eth_Address src; // and the src next (at least all the ones we'll see) union { Eth_DIX dix; // followed by a DIX header... Eth_802_3 e802_3; // ...or an 802.3 header Eth_802_1pq e802_1pq; // ...or an 802.1[pq] tag and a header }; } #include "vmware_pack_end.h" Eth_Header; /* * Official VMware ethertype header format and types */ #define ETH_VMWARE_FRAME_MAGIC 0x026f7564 enum { ETH_VMWARE_FRAME_TYPE_INVALID = 0, ETH_VMWARE_FRAME_TYPE_BEACON = 1, ETH_VMWARE_FRAME_TYPE_COLOR = 2, ETH_VMWARE_FRAME_TYPE_ECHO = 3, ETH_VMWARE_FRAME_TYPE_LLC = 4, // XXX: Just re-use COLOR? }; typedef #include "vmware_pack_begin.h" struct Eth_VMWareFrameHeader { uint32 magic; uint16 lenNBO; uint8 type; } #include "vmware_pack_end.h" Eth_VMWareFrameHeader; typedef Eth_Header Eth_802_1pq_Header; // for sizeof #define ETH_BROADCAST_ADDRESS { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } extern Eth_Address netEthBroadcastAddr; /* * simple predicate for 1536 boundary. * the parameter is a network ordered uint16, which is compared to 0x06, * testing for "length" values greater than or equal to 0x0600 (1536) */ #define ETH_TYPENOT8023(x) (((x) & 0xff) >= 0x06) /* * header length macros * * first two are typical: ETH_HEADER_LEN_DIX, ETH_HEADER_LEN_802_1PQ * last two are suspicious, due to 802.3 incompleteness */ #define ETH_HEADER_LEN_DIX (sizeof(Eth_Address) + \ sizeof(Eth_Address) + \ sizeof(Eth_DIX)) #define ETH_HEADER_LEN_802_1PQ (sizeof(Eth_Address) + \ sizeof(Eth_Address) + \ sizeof(Eth_802_1pq_Tag) + \ sizeof(Eth_DIX)) #define ETH_HEADER_LEN_802_2_LLC (sizeof(Eth_Address) + \ sizeof(Eth_Address) + \ sizeof(uint16) + \ sizeof(Eth_LLC8)) #define ETH_HEADER_LEN_802_2_LLC16 (sizeof(Eth_Address) + \ sizeof(Eth_Address) + \ sizeof(uint16) + \ sizeof(Eth_LLC16)) #define ETH_HEADER_LEN_802_3 (sizeof(Eth_Address) + \ sizeof(Eth_Address) + \ sizeof(Eth_802_3)) #define ETH_HEADER_LEN_802_1PQ_LLC (sizeof(Eth_Address) + \ sizeof(Eth_Address) + \ sizeof(Eth_802_1pq_Tag) + \ sizeof(uint16) + \ sizeof(Eth_LLC8)) #define ETH_HEADER_LEN_802_1PQ_LLC16 (sizeof(Eth_Address) + \ sizeof(Eth_Address) + \ sizeof(Eth_802_1pq_Tag) + \ sizeof(uint16) + \ sizeof(Eth_LLC16)) #define ETH_HEADER_LEN_802_1PQ_802_3 (sizeof(Eth_Address) + \ sizeof(Eth_Address) + \ sizeof(Eth_802_1pq_Tag) + \ sizeof(Eth_802_3)) #define ETH_MIN_HEADER_LEN (ETH_HEADER_LEN_DIX) #define ETH_MAX_HEADER_LEN (ETH_HEADER_LEN_802_1PQ_802_3) #define ETH_MIN_FRAME_LEN 60 #define ETH_MAX_STD_MTU 1500 #define ETH_MAX_STD_FRAMELEN (ETH_MAX_STD_MTU + ETH_MAX_HEADER_LEN) #define ETH_MAX_JUMBO_MTU 9000 #define ETH_MAX_JUMBO_FRAMELEN (ETH_MAX_JUMBO_MTU + ETH_MAX_HEADER_LEN) #define ETH_DEFAULT_MTU 1500 #define ETH_FCS_LEN 4 #define ETH_VLAN_LEN sizeof(Eth_802_1pq_Tag) /* *---------------------------------------------------------------------- * * Eth_IsAddrMatch -- * * Do the two ethernet addresses match? * * Results: * TRUE or FALSE. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE Bool Eth_IsAddrMatch(const Eth_Address addr1, const Eth_Address addr2) { #ifdef __GNUC__ /* string.h may not exist for kernel modules, so cannot use memcmp() */ return !__builtin_memcmp(addr1, addr2, ETH_ADDR_LENGTH); #else return !memcmp(addr1, addr2, ETH_ADDR_LENGTH); #endif } /* *---------------------------------------------------------------------- * * Eth_IsBroadcastAddr -- * * Is the address the broadcast address? * * Results: * TRUE or FALSE. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE Bool Eth_IsBroadcastAddr(const Eth_Address addr) { return Eth_IsAddrMatch(addr, netEthBroadcastAddr); } /* *---------------------------------------------------------------------- * * Eth_IsUnicastAddr -- * * Is the address a unicast address? * * Results: * TRUE or FALSE. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE Bool Eth_IsUnicastAddr(const Eth_Address addr) { // broadcast and multicast frames always have the low bit set in byte 0 return !(((char *)addr)[0] & 0x1); } /* *---------------------------------------------------------------------- * * Eth_IsNullAddr -- * * Is the address the all-zeros address? * * Results: * TRUE or FALSE. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE Bool Eth_IsNullAddr(const Eth_Address addr) { return ((addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]) == 0); } /* *---------------------------------------------------------------------- * * Eth_HeaderType -- * * return an Eth_HdrType depending on the eth header * contents. will not work in all cases, especially since it * requres ETH_HEADER_LEN_802_1PQ bytes to determine the type * * HeaderType isn't sufficient to determine the length of * the eth header. for 802.3 header, its not clear without * examination, whether a SNAP is included * * returned type: * * ETH_HEADER_TYPE_DIX: typical 14 byte eth header * ETH_HEADER_TYPE_802_1PQ: DIX+vlan tagging * ETH_HEADER_TYPE_802_3: 802.3 eth header * ETH_HEADER_TYPE_802_1PQ_802_3: 802.3 + vlan tag * * the test for DIX was moved from a 1500 boundary to a 1536 * boundary, since the vmxnet2 MTU was updated to 1514. when * W2K8 attempted to send LLC frames, these were interpreted * as DIX frames instead of the correct 802.3 type * * these links may help if they're valid: * * http://standards.ieee.org/regauth/ethertype/type-tut.html * http://standards.ieee.org/regauth/ethertype/type-pub.html * * * Results: * Eth_HdrType value * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE Eth_HdrType Eth_HeaderType(const Eth_Header *eh) { /* * we use 1536 (IEEE 802.3-std mentions 1536, but iana indicates * type of 0-0x5dc are 802.3) instead of some #def symbol to prevent * inadvertant reuse of the same macro for buffer size decls. */ if (ETH_TYPENOT8023(eh->dix.typeNBO)) { if (eh->dix.typeNBO != ETH_TYPE_802_1PQ_NBO) { /* * typical case */ return ETH_HEADER_TYPE_DIX; } /* * some type of 802.1pq tagged frame */ if (ETH_TYPENOT8023(eh->e802_1pq.dix.typeNBO)) { /* * vlan tagging with dix style type */ return ETH_HEADER_TYPE_802_1PQ; } /* * vlan tagging with 802.3 header */ return ETH_HEADER_TYPE_802_1PQ_802_3; } /* * assume 802.3 */ return ETH_HEADER_TYPE_802_3; } /* *---------------------------------------------------------------------- * * Eth_EncapsulatedPktType -- * * Get the encapsulated (layer 3) frame type. * for LLC frames without SNAP, we don't have * an encapsulated type, and return ETH_TYPE_LLC. * * IANA reserves 0xFFFF, which we reuse to indicate * ETH_TYPE_LLC. * * * Results: * NBO frame type. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE uint16 Eth_EncapsulatedPktType(const Eth_Header *eh) { Eth_HdrType type = Eth_HeaderType(eh); switch (type) { case ETH_HEADER_TYPE_DIX : return eh->dix.typeNBO; case ETH_HEADER_TYPE_802_1PQ : return eh->e802_1pq.dix.typeNBO; case ETH_HEADER_TYPE_802_3 : /* * Documentation describes SNAP headers as having ONLY * 0x03 as the control fields, not just the lower two bits * This prevents the use of Eth_IsLLCControlUFormat. */ if ((eh->e802_3.llc.dsap == 0xaa) && (eh->e802_3.llc.ssap == 0xaa) && (eh->e802_3.llc.control == ETH_LLC_CONTROL_UFRAME)) { return eh->e802_3.snap.snapType.typeNBO; } else { // LLC, no snap header, then no type return ETH_TYPE_LLC; } case ETH_HEADER_TYPE_802_1PQ_802_3 : if ((eh->e802_1pq.e802_3.llc.dsap == 0xaa) && (eh->e802_1pq.e802_3.llc.ssap == 0xaa) && (eh->e802_1pq.e802_3.llc.control == ETH_LLC_CONTROL_UFRAME)) { return eh->e802_1pq.e802_3.snap.snapType.typeNBO; } else { // tagged LLC, no snap header, then no type return ETH_TYPE_LLC; } } ASSERT(FALSE); return 0; } /* *---------------------------------------------------------------------- * * Eth_IsDixType -- * * Is the frame of the requested protocol type or is it an 802.1[pq] * encapsulation of such a frame? * * Results: * TRUE or FALSE. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE Bool Eth_IsDixType(const Eth_Header *eh, const Eth_DixTypeNBO type) { return Eth_EncapsulatedPktType(eh) == type; } /* *---------------------------------------------------------------------- * * Eth_IsBeaconSap -- * * test to validate a frame to determine if its a beacon * (ncp) frame. sap is passed in. * * ncp beacon/color frames are LLC frames with a DSAP/SSAP * set based on a config value. non-zero llc length is * tested here to prevent the predicate from interfering * with testworld etherswitch tests * * * Results: * TRUE or FALSE. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE Bool Eth_IsBeaconSap(const Eth_Header *eh, const uint8 sap) { Eth_HdrType type = Eth_HeaderType(eh); if (type == ETH_HEADER_TYPE_802_3) { if ((eh->e802_3.llc.dsap == sap) && (eh->e802_3.llc.ssap == sap)) { if (eh->e802_3.lenNBO != 0) { return TRUE; } } } else if (type == ETH_HEADER_TYPE_802_1PQ_802_3) { if ((eh->e802_1pq.e802_3.llc.dsap == sap) && (eh->e802_1pq.e802_3.llc.ssap == sap)) { if (eh->e802_1pq.e802_3.lenNBO != 0) { return TRUE; } } } return FALSE; } /* *---------------------------------------------------------------------- * * Eth_IsIPV4 -- * * Is the frame an IPV4 frame? * * Results: * TRUE or FALSE. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE Bool Eth_IsIPV4(const Eth_Header *eh) { return Eth_IsDixType(eh, ETH_TYPE_IPV4_NBO); } /* *---------------------------------------------------------------------- * * Eth_IsIPV6 -- * * Is the frame an IPV6 frame? * * Results: * TRUE or FALSE. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE Bool Eth_IsIPV6(const Eth_Header *eh) { return Eth_IsDixType(eh, ETH_TYPE_IPV6_NBO); } /* *---------------------------------------------------------------------- * * Eth_IsVMWare -- * * Is the frame a VMWare frame? * * Results: * TRUE or FALSE. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE Bool Eth_IsVMWare(const Eth_Header *eh) { return Eth_IsDixType(eh, ETH_TYPE_VMWARE_NBO); } /* *---------------------------------------------------------------------- * * Eth_IsARP -- * * Is the frame an ARP frame? * * Results: * TRUE or FALSE. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE Bool Eth_IsARP(const Eth_Header *eh) { return Eth_IsDixType(eh, ETH_TYPE_ARP_NBO); } /* *---------------------------------------------------------------------- * * Eth_IsFrameTagged -- * * Does the frame contain an 802.1[pq] tag? * * Results: * TRUE or FALSE. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE Bool Eth_IsFrameTagged(const Eth_Header *eh) { return (eh->dix.typeNBO == ETH_TYPE_802_1PQ_NBO); } /* *---------------------------------------------------------------------- * * Eth_FillVlanTag -- * * Populate the fields of a vlan tag * * Results: * The populated vlan tag * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE Eth_802_1pq_Tag * Eth_FillVlanTag(Eth_802_1pq_Tag *tag, const uint32 vlanId, const uint32 priority) { ASSERT(vlanId < 4096); ASSERT(priority < 8); tag->typeNBO = ETH_TYPE_802_1PQ_NBO; tag->priority = priority; tag->canonical = 0; // bit order (should be 0) tag->vidHi = vlanId >> 8; tag->vidLo = vlanId & 0xff; return tag; } /* *---------------------------------------------------------------------- * * Eth_VlanTagGetVlanID -- * * Extract the VLAN ID from the vlanTag. * * Results: * The VLAN ID. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE uint16 Eth_VlanTagGetVlanID(const Eth_802_1pq_Tag *tag) { return (tag->vidHi << 8) | tag->vidLo; } /* *---------------------------------------------------------------------- * * Eth_FrameGetVlanID -- * * Extract the VLAN ID from the frame's 802.1[pq] tag. * * Results: * The VLAN ID. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE uint16 Eth_FrameGetVlanID(const Eth_Header *eh) { ASSERT(Eth_IsFrameTagged(eh)); return Eth_VlanTagGetVlanID(&eh->e802_1pq.tag); } /* *---------------------------------------------------------------------- * * Eth_FrameSetVlanID -- * * Set the VLAN ID in the frame's 802.1[pq] tag. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE void Eth_FrameSetVlanID(Eth_Header *eh, uint16 vid) { ASSERT(Eth_IsFrameTagged(eh)); eh->e802_1pq.tag.vidHi = vid >> 8; eh->e802_1pq.tag.vidLo = vid & 0xff; } /* *---------------------------------------------------------------------- * * Eth_FrameGetPriority -- * * Extract the priority from the frame's 802.1[pq] tag. * * Results: * The priority. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE uint8 Eth_FrameGetPriority(const Eth_Header *eh) { ASSERT(Eth_IsFrameTagged(eh)); return eh->e802_1pq.tag.priority; } /* *---------------------------------------------------------------------- * * Eth_FrameSetPriority -- * * Set the priority in the frame's 802.1[pq] tag. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE void Eth_FrameSetPriority(Eth_Header *eh, const uint8 prio) { ASSERT(Eth_IsFrameTagged(eh)); ASSERT(prio <= 7); eh->e802_1pq.tag.priority = prio; } /* *---------------------------------------------------------------------- * Eth_IsLLCControlUFormat -- * * The LLC Control fields determines the lengeth of the LLC * field, selecting 8 bit of 16 bit. Thies predicate indicates * whether the LLC frame is a U-Format frames. The U-Format * frame is the only LLC frame header which is 8 bits long. * * Results * Bool * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE Bool Eth_IsLLCControlUFormat(const uint8 control) { return (control & ETH_LLC_CONTROL_UFRAME_MASK) == ETH_LLC_CONTROL_UFRAME; } /* *---------------------------------------------------------------------- * * Eth_HeaderLength_802_3 -- * * Returns the length of an 802_3 eth header without * any vlan tagging. factored out for Eth_HeaderComplete() * * Results: * uint16 length * * Side Effects: * None. * *---------------------------------------------------------------------- */ static INLINE uint16 Eth_HeaderLength_802_3(const Eth_Header *eh) { /* * Documentation describes SNAP headers as having ONLY * 0x03 as the control fields, not just the lower two bits * This prevents the use of Eth_IsLLCControlUFormat. */ if ((eh->e802_3.llc.dsap == 0xaa) && (eh->e802_3.llc.ssap == 0xaa) && (eh->e802_3.llc.control == ETH_LLC_CONTROL_UFRAME)) { return ETH_HEADER_LEN_802_3; } // LLC, no snap header if (Eth_IsLLCControlUFormat(eh->e802_3.llc.control)) { return ETH_HEADER_LEN_802_2_LLC; } // Eth_LLC with a two byte control field return ETH_HEADER_LEN_802_2_LLC16; } /* *---------------------------------------------------------------------- * * Eth_HeaderLength_802_1PQ_802_3 -- * * Returns the length of an 802_3 eth header with * vlan tagging. factored out for Eth_HeaderComplete() * * Results: * uint16 length * * Side Effects: * None. * * *---------------------------------------------------------------------- */ static INLINE uint16 Eth_HeaderLength_802_1PQ_802_3(const Eth_Header *eh) { if ((eh->e802_1pq.e802_3.llc.dsap == 0xaa) && (eh->e802_1pq.e802_3.llc.ssap == 0xaa) && (eh->e802_1pq.e802_3.llc.control == ETH_LLC_CONTROL_UFRAME)) { return ETH_HEADER_LEN_802_1PQ_802_3; } // tagged LLC, no snap header if (Eth_IsLLCControlUFormat(eh->e802_1pq.e802_3.llc.control)) { return ETH_HEADER_LEN_802_1PQ_LLC; } // Eth_LLC with a two byte control field return ETH_HEADER_LEN_802_1PQ_LLC16; } /* *---------------------------------------------------------------------- * * Eth_HeaderLength -- * * Return the length of the header, taking into account * different header variations. for LLC headers, determine * whether the eth header has an associated SNAP header, * * all references to the eth header assume the complete * frame is mapped withing the frame mapped length * * To determine the length, 17 bytes must be readable. * LLC requires three bytes (after the 802.3 length) to * identify SNAP frames. * * when the header isn't complete: * Eth_HeaderType needs ETH_HEADER_LEN_DIX + sizeof(Eth_802_1pq_Tag) * to completely distinguish types (18 bytes), * Eth_HeaderType correctly identifies basic untagged DIX frames * with ETH_HEADER_LEN_DIX (14 bytes) bytes. * Eth_HeaderLength will correctly return length of untagged LLC frames * with ETH_HEADER_LEN_DIX + sizeof(Eth_LLC) (17 bytes), but if the * frame is tagged, it will need * ETH_HEADER_LEN_DIX + sizeof(Eth_802_1pq_Tag) + sizeof(Eth_LLC) * (21 bytes) * * * Results: * uint16 size of the header * * Side Effects: * None. * *---------------------------------------------------------------------- */ static INLINE uint16 Eth_HeaderLength(const Eth_Header *eh) { Eth_HdrType type = Eth_HeaderType(eh); switch (type) { case ETH_HEADER_TYPE_DIX : return ETH_HEADER_LEN_DIX; case ETH_HEADER_TYPE_802_1PQ : return ETH_HEADER_LEN_802_1PQ; case ETH_HEADER_TYPE_802_3 : return Eth_HeaderLength_802_3(eh); case ETH_HEADER_TYPE_802_1PQ_802_3 : return Eth_HeaderLength_802_1PQ_802_3(eh); } ASSERT(FALSE); return 0; } /* *---------------------------------------------------------------------- * * Eth_GetPayloadWithLen -- * * Simple cover to comput the payload's address given the length * * Results: * pointer to the frame's payload * * Side Effects: * None. * *---------------------------------------------------------------------- */ static INLINE void * Eth_GetPayloadWithLen(const void *frame, const uint16 ehHdrLen) { return (void *)((uint8 *)frame + ehHdrLen); } /* *---------------------------------------------------------------------- * * Eth_GetPayload -- * * Return the address of the frame's payload, taking into account * different header variations. Code assumes a complete ether * header is mapped at the frame, assumption exists due to * the use of Eth_HeaderLength, which isn't provided with * the frame's length (how much data it can examine to determine * the ethernet header length) * * Results: * pointer to the frame's payload * * Side Effects: * None. * *---------------------------------------------------------------------- */ static INLINE void * Eth_GetPayload(const void *frame) { return Eth_GetPayloadWithLen(frame, Eth_HeaderLength((Eth_Header *)frame)); } /* *---------------------------------------------------------------------- * * Eth_IsFrameHeaderComplete -- * * Predicate to determine whether the frame has enough length * to contain a complete eth header of the correct type. * If you already know/expect the length to exceed * ETH_MAX_HEADER_LEN then for performance reasons you should * explicitly check for that before calling this function. * * Results: * returns true when a complete eth header is available * * Side Effects: * None. * *---------------------------------------------------------------------- */ static INLINE Bool Eth_IsFrameHeaderComplete(const Eth_Header *eh, const uint32 len, uint16 *ehHdrLen) { uint16 ehLen; if (UNLIKELY(eh == NULL)) { return FALSE; } /* * Hard to know what's the optimal order for these checks * perform the most likely case first. * Since its not directly obvious, hex 0x06 -> 1536, * (see ETH_TYPENOT8023() for 1536 details) */ if (LIKELY((len >= ETH_HEADER_LEN_DIX) && ETH_TYPENOT8023(eh->dix.typeNBO) && (eh->dix.typeNBO != ETH_TYPE_802_1PQ_NBO))) { if (ehHdrLen != NULL) { *ehHdrLen = ETH_HEADER_LEN_DIX; } return TRUE; } if (len >= ETH_HEADER_LEN_802_1PQ) { /* * Eth_HeaderType will correctly enumerate all types once * at least ETH_HEADER_LEN_802_1PQ bytes are available */ Eth_HdrType type = Eth_HeaderType(eh); if (type == ETH_HEADER_TYPE_802_1PQ) { if (ehHdrLen != NULL) { *ehHdrLen = ETH_HEADER_LEN_802_1PQ; } return TRUE; } else if (type == ETH_HEADER_TYPE_802_3) { /* * Length could be shorter LLC or LLC+SNAP. * ETH_HEADER_LEN_802_2_LLC bytes are needed to disambiguate. * note: ASSERT_ON_COMPILE fails windows builds. */ ASSERT(ETH_HEADER_LEN_802_1PQ > ETH_HEADER_LEN_802_2_LLC); ehLen = Eth_HeaderLength_802_3(eh); /* continue to common test */ } else if (type == ETH_HEADER_TYPE_802_1PQ_802_3) { if (len < ETH_HEADER_LEN_802_1PQ_LLC) { return FALSE; } ehLen = Eth_HeaderLength_802_1PQ_802_3(eh); /* continue to common test */ } else { /* * This else clause is unreachable, but if removed * compiler complains about ehLen possibly being * uninitialized. this else is marginally preferred * over an unnecessary initialization */ ASSERT(type != ETH_HEADER_TYPE_DIX); // NOT_REACHED() return FALSE; } /* common test */ if (len >= ehLen) { if (ehHdrLen != NULL) { *ehHdrLen = ehLen; } return TRUE; } return FALSE; } /* * Corner case... not enough len to use Eth_HeaderType, * since len is shorter than ETH_HEADER_LEN_802_1PQ bytes. * but with ETH_HEADER_LEN_802_2_LLC bytes, and an 802.3 * frame, a U Format LLC frame indicates TRUE * with a header length of ETH_HEADER_LEN_802_2_LLC bytes. * * The additional test for ETH_TYPENOT8023() is necessary * for the case where the dix frame failed due to the * vlan tagging test early in this procedure. */ if ((len == ETH_HEADER_LEN_802_2_LLC) && !ETH_TYPENOT8023(eh->dix.typeNBO) && Eth_IsLLCControlUFormat(eh->e802_3.llc.control)) { if (ehHdrLen != NULL) { *ehHdrLen = ETH_HEADER_LEN_802_2_LLC; } return TRUE; } return FALSE; } #endif // _ETH_PUBLIC_H_ open-vm-tools-9.4.0-1280544/modules/shared/vmxnet/vmxnet2_def.h0000644765153500003110000003573112220061556022301 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ #ifndef _VMXNET2_DEF_H_ #define _VMXNET2_DEF_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_DISTRIBUTE #include "includeCheck.h" #include "net_sg.h" #include "vmxnet_def.h" /* * Magic number that identifies this version of the vmxnet protocol. */ #define VMXNET2_MAGIC 0xbabe864f /* size of the rx ring */ #define VMXNET2_MAX_NUM_RX_BUFFERS 128 #define VMXNET2_DEFAULT_NUM_RX_BUFFERS 100 /* size of the rx ring when enhanced vmxnet is used */ #define ENHANCED_VMXNET2_MAX_NUM_RX_BUFFERS 512 #define ENHANCED_VMXNET2_DEFAULT_NUM_RX_BUFFERS 150 /* size of the 2nd rx ring */ #define VMXNET2_MAX_NUM_RX_BUFFERS2 2048 #define VMXNET2_DEFAULT_NUM_RX_BUFFERS2 512 /* size of the tx ring */ #define VMXNET2_MAX_NUM_TX_BUFFERS 128 #define VMXNET2_DEFAULT_NUM_TX_BUFFERS 100 /* size of the tx ring when tso/jf is used */ #define VMXNET2_MAX_NUM_TX_BUFFERS_TSO 512 #define VMXNET2_DEFAULT_NUM_TX_BUFFERS_TSO 256 enum { VMXNET2_OWNERSHIP_DRIVER, VMXNET2_OWNERSHIP_DRIVER_PENDING, VMXNET2_OWNERSHIP_NIC, VMXNET2_OWNERSHIP_NIC_PENDING, VMXNET2_OWNERSHIP_NIC_FRAG, VMXNET2_OWNERSHIP_DRIVER_FRAG, }; #define VMXNET2_SG_DEFAULT_LENGTH 6 typedef struct Vmxnet2_SG_Array { uint16 addrType; uint16 length; NetSG_Elem sg[VMXNET2_SG_DEFAULT_LENGTH]; } Vmxnet2_SG_Array; typedef struct Vmxnet2_RxRingEntry { uint64 paddr; /* Physical address of the packet data. */ uint32 bufferLength; /* The length of the data at paddr. */ uint32 actualLength; /* The actual length of the received data. */ uint16 ownership; /* Who owns the packet. */ uint16 flags; /* Flags as defined below. */ uint32 index; /* * Currently: * * This is being used as an packet index to * rx buffers. * * Originally: * * was void* driverData ("Driver specific data.") * which was used for sk_buf**s in Linux and * VmxnetRxBuff*s in Windows. It could not be * here because the structure needs to be the * same size between architectures, and it was * not used on the device side, anyway. Look * for its replacement in * Vmxnet_Private.rxRingBuffPtr on Linux and * VmxnetAdapter.rxRingBuffPtr on Windows. */ } Vmxnet2_RxRingEntry; /* * Vmxnet2_RxRingEntry flags: * * VMXNET2_RX_HW_XSUM_OK The hardware verified the TCP/UDP checksum. * VMXNET2_RX_WITH_FRAG More data is in the 2nd ring * VMXNET2_RX_FRAG_EOP This is the last frag, the only valid flag for * 2nd ring entry * */ #define VMXNET2_RX_HW_XSUM_OK 0x01 #define VMXNET2_RX_WITH_FRAG 0x02 #define VMXNET2_RX_FRAG_EOP 0x04 typedef struct Vmxnet2_TxRingEntry { uint16 flags; /* Flags as defined below. */ uint16 ownership; /* Who owns this packet. */ uint32 extra; /* * was void* driverData ("Driver specific data.") * which was used for sk_buf*s in Linux and * VmxnetTxInfo*s in Windows. It could not be * here because the structure needs to be the * same size between architectures, and it was * not used on the device side, anyway. Look * for its replacement in * Vmxnet_Private.txRingBuffPtr on Linux and * VmxnetAdapter.txRingBuffPtr on Windows. */ uint32 tsoMss; /* TSO pkt MSS */ Vmxnet2_SG_Array sg; /* Packet data. */ } Vmxnet2_TxRingEntry; /* * Vmxnet2_TxRingEntry flags: * * VMXNET2_TX_CAN_KEEP The implementation can return the tx ring entry * to the driver when it is ready as opposed to * before the transmit call from the driver completes. * VMXNET2_TX_RING_LOW The driver's transmit ring buffer is low on free * slots. * VMXNET2_TX_HW_XSUM The hardware should perform the TCP/UDP checksum * VMXNET2_TX_TSO The hardware should do TCP segmentation. * VMXNET2_TX_PINNED_BUFFER The driver used one of the preallocated vmkernel * buffers *and* it has been pinned with Net_PinTxBuffers. * VMXNET2_TX_MORE This is *not* the last tx entry for the pkt. * All flags except VMXNET2_TX_MORE are ignored * for the subsequent tx entries. */ #define VMXNET2_TX_CAN_KEEP 0x0001 #define VMXNET2_TX_RING_LOW 0x0002 #define VMXNET2_TX_HW_XSUM 0x0004 #define VMXNET2_TX_TSO 0x0008 #define VMXNET2_TX_PINNED_BUFFER 0x0010 #define VMXNET2_TX_MORE 0x0020 /* * Structure used by implementations. This structure allows the inline * functions below to be used. */ typedef struct Vmxnet2_RxRingInfo { Vmxnet2_RxRingEntry *base; /* starting addr of the ring */ uint32 nicNext; /* next entry to use in the ring */ uint32 ringLength; /* # of entries in the ring */ PA startPA; /* PA of the starting addr of the ring */ #ifdef VMX86_DEBUG const char *name; #endif } Vmxnet2_RxRingInfo; typedef struct Vmxnet2_TxRingInfo { Vmxnet2_TxRingEntry *base; /* starting addr of the ring */ uint32 nicNext; /* next entry to use in the ring */ uint32 ringLength; /* # of entries in the ring */ PA startPA; /* PA of the starting addr of the ring */ #ifdef VMX86_DEBUG const char *name; #endif } Vmxnet2_TxRingInfo; typedef struct Vmxnet2_ImplData { Vmxnet2_RxRingInfo rxRing; Vmxnet2_RxRingInfo rxRing2; Vmxnet2_TxRingInfo txRing; struct PhysMem_Token *ddPhysMemToken; } Vmxnet2_ImplData; /* * Used internally for performance studies. By default this will be off so there * should be no compatibilty or other interferences. */ /* #define ENABLE_VMXNET2_PROFILING */ #ifdef ENABLE_VMXNET2_PROFILING typedef struct Vmxnet2_VmmStats { uint64 vIntTSC; /* the time that virtual int was posted */ uint64 actionsCount; /* Number of actions received */ uint64 numWasteActions; /* Number of non-productive actions */ } Vmxnet2_VmmStats; #endif typedef struct Vmxnet2_DriverStats { uint32 transmits; /* # of times that the drivers transmit function */ /* is called. The driver could transmit more */ /* than one packet per call. */ uint32 pktsTransmitted; /* # of packets transmitted. */ uint32 noCopyTransmits; /* # of packets that are transmitted without */ /* copying any data. */ uint32 copyTransmits; /* # of packets that are transmittted by copying */ /* the data into a buffer. */ uint32 maxTxsPending; /* Max # of transmits outstanding. */ uint32 txStopped; /* # of times that transmits got stopped because */ /* the tx ring was full. */ uint32 txRingOverflow; /* # of times that transmits got deferred bc */ /* the tx ring was full. This must be >= */ /* txStopped since there will be one */ /* txStopped when the ring fills up and then */ /* one txsRingOverflow for each packet that */ /* that gets deferred until there is space. */ uint32 interrupts; /* # of times interrupted. */ uint32 pktsReceived; /* # of packets received. */ uint32 rxBuffersLow; /* # of times that the driver was low on */ /* receive buffers. */ #ifdef ENABLE_VMXNET2_PROFILING Vmxnet2_VmmStats vmmStats; /* vmm related stats for perf study */ #endif } Vmxnet2_DriverStats; /* * Shared data structure between the vm, the vmm, and the vmkernel. * This structure was originally arranged to try to group common data * on 32-byte cache lines, but bit rot and the fact that we no longer * run on many CPUs with that cacheline size killed that optimization. * vmxnet3 should target 128 byte sizes and alignments to optimize for * the 64 byte cacheline pairs on P4. */ typedef struct Vmxnet2_DriverData { /* * Magic must be first. */ Vmxnet_DDMagic magic; /* * Receive fields. */ uint32 rxRingLength; /* Length of the receive ring. */ uint32 rxDriverNext; /* Index of the next packet that will */ /* be filled in by the impl */ uint32 rxRingLength2; /* Length of the 2nd receive ring. */ uint32 rxDriverNext2; /* Index of the next packet that will */ /* be filled in by the impl */ uint32 notUsed1; /* was "irq" */ /* * Interface flags and multicast filter. */ uint32 ifflags; uint32 LADRF[VMXNET_MAX_LADRF]; /* * Transmit fields */ uint32 txDontClusterSize; /* All packets <= this will be transmitted */ /* immediately, regardless of clustering */ /* settings [was fill[1]] */ uint32 txRingLength; /* Length of the transmit ring. */ uint32 txDriverCur; /* Index of the next packet to be */ /* returned by the implementation.*/ uint32 txDriverNext; /* Index of the entry in the ring */ /* buffer to use for the next packet.*/ uint32 txStopped; /* The driver has stopped transmitting */ /* because its ring buffer is full.*/ uint32 txClusterLength; /* Maximum number of packets to */ /* put in the ring buffer before */ /* asking the implementation to */ /* transmit the packets in the buffer.*/ uint32 txNumDeferred; /* Number of packets that have been */ /* queued in the ring buffer since */ /* the last time the implementation */ /* was asked to transmit. */ uint32 notUsed3; /* This field is deprecated but still used */ /* as minXmitPhysLength on the escher branch. */ /* It cannot be used for other purposes */ /* until escher vms no longer are allowed */ /* to install this driver. */ uint32 totalRxBuffers; /* used by esx for max rx buffers */ uint64 rxBufferPhysStart; /* used by esx for pinng rx buffers */ /* * Extra fields for future expansion. */ uint32 extra[2]; uint16 maxFrags; /* # of frags the driver can handle */ uint16 featureCtl; /* for driver to enable some feature */ /* * The following fields are used to save the nicNext indexes part * of implData in the vmkernel when disconnecting the adapter, we * need them when we reconnect. This mechanism is used for * checkpointing as well. */ uint32 savedRxNICNext; uint32 savedRxNICNext2; uint32 savedTxNICNext; /* * Fields used during initialization or debugging. */ uint32 length; uint32 rxRingOffset; uint32 rxRingOffset2; uint32 txRingOffset; uint32 debugLevel; uint32 txBufferPhysStart; uint32 txBufferPhysLength; uint32 txPktMaxSize; /* * Driver statistics. */ Vmxnet2_DriverStats stats; } Vmxnet2_DriverData; /* * Shared between VMM and Vmkernel part of vmxnet2 to optimize action posting * VMM writes 1 (don't post) or 0 (okay to post) and vmk reads this. */ typedef struct VmxnetVMKShared { uint32 dontPostActions; } VmxnetVMKShared; #if defined VMX86_VMX || defined VMKERNEL /* * Inline functions used to assist the implementation of the vmxnet interface. */ /* * Get the next empty packet out of the receive ring and move to * the next packet. */ static INLINE Vmxnet2_RxRingEntry * Vmxnet2_GetNextRx(Vmxnet2_RxRingInfo *ri, uint16 ownership) { Vmxnet2_RxRingEntry *rre = ri->base + ri->nicNext; if (rre->ownership == ownership) { VMXNET_INC(ri->nicNext, ri->ringLength); } else { rre = NULL; } return rre; } /* * Return ownership of a packet in the receive ring to the driver. */ static INLINE void Vmxnet2_PutRx(Vmxnet2_RxRingEntry *rre, uint32 pktLength, uint16 ownership) { rre->actualLength = pktLength; COMPILER_MEM_BARRIER(); rre->ownership = ownership; } /* * Get the next pending packet out of the transmit ring. */ static INLINE Vmxnet2_TxRingEntry * Vmxnet2_GetNextTx(Vmxnet2_TxRingInfo *ri) { Vmxnet2_TxRingEntry *txre = ri->base + ri->nicNext; if (txre->ownership == VMXNET2_OWNERSHIP_NIC) { return txre; } else { return NULL; } } /* * Move to the next entry in the transmit ring. */ static INLINE unsigned int Vmxnet2_IncNextTx(Vmxnet2_TxRingInfo *ri) { unsigned int prev = ri->nicNext; Vmxnet2_TxRingEntry *txre = ri->base + ri->nicNext; txre->ownership = VMXNET2_OWNERSHIP_NIC_PENDING; VMXNET_INC(ri->nicNext, ri->ringLength); return prev; } /* * Get the indicated entry from transmit ring. */ static INLINE Vmxnet2_TxRingEntry * Vmxnet2_GetTxEntry(Vmxnet2_TxRingInfo *ri, unsigned int idx) { return ri->base + idx; } /* * Get the indicated entry from the given rx ring */ static INLINE Vmxnet2_RxRingEntry * Vmxnet2_GetRxEntry(Vmxnet2_RxRingInfo *ri, unsigned int idx) { return ri->base + idx; } #endif /* defined VMX86_VMX || defined VMKERNEL */ #endif open-vm-tools-9.4.0-1280544/modules/shared/vmxnet/vmxnet_def.h0000644765153500003110000001433412220061556022213 0ustar dtormts/********************************************************* * Copyright (C) 1999 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ #ifndef _VMXNET_DEF_H_ #define _VMXNET_DEF_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_DISTRIBUTE #include "includeCheck.h" #include "net_sg.h" #include "vmnet_def.h" /* * Vmxnet I/O ports, used by both the vmxnet driver and * the device emulation code. */ #define VMXNET_INIT_ADDR 0x00 #define VMXNET_INIT_LENGTH 0x04 #define VMXNET_TX_ADDR 0x08 #define VMXNET_COMMAND_ADDR 0x0c #define VMXNET_MAC_ADDR 0x10 #define VMXNET_LOW_VERSION 0x18 #define VMXNET_HIGH_VERSION 0x1c #define VMXNET_STATUS_ADDR 0x20 #define VMXNET_TOE_INIT_ADDR 0x24 #define VMXNET_APROM_ADDR 0x28 #define VMXNET_INT_ENABLE_ADDR 0x30 #define VMXNET_WAKE_PKT_PATTERNS 0x34 /* * Vmxnet command register values. */ #define VMXNET_CMD_INTR_ACK 0x0001 #define VMXNET_CMD_UPDATE_LADRF 0x0002 #define VMXNET_CMD_UPDATE_IFF 0x0004 #define VMXNET_CMD_UNUSED 1 0x0008 #define VMXNET_CMD_UNUSED_2 0x0010 #define VMXNET_CMD_INTR_DISABLE 0x0020 #define VMXNET_CMD_INTR_ENABLE 0x0040 #define VMXNET_CMD_UNUSED_3 0x0080 #define VMXNET_CMD_CHECK_TX_DONE 0x0100 #define VMXNET_CMD_GET_NUM_RX_BUFFERS 0x0200 #define VMXNET_CMD_GET_NUM_TX_BUFFERS 0x0400 #define VMXNET_CMD_PIN_TX_BUFFERS 0x0800 #define VMXNET_CMD_GET_CAPABILITIES 0x1000 #define VMXNET_CMD_GET_FEATURES 0x2000 #define VMXNET_CMD_SET_POWER_FULL 0x4000 #define VMXNET_CMD_SET_POWER_LOW 0x8000 /* * Vmxnet status register values. */ #define VMXNET_STATUS_CONNECTED 0x0001 #define VMXNET_STATUS_ENABLED 0x0002 #define VMXNET_STATUS_TX_PINNED 0x0004 /* * Values for the interface flags. */ #define VMXNET_IFF_PROMISC 0x01 #define VMXNET_IFF_BROADCAST 0x02 #define VMXNET_IFF_MULTICAST 0x04 #define VMXNET_IFF_DIRECTED 0x08 /* * Length of the multicast address filter. */ #define VMXNET_MAX_LADRF 2 /* * Size of Vmxnet APROM. */ #define VMXNET_APROM_SIZE 6 /* * An invalid ring index. */ #define VMXNET_INVALID_RING_INDEX (-1) /* * Features that are implemented by the driver. These are driver * specific so not all features will be listed here. In addition not all * drivers have to pay attention to these feature flags. * * VMXNET_FEATURE_ZERO_COPY_TX The driver won't do any copies as long as * the packet length is > * Vmxnet_DriverData.minTxPhysLength. * * VMXNET_FEATURE_TSO The driver will use the TSO capabilities * of the underlying hardware if available * and enabled. * * VMXNET_FEATURE_JUMBO_FRAME The driver can send/rcv jumbo frame * * VMXNET_FEATURE_LPD The backend can deliver large pkts */ #define VMXNET_FEATURE_ZERO_COPY_TX 0x01 #define VMXNET_FEATURE_TSO 0x02 #define VMXNET_FEATURE_JUMBO_FRAME 0x04 #define VMXNET_FEATURE_LPD 0x08 /* * Define the set of capabilities required by each feature above */ #define VMXNET_FEATURE_ZERO_COPY_TX_CAPS VMXNET_CAP_SG #define VMXNET_FEATURE_TSO_CAPS VMXNET_CAP_TSO #define VMXNET_HIGHEST_FEATURE_BIT VMXNET_FEATURE_TSO #define VMXNET_INC(val, max) \ val++; \ if (UNLIKELY(val == max)) { \ val = 0; \ } /* * code that just wants to switch on the different versions of the * guest<->implementation protocol can cast driver data to this. */ typedef uint32 Vmxnet_DDMagic; /* * Wake packet pattern commands sent through VMXNET_WAKE_PKT_PATTERNS port */ #define VMXNET_PM_OPCODE_START 3 /* args: cnt of wake packet patterns */ #define VMXNET_PM_OPCODE_LEN 2 /* args: index of wake packet pattern */ /* number of pattern byte values */ #define VMXNET_PM_OPCODE_DATA 1 /* args: index of wake packet pattern */ /* offset in pattern byte values list */ /* packet byte offset */ /* packet byte value */ #define VMXNET_PM_OPCODE_END 0 /* args: */ typedef union Vmxnet_WakePktCmd { uint32 pktData : 32; struct { unsigned cmd : 2; /* wake packet pattern cmd [from list above] */ unsigned cnt : 3; /* cnt wk pkt pttrns 1..MAX_NUM_FILTER_PTTRNS */ unsigned ind : 3; /* ind wk pkt pttrn 0..MAX_NUM_FILTER_PTTRNS-1 */ unsigned lenOff : 8; /* num pttrn byte vals 1..MAX_PKT_FILTER_SIZE */ /* OR offset in pattern byte values list */ /* 0..MAX_PKT_FILTER_SIZE-1 */ unsigned byteOff : 8; /* pkt byte offset 0..MAX_PKT_FILTER_SIZE-1 */ unsigned byteVal : 8; /* packet byte value 0..255 */ } pktPttrn; } Vmxnet_WakePktCmd; #endif /* _VMXNET_DEF_H_ */ open-vm-tools-9.4.0-1280544/modules/shared/vmxnet/vmnet_def.h0000644765153500003110000001635512220061556022030 0ustar dtormts/********************************************************* * Copyright (C) 2004-2011 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * vmnet_def.h * * - definitions which are (mostly) not vmxnet or vlance specific */ #ifndef _VMNET_DEF_H_ #define _VMNET_DEF_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_DISTRIBUTE #include "includeCheck.h" #define VMNET_NAME_BUFFER_LEN 128 /* Increased for i18n. */ #define VMNET_COAL_STRING_LEN 16 /* * capabilities - not all of these are implemented in the virtual HW * (eg VLAN support is in the virtual switch) so even vlance * can use them */ #define VMNET_CAP_SG CONST64U(0x0001) /* Can do scatter-gather transmits. */ #define VMNET_CAP_IP4_CSUM CONST64U(0x0002) /* Can checksum only TCP/UDP over IPv4. */ #define VMNET_CAP_HW_CSUM CONST64U(0x0004) /* Can checksum all packets. */ #define VMNET_CAP_HIGH_DMA CONST64U(0x0008) /* Can DMA to high memory. */ #define VMNET_CAP_TOE CONST64U(0x0010) /* Supports TCP/IP offload. */ #define VMNET_CAP_TSO CONST64U(0x0020) /* Supports TCP Segmentation offload */ #define VMNET_CAP_SW_TSO CONST64U(0x0040) /* Supports SW TCP Segmentation */ #define VMNET_CAP_VMXNET_APROM CONST64U(0x0080) /* Vmxnet APROM support */ #define VMNET_CAP_HW_TX_VLAN CONST64U(0x0100) /* Can we do VLAN tagging in HW */ #define VMNET_CAP_HW_RX_VLAN CONST64U(0x0200) /* Can we do VLAN untagging in HW */ #define VMNET_CAP_SW_VLAN CONST64U(0x0400) /* Can we do VLAN tagging/untagging in SW */ #define VMNET_CAP_WAKE_PCKT_RCV CONST64U(0x0800) /* Can wake on network packet recv? */ #define VMNET_CAP_ENABLE_INT_INLINE CONST64U(0x1000) /* Enable Interrupt Inline */ #define VMNET_CAP_ENABLE_HEADER_COPY CONST64U(0x2000) /* copy header for vmkernel */ #define VMNET_CAP_TX_CHAIN CONST64U(0x4000) /* Guest can use multiple tx entries for a pkt */ #define VMNET_CAP_RX_CHAIN CONST64U(0x8000) /* a pkt can span multiple rx entries */ #define VMNET_CAP_LPD CONST64U(0x10000) /* large pkt delivery */ #define VMNET_CAP_BPF CONST64U(0x20000) /* BPF Support in VMXNET Virtual Hardware */ #define VMNET_CAP_SG_SPAN_PAGES CONST64U(0x40000) /* Can do scatter-gather span multiple pages transmits. */ #define VMNET_CAP_IP6_CSUM CONST64U(0x80000) /* Can do IPv6 csum offload. */ #define VMNET_CAP_TSO6 CONST64U(0x100000) /* Can do TSO segmentation offload for IPv6 pkts. */ #define VMNET_CAP_TSO256k CONST64U(0x200000) /* Can do TSO segmentation offload for pkts up to 256kB. */ #define VMNET_CAP_UPT CONST64U(0x400000) /* Support UPT */ #define VMNET_CAP_RDONLY_INETHDRS CONST64U(0x800000) /* Modifies inet headers for TSO/CSUm */ #define VMNET_CAP_ENCAP CONST64U(0x1000000) /* NPA not used, so redefining for ENCAP support */ #define VMNET_CAP_DCB CONST64U(0x2000000) /* Support DCB */ #define VMNET_CAP_OFFLOAD_8OFFSET CONST64U(0x4000000) /* supports 8bit parameterized offsets */ #define VMNET_CAP_OFFLOAD_16OFFSET CONST64U(0x8000000) /* supports 16bit parameterized offsets */ #define VMNET_CAP_IP6_CSUM_EXT_HDRS CONST64U(0x10000000) /* support csum of ip6 ext hdrs */ #define VMNET_CAP_TSO6_EXT_HDRS CONST64U(0x20000000) /* support TSO for ip6 ext hdrs */ #define VMNET_CAP_SCHED CONST64U(0x40000000) /* compliant with network scheduling */ #define VMNET_CAP_SRIOV CONST64U(0x80000000) /* Supports SR-IOV */ #define VMNET_CAP_SG_TX VMNET_CAP_SG #define VMNET_CAP_SG_RX CONST64U(0x200000000) /* Scatter-gather receive capability */ #define VMNET_CAP_PRIV_STATS CONST64U(0x400000000) /* Driver supports accessing private stats */ #define VMNET_CAP_LINK_STATUS_SET CONST64U(0x800000000) /* Driver supports changing link status */ #define VMNET_CAP_MAC_ADDR_SET CONST64U(0x1000000000) /* Driver supports changing the interface MAC address */ #define VMNET_CAP_COALESCE_PARAMS CONST64U(0x2000000000) /* Driver supports changing interrupt coalescing parameters */ #define VMNET_CAP_VLAN_FILTER CONST64U(0x4000000000) /* VLAN Filtering capability */ #define VMNET_CAP_WAKE_ON_LAN CONST64U(0x8000000000) /* Wake-On-LAN capability */ #define VMNET_CAP_NETWORK_DUMP CONST64U(0x10000000000) /* Network core dumping capability */ #define VMNET_CAP_MULTI_QUEUE CONST64U(0x20000000000) /* Multiple queue capability */ #define VMNET_CAP_EEPROM CONST64U(0x40000000000) /* EEPROM dump capability */ #define VMNET_CAP_REGDUMP CONST64U(0x80000000000) /* Register dump capability */ #define VMNET_CAP_SELF_TEST CONST64U(0x100000000000) /* Self-test capability */ #define VMNET_CAP_PAUSE_PARAMS CONST64U(0x200000000000) /* Pause frame parameter adjusting */ #define VMNET_CAP_RESTART_NEG CONST64U(0x400000000000) /* Ability to restart negotiation of link speed/duplexity */ #define VMNET_CAP_LRO CONST64U(0x800000000000) /* Hardware supported LRO */ #define VMNET_CAP_OFFLOAD_ALIGN_ANY CONST64U(0x1000000000000) /* Nic requires no header alignment */ #define VMNET_CAP_GENERIC_OFFLOAD CONST64U(0x2000000000000) /* Generic hardware offloading (eg. vxlan encap offload and offset based offload) */ #define VMNET_CAP_LEGACY CONST64U(0x8000000000000000) /* Uplink is compatible with vmklinux drivers */ #endif // _VMNET_DEF_H_ open-vm-tools-9.4.0-1280544/modules/shared/vmxnet/net_sg.h0000644765153500003110000000504312220061556021330 0ustar dtormts/********************************************************* * Copyright (C) 2000 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * net_sg.h -- * * Network packet scatter gather structure. */ #ifndef _NET_SG_H #define _NET_SG_H #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_DISTRIBUTE #include "includeCheck.h" #define NET_SG_DEFAULT_LENGTH 16 /* * A single scatter-gather element for a network packet. * The address is split into low and high to save space. * If we make it 64 bits then Windows pads things out such that * we lose a lot of space for each scatter gather array. * This adds up when you have embedded scatter-gather * arrays for transmit and receive ring buffers. */ typedef struct NetSG_Elem { uint32 addrLow; uint16 addrHi; uint16 length; } NetSG_Elem; typedef enum NetSG_AddrType { NET_SG_MACH_ADDR, NET_SG_PHYS_ADDR, NET_SG_VIRT_ADDR, } NetSG_AddrType; typedef struct NetSG_Array { uint16 addrType; uint16 length; NetSG_Elem sg[NET_SG_DEFAULT_LENGTH]; } NetSG_Array; #define NET_SG_MAKE_PA(elem) (PA)QWORD(elem.addrHi, elem.addrLow) #define NET_SG_MAKE_PTR(elem) (char *)(uintptr_t)QWORD(elem.addrHi, elem.addrLow) #endif open-vm-tools-9.4.0-1280544/modules/shared/vmxnet/net.h0000644765153500003110000001434012220061556020637 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /************************************************************ * * net.h * * This file should contain all network global defines. * No vlance/vmxnet/vnet/vmknet specific stuff should be * put here only defines used/usable by all network code. * --gustav * ************************************************************/ #ifndef VMWARE_DEVICES_NET_H #define VMWARE_DEVICES_NET_H #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #include "vm_device_version.h" #ifdef VMCORE #include "config.h" #include "str.h" #include "strutil.h" #endif #define ETHERNET_MTU 1518 #ifndef ETHER_ADDR_LEN #define ETHER_ADDR_LEN 6 /* length of MAC address */ #endif #define ETH_HEADER_LEN 14 /* length of Ethernet header */ #define IP_ADDR_LEN 4 /* length of IPv4 address */ #define IP_HEADER_LEN 20 /* minimum length of IPv4 header */ #define ETHER_MAX_QUEUED_PACKET 1600 /* * State's that a NIC can be in currently we only use this * in VLance but if we implement/emulate new adapters that * we also want to be able to morph a new corresponding * state should be added. */ #define LANCE_CHIP 0x2934 #define VMXNET_CHIP 0x4392 /* * Size of reserved IO space needed by the LANCE adapter and * the VMXNET adapter. If you add more ports to Vmxnet than * there is reserved space you must bump VMXNET_CHIP_IO_RESV_SIZE. * The sizes must be powers of 2. */ #define LANCE_CHIP_IO_RESV_SIZE 0x20 #define VMXNET_CHIP_IO_RESV_SIZE 0x40 #define MORPH_PORT_SIZE 4 #ifdef VMCORE typedef struct Net_AdapterCount { uint8 vlance; uint8 vmxnet2; uint8 vmxnet3; uint8 e1000; uint8 e1000e; } Net_AdapterCount; #endif #ifdef USERLEVEL /* *---------------------------------------------------------------------------- * * Net_AddAddrToLADRF -- * * Given a MAC address, sets the corresponding bit in the LANCE style * Logical Address Filter 'ladrf'. * The caller should have initialized the ladrf to all 0's, as this * function only ORs on a bit in the array. * 'addr' is presumed to be ETHER_ADDR_LEN in size; * 'ladrf' is presumed to point to a 64-bit vector. * * Derived from a long history of derivations, originally inspired by * sample code from the AMD "Network Products: Ethernet Controllers 1998 * Data Book, Book 2", pages 1-53..1-55. * * Returns: * None. * * Side effects: * Updates 'ladrf'. * *---------------------------------------------------------------------------- */ static INLINE void Net_AddAddrToLadrf(const uint8 *addr, // IN: pointer to MAC address uint8 *ladrf) // IN/OUT: pointer to ladrf { #define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */ uint16 hashcode; int32 crc = 0xffffffff; /* init CRC for each address */ int32 j; int32 bit; int32 byte; ASSERT(addr); ASSERT(ladrf); for (byte = 0; byte < ETHER_ADDR_LEN; byte++) { /* for each address byte */ /* process each address bit */ for (bit = *addr++, j = 0; j < 8; j++, bit >>= 1) { crc = (crc << 1) ^ ((((crc < 0 ? 1 : 0) ^ bit) & 0x01) ? CRC_POLYNOMIAL_BE : 0); } } hashcode = (crc & 1); /* hashcode is 6 LSb of CRC ... */ for (j = 0; j < 5; j++) { /* ... in reverse order. */ hashcode = (hashcode << 1) | ((crc>>=1) & 1); } ladrf[hashcode >> 3] |= 1 << (hashcode & 0x07); } #endif // USERLEVEL #ifdef VMCORE /* *---------------------------------------------------------------------- * * Net_GetNumAdapters -- * * Returns the number of each type of network adapter configured in this * VM. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE void Net_GetNumAdapters(Net_AdapterCount *counts) { uint32 i; counts->vlance = 0; counts->vmxnet2 = 0; counts->vmxnet3 = 0; counts->e1000 = 0; counts->e1000e = 0; for (i = 0; i < MAX_ETHERNET_CARDS; i++) { char* adapterStr; if (!Config_GetBool(FALSE, "ethernet%d.present", i)) { continue; } adapterStr = Config_GetString("vlance", "ethernet%d.virtualDev", i); if (Str_Strcasecmp(adapterStr, "vmxnet3") == 0) { counts->vmxnet3++; } else if (Str_Strcasecmp(adapterStr, "vlance") == 0) { counts->vlance++; } else if (Str_Strcasecmp(adapterStr, "vmxnet") == 0) { counts->vmxnet2++; } else if (Str_Strcasecmp(adapterStr, "e1000") == 0) { counts->e1000++; } else if (Str_Strcasecmp(adapterStr, "e1000e") == 0) { counts->e1000e++; } else { LOG_ONCE(("%s: unknown adapter: %s\n", __FUNCTION__, adapterStr)); } free(adapterStr); } } #endif // VMCORE #endif // VMWARE_DEVICES_NET_H open-vm-tools-9.4.0-1280544/modules/shared/vmxnet/vmxnet3_defs.h0000644765153500003110000005465112220061556022467 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * 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 version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * vmxnet3_defs.h -- * * Definitions shared by device emulation and guest drivers for * VMXNET3 NIC */ #ifndef _VMXNET3_DEFS_H_ #define _VMXNET3_DEFS_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_DISTRIBUTE #define INCLUDE_ALLOW_VMKDRIVERS #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_MODULE #include "includeCheck.h" #include "upt1_defs.h" /* all registers are 32 bit wide */ /* BAR 1 */ #define VMXNET3_REG_VRRS 0x0 /* Vmxnet3 Revision Report Selection */ #define VMXNET3_REG_UVRS 0x8 /* UPT Version Report Selection */ #define VMXNET3_REG_DSAL 0x10 /* Driver Shared Address Low */ #define VMXNET3_REG_DSAH 0x18 /* Driver Shared Address High */ #define VMXNET3_REG_CMD 0x20 /* Command */ #define VMXNET3_REG_MACL 0x28 /* MAC Address Low */ #define VMXNET3_REG_MACH 0x30 /* MAC Address High */ #define VMXNET3_REG_ICR 0x38 /* Interrupt Cause Register */ #define VMXNET3_REG_ECR 0x40 /* Event Cause Register */ #define VMXNET3_REG_WSAL 0xF00 /* Wireless Shared Address Lo */ #define VMXNET3_REG_WSAH 0xF08 /* Wireless Shared Address Hi */ #define VMXNET3_REG_WCMD 0xF18 /* Wireless Command */ /* BAR 0 */ #define VMXNET3_REG_IMR 0x0 /* Interrupt Mask Register */ #define VMXNET3_REG_TXPROD 0x600 /* Tx Producer Index */ #define VMXNET3_REG_RXPROD 0x800 /* Rx Producer Index for ring 1 */ #define VMXNET3_REG_RXPROD2 0xA00 /* Rx Producer Index for ring 2 */ #define VMXNET3_PT_REG_SIZE 4096 /* BAR 0 */ #define VMXNET3_VD_REG_SIZE 4096 /* BAR 1 */ /* * The two Vmxnet3 MMIO Register PCI BARs (BAR 0 at offset 10h and BAR 1 at * offset 14h) as well as the MSI-X BAR are combined into one PhysMem region: * <-VMXNET3_PT_REG_SIZE-><-VMXNET3_VD_REG_SIZE-><-VMXNET3_MSIX_BAR_SIZE--> * ------------------------------------------------------------------------- * |Pass Thru Registers | Virtual Dev Registers | MSI-X Vector/PBA Table | * ------------------------------------------------------------------------- * VMXNET3_MSIX_BAR_SIZE is defined in "vmxnet3Int.h" */ #define VMXNET3_PHYSMEM_PAGES 4 #define VMXNET3_REG_ALIGN 8 /* All registers are 8-byte aligned. */ #define VMXNET3_REG_ALIGN_MASK 0x7 /* I/O Mapped access to registers */ #define VMXNET3_IO_TYPE_PT 0 #define VMXNET3_IO_TYPE_VD 1 #define VMXNET3_IO_ADDR(type, reg) (((type) << 24) | ((reg) & 0xFFFFFF)) #define VMXNET3_IO_TYPE(addr) ((addr) >> 24) #define VMXNET3_IO_REG(addr) ((addr) & 0xFFFFFF) #ifndef __le16 #define __le16 uint16 #endif #ifndef __le32 #define __le32 uint32 #endif #ifndef __le64 #define __le64 uint64 #endif typedef enum { VMXNET3_CMD_FIRST_SET = 0xCAFE0000, VMXNET3_CMD_ACTIVATE_DEV = VMXNET3_CMD_FIRST_SET, VMXNET3_CMD_QUIESCE_DEV, VMXNET3_CMD_RESET_DEV, VMXNET3_CMD_UPDATE_RX_MODE, VMXNET3_CMD_UPDATE_MAC_FILTERS, VMXNET3_CMD_UPDATE_VLAN_FILTERS, VMXNET3_CMD_UPDATE_RSSIDT, VMXNET3_CMD_UPDATE_IML, VMXNET3_CMD_UPDATE_PMCFG, VMXNET3_CMD_UPDATE_FEATURE, VMXNET3_CMD_STOP_EMULATION, VMXNET3_CMD_LOAD_PLUGIN, VMXNET3_CMD_ACTIVATE_VF, VMXNET3_CMD_FIRST_GET = 0xF00D0000, VMXNET3_CMD_GET_QUEUE_STATUS = VMXNET3_CMD_FIRST_GET, VMXNET3_CMD_GET_STATS, VMXNET3_CMD_GET_LINK, VMXNET3_CMD_GET_PERM_MAC_LO, VMXNET3_CMD_GET_PERM_MAC_HI, VMXNET3_CMD_GET_DID_LO, VMXNET3_CMD_GET_DID_HI, VMXNET3_CMD_GET_DEV_EXTRA_INFO, VMXNET3_CMD_GET_CONF_INTR, VMXNET3_CMD_GET_ADAPTIVE_RING_INFO } Vmxnet3_Cmd; /* Adaptive Ring Info Flags */ #define VMXNET3_DISABLE_ADAPTIVE_RING 1 /* * Little Endian layout of bitfields - * Byte 0 : 7.....len.....0 * Byte 1 : rsvd gen 13.len.8 * Byte 2 : 5.msscof.0 ext1 dtype * Byte 3 : 13...msscof...6 * * Big Endian layout of bitfields - * Byte 0: 13...msscof...6 * Byte 1 : 5.msscof.0 ext1 dtype * Byte 2 : rsvd gen 13.len.8 * Byte 3 : 7.....len.....0 * * Thus, le32_to_cpu on the dword will allow the big endian driver to read * the bit fields correctly. And cpu_to_le32 will convert bitfields * bit fields written by big endian driver to format required by device. */ typedef #include "vmware_pack_begin.h" struct Vmxnet3_TxDesc { __le64 addr; #ifdef __BIG_ENDIAN_BITFIELD uint32 msscof:14; /* MSS, checksum offset, flags */ uint32 ext1:1; uint32 dtype:1; /* descriptor type */ uint32 rsvd:1; uint32 gen:1; /* generation bit */ uint32 len:14; #else uint32 len:14; uint32 gen:1; /* generation bit */ uint32 rsvd:1; uint32 dtype:1; /* descriptor type */ uint32 ext1:1; uint32 msscof:14; /* MSS, checksum offset, flags */ #endif /* __BIG_ENDIAN_BITFIELD */ #ifdef __BIG_ENDIAN_BITFIELD uint32 tci:16; /* Tag to Insert */ uint32 ti:1; /* VLAN Tag Insertion */ uint32 ext2:1; uint32 cq:1; /* completion request */ uint32 eop:1; /* End Of Packet */ uint32 om:2; /* offload mode */ uint32 hlen:10; /* header len */ #else uint32 hlen:10; /* header len */ uint32 om:2; /* offload mode */ uint32 eop:1; /* End Of Packet */ uint32 cq:1; /* completion request */ uint32 ext2:1; uint32 ti:1; /* VLAN Tag Insertion */ uint32 tci:16; /* Tag to Insert */ #endif /* __BIG_ENDIAN_BITFIELD */ } #include "vmware_pack_end.h" Vmxnet3_TxDesc; /* TxDesc.OM values */ #define VMXNET3_OM_NONE 0 #define VMXNET3_OM_CSUM 2 #define VMXNET3_OM_TSO 3 /* fields in TxDesc we access w/o using bit fields */ #define VMXNET3_TXD_EOP_SHIFT 12 #define VMXNET3_TXD_CQ_SHIFT 13 #define VMXNET3_TXD_GEN_SHIFT 14 #define VMXNET3_TXD_EOP_DWORD_SHIFT 3 #define VMXNET3_TXD_GEN_DWORD_SHIFT 2 #define VMXNET3_TXD_CQ (1 << VMXNET3_TXD_CQ_SHIFT) #define VMXNET3_TXD_EOP (1 << VMXNET3_TXD_EOP_SHIFT) #define VMXNET3_TXD_GEN (1 << VMXNET3_TXD_GEN_SHIFT) #define VMXNET3_TXD_GEN_SIZE 1 #define VMXNET3_TXD_EOP_SIZE 1 #define VMXNET3_HDR_COPY_SIZE 128 typedef #include "vmware_pack_begin.h" struct Vmxnet3_TxDataDesc { uint8 data[VMXNET3_HDR_COPY_SIZE]; } #include "vmware_pack_end.h" Vmxnet3_TxDataDesc; #define VMXNET3_TCD_GEN_SHIFT 31 #define VMXNET3_TCD_GEN_SIZE 1 #define VMXNET3_TCD_TXIDX_SHIFT 0 #define VMXNET3_TCD_TXIDX_SIZE 12 #define VMXNET3_TCD_GEN_DWORD_SHIFT 3 typedef #include "vmware_pack_begin.h" struct Vmxnet3_TxCompDesc { uint32 txdIdx:12; /* Index of the EOP TxDesc */ uint32 ext1:20; __le32 ext2; __le32 ext3; uint32 rsvd:24; uint32 type:7; /* completion type */ uint32 gen:1; /* generation bit */ } #include "vmware_pack_end.h" Vmxnet3_TxCompDesc; typedef #include "vmware_pack_begin.h" struct Vmxnet3_RxDesc { __le64 addr; #ifdef __BIG_ENDIAN_BITFIELD uint32 gen:1; /* Generation bit */ uint32 rsvd:15; uint32 dtype:1; /* Descriptor type */ uint32 btype:1; /* Buffer Type */ uint32 len:14; #else uint32 len:14; uint32 btype:1; /* Buffer Type */ uint32 dtype:1; /* Descriptor type */ uint32 rsvd:15; uint32 gen:1; /* Generation bit */ #endif __le32 ext1; } #include "vmware_pack_end.h" Vmxnet3_RxDesc; /* values of RXD.BTYPE */ #define VMXNET3_RXD_BTYPE_HEAD 0 /* head only */ #define VMXNET3_RXD_BTYPE_BODY 1 /* body only */ /* fields in RxDesc we access w/o using bit fields */ #define VMXNET3_RXD_BTYPE_SHIFT 14 #define VMXNET3_RXD_GEN_SHIFT 31 typedef #include "vmware_pack_begin.h" struct Vmxnet3_RxCompDesc { #ifdef __BIG_ENDIAN_BITFIELD uint32 ext2:1; uint32 cnc:1; /* Checksum Not Calculated */ uint32 rssType:4; /* RSS hash type used */ uint32 rqID:10; /* rx queue/ring ID */ uint32 sop:1; /* Start of Packet */ uint32 eop:1; /* End of Packet */ uint32 ext1:2; uint32 rxdIdx:12; /* Index of the RxDesc */ #else uint32 rxdIdx:12; /* Index of the RxDesc */ uint32 ext1:2; uint32 eop:1; /* End of Packet */ uint32 sop:1; /* Start of Packet */ uint32 rqID:10; /* rx queue/ring ID */ uint32 rssType:4; /* RSS hash type used */ uint32 cnc:1; /* Checksum Not Calculated */ uint32 ext2:1; #endif /* __BIG_ENDIAN_BITFIELD */ __le32 rssHash; /* RSS hash value */ #ifdef __BIG_ENDIAN_BITFIELD uint32 tci:16; /* Tag stripped */ uint32 ts:1; /* Tag is stripped */ uint32 err:1; /* Error */ uint32 len:14; /* data length */ #else uint32 len:14; /* data length */ uint32 err:1; /* Error */ uint32 ts:1; /* Tag is stripped */ uint32 tci:16; /* Tag stripped */ #endif /* __BIG_ENDIAN_BITFIELD */ #ifdef __BIG_ENDIAN_BITFIELD uint32 gen:1; /* generation bit */ uint32 type:7; /* completion type */ uint32 fcs:1; /* Frame CRC correct */ uint32 frg:1; /* IP Fragment */ uint32 v4:1; /* IPv4 */ uint32 v6:1; /* IPv6 */ uint32 ipc:1; /* IP Checksum Correct */ uint32 tcp:1; /* TCP packet */ uint32 udp:1; /* UDP packet */ uint32 tuc:1; /* TCP/UDP Checksum Correct */ uint32 csum:16; #else uint32 csum:16; uint32 tuc:1; /* TCP/UDP Checksum Correct */ uint32 udp:1; /* UDP packet */ uint32 tcp:1; /* TCP packet */ uint32 ipc:1; /* IP Checksum Correct */ uint32 v6:1; /* IPv6 */ uint32 v4:1; /* IPv4 */ uint32 frg:1; /* IP Fragment */ uint32 fcs:1; /* Frame CRC correct */ uint32 type:7; /* completion type */ uint32 gen:1; /* generation bit */ #endif /* __BIG_ENDIAN_BITFIELD */ } #include "vmware_pack_end.h" Vmxnet3_RxCompDesc; /* fields in RxCompDesc we access via Vmxnet3_GenericDesc.dword[3] */ #define VMXNET3_RCD_TUC_SHIFT 16 #define VMXNET3_RCD_IPC_SHIFT 19 /* fields in RxCompDesc we access via Vmxnet3_GenericDesc.qword[1] */ #define VMXNET3_RCD_TYPE_SHIFT 56 #define VMXNET3_RCD_GEN_SHIFT 63 /* csum OK for TCP/UDP pkts over IP */ #define VMXNET3_RCD_CSUM_OK (1 << VMXNET3_RCD_TUC_SHIFT | 1 << VMXNET3_RCD_IPC_SHIFT) /* value of RxCompDesc.rssType */ #define VMXNET3_RCD_RSS_TYPE_NONE 0 #define VMXNET3_RCD_RSS_TYPE_IPV4 1 #define VMXNET3_RCD_RSS_TYPE_TCPIPV4 2 #define VMXNET3_RCD_RSS_TYPE_IPV6 3 #define VMXNET3_RCD_RSS_TYPE_TCPIPV6 4 /* a union for accessing all cmd/completion descriptors */ typedef union Vmxnet3_GenericDesc { __le64 qword[2]; __le32 dword[4]; __le16 word[8]; Vmxnet3_TxDesc txd; Vmxnet3_RxDesc rxd; Vmxnet3_TxCompDesc tcd; Vmxnet3_RxCompDesc rcd; } Vmxnet3_GenericDesc; #define VMXNET3_INIT_GEN 1 /* Max size of a single tx buffer */ #define VMXNET3_MAX_TX_BUF_SIZE (1 << 14) /* # of tx desc needed for a tx buffer size */ #define VMXNET3_TXD_NEEDED(size) (((size) + VMXNET3_MAX_TX_BUF_SIZE - 1) / VMXNET3_MAX_TX_BUF_SIZE) /* max # of tx descs for a non-tso pkt */ #define VMXNET3_MAX_TXD_PER_PKT 16 /* Max size of a single rx buffer */ #define VMXNET3_MAX_RX_BUF_SIZE ((1 << 14) - 1) /* Minimum size of a type 0 buffer */ #define VMXNET3_MIN_T0_BUF_SIZE 128 #define VMXNET3_MAX_CSUM_OFFSET 1024 /* Ring base address alignment */ #define VMXNET3_RING_BA_ALIGN 512 #define VMXNET3_RING_BA_MASK (VMXNET3_RING_BA_ALIGN - 1) /* Ring size must be a multiple of 32 */ #define VMXNET3_RING_SIZE_ALIGN 32 #define VMXNET3_RING_SIZE_MASK (VMXNET3_RING_SIZE_ALIGN - 1) /* Max ring size */ #define VMXNET3_TX_RING_MAX_SIZE 4096 #define VMXNET3_TC_RING_MAX_SIZE 4096 #define VMXNET3_RX_RING_MAX_SIZE 4096 #define VMXNET3_RC_RING_MAX_SIZE 8192 /* a list of reasons for queue stop */ #define VMXNET3_ERR_NOEOP 0x80000000 /* cannot find the EOP desc of a pkt */ #define VMXNET3_ERR_TXD_REUSE 0x80000001 /* reuse a TxDesc before tx completion */ #define VMXNET3_ERR_BIG_PKT 0x80000002 /* too many TxDesc for a pkt */ #define VMXNET3_ERR_DESC_NOT_SPT 0x80000003 /* descriptor type not supported */ #define VMXNET3_ERR_SMALL_BUF 0x80000004 /* type 0 buffer too small */ #define VMXNET3_ERR_STRESS 0x80000005 /* stress option firing in vmkernel */ #define VMXNET3_ERR_SWITCH 0x80000006 /* mode switch failure */ #define VMXNET3_ERR_TXD_INVALID 0x80000007 /* invalid TxDesc */ /* completion descriptor types */ #define VMXNET3_CDTYPE_TXCOMP 0 /* Tx Completion Descriptor */ #define VMXNET3_CDTYPE_RXCOMP 3 /* Rx Completion Descriptor */ #define VMXNET3_GOS_BITS_UNK 0 /* unknown */ #define VMXNET3_GOS_BITS_32 1 #define VMXNET3_GOS_BITS_64 2 #define VMXNET3_GOS_TYPE_UNK 0 /* unknown */ #define VMXNET3_GOS_TYPE_LINUX 1 #define VMXNET3_GOS_TYPE_WIN 2 #define VMXNET3_GOS_TYPE_SOLARIS 3 #define VMXNET3_GOS_TYPE_FREEBSD 4 #define VMXNET3_GOS_TYPE_PXE 5 /* All structures in DriverShared are padded to multiples of 8 bytes */ typedef #include "vmware_pack_begin.h" struct Vmxnet3_GOSInfo { #ifdef __BIG_ENDIAN_BITFIELD uint32 gosMisc: 10; /* other info about gos */ uint32 gosVer: 16; /* gos version */ uint32 gosType: 4; /* which guest */ uint32 gosBits: 2; /* 32-bit or 64-bit? */ #else uint32 gosBits: 2; /* 32-bit or 64-bit? */ uint32 gosType: 4; /* which guest */ uint32 gosVer: 16; /* gos version */ uint32 gosMisc: 10; /* other info about gos */ #endif /* __BIG_ENDIAN_BITFIELD */ } #include "vmware_pack_end.h" Vmxnet3_GOSInfo; typedef #include "vmware_pack_begin.h" struct Vmxnet3_DriverInfo { __le32 version; /* driver version */ Vmxnet3_GOSInfo gos; __le32 vmxnet3RevSpt; /* vmxnet3 revision supported */ __le32 uptVerSpt; /* upt version supported */ } #include "vmware_pack_end.h" Vmxnet3_DriverInfo; #define VMXNET3_REV1_MAGIC 0xbabefee1 /* * QueueDescPA must be 128 bytes aligned. It points to an array of * Vmxnet3_TxQueueDesc followed by an array of Vmxnet3_RxQueueDesc. * The number of Vmxnet3_TxQueueDesc/Vmxnet3_RxQueueDesc are specified by * Vmxnet3_MiscConf.numTxQueues/numRxQueues, respectively. */ #define VMXNET3_QUEUE_DESC_ALIGN 128 typedef #include "vmware_pack_begin.h" struct Vmxnet3_MiscConf { Vmxnet3_DriverInfo driverInfo; __le64 uptFeatures; __le64 ddPA; /* driver data PA */ __le64 queueDescPA; /* queue descriptor table PA */ __le32 ddLen; /* driver data len */ __le32 queueDescLen; /* queue descriptor table len, in bytes */ __le32 mtu; __le16 maxNumRxSG; uint8 numTxQueues; uint8 numRxQueues; __le32 reserved[4]; } #include "vmware_pack_end.h" Vmxnet3_MiscConf; typedef #include "vmware_pack_begin.h" struct Vmxnet3_TxQueueConf { __le64 txRingBasePA; __le64 dataRingBasePA; __le64 compRingBasePA; __le64 ddPA; /* driver data */ __le64 reserved; __le32 txRingSize; /* # of tx desc */ __le32 dataRingSize; /* # of data desc */ __le32 compRingSize; /* # of comp desc */ __le32 ddLen; /* size of driver data */ uint8 intrIdx; uint8 _pad[7]; } #include "vmware_pack_end.h" Vmxnet3_TxQueueConf; typedef #include "vmware_pack_begin.h" struct Vmxnet3_RxQueueConf { __le64 rxRingBasePA[2]; __le64 compRingBasePA; __le64 ddPA; /* driver data */ __le64 reserved; __le32 rxRingSize[2]; /* # of rx desc */ __le32 compRingSize; /* # of rx comp desc */ __le32 ddLen; /* size of driver data */ uint8 intrIdx; uint8 _pad[7]; } #include "vmware_pack_end.h" Vmxnet3_RxQueueConf; enum vmxnet3_intr_mask_mode { VMXNET3_IMM_AUTO = 0, VMXNET3_IMM_ACTIVE = 1, VMXNET3_IMM_LAZY = 2 }; enum vmxnet3_intr_type { VMXNET3_IT_AUTO = 0, VMXNET3_IT_INTX = 1, VMXNET3_IT_MSI = 2, VMXNET3_IT_MSIX = 3 }; #define VMXNET3_MAX_TX_QUEUES 8 #define VMXNET3_MAX_RX_QUEUES 16 /* addition 1 for events */ #define VMXNET3_MAX_INTRS 25 /* value of intrCtrl */ #define VMXNET3_IC_DISABLE_ALL 0x1 /* bit 0 */ typedef #include "vmware_pack_begin.h" struct Vmxnet3_IntrConf { Bool autoMask; uint8 numIntrs; /* # of interrupts */ uint8 eventIntrIdx; uint8 modLevels[VMXNET3_MAX_INTRS]; /* moderation level for each intr */ __le32 intrCtrl; __le32 reserved[2]; } #include "vmware_pack_end.h" Vmxnet3_IntrConf; /* one bit per VLAN ID, the size is in the units of uint32 */ #define VMXNET3_VFT_SIZE (4096 / (sizeof(uint32) * 8)) typedef #include "vmware_pack_begin.h" struct Vmxnet3_QueueStatus { Bool stopped; uint8 _pad[3]; __le32 error; } #include "vmware_pack_end.h" Vmxnet3_QueueStatus; typedef #include "vmware_pack_begin.h" struct Vmxnet3_TxQueueCtrl { __le32 txNumDeferred; __le32 txThreshold; __le64 reserved; } #include "vmware_pack_end.h" Vmxnet3_TxQueueCtrl; typedef #include "vmware_pack_begin.h" struct Vmxnet3_RxQueueCtrl { Bool updateRxProd; uint8 _pad[7]; __le64 reserved; } #include "vmware_pack_end.h" Vmxnet3_RxQueueCtrl; #define VMXNET3_RXM_UCAST 0x01 /* unicast only */ #define VMXNET3_RXM_MCAST 0x02 /* multicast passing the filters */ #define VMXNET3_RXM_BCAST 0x04 /* broadcast only */ #define VMXNET3_RXM_ALL_MULTI 0x08 /* all multicast */ #define VMXNET3_RXM_PROMISC 0x10 /* promiscuous */ typedef #include "vmware_pack_begin.h" struct Vmxnet3_RxFilterConf { __le32 rxMode; /* VMXNET3_RXM_xxx */ __le16 mfTableLen; /* size of the multicast filter table */ __le16 _pad1; __le64 mfTablePA; /* PA of the multicast filters table */ __le32 vfTable[VMXNET3_VFT_SIZE]; /* vlan filter */ } #include "vmware_pack_end.h" Vmxnet3_RxFilterConf; #define VMXNET3_PM_MAX_FILTERS 6 #define VMXNET3_PM_MAX_PATTERN_SIZE 128 #define VMXNET3_PM_MAX_MASK_SIZE (VMXNET3_PM_MAX_PATTERN_SIZE / 8) #define VMXNET3_PM_WAKEUP_MAGIC 0x01 /* wake up on magic pkts */ #define VMXNET3_PM_WAKEUP_FILTER 0x02 /* wake up on pkts matching filters */ typedef #include "vmware_pack_begin.h" struct Vmxnet3_PM_PktFilter { uint8 maskSize; uint8 patternSize; uint8 mask[VMXNET3_PM_MAX_MASK_SIZE]; uint8 pattern[VMXNET3_PM_MAX_PATTERN_SIZE]; uint8 pad[6]; } #include "vmware_pack_end.h" Vmxnet3_PM_PktFilter; typedef #include "vmware_pack_begin.h" struct Vmxnet3_PMConf { __le16 wakeUpEvents; /* VMXNET3_PM_WAKEUP_xxx */ uint8 numFilters; uint8 pad[5]; Vmxnet3_PM_PktFilter filters[VMXNET3_PM_MAX_FILTERS]; } #include "vmware_pack_end.h" Vmxnet3_PMConf; typedef #include "vmware_pack_begin.h" struct Vmxnet3_VariableLenConfDesc { __le32 confVer; __le32 confLen; __le64 confPA; } #include "vmware_pack_end.h" Vmxnet3_VariableLenConfDesc; typedef #include "vmware_pack_begin.h" struct Vmxnet3_DSDevRead { /* read-only region for device, read by dev in response to a SET cmd */ Vmxnet3_MiscConf misc; Vmxnet3_IntrConf intrConf; Vmxnet3_RxFilterConf rxFilterConf; Vmxnet3_VariableLenConfDesc rssConfDesc; Vmxnet3_VariableLenConfDesc pmConfDesc; Vmxnet3_VariableLenConfDesc pluginConfDesc; } #include "vmware_pack_end.h" Vmxnet3_DSDevRead; typedef #include "vmware_pack_begin.h" struct Vmxnet3_TxQueueDesc { Vmxnet3_TxQueueCtrl ctrl; Vmxnet3_TxQueueConf conf; /* Driver read after a GET command */ Vmxnet3_QueueStatus status; UPT1_TxStats stats; uint8 _pad[88]; /* 128 aligned */ } #include "vmware_pack_end.h" Vmxnet3_TxQueueDesc; typedef #include "vmware_pack_begin.h" struct Vmxnet3_RxQueueDesc { Vmxnet3_RxQueueCtrl ctrl; Vmxnet3_RxQueueConf conf; /* Driver read after a GET command */ Vmxnet3_QueueStatus status; UPT1_RxStats stats; uint8 _pad[88]; /* 128 aligned */ } #include "vmware_pack_end.h" Vmxnet3_RxQueueDesc; typedef #include "vmware_pack_begin.h" struct Vmxnet3_DriverShared { __le32 magic; __le32 pad; /* make devRead start at 64-bit boundaries */ Vmxnet3_DSDevRead devRead; __le32 ecr; __le32 reserved[5]; } #include "vmware_pack_end.h" Vmxnet3_DriverShared; #define VMXNET3_ECR_RQERR (1 << 0) #define VMXNET3_ECR_TQERR (1 << 1) #define VMXNET3_ECR_LINK (1 << 2) #define VMXNET3_ECR_DIC (1 << 3) #define VMXNET3_ECR_DEBUG (1 << 4) /* flip the gen bit of a ring */ #define VMXNET3_FLIP_RING_GEN(gen) ((gen) = (gen) ^ 0x1) /* only use this if moving the idx won't affect the gen bit */ #define VMXNET3_INC_RING_IDX_ONLY(idx, ring_size) \ do {\ (idx)++;\ if (UNLIKELY((idx) == (ring_size))) {\ (idx) = 0;\ }\ } while (0) #define VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid) \ vfTable[vid >> 5] |= (1 << (vid & 31)) #define VMXNET3_CLEAR_VFTABLE_ENTRY(vfTable, vid) \ vfTable[vid >> 5] &= ~(1 << (vid & 31)) #define VMXNET3_VFTABLE_ENTRY_IS_SET(vfTable, vid) \ ((vfTable[vid >> 5] & (1 << (vid & 31))) != 0) #define VMXNET3_MAX_MTU 9000 #define VMXNET3_MIN_MTU 60 #define VMXNET3_LINK_UP (10000 << 16 | 1) // 10 Gbps, up #define VMXNET3_LINK_DOWN 0 #define VMXWIFI_DRIVER_SHARED_LEN 8192 #define VMXNET3_DID_PASSTHRU 0xFFFF #endif /* _VMXNET3_DEFS_H_ */ open-vm-tools-9.4.0-1280544/modules/shared/vmblock/0000755765153500003110000000000012220061556020012 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/shared/vmblock/stubs.c0000644765153500003110000000742412220061556021325 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * stubs.c -- * * Common stubs. */ #if defined(__FreeBSD__) #include #include #else #include #endif #include "os.h" #include "vm_assert.h" /* *---------------------------------------------------------------------------- * * Panic -- * * Panic implementation. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void Panic(const char *fmt, ...) { va_list args; va_start(args, fmt); os_panic(fmt, args); va_end(args); /* * Solaris's vcmn_err() is not marked as NORETURN and thus generates a * warning. I'd use NOT_REACHED(), as recommended, except that we are * already in Panic(). */ INFINITE_LOOP(); } open-vm-tools-9.4.0-1280544/modules/shared/vmblock/block.h0000644765153500003110000000725212220061556021263 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * block.h -- * * Blocking operations for the vmblock driver. */ #ifndef __BLOCK_H__ #define __BLOCK_H__ #include "os.h" typedef struct BlockInfo * BlockHandle; /* * Global functions */ int BlockInit(void); void BlockCleanup(void); int BlockAddFileBlock(const char *filename, const os_blocker_id_t blocker); int BlockRemoveFileBlock(const char *filename, const os_blocker_id_t blocker); unsigned int BlockRemoveAllBlocks(const os_blocker_id_t blocker); int BlockWaitOnFile(const char *filename, BlockHandle cookie); BlockHandle BlockLookup(const char *filename, const os_blocker_id_t blocker); #ifdef VMX86_DEVEL void BlockListFileBlocks(void); #endif #endif /* __BLOCK_H__ */ open-vm-tools-9.4.0-1280544/modules/shared/vmblock/block.c0000644765153500003110000004171212220061556021255 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * block.c -- * * Blocking operation implementions for the vmblock driver. */ /* os.h includes necessary OS-specific headers. */ #include "os.h" #if defined(vmblock_fuse) #elif defined(linux) # include "vmblockInt.h" #elif defined(sun) # include "module.h" #elif defined(__FreeBSD__) # include "vmblock_k.h" #endif #include "block.h" #include "dbllnklst.h" typedef struct BlockInfo { DblLnkLst_Links links; os_atomic_t refcount; os_blocker_id_t blocker; os_completion_t completion; char filename[OS_PATH_MAX]; } BlockInfo; /* XXX: Is it worth turning this into a hash table? */ static DblLnkLst_Links blockedFiles; static os_rwlock_t blockedFilesLock; static os_kmem_cache_t *blockInfoCache; /* *---------------------------------------------------------------------------- * * BlockInit -- * * Initializes blocking portion of module. * * Results: * Zero on success, error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int BlockInit(void) { ASSERT(!blockInfoCache); blockInfoCache = os_kmem_cache_create("blockInfoCache", sizeof (BlockInfo), 0, NULL); if (!blockInfoCache) { return OS_ENOMEM; } DblLnkLst_Init(&blockedFiles); os_rwlock_init(&blockedFilesLock); return 0; } /* *---------------------------------------------------------------------------- * * BlockCleanup -- * * Cleans up the blocking portion of the module. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void BlockCleanup(void) { ASSERT(blockInfoCache); ASSERT(!DblLnkLst_IsLinked(&blockedFiles)); os_rwlock_destroy(&blockedFilesLock); os_kmem_cache_destroy(blockInfoCache); } /* *---------------------------------------------------------------------------- * * AllocBlock -- * * Allocates and initializes a new block structure. * * Results: * Pointer to the struct on success, NULL on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static BlockInfo * AllocBlock(os_kmem_cache_t *cache, // IN: cache to allocate from const char *filename, // IN: filname of block const os_blocker_id_t blocker) // IN: blocker id { BlockInfo *block; size_t ret; /* Initialize this file's block structure. */ block = os_kmem_cache_alloc(blockInfoCache); if (!block) { return NULL; } ret = strlcpy(block->filename, filename, sizeof block->filename); if (ret >= sizeof block->filename) { Warning("BlockAddFileBlock: filename is too large\n"); os_kmem_cache_free(blockInfoCache, block); return NULL; } DblLnkLst_Init(&block->links); os_atomic_set(&block->refcount, 1); os_completion_init(&block->completion); block->blocker = blocker; return block; } /* *---------------------------------------------------------------------------- * * FreeBlock -- * * Frees the provided block structure. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void FreeBlock(os_kmem_cache_t *cache, // IN: cache block was allocated from BlockInfo *block) // IN: block to free { ASSERT(cache); ASSERT(block); if (DblLnkLst_IsLinked(&block->links)) { Warning("Block on file [%s] is still in the list, " "not freeing, leaking memory\n", block->filename); return; } os_completion_destroy(&block->completion); os_kmem_cache_free(cache, block); } /* *---------------------------------------------------------------------------- * * BlockGrabReference -- * * Increments reference count in the provided block structure. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static BlockInfo * BlockGrabReference(BlockInfo *block) { ASSERT(block); os_atomic_inc(&block->refcount); return block; } /* *---------------------------------------------------------------------------- * * BlockDropReference -- * * Increments reference count in the provided block structure. * * Results: * None. * * Side effects: * When reference count reaches 0 disposes of the block structure by * calling FreeBlock(). * *---------------------------------------------------------------------------- */ static void BlockDropReference(BlockInfo *block) { if (os_atomic_dec_and_test(&block->refcount)) { LOG(4, "Dropped last reference for block on [%s]\n", block->filename); FreeBlock(blockInfoCache, block); } } /* *---------------------------------------------------------------------------- * * GetBlock -- * * Searches for a block on the provided filename by the provided blocker. * If blocker is NULL, it is ignored and any matching filename is returned. * * Note that this assumes the proper locking has been done on the data * structure holding the blocked files. * * Results: * A pointer to the corresponding BlockInfo if found, NULL otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static BlockInfo * GetBlock(const char *filename, // IN: file to find block for const os_blocker_id_t blocker) // IN: blocker associated with this block { struct DblLnkLst_Links *curr; /* * On FreeBSD we have a mechanism to assert (but not simply check) * that a lock is held. Since semantic is different (panic that * happens if assertion fails can not be suppressed) we are using * different name. */ #ifdef os_assert_rwlock_held os_assert_rwlock_held(&blockedFilesLock); #else ASSERT(os_rwlock_held(&blockedFilesLock)); #endif DblLnkLst_ForEach(curr, &blockedFiles) { BlockInfo *currBlock = DblLnkLst_Container(curr, BlockInfo, links); if ((blocker == OS_UNKNOWN_BLOCKER || currBlock->blocker == blocker) && strcmp(currBlock->filename, filename) == 0) { return currBlock; } } return NULL; } /* *---------------------------------------------------------------------------- * * BlockDoRemoveBlock -- * * Removes given block from the block list and notifies waiters that block * is gone. * * Results: * None. * * Side effects: * Block structure will be freed if there were no waiters. * *---------------------------------------------------------------------------- */ static void BlockDoRemoveBlock(BlockInfo *block) { ASSERT(block); DblLnkLst_Unlink1(&block->links); /* Wake up waiters, if any */ LOG(4, "Completing block on [%s] (%d waiters)\n", block->filename, os_atomic_read(&block->refcount) - 1); os_complete_all(&block->completion); /* Now drop our reference */ BlockDropReference(block); } /* *---------------------------------------------------------------------------- * * BlockAddFileBlock -- * * Adds a block for the provided filename. filename should be the name of * the actual file being blocked, not the name within our namespace. The * provided blocker ID should uniquely identify this blocker. * * All calls to BlockWaitOnFile() with the same filename will not return * until BlockRemoveFileBlock() is called. * * Note that this function assumes a block on filename does not already * exist. * * Results: * Zero on success, error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int BlockAddFileBlock(const char *filename, // IN: name of file to block const os_blocker_id_t blocker) // IN: blocker adding the block { BlockInfo *block; int retval; ASSERT(filename); os_write_lock(&blockedFilesLock); if (GetBlock(filename, OS_UNKNOWN_BLOCKER)) { retval = OS_EEXIST; goto out; } block = AllocBlock(blockInfoCache, filename, blocker); if (!block) { Warning("BlockAddFileBlock: out of memory\n"); retval = OS_ENOMEM; goto out; } DblLnkLst_LinkLast(&blockedFiles, &block->links); LOG(4, "added block for [%s]\n", filename); retval = 0; out: os_write_unlock(&blockedFilesLock); return retval; } /* *---------------------------------------------------------------------------- * * BlockRemoveFileBlock -- * * Removes the provided file block and wakes up any threads waiting within * BlockWaitOnFile(). Note that only the blocker that added a block can * remove it. * * Results: * Zero on success, error code on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int BlockRemoveFileBlock(const char *filename, // IN: block to remove const os_blocker_id_t blocker) // IN: blocker removing this block { BlockInfo *block; int retval; ASSERT(filename); os_write_lock(&blockedFilesLock); block = GetBlock(filename, blocker); if (!block) { retval = OS_ENOENT; goto out; } BlockDoRemoveBlock(block); retval = 0; out: os_write_unlock(&blockedFilesLock); return retval; } /* *---------------------------------------------------------------------------- * * BlockRemoveAllBlocks -- * * Removes all blocks added by the provided blocker. * * Results: * Returns the number of entries removed from the blocklist. * * Side effects: * None. * *---------------------------------------------------------------------------- */ unsigned int BlockRemoveAllBlocks(const os_blocker_id_t blocker) // IN: blocker to remove blocks for { struct DblLnkLst_Links *curr; struct DblLnkLst_Links *tmp; unsigned int removed = 0; os_write_lock(&blockedFilesLock); DblLnkLst_ForEachSafe(curr, tmp, &blockedFiles) { BlockInfo *currBlock = DblLnkLst_Container(curr, BlockInfo, links); if (currBlock->blocker == blocker || blocker == OS_UNKNOWN_BLOCKER) { BlockDoRemoveBlock(currBlock); /* * We count only entries removed from the -list-, regardless of whether * or not other waiters exist. */ ++removed; } } os_write_unlock(&blockedFilesLock); return removed; } /* *---------------------------------------------------------------------------- * * BlockWaitOnFile -- * * Searches for a block on the provided filename. If one exists, this * function does not return until that block has been lifted; otherwise, it * returns right away. * * Results: * Zero on success, otherwise an appropriate system error if our sleep/ * block is interrupted. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int BlockWaitOnFile(const char *filename, // IN: file to block on BlockHandle cookie) // IN: previously found block { BlockInfo *block = NULL; int error = 0; ASSERT(filename); /* * Caller may have used BlockLookup to conditionally search for a * block before actually going to sleep. (This allows the caller to * do a little housekeeping, such as releasing vnode locks, before * blocking here.) */ if (cookie == NULL) { os_read_lock(&blockedFilesLock); block = GetBlock(filename, OS_UNKNOWN_BLOCKER); if (block) { BlockGrabReference(block); } os_read_unlock(&blockedFilesLock); if (!block) { /* This file is not blocked, just return */ return 0; } } else { /* * Note that the "cookie's" reference count was incremented when it * was fetched via BlockLookup, so this is completely safe. (We'll * decrement it below.) */ block = cookie; } LOG(4, "(%"OS_FMTTID") Waiting for completion on [%s]\n", os_threadid, filename); error = os_wait_for_completion(&block->completion); LOG(4, "(%"OS_FMTTID") Wokeup from block on [%s]\n", os_threadid, filename); BlockDropReference(block); return error; } /* *----------------------------------------------------------------------------- * * BlockLookup -- * * VFS-exported function for searching for blocks. * * Results: * Opaque pointer to a blockInfo if a block is found, NULL otherwise. * * Side effects: * Located blockInfo, if any, has an incremented reference count. * *----------------------------------------------------------------------------- */ BlockHandle BlockLookup(const char *filename, // IN: pathname to test for // blocking const os_blocker_id_t blocker) // IN: specific blocker to // search for { BlockInfo *block; os_read_lock(&blockedFilesLock); block = GetBlock(filename, blocker); if (block) { BlockGrabReference(block); } os_read_unlock(&blockedFilesLock); return block; } #ifdef VMX86_DEVEL /* *---------------------------------------------------------------------------- * * BlockListFileBlocks -- * * Lists all the current file blocks. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void BlockListFileBlocks(void) { DblLnkLst_Links *curr; int count = 0; os_read_lock(&blockedFilesLock); DblLnkLst_ForEach(curr, &blockedFiles) { BlockInfo *currBlock = DblLnkLst_Container(curr, BlockInfo, links); LOG(1, "BlockListFileBlocks: (%d) Filename: [%s], Blocker: [%p]\n", count++, currBlock->filename, currBlock->blocker); } os_read_unlock(&blockedFilesLock); if (!count) { LOG(1, "BlockListFileBlocks: No blocks currently exist.\n"); } } #endif open-vm-tools-9.4.0-1280544/modules/shared/vmmemctl/0000755765153500003110000000000012220061556020201 5ustar dtormtsopen-vm-tools-9.4.0-1280544/modules/shared/vmmemctl/backdoor_balloon.c0000644765153500003110000002672212220061556023650 0ustar dtormts/********************************************************* * Copyright (C) 2012 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ #include "backdoor_balloon.h" #include "backdoor.h" #include "balloon_def.h" #include "os.h" /* *---------------------------------------------------------------------- * * BackdoorCmd -- * * Do the balloon hypercall to the vmkernel. * * Results: * Hypercall status will be returned and out will be filled * if it's not NULL, either by bx or cx depending on the command. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int BackdoorCmd(uint16 cmd, // IN size_t arg1, // IN uint32 arg2, // IN uint32 *out, // OUT int *resetFlag) // OUT { Backdoor_proto bp; int status; /* prepare backdoor args */ bp.in.cx.halfs.low = cmd; bp.in.size = arg1; bp.in.si.word = arg2; /* invoke backdoor */ bp.in.ax.word = BALLOON_BDOOR_MAGIC; bp.in.dx.halfs.low = BALLOON_BDOOR_PORT; Backdoor_InOut(&bp); status = bp.out.ax.word; /* set flag if reset requested */ if (status == BALLOON_ERROR_RESET) { *resetFlag = 1; } if (out) { if (cmd == BALLOON_BDOOR_CMD_START) { *out = bp.out.cx.word; } else { *out = bp.out.bx.word; } } return status; } /* *---------------------------------------------------------------------- * * Backdoor_MonitorStart -- * * Attempts to contact monitor via backdoor to begin operation. * * Results: * Returns BALLOON_SUCCESS if successful, otherwise error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Backdoor_MonitorStart(Balloon *b, // IN uint32 protoVersion) // IN { uint32 capabilities; int status = BackdoorCmd(BALLOON_BDOOR_CMD_START, protoVersion, 0, &capabilities, &b->resetFlag); /* * If return code is BALLOON_SUCCESS_WITH_CAPABILITY, then ESX is * sending the common capabilities supported by the monitor and the * guest in cx. */ if (status == BALLOON_SUCCESS_WITH_CAPABILITIES) { b->hypervisorCapabilities = capabilities; status = BALLOON_SUCCESS; } else if (status == BALLOON_SUCCESS) { b->hypervisorCapabilities = BALLOON_BASIC_CMDS; } /* update stats */ STATS_INC(b->stats.start); if (status != BALLOON_SUCCESS) { STATS_INC(b->stats.startFail); } return status; } /* *---------------------------------------------------------------------- * * Backdoor_MonitorGuestType -- * * Attempts to contact monitor and report guest OS identity. * * Results: * Returns BALLOON_SUCCESS if successful, otherwise error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Backdoor_MonitorGuestType(Balloon *b) // IN { int status = BackdoorCmd(BALLOON_BDOOR_CMD_GUEST_ID, b->guestType, 0, NULL, &b->resetFlag); /* update stats */ STATS_INC(b->stats.guestType); if (status != BALLOON_SUCCESS) { STATS_INC(b->stats.guestTypeFail); } return status; } /* *---------------------------------------------------------------------- * * Backdoor_MonitorGetTarget -- * * Attempts to contact monitor via backdoor to obtain desired * balloon size. * * Predicts the maximum achievable balloon size and sends it * to vmm => vmkernel via vEbx register. * * OS_ReservedPageGetLimit() returns either predicted max balloon * pages or BALLOON_MAX_SIZE_USE_CONFIG. In the later scenario, * vmkernel uses global config options for determining a guest's max * balloon size. Note that older vmballoon drivers set vEbx to * BALLOON_MAX_SIZE_USE_CONFIG, i.e., value 0 (zero). So vmkernel * will fallback to config-based max balloon size estimation. * * Results: * If successful, sets "target" to value obtained from monitor, * and returns BALLOON_SUCCESS. Otherwise returns error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Backdoor_MonitorGetTarget(Balloon *b, // IN uint32 *target) // OUT { unsigned long limit; uint32 limit32; int status; limit = OS_ReservedPageGetLimit(); /* Ensure limit fits in 32-bits */ limit32 = (uint32)limit; if (limit32 != limit) { return BALLOON_FAILURE; } status = BackdoorCmd(BALLOON_BDOOR_CMD_TARGET, limit, 0, target, &b->resetFlag); /* update stats */ STATS_INC(b->stats.target); if (status != BALLOON_SUCCESS) { STATS_INC(b->stats.targetFail); } return status; } /* *---------------------------------------------------------------------- * * Backdoor_MonitorLockPage -- * * Attempts to contact monitor and add PPN corresponding to * the page handle to set of "balloon locked" pages. * If the current protocol support batching, it will balloon all * PPNs listed in the batch page. * * Results: * Returns BALLOON_SUCCESS if successful, otherwise error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Backdoor_MonitorLockPage(Balloon *b, // IN PPN64 ppn) // IN { int status; uint32 ppn32 = (uint32)ppn; /* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */ if (ppn32 != ppn) { return BALLOON_ERROR_PPN_INVALID; } status = BackdoorCmd(BALLOON_BDOOR_CMD_LOCK, ppn32, 0, NULL, &b->resetFlag); /* update stats */ STATS_INC(b->stats.lock); if (status != BALLOON_SUCCESS) { STATS_INC(b->stats.lockFail); } return status; } /* *---------------------------------------------------------------------- * * Backdoor_MonitorUnlockPage -- * * Attempts to contact monitor and remove PPN corresponding to * the page handle from set of "balloon locked" pages. * If the current protocol support batching, it will remove all * the PPNs listed in the batch page. * * Results: * Returns BALLOON_SUCCESS if successful, otherwise error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Backdoor_MonitorUnlockPage(Balloon *b, // IN PPN64 ppn) // IN { int status; uint32 ppn32 = (uint32)ppn; /* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */ if (ppn32 != ppn) { return BALLOON_ERROR_PPN_INVALID; } status = BackdoorCmd(BALLOON_BDOOR_CMD_UNLOCK, ppn32, 0, NULL, &b->resetFlag); /* update stats */ STATS_INC(b->stats.unlock); if (status != BALLOON_SUCCESS) { STATS_INC(b->stats.unlockFail); } return status; } /* *---------------------------------------------------------------------- * * Backdoor_MonitorLockPagesBatched -- * * Balloon all PPNs listed in the batch page. * * Results: * Returns BALLOON_SUCCESS if successful, otherwise error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Backdoor_MonitorLockPagesBatched(Balloon *b, // IN PPN64 ppn, // IN uint32 nPages) // IN { int status = BackdoorCmd(BALLOON_BDOOR_CMD_BATCHED_LOCK, (size_t)ppn, nPages, NULL, &b->resetFlag); /* update stats */ STATS_INC(b->stats.lock); if (status != BALLOON_SUCCESS) { STATS_INC(b->stats.lockFail); } return status; } /* *---------------------------------------------------------------------- * * Backdoor_MonitorUnlockPagesBatched -- * * Unballoon all PPNs listed in the batch page. * * Results: * Returns BALLOON_SUCCESS if successful, otherwise error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Backdoor_MonitorUnlockPagesBatched(Balloon *b, // IN PPN64 ppn, // IN uint32 nPages) // IN { int status = BackdoorCmd(BALLOON_BDOOR_CMD_BATCHED_UNLOCK, (size_t)ppn, nPages, NULL, &b->resetFlag); /* update stats */ STATS_INC(b->stats.unlock); if (status != BALLOON_SUCCESS) { STATS_INC(b->stats.unlockFail); } return status; } open-vm-tools-9.4.0-1280544/modules/shared/vmmemctl/vmballoon.c0000644765153500003110000010024612220061556022341 0ustar dtormts/********************************************************* * Copyright (C) 2000 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * vmballoon.c -- * * VMware physical memory management driver for Unix-ish * (Linux, FreeBSD, Solaris, Mac OS) guests. The driver acts like * a "balloon" that can be inflated to reclaim physical pages by * reserving them in the guest and invalidating them in the * monitor, freeing up the underlying machine pages so they can * be allocated to other guests. The balloon can also be * deflated to allow the guest to use more physical memory. * Higher level policies can control the sizes of balloons in VMs * in order to manage physical memory resources. */ #ifdef __cplusplus extern "C" { #endif /* * Includes */ #include "os.h" #include "backdoor.h" #include "backdoor_balloon.h" #include "vmballoon.h" /* * Constants */ #ifndef NULL #define NULL 0 #endif /* * When guest is under memory pressure, use a reduced page allocation * rate for next several cycles. */ #define SLOW_PAGE_ALLOCATION_CYCLES 4 /* Maximum number of page allocations without yielding processor */ #define BALLOON_ALLOC_YIELD_THRESHOLD 1024 /* * Balloon operations */ static int BalloonPageFree(Balloon *b); static int BalloonAdjustSize(Balloon *b, uint32 target); static void BalloonReset(Balloon *b); static void BalloonAddPage(Balloon *b, uint16 idx, PageHandle page); static void BalloonAddPageBatched(Balloon *b, uint16 idx, PageHandle page); static int BalloonLock(Balloon *b, uint16 nPages); static int BalloonLockBatched(Balloon *b, uint16 nPages); static int BalloonUnlock(Balloon *b, uint16 nPages); static int BalloonUnlockBatched(Balloon *b, uint16 nPages); /* * Globals */ static Balloon globalBalloon; static const BalloonOps balloonOps = { .addPage = BalloonAddPage, .lock = BalloonLock, .unlock = BalloonUnlock }; static const struct BalloonOps balloonOpsBatched = { .addPage = BalloonAddPageBatched, .lock = BalloonLockBatched, .unlock = BalloonUnlockBatched }; /* *---------------------------------------------------------------------- * * Balloon_GetStats -- * * Returns information about balloon state, including the current and * target size, rates for allocating and freeing pages, and statistics * about past activity. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ const BalloonStats * Balloon_GetStats(void) { Balloon *b = &globalBalloon; BalloonStats *stats = &b->stats; /* * Fill in additional information about size and rates, which is * normally kept in the Balloon structure itself. */ stats->nPages = b->nPages; stats->nPagesTarget = b->nPagesTarget; stats->rateNoSleepAlloc = BALLOON_NOSLEEP_ALLOC_MAX; stats->rateAlloc = b->rateAlloc; stats->rateFree = b->rateFree; return stats; } /* *---------------------------------------------------------------------- * * BalloonChunk_Create -- * * Creates a new BalloonChunk object capable of tracking * BALLOON_CHUNK_PAGES PAs. * * We do not bother to define two versions (NOSLEEP and CANSLEEP) * of OS_Malloc because Chunk_Create does not require a new page * often. * * Results: * On success: initialized BalloonChunk * On failure: NULL * * Side effects: * None * *---------------------------------------------------------------------- */ static BalloonChunk * BalloonChunk_Create(void) { BalloonChunk *chunk; /* allocate memory, fail if unable */ chunk = OS_Malloc(sizeof *chunk); if (chunk == NULL) { return NULL; } /* initialize */ OS_MemZero(chunk, sizeof *chunk); DblLnkLst_Init(&chunk->node); return chunk; } /* *---------------------------------------------------------------------- * * BalloonChunk_Destroy -- * * Reclaims all storage associated with specified BalloonChunk. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void BalloonChunk_Destroy(BalloonChunk *chunk) // IN { /* reclaim storage */ OS_Free(chunk, sizeof *chunk); } /* *---------------------------------------------------------------------- * * Balloon_Deallocate -- * * Frees all allocated pages. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void Balloon_Deallocate(Balloon *b) // IN { unsigned int cnt = 0; /* free all pages, skipping monitor unlock */ while (b->nChunks > 0) { (void) BalloonPageFree(b); if (++cnt >= b->rateFree) { cnt = 0; OS_Yield(); } } /* Release the batch page */ if (b->batchPageMapping != MAPPING_INVALID) { OS_UnmapPage(b->batchPageMapping); b->batchPageMapping = MAPPING_INVALID; b->batchPage = NULL; } if (b->pageHandle != PAGE_HANDLE_INVALID) { OS_ReservedPageFree(b->pageHandle); b->pageHandle = PAGE_HANDLE_INVALID; } } /* *---------------------------------------------------------------------- * * BalloonInitBatching -- * * Allocate and map the batch page. * * Results: * BALLOON_SUCCESS or an error code in case of failure. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int BalloonInitBatching(Balloon *b) // IN { b->batchMaxPages = BALLOON_BATCH_MAX_PAGES; b->pageHandle = OS_ReservedPageAlloc(BALLOON_PAGE_ALLOC_NOSLEEP); if (b->pageHandle == PAGE_HANDLE_INVALID) { return BALLOON_PAGE_ALLOC_FAILURE; } b->batchPageMapping = OS_MapPageHandle(b->pageHandle); if (b->batchPageMapping == MAPPING_INVALID) { OS_ReservedPageFree(b->pageHandle); b->pageHandle = PAGE_HANDLE_INVALID; return BALLOON_PAGE_ALLOC_FAILURE; } b->batchPage = OS_Mapping2Addr(b->batchPageMapping); return BALLOON_SUCCESS; } /* *---------------------------------------------------------------------- * * BalloonReset -- * * Resets balloon "b" to empty state. Frees all allocated pages * and attempts to reset contact with the monitor. * * Results: * None. * * Side effects: * Schedules next execution of balloon timer handler. * *---------------------------------------------------------------------- */ static void BalloonReset(Balloon *b) // IN { int status; /* free all pages, skipping monitor unlock */ Balloon_Deallocate(b); status = Backdoor_MonitorStart(b, BALLOON_CAPABILITIES); if (status != BALLOON_SUCCESS) { return; } if ((b->hypervisorCapabilities & BALLOON_BATCHED_CMDS) != 0) { status = BalloonInitBatching(b); if (status != BALLOON_SUCCESS) { /* * We failed to initialize the batching in the guest, inform * the monitor about that by sending a null capability. * * The guest will retry to init itself in one second. */ Backdoor_MonitorStart(b, 0); return; } } if ((b->hypervisorCapabilities & BALLOON_BATCHED_CMDS) != 0) { b->balloonOps = &balloonOpsBatched; } else if ((b->hypervisorCapabilities & BALLOON_BASIC_CMDS) != 0) { b->balloonOps = &balloonOps; b->batchMaxPages = 1; } /* clear flag */ b->resetFlag = FALSE; /* report guest type */ (void) Backdoor_MonitorGuestType(b); } /* *---------------------------------------------------------------------- * * Balloon_QueryAndExecute -- * * Contacts monitor via backdoor to obtain balloon size target, * and starts adjusting balloon size to achieve target by allocating * or deallocating pages. Resets balloon if requested by the monitor. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void Balloon_QueryAndExecute(void) { Balloon *b = &globalBalloon; uint32 target = 0; // Silence compiler warning. int status; /* update stats */ STATS_INC(b->stats.timer); /* reset, if specified */ if (b->resetFlag) { BalloonReset(b); } /* contact monitor via backdoor */ status = Backdoor_MonitorGetTarget(b, &target); /* decrement slowPageAllocationCycles counter */ if (b->slowPageAllocationCycles > 0) { b->slowPageAllocationCycles--; } if (status == BALLOON_SUCCESS) { /* update target, adjust size */ b->nPagesTarget = target; (void) BalloonAdjustSize(b, target); } } /* *---------------------------------------------------------------------- * * BalloonErrorPageStore -- * * Attempt to add "page" to list of non-balloonable pages * associated with "b". * * Results: * On success: BALLOON_SUCCESS * On failure: BALLOON_FAILURE (non-balloonable page list is already full) * * Side effects: * None. * *---------------------------------------------------------------------- */ static int BalloonErrorPageStore(Balloon *b, // IN PageHandle page) // IN { /* fail if list already full */ if (b->errors.pageCount >= BALLOON_ERROR_PAGES) { return BALLOON_FAILURE; } /* add page to list */ b->errors.page[b->errors.pageCount++] = page; STATS_INC(b->stats.primErrorPageAlloc); return BALLOON_SUCCESS; } /* *---------------------------------------------------------------------- * * BalloonErrorPagesFree -- * * Deallocates all pages on the list of non-balloonable pages * associated with "b". * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void BalloonErrorPagesFree(Balloon *b) // IN { unsigned int i; /* free all non-balloonable "error" pages */ for (i = 0; i < b->errors.pageCount; i++) { OS_ReservedPageFree(b->errors.page[i]); b->errors.page[i] = PAGE_HANDLE_INVALID; STATS_INC(b->stats.primErrorPageFree); } b->errors.pageCount = 0; } /* *---------------------------------------------------------------------- * * BalloonGetChunk -- * * Attempt to find a "chunk" with a free slot to store locked page. * Try to allocate new chunk if all existing chunks are full. * * Results: * Returns NULL on failure. * * Side effects: * None. * *---------------------------------------------------------------------- */ static BalloonChunk * BalloonGetChunk(Balloon *b) // IN { BalloonChunk *chunk; /* Get first chunk from the list */ if (DblLnkLst_IsLinked(&b->chunks)) { chunk = DblLnkLst_Container(b->chunks.next, BalloonChunk, node); if (chunk->pageCount < BALLOON_CHUNK_PAGES) { /* This chunk has free slots, use it */ return chunk; } } /* create new chunk */ chunk = BalloonChunk_Create(); if (chunk != NULL) { DblLnkLst_LinkFirst(&b->chunks, &chunk->node); /* update stats */ b->nChunks++; } return chunk; } /* *---------------------------------------------------------------------- * * BalloonGetChunkOrFallback -- * * Attempt to find a "chunk" with a free slot to store locked page. * If the allocation fails, use the previously allocated * fallbackChunk. * * Results: * A valid chunk. * * Side effects: * None. * *---------------------------------------------------------------------- */ static BalloonChunk * BalloonGetChunkOrFallback(Balloon *b) // IN { BalloonChunk *chunk = BalloonGetChunk(b); if (chunk == NULL) { ASSERT(b->fallbackChunk != NULL); chunk = b->fallbackChunk; b->fallbackChunk = NULL; DblLnkLst_LinkFirst(&b->chunks, &chunk->node); b->nChunks++; } return chunk; } /* *---------------------------------------------------------------------- * * BalloonPageStore -- * * Add "page" to the given "chunk". * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void BalloonPageStore(BalloonChunk *chunk, PageHandle page) { chunk->page[chunk->pageCount++] = page; } /* *---------------------------------------------------------------------- * * BalloonPageFree -- * * Attempts to deallocate a physical page, deflating balloon "b". * Never informs monitor. * * Results: * Returns BALLOON_SUCCESS if successful, otherwise error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int BalloonPageFree(Balloon *b) // IN { BalloonChunk *chunk; PageHandle page; if (!DblLnkLst_IsLinked(&b->chunks)) { /* The chunk list is empty, the balloon cannot be deflated */ return BALLOON_FAILURE; } chunk = DblLnkLst_Container(b->chunks.next, BalloonChunk, node); /* deallocate last page */ page = chunk->page[--chunk->pageCount]; /* deallocate page */ OS_ReservedPageFree(page); STATS_INC(b->stats.primFree); /* update balloon size */ b->nPages--; /* reclaim chunk, if empty */ if (chunk->pageCount == 0) { /* destroy empty chunk */ DblLnkLst_Unlink1(&chunk->node); BalloonChunk_Destroy(chunk); /* update stats */ b->nChunks--; } return BALLOON_SUCCESS; } /* *---------------------------------------------------------------------- * * BalloonInflate -- * * Attempts to allocate physical pages to inflate balloon. * * Results: * Returns BALLOON_SUCCESS if successful, otherwise error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int BalloonInflate(Balloon *b, // IN uint32 target) // IN { uint32 goal, nPages; unsigned int rate; unsigned int i; unsigned int allocations = 0; int status = 0; BalloonPageAllocType allocType = BALLOON_PAGE_ALLOC_NOSLEEP; /* * First try NOSLEEP page allocations to inflate balloon. * * If we do not throttle nosleep allocations, we can drain all * free pages in the guest quickly (if the balloon target is high). * As a side-effect, draining free pages helps to inform (force) * the guest to start swapping if balloon target is not met yet, * which is a desired behavior. However, balloon driver can consume * all available CPU cycles if too many pages are allocated in a * second. Therefore, we throttle nosleep allocations even when * the guest is not under memory pressure. OTOH, if we have already * predicted that the guest is under memory pressure, then we * slowdown page allocations considerably. */ goal = target - b->nPages; /* * Start with no sleep allocation rate which may be higher * than sleeping allocation rate. */ rate = b->slowPageAllocationCycles ? b->rateAlloc : BALLOON_NOSLEEP_ALLOC_MAX; nPages = 0; for (i = 0; i < goal; i++) { PageHandle handle; STATS_INC(b->stats.primAlloc[allocType]); handle = OS_ReservedPageAlloc(allocType); if (handle == PAGE_HANDLE_INVALID) { STATS_INC(b->stats.primAllocFail[allocType]); if (allocType == BALLOON_PAGE_ALLOC_CANSLEEP) { /* * CANSLEEP page allocation failed, so guest is under severe * memory pressure. Quickly decrease allocation rate. */ b->rateAlloc = MAX(b->rateAlloc / 2, BALLOON_RATE_ALLOC_MIN); break; } /* * NOSLEEP page allocation failed, so the guest is under memory * pressure. Let us slow down page allocations for next few cycles * so that the guest gets out of memory pressure. Also, if we * already allocated b->rateAlloc pages, let's pause, otherwise * switch to sleeping allocations. */ b->slowPageAllocationCycles = SLOW_PAGE_ALLOCATION_CYCLES; if (allocations >= b->rateAlloc) { break; } allocType = BALLOON_PAGE_ALLOC_CANSLEEP; /* Lower rate for sleeping allocations. */ rate = b->rateAlloc; continue; } allocations++; b->balloonOps->addPage(b, nPages++, handle); if (nPages == b->batchMaxPages) { status = b->balloonOps->lock(b, nPages); nPages = 0; if (status != BALLOON_SUCCESS) { break; } } if (allocations % BALLOON_ALLOC_YIELD_THRESHOLD == 0) { OS_Yield(); } if (allocations >= rate) { /* We allocated enough pages, let's take a break. */ break; } } if (nPages > 0) { status = b->balloonOps->lock(b, nPages); } /* * We reached our goal without failures so try increasing * allocation rate. */ if (status == BALLOON_SUCCESS && i >= b->rateAlloc) { unsigned int mult = i / b->rateAlloc; b->rateAlloc = MIN(b->rateAlloc + mult * BALLOON_RATE_ALLOC_INC, BALLOON_RATE_ALLOC_MAX); } /* release non-balloonable pages, succeed */ BalloonErrorPagesFree(b); return BALLOON_SUCCESS; } /* *---------------------------------------------------------------------- * * BalloonLockBatched -- * * Lock all the batched page, previously stored by * BalloonAddPageBatched. * * Results: * BALLOON_SUCCESS or an error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int BalloonLockBatched(Balloon *b, // IN uint16 nPages) // IN { int status; uint32 i; uint32 nLockedPages; PageHandle handle; PPN64 batchPagePPN; BalloonChunk *chunk = NULL; batchPagePPN = PA_2_PPN(OS_ReservedPageGetPA(b->pageHandle)); /* * Make sure that we will always have an available chunk before doing * the LOCK_BATCHED call. */ ASSERT(b->batchMaxPages < BALLOON_CHUNK_PAGES); b->fallbackChunk = BalloonChunk_Create(); if (b->fallbackChunk == NULL) { status = BALLOON_PAGE_ALLOC_FAILURE; } else { status = Backdoor_MonitorLockPagesBatched(b, batchPagePPN, nPages); } if (status != BALLOON_SUCCESS) { for (i = 0; i < nPages; i++) { PA64 pa = Balloon_BatchGetPA(b->batchPage, i); handle = OS_ReservedPageGetHandle(pa); OS_ReservedPageFree(handle); } goto out; } nLockedPages = 0; for (i = 0; i < nPages; i++) { PA64 pa; int error; pa = Balloon_BatchGetPA(b->batchPage, i); handle = OS_ReservedPageGetHandle(pa); error = Balloon_BatchGetStatus(b->batchPage, i); if (error != BALLOON_SUCCESS) { switch (error) { case BALLOON_ERROR_PPN_PINNED: case BALLOON_ERROR_PPN_INVALID: if (BalloonErrorPageStore(b, handle) == BALLOON_SUCCESS) { break; } // Fallthrough. case BALLOON_ERROR_RESET: case BALLOON_ERROR_PPN_NOTNEEDED: OS_ReservedPageFree(handle); break; default: /* * If we fall here, there is definitively a bug in the * driver that needs to be fixed, I'm not sure if * PINNED and INVALID PPN can be seen as a bug in the * driver. */ ASSERT(FALSE); } continue; } if (chunk == NULL) { chunk = BalloonGetChunkOrFallback(b); } BalloonPageStore(chunk, handle); if (chunk->pageCount == BALLOON_CHUNK_PAGES) { chunk = NULL; } nLockedPages++; } b->nPages += nLockedPages; out: if (b->fallbackChunk != NULL) { BalloonChunk_Destroy(b->fallbackChunk); b->fallbackChunk = NULL; } return status; } /* *---------------------------------------------------------------------- * * BalloonUnlockBatched -- * * Unlock all the batched page, previously stored by * BalloonAddPageBatched. * * Results: * BALLOON_SUCCESS or an error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int BalloonUnlockBatched(Balloon *b, // IN uint16 nPages) // IN { uint32 i; int status = BALLOON_SUCCESS; uint32 nUnlockedPages; PPN64 batchPagePPN; BalloonChunk *chunk = NULL; batchPagePPN = PA_2_PPN(OS_ReservedPageGetPA(b->pageHandle)); status = Backdoor_MonitorUnlockPagesBatched(b, batchPagePPN, nPages); if (status != BALLOON_SUCCESS) { for (i = 0; i < nPages; i++) { PA64 pa = Balloon_BatchGetPA(b->batchPage, i); PageHandle handle = OS_ReservedPageGetHandle(pa); chunk = BalloonGetChunkOrFallback(b); BalloonPageStore(chunk, handle); } goto out; } nUnlockedPages = 0; for (i = 0; i < nPages; i++) { int status = Balloon_BatchGetStatus(b->batchPage, i); PA64 pa = Balloon_BatchGetPA(b->batchPage, i); PageHandle handle = OS_ReservedPageGetHandle(pa); if (status != BALLOON_SUCCESS) { chunk = BalloonGetChunkOrFallback(b); BalloonPageStore(chunk, handle); continue; } OS_ReservedPageFree(handle); STATS_INC(b->stats.primFree); nUnlockedPages++; } b->nPages -= nUnlockedPages; out: if (b->fallbackChunk != NULL) { BalloonChunk_Destroy(b->fallbackChunk); b->fallbackChunk = NULL; } return status; } /* *---------------------------------------------------------------------- * * BalloonAddPageBatched -- * * Add a page to the batch page, that will be ballooned later. * * Results: * Nothing. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void BalloonAddPageBatched(Balloon *b, // IN uint16 idx, // IN PageHandle page) // IN { PA64 pa = OS_ReservedPageGetPA(page); Balloon_BatchSetPA(b->batchPage, idx, pa); } /* *---------------------------------------------------------------------- * * BalloonLock -- * * Lock a page, previously stored with a call to BalloonAddPage, * by notifying the monitor. * * Results: * BALLOON_SUCCESS or an error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int BalloonLock(Balloon *b, // IN uint16 nPages) // IN { PPN pagePPN; BalloonChunk *chunk; int status; /* Get the chunk to store allocated page. */ chunk = BalloonGetChunk(b); if (chunk == NULL) { OS_ReservedPageFree(b->pageHandle); status = BALLOON_PAGE_ALLOC_FAILURE; goto out; } /* inform monitor via backdoor */ pagePPN = PA_2_PPN(OS_ReservedPageGetPA(b->pageHandle)); status = Backdoor_MonitorLockPage(b, pagePPN); if (status != BALLOON_SUCCESS) { int old_status = status; if (status == BALLOON_ERROR_RESET || status == BALLOON_ERROR_PPN_NOTNEEDED) { OS_ReservedPageFree(b->pageHandle); goto out; } /* place on list of non-balloonable pages, retry allocation */ status = BalloonErrorPageStore(b, b->pageHandle); if (status != BALLOON_SUCCESS) { OS_ReservedPageFree(b->pageHandle); goto out; } status = old_status; goto out; } /* track allocated page */ BalloonPageStore(chunk, b->pageHandle); /* update balloon size */ b->nPages++; out: b->pageHandle = PAGE_HANDLE_INVALID; return status; } /* *---------------------------------------------------------------------- * * BalloonUnlock -- * * Unlock a page, previously stored with a call to * BalloonAddPage, by notifying the monitor. * * Results: * BALLOON_SUCCESS or an error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int BalloonUnlock(Balloon *b, // IN uint16 nPages) // IN { PPN pagePPN = PA_2_PPN(OS_ReservedPageGetPA(b->pageHandle)); int status = Backdoor_MonitorUnlockPage(b, pagePPN); if (status != BALLOON_SUCCESS) { BalloonChunk *chunk = BalloonGetChunkOrFallback(b); BalloonPageStore(chunk, b->pageHandle); goto out; } OS_ReservedPageFree(b->pageHandle); STATS_INC(b->stats.primFree); /* update balloon size */ b->nPages--; out: b->pageHandle = PAGE_HANDLE_INVALID; if (b->fallbackChunk != NULL) { BalloonChunk_Destroy(b->fallbackChunk); b->fallbackChunk = NULL; } return status; } /* *---------------------------------------------------------------------- * * BalloonAddPage -- * * Add a page to be ballooned later. * * Results: * Nothing. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void BalloonAddPage(Balloon *b, // IN uint16 idx, // IN PageHandle page) // IN { ASSERT(b->pageHandle == PAGE_HANDLE_INVALID); b->pageHandle = page; } /* *---------------------------------------------------------------------- * * BalloonDeflate -- * * Frees physical pages to deflate balloon. * * Results: * Returns BALLOON_SUCCESS if successful, otherwise error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int BalloonDeflate(Balloon *b, // IN uint32 target) // IN { int status = BALLOON_SUCCESS; uint32 goal, nPages; BalloonChunk *chunk = NULL; goal = b->nPages - target; /* limit deallocation rate */ goal = MIN(goal, b->rateFree); nPages = 0; for ( ; goal > 0; goal--) { PageHandle lockedHandle; if (chunk == NULL) { if (!DblLnkLst_IsLinked(&b->chunks)) { /* The chunk list is empty, the balloon cannot be deflated */ status = BALLOON_FAILURE; goto out; } chunk = DblLnkLst_Container(b->chunks.next, BalloonChunk, node); } lockedHandle = chunk->page[--chunk->pageCount]; if (!chunk->pageCount) { DblLnkLst_Unlink1(&chunk->node); /* * Do not free the chunk, we may need it if the UNLOCK cmd fails */ b->fallbackChunk = chunk; b->nChunks--; chunk = NULL; } b->balloonOps->addPage(b, nPages++, lockedHandle); if (nPages == b->batchMaxPages) { status = b->balloonOps->unlock(b, nPages); nPages = 0; if (status != BALLOON_SUCCESS) { if (BALLOON_RATE_ADAPT) { /* quickly decrease rate if error */ b->rateFree = MAX(b->rateFree / 2, BALLOON_RATE_FREE_MIN); } goto out; } } } if (nPages) { status = b->balloonOps->unlock(b, nPages); } if (status == BALLOON_SUCCESS && BALLOON_RATE_ADAPT) { /* slowly increase rate if no errors */ b->rateFree = MIN(b->rateFree + BALLOON_RATE_FREE_INC, BALLOON_RATE_FREE_MAX); } out: return status; } /* *---------------------------------------------------------------------- * * BalloonAdjustSize -- * * Attempts to allocate or deallocate physical pages in order * to reach desired "target" size for balloon "b". * * Results: * Returns BALLOON_SUCCESS if successful, otherwise error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int BalloonAdjustSize(Balloon *b, // IN uint32 target) // IN { if (b->nPages < target) { return BalloonInflate(b, target); } else if (b->nPages > target) { return BalloonDeflate(b, target); } else { /* already at target */ return BALLOON_SUCCESS; } } /* *---------------------------------------------------------------------- * * Balloon_Init -- * * Initializes state of the balloon. * * Results: * Returns TRUE on success (always). * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool Balloon_Init(BalloonGuest guestType) { Balloon *b = &globalBalloon; DblLnkLst_Init(&b->chunks); b->guestType = guestType; /* initialize rates */ b->rateAlloc = BALLOON_RATE_ALLOC_MAX; b->rateFree = BALLOON_RATE_FREE_MAX; /* initialize reset flag */ b->resetFlag = TRUE; b->hypervisorCapabilities = 0; b->pageHandle = PAGE_HANDLE_INVALID; b->batchPageMapping = MAPPING_INVALID; b->batchPage = NULL; return TRUE; } /* *---------------------------------------------------------------------- * * Balloon_Cleanup -- * * Cleanup after ballooning. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ void Balloon_Cleanup(void) { Balloon *b = &globalBalloon; /* * Deallocate all reserved memory, and reset connection with monitor. * Reset connection before deallocating memory to avoid potential for * additional spurious resets from guest touching deallocated pages. */ Backdoor_MonitorStart(b, BALLOON_CAPABILITIES); Balloon_Deallocate(b); } #ifdef __cplusplus } #endif open-vm-tools-9.4.0-1280544/modules/shared/vmmemctl/backdoor_balloon.h0000644765153500003110000000735212220061556023653 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * backdoor_balloon.h -- * * This file provides a wrapper for using the more generic backdoor library * together with the vmballoon-specific backdoor. */ #ifndef _BACKDOOR_BALLOON_H_ #define _BACKDOOR_BALLOON_H_ #include "vmballoon.h" #include "backdoor.h" #include "balloon_def.h" int Backdoor_MonitorStart(Balloon *b, uint32 protoVersion); int Backdoor_MonitorGuestType(Balloon *b); int Backdoor_MonitorGetTarget(Balloon *b, uint32 *target); int Backdoor_MonitorLockPage(Balloon *b, PPN64 ppn); int Backdoor_MonitorUnlockPage(Balloon *b, PPN64 ppn); int Backdoor_MonitorLockPagesBatched(Balloon *b, PPN64 ppn, uint32 nPages); int Backdoor_MonitorUnlockPagesBatched(Balloon *b, PPN64 ppn, uint32 nPages); #endif /* _BACKDOOR_BALLOON_H_ */ open-vm-tools-9.4.0-1280544/modules/shared/vmmemctl/kernelStubs.h0000644765153500003110000001560212220061556022657 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * kernelStubs.h * * KernelStubs implements some userspace library functions in terms * of kernel functions to allow library userspace code to be used in a * kernel. */ #ifndef __KERNELSTUBS_H__ #define __KERNELSTUBS_H__ #ifdef linux # ifndef __KERNEL__ # error "__KERNEL__ is not defined" # endif # include "driver-config.h" // Must be included before any other header files # include "vm_basic_types.h" # include # include #elif defined(_WIN32) # include "vm_basic_types.h" # include /* kernel memory APIs */ # include /* for _vsnprintf, vsprintf */ # include /* for va_start stuff */ # include /* for min macro. */ # include "vm_assert.h" /* Our assert macros */ #elif defined(__FreeBSD__) # include "vm_basic_types.h" # ifndef _KERNEL # error "_KERNEL is not defined" # endif # include # include # include # include # include # include #elif defined(__APPLE__) # include "vm_basic_types.h" # ifndef KERNEL # error "KERNEL is not defined" # endif # include # include # elif defined(sun) # include "vm_basic_types.h" # include # include #endif /* * Function Prototypes */ #if defined(linux) || defined(__APPLE__) || defined (sun) # ifdef linux /* if (linux) { */ char *strdup(const char *source); # endif /* Shared between Linux and Apple kernel stubs. */ void *malloc(size_t size); void free(void *mem); void *calloc(size_t num, size_t len); void *realloc(void *ptr, size_t newSize); #elif defined(_WIN32) /* } else if (_WIN32) { */ #if (_WIN32_WINNT == 0x0400) /* The following declarations are missing on NT4. */ typedef unsigned int UINT_PTR; typedef unsigned int SIZE_T; /* No free with tag availaible on NT4 kernel! */ #define KRNL_STUBS_FREE(P,T) ExFreePool((P)) #else /* _WIN32_WINNT */ #define KRNL_STUBS_FREE(P,T) ExFreePoolWithTag((P),(T)) /* Win 2K and later useful kernel function, documented but not declared! */ NTKERNELAPI VOID ExFreePoolWithTag(IN PVOID P, IN ULONG Tag); #endif /* _WIN32_WINNT */ #elif defined(__FreeBSD__) /* } else if (FreeBSD) { */ /* Kernel memory on FreeBSD is tagged for statistics and sanity checking. */ MALLOC_DECLARE(M_VMWARE_TEMP); /* * On FreeBSD, the general memory allocator for both userland and the kernel is named * malloc, but the kernel malloc() takes more arguments. The following alias & macros * work around this, to provide the standard malloc() API for userspace code that is * being used in the kernel. */ # undef malloc static INLINE void * __compat_malloc(unsigned long size, struct malloc_type *type, int flags) { return malloc(size, type, flags); } # define malloc(size) __compat_malloc(size, M_VMWARE_TEMP, M_NOWAIT) # define calloc(count, size) __compat_malloc((count) * (size), \ M_VMWARE_TEMP, M_NOWAIT|M_ZERO) # define realloc(buf, size) realloc(buf, size, M_VMWARE_TEMP, M_NOWAIT) # define free(buf) free(buf, M_VMWARE_TEMP) # define strchr(s,c) index(s,c) # define strrchr(s,c) rindex(s,c) #endif /* } */ /* * Stub functions we provide. */ void Panic(const char *fmt, ...); char *Str_Strcpy(char *buf, const char *src, size_t maxSize); int Str_Vsnprintf(char *str, size_t size, const char *format, va_list arguments); char *Str_Vasprintf(size_t *length, const char *format, va_list arguments); char *Str_Asprintf(size_t *length, const char *Format, ...); /* * Functions the driver must implement for the stubs. */ EXTERN void Debug(const char *fmt, ...); #endif /* __KERNELSTUBS_H__ */ open-vm-tools-9.4.0-1280544/modules/shared/vmmemctl/dbllnklst.h0000644765153500003110000002120612220061556022344 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * dbllnklst.h -- * * Double linked lists */ #ifndef _DBLLNKLST_H_ #define _DBLLNKLST_H_ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #include "vm_basic_types.h" #define DblLnkLst_OffsetOf(type, field) ((intptr_t)&((type *)0)->field) #define DblLnkLst_Container(addr, type, field) \ ((type *)((char *)(addr) - DblLnkLst_OffsetOf(type, field))) #define DblLnkLst_ForEach(curr, head) \ for (curr = (head)->next; curr != (head); curr = (curr)->next) /* Safe from list element removal within loop body. */ #define DblLnkLst_ForEachSafe(curr, nextElem, head) \ for (curr = (head)->next, nextElem = (curr)->next; \ curr != (head); \ curr = nextElem, nextElem = (curr)->next) typedef struct DblLnkLst_Links { struct DblLnkLst_Links *prev; struct DblLnkLst_Links *next; } DblLnkLst_Links; /* * Functions * * DblLnkLst_LinkFirst, DblLnkLst_LinkLast, and DblLnkLst_Swap are specific * to anchored lists. The rest are for both circular and anchored lists. */ /* *---------------------------------------------------------------------- * * DblLnkLst_Init -- * * Initialize a member of a doubly linked list * * Result * None * * Side effects: * None * *---------------------------------------------------------------------- */ static INLINE void DblLnkLst_Init(DblLnkLst_Links *l) // IN { l->prev = l->next = l; } /* *---------------------------------------------------------------------- * * DblLnkLst_Link -- * * Merge two doubly linked lists into one * * The operation is commutative * The operation is inversible (its inverse is DblLnkLst_Unlink) * * Result * None * * Side effects: * None * *---------------------------------------------------------------------- */ static INLINE void DblLnkLst_Link(DblLnkLst_Links *l1, // IN DblLnkLst_Links *l2) // IN { DblLnkLst_Links *tmp; (tmp = l1->prev)->next = l2; (l1->prev = l2->prev)->next = l1; l2->prev = tmp ; } /* *---------------------------------------------------------------------- * * DblLnkLst_Unlink -- * * Split one doubly linked list into two * * No check is performed: the caller must ensure that both members * belong to the same doubly linked list * * The operation is commutative * The operation is inversible (its inverse is DblLnkLst_Link) * * Result * None * * Side effects: * None * *---------------------------------------------------------------------- */ static INLINE void DblLnkLst_Unlink(DblLnkLst_Links *l1, // IN DblLnkLst_Links *l2) // IN { DblLnkLst_Links *tmp; tmp = l1->prev ; (l1->prev = l2->prev)->next = l1; (l2->prev = tmp )->next = l2; } /* *---------------------------------------------------------------------- * * DblLnkLst_Unlink1 -- * * Unlink an element from its list. * * Result * None * * Side effects: * None * *---------------------------------------------------------------------- */ static INLINE void DblLnkLst_Unlink1(DblLnkLst_Links *l) // IN { DblLnkLst_Unlink(l, l->next); } /* *---------------------------------------------------------------------------- * * DblLnkLst_IsLinked -- * * Determines whether an element is linked with any other elements. * * Results: * TRUE if link is linked, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static INLINE Bool DblLnkLst_IsLinked(DblLnkLst_Links const *l) // IN { /* * A DblLnkLst_Links is either linked to itself (not linked) or linked to * other elements in a list (linked). */ return l->prev != l; } /* *---------------------------------------------------------------------- * * DblLnkLst_LinkFirst -- * * Insert 'l' at the beginning of the list anchored at 'head' * * Result * None * * Side effects: * None * *---------------------------------------------------------------------- */ static INLINE void DblLnkLst_LinkFirst(DblLnkLst_Links *head, // IN DblLnkLst_Links *l) // IN { DblLnkLst_Link(head->next, l); } /* *---------------------------------------------------------------------- * * DblLnkLst_LinkLast -- * * Insert 'l' at the end of the list anchored at 'head' * * Result * None * * Side effects: * None * *---------------------------------------------------------------------- */ static INLINE void DblLnkLst_LinkLast(DblLnkLst_Links *head, // IN DblLnkLst_Links *l) // IN { DblLnkLst_Link(head, l); } /* *---------------------------------------------------------------------- * * DblLnkLst_Swap -- * * Swap all entries between the list anchored at 'head1' and the list * anchored at 'head2'. * * The operation is commutative * The operation is inversible (its inverse is itself) * * Result * None * * Side effects: * None * *---------------------------------------------------------------------- */ static INLINE void DblLnkLst_Swap(DblLnkLst_Links *head1, // IN/OUT DblLnkLst_Links *head2) // IN/OUT { DblLnkLst_Links const tmp = *head1; if (DblLnkLst_IsLinked(head2)) { (head1->prev = head2->prev)->next = head1; (head1->next = head2->next)->prev = head1; } else { DblLnkLst_Init(head1); } if (tmp.prev != head1) { (head2->prev = tmp.prev)->next = head2; (head2->next = tmp.next)->prev = head2; } else { DblLnkLst_Init(head2); } } #endif /* _DBLLNKLST_H_ */ open-vm-tools-9.4.0-1280544/modules/shared/vmmemctl/balloon_def.h0000644765153500003110000002412212220061556022617 0ustar dtormts/********************************************************* * Copyright (C) 2000-2012 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * balloon_def.h -- * * Definitions for server "balloon" mechanism for reclaiming * physical memory from a VM. */ #ifndef _BALLOON_DEF_H #define _BALLOON_DEF_H #define INCLUDE_ALLOW_VMX #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_MODULE #include "includeCheck.h" #include "vm_basic_types.h" #include "vm_basic_defs.h" #include "vm_assert.h" /* * constants */ /* backdoor port */ #define BALLOON_BDOOR_PORT (0x5670) #define BALLOON_BDOOR_MAGIC (0x456c6d6f) /* * Backdoor commands availability: * * +====================+======================+ * | CMD | Capabilities | * +--------------------+----------------------+ * | START | Always available (*) | * | TARGET | Always available | * | LOCK | BASIC_CMDS | * | UNLOCK | BASIC_CMDS | * | GUEST_ID | Always available | * | BATCHED_LOCK | BATCHED_CMDS | * | BATCHED_UNLOCK | BATCHED_CMDS | * +====================+======================+ * * (*) The START command has been slightly modified when more than the * basic commands are available: It returns * BALLOON_SUCCESS_WITH_CAPABILITIES with the available capabilities * stored in %ecx. Previously, a versioned protocol was used, and the * protocol that should be used was also returned in %ecx. Protocol * version 2 was the initial version and the only one shipped. Version 3 * was temporary used internally but has caused several issue due to * protocol mismatch between monitor and guest. * */ /* backdoor command numbers */ #define BALLOON_BDOOR_CMD_START (0) #define BALLOON_BDOOR_CMD_TARGET (1) #define BALLOON_BDOOR_CMD_LOCK (2) #define BALLOON_BDOOR_CMD_UNLOCK (3) #define BALLOON_BDOOR_CMD_GUEST_ID (4) /* The command 5 was shortly used between 1881144 and 1901153. */ #define BALLOON_BDOOR_CMD_BATCHED_LOCK (6) #define BALLOON_BDOOR_CMD_BATCHED_UNLOCK (7) /* balloon capabilities */ typedef enum { /* * Bit 0 is not used and shouldn't be used, due to issue with * protocol v3, to avoid ambiguity between protocol v3 and * capabilities, leave this bit as 0. That way, by masking guest * capabilities with monitor capabilities, bit 0 will always be set * to 0, and buggy v3 tool will automatically switch to unbatched * LOCK and UNLOCK. */ BALLOON_BASIC_CMDS = (1 << 1), BALLOON_BATCHED_CMDS = (1 << 2) } BalloonCapabilities; /* use config value for max balloon size */ #define BALLOON_MAX_SIZE_USE_CONFIG (0) /* * Guest identities * * Note : all values should fit in 32 bits */ typedef enum { BALLOON_GUEST_UNKNOWN = 0, BALLOON_GUEST_LINUX = 1, BALLOON_GUEST_BSD = 2, BALLOON_GUEST_WINDOWS_NT4 = 3, BALLOON_GUEST_WINDOWS_NT5 = 4, BALLOON_GUEST_SOLARIS = 5, BALLOON_GUEST_MACOS = 6, BALLOON_GUEST_FROBOS = 7, } BalloonGuest; /* error codes */ #define BALLOON_SUCCESS (0) #define BALLOON_FAILURE (-1) #define BALLOON_ERROR_CMD_INVALID (1) #define BALLOON_ERROR_PPN_INVALID (2) #define BALLOON_ERROR_PPN_LOCKED (3) #define BALLOON_ERROR_PPN_UNLOCKED (4) #define BALLOON_ERROR_PPN_PINNED (5) #define BALLOON_ERROR_PPN_NOTNEEDED (6) #define BALLOON_ERROR_RESET (7) #define BALLOON_ERROR_BUSY (8) #define BALLOON_SUCCESS_WITH_CAPABILITIES (0x03000000) /* * BatchPage. */ #define BALLOON_BATCH_MAX_PAGES (PAGE_SIZE / sizeof(PA64)) /* * We are using the fact that for 4k pages, the 12LSB are set to 0, so * we can use them and mask those bit when we need the real PA. * * +=============+==========+========+ * | | | | * | Page number | Reserved | Status | * | | | | * +=============+==========+========+ * 64 PAGE_SHIFT 6 0 * * For now, only 4k pages are supported by the monitor, but by using * reserved bit we can in the future add some flags that will indicate * whether the page is a 2M page or a 1G page. * * The reserved field should be set to 0. * */ #define BALLOON_BATCH_STATUS_MASK MASK64(5) #define BALLOON_BATCH_PAGE_MASK (~MASK64(PAGE_SHIFT)) typedef struct BalloonBatchPage { PA64 pages[BALLOON_BATCH_MAX_PAGES]; } BalloonBatchPage; /* *----------------------------------------------------------------------------- * * Balloon_BatchGetPA -- * * Get the page stored in the batch page at idx. * * Results: * See above. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE PA64 Balloon_BatchGetPA(BalloonBatchPage *batchPage, // IN uint16 idx) // IN { ASSERT(idx < BALLOON_BATCH_MAX_PAGES); return batchPage->pages[idx] & BALLOON_BATCH_PAGE_MASK; } /* *----------------------------------------------------------------------------- * * Balloon_BatchGetStatus -- * * Get the error code associated with a page. * * Results: * See above. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE uint8 Balloon_BatchGetStatus(BalloonBatchPage *batchPage, // IN uint16 idx) // IN { ASSERT(idx < BALLOON_BATCH_MAX_PAGES); return (uint8)(batchPage->pages[idx] & BALLOON_BATCH_STATUS_MASK); } /* *----------------------------------------------------------------------------- * * Balloon_BatchSetPA -- * * Store the page in the batch page at idx. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE void Balloon_BatchSetPA(BalloonBatchPage *batchPage, // IN uint16 idx, // IN PA64 pa) // IN { ASSERT(idx < BALLOON_BATCH_MAX_PAGES); ASSERT((pa & ~BALLOON_BATCH_PAGE_MASK) == 0); batchPage->pages[idx] = pa; } /* *----------------------------------------------------------------------------- * * Balloon_BatchSetStatus -- * * Set the error code associated with a page. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE void Balloon_BatchSetStatus(BalloonBatchPage *batchPage, // IN uint16 idx, // IN int error) // IN { PA64 pa = Balloon_BatchGetPA(batchPage, idx); ASSERT(idx < BALLOON_BATCH_MAX_PAGES); ASSERT(error <= BALLOON_ERROR_BUSY && error >= BALLOON_FAILURE); batchPage->pages[idx] = pa | (PPN64)error; } MY_ASSERTS(BALLOON_BATCH_SIZE, ASSERT_ON_COMPILE(sizeof(BalloonBatchPage) == PAGE_SIZE); ) #endif /* _BALLOON_DEF_H */ open-vm-tools-9.4.0-1280544/modules/shared/vmmemctl/vmballoon.h0000644765153500003110000001333712220061556022352 0ustar dtormts/********************************************************* * Copyright (C) 2000-2012 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * vmballoon.h: Definitions and macros for vmballoon driver. */ #ifndef VMBALLOON_H #define VMBALLOON_H #include "balloonInt.h" #include "vm_basic_types.h" #include "dbllnklst.h" #include "os.h" /* * Page allocation flags */ typedef enum BalloonPageAllocType { BALLOON_PAGE_ALLOC_NOSLEEP = 0, BALLOON_PAGE_ALLOC_CANSLEEP = 1, BALLOON_PAGE_ALLOC_TYPES_NR, // total number of alloc types } BalloonPageAllocType; /* * Types */ typedef struct { /* current status */ uint32 nPages; uint32 nPagesTarget; /* adjustment rates */ uint32 rateNoSleepAlloc; uint32 rateAlloc; uint32 rateFree; /* high-level operations */ uint32 timer; /* primitives */ uint32 primAlloc[BALLOON_PAGE_ALLOC_TYPES_NR]; uint32 primAllocFail[BALLOON_PAGE_ALLOC_TYPES_NR]; uint32 primFree; uint32 primErrorPageAlloc; uint32 primErrorPageFree; /* monitor operations */ uint32 lock; uint32 lockFail; uint32 unlock; uint32 unlockFail; uint32 target; uint32 targetFail; uint32 start; uint32 startFail; uint32 guestType; uint32 guestTypeFail; } BalloonStats; #define BALLOON_ERROR_PAGES 16 typedef struct { PageHandle page[BALLOON_ERROR_PAGES]; uint32 pageCount; } BalloonErrorPages; #define BALLOON_CHUNK_PAGES 1000 typedef struct BalloonChunk { PageHandle page[BALLOON_CHUNK_PAGES]; uint32 pageCount; DblLnkLst_Links node; } BalloonChunk; struct BalloonOps; typedef struct { /* sets of reserved physical pages */ DblLnkLst_Links chunks; int nChunks; /* transient list of non-balloonable pages */ BalloonErrorPages errors; BalloonGuest guestType; /* balloon size */ int nPages; int nPagesTarget; /* reset flag */ int resetFlag; /* adjustment rates (pages per second) */ int rateAlloc; int rateFree; /* slowdown page allocations for next few cycles */ int slowPageAllocationCycles; /* statistics */ BalloonStats stats; /* hypervisor exposed capabilities */ BalloonCapabilities hypervisorCapabilities; /* balloon operations, tied to the capabilities */ const struct BalloonOps *balloonOps; /* Either the batch page handle, or the page to lock on v2 */ PageHandle pageHandle; Mapping batchPageMapping; BalloonBatchPage *batchPage; uint16 batchMaxPages; BalloonChunk *fallbackChunk; } Balloon; typedef struct BalloonOps { void (*addPage)(Balloon *b, uint16 idx, PageHandle page); int (*lock)(Balloon *b, uint16 nPages); int (*unlock)(Balloon *b, uint16 nPages); } BalloonOps; /* * Operations */ Bool Balloon_Init(BalloonGuest guestType); void Balloon_Cleanup(void); void Balloon_QueryAndExecute(void); const BalloonStats *Balloon_GetStats(void); #endif /* VMBALLOON_H */ open-vm-tools-9.4.0-1280544/modules/shared/vmmemctl/balloonInt.h0000644765153500003110000001110112220061556022445 0ustar dtormts/********************************************************* * Copyright (C) 2012 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ #ifndef BALLOONINT_H_ # define BALLOONINT_H_ /* * Compile-Time Options */ #define BALLOON_NAME "vmmemctl" #define BALLOON_NAME_VERBOSE "VMware memory control driver" #if defined __linux__ || defined __FreeBSD__ || defined _WIN32 /* * FIXME: Even if the driver support batched commands keep using the * non-batched one until more testing has been done. */ #define BALLOON_CAPABILITIES BALLOON_BASIC_CMDS #else #define BALLOON_CAPABILITIES BALLOON_BASIC_CMDS #endif #define BALLOON_RATE_ADAPT 1 #define BALLOON_DEBUG 1 #define BALLOON_DEBUG_VERBOSE 0 #define BALLOON_POLL_PERIOD 1 /* sec */ #define BALLOON_NOSLEEP_ALLOC_MAX 16384 #define BALLOON_RATE_ALLOC_MIN 512 #define BALLOON_RATE_ALLOC_MAX 2048 #define BALLOON_RATE_ALLOC_INC 16 #define BALLOON_RATE_FREE_MIN 512 #define BALLOON_RATE_FREE_MAX 16384 #define BALLOON_RATE_FREE_INC 16 /* * Move it to bora/public/balloon_def.h later, if needed. Note that * BALLOON_PAGE_ALLOC_FAILURE is an internal error code used for * distinguishing page allocation failures from monitor-backdoor errors. * We use value 1000 because all monitor-backdoor error codes are < 1000. */ #define BALLOON_PAGE_ALLOC_FAILURE 1000 #define BALLOON_STATS #ifdef BALLOON_STATS #define STATS_INC(stat) (stat)++ #define STATS_DEC(stat) (stat)-- #else #define STATS_INC(stat) #define STATS_DEC(stat) #endif #define PPN_2_PA(_ppn) ((PPN64)(_ppn) << PAGE_SHIFT) #define PA_2_PPN(_pa) ((_pa) >> PAGE_SHIFT) #endif /* !BALLOONINT_H_ */ open-vm-tools-9.4.0-1280544/modules/shared/vmmemctl/os.h0000644765153500003110000001001612220061556020771 0ustar dtormts/********************************************************* * Copyright (C) 2000 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * os.h -- * * Definitions for OS-specific wrapper functions required by "vmmemctl". */ #ifndef OS_H #define OS_H #include "vm_basic_types.h" #include "balloon_def.h" /* * Types */ typedef uintptr_t PageHandle; typedef uintptr_t Mapping; #define PAGE_HANDLE_INVALID 0 #define MAPPING_INVALID 0 /* * Operations */ extern void OS_MemZero(void *ptr, size_t size); extern void OS_MemCopy(void *dest, const void *src, size_t size); extern void *OS_Malloc(size_t size); extern void OS_Free(void *ptr, size_t size); extern void OS_Yield(void); extern unsigned long OS_ReservedPageGetLimit(void); extern PA64 OS_ReservedPageGetPA(PageHandle handle); extern PageHandle OS_ReservedPageGetHandle(PA64 pa); extern PageHandle OS_ReservedPageAlloc(int canSleep); extern void OS_ReservedPageFree(PageHandle handle); extern Mapping OS_MapPageHandle(PageHandle handle); extern void *OS_Mapping2Addr(Mapping mapping); extern void OS_UnmapPage(Mapping mapping); #endif /* OS_H */ open-vm-tools-9.4.0-1280544/libhgfs/0000755765153500003110000000000012220061624015051 5ustar dtormtsopen-vm-tools-9.4.0-1280544/libhgfs/hgfslib.c0000644765153500003110000000314612220061556016643 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file hgfslib.c * * Library entry point. */ #include "embed_version.h" #include "vmtoolslib_version.h" VM_EMBED_VERSION(VMTOOLSLIB_VERSION_STRING); #if defined(_WIN32) #include /* ****************************************************************************** * DllMain -- */ /** * * Library entry point, currently does nothing. * * @param[in] hinstDLL Unused. * @param[in] fdwReason Unused. * @param[in] lpvReserved Unused. * * @return TRUE. * ****************************************************************************** */ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { return TRUE; } #endif open-vm-tools-9.4.0-1280544/libhgfs/Makefile.am0000644765153500003110000000327412220061556017117 0ustar dtormts################################################################################ ### Copyright 2010 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ lib_LTLIBRARIES = libhgfs.la libhgfs_la_LIBADD = libhgfs_la_LIBADD += ../lib/hgfs/libHgfs.la libhgfs_la_LIBADD += ../lib/hgfsHelper/libHgfsHelper.la libhgfs_la_LIBADD += ../lib/hgfsServer/libHgfsServer.la libhgfs_la_LIBADD += ../lib/hgfsServerManagerGuest/libHgfsServerManagerGuest.la libhgfs_la_LIBADD += ../lib/hgfsServerPolicyGuest/libHgfsServerPolicyGuest.la libhgfs_la_LIBADD += @GLIB2_LIBS@ libhgfs_la_LIBADD += @GTHREAD_LIBS@ libhgfs_la_LIBADD += @VMTOOLS_LIBS@ libhgfs_la_SOURCES = libhgfs_la_SOURCES += hgfslib.c libhgfs_la_CPPFLAGS = libhgfs_la_CPPFLAGS += -I$(top_srcdir)/libvmtools libhgfs_la_LDFLAGS = # We require GCC, so we're fine passing compiler-specific flags. libhgfs_la_LDFLAGS += -Wl,-z,defs # Needed for OS's that don't link shared libraries against libc by #default, e.g. FreeBSD libhgfs_la_LDFLAGS += -Wl,-lc open-vm-tools-9.4.0-1280544/libhgfs/Makefile.in0000644765153500003110000005405512220061624017127 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2010 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = libhgfs DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libhgfs_la_DEPENDENCIES = ../lib/hgfs/libHgfs.la \ ../lib/hgfsHelper/libHgfsHelper.la \ ../lib/hgfsServer/libHgfsServer.la \ ../lib/hgfsServerManagerGuest/libHgfsServerManagerGuest.la \ ../lib/hgfsServerPolicyGuest/libHgfsServerPolicyGuest.la am_libhgfs_la_OBJECTS = libhgfs_la-hgfslib.lo libhgfs_la_OBJECTS = $(am_libhgfs_la_OBJECTS) libhgfs_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libhgfs_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libhgfs_la_SOURCES) DIST_SOURCES = $(libhgfs_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ lib_LTLIBRARIES = libhgfs.la libhgfs_la_LIBADD = ../lib/hgfs/libHgfs.la \ ../lib/hgfsHelper/libHgfsHelper.la \ ../lib/hgfsServer/libHgfsServer.la \ ../lib/hgfsServerManagerGuest/libHgfsServerManagerGuest.la \ ../lib/hgfsServerPolicyGuest/libHgfsServerPolicyGuest.la \ @GLIB2_LIBS@ @GTHREAD_LIBS@ @VMTOOLS_LIBS@ $(am__empty) libhgfs_la_SOURCES = hgfslib.c libhgfs_la_CPPFLAGS = -I$(top_srcdir)/libvmtools # We require GCC, so we're fine passing compiler-specific flags. # Needed for OS's that don't link shared libraries against libc by #default, e.g. FreeBSD libhgfs_la_LDFLAGS = -Wl,-z,defs -Wl,-lc all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libhgfs/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu libhgfs/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhgfs.la: $(libhgfs_la_OBJECTS) $(libhgfs_la_DEPENDENCIES) $(EXTRA_libhgfs_la_DEPENDENCIES) $(libhgfs_la_LINK) -rpath $(libdir) $(libhgfs_la_OBJECTS) $(libhgfs_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhgfs_la-hgfslib.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libhgfs_la-hgfslib.lo: hgfslib.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhgfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhgfs_la-hgfslib.lo -MD -MP -MF $(DEPDIR)/libhgfs_la-hgfslib.Tpo -c -o libhgfs_la-hgfslib.lo `test -f 'hgfslib.c' || echo '$(srcdir)/'`hgfslib.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libhgfs_la-hgfslib.Tpo $(DEPDIR)/libhgfs_la-hgfslib.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hgfslib.c' object='libhgfs_la-hgfslib.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhgfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhgfs_la-hgfslib.lo `test -f 'hgfslib.c' || echo '$(srcdir)/'`hgfslib.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(libdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool cscopelist ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am \ install-libLTLIBRARIES install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-libLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/hgfsmounter/0000755765153500003110000000000012220061621015771 5ustar dtormtsopen-vm-tools-9.4.0-1280544/hgfsmounter/COPYING0000644765153500003110000006347112220061556017046 0ustar dtormts GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! open-vm-tools-9.4.0-1280544/hgfsmounter/Makefile.am0000644765153500003110000000337112220061556020040 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ sbin_PROGRAMS = mount.vmhgfs mount_vmhgfs_LDADD = mount_vmhgfs_LDADD += ../lib/string/libString.la mount_vmhgfs_LDADD += ../lib/panicDefault/libPanicDefault.la mount_vmhgfs_LDADD += ../lib/panic/libPanic.la mount_vmhgfs_LDADD += ../lib/lock/libLock.la mount_vmhgfs_LDADD += ../lib/misc/libMisc.la mount_vmhgfs_LDADD += ../lib/stubs/libStubs.la mount_vmhgfs_SOURCES = mount_vmhgfs_SOURCES += hgfsmounter.c if FREEBSD install-exec-hook: mv $(DESTDIR)$(sbindir)/mount.vmhgfs \ $(DESTDIR)$(sbindir)/mount_vmhgfs -$(MKDIR_P) $(DESTDIR)/sbin -$(LN_S) $(DESTDIR)$(sbindir)/mount_vmhgfs \ $(DESTDIR)/sbin/mount_vmhgfs &> /dev/null uninstall-hook: rm -f $(DESTDIR)$(sbindir)/mount_vmhgfs else install-exec-hook: -$(MKDIR_P) $(DESTDIR)/sbin -$(LN_S) $(DESTDIR)$(sbindir)/mount.vmhgfs \ $(DESTDIR)/sbin/mount.vmhgfs &> /dev/null uninstall-hook: rm -f $(DESTDIR)/sbin/mount.vmhgfs endif !FREEBSD open-vm-tools-9.4.0-1280544/hgfsmounter/hgfsmounter_version.h0000644765153500003110000000305212220061556022257 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * hgfsmounter_version.h -- * * Version definitions for the HGFS mount helper application. */ #ifndef _HGFSMOUNTER_VERSION_H_ #define _HGFSMOUNTER_VERSION_H_ /* * This component's version is coupled with Tools versioning. The effect * is that the version increments with each build, and with each Tools * version bump. If and when it becomes necessary to version the component * manually, make sure that the version is bumped any time the component or * its dependencies are changed. */ #include "vm_tools_version.h" #define HGFSMOUNTER_VERSION_COMMAS TOOLS_VERSION_EXT_CURRENT_CSV #define HGFSMOUNTER_VERSION_STRING TOOLS_VERSION_EXT_CURRENT_STR #endif /* _HGFSMOUNTER_VERSION_H_ */ open-vm-tools-9.4.0-1280544/hgfsmounter/hgfsmounter.c0000644765153500003110000010052712220061556020512 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * hgfsmounter.c -- * * Helper app for mounting HGFS shares on Linux and FreeBSD. On Linux, we need this * because we must pass a binary blob through mount(2) to the HGFS driver, in order * to properly communicate the share name that we're interested in mounting. On * FreeBSD, we need this because FreeBSD requires that each filesystem type have a * separate mount program installed as /sbin/mount_fstype */ #define _GNU_SOURCE #include #include #include #include #if defined(linux) # include #endif #if defined(__FreeBSD__) || defined(__APPLE__) # include # include # define MS_MANDLOCK 0 # define MS_RDONLY MNT_RDONLY # define MS_SYNCHRONOUS MNT_SYNCHRONOUS # define MS_NOEXEC MNT_NOEXEC # define MS_NOSUID MNT_NOSUID /* * MNT_NODEV does not exist, or is set to 0, on newer versions of FreeBSD. */ # if defined(MNT_NODEV) && MNT_NODEV # define MS_NODEV MNT_NODEV # endif # define MS_UNION MNT_UNION # define MS_ASYNC MNT_ASYNC # define MS_SUIDDIR MNT_SUIDDIR # define MS_SOFTDEP MNT_SOFTDEP # define MS_NOSYMFOLLOW MNT_NOSYMFOLLOW # define MS_JAILDEVFS MNT_JAILDEVFS # define MS_MULTILABEL MNT_MULTILABEL # define MS_ACLS MNT_ACLS # define MS_NODIRATIME 0 # define MS_NOCLUSTERR MNT_NOCLUSTERR # define MS_NOCLUSTERW MNT_NOCLUSTERW # define MS_REMOUNT MNT_RELOAD # if defined(__FreeBSD__) # define MS_NOATIME MNT_NOATIME # elif defined(__APPLE__) /* * XXX This is defined in the sys/mount.h in the OS X 10.5 Kernel.framework but not the * 10.4 one. Once this is built against the newer library, this should be changed. */ # define MS_NOATIME 0 # endif #endif #include #include #include #include #include #include #include #include #ifdef MOUNTED /* defined in mntent.h */ /* * If VM_HAVE_MTAB is set, hgfsmounter will update /etc/mtab. This is not necessary on * systems such as FreeBSD (and possibly Solaris) that don't have a mtab or the mntent.h * routines. */ # define VM_HAVE_MTAB 1 #endif #include "hgfsDevLinux.h" #include "vm_basic_types.h" #include "vm_assert.h" #include "str.h" #include "strutil.h" #include "hgfsmounter_version.h" /* XXX embed_version.h does not currently support Mach-O binaries (OS X). */ #if defined(linux) || defined(__FreeBSD__) # include "embed_version.h" VM_EMBED_VERSION(HGFSMOUNTER_VERSION_STRING); #endif /* * Not defined in glibc 2.1.3 */ #ifndef MS_BIND #define MS_BIND 4096 #endif #ifndef MS_MOVE #define MS_MOVE 8192 #endif #define MOUNT_OPTS_BUFFER_SIZE 256 #if defined(__GNUC__) && __GNUC__ < 3 /* __VA_ARGS__ isn't supported by old gcc's, so hack around the situation */ #define LOG(format...) (beVerbose ? printf(format) : 0) #else #define LOG(format, ...) (beVerbose ? printf(format, ##__VA_ARGS__) : 0) #endif typedef struct MountOptions { char *opt; /* Option name */ int flag; /* Corresponding flag */ Bool set; /* Whether the flag should be set or reset */ char *helpMsg; /* Help message for the option */ char *logMsg; /* Log message to emit when option was detected */ /* Special handler for more complex options */ Bool (*handler)(const char *opt, HgfsMountInfo *mountInfo, int *flags); } MountOptions; static char *thisProgram; static char *thisProgramBase; static char *shareName; static char *mountPoint; static Bool beVerbose = FALSE; /* *----------------------------------------------------------------------------- * * PrintVersion -- * * Displays version and exits with success. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void PrintVersion(void) { printf("%s version: %s\n", thisProgramBase, HGFSMOUNTER_VERSION_STRING); exit(EXIT_SUCCESS); } /* *----------------------------------------------------------------------------- * * GetPathMax * * Helper function to get the system's maximum path length for a given * path. In userspace, PATH_MAX may not be defined, and we must use * pathconf(3) to get its value. * * This is the realpath(3)-approved way of getting the maximum path size, * inasmuch as realpath(3) can be an approved function (see the BUGS section * in the manpage for details). * * Results: * Always succeeds, returns the maximum path size. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static size_t GetPathMax(const char *path) // IN: path to check { size_t pathMax; #ifndef PATH_MAX long sysPathMax; /* * pathconf(3) may return -1 if the system imposes no pathname bound, or if * there was an error. In any case, we're advised by realpath(3)'s manpage * not to use the result of pathconf for direct allocation, as it may be too * large. So we declare 4096 as our upper bound, to be used when pathconf(3) * returns an error, returns zero, returns a very large quantity, or when * we learn that there's no limit. */ sysPathMax = pathconf(path, _PC_PATH_MAX); if (sysPathMax <= 0 || sysPathMax > 4096) { pathMax = 4096; } else { pathMax = sysPathMax; } #else pathMax = PATH_MAX; #endif return pathMax; } /* *----------------------------------------------------------------------------- * * IsValidShareName * * A helper function to parse the share name from "host:share" format into * two separate strings, reporting errors if any. * * Results: * TRUE on success, shareNameHost and shareNameDir have been set. * FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool ParseShareName(const char *shareName, // IN: Share name to validate const char **shareNameHost, // OUT: Share name, host component const char **shareNameDir) // OUT: Share name, dir component { const char *colon; const char *dir; /* 1) Must be colon separated into host and dir. */ colon = strchr(shareName, ':'); if (colon == NULL) { printf("Share name must be in host:dir format\n"); return FALSE; } /* 2) Dir must not be empty. */ dir = colon + 1; if (*dir == '\0') { printf("Directory in share name must not be empty\n"); return FALSE; } /* 3) Dir must start with forward slash. */ if (*dir != '/') { printf("Directory in share name must be an absolute path\n"); return FALSE; } /* 4) Host must be ".host". */ if (strncmp(shareName, ".host:", 6) != 0) { printf("Host in share name must be \".host\"\n"); return FALSE; } *shareNameHost = ".host"; LOG("Host component of share name is \"%s\"\n", *shareNameHost); *shareNameDir = dir; LOG("Directory component of share name is \"%s\"\n", *shareNameDir); return TRUE; } /* *----------------------------------------------------------------------------- * * ParseUid * * A helper function to process a string containing either a user name * or a uid and set up mountInfo accordingly. * * Results: * TRUE on success, mountInfo modified appropriately, FALSE on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ #ifndef sun static Bool ParseUid(const char *option, // IN: option string along with value HgfsMountInfo *mountInfo, // OUT: mount data int *flags) // OUT: mount flags { Bool success = FALSE; unsigned int idx = 0; char *optString; char *uidString; uid_t myUid = 0; ASSERT(option); ASSERT(mountInfo); ASSERT(flags); /* Figure where value starts, we don't need result, just index. */ optString = StrUtil_GetNextToken(&idx, option, "="); ASSERT(optString); uidString = StrUtil_GetNextToken(&idx, option, "="); if (!uidString) { LOG("Error getting the value for uid\n"); goto out; } /* * The uid can be a direct value or a username which we must first * translate to its numeric value. */ if (isdigit(*uidString)) { errno = 0; myUid = strtoul(uidString, NULL, 10); if (errno == 0) { success = TRUE; } else { printf("Bad UID value \"%s\"\n", uidString); } } else { struct passwd *pw; if (!(pw = getpwnam(uidString))) { printf("Bad user name \"%s\"\n", uidString); } else { myUid = pw->pw_uid; success = TRUE; } endpwent(); } if (success) { mountInfo->uid = myUid; mountInfo->uidSet = TRUE; LOG("Setting mount owner to %"FMTUID"\n", myUid); } free(uidString); out: free(optString); return success; } #endif /* *----------------------------------------------------------------------------- * * ParseGid * * A helper function to process a string containing either a group name * or a gid and set up mountInfo accordingly. * * Results: * TRUE on success, mountInfo modified appropriately, FALSE on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ #ifndef sun static Bool ParseGid(const char *option, // IN: option string along with value HgfsMountInfo *mountInfo, // OUT: mount data int *flags) // OUT: mount flags { Bool success = FALSE; unsigned int idx = 0; char *optString; char *gidString; gid_t myGid = 0; ASSERT(option); ASSERT(mountInfo); ASSERT(flags); /* Figure where value starts, we don't need result, just index. */ optString = StrUtil_GetNextToken(&idx, option, "="); ASSERT(optString); gidString = StrUtil_GetNextToken(&idx, option, "="); if (!gidString) { LOG("Error getting the value for gid\n"); goto out; } /* * The gid can be a direct value or a group name which we must first * translate to its numeric value. */ if (isdigit(*gidString)) { errno = 0; myGid = strtoul(gidString, NULL, 10); if (errno == 0) { success = TRUE; } else { printf("Bad GID value \"%s\"\n", gidString); } } else { struct group *gr; if (!(gr = getgrnam(gidString))) { printf("Bad group name \"%s\"\n", gidString); } else { myGid = gr->gr_gid; success = TRUE; } endpwent(); } if (success) { mountInfo->gid = myGid; mountInfo->gidSet = TRUE; LOG("Setting mount group to %"FMTUID"\n", myGid); } free(gidString); out: free(optString); return success; } #endif /* *----------------------------------------------------------------------------- * * ParseMask * * A helper function to parse a string containing File/Directory * mask value. * * Results: * TRUE on success, along with the mask, FALSE on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ #ifndef sun static Bool ParseMask(const char *option, // IN: option string along with value unsigned short *pmask) // OUT: parsed mask { Bool success = FALSE; unsigned int idx = 0; char *optString; char *maskString; unsigned short mask; optString = StrUtil_GetNextToken(&idx, option, "="); ASSERT(optString); maskString = StrUtil_GetNextToken(&idx, option, "="); if (!maskString) { LOG("Error getting the value for %s\n", optString); goto out; } /* * The way to check for an overflow in strtol(3), according to its * man page. */ errno = 0; mask = strtol(maskString, NULL, 8); if (errno == 0) { *pmask = mask; success = TRUE; } else { LOG("Error, overflow in %s\n", optString); } free(maskString); out: free(optString); return success; } #endif /* *----------------------------------------------------------------------------- * * ParseFmask * * A helper function to process a string containing File mask value. * * Results: * TRUE on success, mountInfo modified appropriately, FALSE on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ #ifndef sun static Bool ParseFmask(const char *option, // IN: option string along with value HgfsMountInfo *mountInfo, // OUT: mount data int *flags) // OUT: mount flags { ASSERT(option); ASSERT(mountInfo); if (ParseMask(option, &mountInfo->fmask)) { LOG("Setting mount fmask to %o\n", mountInfo->fmask); return TRUE; } return FALSE; } #endif /* *----------------------------------------------------------------------------- * * ParseDmask * * A helper function to process a string containing dmask value. * * Results: * TRUE on success, mountInfo modified appropriately, FALSE on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ #ifndef sun static Bool ParseDmask(const char *option, // IN: option string along with value HgfsMountInfo *mountInfo, // OUT: mount data int *flags) // OUT: mount flags { ASSERT(option); ASSERT(mountInfo); if (ParseMask(option, &mountInfo->dmask)) { LOG("Setting mount dmask to %o\n", mountInfo->dmask); return TRUE; } return FALSE; } #endif /* *----------------------------------------------------------------------------- * * ParseTtl * * A helper function to process a string containing TTL value. * * Results: * TRUE on success, mountInfo modified appropriately, FALSE on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ #ifndef sun static Bool ParseTtl(const char *option, // IN: option string along with value HgfsMountInfo *mountInfo, // OUT: mount data int *flags) // OUT: mount flags { Bool success = FALSE; unsigned int idx = 0; char *optString; int32 ttl; ASSERT(option); ASSERT(mountInfo); ASSERT(flags); /* Figure where value starts, we don't need result, just index. */ optString = StrUtil_GetNextToken(&idx, option, "="); ASSERT(optString); if (StrUtil_GetNextIntToken(&ttl, &idx, option, "=") && ttl >= 0) { LOG("Setting maximum attribute TTL to %u\n", ttl); mountInfo->ttl = ttl; success = TRUE; } else { LOG("Error getting the value for ttl\n"); } free(optString); return success; } #endif static MountOptions mountOptions[] = { { "ro", MS_RDONLY, TRUE, "mount read-only", "Setting mount read-only", NULL }, { "rw", MS_RDONLY, FALSE, "mount read-write", "Setting mount read-write", NULL }, { "nosuid", MS_NOSUID, TRUE, "ignore suid/sgid bits", "Setting mount option for allowing suid/sgid bits off", NULL }, { "suid", MS_NOSUID, FALSE, "allow suid/sgid bits (default)", "Setting mount option for allowing suid/sgid bits on", NULL }, #ifndef sun /* Solaris does not have any of these options */ { "uid=", 0, TRUE, "mount owner (by uid or username)", NULL, ParseUid }, { "gid=", 0, TRUE, "mount group (by gid or groupname)", NULL, ParseGid }, { "fmask=", 0, TRUE, "file umask (in octal)", NULL, ParseFmask }, { "dmask=", 0, TRUE, "directory umask (in octal)", NULL, ParseDmask }, #ifdef MS_NODEV { "nodev", MS_NODEV, TRUE, "prevent device node access", "Setting mount option for accessing device nodes off", NULL }, { "dev", MS_NODEV, FALSE, "allow device node access (default)", "Setting mount option for accessing device nodes on", NULL }, #endif { "noexec", MS_NOEXEC, TRUE, "prevent program execution", "Setting mount option for program execution off", NULL }, { "exec", MS_NOEXEC, FALSE, "allow program execution (default)", "Setting mount option for program execution on", NULL }, { "sync", MS_SYNCHRONOUS, TRUE, "file writes are synchronous", "Setting mount synchronous writes", NULL }, { "async", MS_SYNCHRONOUS, FALSE, "file writes are asynchronous (default)", "Setting mount synchronous writes", NULL }, { "mand", MS_MANDLOCK, TRUE, "allow mandatory locks", "Setting mount option for allow mandatory locks on", NULL }, { "nomand", MS_MANDLOCK, FALSE, "prevent mandatory locks (default)", "Setting mount option for allow mandatory locks off", NULL }, { "noatime", MS_NOATIME, TRUE, "do not update access times", "Setting mount option for updating access times off", NULL }, { "atime", MS_NOATIME, FALSE, "update access times (default)", "Setting mount option for updating access times on", NULL }, { "nodiratime", MS_NOATIME, TRUE, "do not update directory access times", "Setting mount option for updating directory access times off", NULL }, { "diratime", MS_NOATIME, FALSE, "update access directory times (default)", "Setting mount option for updating directory access times on", NULL }, { "ttl=", 0, TRUE, "time before file attributes must be\n" "revalidated (in seconds). Improves\n" "performance but decreases coherency.\n" "Defaults to 1 if not set.\n", NULL, ParseTtl }, { "bind", MS_BIND, TRUE, "perform bind mount", "Setting mount type to bind", NULL }, { "bind", MS_MOVE, TRUE, "move an existig mount point", "Setting mount type to move", NULL }, #endif { "remount", MS_REMOUNT, TRUE, "remount already mounted filesystem", "Setting mount type to remount", NULL } }; /* *----------------------------------------------------------------------------- * * ParseOptions -- * * Parses the options passed in by mount. Note that this doesn't correspond * to the entire argument string, merely the "-o opt1=val1,opt2=val2" * section. * * Results: * TRUE if there were no problems. * FALSE if there was an issue parsing an option. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool ParseOptions(const char *optionString, // IN: Option string to parse HgfsMountInfo *mountInfo, // OUT: Where we put the results int *flags) // OUT: Flags we might modify { unsigned int commaIndex = 0; Bool success = FALSE; char *key = NULL; char *keyVal = NULL; int i; ASSERT(optionString); ASSERT(mountInfo); ASSERT(flags); /* Parse the options string. */ LOG("Parsing option string: %s\n", optionString); /* Loop to tokenize ,,. */ while ((keyVal = StrUtil_GetNextToken(&commaIndex, optionString, ",")) != NULL) { /* Now tokenize [=]. */ unsigned int equalsIndex = 0; key = StrUtil_GetNextToken(&equalsIndex, keyVal, "="); if (key == NULL) { printf("Malformed options string\n"); goto out; } for (i = 0; i < ARRAYSIZE(mountOptions); i++) { Bool match = FALSE; unsigned int idx = 0; char *optName = StrUtil_GetNextToken(&idx, mountOptions[i].opt, "="); if (!optName) { printf("Failed to parse option name, out of memory?\n"); goto out; } match = strcmp(key, optName) == 0; free(optName); if (match) { if (mountOptions[i].handler) { if (!mountOptions[i].handler(keyVal, mountInfo, flags)) { goto out; } } else { if (mountOptions[i].set) { *flags |= mountOptions[i].flag; } else { *flags &= ~mountOptions[i].flag; } LOG("%s\n", mountOptions[i].logMsg); } break; } } if (i == ARRAYSIZE(mountOptions)) { LOG("Skipping unrecognized option \"%s\"\n", key); } free(key); free(keyVal); key = NULL; keyVal = NULL; } success = TRUE; out: free(key); free(keyVal); return success; } /* *----------------------------------------------------------------------------- * * PrintUsage -- * * Displays usage for the HGFS mounting utility, and exits with failure. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void PrintUsage(void) { int i; printf("Usage: %s [-o ]\n", thisProgramBase); printf("Mount the HGFS share, specified by name, to a local directory.\n"); printf("Share name must be in host:dir format.\n\nOptions:\n"); for (i = 0; i < ARRAYSIZE(mountOptions); i++) { Bool printOptName = TRUE; unsigned int tokidx = 0; char *msg; while ((msg = StrUtil_GetNextToken(&tokidx, mountOptions[i].helpMsg, "\n")) != NULL) { printf(" %-15s %s\n", printOptName ? mountOptions[i].opt : "", msg); free(msg); printOptName = FALSE; } } printf("\n"); printf("This command is intended to be run from within /bin/mount by\n"); printf("passing the option '-t %s'. For example:\n", HGFS_NAME); printf(" mount -t %s .host:/ /mnt/hgfs/\n", HGFS_NAME); printf(" mount -t %s .host:/foo /mnt/foo\n", HGFS_NAME); printf(" mount -t %s .host:/foo/bar /var/lib/bar\n", HGFS_NAME); exit(EXIT_FAILURE); } #ifdef VM_HAVE_MTAB /* *----------------------------------------------------------------------------- * * UpdateMtab -- * * Write the results of the mount into /etc/mtab. * * Results: * None. * * Side effects: * May write to /etc/mtab. * *----------------------------------------------------------------------------- */ static void UpdateMtab(HgfsMountInfo *mountInfo, // IN: Info to write into mtab int flags) // IN: Flags (read-only, etc.) { struct mntent mountEnt; FILE *mountFile; struct passwd *password; char *userName = NULL; ASSERT(mountInfo); mountFile = setmntent(MOUNTED, "a+"); if (mountFile == NULL) { printf("Could not open mtab for appending, continuing sans mtab\n"); return; } /* We only care about the mounting user if it isn't root. */ if (getuid() != 0) { password = getpwuid(getuid()); if (password == NULL) { printf("Could not get user for mounting uid, skipping user entry\n"); } else { userName = password->pw_name; } } /* * Create the mtab entry to be written. We'll go ahead and try to write * even if we fail to allocate the mount options. */ mountEnt.mnt_fsname = shareName; mountEnt.mnt_dir = mountPoint; mountEnt.mnt_type = HGFS_NAME; mountEnt.mnt_freq = 0; mountEnt.mnt_passno = 0; mountEnt.mnt_opts = malloc(MOUNT_OPTS_BUFFER_SIZE); if (mountEnt.mnt_opts) { char *ttlString; memset(mountEnt.mnt_opts, 0, MOUNT_OPTS_BUFFER_SIZE); /* * These are typically the displayed options in /etc/mtab (note that not * all options are typically displayed, just those the user may find * interesting). */ if (flags & MS_RDONLY) { Str_Strcat(mountEnt.mnt_opts, "ro", MOUNT_OPTS_BUFFER_SIZE); } else { Str_Strcat(mountEnt.mnt_opts, "rw", MOUNT_OPTS_BUFFER_SIZE); } if (flags & MS_NOSUID) { Str_Strcat(mountEnt.mnt_opts, ",nosuid", MOUNT_OPTS_BUFFER_SIZE); } #ifdef MS_NODEV if (flags & MS_NODEV) { Str_Strcat(mountEnt.mnt_opts, ",nodev", MOUNT_OPTS_BUFFER_SIZE); } #endif if (flags & MS_NOEXEC) { Str_Strcat(mountEnt.mnt_opts, ",noexec", MOUNT_OPTS_BUFFER_SIZE); } if (flags & MS_SYNCHRONOUS) { Str_Strcat(mountEnt.mnt_opts, ",sync", MOUNT_OPTS_BUFFER_SIZE); } if (flags & MS_MANDLOCK) { Str_Strcat(mountEnt.mnt_opts, ",mand", MOUNT_OPTS_BUFFER_SIZE); } if (flags & MS_NOATIME) { Str_Strcat(mountEnt.mnt_opts, ",noatime", MOUNT_OPTS_BUFFER_SIZE); } if (flags & MS_NODIRATIME) { Str_Strcat(mountEnt.mnt_opts, ",nodiratime", MOUNT_OPTS_BUFFER_SIZE); } if (userName != NULL) { Str_Strcat(mountEnt.mnt_opts, ",user=", MOUNT_OPTS_BUFFER_SIZE); Str_Strcat(mountEnt.mnt_opts, userName, MOUNT_OPTS_BUFFER_SIZE); } ttlString = Str_Asprintf(NULL, "%u", mountInfo->ttl); if (ttlString != NULL) { Str_Strcat(mountEnt.mnt_opts, ",ttl=", MOUNT_OPTS_BUFFER_SIZE); Str_Strcat(mountEnt.mnt_opts, ttlString, MOUNT_OPTS_BUFFER_SIZE); free(ttlString); } else { printf("Could not allocate memory for ttl entry in mtab, " "continuing\n"); } } /* Add the entry and close. */ if (addmntent(mountFile, &mountEnt)) { printf("Could not add entry to mtab, continuing\n"); } endmntent(mountFile); if (mountEnt.mnt_opts) { free(mountEnt.mnt_opts); } } #endif /*----------------------------------------------------------------------------- * * main -- * * Main entry point. Parses the mount options received, makes a call to * mount(2), and handles the results. * * Results: * Zero on success, non-zero on failure. * * Side effects: * May mount an HGFS filesystem. * *----------------------------------------------------------------------------- */ int main(int argc, // IN char *argv[]) // IN { #ifdef VM_HAVE_MTAB Bool doMtab = TRUE; #endif char c; int i; int result = EXIT_FAILURE; int flags = 0; int mntRes = -1; char *optionString = NULL; const char *shareNameHost = NULL; const char *shareNameDir = NULL; struct stat statBuf; HgfsMountInfo mountInfo; char *canonicalizedPath = NULL; size_t pathMax; thisProgram = argv[0]; /* Compute the base name of the program, too. */ thisProgramBase = strrchr(thisProgram, '/'); if (thisProgramBase != NULL) { thisProgramBase++; } else { thisProgramBase = thisProgram; } setpwent(); if (argc < 3) { PrintUsage(); } while ((c = getopt(argc, argv, "hno:vV")) != -1) { switch (c) { case '?': case 'h': PrintUsage(); #ifdef VM_HAVE_MTAB case 'n': doMtab = FALSE; break; #endif case 'o': if (optionString == NULL) { optionString = strdup(optarg); } else { size_t newLength; char *savedString = optionString; newLength = strlen(optionString) + strlen(",") + strlen(optarg) + sizeof '\0'; optionString = realloc(optionString, newLength); if (optionString != NULL) { Str_Strcat(optionString, ",", newLength); Str_Strcat(optionString, optarg, newLength); } else { free(savedString); } } if (optionString == NULL) { printf("Error: could not allocate memory for options\n"); goto out; } break; case 'v': beVerbose = TRUE; break; case 'V': PrintVersion(); default: printf("Error: unknown mount option %c\n", c); PrintUsage(); } } LOG("Original command line: \"%s", thisProgram); for (i = 1; i < argc; i++) { LOG(" %s", argv[i]); } LOG("\"\n"); /* After getopt_long(3), optind is the first non-option argument. */ shareName = argv[optind]; mountPoint = argv[optind + 1]; /* * We canonicalize the mount point to avoid any discrepancies between the actual mount * point and the listed mount point in /etc/mtab (such discrepancies could prevent * umount(8) from removing the mount point from /etc/mtab). */ pathMax = GetPathMax(mountPoint); canonicalizedPath = malloc(pathMax * sizeof *canonicalizedPath); if (canonicalizedPath == NULL) { printf("Error: cannot allocate memory for canonicalized path, " "aborting mount\n"); goto out; } else if (!realpath(mountPoint, canonicalizedPath)) { perror("Error: cannot canonicalize mount point"); goto out; } mountPoint = canonicalizedPath; if (!ParseShareName(shareName, &shareNameHost, &shareNameDir)) { printf("Error: share name is invalid, aborting mount\n"); goto out; } mountInfo.magicNumber = HGFS_SUPER_MAGIC; mountInfo.version = HGFS_PROTOCOL_VERSION; #ifndef sun mountInfo.fmask = 0; mountInfo.dmask = 0; mountInfo.uidSet = FALSE; mountInfo.gidSet = FALSE; mountInfo.ttl = HGFS_DEFAULT_TTL; #if defined(__APPLE__) strlcpy(mountInfo.shareNameHost, shareNameHost, MAXPATHLEN); strlcpy(mountInfo.shareNameDir, shareNameDir, MAXPATHLEN); #else mountInfo.shareNameHost = shareNameHost; mountInfo.shareNameDir = shareNameDir; #endif #endif /* * This'll write the rest of the options into HgfsMountInfo and possibly * modify the flags. */ if (optionString && !ParseOptions(optionString, &mountInfo, &flags)) { printf("Error: could not parse options string\n"); goto out; } /* Do some sanity checks on our desired mount point. */ if (stat(mountPoint, &statBuf)) { perror("Error: cannot stat mount point"); goto out; } if (S_ISDIR(statBuf.st_mode) == 0) { printf("Error: mount point \"%s\" is not a directory\n", mountPoint); goto out; } /* * Must be root in one flavor or another. If we're suid root, only proceed * if the user owns the mountpoint. */ if (geteuid() != 0) { printf("Error: either you're not root, or %s isn't installed SUID\n", thisProgram); goto out; } else if (getuid() != 0 && (getuid() != statBuf.st_uid || (statBuf.st_mode & S_IRWXU) != S_IRWXU)) { printf("Error: for user mounts, user must own the mount point\n"); goto out; } /* Go! */ #if defined(linux) mntRes = mount(shareName, mountPoint, HGFS_NAME, flags, &mountInfo); #elif defined(__FreeBSD__) { struct iovec iov[] = {{"fstype", sizeof("fstype")}, {HGFS_NAME, sizeof(HGFS_NAME)}, {"target", sizeof("target")}, {shareName, strlen(shareName) + 1}, {"fspath", sizeof("fspath")}, {(void *)mountPoint, strlen(mountPoint) + 1}, {"uidSet", sizeof("uidSet")}, {&mountInfo.uidSet, sizeof(mountInfo.uidSet)}, {"uid", sizeof("uid")}, {&mountInfo.uid, sizeof(mountInfo.uid)}, {"gidSet", sizeof("gidSet")}, {&mountInfo.gidSet, sizeof(mountInfo.gidSet)}, {"gid", sizeof("gid")}, {&mountInfo.gid, sizeof(mountInfo.gid)}}; mntRes = nmount(iov, ARRAYSIZE(iov), flags); } #elif defined(__APPLE__) mntRes = mount(HGFS_NAME, mountPoint, flags, &mountInfo); #elif defined(sun) mntRes = mount(mountPoint, mountPoint, MS_DATA | flags, HGFS_NAME, &mountInfo, sizeof mountInfo); #endif if (mntRes) { perror("Error: cannot mount filesystem"); goto out; } result = EXIT_SUCCESS; #ifdef VM_HAVE_MTAB if (doMtab) { UpdateMtab(&mountInfo, flags); } #endif out: free(optionString); free(canonicalizedPath); return result; } open-vm-tools-9.4.0-1280544/hgfsmounter/Makefile.in0000644765153500003110000005160412220061621020044 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ sbin_PROGRAMS = mount.vmhgfs$(EXEEXT) subdir = hgfsmounter DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(sbindir)" PROGRAMS = $(sbin_PROGRAMS) am_mount_vmhgfs_OBJECTS = hgfsmounter.$(OBJEXT) mount_vmhgfs_OBJECTS = $(am_mount_vmhgfs_OBJECTS) mount_vmhgfs_DEPENDENCIES = ../lib/string/libString.la \ ../lib/panicDefault/libPanicDefault.la \ ../lib/panic/libPanic.la ../lib/lock/libLock.la \ ../lib/misc/libMisc.la ../lib/stubs/libStubs.la DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(mount_vmhgfs_SOURCES) DIST_SOURCES = $(mount_vmhgfs_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ mount_vmhgfs_LDADD = ../lib/string/libString.la \ ../lib/panicDefault/libPanicDefault.la \ ../lib/panic/libPanic.la ../lib/lock/libLock.la \ ../lib/misc/libMisc.la ../lib/stubs/libStubs.la mount_vmhgfs_SOURCES = hgfsmounter.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu hgfsmounter/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu hgfsmounter/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ } \ ; done uninstall-sbinPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(sbindir)" && rm -f $$files clean-sbinPROGRAMS: @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list mount.vmhgfs$(EXEEXT): $(mount_vmhgfs_OBJECTS) $(mount_vmhgfs_DEPENDENCIES) $(EXTRA_mount_vmhgfs_DEPENDENCIES) @rm -f mount.vmhgfs$(EXEEXT) $(LINK) $(mount_vmhgfs_OBJECTS) $(mount_vmhgfs_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hgfsmounter.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(sbindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-sbinPROGRAMS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-sbinPROGRAMS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-hook .MAKE: install-am install-exec-am install-strip uninstall-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-sbinPROGRAMS cscopelist ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-exec-hook \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-sbinPROGRAMS install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-hook \ uninstall-sbinPROGRAMS @FREEBSD_TRUE@install-exec-hook: @FREEBSD_TRUE@ mv $(DESTDIR)$(sbindir)/mount.vmhgfs \ @FREEBSD_TRUE@ $(DESTDIR)$(sbindir)/mount_vmhgfs @FREEBSD_TRUE@ -$(MKDIR_P) $(DESTDIR)/sbin @FREEBSD_TRUE@ -$(LN_S) $(DESTDIR)$(sbindir)/mount_vmhgfs \ @FREEBSD_TRUE@ $(DESTDIR)/sbin/mount_vmhgfs &> /dev/null @FREEBSD_TRUE@uninstall-hook: @FREEBSD_TRUE@ rm -f $(DESTDIR)$(sbindir)/mount_vmhgfs @FREEBSD_FALSE@install-exec-hook: @FREEBSD_FALSE@ -$(MKDIR_P) $(DESTDIR)/sbin @FREEBSD_FALSE@ -$(LN_S) $(DESTDIR)$(sbindir)/mount.vmhgfs \ @FREEBSD_FALSE@ $(DESTDIR)/sbin/mount.vmhgfs &> /dev/null @FREEBSD_FALSE@uninstall-hook: @FREEBSD_FALSE@ rm -f $(DESTDIR)/sbin/mount.vmhgfs # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/0000755765153500003110000000000012220061621014176 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/hgfs/0000755765153500003110000000000012220061622015126 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/hgfs/cpNameUtilLinux.c0000644765153500003110000001401312220061556020360 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * cpNameUtilLinux.c * * Linux implementation of CPName utility functions. These are not included * in the main CPName API since they may require other calls on the * resulting CPName to be from the same OS-type. */ /* Some of the headers in cpNameUtil.c cannot be included in driver code */ #if !defined __KERNEL__ && !defined _KERNEL && !defined KERNEL #include "cpNameUtil.h" #include "cpNameUtilInt.h" #if defined __APPLE__ #include "codeset.h" #endif /* defined __APPLE__ */ #include "util.h" /* *---------------------------------------------------------------------------- * * CPNameUtil_ConvertToRoot -- * * Pass through function that calls Linux version of _ConvertToRoot(). * * Performs CPName conversion and such that the result can be converted back * to an absolute path (in the "root" share) by a Linux hgfs server. * * Note that nameIn must contain an absolute path. * * Results: * Size of the output buffer on success, negative value on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int CPNameUtil_ConvertToRoot(char const *nameIn, // IN: buf to convert size_t bufOutSize, // IN: size of the output buffer char *bufOut) // OUT: output buffer { return CPNameUtil_LinuxConvertToRoot(nameIn, bufOutSize, bufOut); } /* *---------------------------------------------------------------------------- * * CPNameUtilConvertUtf8FormCAndD -- * * Helper conversion routine to convert between a CP format name * in unicode form C (precomposed) format which is used by the HGFS * protocol requests and the unicode form D (decomposed) format, * which is used on Mac OS host (everyone else uses form C). * * Results: * TRUE if success result string is converted, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool CPNameUtilConvertUtf8FormCAndD(const char *cpNameToConvert, // IN: size_t cpNameToConvertLen, // IN: includes nul Bool convertToFormC, // IN: char **cpConvertedName, // OUT: size_t *cpConvertedNameLen) // OUT: includes nul { Bool status = TRUE; #if defined __APPLE__ const char *begin; const char *end; const char *next; char *newData = NULL; char *convertedName = NULL; size_t convertedNameLen; uint32 newDataLen = 0; int len; ASSERT(cpNameToConvert); ASSERT(cpConvertedName); ASSERT(cpConvertedNameLen); /* * Get first component. We bypass the higher level CPName_GetComponent * function so we'll have more control over the illegal characters. */ begin = cpNameToConvert; end = cpNameToConvert + cpNameToConvertLen - 1; /* Get the length of this component, and a pointer to the next. */ while ((len = CPName_GetComponent(begin, end, &next)) != 0) { uint32 origNewDataLen = newDataLen; if (len < 0) { status = FALSE; goto exit; } if (convertToFormC) { status = CodeSet_Utf8FormDToUtf8FormC(begin, len, &convertedName, &convertedNameLen); } else { status = CodeSet_Utf8FormCToUtf8FormD(begin, len, &convertedName, &convertedNameLen); } if (!status) { goto exit; } /* * Append this component to our list: allocate one more for NUL. */ newDataLen += convertedNameLen + 1; newData = (char *)Util_SafeRealloc(newData, newDataLen); memcpy(newData + origNewDataLen, convertedName, convertedNameLen); newData[newDataLen - 1] = '\0'; free(convertedName); convertedName = NULL; begin = next; } *cpConvertedName = newData; /* Including nul terminator */ *cpConvertedNameLen = newDataLen; exit: if (!status) { if (newData != NULL) { free(newData); } } #else /* defined __APPLE__ */ /* No conversion required return a copy of what is received. */ *cpConvertedName = Util_SafeCalloc(1, cpNameToConvertLen); memcpy(*cpConvertedName, cpNameToConvert, cpNameToConvertLen); *cpConvertedNameLen = cpNameToConvertLen; #endif /* defined __APPLE__ */ return status; } #endif /* __KERNEL__ */ open-vm-tools-9.4.0-1280544/lib/hgfs/hgfsEscape.c0000644765153500003110000007641312220061556017363 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * hgfsEscape.c -- * * Escape and unescape illegal filenames for different platforms. * */ #ifdef __KERNEL__ # include "driver-config.h" # include #elif defined __FreeBSD__ # if defined _KERNEL # include # define strchr(s,c) index(s,c) # else # include # endif # define memmove(s1,s2,n) bcopy(s2,s1,n) #elif defined __APPLE__ && defined KERNEL # include #elif !defined sun # include # include #else # include #endif #include "vmware.h" #include "hgfsEscape.h" #include "cpName.h" #ifdef _WIN32 #define UNREFERENCED_PARAMETER(P) (P) /* These characters are illegal in Windows file names. */ const char* HGFS_ILLEGAL_CHARS = "/\\*?:\"<>|"; const char* HGFS_SUBSTITUTE_CHARS = "!@#$^&(){}"; /* Last character of a file name in Windows can be neither dot nor space. */ const char* HGFS_ILLEGAL_LAST_CHARS = ". "; /* http://msdn.microsoft.com/en-us/library/aa365247.aspx */ char *HgfsReservedNames[] = {"CON", "PRN", "AUX", "NUL"}; char *HgfsReservedNamesWithNumber[] = {"COM", "LPT"}; #define HGFS_RESERVED_NAME_CHARS_LENGTH 3 #define HGFS_RESERVED_NAME_WITH_NUMBER_CHARS_LENGTH (HGFS_RESERVED_NAME_CHARS_LENGTH + 1) /* Check for special escaping cases - reserved names and illegal last characters. */ #define IS_SPECIAL_CASE_ESCAPE(b,o,l) HgfsIsSpecialCaseEscape(b,o,l) /* Process Windows reserved names. */ #define PROCESS_RESERVED_NAME(b,s,p,o,c) \ if (!HgfsProcessReservedName(b,s,p,o,c)) \ { \ return FALSE; \ } /* Process Windows reserved names. */ #define PROCESS_LAST_CHARACTER(b,s,p,c) \ if (!HgfsProcessLastCharacter(b,s,p,c)) \ { \ return FALSE; \ } #else // _WIN32 #define UNREFERENCED_PARAMETER(P) /* There is no special escape sequences on other than Windows platforms. */ #define IS_SPECIAL_CASE_ESCAPE(b,o,l) FALSE /* There is no reserved names on other then Windows platforms. */ #define PROCESS_RESERVED_NAME(b,s,p,o,c) /* There is no special processing for the last character on non-Windows platforms. */ #define PROCESS_LAST_CHARACTER(b,s,p,c) #if defined __APPLE__ /* These characters are illegal in MAC OS file names. */ const char* HGFS_ILLEGAL_CHARS = "/:"; const char* HGFS_SUBSTITUTE_CHARS = "!&"; #else // __APPLE__ /* These characters are illegal in Linux file names. */ const char* HGFS_ILLEGAL_CHARS = "/"; const char* HGFS_SUBSTITUTE_CHARS = "!"; #endif // __APPLE__ #endif // _WIN32 #define HGFS_ESCAPE_CHAR '%' #define HGFS_ESCAPE_SUBSTITUE_CHAR ']' typedef enum { HGFS_ESCAPE_ILLEGAL_CHARACTER, HGFS_ESCAPE_RESERVED_NAME, HGFS_ESCAPE_ILLEGAL_LAST_CHARACTER, HGFS_ESCAPE_ESCAPE_SEQUENCE, HGFS_ESCAPE_COMPLETE } HgfsEscapeReason; typedef Bool (*HgfsEnumCallback)(char const *bufIn, uint32 offset, HgfsEscapeReason reason, void* context); /* * The structure is used by HgfsAddEscapeCharacter to keep context information between * invocations * All offsets defined in this structure are in characters, not bytes */ typedef struct { uint32 processedOffset; // Offset of the first unprocessed input character uint32 outputBufferLength; // Number of characters in the output buffer uint32 outputOffset; // Number of characters that are already in the output char *outputBuffer; // Pointer to the output buffer } HgfsEscapeContext; static void HgfsEscapeUndoComponent(char *bufIn, uint32 *totalLength); static int HgfsEscapeGetComponentSize(char const *bufIn, uint32 sizeIn); static int HgfsEscapeDoComponent(char const *bufIn, uint32 sizeIn, uint32 sizeBufOut, char *bufOut); /* *----------------------------------------------------------------------------- * * HgfsAddEscapeCharacter -- * * Callback function that is called by HgfsEnumerate to insert an escape sequence * into the input name. * * Results: * TRUE if successful, FALSE if there is an error like the output buffer is * too small. * * Side effects: * Updates the output buffer pointer (stored in the context variable). * *----------------------------------------------------------------------------- */ static Bool HgfsAddEscapeCharacter(char const * bufIn, // IN: input name uint32 offset, // IN: offset that requires escaping HgfsEscapeReason reason, // IN: reason for esaping void *context) // IN/OUT: convertion context { HgfsEscapeContext *escapeContext = (HgfsEscapeContext *)context; uint32 charactersToCopy; uint32 outputSpace; char* illegal; Bool result = TRUE; ASSERT(offset >= escapeContext->processedOffset); // Scanning forward charactersToCopy = offset - escapeContext->processedOffset; if (escapeContext->outputOffset + charactersToCopy > escapeContext->outputBufferLength) { return FALSE; } memcpy(escapeContext->outputBuffer + escapeContext->outputOffset, bufIn + escapeContext->processedOffset, charactersToCopy * sizeof *bufIn); escapeContext->outputOffset += charactersToCopy; escapeContext->processedOffset += charactersToCopy; outputSpace = escapeContext->outputBufferLength - escapeContext->outputOffset; switch(reason) { case HGFS_ESCAPE_ILLEGAL_CHARACTER: if (outputSpace < 2) { return FALSE; } illegal = strchr(HGFS_ILLEGAL_CHARS, bufIn[escapeContext->processedOffset]); escapeContext->processedOffset++; // Skip illegal input character ASSERT(illegal != NULL); escapeContext->outputBuffer[escapeContext->outputOffset] = HGFS_SUBSTITUTE_CHARS[illegal - HGFS_ILLEGAL_CHARS]; escapeContext->outputOffset++; escapeContext->outputBuffer[escapeContext->outputOffset] = HGFS_ESCAPE_CHAR; escapeContext->outputOffset++; break; case HGFS_ESCAPE_RESERVED_NAME: if (outputSpace < 1) { return FALSE; } escapeContext->outputBuffer[escapeContext->outputOffset] = HGFS_ESCAPE_CHAR; escapeContext->outputOffset++; break; case HGFS_ESCAPE_ILLEGAL_LAST_CHARACTER: if (outputSpace < 1) { return FALSE; } escapeContext->outputBuffer[escapeContext->outputOffset] = HGFS_ESCAPE_CHAR; escapeContext->outputOffset++; break; case HGFS_ESCAPE_ESCAPE_SEQUENCE: if (outputSpace < 2) { return FALSE; } escapeContext->processedOffset++; // Skip input esape character escapeContext->outputBuffer[escapeContext->outputOffset] = HGFS_ESCAPE_SUBSTITUE_CHAR; escapeContext->outputOffset++; escapeContext->outputBuffer[escapeContext->outputOffset] = HGFS_ESCAPE_CHAR; escapeContext->outputOffset++; break; case HGFS_ESCAPE_COMPLETE: if (outputSpace < 1) { return FALSE; } escapeContext->outputBuffer[escapeContext->outputOffset] = '\0'; break; default: result = FALSE; ASSERT(FALSE); } return result; } /* *----------------------------------------------------------------------------- * * HgfsCountEscapeChars -- * * Callback function that is called by HgfsEnumerate to count additional characters * that need to be inserted in the input name. * * Results: * TRUE since it never fails. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool HgfsCountEscapeChars(char const *bufIn, // IN: input name uint32 offset, // IN: offset where escape is needed HgfsEscapeReason reason, // IN: reason for escaping void *context) // IN/OUT: context info { UNREFERENCED_PARAMETER(bufIn); UNREFERENCED_PARAMETER(offset); if (reason != HGFS_ESCAPE_COMPLETE) { uint32 *counter = (uint32*)context; (*counter)++; } return TRUE; } #ifdef _WIN32 /* *----------------------------------------------------------------------------- * * HgfsLetterToUpper -- * * Converts lowercase English letters to uppercase. * If the symbol is not a lowercase English letter returns the original character. * * Results: * Converted character. * * Side effects: * None * *----------------------------------------------------------------------------- */ static char HgfsLetterToUpper(char letter) { if (letter >= 'a' && letter <= 'z') { return letter - ('a' - 'A'); } return letter; } /* *----------------------------------------------------------------------------- * * HgfsIsEqualPrefix -- * * Verifies if the string prefix is equal to the given prefix. * It assumes that the prefix includes only uppercase English letters or numbers * and it does not have any international characters. * The string must be either NULL terminated or not shorter then the prefix. * * Results: * TRUE if the uppcased string starts with the given prefix. False otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool HgfsIsEqualPrefix(char const *prefix, // IN: prefix to check char const *string, // IN: input string uint32 prefixLength) // IN: length of the prefix in characters { int i; for (i = 0; i < prefixLength; i++) { ASSERT(prefix[i] > 0 && (prefix[i] < 'a' || prefix[i] > 'z' )); if (prefix[i] != HgfsLetterToUpper(string[i])) { return FALSE; } } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsIsReservedPrefix -- * * Verifies if the name's prefix is one of the reserved names. * * Results: * TRUE if the name's prefix is one of the reserved names. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool HgfsIsReservedPrefix(char const *bufIn) // IN: input name { uint32 i; for (i = 0; i < ARRAYSIZE(HgfsReservedNames); i++) { if (HgfsIsEqualPrefix(HgfsReservedNames[i], bufIn, HGFS_RESERVED_NAME_CHARS_LENGTH)) { return TRUE; } } return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsIsReservedPrefixWithNumber -- * * Verifies if the name's prefix is one of the reserved names with number: * COM1-9 or LPT1-9. * * Results: * TRUE if the name's prefix is one of the reserved names with number. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool HgfsIsReservedPrefixWithNumber(char const *bufIn) // IN: input name { uint32 i; for (i = 0; i < ARRAYSIZE(HgfsReservedNamesWithNumber); i++) { if (HgfsIsEqualPrefix(HgfsReservedNamesWithNumber[i], bufIn, HGFS_RESERVED_NAME_CHARS_LENGTH) && bufIn[HGFS_RESERVED_NAME_CHARS_LENGTH] >= '1' && bufIn[HGFS_RESERVED_NAME_CHARS_LENGTH] <= '9') { return TRUE; } } return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsIsSpecialCaseEscape -- * * Verifies if the escape character is a part of special case escape sequence * that exists only in Windows - escaped reserved name or escaped illegal last * character. * * Results: * TRUE if the name's prefix is one of the reserved names with number. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool HgfsIsSpecialCaseEscape(char const *bufIn, // IN: input name uint32 offset, // IN: offset of the escape character uint32 length) // IN: length of the name in characters { if (offset + 1 == length && strchr(HGFS_ILLEGAL_LAST_CHARS, bufIn[offset - 1]) != NULL) { return TRUE; } if (offset == HGFS_RESERVED_NAME_CHARS_LENGTH && (length == HGFS_RESERVED_NAME_CHARS_LENGTH + 1 || bufIn[offset+1] == '.')) { return HgfsIsReservedPrefix(bufIn); } if (offset == HGFS_RESERVED_NAME_WITH_NUMBER_CHARS_LENGTH && (length == HGFS_RESERVED_NAME_WITH_NUMBER_CHARS_LENGTH + 1 || bufIn[offset+1] == '.')) { return HgfsIsReservedPrefixWithNumber(bufIn); } return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsProcessReservedName -- * * Verifies if the name is one of reserved Windows file names. * If it is a reserved name invokes callback that performs required * processing. * * Results: * TRUE if no processing is required of if processing succeeded, * FALSE if processing failed. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool HgfsProcessReservedName(char const *bufIn, // IN: Unescaped input buffer uint32 sizeIn, // IN: Length of the input HgfsEnumCallback processEscape, // IN: Callack that is invoked // if input is reserved name uint32 *offset, // OUT: New offset in the input void *context) // IN/OUT: Context for callback { /* Look reserved names: CON, PRN, AUX, NUL. */ if (sizeIn >= HGFS_RESERVED_NAME_CHARS_LENGTH && HgfsIsReservedPrefix(bufIn)) { if (HGFS_RESERVED_NAME_CHARS_LENGTH == sizeIn || bufIn[HGFS_RESERVED_NAME_CHARS_LENGTH] == '.') { if (!processEscape(bufIn, HGFS_RESERVED_NAME_CHARS_LENGTH, HGFS_ESCAPE_RESERVED_NAME, context)) { return FALSE; } *offset = HGFS_RESERVED_NAME_CHARS_LENGTH; } } /* Look reserved names with numbers: COM1-9 and LPT1-9. */ if (sizeIn >= HGFS_RESERVED_NAME_WITH_NUMBER_CHARS_LENGTH && HgfsIsReservedPrefixWithNumber(bufIn)) { if (HGFS_RESERVED_NAME_WITH_NUMBER_CHARS_LENGTH == sizeIn || bufIn[HGFS_RESERVED_NAME_WITH_NUMBER_CHARS_LENGTH] == '.') { if (!processEscape(bufIn, HGFS_RESERVED_NAME_WITH_NUMBER_CHARS_LENGTH, HGFS_ESCAPE_RESERVED_NAME, context)) { return FALSE; } *offset = HGFS_RESERVED_NAME_WITH_NUMBER_CHARS_LENGTH; } } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsProcessLastCharacter -- * * Verifies if the trailing character in the name is a valid last character. * In Windows it is illegal to have a file name that ends with dot ('.') or * space (' '). The only exception is "." and ".." directory names. * If the last character is invalid the function invokes a callback to process it. * * Results: * TRUE if no processing is required of if processing succeeded, * FALSE if processing failed. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool HgfsProcessLastCharacter(char const *bufIn, // IN: Unescaped input buffer uint32 sizeIn, // IN: Length of the input HgfsEnumCallback processEscape, // IN: Callack that is invoked // when escaping is needed void *context) // IN/OUT: Callback context { /* If the filename is '.' or '..' we shouldn't escape it. */ if ((sizeIn == 1 && bufIn[0] == '.') || (sizeIn == 2 && bufIn[0] == '.' && bufIn[1] == '.')) { return TRUE; } /* Invoke the callback if the last character is illegal. */ if (strchr(HGFS_ILLEGAL_LAST_CHARS, bufIn[sizeIn - 1]) != NULL) { if (!processEscape(bufIn, sizeIn, HGFS_ESCAPE_ILLEGAL_LAST_CHARACTER, context)) { return FALSE; } } return TRUE; } #endif // WIN32 /* *----------------------------------------------------------------------------- * * HgfsIsEscapeSequence -- * * Verifies if input buffer has an escape sequence at the position * defined by offset. * * Results: * TRUE if there is an escape sequence at the position defined by offset. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool HgfsIsEscapeSequence(char const *bufIn, // IN: input name uint32 offset, // IN: offset of the escape character uint32 length) // IN: length of the name in characters { if (bufIn[offset] == HGFS_ESCAPE_CHAR && offset > 0) { char *substitute; if (bufIn[offset - 1] == HGFS_ESCAPE_SUBSTITUE_CHAR && offset > 1) { /* * Possibly a valid sequence, check it must be preceded with a substitute * character or another escape-escape character. Otherwise, HGFS did * not generate this sequence and should leave it alone. */ if (bufIn[offset - 2] == HGFS_ESCAPE_SUBSTITUE_CHAR) { return TRUE; } substitute = strchr(HGFS_SUBSTITUTE_CHARS, bufIn[offset - 2]); if (substitute != NULL) { return TRUE; } } substitute = strchr(HGFS_SUBSTITUTE_CHARS, bufIn[offset - 1]); if (substitute != NULL) { return TRUE; } return IS_SPECIAL_CASE_ESCAPE(bufIn,offset,length); } return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsEscapeEnumerate -- * * The function scans the input buffer and calls processEscape callback for every * place in the input buffer which require escaping. * * Callback does the required processing. There are two different callbacks - * one counts extra symbols that are needed for escaping and another produces * escaped output name based on input name. * * 1. The first function calculates number of extra characters. It just increments * a counter which is passed to it in context variable every time it is called * for the reason different from "complete processing" assuming that * exactly one extra character is required to escape any invalid input. * * 2. The second function produces output name by copying everything from input * name into the output name up to the place which require escaping and * then inserts appropriate escape sequence into the output. It keeps track of its * progress and keeps pointer to the output buffer in the context variable. * HgfsEscapeEnumerate calls calback function one more time at the end of the * input buffer to let callback finish processing of the input (for example copy * the rest of the name after the last escape sequence from input buffer to * output buffer). * * Results: * TRUE if the input has been processed successfully by the callback, false otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool HgfsEscapeEnumerate(char const *bufIn, // IN: Buffer with unescaped input uint32 sizeIn, // IN: Number of input *characters* HgfsEnumCallback processEscape, // IN: Callack that is invoked every // time escaping is required void *context) // IN/OUT: Context for processEscape { /* First look for invalid characters in the input name. */ uint32 i, offset = 0; if (sizeIn == 0) { return TRUE; } ASSERT(processEscape); PROCESS_RESERVED_NAME(bufIn, sizeIn, processEscape, &offset, context); for (i = offset; i < sizeIn; i++) { if (strchr(HGFS_ILLEGAL_CHARS, bufIn[i]) != NULL) { if (!processEscape(bufIn, i, HGFS_ESCAPE_ILLEGAL_CHARACTER, context)) { return FALSE; } } else if (HgfsIsEscapeSequence(bufIn, i, sizeIn)) { if (!processEscape(bufIn, i, HGFS_ESCAPE_ESCAPE_SEQUENCE, context)) { return FALSE; } } } PROCESS_LAST_CHARACTER(bufIn, sizeIn, processEscape, context); if (!processEscape(bufIn, sizeIn, HGFS_ESCAPE_COMPLETE, context)) { return FALSE; } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsEscape_Do -- * * Escape any characters that are not legal in a windows filename. * Escape reserved file names that can't be used in Windows. * We also of course have to escape the escape character, which is "%", * when it is part of a character sequence that would require unescaping * * sizeBufOut must account for the NUL terminator. * * Results: * On success, the size (excluding the NUL terminator) of the * escaped, NUL terminated buffer. * On failure (bufOut not big enough to hold result), negative value. * * Side effects: * None * *----------------------------------------------------------------------------- */ int HgfsEscape_Do(char const *bufIn, // IN: Buffer with unescaped input uint32 sizeIn, // IN: Size of input buffer uint32 sizeBufOut, // IN: Size of output buffer char *bufOut) // OUT: Buffer for escaped output { const char *currentComponent = bufIn; uint32 sizeLeft = sizeBufOut; char *outPointer = bufOut; const char *end = bufIn + sizeIn; const char *next; ASSERT(sizeIn > 0); if (bufIn[sizeIn - 1] == '\0') { /* * In some cases a NUL terminated string is passed to HgfsEscape_Do * so it make sense to support such input even if CPName_GetComponent * does not. Detect this case and make the input compliant with * CPName_GetComponent by removing terminating NUL. */ end--; sizeIn--; } /* * Absolute symbolic link name starts with the '\0'. HgfsEscapeDo needs to work * with such names. Leading NULL symbols should be skipped here since * CPName_GetComponent does not support such names. */ while (*currentComponent == '\0' && currentComponent - bufIn < sizeIn) { currentComponent++; sizeLeft--; *outPointer++ = '\0'; } while (currentComponent - bufIn < sizeIn) { int escapedLength; int componentSize = CPName_GetComponent(currentComponent, end, &next); if (componentSize < 0) { return componentSize; } escapedLength = HgfsEscapeDoComponent(currentComponent, componentSize, sizeLeft, outPointer); if (escapedLength < 0) { return escapedLength; } currentComponent = next; sizeLeft -= escapedLength + 1; outPointer += escapedLength + 1; } return (int) (outPointer - bufOut) - 1; // Do not count the last NUL terminator } /* *----------------------------------------------------------------------------- * * HgfsEscape_GetSize -- * * Calculates required size in bytes for the buffer that is needed to hold escaped * cross platform path name. Returns 0 if no escaping is required. * * Results: * On success, the size (excluding the NUL terminator) of the * escaped, NUL terminated buffer. * Returns 0 if the name is a valid Windows file name. * * Side effects: * None * *----------------------------------------------------------------------------- */ int HgfsEscape_GetSize(char const *bufIn, // IN: Buffer with unescaped input uint32 sizeIn) // IN: Size of the input buffer { uint32 result = 0; const char *currentComponent = bufIn; const char *end = bufIn + sizeIn; const char *next; if (sizeIn == 0) { // No need toescape empty name. return 0; } if (bufIn[sizeIn - 1] == '\0') { /* * In some cases a NUL terminated string is passed to HgfsEscape_GeSize * so it make sense to support such input even if CPName_GetComponent * does not. Detect this case and make the input compliant with * CPName_GetComponent by removing terminating NUL. */ end--; sizeIn--; } /* Skip leading NULs to keep CPName_GetComponent happy. */ while (*currentComponent == '\0' && currentComponent - bufIn < sizeIn) { currentComponent++; } while (currentComponent - bufIn < sizeIn) { int componentSize = CPName_GetComponent(currentComponent, end, &next); if (componentSize < 0) { Log("%s: failed to calculate escapde name size - name is invalid\n", __FUNCTION__); return -1; } result += HgfsEscapeGetComponentSize(currentComponent, componentSize); currentComponent = next; } return (result == 0) ? 0 : result + sizeIn; } /* *----------------------------------------------------------------------------- * * HgfsEscape_Undo -- * * Unescape a buffer that was escaped using HgfsEscapeBuffer. * * The unescaping is done in place in the input buffer, and * can not fail. * * Results: * The size (excluding the NUL terminator) of the unescaped, NUL * terminated buffer. * * Side effects: * None * *----------------------------------------------------------------------------- */ int HgfsEscape_Undo(char *bufIn, // IN: Characters to be unescaped uint32 sizeIn) // IN: Number of characters in bufIn { uint32 componentSize = strlen(bufIn) + 1; uint32 unprocessedSize = sizeIn + 1; uint32 result = 0; char *currentComponent = bufIn; while (currentComponent != NULL) { HgfsEscapeUndoComponent(currentComponent, &unprocessedSize); componentSize = strlen(currentComponent) + 1; // Unescaped size result += componentSize; if (unprocessedSize > 1) { currentComponent = currentComponent + componentSize; componentSize = strlen(currentComponent) + 1; // Size of the next component } else { currentComponent = NULL; } } return result - 1; } /* *----------------------------------------------------------------------------- * * HgfsEscapeUndoComponent -- * * Unescape a buffer that was escaped using HgfsEscapeBuffer. * * The unescaping is done in place in the input buffer, and * can not fail. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsEscapeUndoComponent(char *bufIn, // IN: Characters to be unescaped uint32 *unprocessedLength) // IN: Unprocessed characters // in the whole name { size_t offset; size_t sizeIn; char* curOutBuffer; char* escapePointer; ASSERT(bufIn != NULL); curOutBuffer = bufIn; sizeIn = strlen(curOutBuffer); escapePointer = strchr(curOutBuffer, HGFS_ESCAPE_CHAR); while (escapePointer != NULL) { offset = escapePointer - bufIn; if (HgfsIsEscapeSequence(bufIn, offset, sizeIn)) { char* substitute = strchr(HGFS_SUBSTITUTE_CHARS, bufIn[offset - 1]); if (substitute != NULL) { bufIn[offset - 1] = HGFS_ILLEGAL_CHARS[substitute - HGFS_SUBSTITUTE_CHARS]; } else if (bufIn[offset - 1] == HGFS_ESCAPE_SUBSTITUE_CHAR) { bufIn[offset - 1] = HGFS_ESCAPE_CHAR; } memmove(escapePointer, escapePointer + 1, (*unprocessedLength) - offset - 1); (*unprocessedLength)--; sizeIn--; if (sizeIn > 0) { escapePointer = strchr(escapePointer, HGFS_ESCAPE_CHAR); } else { escapePointer = NULL; } } else { escapePointer = strchr(escapePointer + 1, HGFS_ESCAPE_CHAR); } } ASSERT((*unprocessedLength) > sizeIn); (*unprocessedLength) -= sizeIn + 1; } /* *----------------------------------------------------------------------------- * * HgfsEscapeDoComponent -- * * Escape any characters that are not legal in a windows filename. * Escape reserved file names that can't be used in Windows. * We also of course have to escape the escape character, which is "%", * when it is part of a character sequence that would require unescaping * * sizeBufOut must account for the NUL terminator. * * Results: * On success, the size (excluding the NUL terminator) of the * escaped, NUL terminated buffer. * On failure (bufOut not big enough to hold result), negative value. * * Side effects: * None * *----------------------------------------------------------------------------- */ int HgfsEscapeDoComponent(char const *bufIn, // IN: Buffer with unescaped input uint32 sizeIn, // IN: Size of input buffer uint32 sizeBufOut, // IN: Size of output buffer char *bufOut) // OUT: Buffer for escaped output { HgfsEscapeContext conversionContext; conversionContext.processedOffset = 0; conversionContext.outputBufferLength = sizeBufOut / sizeof *bufOut; conversionContext.outputOffset = 0; conversionContext.outputBuffer = bufOut; if (!HgfsEscapeEnumerate(bufIn, sizeIn, HgfsAddEscapeCharacter, &conversionContext)) { return -1; } return conversionContext.outputOffset * sizeof *bufOut; } /* *----------------------------------------------------------------------------- * * HgfsEscapeGetComponentSize -- * * Calculates number of addtitional characters that are needed to escape * name for one NUL terminated component of the path. * * Results: * Number of additional escape characters needed to escape the name. * Returns 0 if no escaping is required. * * Side effects: * None * *----------------------------------------------------------------------------- */ int HgfsEscapeGetComponentSize(char const *bufIn, // IN: Buffer with unescaped input uint32 sizeIn) // IN: Size of the in input buffer { int result = 0; HgfsEscapeEnumerate(bufIn, sizeIn, HgfsCountEscapeChars, &result); return result; } open-vm-tools-9.4.0-1280544/lib/hgfs/hgfsUtil.c0000644765153500003110000002003412220061556017064 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * hgfsUtil.c -- * * Utility routines used by both HGFS servers and clients, such as * conversion routines between Unix time and Windows NT time. * The former is in units of seconds since midnight 1/1/1970, while the * latter is in units of 100 nanoseconds since midnight 1/1/1601. */ /* * hgfsUtil.h must be included before vm_basic_asm.h, as hgfsUtil.h * includes kernel headers on Linux. That is, vmware.h must come after * hgfsUtil.h. */ #include "hgfsUtil.h" #include "vmware.h" #include "vm_basic_asm.h" #ifndef _WIN32 /* * NT time of the Unix epoch: * midnight January 1, 1970 UTC */ #define UNIX_EPOCH ((((uint64)369 * 365) + 89) * 24 * 3600 * 10000000) /* * NT time of the Unix 32 bit signed time_t wraparound: * 03:14:07 January 19, 2038 UTC */ #define UNIX_S32_MAX (UNIX_EPOCH + (uint64)0x80000000 * 10000000) /* *----------------------------------------------------------------------------- * * HgfsConvertToNtTime -- * * Convert from Unix time to Windows NT time. * * Results: * The time in Windows NT format. * * Side effects: * None * *----------------------------------------------------------------------------- */ uint64 HgfsConvertToNtTime(time_t unixTime, // IN: Time in Unix format (seconds) long nsec) // IN: nanoseconds { return (uint64)unixTime * 10000000 + nsec / 100 + UNIX_EPOCH; } /* *----------------------------------------------------------------------------- * * HgfsConvertFromNtTimeNsec -- * * Convert from Windows NT time to Unix time. If NT time is outside of * UNIX time range (1970-2038), returned time is nearest time valid in * UNIX. * * Results: * 0 on success * non-zero if NT time is outside of valid range for UNIX * * Side effects: * None * *----------------------------------------------------------------------------- */ int HgfsConvertFromNtTimeNsec(struct timespec *unixTime, // OUT: Time in UNIX format uint64 ntTime) // IN: Time in Windows NT format { #if !defined(VM_X86_64) && !defined(__arm__) uint32 sec; uint32 nsec; ASSERT(unixTime); /* We assume that time_t is 32bit */ ASSERT_ON_COMPILE(sizeof (unixTime->tv_sec) == 4); /* Cap NT time values that are outside of Unix time's range */ if (ntTime >= UNIX_S32_MAX) { unixTime->tv_sec = 0x7FFFFFFF; unixTime->tv_nsec = 0; return 1; } #else ASSERT(unixTime); #endif if (ntTime < UNIX_EPOCH) { unixTime->tv_sec = 0; unixTime->tv_nsec = 0; return -1; } #if !defined(VM_X86_64) && !defined(__arm__) Div643232(ntTime - UNIX_EPOCH, 10000000, &sec, &nsec); unixTime->tv_sec = sec; unixTime->tv_nsec = nsec * 100; #else unixTime->tv_sec = (ntTime - UNIX_EPOCH) / 10000000; unixTime->tv_nsec = ((ntTime - UNIX_EPOCH) % 10000000) * 100; #endif return 0; } /* *----------------------------------------------------------------------------- * * HgfsConvertFromNtTime -- * * Convert from Windows NT time to Unix time. * * Results: * 0 on success * nonzero if time is not representable on UNIX * * Side effects: * None * *----------------------------------------------------------------------------- */ int HgfsConvertFromNtTime(time_t *unixTime, // OUT: Time in UNIX format uint64 ntTime) // IN: Time in Windows NT format { struct timespec tm; int ret; ret = HgfsConvertFromNtTimeNsec(&tm, ntTime); *unixTime = tm.tv_sec; return ret; } #endif /* !def(_WIN32) */ #undef UNIX_EPOCH #undef UNIX_S32_MAX /* *----------------------------------------------------------------------------- * * HgfsConvertFromInternalStatus -- * * This function converts between a platform-specific status code and a * cross-platform status code to be sent down the wire. * * Results: * Converted status code. * * Side effects: * None. * *----------------------------------------------------------------------------- */ #ifdef _WIN32 HgfsStatus HgfsConvertFromInternalStatus(HgfsInternalStatus status) // IN { switch(status) { case ERROR_SUCCESS: return HGFS_STATUS_SUCCESS; case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: return HGFS_STATUS_NO_SUCH_FILE_OR_DIR; case ERROR_INVALID_HANDLE: return HGFS_STATUS_INVALID_HANDLE; case ERROR_ALREADY_EXISTS: case ERROR_FILE_EXISTS: return HGFS_STATUS_FILE_EXISTS; case ERROR_DIR_NOT_EMPTY: return HGFS_STATUS_DIR_NOT_EMPTY; case RPC_S_PROTOCOL_ERROR: return HGFS_STATUS_PROTOCOL_ERROR; case ERROR_ACCESS_DENIED: return HGFS_STATUS_ACCESS_DENIED; case ERROR_INVALID_NAME: return HGFS_STATUS_INVALID_NAME; case ERROR_SHARING_VIOLATION: return HGFS_STATUS_SHARING_VIOLATION; case ERROR_DISK_FULL: case ERROR_HANDLE_DISK_FULL: return HGFS_STATUS_NO_SPACE; case ERROR_NOT_SUPPORTED: return HGFS_STATUS_OPERATION_NOT_SUPPORTED; case ERROR_INVALID_PARAMETER: return HGFS_STATUS_INVALID_PARAMETER; case ERROR_NOT_SAME_DEVICE: return HGFS_STATUS_NOT_SAME_DEVICE; case ERROR_FILENAME_EXCED_RANGE: return HGFS_STATUS_NAME_TOO_LONG; case ERROR_CONNECTION_INVALID: // HGFS_ERROR_STALE_SESSION return HGFS_STATUS_STALE_SESSION; case ERROR_MAX_SESSIONS_REACHED: return HGFS_STATUS_TOO_MANY_SESSIONS; case ERROR_INTERNAL_ERROR: case HGFS_INTERNAL_STATUS_ERROR: default: return HGFS_STATUS_GENERIC_ERROR; } } #else /* Win32 */ HgfsStatus HgfsConvertFromInternalStatus(HgfsInternalStatus status) // IN { switch(status) { case 0: return HGFS_STATUS_SUCCESS; case ENOENT: return HGFS_STATUS_NO_SUCH_FILE_OR_DIR; case EBADF: return HGFS_STATUS_INVALID_HANDLE; case EPERM: return HGFS_STATUS_OPERATION_NOT_PERMITTED; case EISDIR: case EEXIST: return HGFS_STATUS_FILE_EXISTS; case ENOTDIR: return HGFS_STATUS_NOT_DIRECTORY; case ENOTEMPTY: return HGFS_STATUS_DIR_NOT_EMPTY; case EPROTO: return HGFS_STATUS_PROTOCOL_ERROR; case EACCES: return HGFS_STATUS_ACCESS_DENIED; case EINVAL: return HGFS_STATUS_INVALID_NAME; case ENOSPC: return HGFS_STATUS_NO_SPACE; case EOPNOTSUPP: return HGFS_STATUS_OPERATION_NOT_SUPPORTED; case ENAMETOOLONG: return HGFS_STATUS_NAME_TOO_LONG; case EPARAMETERNOTSUPPORTED: return HGFS_STATUS_INVALID_PARAMETER; case EXDEV: return HGFS_STATUS_NOT_SAME_DEVICE; case ENETRESET: // HGFS_ERROR_STALE_SESSION return HGFS_STATUS_STALE_SESSION; case ECONNREFUSED: return HGFS_STATUS_TOO_MANY_SESSIONS; case EINTERNAL: case HGFS_INTERNAL_STATUS_ERROR: default: return HGFS_STATUS_GENERIC_ERROR; } } #endif open-vm-tools-9.4.0-1280544/lib/hgfs/cpNameUtil.c0000644765153500003110000002552712220061556017354 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * cpNameUtil.c * * Common implementations of CPName utility functions. */ /* Some of the headers below cannot be included in driver code */ #if !defined __KERNEL__ && !defined _KERNEL && !defined KERNEL #include "cpNameUtil.h" #include "hgfsServerPolicy.h" #include "hgfsVirtualDir.h" #include "util.h" #include "vm_assert.h" #include "str.h" #include "cpNameUtilInt.h" #define WIN_DIRSEPC '\\' #define WIN_DIRSEPS "\\" /* *---------------------------------------------------------------------------- * * CPNameUtil_Strrchr -- * * Performs strrchr(3) on a CPName path. * * Results: * Pointer to last occurrence of searchChar in cpNameIn if found, NULL if * not found. * * Side effects: * None. * *---------------------------------------------------------------------------- */ char * CPNameUtil_Strrchr(char const *cpNameIn, // IN: CPName path to search size_t cpNameInSize, // IN: Size of CPName path char searchChar) // IN: Character to search for { ssize_t index; ASSERT(cpNameIn); ASSERT(cpNameInSize > 0); for (index = cpNameInSize - 1; cpNameIn[index] != searchChar && index >= 0; index--); return (index < 0) ? NULL : (char *)(cpNameIn + index); } /* *---------------------------------------------------------------------------- * * CPNameUtil_LinuxConvertToRoot -- * * Performs CPName conversion and such that the result can be converted back * to an absolute path (in the "root" share) by a Linux hgfs server. * * Note that nameIn must contain an absolute path. * * Results: * Size of the output buffer on success, negative value on error * * Side effects: * None. * *---------------------------------------------------------------------------- */ int CPNameUtil_LinuxConvertToRoot(char const *nameIn, // IN: buf to convert size_t bufOutSize, // IN: size of the output buffer char *bufOut) // OUT: output buffer { const size_t shareNameSize = HGFS_STR_LEN(HGFS_SERVER_POLICY_ROOT_SHARE_NAME); int result; ASSERT(nameIn); ASSERT(bufOut); if (bufOutSize <= shareNameSize) { return -1; } /* Prepend the name of the "root" share directly in the output buffer */ memcpy(bufOut, HGFS_SERVER_POLICY_ROOT_SHARE_NAME, shareNameSize); bufOut[shareNameSize] = '\0'; result = CPName_LinuxConvertTo(nameIn, bufOutSize - shareNameSize - 1, bufOut + shareNameSize + 1); /* Return either the same error code or the correct size */ return (result < 0) ? result : (int)(result + shareNameSize + 1); } /* *---------------------------------------------------------------------------- * * CPNameUtil_WindowsConvertToRoot -- * * Performs CPName conversion and appends necessary strings ("root" and * "drive"|"unc") so that the result can be converted back to an absolute * path (in the "root" share) by a Windows hgfs server. * * Note that nameIn must contain an absolute path. * * Results: * Size of the output buffer on success, negative value on error * * Side effects: * None. * *---------------------------------------------------------------------------- */ int CPNameUtil_WindowsConvertToRoot(char const *nameIn, // IN: buf to convert size_t bufOutSize, // IN: size of the output buffer char *bufOut) // OUT: output buffer { const char partialName[] = HGFS_SERVER_POLICY_ROOT_SHARE_NAME; const size_t partialNameLen = HGFS_STR_LEN(HGFS_SERVER_POLICY_ROOT_SHARE_NAME); const char *partialNameSuffix = ""; size_t partialNameSuffixLen; char *fullName; size_t fullNameLen; size_t nameLen; int result; ASSERT(nameIn); ASSERT(bufOut); /* * Create the full name. Note that Str_Asprintf should not be * used here as it uses FormatMessages which interprets 'data', a UTF-8 * string, as a string in the current locale giving wrong results. */ /* * Is this file path a UNC path? */ if (nameIn[0] == WIN_DIRSEPC && nameIn[1] == WIN_DIRSEPC) { partialNameSuffix = WIN_DIRSEPS HGFS_UNC_DIR_NAME WIN_DIRSEPS; partialNameSuffixLen = HGFS_STR_LEN(WIN_DIRSEPS) + HGFS_STR_LEN(HGFS_UNC_DIR_NAME) + HGFS_STR_LEN(WIN_DIRSEPS); } else { partialNameSuffix = WIN_DIRSEPS HGFS_DRIVE_DIR_NAME WIN_DIRSEPS; partialNameSuffixLen = HGFS_STR_LEN(WIN_DIRSEPS) + HGFS_STR_LEN(HGFS_DRIVE_DIR_NAME) + HGFS_STR_LEN(WIN_DIRSEPS); } /* Skip any path separators at the beginning of the input string */ while (*nameIn == WIN_DIRSEPC) { nameIn++; } nameLen = strlen(nameIn); fullNameLen = partialNameLen + partialNameSuffixLen + nameLen; fullName = (char *)Util_SafeMalloc(fullNameLen + 1); memcpy(fullName, partialName, partialNameLen); memcpy(fullName + partialNameLen, partialNameSuffix, partialNameSuffixLen); if (nameIn[1] == ':') { /* * If the name is in format ":" strip out ':' from it * because the rest of the code assumes that driver letter in a * platform independent name is represented by a single character without colon. */ fullName[partialNameLen + partialNameSuffixLen] = nameIn[0]; memcpy(fullName + partialNameLen + partialNameSuffixLen + 1, nameIn + 2, nameLen - 2); fullNameLen--; } else { memcpy(fullName + partialNameLen + partialNameSuffixLen, nameIn, nameLen); } fullName[fullNameLen] = '\0'; /* CPName_ConvertTo strips out the ':' character */ result = CPName_WindowsConvertTo(fullName, bufOutSize, bufOut); free(fullName); return result; } /* *---------------------------------------------------------------------------- * * CPNameUtil_Utf8FormHostToUtf8FormC -- * * Convert CPname to form C (precomposed) which is used by the HGFS * protocol from host preferred format. On Mac hosts the current format * is unicode form D, so conversion is required, others the current * format is the same. * * Input/output name lengths include the nul-terminator so that the * conversion routine will include the final character when breaking * up the CPName into it's individual components. * * * Results: * TRUE if success result string is in form C format, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool CPNameUtil_Utf8FormHostToUtf8FormC(const char *cpNameToConvert, // IN: size_t cpNameToConvertLen, // IN: includes nul char **cpUtf8FormCName, // OUT: size_t *cpUtf8FormCNameLen) // OUT: includes nul { return CPNameUtilConvertUtf8FormCAndD(cpNameToConvert, cpNameToConvertLen, TRUE, cpUtf8FormCName, cpUtf8FormCNameLen); } /* *---------------------------------------------------------------------------- * * CPNameUtil_Utf8FormCToUtf8FormHost -- * * Convert from CP unicode form C (decomposed) name used by the HGFS * protocol to the host preferred format. On Mac OS is unicode form D * (precomposed), everyone else this stays as form C (precomposed). * * Input/output name lengths include the nul-terminator so that the * conversion routine will include the final character when breaking * up the CPName into it's individual components. * * Results: * TRUE if success result string is in CP format, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool CPNameUtil_Utf8FormCToUtf8FormHost(const char *cpUtf8FormCName, // IN: size_t cpUtf8FormCNameLen, // IN: includes nul char **cpConvertedName, // OUT: size_t *cpConvertedNameLen) // OUT: includes nul { return CPNameUtilConvertUtf8FormCAndD(cpUtf8FormCName, cpUtf8FormCNameLen, FALSE, cpConvertedName, cpConvertedNameLen); } /* *---------------------------------------------------------------------------- * * CPNameUitl_CharReplace -- * * A simple function to replace all oldChar's with newChar's in a binary * buffer. This is used for either replacing NULL with local DIRSPEC to * convert from relative cross-platform name to local relative name, or * replacing local DIRSEPC with NULL to convert from local relative name * to relative cross-platform file name * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void CPNameUtil_CharReplace(char *buf, // IN/OUT size_t bufSize, // IN char oldChar, // IN char newChar) // IN { size_t i; ASSERT(buf); for (i = 0; i < bufSize; i++) { if (buf[i] == oldChar) { buf[i] = newChar; } } } #endif /* __KERNEL__ */ open-vm-tools-9.4.0-1280544/lib/hgfs/cpNameLinux.c0000644765153500003110000001275112220061556017531 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * cpNameLinux.c -- * * Linux implementation of cross-platform name conversion * routines used by hgfs. [bac] * */ #if defined sun && !defined SOL9 #include #endif #include "cpName.h" #include "cpNameInt.h" #include "vm_assert.h" #include "hgfsEscape.h" /* *---------------------------------------------------------------------- * * CPName_ConvertFrom -- * * Converts a cross-platform name representation into a string for * use in the local filesystem. * * Results: * Length (not including NUL termination) >= 0 of resulting * string on success. * Negative error on failure (the converted string did not fit in * the buffer provided or the input was invalid). * * Side effects: * None * *---------------------------------------------------------------------- */ int CPName_ConvertFrom(char const **bufIn, // IN/OUT: Input to convert size_t *inSize, // IN/OUT: Size of input size_t *outSize, // IN/OUT: Size of output buffer char **bufOut) // IN/OUT: Output buffer { ASSERT(bufIn); ASSERT(inSize); ASSERT(outSize); ASSERT(bufOut); return CPNameEscapeAndConvertFrom(bufIn, inSize, outSize, bufOut, '/'); } /* *---------------------------------------------------------------------- * * CPName_ConvertFromRoot -- * * Append the appropriate prefix to the output buffer for accessing * the root of the local filesystem. CPName_ConvertFrom prepends * leading path separators before each path component, but only * when the next component has nonzero length, so we still need to * special case this for Linux. * * The pointers and sizes are updated appropriately. * * Results: * Status of name conversion * * Side effects: * None * *---------------------------------------------------------------------- */ HgfsNameStatus CPName_ConvertFromRoot(char const **bufIn, // IN/OUT: Input to convert size_t *inSize, // IN/OUT: Size of input size_t *outSize, // IN/OUT: Size of output buffer char **bufOut) // IN/OUT: Output buffer { char const *next; char *out; int len; ASSERT(bufIn); ASSERT(inSize); ASSERT(outSize); ASSERT(bufOut); out = *bufOut; /* * Get first component */ len = CPName_GetComponent(*bufIn, *bufIn + *inSize, &next); if (len < 0) { Log("%s: get first component failed\n", __FUNCTION__); return HGFS_NAME_STATUS_FAILURE; } /* Space for leading '/' plus NUL termination */ if (*outSize < len + 2) { return HGFS_NAME_STATUS_FAILURE; } /* Put a leading '/' in the output buffer either way */ *out++ = '/'; memcpy(out, *bufIn, len); out += len; /* NUL terminate */ *out = '\0'; *inSize -= next - *bufIn; *outSize -= out - *bufOut; *bufIn = next; *bufOut = out; return HGFS_NAME_STATUS_COMPLETE; } /* *---------------------------------------------------------------------------- * * CPName_ConvertTo -- * * Wrapper function that calls the Linux implementation of _ConvertTo(). * * Makes a cross-platform name representation from the Linux path input * string and writes it into the output buffer. * If the name being converter may be a result a of name escaping the * function performs unescaping. HGFS convention is to always exchange * unescaped names between guest and host and to perform necessary * name escaping on both ends. * * Results: * On success, returns the number of bytes used in the * cross-platform name, NOT including the final terminating NUL * character. On failure, returns a negative error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int CPName_ConvertTo(char const *nameIn, // IN: Buf to convert size_t bufOutSize, // IN: Size of the output buffer char *bufOut) // OUT: Output buffer { int result; result = CPName_LinuxConvertTo(nameIn, bufOutSize, bufOut); return result; } open-vm-tools-9.4.0-1280544/lib/hgfs/cpNameLite.c0000644765153500003110000000623512220061556017327 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * cpNameLite.c -- * * Shared portions of cross-platform name conversion routines used * by hgfs. Unlike the real CP name conversion routines, these ones * just convert path separators to nul characters and vice versa. * */ #include "cpNameLite.h" #include "vm_assert.h" /* *---------------------------------------------------------------------- * * CPNameLite_ConvertTo -- * * Makes a cross-platform lite name representation from the input * string. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ void CPNameLite_ConvertTo(char *bufIn, // IN/OUT: Input to convert size_t inSize, // IN: Size of input buffer char pathSep) // IN: Path separator { size_t pos; ASSERT(bufIn); for (pos = 0; pos < inSize; pos++) { if (bufIn[pos] == pathSep) { bufIn[pos] = '\0'; } } } /* *---------------------------------------------------------------------- * * CPNameLite_ConvertFrom -- * * Converts a cross-platform lite name representation into a string for * use in the local filesystem. This is a cross-platform * implementation and takes the path separator as an * argument. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ void CPNameLite_ConvertFrom(char *bufIn, // IN/OUT: Input to convert size_t inSize, // IN: Size of input buffer char pathSep) // IN: Path separator { size_t pos; ASSERT(bufIn); for (pos = 0; pos < inSize; pos++) { if (bufIn[pos] == '\0') { bufIn[pos] = pathSep; } } } open-vm-tools-9.4.0-1280544/lib/hgfs/Makefile.am0000644765153500003110000000224012220061556017166 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libHgfs.la libHgfs_la_SOURCES = libHgfs_la_SOURCES += cpName.c libHgfs_la_SOURCES += cpNameLite.c libHgfs_la_SOURCES += cpNameLinux.c libHgfs_la_SOURCES += cpNameUtil.c libHgfs_la_SOURCES += cpNameUtilLinux.c libHgfs_la_SOURCES += hgfsUtil.c libHgfs_la_SOURCES += hgfsEscape.c open-vm-tools-9.4.0-1280544/lib/hgfs/cpNameInt.h0000644765153500003110000000520312220061556017163 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * cpNameInt.h -- * * Cross-platform name format used by hgfs. * */ #ifndef __CP_NAME_INT_H__ #define __CP_NAME_INT_H__ #include "vm_basic_types.h" /* * Used by CPName_ConvertFrom */ int CPNameConvertFrom(char const **bufIn, // IN/OUT: Input to convert size_t *inSize, // IN/OUT: Size of input size_t *outSize, // IN/OUT: Size of output buffer char **bufOut, // IN/OUT: Output buffer char pathSep); // IN: Path separator character int CPNameEscapeAndConvertFrom(char const **bufIn, // IN/OUT: Input to convert size_t *inSize, // IN/OUT: Size of input size_t *outSize, // IN/OUT: Size of output buffer char **bufOut, // IN/OUT: Output buffer char pathSep); // IN: Path separator character /* * Common code for CPName_ConvertTo */ int CPNameConvertTo(char const *nameIn, // IN: Buf to convert size_t bufOutSize, // IN: Size of the output buffer char *bufOut, // OUT: Output buffer char pathSep); // IN: path separator to use #endif /* __CP_NAME_INT_H__ */ open-vm-tools-9.4.0-1280544/lib/hgfs/cpName.c0000644765153500003110000003255112220061556016511 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * cpName.c -- * * Shared portions of cross-platform name conversion routines used * by hgfs. [bac] * */ #ifdef sun #include #endif #include "cpName.h" #include "cpNameInt.h" #include "vm_assert.h" #include "hgfsEscape.h" /* *---------------------------------------------------------------------- * * CPName_GetComponent -- * * Get the next component of the CP name. * * Returns the length of the component starting with the begin * pointer, and a pointer to the next component in the buffer, if * any. The "next" pointer is set to "end" if there is no next * component. * * Results: * length (not including NUL termination) >= 0 of next * component on success. * error < 0 on failure (invalid component). * * Side effects: * None * *---------------------------------------------------------------------- */ int CPName_GetComponent(char const *begin, // IN: Beginning of buffer char const *end, // IN: End of buffer char const **next) // OUT: Start of next component { char const *walk; char const *myNext; size_t len; ASSERT(begin); ASSERT(end); ASSERT(next); ASSERT(begin <= end); for (walk = begin; ; walk++) { if (walk == end) { /* End of buffer. No NUL was found */ myNext = end; break; } if (*walk == '\0') { /* Found a NUL */ if (walk == begin) { Log("%s: error: first char can't be NUL\n", __FUNCTION__); return -1; } myNext = walk + 1; /* Skip consecutive path delimiters. */ while ((*myNext == '\0') && (myNext != end)) { myNext++; } if (myNext == end) { /* Last character in the buffer is not allowed to be NUL */ Log("%s: error: last char can't be NUL\n", __FUNCTION__); return -1; } break; } } len = walk - begin; *next = myNext; return (int) len; } /* *---------------------------------------------------------------------- * * CPNameEscapeAndConvertFrom -- * * Converts a cross-platform name representation into a string for * use in the local filesystem. * Escapes illegal characters as a part of convertion. * This is a cross-platform implementation and takes the path separator * argument as an argument. The path separator is prepended before each * additional path component, so this function never adds a trailing path * separator. * * Results: * 0 on success. * error < 0 on failure (the converted string did not fit in * the buffer provided or the input was invalid). * * Side effects: * None * *---------------------------------------------------------------------- */ int CPNameEscapeAndConvertFrom(char const **bufIn, // IN/OUT: Input to convert size_t *inSize, // IN/OUT: Size of input size_t *outSize, // IN/OUT: Size of output buffer char **bufOut, // IN/OUT: Output buffer char pathSep) // IN: Path separator character { int result; int inputSize; inputSize = HgfsEscape_GetSize(*bufIn, *inSize); if (inputSize < 0) { result = -1; } else if (inputSize != 0) { char *savedBufOut = *bufOut; char const *savedOutConst = savedBufOut; size_t savedOutSize = *outSize; if (inputSize > *outSize) { Log("%s: error: not enough room for escaping\n", __FUNCTION__); return -1; } /* Leaving space for the leading path separator, thus output to savedBufOut + 1. */ *inSize = HgfsEscape_Do(*bufIn, *inSize, savedOutSize, savedBufOut + 1); result = CPNameConvertFrom(&savedOutConst, inSize, outSize, bufOut, pathSep); *bufIn += *inSize; *inSize = 0; } else { result = CPNameConvertFrom(bufIn, inSize, outSize, bufOut, pathSep); } return result; } /* *---------------------------------------------------------------------- * * CPNameConvertFrom -- * * Converts a cross-platform name representation into a string for * use in the local filesystem. This is a cross-platform * implementation and takes the path separator argument as an * argument. The path separator is prepended before each additional * path component, so this function never adds a trailing path * separator. * * Results: * 0 on success. * error < 0 on failure (the converted string did not fit in * the buffer provided or the input was invalid). * * Side effects: * None * *---------------------------------------------------------------------- */ int CPNameConvertFrom(char const **bufIn, // IN/OUT: Input to convert size_t *inSize, // IN/OUT: Size of input size_t *outSize, // IN/OUT: Size of output buffer char **bufOut, // IN/OUT: Output buffer char pathSep) // IN: Path separator character { char const *in; char const *inEnd; size_t myOutSize; char *out; Bool inPlaceConvertion = (*bufIn == *bufOut); ASSERT(bufIn); ASSERT(inSize); ASSERT(outSize); ASSERT(bufOut); in = *bufIn; if (inPlaceConvertion) { in++; // Skip place for the leading path separator. } inEnd = in + *inSize; myOutSize = *outSize; out = *bufOut; for (;;) { char const *next; int len; int newLen; len = CPName_GetComponent(in, inEnd, &next); if (len < 0) { Log("%s: error: get next component failed\n", __FUNCTION__); return len; } /* Bug 27926 - preventing escaping from shared folder. */ if ((len == 1 && *in == '.') || (len == 2 && in[0] == '.' && in[1] == '.')) { Log("%s: error: found dot/dotdot\n", __FUNCTION__); return -1; } if (len == 0) { /* No more component */ break; } newLen = ((int) myOutSize) - len - 1; if (newLen < 0) { Log("%s: error: not enough room\n", __FUNCTION__); return -1; } myOutSize = (size_t) newLen; *out++ = pathSep; if (!inPlaceConvertion) { memcpy(out, in, len); } out += len; in = next; } /* NUL terminate */ if (myOutSize < 1) { Log("%s: error: not enough room\n", __FUNCTION__); return -1; } *out = '\0'; /* Path name size should not require more than 4 bytes. */ ASSERT((in - *bufIn) <= 0xFFFFFFFF); /* Update pointers. */ *inSize -= (in - *bufIn); *outSize = myOutSize; *bufIn = in; *bufOut = out; return 0; } /* *---------------------------------------------------------------------------- * * CPName_Print -- * * Converts a CPName formatted string to a valid, NUL-terminated string by * replacing all embedded NUL characters with '|'. * * Results: * Pointer to a static buffer containing the converted string. * * Side effects: * None. * *---------------------------------------------------------------------------- */ char const * CPName_Print(char const *in, // IN: Name to print size_t size) // IN: Size of name { /* Static so it does not go on a kernel stack --hpreg */ static char out[128]; size_t i; ASSERT(in); ASSERT(sizeof out >= 4); if (size > sizeof out - 1) { size = sizeof out - 4; out[size] = '.'; out[size + 1] = '.'; out[size + 2] = '.'; out[size + 3] = '\0'; } else { out[size] = '\0'; } for (i = 0; i < size; i++) { out[i] = in[i] != '\0' ? in[i] : '|'; } return out; } /* *---------------------------------------------------------------------------- * * CPName_LinuxConvertTo -- * * Wrapper function that calls CPNameConvertTo() with the correct arguments * for Linux path conversions. * * Makes a cross-platform name representation from the Linux path input * string and writes it into the output buffer. * * Results: * On success, returns the number of bytes used in the cross-platform name, * NOT including the final terminating NUL character. On failure, returns * a negative error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int CPName_LinuxConvertTo(char const *nameIn, // IN: Buf to convert size_t bufOutSize, // IN: Size of the output buffer char *bufOut) // OUT: Output buffer { return CPNameConvertTo(nameIn, bufOutSize, bufOut, '/'); } /* *---------------------------------------------------------------------------- * * CPName_WindowsConvertTo -- * * Wrapper function that calls CPNameConvertTo() with the correct arguments * for Windows path conversions. * * Makes a cross-platform name representation from the Linux path input * string and writes it into the output buffer. * * Results: * On success, returns the number of bytes used in the cross-platform name, * NOT including the final terminating NUL character. On failure, returns * a negative error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int CPName_WindowsConvertTo(char const *nameIn, // IN: Buf to convert size_t bufOutSize, // IN: Size of the output buffer char *bufOut) // OUT: Output buffer { return CPNameConvertTo(nameIn, bufOutSize, bufOut, '\\'); } /* *---------------------------------------------------------------------- * * CPNameConvertTo -- * * Makes a cross-platform name representation from the input string * and writes it into the output buffer. * HGFS convention is to echange names between guest and host in uescaped form. * Both ends perform necessary name escaping according to its own rules * to avoid presenitng invalid file names to OS. Thus the name needs to be unescaped * as a part of conversion to host-independent format. * * Results: * On success, returns the number of bytes used in the * cross-platform name, NOT including the final terminating NUL * character. On failure, returns a negative error. * * Side effects: * None * *---------------------------------------------------------------------- */ int CPNameConvertTo(char const *nameIn, // IN: Buf to convert size_t bufOutSize, // IN: Size of the output buffer char *bufOut, // OUT: Output buffer char pathSep) // IN: path separator to use { char *origOut = bufOut; char const *endOut = bufOut + bufOutSize; size_t cpNameLength = 0; ASSERT(nameIn); ASSERT(bufOut); /* Skip any path separators at the beginning of the input string */ while (*nameIn == pathSep) { nameIn++; } /* * Copy the string to the output buf, converting all path separators into '\0'. * Collapse multiple consecutive path separators into a single one since * CPName_GetComponent can't handle consecutive path separators. */ while (*nameIn != '\0' && bufOut < endOut) { if (*nameIn == pathSep) { *bufOut = '\0'; do { nameIn++; } while (*nameIn == pathSep); } else { *bufOut = *nameIn; nameIn++; } bufOut++; } /* * NUL terminate. XXX This should go away. * * When we get rid of NUL termination here, this test should * also change to "if (*nameIn != '\0')". */ if (bufOut == endOut) { return -1; } *bufOut = '\0'; /* Path name size should not require more than 4 bytes. */ ASSERT((bufOut - origOut) <= 0xFFFFFFFF); /* If there were any trailing path separators, dont count them [krishnan] */ cpNameLength = bufOut - origOut; while ((cpNameLength >= 1) && (origOut[cpNameLength - 1] == 0)) { cpNameLength--; } cpNameLength = HgfsEscape_Undo(origOut, cpNameLength); /* Return number of bytes used */ return (int) cpNameLength; } open-vm-tools-9.4.0-1280544/lib/hgfs/cpNameUtilInt.h0000644765153500003110000000377012220061556020030 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * cpNameUtilInt.h -- * * Cross-platform name format used by hgfs. * */ #ifndef __CP_NAME_UTIL_INT_H__ #define __CP_NAME_UTIL_INT_H__ #include "vm_basic_types.h" /* * Used by CPNameUtil_Utf8FormHostToUtf8FormC and * CPNameUtil_Utf8FormCToUtf8FormHost. */ Bool CPNameUtilConvertUtf8FormCAndD(const char *cpNameToConvert, size_t cpNameToConvertLen, Bool convertToFormC, char **cpConvertedName, size_t *cpConvertedNameLen); #endif /* __CP_NAME_UTIL_INT_H__ */ open-vm-tools-9.4.0-1280544/lib/hgfs/Makefile.in0000644765153500003110000004466012220061622017205 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/hgfs DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libHgfs_la_LIBADD = am_libHgfs_la_OBJECTS = cpName.lo cpNameLite.lo cpNameLinux.lo \ cpNameUtil.lo cpNameUtilLinux.lo hgfsUtil.lo hgfsEscape.lo libHgfs_la_OBJECTS = $(am_libHgfs_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libHgfs_la_SOURCES) DIST_SOURCES = $(libHgfs_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libHgfs.la libHgfs_la_SOURCES = cpName.c cpNameLite.c cpNameLinux.c cpNameUtil.c \ cpNameUtilLinux.c hgfsUtil.c hgfsEscape.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/hgfs/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/hgfs/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libHgfs.la: $(libHgfs_la_OBJECTS) $(libHgfs_la_DEPENDENCIES) $(EXTRA_libHgfs_la_DEPENDENCIES) $(LINK) $(libHgfs_la_OBJECTS) $(libHgfs_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpName.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpNameLinux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpNameLite.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpNameUtil.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpNameUtilLinux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hgfsEscape.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hgfsUtil.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/rpcChannel/0000755765153500003110000000000012220061623016255 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/rpcChannel/rpcChannelInt.h0000644765153500003110000000221412220061556021162 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _RPCCHANNELINT_H_ #define _RPCCHANNELINT_H_ /** * @file rpcChannelInt.h * * Internal definitions for the RPC channel library. */ #include "vmware/tools/guestrpc.h" void RpcChannel_Error(void *_state, char const *status); #endif /* _RPCCHANNELINT_H_ */ open-vm-tools-9.4.0-1280544/lib/rpcChannel/bdoorChannel.c0000644765153500003110000001757712220061556021045 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file bdoorChannel.c * * Implements a backdoor-based RPC channel. This is based on the * RpcIn / RpcOut libraries. */ #include "vm_assert.h" #include "rpcChannelInt.h" #include "rpcin.h" #include "rpcout.h" #include "util.h" /** Max amount of time (in .01s) that the RpcIn loop will sleep for. */ #define RPCIN_MAX_DELAY 10 typedef struct BackdoorChannel { GMainContext *mainCtx; GStaticMutex outLock; RpcIn *in; RpcOut *out; gboolean inStarted; gboolean outStarted; } BackdoorChannel; /** * Initializes internal state for the inbound channel. * * @param[in] chan The RPC channel instance. * @param[in] ctx Main application context. * @param[in] appName Unused. * @param[in] appCtx Unused. */ static void RpcInSetup(RpcChannel *chan, GMainContext *ctx, const char *appName, gpointer appCtx) { BackdoorChannel *bdoor = chan->_private; bdoor->mainCtx = g_main_context_ref(ctx); bdoor->in = RpcIn_Construct(ctx, RpcChannel_Dispatch, chan); ASSERT(bdoor->in != NULL); } /** * Starts the RpcIn loop and the RpcOut channel. * * No-op if channels are already started. * * @param[in] chan The RPC channel instance. * * @return TRUE on success. */ static gboolean RpcInStart(RpcChannel *chan) { gboolean ret = TRUE; BackdoorChannel *bdoor = chan->_private; if (bdoor->outStarted) { /* Already started. Make sure both channels are in sync and return. */ ASSERT(bdoor->in == NULL || bdoor->inStarted); return ret; } else { ASSERT(bdoor->in == NULL || !bdoor->inStarted); } if (bdoor->in != NULL) { ret = RpcIn_start(bdoor->in, RPCIN_MAX_DELAY, RpcChannel_Error, chan); } if (ret) { ret = RpcOut_start(bdoor->out); if (!ret) { RpcIn_stop(bdoor->in); } } bdoor->inStarted = (bdoor->in != NULL); bdoor->outStarted = TRUE; return ret; } /** * Stops a channel, keeping internal state so that it can be restarted later. * It's safe to call this function more than once. * * @internal This function does a best effort at tearing down the host-side * channels, but if the host returns any failure, it still shuts * down the guest channels. See bug 388777 for details. * * @param[in] chan The RPC channel instance. */ static void RpcInStop(RpcChannel *chan) { BackdoorChannel *bdoor = chan->_private; g_static_mutex_lock(&bdoor->outLock); if (bdoor->out != NULL) { if (bdoor->outStarted) { RpcOut_stop(bdoor->out); } bdoor->outStarted = FALSE; } else { ASSERT(!bdoor->outStarted); } g_static_mutex_unlock(&bdoor->outLock); if (bdoor->in != NULL) { if (bdoor->inStarted) { RpcIn_stop(bdoor->in); } bdoor->inStarted = FALSE; } else { ASSERT(!bdoor->inStarted); } } /** * Shuts down the RpcIn channel. Due to the "split brain" nature of the backdoor, * if this function fails, it's possible that while the "out" channel was shut * down the "in" one wasn't, for example, although that's unlikely. * * @param[in] chan The RPC channel instance. */ static void RpcInShutdown(RpcChannel *chan) { BackdoorChannel *bdoor = chan->_private; RpcInStop(chan); if (bdoor->in != NULL) { RpcIn_Destruct(bdoor->in); } RpcOut_Destruct(bdoor->out); g_static_mutex_free(&bdoor->outLock); if (bdoor->mainCtx != NULL) { g_main_context_unref(bdoor->mainCtx); } g_free(bdoor); } /** * Sends the data using the RpcOut library. * * @param[in] chan The RPC channel instance. * @param[in] data Data to send. * @param[in] dataLen Number of bytes to send. * @param[out] result Response from other side. * @param[out] resultLen Number of bytes in response. * * @return The status from the remote end (TRUE if call was successful). */ static gboolean RpcInSend(RpcChannel *chan, char const *data, size_t dataLen, char **result, size_t *resultLen) { gboolean ret = FALSE; const char *reply; size_t replyLen; BackdoorChannel *bdoor = chan->_private; g_static_mutex_lock(&bdoor->outLock); if (!bdoor->outStarted) { goto exit; } ret = RpcOut_send(bdoor->out, data, dataLen, &reply, &replyLen); /* * This is a hack to try to work around bug 393650 without having to revert * to the old behavior of opening and closing an RpcOut channel for every * outgoing message. The issue here is that it's possible for the code to * try to write to the channel when a "reset" has just happened. In these * cases, the current RpcOut channel is not valid anymore, and we'll get an * error. The RpcOut lib doesn't really reply with a useful error, but it * does have consistent error messages starting with "RpcOut:". * * So, if the error is one of those messages, restart the RpcOut channel and * try to send the message again. If this second attempt fails, then give up. * * This is not 100% break-proof: a reset can still occur after we open the * new channel and before we try to re-send the message. But that's a race * that we can't easily fix, and exists even in code that just uses the * RpcOut_SendOne() API. Also, if some host handler returns an error that * starts with "RpcOut:", it will trigger this; but I don't think we have * any such handlers. */ if (!ret && reply != NULL && replyLen > sizeof "RpcOut: " && g_str_has_prefix(reply, "RpcOut: ")) { g_debug("RpcOut failure, restarting channel.\n"); RpcOut_stop(bdoor->out); if (RpcOut_start(bdoor->out)) { ret = RpcOut_send(bdoor->out, data, dataLen, &reply, &replyLen); } else { g_warning("Couldn't restart RpcOut channel; bad things may happen " "until the RPC channel is reset.\n"); bdoor->outStarted = FALSE; } } /* * A lot of this logic is just replicated from rpcout.c:RpcOut_SendOneRaw(). * Look there for comments about a few details. */ if (result != NULL) { if (reply != NULL) { *result = Util_SafeMalloc(replyLen + 1); memcpy(*result, reply, replyLen); (*result)[replyLen] = '\0'; } else { *result = NULL; } } if (resultLen != NULL) { *resultLen = replyLen; } exit: g_static_mutex_unlock(&bdoor->outLock); return ret; } /** * Creates a new RpcChannel channel that uses the backdoor for communication. * * @return A new channel instance (never NULL). */ RpcChannel * BackdoorChannel_New(void) { RpcChannel *ret; BackdoorChannel *bdoor; ret = RpcChannel_Create(); bdoor = g_malloc0(sizeof *bdoor); g_static_mutex_init(&bdoor->outLock); bdoor->out = RpcOut_Construct(); ASSERT(bdoor->out != NULL); bdoor->inStarted = FALSE; bdoor->outStarted = FALSE; ret->start = RpcInStart; ret->stop = RpcInStop; ret->send = RpcInSend; ret->setup = RpcInSetup; ret->shutdown = RpcInShutdown; ret->_private = bdoor; return ret; } open-vm-tools-9.4.0-1280544/lib/rpcChannel/Makefile.am0000644765153500003110000000213012220061556020312 0ustar dtormts################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libRpcChannel.la libRpcChannel_la_SOURCES = libRpcChannel_la_SOURCES += bdoorChannel.c libRpcChannel_la_SOURCES += rpcChannel.c libRpcChannel_la_CPPFLAGS = libRpcChannel_la_CPPFLAGS += @VMTOOLS_CPPFLAGS@ open-vm-tools-9.4.0-1280544/lib/rpcChannel/rpcChannel.c0000644765153500003110000003670312220061556020514 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file rpcChannel.c * * Common functions to all RPC channel implementations. */ #include #include "vm_assert.h" #include "dynxdr.h" #include "rpcChannelInt.h" #include "str.h" #include "strutil.h" #include "vmxrpc.h" #include "xdrutil.h" /** Internal state of a channel. */ typedef struct RpcChannelInt { RpcChannel impl; gchar *appName; GHashTable *rpcs; GMainContext *mainCtx; GSource *resetCheck; gpointer appCtx; RpcChannelCallback resetReg; RpcChannelResetCb resetCb; gpointer resetData; gboolean rpcError; guint rpcErrorCount; } RpcChannelInt; /** Max number of times to attempt a channel restart. */ #define RPCIN_MAX_RESTARTS 60 static gboolean RpcChannelPing(RpcInData *data); static RpcChannelCallback gRpcHandlers[] = { { "ping", RpcChannelPing, NULL, NULL, NULL, 0 } }; /** * Handler for a "ping" message. Does nothing. * * @param[in] data The RPC data. * * @return TRUE. */ static gboolean RpcChannelPing(RpcInData *data) { return RPCIN_SETRETVALS(data, "", TRUE); } /** * Callback for restarting the RPC channel. * * @param[in] _chan The RPC channel * * @return FALSE */ static gboolean RpcChannelRestart(gpointer _chan) { RpcChannelInt *chan = _chan; RpcChannel_Stop(&chan->impl); if (!RpcChannel_Start(&chan->impl)) { g_warning("Channel restart failed [%d]\n", chan->rpcErrorCount); if (chan->resetCb != NULL) { chan->resetCb(&chan->impl, FALSE, chan->resetData); } } else { chan->rpcError = FALSE; } return FALSE; } /** * Checks and potentially resets the RPC channel. This code is based on the * toolsDaemon.c function "ToolsDaemon_CheckReset". * * @param[in] _chan The RPC channel. * * @return FALSE. The reset callback will schedule a new check when it's called. */ static gboolean RpcChannelCheckReset(gpointer _chan) { static int channelTimeoutAttempts = RPCIN_MAX_RESTARTS; RpcChannelInt *chan = _chan; /* Check the channel state. */ if (chan->rpcError) { GSource *src; if (++(chan->rpcErrorCount) > channelTimeoutAttempts) { g_warning("Failed to reset channel after %u attempts\n", chan->rpcErrorCount - 1); if (chan->resetCb != NULL) { chan->resetCb(&chan->impl, FALSE, chan->resetData); } goto exit; } /* Schedule the channel restart for 1 sec in the future. */ g_debug("Resetting channel [%u]\n", chan->rpcErrorCount); src = g_timeout_source_new(1000); g_source_set_callback(src, RpcChannelRestart, chan, NULL); g_source_attach(src, chan->mainCtx); g_source_unref(src); goto exit; } /* Reset was successful. */ g_debug("Channel was reset successfully.\n"); chan->rpcErrorCount = 0; if (chan->resetCb != NULL) { chan->resetCb(&chan->impl, TRUE, chan->resetData); } exit: g_source_unref(chan->resetCheck); chan->resetCheck = NULL; return FALSE; } /** * Handles an RPC reset. Calls the reset callback of all loaded plugins. * * @param[in] data The RPC data. * * @return TRUE. */ static gboolean RpcChannelReset(RpcInData *data) { gchar *msg; RpcChannelInt *chan = data->clientData; if (chan->resetCheck == NULL) { chan->resetCheck = g_idle_source_new(); g_source_set_priority(chan->resetCheck, G_PRIORITY_HIGH); g_source_set_callback(chan->resetCheck, RpcChannelCheckReset, chan, NULL); g_source_attach(chan->resetCheck, chan->mainCtx); } msg = Str_Asprintf(NULL, "ATR %s", chan->appName); ASSERT_MEM_ALLOC(msg); return RPCIN_SETRETVALSF(data, msg, TRUE); } /** * A wrapper for standard RPC callback functions which provides automatic * XDR serialization / deserialization if requested by the application. * * @param[in] data RpcIn data. * @param[in] rpc The RPC registration data. * * @return Whether the RPC was handled successfully. */ static Bool RpcChannelXdrWrapper(RpcInData *data, RpcChannelCallback *rpc) { Bool ret; RpcInData copy; void *xdrData = NULL; if (rpc->xdrIn != NULL) { xdrData = malloc(rpc->xdrInSize); if (xdrData == NULL) { ret = RPCIN_SETRETVALS(data, "Out of memory.", FALSE); goto exit; } memset(xdrData, 0, rpc->xdrInSize); if (!XdrUtil_Deserialize(data->args + 1, data->argsSize - 1, rpc->xdrIn, xdrData)) { ret = RPCIN_SETRETVALS(data, "XDR deserialization failed.", FALSE); free(xdrData); goto exit; } copy.name = data->name; copy.args = xdrData; copy.argsSize = rpc->xdrInSize; copy.result = data->result; copy.resultLen = data->resultLen; copy.freeResult = data->freeResult; copy.appCtx = data->appCtx; copy.clientData = rpc->clientData; } else { memcpy(©, data, sizeof copy); } ret = rpc->callback(©); if (rpc->xdrIn != NULL) { VMX_XDR_FREE(rpc->xdrIn, xdrData); free(xdrData); copy.args = NULL; data->result = copy.result; data->resultLen = copy.resultLen; data->freeResult = copy.freeResult; } if (rpc->xdrOut != NULL && copy.result != NULL) { XDR xdrs; xdrproc_t xdrProc = rpc->xdrOut; if (DynXdr_Create(&xdrs) == NULL) { ret = RPCIN_SETRETVALS(data, "Out of memory.", FALSE); goto exit; } if (!xdrProc(&xdrs, copy.result)) { ret = RPCIN_SETRETVALS(data, "XDR serialization failed.", FALSE); DynXdr_Destroy(&xdrs, TRUE); goto exit; } if (copy.freeResult) { VMX_XDR_FREE(rpc->xdrOut, copy.result); } data->result = DynXdr_Get(&xdrs); data->resultLen = XDR_GETPOS(&xdrs); data->freeResult = TRUE; DynXdr_Destroy(&xdrs, FALSE); } exit: if (copy.freeResult && copy.result != NULL) { g_free(copy.result); } return ret; } /** * Builds an "rpcout" command to send a XDR struct. * * @param[in] cmd The command name. * @param[in] xdrProc Function to use for serializing the XDR struct. * @param[in] xdrData The XDR struct to serialize. * @param[out] result Where to store the serialized data. * @param[out] resultLen Where to store the serialized data length. * * @return Whether successfully built the command. */ gboolean RpcChannel_BuildXdrCommand(const char *cmd, void *xdrProc, void *xdrData, char **result, size_t *resultLen) { Bool ret = FALSE; xdrproc_t proc = xdrProc; XDR xdrs; if (DynXdr_Create(&xdrs) == NULL) { return FALSE; } if (!DynXdr_AppendRaw(&xdrs, cmd, strlen(cmd))) { goto exit; } if (!DynXdr_AppendRaw(&xdrs, " ", 1)) { goto exit; } if (!proc(&xdrs, xdrData)) { goto exit; } *result = DynXdr_Get(&xdrs); *resultLen = xdr_getpos(&xdrs); ret = TRUE; exit: DynXdr_Destroy(&xdrs, !ret); return ret; } /** * Creates a new RpcChannel without any implementation. * * This is mainly for use of code that is implementing a custom RpcChannel. * Such implementations should provide their own "constructor"-type function * which should then call this function to get an RpcChannel instance. They * should then fill in the function pointers that provide the implementation * for the channel before making the channel available to the callers. * * @return A new RpcChannel instance. */ RpcChannel * RpcChannel_Create(void) { RpcChannelInt *chan = g_new0(RpcChannelInt, 1); return &chan->impl; } /** * Dispatches the given RPC to the registered handler. This mimics the behavior * of the RpcIn library (but is not tied to that particular implementation of * an RPC channel). * * @param[in,out] data The RPC data. * * @return Whether the RPC was handled successfully. */ gboolean RpcChannel_Dispatch(RpcInData *data) { char *name = NULL; unsigned int index = 0; size_t nameLen; Bool status; RpcChannelCallback *rpc = NULL; RpcChannelInt *chan = data->clientData; name = StrUtil_GetNextToken(&index, data->args, " "); if (name == NULL) { status = RPCIN_SETRETVALS(data, "Bad command", FALSE); goto exit; } if (chan->rpcs != NULL) { rpc = g_hash_table_lookup(chan->rpcs, name); } if (rpc == NULL) { status = RPCIN_SETRETVALS(data, "Unknown Command", FALSE); goto exit; } /* Adjust the RPC arguments. */ nameLen = strlen(name); data->name = name; data->args = data->args + nameLen; data->argsSize -= nameLen; data->appCtx = chan->appCtx; data->clientData = rpc->clientData; if (rpc->xdrIn != NULL || rpc->xdrOut != NULL) { status = RpcChannelXdrWrapper(data, rpc); } else { status = rpc->callback(data); } ASSERT(data->result != NULL); exit: data->name = NULL; free(name); return status; } /** * Shuts down an RPC channel and release any held resources. * * @param[in] chan The RPC channel. * * @return Whether the channel was shut down successfully. */ gboolean RpcChannel_Destroy(RpcChannel *chan) { size_t i; RpcChannelInt *cdata = (RpcChannelInt *) chan; if (cdata->impl.shutdown != NULL) { cdata->impl.shutdown(chan); } RpcChannel_UnregisterCallback(chan, &cdata->resetReg); for (i = 0; i < ARRAYSIZE(gRpcHandlers); i++) { RpcChannel_UnregisterCallback(chan, &gRpcHandlers[i]); } if (cdata->rpcs != NULL) { g_hash_table_destroy(cdata->rpcs); cdata->rpcs = NULL; } cdata->resetCb = NULL; cdata->resetData = NULL; cdata->appCtx = NULL; g_free(cdata->appName); cdata->appName = NULL; if (cdata->mainCtx != NULL) { g_main_context_unref(cdata->mainCtx); cdata->mainCtx = NULL; } if (cdata->resetCheck != NULL) { g_source_destroy(cdata->resetCheck); cdata->resetCheck = NULL; } g_free(cdata); return TRUE; } /** * Error handling function for the RPC channel. Enqueues the "check reset" * function for running later, if it's not yet enqueued. * * @param[in] _chan The RPC channel. * @param[in] status Error description. */ void RpcChannel_Error(void *_chan, char const *status) { RpcChannelInt *chan = _chan; chan->rpcError = TRUE; g_debug("Error in the RPC receive loop: %s.\n", status); if (chan->resetCheck == NULL) { chan->resetCheck = g_idle_source_new(); g_source_set_callback(chan->resetCheck, RpcChannelCheckReset, chan, NULL); g_source_attach(chan->resetCheck, chan->mainCtx); } } /** * Initializes the RPC channel for inbound operations. * * This function must be called before starting the channel if the application * wants to receive messages on the channel. Applications don't need to call it * if only using the outbound functionality. * * @param[in] chan The RPC channel. * @param[in] appName TCLO application name. * @param[in] mainCtx Application event context. * @param[in] appCtx Application context. * @param[in] resetCb Callback for when a reset occurs. * @param[in] resetData Client data for the reset callback. */ void RpcChannel_Setup(RpcChannel *chan, const gchar *appName, GMainContext *mainCtx, gpointer appCtx, RpcChannelResetCb resetCb, gpointer resetData) { size_t i; RpcChannelInt *cdata = (RpcChannelInt *) chan; cdata->appName = g_strdup(appName); cdata->appCtx = appCtx; cdata->mainCtx = g_main_context_ref(mainCtx); cdata->resetCb = resetCb; cdata->resetData = resetData; cdata->resetReg.name = "reset"; cdata->resetReg.callback = RpcChannelReset; cdata->resetReg.clientData = chan; /* Register the callbacks handled by the rpcChannel library. */ RpcChannel_RegisterCallback(chan, &cdata->resetReg); for (i = 0; i < ARRAYSIZE(gRpcHandlers); i++) { RpcChannel_RegisterCallback(chan, &gRpcHandlers[i]); } if (cdata->impl.setup != NULL) { cdata->impl.setup(&cdata->impl, mainCtx, appName, appCtx); } } /** * Sets the non-freeable result of the given RPC context to the given value. * The result should be a NULL-terminated string. * * @param[in] data RPC context. * @param[in] result Result string. * @param[in] retVal Return value of this function. * * @return @a retVal */ gboolean RpcChannel_SetRetVals(RpcInData *data, char const *result, gboolean retVal) { ASSERT(data); /* This cast is safe: data->result will not be freed. */ data->result = (char *)result; data->resultLen = strlen(data->result); data->freeResult = FALSE; return retVal; } /** * Sets the freeable result of the given RPC context to the given value. * The result should be a NULL-terminated string. * * @param[in] data RPC context. * @param[in] result Result string. * @param[in] retVal Return value of this function. * * @return @a retVal */ gboolean RpcChannel_SetRetValsF(RpcInData *data, char *result, gboolean retVal) { ASSERT(data); data->result = result; data->resultLen = strlen(data->result); data->freeResult = TRUE; return retVal; } /** * Registers a new RPC handler in the given RPC channel. This function is * not thread-safe. * * @param[in] chan The channel instance. * @param[in] rpc Info about the RPC being registered. */ void RpcChannel_RegisterCallback(RpcChannel *chan, RpcChannelCallback *rpc) { RpcChannelInt *cdata = (RpcChannelInt *) chan; ASSERT(rpc->name != NULL && strlen(rpc->name) > 0); ASSERT(rpc->callback); ASSERT(rpc->xdrIn == NULL || rpc->xdrInSize > 0); if (cdata->rpcs == NULL) { cdata->rpcs = g_hash_table_new(g_str_hash, g_str_equal); } if (g_hash_table_lookup(cdata->rpcs, rpc->name) != NULL) { g_error("Trying to overwrite existing RPC registration for %s!\n", rpc->name); } g_hash_table_insert(cdata->rpcs, (gpointer) rpc->name, rpc); } /** * Unregisters a new RPC handler from the given RPC channel. This function is * not thread-safe. * * @param[in] chan The channel instance. * @param[in] rpc Info about the RPC being unregistered. */ void RpcChannel_UnregisterCallback(RpcChannel *chan, RpcChannelCallback *rpc) { RpcChannelInt *cdata = (RpcChannelInt *) chan; if (cdata->rpcs != NULL) { g_hash_table_remove(cdata->rpcs, rpc->name); } } open-vm-tools-9.4.0-1280544/lib/rpcChannel/Makefile.in0000644765153500003110000005036612220061623020334 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/rpcChannel DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libRpcChannel_la_LIBADD = am_libRpcChannel_la_OBJECTS = libRpcChannel_la-bdoorChannel.lo \ libRpcChannel_la-rpcChannel.lo libRpcChannel_la_OBJECTS = $(am_libRpcChannel_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libRpcChannel_la_SOURCES) DIST_SOURCES = $(libRpcChannel_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libRpcChannel.la libRpcChannel_la_SOURCES = bdoorChannel.c rpcChannel.c libRpcChannel_la_CPPFLAGS = @VMTOOLS_CPPFLAGS@ all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/rpcChannel/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/rpcChannel/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libRpcChannel.la: $(libRpcChannel_la_OBJECTS) $(libRpcChannel_la_DEPENDENCIES) $(EXTRA_libRpcChannel_la_DEPENDENCIES) $(LINK) $(libRpcChannel_la_OBJECTS) $(libRpcChannel_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libRpcChannel_la-bdoorChannel.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libRpcChannel_la-rpcChannel.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libRpcChannel_la-bdoorChannel.lo: bdoorChannel.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libRpcChannel_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libRpcChannel_la-bdoorChannel.lo -MD -MP -MF $(DEPDIR)/libRpcChannel_la-bdoorChannel.Tpo -c -o libRpcChannel_la-bdoorChannel.lo `test -f 'bdoorChannel.c' || echo '$(srcdir)/'`bdoorChannel.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libRpcChannel_la-bdoorChannel.Tpo $(DEPDIR)/libRpcChannel_la-bdoorChannel.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bdoorChannel.c' object='libRpcChannel_la-bdoorChannel.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libRpcChannel_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libRpcChannel_la-bdoorChannel.lo `test -f 'bdoorChannel.c' || echo '$(srcdir)/'`bdoorChannel.c libRpcChannel_la-rpcChannel.lo: rpcChannel.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libRpcChannel_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libRpcChannel_la-rpcChannel.lo -MD -MP -MF $(DEPDIR)/libRpcChannel_la-rpcChannel.Tpo -c -o libRpcChannel_la-rpcChannel.lo `test -f 'rpcChannel.c' || echo '$(srcdir)/'`rpcChannel.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libRpcChannel_la-rpcChannel.Tpo $(DEPDIR)/libRpcChannel_la-rpcChannel.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpcChannel.c' object='libRpcChannel_la-rpcChannel.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libRpcChannel_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libRpcChannel_la-rpcChannel.lo `test -f 'rpcChannel.c' || echo '$(srcdir)/'`rpcChannel.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/unicode/0000755765153500003110000000000012220061623015626 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/unicode/unicodeSimpleBase.c0000644765153500003110000006356612220061556021412 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * unicodeSimpleBase.cc -- * * Simple implementation of unicodeBase.h interface using char * * containing NUL-terminated UTF-8 bytes as the typedef for * Unicode. * * Basic Unicode string creation and encoding conversion. * * The thread-safety of ConstUnicode functions is the same as * that for standard const char * functions: multiple threads can * call ConstUnicode functions on the same string simultaneously. * * However, a non-const Unicode function (like Unicode_Free) must * not be called concurrently with any other Unicode or * ConstUnicode function on the same string. */ #include #include "vmware.h" #include "util.h" #include "codeset.h" #include "str.h" #include "unicodeBase.h" #include "unicodeInt.h" /* * Padding for initial and final bytes used by an encoding. The value * comes from ICU's UCNV_GET_MAX_BYTES_FOR_STRING macro and accounts * for leading and trailing bytes and NUL. */ static const size_t UNICODE_UTF16_CODE_UNITS_PADDING = 10; /* *----------------------------------------------------------------------------- * * UnicodeAllocInternal -- * * Allocates a new Unicode string given a buffer with both length * in bytes and string encoding specified. * * If lengthInBytes is -1, then buffer must be NUL-terminated. * Otherwise, buffer must be of the specified length, but does * not need to be NUL-terminated. * * Return NULL on memory allocation failure. * * Return NULL if strict is true and the buffer contains an invalid * sequence in the specified encoding. * * If strict is false, then an invalid sequence is replaced by * a substitution character, which is either the Unicode * substitution character (U+FFFD or \xef\xbf\xbd in UTF-8) * or subchar1 (ASCII SUB or control-z, value 0x1a). * * Results: * An allocated Unicode string containing the decoded characters * in buffer, or NULL on failure. Caller must pass to * Unicode_Free to free. * * Side effects: * None * *----------------------------------------------------------------------------- */ Unicode UnicodeAllocInternal(const void *buffer, // IN ssize_t lengthInBytes, // IN StringEncoding encoding, // IN Bool strict) // IN { char *utf8Result = NULL; ASSERT(buffer != NULL); ASSERT(lengthInBytes >= 0); ASSERT(Unicode_IsEncodingValid(encoding)); if (!strict) { CodeSet_GenericToGeneric(Unicode_EncodingEnumToName(encoding), buffer, lengthInBytes, "UTF-8", CSGTG_TRANSLIT, &utf8Result, NULL); return utf8Result; } switch (encoding) { case STRING_ENCODING_US_ASCII: case STRING_ENCODING_UTF8: if (Unicode_IsBufferValid(buffer, lengthInBytes, encoding)) { utf8Result = Util_SafeStrndup(buffer, lengthInBytes); } break; case STRING_ENCODING_UTF16_LE: // utf8Result will be left NULL on failure. CodeSet_Utf16leToUtf8((const char *)buffer, lengthInBytes, &utf8Result, NULL); break; default: CodeSet_GenericToGeneric(Unicode_EncodingEnumToName(encoding), buffer, lengthInBytes, "UTF-8", 0, &utf8Result, NULL); break; } return (Unicode)utf8Result; } /* *----------------------------------------------------------------------------- * * Unicode_IsBufferValid -- * * Tests if the given buffer is valid in the specified encoding. * * If lengthInBytes is -1, then buffer must be NUL-terminated. * Otherwise, buffer must be of the specified length, but does * not need to be NUL-terminated. * * This function should not be used for heuristic determination of * encodings. Since the test looks for bit patterns in the buffer * that are invalid in the specified encoding, negative results * guarantee the buffer is not in the specified encoding, but positive * results are inconclusive. Source buffers containing pure ASCII * will pass all 8-bit encodings, and all source buffers will pass * a windows-1252 test since win-1252 maps all 256 8-bit combinations. * * Results: * TRUE if the buffer is valid, FALSE if it's not. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool Unicode_IsBufferValid(const void *buffer, // IN ssize_t lengthInBytes, // IN StringEncoding encoding) // IN { if (buffer == NULL) { ASSERT(lengthInBytes <= 0); return TRUE; } encoding = Unicode_ResolveEncoding(encoding); if (encoding == STRING_ENCODING_US_ASCII) { return UnicodeSanityCheck(buffer, lengthInBytes, encoding); } if (lengthInBytes == -1) { lengthInBytes = Unicode_LengthInBytes(buffer, encoding); } return CodeSet_Validate(buffer, lengthInBytes, Unicode_EncodingEnumToName(encoding)); } /* *----------------------------------------------------------------------------- * * Unicode_Duplicate -- * * Allocates and returns a copy of the passed-in Unicode string. * * Results: * An allocated Unicode string containing a duplicate of the passed-in * string. Caller must pass to Unicode_Free to free. * * Side effects: * None * *----------------------------------------------------------------------------- */ Unicode Unicode_Duplicate(ConstUnicode str) // IN { return (Unicode)Util_SafeStrdup((const char *)str); } /* *----------------------------------------------------------------------------- * * Unicode_Free -- * * Frees the memory for the specified Unicode string and invalidates it. * * Not thread-safe when other functions are concurrently * operating on the same string. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void Unicode_Free(Unicode str) // IN { free(str); } /* *----------------------------------------------------------------------------- * * Unicode_AllocList -- * * Allocates a list (actually a vector) of Unicode strings from a list * (vector) of strings of specified encoding. * The input list has a specified length or can be an argv-style * NULL-terminated list (if length is negative). * * Results: * An allocated list (vector) of Unicode strings. * The individual strings must be freed with Unicode_Free, * or the entire list can be free with Unicode_FreeList. * * Side effects: * None * *----------------------------------------------------------------------------- */ Unicode * Unicode_AllocList(char **srcList, // IN: list of strings ssize_t length, // IN: list StringEncoding encoding) // IN: { Unicode *dstList = NULL; ssize_t i; ASSERT(srcList != NULL); encoding = Unicode_ResolveEncoding(encoding); if (length < 0) { length = 0; while (srcList[length] != NULL) { length++; } /* Include the sentinel element. */ length++; } dstList = Util_SafeMalloc(length * sizeof *dstList); for (i = 0; i < length; i++) { dstList[i] = Unicode_Alloc(srcList[i], encoding); } return dstList; } /* *----------------------------------------------------------------------------- * * Unicode_FreeList -- * * Free a list (actually a vector) of Unicode strings. * The list (vector) itself is also freed. * * The list either has a specified length or is * argv-style NULL terminated (if length is negative). * * Results: * None * * Side effects: * errno or Windows last error is preserved. * *----------------------------------------------------------------------------- */ void Unicode_FreeList(Unicode *list, // IN: the list to free ssize_t length) // IN: the length { Util_FreeStringList(list, length); } /* *----------------------------------------------------------------------------- * * Unicode_GetAllocList -- * * Given a list of Unicode strings, converts them to a list of * buffers in the specified encoding. * * The input list has a specified length or can be an argv-style * NULL-terminated list (if length is negative). * * Results: * An allocated list (vector) of NUL terminated buffers in the specified * encoding * or NULL on conversion failure. * The caller is responsible to free the memory allocated by * this routine. * * Side effects: * None * *----------------------------------------------------------------------------- */ char ** Unicode_GetAllocList(Unicode const srcList[], // IN: list of strings ssize_t length, // IN: length (-1 for NULL term.) StringEncoding encoding) // IN: Encoding of returned list { char **dstList = NULL; ssize_t i; ASSERT(srcList != NULL); encoding = Unicode_ResolveEncoding(encoding); if (length < 0) { length = 0; while (srcList[length] != NULL) { length++; } /* Include the sentinel element. */ length++; } dstList = Util_SafeMalloc(length * sizeof *dstList); for (i = 0; i < length; i++) { dstList[i] = Unicode_GetAllocBytes(srcList[i], encoding); if (dstList[i] == NULL && srcList[i] != NULL) { while (--i >= 0) { free(dstList[i]); } free(dstList); return NULL; } } return dstList; } /* *----------------------------------------------------------------------------- * * Unicode_GetUTF8 -- * * Returns the contents of the string encoded as a NUL-terminated UTF-8 * byte array. * * Results: * A NUL-terminated UTF-8 string; lifetime is valid until the next * non-const Unicode function is called on the string. Caller should * strdup if storing the return value long-term. * * Caller does not need to free; the memory is managed inside the * Unicode object. * * Side effects: * None * *----------------------------------------------------------------------------- */ const char * Unicode_GetUTF8(ConstUnicode str) // IN { return (const char *)str; } /* *----------------------------------------------------------------------------- * * Unicode_LengthInCodeUnits -- * * Gets the length of the Unicode string in UTF-8 code units. * * Results: * The length of the string in UTF-8 code units. * * Side effects: * None * *----------------------------------------------------------------------------- */ UnicodeIndex Unicode_LengthInCodeUnits(ConstUnicode str) // IN { return strlen((const char *)str); } /* *----------------------------------------------------------------------------- * * Unicode_BytesRequired -- * * Gets the number of bytes needed to encode the Unicode string in * the specified encoding, including NUL-termination. * * Use this to find the size required for the byte array passed * to Unicode_CopyBytes. * * Results: * The number of bytes needed to encode the Unicode string in the * specified encoding. * * Side effects: * None * *----------------------------------------------------------------------------- */ size_t Unicode_BytesRequired(ConstUnicode str, // IN StringEncoding encoding) // IN { const uint8 *utf8 = (const uint8 *)str; // Number of bytes needed for a code point [U+0000, U+FFFF]. size_t basicCodePointSize; // Number of bytes needed for a code point [U+10000, U+10FFFF]. size_t supplementaryCodePointSize; size_t result = 0; encoding = Unicode_ResolveEncoding(encoding); switch (encoding) { case STRING_ENCODING_UTF8: return strlen((const char *)utf8) + 1; case STRING_ENCODING_US_ASCII: case STRING_ENCODING_ISO_8859_1: case STRING_ENCODING_WINDOWS_1252: // TODO: Lots more encodings can be added here. basicCodePointSize = supplementaryCodePointSize = 1; break; case STRING_ENCODING_UTF16_LE: case STRING_ENCODING_UTF16_BE: case STRING_ENCODING_UTF16_XE: basicCodePointSize = 2; supplementaryCodePointSize = 4; break; case STRING_ENCODING_UTF32_LE: case STRING_ENCODING_UTF32_BE: case STRING_ENCODING_UTF32_XE: basicCodePointSize = 4; supplementaryCodePointSize = 4; break; default: /* * Assume the worst: ISO-2022-JP takes up to 7 bytes per code point. */ basicCodePointSize = 7; supplementaryCodePointSize = 7; break; } /* * Do a simple check of how many bytes are needed to convert the * UTF-8 to the target encoding. This doesn't do UTF-8 validity * checking, but will not overrun the end of the buffer. */ while (*utf8) { size_t utf8NumBytesRemaining; // Advance one code point forward in the UTF-8 input. if (*utf8 <= 0x7F) { utf8NumBytesRemaining = 1; result += basicCodePointSize; } else if (*utf8 & 0xC0) { utf8NumBytesRemaining = 2; result += basicCodePointSize; } else if (*utf8 & 0xE0) { utf8NumBytesRemaining = 3; result += basicCodePointSize; } else if (*utf8 & 0xF0) { utf8NumBytesRemaining = 4; result += supplementaryCodePointSize; } else { // Invalid input; nothing we can do. break; } while (*utf8 && utf8NumBytesRemaining) { utf8NumBytesRemaining--; utf8++; } if (utf8NumBytesRemaining > 0) { // Invalid input; nothing we can do. break; } } // Add enough for NUL expressed in the target encoding. result += UNICODE_UTF16_CODE_UNITS_PADDING * basicCodePointSize; return result; } /* *----------------------------------------------------------------------------- * * Unicode_CopyBytes -- * * Encodes the Unicode string using the specified encoding into * the specified buffer and NUL-terminates it, writing at most * maxLengthInBytes bytes in total to the buffer. * * Results: * FALSE on conversion failure or if the Unicode string requires * more than maxLengthInBytes bytes to be encoded in the specified * encoding, including NUL termination. (Call * Unicode_BytesRequired(str, encoding) to get the correct * length.). Returns TRUE if no truncation was required. In * either case, if retLength is not NULL, *retLength contains the * number of bytes actually written to the buffer upon return. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool Unicode_CopyBytes(void *destBuffer, // OUT ConstUnicode srcBuffer, // IN size_t maxLengthInBytes, // IN size_t *retLength, // OUT StringEncoding encoding) // IN { const char *utf8Str = (const char *)srcBuffer; Bool success = FALSE; size_t copyBytes = 0; encoding = Unicode_ResolveEncoding(encoding); switch (encoding) { case STRING_ENCODING_US_ASCII: if (!UnicodeSanityCheck(utf8Str, -1, encoding)) { break; } // fall through case STRING_ENCODING_UTF8: { size_t len = strlen(utf8Str); copyBytes = MIN(len, maxLengthInBytes - 1); memcpy(destBuffer, utf8Str, copyBytes); /* * If we truncated, force a null termination in a UTF-8 safe * manner. */ if (copyBytes >= len) { success = TRUE; } else { if (encoding == STRING_ENCODING_UTF8) { copyBytes = CodeSet_Utf8FindCodePointBoundary(destBuffer, copyBytes); } } ((char*)destBuffer)[copyBytes] = '\0'; } break; case STRING_ENCODING_UTF16_LE: { char *utf16Buf; size_t utf16BufLen; if (!CodeSet_Utf8ToUtf16le(utf8Str, strlen(utf8Str), &utf16Buf, &utf16BufLen)) { // input should be valid UTF-8, no conversion error possible ASSERT_MEM_ALLOC(FALSE); break; } copyBytes = MIN(utf16BufLen, maxLengthInBytes - 2); memcpy(destBuffer, utf16Buf, copyBytes); copyBytes = CodeSet_Utf16FindCodePointBoundary(destBuffer, copyBytes); ((utf16_t*)destBuffer)[copyBytes / 2] = 0; free(utf16Buf); if (copyBytes >= utf16BufLen) { success = TRUE; } break; } default: { char *currentBuf; size_t currentBufSize; if (!CodeSet_GenericToGeneric("UTF-8", utf8Str, strlen(utf8Str), Unicode_EncodingEnumToName(encoding), CSGTG_NORMAL, ¤tBuf, ¤tBufSize)) { // XXX can't distinguish error cause break; } copyBytes = MIN(currentBufSize, maxLengthInBytes - 1); memcpy(destBuffer, currentBuf, copyBytes); free(currentBuf); /* * XXX this isn't quite correct, we still need to truncate on * a code point boundary, based on the current encoding type, * rather than just null terminate blindly. */ ((char*)destBuffer)[copyBytes] = 0; if (copyBytes >= currentBufSize) { success = TRUE; } } break; } if (retLength) { *retLength = copyBytes; } return success; } /* *----------------------------------------------------------------------------- * * Unicode_GetAllocBytes -- * * Allocates and returns a NUL terminated buffer into which the contents * of the unicode string are extracted using the specified encoding. * * NOTE: The length of the NUL can depend on the encoding. * UTF-16 NUL is "\0\0"; UTF-32 NUL is "\0\0\0\0". * * NULL is returned for NULL argument. * * Results: * NULL if argument is NULL. * Otherwise, pointer to the dynamically allocated memory * or NULL on conversion failure. * The caller is responsible to free the memory allocated * by this routine. * * Side effects: * None * *----------------------------------------------------------------------------- */ void * Unicode_GetAllocBytes(ConstUnicode str, // IN: StringEncoding encoding) // IN: { if (str == NULL) { return NULL; } return UnicodeGetAllocBytesInternal(str, encoding, -1, NULL); } /* *----------------------------------------------------------------------------- * * Unicode_GetAllocBytesWithLength -- * * Allocates and returns a buffer into which the contents of the unicode * string of the specified length are extracted using the specified * encoding. * * NOTE: The buffer returned is always NUL terminated. The length of * the NUL can depend on the encoding. UTF-16 NUL is "\0\0"; * UTF-32 NUL is "\0\0\0\0". * * NULL is returned for NULL argument. * * Results: * NULL if argument is NULL. * Otherwise, pointer to the dynamically allocated memory * or NULL on conversion failure. * The caller is responsible to free the memory allocated * by this routine. * * Side effects: * None * *----------------------------------------------------------------------------- */ void * Unicode_GetAllocBytesWithLength(ConstUnicode str, // IN: StringEncoding encoding, // IN: ssize_t lengthInBytes) // IN: { if (str == NULL) { return NULL; } ASSERT(lengthInBytes >= 0); return UnicodeGetAllocBytesInternal(str, encoding, lengthInBytes, NULL); } /* *----------------------------------------------------------------------------- * * UnicodeGetAllocBytesInternal -- * * Encodes the Unicode string using the specified encoding into * an allocated, null-terminated buffer. * * Results: * The converted string in an allocated buffer, * or NULL on conversion failure. * * The length of the result (in bytes, without termination) * in retLength. * * Side effects: * Panic on memory allocation failure. * *----------------------------------------------------------------------------- */ void * UnicodeGetAllocBytesInternal(ConstUnicode ustr, // IN StringEncoding encoding, // IN ssize_t lengthInBytes, // IN size_t *retLength) // OUT: optional { const char *utf8Str = ustr; char *result = NULL; ASSERT(ustr != NULL); encoding = Unicode_ResolveEncoding(encoding); if (lengthInBytes == -1) { lengthInBytes = Unicode_LengthInBytes(ustr, STRING_ENCODING_UTF8); } switch (encoding) { case STRING_ENCODING_US_ASCII: if (!UnicodeSanityCheck(utf8Str, lengthInBytes, encoding)) { break; } // fall through case STRING_ENCODING_UTF8: result = Util_SafeMalloc(lengthInBytes + 1); memcpy(result, utf8Str, lengthInBytes + 1); if (retLength != NULL) { *retLength = lengthInBytes; } break; case STRING_ENCODING_UTF16_LE: if (!CodeSet_Utf8ToUtf16le(utf8Str, lengthInBytes, &result, retLength)) { // input should be valid UTF-8, no conversion error possible ASSERT_MEM_ALLOC(FALSE); } break; default: if (!CodeSet_GenericToGeneric("UTF-8", utf8Str, lengthInBytes, Unicode_EncodingEnumToName(encoding), CSGTG_NORMAL, &result, retLength)) { // XXX can't distinguish error cause ASSERT(result == NULL); } } return result; } /* *----------------------------------------------------------------------------- * * UnicodeAllocStatic -- * * Internal helper function to allocate a new Unicode string * given an array of bytes in US-ASCII encoding. * * If 'unescape' is TRUE, unescapes \\uABCD to U+ABCD, and * \\U001FABCD to U+1FABCD. * * Results: * The allocated Unicode string. * * Side effects: * None * *----------------------------------------------------------------------------- */ Unicode UnicodeAllocStatic(const char *asciiBytes, // IN Bool unescape) // IN { utf16_t *utf16; // Explicitly use int8 so we don't depend on whether char is signed. const int8 *byte = (const int8 *)asciiBytes; size_t utf16Offset = 0; Unicode result; ASSERT(asciiBytes); if (!unescape) { DEBUG_ONLY( while (*byte > 0) { byte++; } // All input must be 7-bit US-ASCII. ASSERT(*byte == 0); ); return Util_SafeStrdup(asciiBytes); } utf16 = Util_SafeMalloc(sizeof *utf16 * (strlen(asciiBytes) + 1)); while (TRUE) { size_t hexDigitsRemaining; uint32 escapedCodePoint = 0; Bool foundEscapedCodePoint = FALSE; if (*byte == '\0') { utf16[utf16Offset] = 0; break; } // Only US-ASCII bytes are allowed as input. ASSERT_NOT_IMPLEMENTED(*byte > 0); if (*byte != '\\') { utf16[utf16Offset++] = *byte; byte++; continue; } // Handle the backslash. byte++; if (*byte == '\0') { // We'll fall out at the top of the loop. continue; } ASSERT_NOT_IMPLEMENTED(*byte > 0); switch (*byte) { case 'u': /* * \\uABCD must have exactly four hexadecimal digits after * the escape, denoting the Unicode code point U+ABCD. */ foundEscapedCodePoint = TRUE; hexDigitsRemaining = 4; break; case 'U': /* * \\U0010CDEF must have exactly eight hexadecimal digits * after the escape, denoting the Unicode code point U+10CDEF. */ foundEscapedCodePoint = TRUE; hexDigitsRemaining = 8; break; default: // Unsupported escape; treat the next byte literally. hexDigitsRemaining = 0; utf16[utf16Offset++] = *byte; break; } byte++; while (hexDigitsRemaining) { uint8 hexValue; if (*byte >= '0' && *byte <= '9') { hexValue = *byte - '0'; } else if (*byte >= 'A' && *byte <= 'F') { hexValue = *byte - 'A' + 0xA; } else if (*byte >= 'a' && *byte <= 'f') { hexValue = *byte - 'a' + 0xA; } else { NOT_IMPLEMENTED(); } escapedCodePoint = (escapedCodePoint << 4) | hexValue; byte++; hexDigitsRemaining--; } if (foundEscapedCodePoint) { ASSERT_NOT_IMPLEMENTED(escapedCodePoint <= 0x10FFFF); if (U16_LENGTH(escapedCodePoint) == 1) { utf16[utf16Offset++] = (utf16_t)escapedCodePoint; } else { utf16[utf16Offset++] = U16_LEAD(escapedCodePoint); utf16[utf16Offset++] = U16_TRAIL(escapedCodePoint); } } } result = Unicode_AllocWithUTF16(utf16); free(utf16); return result; } open-vm-tools-9.4.0-1280544/lib/unicode/unicodeInt.h0000644765153500003110000000352312220061556020110 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * unicodeInt.h -- * * Internal functions common to all implementations of the * Unicode library. */ #ifndef _UNICODE_INT_H #define _UNICODE_INT_H #include "unicodeTypes.h" #ifdef __cplusplus extern "C" { #endif Unicode UnicodeAllocInternal(const void *buffer, ssize_t lengthInBytes, StringEncoding encoding, Bool strict); Unicode UnicodeAllocStatic(const char *asciiBytes, Bool unescape); utf16_t UnicodeSimpleCaseFold(utf16_t codeUnit); void *UnicodeGetAllocBytesInternal(ConstUnicode src, StringEncoding encoding, ssize_t lengthInBytes, size_t *retLength); Bool UnicodeSanityCheck(const void *buffer, ssize_t lengthInBytes, StringEncoding encoding); #ifdef __cplusplus } #endif #endif // _UNICODE_INT_H open-vm-tools-9.4.0-1280544/lib/unicode/unicodeSimpleOperations.c0000644765153500003110000004341312220061556022650 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * unicodeSimpleOperations.c -- * * Simple UTF-8 implementation of unicodeOperations.h interface. */ #include "vmware.h" #include "util.h" #include "str.h" #include "unicodeBase.h" #include "unicodeInt.h" #include "unicodeOperations.h" #include "codeset.h" /* *----------------------------------------------------------------------------- * * Unicode_LengthInCodePoints -- * * Returns the length of the unicode string in code points * ("unicode characters"). * * Results: * As above * * Side effects: * None * *----------------------------------------------------------------------------- */ UnicodeIndex Unicode_LengthInCodePoints(ConstUnicode str) // IN: { return CodeSet_LengthInCodePoints(str); } /* *----------------------------------------------------------------------------- * * Unicode_CompareRange -- * * Compares ranges of two Unicode strings for canonical * equivalence in code point order. * * Canonical equivalence means the two strings represent the same * Unicode code points, regardless of the order of combining * characters or use of compatibility singletons. * * See Unicode Standard Annex #15 (Unicode Normalization Forms) * for more on canonical equivalence and composition. * * If ignoreCase is TRUE, then the two strings are case-folded * (converted to upper-case, then converted to lower-case) in a * locale-agnostic manner before comparing. * * Indices and lengths that are out of bounds are pinned to the * edges of the string. * * Pass -1 for any length parameter to indicate "from start until * end of string". * * The start and length arguments are in code points - unicode * "characters" - not bytes! * * Results: * -1 if str1 < str2, 0 if str1 == str2, 1 if str1 > str2. * * Side effects: * None * *----------------------------------------------------------------------------- */ int Unicode_CompareRange(ConstUnicode str1, // IN: UnicodeIndex str1Start, // IN: UnicodeIndex str1Length, // IN: ConstUnicode str2, // IN: UnicodeIndex str2Start, // IN: UnicodeIndex str2Length, // IN: Bool ignoreCase) // IN: { int result = -1; Unicode substr1 = NULL; Unicode substr2 = NULL; utf16_t *substr1UTF16 = NULL; utf16_t *substr2UTF16 = NULL; UnicodeIndex i = 0; UnicodeIndex utf16Index; utf16_t codeUnit1; utf16_t codeUnit2; uint32 codePoint1; uint32 codePoint2; /* * TODO: Allocating substrings is a performance hit. We should do this * search in-place. (However, searching UTF-8 requires tender loving * care, and it's just easier to search UTF-16.) */ substr1 = Unicode_Substr(str1, str1Start, str1Length); if (!substr1) { goto out; } substr2 = Unicode_Substr(str2, str2Start, str2Length); if (!substr2) { goto out; } /* * XXX TODO: Need to normalize the incoming strings to NFC or NFD. */ substr1UTF16 = Unicode_GetAllocUTF16(substr1); if (!substr1UTF16) { goto out; } substr2UTF16 = Unicode_GetAllocUTF16(substr2); if (!substr2UTF16) { goto out; } /* * TODO: This is the naive string search algorithm, which is O(n * m). We * can do better with KMP or Boyer-Moore if this proves to be a bottleneck. */ while (TRUE) { codeUnit1 = *(substr1UTF16 + i); codeUnit2 = *(substr2UTF16 + i); /* * TODO: Simple case folding doesn't handle the situation where more * than one code unit is needed to store the result of the case folding. * * This means that German "straBe" (where B = sharp S, U+00DF) will not * match "STRASSE", even though the two strings are the same. */ if (ignoreCase) { codeUnit1 = UnicodeSimpleCaseFold(codeUnit1); codeUnit2 = UnicodeSimpleCaseFold(codeUnit2); } if (codeUnit1 != codeUnit2) { break; } if (codeUnit1 == 0) { // End of both strings reached: strings are equal. result = 0; goto out; } i++; } /* * The two UTF-16 code units differ. If they're the first code unit of a * surrogate pair (for Unicode values past U+FFFF), decode the surrogate * pair into a full Unicode code point. */ if (U16_IS_SURROGATE(codeUnit1)) { ssize_t substrUTF16Len = Unicode_UTF16Strlen(substr1UTF16); // U16_NEXT modifies the index, so let it work on a copy. utf16Index = i; // Decode the surrogate if needed. U16_NEXT(substr1UTF16, utf16Index, substrUTF16Len, codePoint1); } else { // Not a surrogate? Then the code point value is the code unit. codePoint1 = codeUnit1; } if (U16_IS_SURROGATE(codeUnit2)) { ssize_t substrUTF16Len = Unicode_UTF16Strlen(substr2UTF16); utf16Index = i; U16_NEXT(substr2UTF16, utf16Index, substrUTF16Len, codePoint2); } else { codePoint2 = codeUnit2; } if (codePoint1 < codePoint2) { result = -1; } else if (codePoint1 > codePoint2) { result = 1; } else { // If we hit the end of the string, we've already gone to 'out'. NOT_REACHED(); } out: free(substr1UTF16); free(substr2UTF16); Unicode_Free(substr1); Unicode_Free(substr2); return result; } /* *----------------------------------------------------------------------------- * * Unicode_FindSubstrInRange -- * * Searches the string 'str' in the range [strStart, strStart+strLength) * for the first occurrence of the code units of 'strToFind' * in the range [strToFindStart, strToFindStart+strToFindLength). * * Indices and lengths that are out of bounds are pinned to the * edges of the string. * * Pass -1 for any length parameter to indicate "from start until * end of string". * * The start and length arguments are in code points - unicode * "characters" - not bytes! * * Results: * If 'strToFind' exists inside 'str' in the specified range, * returns the first starting index of 'strToFind' in that range. * * Otherwise, returns UNICODE_INDEX_NOT_FOUND. * * Side effects: * None * *----------------------------------------------------------------------------- */ UnicodeIndex Unicode_FindSubstrInRange(ConstUnicode str, // IN: UnicodeIndex strStart, // IN: UnicodeIndex strLength, // IN: ConstUnicode strToFind, // IN: UnicodeIndex strToFindStart, // IN: UnicodeIndex strToFindLength) // IN: { UnicodeIndex index; uint32 *utf32Source = NULL; uint32 *utf32Search = NULL; ASSERT(str); ASSERT(strStart >= 0); ASSERT((strLength >= 0) || (strLength == -1)); ASSERT(strToFind); ASSERT(strToFindStart >= 0); ASSERT((strToFindLength >= 0) || (strToFindLength == -1)); /* * Convert the string to be searched and the search string to UTF32. */ if (!CodeSet_UTF8ToUTF32(str, (char **) &utf32Source)) { Panic("%s: invalid UTF8 string @ %p\n", __FUNCTION__, str); } if (!CodeSet_UTF8ToUTF32(strToFind, (char **) &utf32Search)) { Panic("%s: invalid UTF8 string @ %p\n", __FUNCTION__, strToFind); } /* * Do any bounds cleanup and checking that is necessary... */ if (strLength < 0) { strLength = Unicode_LengthInCodePoints(str) - strStart; } if (strToFindLength < 0) { strToFindLength = Unicode_LengthInCodePoints(strToFind) - strToFindStart; } if (strLength < strToFindLength) { index = UNICODE_INDEX_NOT_FOUND; goto bail; } /* * Yes, this may be viewed as a bit strange but this is what strstr does. */ if (strToFindLength == 0) { index = strStart; goto bail; } /* * Attempt to find the first occurence of the search string in the string * to be searched. */ for (index = strStart; index <= (strStart + strLength - strToFindLength); index++) { UnicodeIndex i; Bool match = FALSE; UnicodeIndex indexSrc = index; UnicodeIndex indexSrch = strToFindStart; for (i = 0; i < strToFindLength; i++) { match = (utf32Source[indexSrc++] == utf32Search[indexSrch++]); if (!match) { break; } } if (match) { goto bail; } } index = UNICODE_INDEX_NOT_FOUND; bail: free(utf32Source); free(utf32Search); return index; } /* *----------------------------------------------------------------------------- * * Unicode_FindLastSubstrInRange -- * * Searches the string 'str' in the range [strStart, strStart+strLength) * for the last occurrence of the code units of 'strToFind' * in the range [strToFindStart, strToFindStart+strToFindLength). * * Indices and lengths that are out of bounds are pinned to the * edges of the string. * * Pass -1 for any length parameter to indicate "from start until * end of string". * * The start and length arguments are in code points - unicode * "characters" - not bytes! * * Results: * If 'strToFind' exists inside 'str' in the specified range, * returns the last starting index of 'strToFind' in that range. * * Otherwise, returns UNICODE_INDEX_NOT_FOUND. * * Side effects: * None * *----------------------------------------------------------------------------- */ UnicodeIndex Unicode_FindLastSubstrInRange(ConstUnicode str, // IN: UnicodeIndex strStart, // IN: UnicodeIndex strLength, // IN: ConstUnicode strToFind, // IN: UnicodeIndex strToFindStart, // IN: UnicodeIndex strToFindLength) // IN: { UnicodeIndex index; uint32 *utf32Source = NULL; uint32 *utf32Search = NULL; ASSERT(str); ASSERT(strStart >= 0); ASSERT((strLength >= 0) || (strLength == -1)); ASSERT(strToFind); ASSERT(strToFindStart >= 0); ASSERT((strToFindLength >= 0) || (strToFindLength == -1)); /* * Convert the string to be searched and the search string to UTF32. */ if (!CodeSet_UTF8ToUTF32(str, (char **) &utf32Source)) { Panic("%s: invalid UTF8 string @ %p\n", __FUNCTION__, str); } if (!CodeSet_UTF8ToUTF32(strToFind, (char **) &utf32Search)) { Panic("%s: invalid UTF8 string @ %p\n", __FUNCTION__, strToFind); } /* * Do any bounds cleanup and checking that is necessary... */ if (strLength < 0) { strLength = Unicode_LengthInCodePoints(str) - strStart; } if (strToFindLength < 0) { strToFindLength = Unicode_LengthInCodePoints(strToFind) - strToFindStart; } if (strLength < strToFindLength) { index = UNICODE_INDEX_NOT_FOUND; goto bail; } /* * Yes, this may be viewed as a bit strange but this is what strstr does. */ if (strToFindLength == 0) { index = strStart; goto bail; } /* * Attempt to find the last occurence of the search string in the string * to be searched. */ for (index = strStart + strLength - strToFindLength; index >= strStart; index--) { UnicodeIndex i; Bool match = FALSE; UnicodeIndex indexSrc = index; UnicodeIndex indexSrch = strToFindStart; for (i = 0; i < strToFindLength; i++) { match = (utf32Source[indexSrc++] == utf32Search[indexSrch++]); if (!match) { break; } } if (match) { goto bail; } } index = UNICODE_INDEX_NOT_FOUND; bail: free(utf32Source); free(utf32Search); return index; } /* *----------------------------------------------------------------------------- * * Unicode_Substr -- * * Allocates and returns a substring of 'str'. * * Indices and lengths that are out of bounds are pinned to the * edges of the string. * * Pass -1 for the length parameter to indicate "from start until * end of string". * * The start and length arguments are in code points - unicode * "characters" - not bytes! * * Results: * The newly-allocated substring of 'str' in the range [index, * index + length). Caller must free with Unicode_Free. * * Side effects: * None * *----------------------------------------------------------------------------- */ Unicode Unicode_Substr(ConstUnicode str, // IN: UnicodeIndex start, // IN: UnicodeIndex length) // IN: { char *substr; uint32 codePointLen; uint32 *utf32 = NULL; ASSERT(str); ASSERT((start >= 0) || (start == -1)); ASSERT((length >= 0) || (length == -1)); if (!CodeSet_UTF8ToUTF32(str, (char **) &utf32)) { Panic("%s: invalid UTF8 string @ %p\n", __FUNCTION__, str); } codePointLen = 0; while (utf32[codePointLen] != 0) { codePointLen++; } if ((start < 0) || (start > codePointLen)) { start = codePointLen; } if ((length < 0) || ((start + length) > codePointLen)) { length = codePointLen - start; } utf32[start + length] = 0; CodeSet_UTF32ToUTF8((char *) &utf32[start], &substr); free(utf32); return substr; } /* *----------------------------------------------------------------------------- * * Unicode_ReplaceRange -- * * Core operation upon which append, insert, replace, and remove * are based. * * Replaces the code units of destination in the range * [destinationStart, destinationLength) with the code units of * source in the range [sourceStart, sourceLength). * * Indices and lengths that are out of bounds are pinned to the * edges of the string. * * Pass -1 for any length parameter to indicate "from start until * end of string". * * The start and length arguments are in code points - unicode * "characters" - not bytes! * * Results: * A newly-allocated string containing the results of the replace * operation. Caller must free with Unicode_Free. * * Side effects: * None * *----------------------------------------------------------------------------- */ Unicode Unicode_ReplaceRange(ConstUnicode dest, // IN: UnicodeIndex destStart, // IN: UnicodeIndex destLength, // IN: ConstUnicode src, // IN: UnicodeIndex srcStart, // IN: UnicodeIndex srcLength) // IN: { Unicode result; Unicode stringOne; Unicode stringTwo; Unicode stringThree; ASSERT(dest); ASSERT((destStart >= 0) || (destStart == -1)); ASSERT((destLength >= 0) || (destLength == -1)); ASSERT(src); ASSERT((srcStart >= 0) || (srcStart == -1)); ASSERT((srcLength >= 0) || (srcLength == -1)); stringOne = Unicode_Substr(dest, 0, destStart); stringTwo = Unicode_Substr(src, srcStart, srcLength); stringThree = Unicode_Substr(dest, destStart + destLength, -1); result = Unicode_Join(stringOne, stringTwo, stringThree, NULL); Unicode_Free(stringOne); Unicode_Free(stringTwo); Unicode_Free(stringThree); return result; } /* *----------------------------------------------------------------------------- * * Unicode_Join -- * * Allocates and returns a new string containing the 'first' followed by * all the unicode strings specified as optional arguments (which must * be of type ConstUnicode). Appending ceases when a NULL pointer is * detected. * * Results: * The newly-allocated string. Caller must free with Unicode_Free. * * Side effects: * None * *----------------------------------------------------------------------------- */ Unicode Unicode_Join(ConstUnicode first, // IN: ...) // IN: { Unicode result; if (first == NULL) { result = NULL; } else { va_list args; ConstUnicode cur; result = Unicode_Duplicate(first); va_start(args, first); while ((cur = va_arg(args, ConstUnicode)) != NULL) { Unicode temp; temp = Unicode_Format("%s%s", result, cur); Unicode_Free(result); result = temp; } va_end(args); } return result; } /* *----------------------------------------------------------------------------- * * Unicode_Format -- * * Format a Unicode string (roughly equivalent to Str_Asprintf()). * * Results: * The formatted string. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Unicode Unicode_Format(const char *fmt, // IN: the format ...) // IN: the arguments { va_list args; char *p; va_start(args, fmt); p = Str_Vasprintf(NULL, fmt, args); va_end(args); return p; } open-vm-tools-9.4.0-1280544/lib/unicode/Makefile.am0000644765153500003110000000246112220061556017672 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libUnicode.la libUnicode_la_SOURCES = libUnicode_la_SOURCES += unicodeCommon.c libUnicode_la_SOURCES += unicodeSimpleBase.c libUnicode_la_SOURCES += unicodeSimpleCaseFolding.c libUnicode_la_SOURCES += unicodeSimpleTypes.c libUnicode_la_SOURCES += unicodeSimpleOperations.c libUnicode_la_SOURCES += unicodeSimpleTransforms.c libUnicode_la_SOURCES += unicodeStatic.c if HAVE_ICU libUnicode_la_SOURCES += unicodeICU.c endif open-vm-tools-9.4.0-1280544/lib/unicode/unicodeSimpleTypes.c0000644765153500003110000027555012220061556021642 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * unicodeSimpleTypes.c -- * * Basic types and cache handling for simple UTF-8 implementation * of Unicode library interface. */ #include #include #include #include "unicodeBase.h" #include "unicodeInt.h" #include "codeset.h" #include "vm_assert.h" #include "util.h" #include "hashTable.h" #include "vm_atomic.h" static char *UnicodeNormalizeEncodingName(const char *encoding); /* * Cross reference of IANA character set names, windows code pages * and ICU encodings * * See: http://www.iana.org/assignments/character-sets * http://msdn2.microsoft.com/en-us/library/ms776446(VS.85).aspx * http://demo.icu-project.org/icu-bin/convexp * * If you add new StringEncodings to this table, you must keep the * StringEncoding enum in lib/public/unicodeTypes.h in sync! */ #define MAXCHARSETNAMES 21 #define MIBUNDEF (-1) #define WINUNDEF (-1) #define SUPPORTED TRUE #define UNSUPPORTED FALSE #define IN_FULL_ICU FALSE static struct xRef { int MIBenum; // Assigned by IANA int winACP; // Windows code page from GetACP() StringEncoding encoding; // ICU encoding enum Bool isSupported; // VMware supported encoding int preferredMime; // Index of preferred MIME name char *names[MAXCHARSETNAMES]; // Encoding name and aliases } xRef[] = { /* * Source: ECMA registry */ { 3, 20127, STRING_ENCODING_US_ASCII, SUPPORTED, 4, { "ANSI_X3.4-1968", "iso-ir-6", "ANSI_X3.4-1986", "ISO_646.irv:1991", "ASCII", "ISO646-US", "US-ASCII", "us", "IBM367", "cp367", "csASCII", "646", "ascii7", NULL } }, /* * Source: ECMA registry */ { 4, 28591, STRING_ENCODING_ISO_8859_1, SUPPORTED, 3, { "ISO_8859-1:1987", "iso-ir-100", "ISO_8859-1", "ISO-8859-1", "latin1", "l1", "IBM819", "CP819", "csISOLatin1", "8859_1", "819", NULL } }, /* * Source: ECMA registry */ { 5, 28592, STRING_ENCODING_ISO_8859_2, SUPPORTED, 3, { "ISO_8859-2:1987", "iso-ir-101", "ISO_8859-2", "ISO-8859-2", "latin2", "l2", "csISOLatin2", "ibm-912_P100-1995", "ibm-912", "8859_2", "cp912", "912", NULL } }, /* * Source: ECMA registry */ { 6, 28593, STRING_ENCODING_ISO_8859_3, SUPPORTED, 3, { "ISO_8859-3:1988", "iso-ir-109", "ISO_8859-3", "ISO-8859-3", "latin3", "l3", "csISOLatin3", "ibm-913_P100-2000", "ibm-913", "8859_3", "cp913", "913", NULL } }, /* * Source: ECMA registry */ { 7, 28594, STRING_ENCODING_ISO_8859_4, SUPPORTED, 3, { "ISO_8859-4:1988", "iso-ir-110", "ISO_8859-4", "ISO-8859-4", "latin4", "l4", "csISOLatin4", "ibm-914_P100-1995", "ibm-914", "8859_4", "cp914", "914", NULL } }, /* * Source: ECMA registry */ { 8, 28595, STRING_ENCODING_ISO_8859_5, SUPPORTED, 3, { "ISO_8859-5:1988", "iso-ir-144", "ISO_8859-5", "ISO-8859-5", "cyrillic", "csISOLatinCyrillic", "ibm-915_P100-1995", "ibm-915", "8859_5", "cp915", "915", NULL } }, /* * Source: ECMA registry */ { 9, 28596, STRING_ENCODING_ISO_8859_6, SUPPORTED, 3, { "ISO_8859-6:1987", "iso-ir-127", "ISO_8859-6", "ISO-8859-6", "ECMA-114", "ASMO-708", "arabic", "csISOLatinArabic", "ibm-1089_P100-1995", "ibm-1089", "8859_6", "cp1089", "1089", NULL } }, /* * Source: Windows duplicate of ISO-8859-6 */ { 9, 708, STRING_ENCODING_ISO_8859_6, SUPPORTED, 0, { "ASMO-708", NULL } }, /* * Source: ECMA registry, ICU almost completely duplicates this entry with * ibm-813 (see below), which is an older version */ { 10, 28597, STRING_ENCODING_ISO_8859_7, SUPPORTED, 3, { "ISO_8859-7:1987", "iso-ir-126", "ISO_8859-7", "ISO-8859-7", "ELOT_928", "ECMA-118", "greek", "greek8", "csISOLatinGreek", "ibm-9005_X110-2007", "ibm-9005", "sun_eu_greek", NULL } }, /* * Source: ICU */ { MIBUNDEF, WINUNDEF, STRING_ENCODING_IBM_813, IN_FULL_ICU, 0, { "ibm-813_P100-1995", "ibm-813", "cp813", "813", "8859_7", NULL } }, /* * Source: ECMA registry */ { 11, 28598, STRING_ENCODING_ISO_8859_8, SUPPORTED, 3, { "ISO_8859-8:1988", "iso-ir-138", "ISO_8859-8", "ISO-8859-8", "hebrew", "csISOLatinHebrew", "ibm-5012_P100-1999", "ibm-5012", "8859_8", "hebrew8", NULL } }, /* * Source: ECMA registry */ { 12, 28599, STRING_ENCODING_ISO_8859_9, SUPPORTED, 3, { "ISO_8859-9:1989", "iso-ir-148", "ISO_8859-9", "ISO-8859-9", "latin5", "l5", "csISOLatin5", "ibm-920_P100-1995", "ibm-920", "8859_9", "cp920", "920", "ECMA-128", "turkish", "turkish8", NULL } }, /* * Source: ECMA registry */ { 13, WINUNDEF, STRING_ENCODING_ISO_8859_10, SUPPORTED, 0, { "ISO-8859-10", "iso-ir-157", "l6", "ISO_8859-10:1992", "csISOLatin6", "latin6", "iso-8859_10-1998", NULL } }, /* * Source: ECMA registry and ISO 6937-2:1983, not supported by ICU */ { 14, WINUNDEF, STRING_ENCODING_ISO_6937_2_ADD, UNSUPPORTED, 0, { "ISO_6937-2-add", "iso-ir-142", "csISOTextComm", NULL } }, /* * Source: JIS X 0201-1976. One byte only, this is equivalent to * JIS/Roman (similar to ASCII) plus eight-bit half-width * Katakana */ { 15, WINUNDEF, STRING_ENCODING_JIS_X0201, IN_FULL_ICU, 0, { "JIS_X0201", "X0201", "csHalfWidthKatakana", NULL } }, /* * Source: JIS X 0202-1991. Uses ISO 2022 escape sequences to * shift code sets as documented in JIS X 0202-1991. * ICU maps this to ISO-2022-JP-1 */ { 16, WINUNDEF, STRING_ENCODING_JIS_ENCODING, IN_FULL_ICU, 0, { "JIS_Encoding", "csJISEncoding", "JIS", NULL } }, /* * Source: This charset is an extension of csHalfWidthKatakana by * adding graphic characters in JIS X 0208. The CCS's are * JIS X0201:1997 and JIS X0208:1997. The * complete definition is shown in Appendix 1 of JIS * X0208:1997. * This charset can be used for the top-level media type "text". */ { 17, 932, STRING_ENCODING_SHIFT_JIS, SUPPORTED, 0, { "Shift_JIS", "MS_Kanji", "csShiftJIS", "ibm-943_P15A-2003", "ibm-943", "x-sjis", "x-ms-cp932", "cp932", "cp943c", "IBM-943C", "ms932", "pck", "sjis", "ibm-943_VSUB_VPUA", NULL } }, /* * Source: ICU, older version of Shift_JIS, use newer version above for * common entries between the two * */ { MIBUNDEF, WINUNDEF, STRING_ENCODING_IBM_943_P130_1999, SUPPORTED, 0, { "ibm-943_P130-1999", "cp943", "943", "ibm-943_VASCII_VSUB_VPUA", NULL } }, /* * Source: Standardized by OSF, UNIX International, and UNIX Systems * Laboratories Pacific. Uses ISO 2022 rules to select * code set 0: US-ASCII (a single 7-bit byte set) * code set 1: JIS X0208-1990 (a double 8-bit byte set) * restricted to A0-FF in both bytes * code set 2: Half Width Katakana (a single 7-bit byte set) * requiring SS2 as the character prefix * code set 3: JIS X0212-1990 (a double 7-bit byte set) * restricted to A0-FF in both bytes * requiring SS3 as the character prefix */ { 18, 20932, STRING_ENCODING_EUC_JP, IN_FULL_ICU, 2, { "Extended_UNIX_Code_Packed_Format_for_Japanese", "csEUCPkdFmtJapanese", "EUC-JP", "ibm-954_P101-2007", "ibm-954", "X-EUC-JP", "eucjis", "ujis", NULL } }, /* * Windows duplicate and older ICU version of EUC-JP */ { 18, 51932, STRING_ENCODING_IBM_33722, IN_FULL_ICU, 0, { "ibm-33722_P12A_P12A-2004_U2", "ibm-33722", "ibm-5050", "ibm-33722_VPUA", "IBM-eucJP", NULL } }, /* * Source: Used in Japan. Each character is 2 octets. * code set 0: US-ASCII (a single 7-bit byte set) * 1st byte = 00 * 2nd byte = 20-7E * code set 1: JIS X0208-1990 (a double 7-bit byte set) * restricted to A0-FF in both bytes * code set 2: Half Width Katakana (a single 7-bit byte set) * 1st byte = 00 * 2nd byte = A0-FF * code set 3: JIS X0212-1990 (a double 7-bit byte set) * restricted to A0-FF in * the first byte * and 21-7E in the second byte * * Not supported by ICU */ { 19, WINUNDEF, STRING_ENCODING_EXTENDED_UNIX_CODE_FIXED_WIDTH_FOR_JAPANESE, UNSUPPORTED, 0, { "Extended_UNIX_Code_Fixed_Width_for_Japanese", "csEUCFixWidJapanese", NULL } }, /* * Source: ECMA registry */ { 20, WINUNDEF, STRING_ENCODING_BS_4730, IN_FULL_ICU, 0, { "BS_4730", "iso-ir-4", "ISO646-GB", "gb", "uk", "csISO4UnitedKingdom", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 21, WINUNDEF, STRING_ENCODING_SEN_850200_C, UNSUPPORTED, 0, { "SEN_850200_C", "iso-ir-11", "ISO646-SE2", "se2", "csISO11SwedishForNames", NULL } }, /* * Source: ECMA registry */ { 22, WINUNDEF, STRING_ENCODING_IT, IN_FULL_ICU, 0, { "IT", "iso-ir-15", "ISO646-IT", "csISO15Italian", NULL } }, /* * Source: ECMA registry */ { 23, WINUNDEF, STRING_ENCODING_ES, IN_FULL_ICU, 0, { "ES", "iso-ir-17", "ISO646-ES", "csISO17Spanish", NULL } }, /* * Source: ECMA registry */ { 24, WINUNDEF, STRING_ENCODING_DIN_66003, IN_FULL_ICU, 0, { "DIN_66003", "iso-ir-21", "de", "ISO646-DE", "csISO21German", NULL } }, /* * Source: ECMA registry */ { 25, WINUNDEF, STRING_ENCODING_NS_4551_1, IN_FULL_ICU, 0, { "NS_4551-1", "iso-ir-60", "ISO646-NO", "no", "csISO60DanishNorwegian", "csISO60Norwegian1", NULL } }, /* * Source: ECMA registry */ { 26, WINUNDEF, STRING_ENCODING_NF_Z_62_010, IN_FULL_ICU, 0, { "NF_Z_62-010", "iso-ir-69", "ISO646-FR", "fr", "csISO69French", NULL } }, /* * Source: Universal Transfer Format (1), this is the multibyte * encoding, that subsets ASCII-7. It does not have byte * ordering issues. * * Not supported by ICU. */ { 27, WINUNDEF, STRING_ENCODING_ISO_10646_UTF_1, UNSUPPORTED, 0, { "ISO-10646-UTF-1", "csISO10646UTF1", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 28, WINUNDEF, STRING_ENCODING_ISO_646_BASIC_1983, UNSUPPORTED, 0, { "ISO_646.basic:1983", "ref", "csISO646basic1983", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 29, WINUNDEF, STRING_ENCODING_INVARIANT, UNSUPPORTED, 0, { "INVARIANT", "csINVARIANT", NULL } }, /* * Source: ECMA registry, ICU maps this to ASCII */ { 30, WINUNDEF, STRING_ENCODING_ISO_646_IRV_1983, SUPPORTED, 0, { "ISO_646.irv:1983", "iso-ir-2", "irv", "csISO2IntlRefVersion", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 31, WINUNDEF, STRING_ENCODING_NATS_SEFI, UNSUPPORTED, 0, { "NATS-SEFI", "iso-ir-8-1", "csNATSSEFI", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 32, WINUNDEF, STRING_ENCODING_NATS_SEFI_ADD, UNSUPPORTED, 0, { "NATS-SEFI-ADD", "iso-ir-8-2", "csNATSSEFIADD", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 33, WINUNDEF, STRING_ENCODING_NATS_DANO, UNSUPPORTED, 0, { "NATS-DANO", "iso-ir-9-1", "csNATSDANO", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 34, WINUNDEF, STRING_ENCODING_NATS_DANO_ADD, UNSUPPORTED, 0, { "NATS-DANO-ADD", "iso-ir-9-2", "csNATSDANOADD", NULL } }, /* * Source: ECMA registry */ { 35, WINUNDEF, STRING_ENCODING_SEN_850200_B, IN_FULL_ICU, 0, { "SEN_850200_B", "iso-ir-10", "FI", "ISO646-FI", "ISO646-SE", "se", "csISO10Swedish", NULL } }, /* * Source: ECMA registry */ { 36, 51949, STRING_ENCODING_KS_C_5601_1987, SUPPORTED, 0, { "KS_C_5601-1987", "ibm-970_P110_P110-2006_U2", "ibm-970", "EUC-KR", "csEUCKR", "ibm-eucKR", "KSC_5601", "5601", "cp970", "970", "ibm-970_VPUA", NULL } }, /* * Windows-949 code page for KS_C_5601 */ { 36, 949, STRING_ENCODING_WINDOWS_949, SUPPORTED, 0, { "windows-949-2000", "KS_C_5601-1989", "KS_C_5601-1987", "KSC_5601", "csKSC56011987", "korean", "iso-ir-149", "ms949", NULL } }, /* * Another ICU converter for KS_C_5601 */ { 36, WINUNDEF, STRING_ENCODING_IBM_1363, SUPPORTED, 0, { "ibm-1363_P11B-1998", "ibm-1363", "cp1363", "5601", "ksc", "ibm-1363_VSUB_VPUA", NULL } }, /* * Source: RFC-1557 (see also KS_C_5601-1987) */ { 37, 50225, STRING_ENCODING_ISO_2022_KR, IN_FULL_ICU, 0, { "ISO-2022-KR", "csISO2022KR", NULL } }, /* * Source: RFC-1468 (see also RFC-2237) * Windows-50221 and 50222 are routed here */ { 39, 50220, STRING_ENCODING_ISO_2022_JP, SUPPORTED, 0, { "ISO-2022-JP", "csISO2022JP", NULL } }, /* * Source: VMware */ { MIBUNDEF, WINUNDEF, STRING_ENCODING_ISO_2022_JP_1, IN_FULL_ICU, 0, { "ISO-2022-JP-1", "ibm-5054", NULL } }, /* * Source: RFC-1554 */ { 40, WINUNDEF, STRING_ENCODING_ISO_2022_JP_2, IN_FULL_ICU, 0, { "ISO-2022-JP-2", "csISO2022JP2", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 41, WINUNDEF, STRING_ENCODING_JIS_C6220_1969_JP, UNSUPPORTED, 0, { "JIS_C6220-1969-jp", "JIS_C6220-1969", "iso-ir-13", "katakana", "x0201-7", "csISO13JISC6220jp", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 42, WINUNDEF, STRING_ENCODING_JIS_C6220_1969_RO, UNSUPPORTED, 0, { "JIS_C6220-1969-ro", "iso-ir-14", "jp", "ISO646-JP", "csISO14JISC6220ro", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 43, WINUNDEF, STRING_ENCODING_PT, UNSUPPORTED, 0, { "PT", "iso-ir-16", "ISO646-PT", "csISO16Portuguese", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 44, WINUNDEF, STRING_ENCODING_GREEK7_OLD, UNSUPPORTED, 0, { "greek7-old", "iso-ir-18", "csISO18Greek7Old", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 45, WINUNDEF, STRING_ENCODING_LATIN_GREEK, UNSUPPORTED, 0, { "latin-greek", "iso-ir-19", "csISO19LatinGreek", NULL } }, /* * Source: ECMA registry */ { 46, WINUNDEF, STRING_ENCODING_NF_Z_62_010__1973_, IN_FULL_ICU, 0, { "NF_Z_62-010_(1973)", "iso-ir-25", "ISO646-FR1", "csISO25French", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 47, WINUNDEF, STRING_ENCODING_LATIN_GREEK_1, UNSUPPORTED, 0, { "Latin-greek-1", "iso-ir-27", "csISO27LatinGreek1", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 48, WINUNDEF, STRING_ENCODING_ISO_5427, UNSUPPORTED, 0, { "ISO_5427", "iso-ir-37", "csISO5427Cyrillic", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 49, WINUNDEF, STRING_ENCODING_JIS_C6226_1978, UNSUPPORTED, 0, { "JIS_C6226-1978", "iso-ir-42", "csISO42JISC62261978", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 50, WINUNDEF, STRING_ENCODING_BS_VIEWDATA, UNSUPPORTED, 0, { "BS_viewdata", "iso-ir-47", "csISO47BSViewdata", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 51, WINUNDEF, STRING_ENCODING_INIS, UNSUPPORTED, 0, { "INIS", "iso-ir-49", "csISO49INIS", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 52, WINUNDEF, STRING_ENCODING_INIS_8, UNSUPPORTED, 0, { "INIS-8", "iso-ir-50", "csISO50INIS8", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 53, WINUNDEF, STRING_ENCODING_INIS_CYRILLIC, UNSUPPORTED, 0, { "INIS-cyrillic", "iso-ir-51", "csISO51INISCyrillic", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 54, WINUNDEF, STRING_ENCODING_ISO_5427_1981, UNSUPPORTED, 0, { "ISO_5427:1981", "iso-ir-54", "ISO5427Cyrillic1981", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 55, WINUNDEF, STRING_ENCODING_ISO_5428_1980, UNSUPPORTED, 0, { "ISO_5428:1980", "iso-ir-55", "csISO5428Greek", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 56, WINUNDEF, STRING_ENCODING_GB_1988_80, UNSUPPORTED, 0, { "GB_1988-80", "iso-ir-57", "cn", "ISO646-CN", "csISO57GB1988", NULL } }, /* * Source: ECMA registry * Note that this encoding does not support ASCII as a subset */ { 57, 20936, STRING_ENCODING_GB_2312_80, IN_FULL_ICU, 0, { "GB_2312-80", "iso-ir-58", "chinese", "csISO58GB231280", "ibm-5478_P100-1995", "ibm-5478", "gb2312-1980", "GB2312.1980-0", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 58, WINUNDEF, STRING_ENCODING_NS_4551_2, UNSUPPORTED, 0, { "NS_4551-2", "ISO646-NO2", "iso-ir-61", "no2", "csISO61Norwegian2", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 59, WINUNDEF, STRING_ENCODING_VIDEOTEX_SUPPL, UNSUPPORTED, 0, { "videotex-suppl", "iso-ir-70", "csISO70VideotexSupp1", NULL } }, /* * Source: ECMA registry */ { 60, WINUNDEF, STRING_ENCODING_PT2, IN_FULL_ICU, 0, { "PT2", "iso-ir-84", "ISO646-PT2", "csISO84Portuguese2", NULL } }, /* * Source: ECMA registry */ { 61, WINUNDEF, STRING_ENCODING_ES2, IN_FULL_ICU, 0, { "ES2", "iso-ir-85", "ISO646-ES2", "csISO85Spanish2", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 62, WINUNDEF, STRING_ENCODING_MSZ_7795_3, UNSUPPORTED, 0, { "MSZ_7795.3", "iso-ir-86", "ISO646-HU", "hu", "csISO86Hungarian", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 63, WINUNDEF, STRING_ENCODING_JIS_C6226_1983, UNSUPPORTED, 0, { "JIS_C6226-1983", "iso-ir-87", "x0208", "JIS_X0208-1983", "csISO87JISX0208", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 64, WINUNDEF, STRING_ENCODING_GREEK7, UNSUPPORTED, 0, { "greek7", "iso-ir-88", "csISO88Greek7", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 65, WINUNDEF, STRING_ENCODING_ASMO_449, UNSUPPORTED, 0, { "ASMO_449", "ISO_9036", "arabic7", "iso-ir-89", "csISO89ASMO449", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 66, WINUNDEF, STRING_ENCODING_ISO_IR_90, UNSUPPORTED, 0, { "iso-ir-90", "csISO90", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 67, WINUNDEF, STRING_ENCODING_JIS_C6229_1984_A, UNSUPPORTED, 0, { "JIS_C6229-1984-a", "iso-ir-91", "jp-ocr-a", "csISO91JISC62291984a", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 68, WINUNDEF, STRING_ENCODING_JIS_C6229_1984_B, UNSUPPORTED, 0, { "JIS_C6229-1984-b", "iso-ir-92", "ISO646-JP-OCR-B", "jp-ocr-b", "csISO92JISC62991984b", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 69, WINUNDEF, STRING_ENCODING_JIS_C6229_1984_B_ADD, UNSUPPORTED, 0, { "JIS_C6229-1984-b-add", "iso-ir-93", "jp-ocr-b-add", "csISO93JIS62291984badd", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 70, WINUNDEF, STRING_ENCODING_JIS_C6229_1984_HAND, UNSUPPORTED, 0, { "JIS_C6229-1984-hand", "iso-ir-94", "jp-ocr-hand", "csISO94JIS62291984hand", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 71, WINUNDEF, STRING_ENCODING_JIS_C6229_1984_HAND_ADD, UNSUPPORTED, 0, { "JIS_C6229-1984-hand-add", "iso-ir-95", "jp-ocr-hand-add", "csISO95JIS62291984handadd", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 72, WINUNDEF, STRING_ENCODING_JIS_C6229_1984_KANA, UNSUPPORTED, 0, { "JIS_C6229-1984-kana", "iso-ir-96", "csISO96JISC62291984kana", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 73, WINUNDEF, STRING_ENCODING_ISO_2033_1983, UNSUPPORTED, 0, { "ISO_2033-1983", "iso-ir-98", "e13b", "csISO2033", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 74, WINUNDEF, STRING_ENCODING_ANSI_X3_110_1983, UNSUPPORTED, 0, { "ANSI_X3.110-1983", "iso-ir-99", "CSA_T500-1983", "NAPLPS", "csISO99NAPLPS", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 75, WINUNDEF, STRING_ENCODING_T_61_7BIT, UNSUPPORTED, 0, { "T.61-7bit", "iso-ir-102", "csISO102T617bit", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 76, 20261, STRING_ENCODING_T_61_8BIT, UNSUPPORTED, 0, { "T.61-8bit", "T.61", "iso-ir-103", "csISO103T618bit", NULL } }, /* * Source: ISO registry (formerly ECMA registry) * http://www.itscj.ipsj.jp/ISO-IR/111.pdf * Not supported by ICU */ { 77, WINUNDEF, STRING_ENCODING_ECMA_CYRILLIC, UNSUPPORTED, 0, { "ECMA-cyrillic", "iso-ir-111", "KOI8-E", "csISO111ECMACyrillic", NULL } }, /* * Source: ECMA registry */ { 78, WINUNDEF, STRING_ENCODING_CSA_Z243_4_1985_1, IN_FULL_ICU, 0, { "CSA_Z243.4-1985-1", "iso-ir-121", "ISO646-CA", "csa7-1", "ca", "csISO121Canadian1", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 79, WINUNDEF, STRING_ENCODING_CSA_Z243_4_1985_2, UNSUPPORTED, 0, { "CSA_Z243.4-1985-2", "iso-ir-122", "ISO646-CA2", "csa7-2", "csISO122Canadian2", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 80, WINUNDEF, STRING_ENCODING_CSA_Z243_4_1985_GR, UNSUPPORTED, 0, { "CSA_Z243.4-1985-gr", "iso-ir-123", "csISO123CSAZ24341985gr", NULL } }, /* * Source: RFC1556, ICU maps this to ISO-8859-6 */ { 81, WINUNDEF, STRING_ENCODING_ISO_8859_6_E, SUPPORTED, 2, { "ISO_8859-6-E", "csISO88596E", "ISO-8859-6-E", NULL } }, /* * Source: RFC1556, ICU maps this to ISO-8859-6 */ { 82, WINUNDEF, STRING_ENCODING_ISO_8859_6_I, SUPPORTED, 2, { "ISO_8859-6-I", "csISO88596I", "ISO-8859-6-I", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 83, WINUNDEF, STRING_ENCODING_T_101_G2, UNSUPPORTED, 0, { "T.101-G2", "iso-ir-128", "csISO128T101G2", NULL } }, /* * Source: RFC1556, ICU maps this to ISO-8859-8 */ { 84, WINUNDEF, STRING_ENCODING_ISO_8859_8_E, SUPPORTED, 2, { "ISO_8859-8-E", "csISO88598E", "ISO-8859-8-E", NULL } }, /* * Source: RFC1556, ICU maps this to ISO-8859-8 */ { 85, WINUNDEF, STRING_ENCODING_ISO_8859_8_I, SUPPORTED, 2, { "ISO_8859-8-I", "csISO88598I", "ISO-8859-8-I", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 86, WINUNDEF, STRING_ENCODING_CSN_369103, UNSUPPORTED, 0, { "CSN_369103", "iso-ir-139", "csISO139CSN369103", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 87, WINUNDEF, STRING_ENCODING_JUS_I_B1_002, UNSUPPORTED, 0, { "JUS_I.B1.002", "iso-ir-141", "ISO646-YU", "js", "yu", "csISO141JUSIB1002", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 88, WINUNDEF, STRING_ENCODING_IEC_P27_1, UNSUPPORTED, 0, { "IEC_P27-1", "iso-ir-143", "csISO143IECP271", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 89, WINUNDEF, STRING_ENCODING_JUS_I_B1_003_SERB, UNSUPPORTED, 0, { "JUS_I.B1.003-serb", "iso-ir-146", "serbian", "csISO146Serbian", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 90, WINUNDEF, STRING_ENCODING_JUS_I_B1_003_MAC, UNSUPPORTED, 0, { "JUS_I.B1.003-mac", "macedonian", "iso-ir-147", "csISO147Macedonian", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 91, WINUNDEF, STRING_ENCODING_GREEK_CCITT, UNSUPPORTED, 0, { "greek-ccitt", "iso-ir-150", "csISO150", "csISO150GreekCCITT", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 92, WINUNDEF, STRING_ENCODING_NC_NC00_10_81, UNSUPPORTED, 0, { "NC_NC00-10:81", "cuba", "iso-ir-151", "ISO646-CU", "csISO151Cuba", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 93, WINUNDEF, STRING_ENCODING_ISO_6937_2_25, UNSUPPORTED, 0, { "ISO_6937-2-25", "iso-ir-152", "csISO6937Add", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 94, WINUNDEF, STRING_ENCODING_GOST_19768_74, UNSUPPORTED, 0, { "GOST_19768-74", "ST_SEV_358-88", "iso-ir-153", "csISO153GOST1976874", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 95, WINUNDEF, STRING_ENCODING_ISO_8859_SUPP, UNSUPPORTED, 0, { "ISO_8859-supp", "iso-ir-154", "latin1-2-5", "csISO8859Supp", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 96, WINUNDEF, STRING_ENCODING_ISO_10367_BOX, UNSUPPORTED, 0, { "ISO_10367-box", "iso-ir-155", "csISO10367Box", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 97, WINUNDEF, STRING_ENCODING_LATIN_LAP, UNSUPPORTED, 0, { "latin-lap", "lap", "iso-ir-158", "csISO158Lap", NULL } }, /* * Source: ECMA registry, not supported by ICU */ { 98, WINUNDEF, STRING_ENCODING_JIS_X0212_1990, UNSUPPORTED, 0, { "JIS_X0212-1990", "x0212", "iso-ir-159", "csISO159JISX02121990", NULL } }, /* * Source: Danish Standard, DS 2089, February 1974 */ { 99, WINUNDEF, STRING_ENCODING_DS_2089, IN_FULL_ICU, 0, { "DS_2089", "DS2089", "ISO646-DK", "dk", "csISO646Danish", NULL } }, { 100, WINUNDEF, STRING_ENCODING_US_DK, UNSUPPORTED, 0, { "us-dk", "csUSDK", NULL } }, { 101, WINUNDEF, STRING_ENCODING_DK_US, UNSUPPORTED, 0, { "dk-us", "csDKUS", NULL } }, { 102, WINUNDEF, STRING_ENCODING_KSC5636, UNSUPPORTED, 0, { "KSC5636", "ISO646-KR", "csKSC5636", NULL } }, /* * Source: RFC 1642, not supported by ICU */ { 103, WINUNDEF, STRING_ENCODING_UNICODE_1_1_UTF_7, UNSUPPORTED, 0, { "UNICODE-1-1-UTF-7", "csUnicode11UTF7", NULL } }, /* * Source: RFC-1922 */ { 104, 50227, STRING_ENCODING_ISO_2022_CN, IN_FULL_ICU, 0, { "ISO-2022-CN", "csISO2022CN", NULL } }, /* * Source: RFC-1922 */ { 105, WINUNDEF, STRING_ENCODING_ISO_2022_CN_EXT, IN_FULL_ICU, 0, { "ISO-2022-CN-EXT", NULL } }, /* * Source: RFC 3629 */ { 106, 65001, STRING_ENCODING_UTF8, SUPPORTED, 0, { "UTF-8", "ibm-1208", "ibm-1209", "ibm-5304", "ibm-5305", "ibm-13496", "ibm-13497", "ibm-17592", "ibm-17593", "cp1208", NULL } }, /* * Source: ISO See * (http://www.iana.org/assignments/charset-reg/ISO-8859-13)[Tumasonis] */ { 109, 28603, STRING_ENCODING_ISO_8859_13, SUPPORTED, 0, { "ISO-8859-13", "ibm-921_P100-1995", "ibm-921", "8859_13", "cp921", "921", NULL } }, /* * Source: ISO See * (http://www.iana.org/assignments/charset-reg/ISO-8859-14) [Simonsen] */ { 110, WINUNDEF, STRING_ENCODING_ISO_8859_14, SUPPORTED, 0, { "ISO-8859-14", "iso-ir-199", "ISO_8859-14:1998", "ISO_8859-14", "latin8", "iso-celtic", "l8", NULL } }, /* * Source: ISO * Please see: */ { 111, 28605, STRING_ENCODING_ISO_8859_15, SUPPORTED, 0, { "ISO-8859-15", "ISO_8859-15", "Latin-9", "ibm-923_P100-1998", "ibm-923", "l9", "8859_15", "latin0", "csisolatin0", "csisolatin9", "cp923", "923", "iso8859_15_fdis", NULL } }, /* * Windows duplicate of ISO-8859-15 * windows-874: ANSI/OEM Thai */ { 111, 874, STRING_ENCODING_IBM_874, SUPPORTED, 0, { "ibm-874", "ibm-874_P100-1995", "cp874", "ibm-9066", "TIS-620", "tis620.2533", "eucTH", NULL } }, /* * Source: ISO */ { 112, WINUNDEF, STRING_ENCODING_ISO_8859_16, IN_FULL_ICU, 0, { "ISO-8859-16", "iso-ir-226", "ISO_8859-16:2001", "ISO_8859-16", "latin10", "l10", NULL } }, /* * Source: Chinese IT Standardization Technical Committee * Please see: */ { 113, 936, STRING_ENCODING_GBK, SUPPORTED, 0, { "GBK", "CP936", "MS936", "windows-936", "windows-936-2000", NULL } }, /* * Alternate ICU encoding for Windows-936 */ { MIBUNDEF, WINUNDEF, STRING_ENCODING_IBM_1386, SUPPORTED, 1, { "ibm-1386_P100-2001", "ibm-1386", "cp1386", "ibm-1386_VSUB_VPUA", NULL } }, /* * Source: Chinese IT Standardization Technical Committee * Please see: */ { 114, 54936, STRING_ENCODING_GB_18030, IN_FULL_ICU, 0, { "GB18030", "ibm-1392", NULL } }, /* * Source: Fujitsu-Siemens standard mainframe EBCDIC encoding * Please see: * * Not supported by ICU */ { 116, WINUNDEF, STRING_ENCODING_OSD_EBCDIC_DF03_IRV, UNSUPPORTED, 0, { "OSD_EBCDIC_DF03_IRV", NULL } }, /* * Source: Fujitsu-Siemens standard mainframe EBCDIC encoding * Please see: * * Not supported by ICU */ { 117, WINUNDEF, STRING_ENCODING_OSD_EBCDIC_DF04_1, UNSUPPORTED, 0, { "OSD_EBCDIC_DF04_1", NULL } }, /* * Source: See * [Thibault] * Not supported by ICU */ { 118, WINUNDEF, STRING_ENCODING_ISO_11548_1, UNSUPPORTED, 0, { "ISO-11548-1", "ISO_11548-1", "ISO_TR_11548-1", "csISO115481", NULL } }, /* * Source: See * [Veremeev, Kikkarin] */ { 119, WINUNDEF, STRING_ENCODING_KZ_1048, IN_FULL_ICU, 0, { "KZ-1048", "STRK1048-2002", "RK1048", "csKZ1048", NULL } }, /* * Source: the 2-octet Basic Multilingual Plane, aka Unicode * this needs to specify network byte order: the standard * does not specify (it is a 16-bit integer space) */ { 1000, WINUNDEF, STRING_ENCODING_ISO_10646_UCS_2, SUPPORTED, 0, { "ISO-10646-UCS-2", "csUnicode", "ibm-1204", "ibm-1205", "unicode", "ucs-2", NULL } }, /* * Source: the full code space. (same comment about byte order, * these are 31-bit numbers. */ { 1001, WINUNDEF, STRING_ENCODING_ISO_10646_UCS_4, SUPPORTED, 0, { "ISO-10646-UCS-4", "csUCS4", "ibm-1236", "ibm-1237", "ucs-4", NULL } }, /* * Source: ASCII subset of Unicode. Basic Latin = collection 1 * See ISO 10646, Appendix A * Not supported by ICU */ { 1002, WINUNDEF, STRING_ENCODING_ISO_10646_UCS_BASIC, UNSUPPORTED, 0, { "ISO-10646-UCS-Basic", "csUnicodeASCII", NULL } }, /* * Source: ISO Latin-1 subset of Unicode. Basic Latin and Latin-1 * Supplement = collections 1 and 2. See ISO 10646, * Appendix A. See RFC 1815. * Not supported by ICU */ { 1003, WINUNDEF, STRING_ENCODING_ISO_10646_UNICODE_LATIN1, UNSUPPORTED, 0, { "ISO-10646-Unicode-Latin1", "csUnicodeLatin1", "ISO-10646", NULL } }, /* * Source: ISO 10646 Japanese, see RFC 1815. * Not supported by ICU */ { MIBUNDEF, WINUNDEF, STRING_ENCODING_ISO_10646_J_1, UNSUPPORTED, 0, { "ISO-10646-J-1", NULL } }, /* * Source: IBM Latin-2, -3, -5, Extended Presentation Set, GCSGID: 1261 * Not supported by ICU */ { 1005, WINUNDEF, STRING_ENCODING_ISO_UNICODE_IBM_1261, UNSUPPORTED, 0, { "ISO-Unicode-IBM-1261", "csUnicodeIBM1261", NULL } }, /* * Source: IBM Latin-4 Extended Presentation Set, GCSGID: 1268 * Not supported by ICU */ { 1006, WINUNDEF, STRING_ENCODING_ISO_UNICODE_IBM_1268, UNSUPPORTED, 0, { "ISO-Unicode-IBM-1268", "csUnicodeIBM1268", NULL } }, /* * Source: IBM Cyrillic Greek Extended Presentation Set, GCSGID: 1276 * Not supported by ICU */ { 1007, WINUNDEF, STRING_ENCODING_ISO_UNICODE_IBM_1276, UNSUPPORTED, 0, { "ISO-Unicode-IBM-1276", "csUnicodeIBM1276", NULL } }, /* * Source: IBM Arabic Presentation Set, GCSGID: 1264 * Not supported by ICU */ { 1008, WINUNDEF, STRING_ENCODING_ISO_UNICODE_IBM_1264, UNSUPPORTED, 0, { "ISO-Unicode-IBM-1264", "csUnicodeIBM1264", NULL } }, /* * Source: IBM Hebrew Presentation Set, GCSGID: 1265 * Not supported by ICU */ { 1009, WINUNDEF, STRING_ENCODING_ISO_UNICODE_IBM_1265, UNSUPPORTED, 0, { "ISO-Unicode-IBM-1265", "csUnicodeIBM1265", NULL } }, /* * Source: RFC 1641, not supported by ICU */ { 1010, WINUNDEF, STRING_ENCODING_UNICODE_1_1, UNSUPPORTED, 0, { "UNICODE-1-1", "csUnicode11", NULL } }, /* * Source: SCSU See (http://www.iana.org/assignments/charset-reg/SCSU) * [Scherer] */ { 1011, WINUNDEF, STRING_ENCODING_SCSU, SUPPORTED, 0, { "SCSU", "ibm-1212", "ibm-1213", NULL } }, /* * Source: RFC 2152 */ { 1012, 65000, STRING_ENCODING_UTF_7, SUPPORTED, 0, { "UTF-7", NULL } }, /* * Source: RFC 2781 */ { 1013, 1201, STRING_ENCODING_UTF16_BE, SUPPORTED, 0, { "UTF-16BE", "x-utf-16be", "ibm-1200", "ibm-1201", "ibm-13488", "ibm-13489", "ibm-17584", "ibm-17585", "ibm-21680", "ibm-21681", "ibm-25776", "ibm-25777", "ibm-29872", "ibm-29873", "ibm-61955", "ibm-61956", "cp1200", "cp1201", "UTF16_BigEndian", "UnicodeBigUnmarked", NULL } }, /* * Source: RFC 2781 */ { 1014, 1200, STRING_ENCODING_UTF16_LE, SUPPORTED, 0, { "UTF-16LE", "x-utf-16le", "ibm-1202", "ibm-1203", "ibm-13490", "ibm-13491", "ibm-17586", "ibm-17587", "ibm-21682", "ibm-21683", "ibm-25778", "ibm-25779", "ibm-29874", "ibm-29875", "UTF16_LittleEndian", "UnicodeLittleUnmarked", NULL } }, /* * Source: RFC 2781 */ { 1015, WINUNDEF, STRING_ENCODING_UTF16_XE, SUPPORTED, 0, { "UTF-16", NULL } }, /* * Source: */ { 1016, WINUNDEF, STRING_ENCODING_CESU_8, SUPPORTED, 0, { "CESU-8", "csCESU-8", "ibm-9400", NULL } }, /* * Source: */ { 1017, WINUNDEF, STRING_ENCODING_UTF32_XE, SUPPORTED, 0, { "UTF-32", NULL } }, /* * Source: */ { 1018, 12001, STRING_ENCODING_UTF32_BE, SUPPORTED, 0, { "UTF-32BE", "UTF32_BigEndian", "ibm-1232", "ibm-1233", "ibm-9424", NULL } }, /* * Source: */ { 1019, 12000, STRING_ENCODING_UTF32_LE, SUPPORTED, 0, { "UTF-32LE", "UTF32_LittleEndian", "ibm-1234", "ibm-1235", NULL } }, /* * Source: http://www.unicode.org/notes/tn6/ */ { 1020, WINUNDEF, STRING_ENCODING_BOCU_1, SUPPORTED, 0, { "BOCU-1", "csBOCU-1", "ibm-1214", "ibm-1215", NULL } }, /* * Source: Extended ISO 8859-1 Latin-1 for Windows 3.0. * PCL Symbol Set id: 9U */ { 2000, WINUNDEF, STRING_ENCODING_ISO_8859_1_WINDOWS_3_0_LATIN_1, UNSUPPORTED, 0, { "ISO-8859-1-Windows-3.0-Latin-1", "csWindows30Latin1", NULL } }, /* * Source: Extended ISO 8859-1 Latin-1 for Windows 3.1. * PCL Symbol Set id: 19U * Not supported by ICU */ { 2001, WINUNDEF, STRING_ENCODING_ISO_8859_1_WINDOWS_3_1_LATIN_1, UNSUPPORTED, 0, { "ISO-8859-1-Windows-3.1-Latin-1", "csWindows31Latin1", NULL } }, /* * Source: Extended ISO 8859-2. Latin-2 for Windows 3.1. * PCL Symbol Set id: 9E * Not supported by ICU */ { 2002, WINUNDEF, STRING_ENCODING_ISO_8859_2_WINDOWS_LATIN_2, UNSUPPORTED, 0, { "ISO-8859-2-Windows-Latin-2", "csWindows31Latin2", NULL } }, /* * Source: Extended ISO 8859-9. Latin-5 for Windows 3.1 * PCL Symbol Set id: 5T * Not supported by ICU */ { 2003, WINUNDEF, STRING_ENCODING_ISO_8859_9_WINDOWS_LATIN_5, UNSUPPORTED, 0, { "ISO-8859-9-Windows-Latin-5", "csWindows31Latin5", NULL } }, /* * Source: LaserJet IIP Printer User's Manual, * HP part no 33471-90901, Hewlet-Packard, June 1989. */ { 2004, WINUNDEF, STRING_ENCODING_HP_ROMAN8, IN_FULL_ICU, 0, { "hp-roman8", "roman8", "r8", "csHPRoman8", "ibm-1051_P100-1995", "ibm-1051", NULL } }, /* * Source: PostScript Language Reference Manual * PCL Symbol Set id: 10J */ { 2005, WINUNDEF, STRING_ENCODING_ADOBE_STANDARD_ENCODING, IN_FULL_ICU, 0, { "Adobe-Standard-Encoding", "csAdobeStandardEncoding", "ibm-1276_P100-1995", "ibm-1276", NULL } }, /* * Source: Ventura US. ASCII plus characters typically used in * publishing, like pilcrow, copyright, registered, trade mark, * section, dagger, and double dagger in the range A0 (hex) * to FF (hex). * PCL Symbol Set id: 14J * Not supported by ICU */ { 2006, WINUNDEF, STRING_ENCODING_VENTURA_US, UNSUPPORTED, 0, { "Ventura-US", "csVenturaUS", NULL } }, /* * Source: Ventura International. ASCII plus coded characters similar * to Roman8. * PCL Symbol Set id: 13J * Not supported by ICU */ { 2007, WINUNDEF, STRING_ENCODING_VENTURA_INTERNATIONAL, UNSUPPORTED, 0, { "Ventura-International", "csVenturaInternational", NULL } }, /* * Source: VAX/VMS User's Manual, * Order Number: AI-Y517A-TE, April 1986. */ { 2008, WINUNDEF, STRING_ENCODING_DEC_MCS, IN_FULL_ICU, 0, { "DEC-MCS", "dec", "csDECMCS", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2009, 850, STRING_ENCODING_IBM_850, SUPPORTED, 0, { "IBM850", "cp850", "850", "csPC850Multilingual", "ibm-850_P100-1995", NULL } }, /* * Source: PC Danish Norwegian * 8-bit PC set for Danish Norwegian * PCL Symbol Set id: 11U * Not supported by ICU */ { 2012, WINUNDEF, STRING_ENCODING_PC8_DANISH_NORWEGIAN, UNSUPPORTED, 0, { "PC8-Danish-Norwegian", "csPC8DanishNorwegian", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2013, 862, STRING_ENCODING_IBM_862, SUPPORTED, 0, { "IBM862", "cp862", "862", "csPC862LatinHebrew", "ibm-862_P100-1995", "DOS-862", NULL } }, /* * Source: PC Latin Turkish. PCL Symbol Set id: 9T * Not supported by ICU */ { 2014, WINUNDEF, STRING_ENCODING_PC8_TURKISH, UNSUPPORTED, 0, { "PC8-Turkish", "csPC8Turkish", NULL } }, /* * Source: Presentation Set, CPGID: 259 * Not supported by ICU */ { 2015, WINUNDEF, STRING_ENCODING_IBM_SYMBOLS, UNSUPPORTED, 0, { "IBM-Symbols", "csIBMSymbols", NULL } }, /* * Source: Presentation Set, CPGID: 838 */ { 2016, 20838, STRING_ENCODING_IBM_THAI, IN_FULL_ICU, 0, { "IBM-Thai", "csIBMThai", "ibm-838_P100-1995", "ibm-838", "IBM838", "cp838", "838", "ibm-9030", NULL } }, /* * Source: PCL 5 Comparison Guide, Hewlett-Packard, * HP part number 5961-0510, October 1992 * PCL Symbol Set id: 1U * Not supported by ICU */ { 2017, WINUNDEF, STRING_ENCODING_HP_LEGAL, UNSUPPORTED, 0, { "HP-Legal", "csHPLegal", NULL } }, /* * Source: PCL 5 Comparison Guide, Hewlett-Packard, * HP part number 5961-0510, October 1992 * PCL Symbol Set id: 15U * Not supported by ICU */ { 2018, WINUNDEF, STRING_ENCODING_HP_PI_FONT, UNSUPPORTED, 0, { "HP-Pi-font", "csHPPiFont", NULL } }, /* * Source: PCL 5 Comparison Guide, Hewlett-Packard, * HP part number 5961-0510, October 1992 * PCL Symbol Set id: 8M * Not supported by ICU */ { 2019, WINUNDEF, STRING_ENCODING_HP_MATH8, UNSUPPORTED, 0, { "HP-Math8", "csHPMath8", NULL } }, /* * Source: PostScript Language Reference Manual * PCL Symbol Set id: 5M * Not supported by ICU */ { 2020, WINUNDEF, STRING_ENCODING_ADOBE_SYMBOL_ENCODING, UNSUPPORTED, 0, { "Adobe-Symbol-Encoding", "csHPPSMath", NULL } }, /* * Source: PCL 5 Comparison Guide, Hewlett-Packard, * HP part number 5961-0510, October 1992 * PCL Symbol Set id: 7J * Not supported by ICU */ { 2021, WINUNDEF, STRING_ENCODING_HP_DESKTOP, UNSUPPORTED, 0, { "HP-DeskTop", "csHPDesktop", NULL } }, /* * Source: PCL 5 Comparison Guide, Hewlett-Packard, * HP part number 5961-0510, October 1992 * PCL Symbol Set id: 6M * Not supported by ICU */ { 2022, WINUNDEF, STRING_ENCODING_VENTURA_MATH, UNSUPPORTED, 0, { "Ventura-Math", "csVenturaMath", NULL } }, /* * Source: PCL 5 Comparison Guide, Hewlett-Packard, * HP part number 5961-0510, October 1992 * PCL Symbol Set id: 6J * Not supported by ICU */ { 2023, WINUNDEF, STRING_ENCODING_MICROSOFT_PUBLISHING, UNSUPPORTED, 0, { "Microsoft-Publishing", "csMicrosoftPublishing", NULL } }, /* * Source: Windows Japanese. A further extension of Shift_JIS * to include NEC special characters (Row 13), NEC * selection of IBM extensions (Rows 89 to 92), and IBM * extensions (Rows 115 to 119). The CCS's are * JIS X0201:1997, JIS X0208:1997, and these extensions. * This charset can be used for the top-level media type "text", * but it is of limited or specialized use (see RFC2278). * PCL Symbol Set id: 19K */ { 2024, WINUNDEF, STRING_ENCODING_WINDOWS_31J, SUPPORTED, 0, { "Windows-31J", "csWindows31J", NULL } }, /* * Source: Chinese for People's Republic of China (PRC) mixed one byte, * two byte set: * 20-7E = one byte ASCII * A1-FE = two byte PRC Kanji * See GB 2312-80 * PCL Symbol Set Id: 18C */ { 2025, WINUNDEF, STRING_ENCODING_GB_2312, IN_FULL_ICU, 0, { "GB2312", "csGB2312", "ibm-1383_P110-1999", "ibm-1383", "cp1383", "1383", "EUC-CN", "ibm-eucCN", "hp15CN", "ibm-1383_VPUA", NULL } }, /* * Source: Chinese for Taiwan Multi-byte set. * PCL Symbol Set Id: 18T */ { 2026, 950, STRING_ENCODING_BIG_5, SUPPORTED, 0, { "Big5", "csBig5", "windows-950", "windows-950-2000", "x-big5", NULL } }, /* * Alternate ICU converter for Windows-950 (Big5) */ { MIBUNDEF, 950, STRING_ENCODING_IBM_1373, SUPPORTED, 0, { "ibm-1373_P100-2002", "ibm-1373", NULL } }, /* * Source: The Unicode Standard ver1.0, ISBN 0-201-56788-1, Oct 1991 */ { 2027, WINUNDEF, STRING_ENCODING_MACINTOSH, IN_FULL_ICU, 0, { "macintosh", "mac", "csMacintosh", "macos-0_2-10.2", "macroman", "x-macroman", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2028, 37, STRING_ENCODING_IBM_037, IN_FULL_ICU, 0, { "IBM037", "cp037", "ebcdic-cp-us", "ebcdic-cp-ca", "ebcdic-cp-wt", "ebcdic-cp-nl", "csIBM037", "ibm-37_P100-1995", "ibm-37", "037", "cpibm37", "cp37", NULL } }, /* * Source: IBM 3174 Character Set Ref, GA27-3831-02, March 1990 * Not supported by ICU */ { 2029, WINUNDEF, STRING_ENCODING_IBM_038, UNSUPPORTED, 0, { "IBM038", "EBCDIC-INT", "cp038", "csIBM038", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2030, 20273, STRING_ENCODING_IBM_273, IN_FULL_ICU, 0, { "IBM273", "CP273", "csIBM273", "ibm-273_P100-1995", "ebcdic-de", "273", NULL } }, /* * Source: IBM 3174 Character Set Ref, GA27-3831-02, March 1990 */ { 2031, WINUNDEF, STRING_ENCODING_IBM_274, IN_FULL_ICU, 0, { "IBM274", "EBCDIC-BE", "CP274", "csIBM274", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2032, WINUNDEF, STRING_ENCODING_IBM_275, IN_FULL_ICU, 0, { "IBM275", "EBCDIC-BR", "cp275", "csIBM275", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2033, 20277, STRING_ENCODING_IBM_277, IN_FULL_ICU, 0, { "IBM277", "EBCDIC-CP-DK", "EBCDIC-CP-NO", "csIBM277", "ibm-277_P100-1995", "cp277", "ebcdic-dk", "277", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2034, 20278, STRING_ENCODING_IBM_278, IN_FULL_ICU, 0, { "IBM278", "CP278", "ebcdic-cp-fi", "ebcdic-cp-se", "csIBM278", "ibm-278_P100-1995", "ebcdic-sv", "278", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2035, 20280, STRING_ENCODING_IBM_280, IN_FULL_ICU, 0, { "IBM280", "CP280", "ebcdic-cp-it", "csIBM280", "ibm-280_P100-1995", "280", NULL } }, /* * Source: IBM 3174 Character Set Ref, GA27-3831-02, March 1990 * Not supported by ICU */ { 2036, WINUNDEF, STRING_ENCODING_IBM_281, UNSUPPORTED, 0, { "IBM281", "EBCDIC-JP-E", "cp281", "csIBM281", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2037, 20284, STRING_ENCODING_IBM_284, IN_FULL_ICU, 0, { "IBM284", "CP284", "ebcdic-cp-es", "csIBM284", "ibm-284_P100-1995", "cpibm284", "284", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2038, 20285, STRING_ENCODING_IBM_285, IN_FULL_ICU, 0, { "IBM285", "CP285", "ebcdic-cp-gb", "csIBM285", "ibm-284_P100-1995", "cpibm284", "284", NULL } }, /* * Source: IBM 3174 Character Set Ref, GA27-3831-02, March 1990 */ { 2039, 20290, STRING_ENCODING_IBM_290, IN_FULL_ICU, 0, { "IBM290", "cp290", "EBCDIC-JP-kana", "csIBM290", "ibm-290_P100-1995", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2040, 20297, STRING_ENCODING_IBM_297, IN_FULL_ICU, 0, { "IBM297", "cp297", "ebcdic-cp-fr", "csIBM297", "ibm-297_P100-1995", "cpibm297", "297", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990, * IBM NLS RM p 11-11 */ { 2041, 20420, STRING_ENCODING_IBM_420, IN_FULL_ICU, 0, { "IBM420", "cp420", "ebcdic-cp-ar1", "csIBM420", "ibm-420_X120-1999", "420", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 * Not supporeted by ICU */ { 2042, 20423, STRING_ENCODING_IBM_423, UNSUPPORTED, 0, { "IBM423", "cp423", "ebcdic-cp-gr", "csIBM423", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2043, 20424, STRING_ENCODING_IBM_424, IN_FULL_ICU, 0, { "IBM424", "cp424", "ebcdic-cp-he", "csIBM424", "ibm-424_P100-1995", "424", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2011, 437, STRING_ENCODING_IBM_437, SUPPORTED, 0, { "IBM437", "cp437", "437", "csPC8CodePage437", "ibm-437_P100-1995", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2044, 500, STRING_ENCODING_IBM_500, IN_FULL_ICU, 0, { "IBM500", "CP500", "ebcdic-cp-be", "ebcdic-cp-ch", "csIBM500", "ibm-500_P100-1995", "500", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2045, WINUNDEF, STRING_ENCODING_IBM_851, IN_FULL_ICU, 0, { "IBM851", "cp851", "851", "csIBM851", "ibm-851_P100-1995", "csPC851", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2010, 852, STRING_ENCODING_IBM_852, SUPPORTED, 0, { "IBM852", "cp852", "852", "csPCp852", "ibm-852_P100-1995", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2046, 855, STRING_ENCODING_IBM_855, IN_FULL_ICU, 0, { "IBM855", "cp855", "855", "csIBM855", "ibm-855_P100-1995", "csPCp855", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2047, 857, STRING_ENCODING_IBM_857, SUPPORTED, 0, { "IBM857", "cp857", "857", "csIBM857", "ibm-857_P100-1995", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2048, 860, STRING_ENCODING_IBM_860, IN_FULL_ICU, 0, { "IBM860", "cp860", "860", "csIBM860", "ibm-860_P100-1995", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2049, 861, STRING_ENCODING_IBM_861, IN_FULL_ICU, 0, { "IBM861", "cp861", "861", "cp-is", "csIBM861", "ibm-861_P100-1995", NULL } }, /* * Source: IBM Keyboard layouts and code pages, PN 07G4586 June 1991 */ { 2050, 863, STRING_ENCODING_IBM_863, IN_FULL_ICU, 0, { "IBM863", "cp863", "863", "csIBM863", "ibm-863_P100-1995", NULL } }, /* * Source: IBM Keyboard layouts and code pages, PN 07G4586 June 1991 */ { 2051, 864, STRING_ENCODING_IBM_864, IN_FULL_ICU, 0, { "IBM864", "cp864", "csIBM864", "ibm-864_X110-1999", NULL } }, /* * Source: IBM DOS 3.3 Ref (Abridged), 94X9575 (Feb 1987) */ { 2052, 865, STRING_ENCODING_IBM_865, IN_FULL_ICU, 0, { "IBM865", "cp865", "865", "csIBM865", "ibm-865_P100-1995", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2053, WINUNDEF, STRING_ENCODING_IBM_868, IN_FULL_ICU, 0, { "IBM868", "CP868", "cp-ar", "csIBM868", "ibm-868_P100-1995", "868", NULL } }, /* * Source: IBM Keyboard layouts and code pages, PN 07G4586 June 1991 */ { 2054, 869, STRING_ENCODING_IBM_869, IN_FULL_ICU, 0, { "IBM869", "cp869", "869", "cp-gr", "csIBM869", "ibm-869_P100-1995", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2055, 870, STRING_ENCODING_IBM_870, IN_FULL_ICU, 0, { "IBM870", "CP870", "ebcdic-cp-roece", "ebcdic-cp-yu", "csIBM870", "ibm-870_P100-1995", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2056, 20871, STRING_ENCODING_IBM_871, IN_FULL_ICU, 0, { "IBM871", "CP871", "ebcdic-cp-is", "csIBM871", "ibm-871_P100-1995", "ebcdic-is", "871", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2057, 20880, STRING_ENCODING_IBM_880, IN_FULL_ICU, 0, { "IBM880", "cp880", "EBCDIC-Cyrillic", "csIBM880", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 * Not supported by ICU */ { 2058, WINUNDEF, STRING_ENCODING_IBM_891, UNSUPPORTED, 0, { "IBM891", "cp891", "csIBM891", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 * Not supported by ICU */ { 2059, WINUNDEF, STRING_ENCODING_IBM_903, UNSUPPORTED, 0, { "IBM903", "cp903", "csIBM903", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 * Not supported by ICU */ { 2060, WINUNDEF, STRING_ENCODING_IBM_904, UNSUPPORTED, 0, { "IBM904", "cp904", "904", "csIBBM904", NULL } }, /* * Source: IBM 3174 Character Set Ref, GA27-3831-02, March 1990 */ { 2061, 20905, STRING_ENCODING_IBM_905, IN_FULL_ICU, 0, { "IBM905", "CP905", "ebcdic-cp-tr", "csIBM905", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2062, WINUNDEF, STRING_ENCODING_IBM_918, IN_FULL_ICU, 0, { "IBM918", "CP918", "ebcdic-cp-ar2", "csIBM918", "ibm-918_P100-1995", NULL } }, /* * Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 */ { 2063, 1026, STRING_ENCODING_IBM_1026, IN_FULL_ICU, 0, { "IBM1026", "CP1026", "csIBM1026", "ibm-1026_P100-1995", "1026", NULL } }, /* * Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 * Not supported by ICU */ { 2064, WINUNDEF, STRING_ENCODING_EBCDIC_AT_DE, UNSUPPORTED, 0, { "EBCDIC-AT-DE", "csIBMEBCDICATDE", NULL } }, /* * Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 */ { 2065, WINUNDEF, STRING_ENCODING_EBCDIC_AT_DE_A, IN_FULL_ICU, 0, { "EBCDIC-AT-DE-A", "csEBCDICATDEA", NULL } }, /* * Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 * Not supported by ICU */ { 2066, WINUNDEF, STRING_ENCODING_EBCDIC_CA_FR, UNSUPPORTED, 0, { "EBCDIC-CA-FR", "csEBCDICCAFR", NULL } }, /* * Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 * Not supported by ICU */ { 2067, WINUNDEF, STRING_ENCODING_EBCDIC_DK_NO, UNSUPPORTED, 0, { "EBCDIC-DK-NO", "csEBCDICDKNO", NULL } }, /* * Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 * Not supported by ICU */ { 2068, WINUNDEF, STRING_ENCODING_EBCDIC_DK_NO_A, UNSUPPORTED, 0, { "EBCDIC-DK-NO-A", "csEBCDICDKNOA", NULL } }, /* * Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 * Not supported by ICU */ { 2069, WINUNDEF, STRING_ENCODING_EBCDIC_FI_SE, UNSUPPORTED, 0, { "EBCDIC-FI-SE", "csEBCDICFISE", NULL } }, /* * Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 * Not supported by ICU */ { 2070, WINUNDEF, STRING_ENCODING_EBCDIC_FI_SE_A, UNSUPPORTED, 0, { "EBCDIC-FI-SE-A", "csEBCDICFISEA", NULL } }, /* * Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 * Not supported by ICU */ { 2071, WINUNDEF, STRING_ENCODING_EBCDIC_FR, UNSUPPORTED, 0, { "EBCDIC-FR", "csEBCDICFR", NULL } }, /* * Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 * Not supported by ICU */ { 2072, WINUNDEF, STRING_ENCODING_EBCDIC_IT, UNSUPPORTED, 0, { "EBCDIC-IT", "csEBCDICIT", NULL } }, /* * Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 * Not supported by ICU */ { 2073, WINUNDEF, STRING_ENCODING_EBCDIC_PT, UNSUPPORTED, 0, { "EBCDIC-PT", "csEBCDICPT", NULL } }, /* * Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 * Not supported by ICU */ { 2074, WINUNDEF, STRING_ENCODING_EBCDIC_ES, UNSUPPORTED, 0, { "EBCDIC-ES", "csEBCDICES", NULL } }, /* * Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 * Not supported by ICU */ { 2075, WINUNDEF, STRING_ENCODING_EBCDIC_ES_A, UNSUPPORTED, 0, { "EBCDIC-ES-A", "csEBCDICESA", NULL } }, /* * Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 * Not supported by ICU */ { 2076, WINUNDEF, STRING_ENCODING_EBCDIC_ES_S, UNSUPPORTED, 0, { "EBCDIC-ES-S", "csEBCDICESS", NULL } }, /* * Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 * Not supported by ICU */ { 2077, WINUNDEF, STRING_ENCODING_EBCDIC_UK, UNSUPPORTED, 0, { "EBCDIC-UK", "csEBCDICUK", NULL } }, /* * Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 * Not supported by ICU */ { 2078, WINUNDEF, STRING_ENCODING_EBCDIC_US, UNSUPPORTED, 0, { "EBCDIC-US", "csEBCDICUS", NULL } }, /* * Not supported by ICU */ { 2079, WINUNDEF, STRING_ENCODING_UNKNOWN_8BIT, UNSUPPORTED, 0, { "UNKNOWN-8BIT", "csUnknown8BiT", NULL } }, /* * Source: RFC 1345, also known as "mnemonic+ascii+38" * Not supported by ICU */ { 2080, WINUNDEF, STRING_ENCODING_MNEMONIC, UNSUPPORTED, 0, { "MNEMONIC", "csMnemonic", NULL } }, /* * Source: RFC 1345, also known as "mnemonic+ascii+8200" * Not supported by ICU */ { 2081, WINUNDEF, STRING_ENCODING_MNEM, UNSUPPORTED, 0, { "MNEM", "csMnem", NULL } }, /* * Source: RFC 1456 * Not supported by ICU */ { 2082, WINUNDEF, STRING_ENCODING_VISCII, UNSUPPORTED, 0, { "VISCII", "csVISCII", NULL } }, /* * Source: RFC 1456 * Not supported by ICU */ { 2083, WINUNDEF, STRING_ENCODING_VIQR, UNSUPPORTED, 0, { "VIQR", "csVIQR", NULL } }, /* * Source: RFC 1489, based on GOST-19768-74, ISO-6937/8, * INIS-Cyrillic, ISO-5427. */ { 2084, 20866, STRING_ENCODING_KOI8_R, IN_FULL_ICU, 0, { "KOI8-R", "csKOI8R", "koi8", "cp878", "ibm-878", "ibm-878_P100-1996", NULL } }, /* * Source: RFC 1842, RFC 1843 [RFC1842, RFC1843] */ { 2085, 52936, STRING_ENCODING_HZ_GB_2312, SUPPORTED, 0, { "HZ-GB-2312", "HZ", NULL } }, /* * Source: IBM NLDG Volume 2 (SE09-8002-03) August 1994 */ { 2086, 866, STRING_ENCODING_IBM_866, SUPPORTED, 0, { "IBM866", "cp866", "866", "csIBM866", "ibm-866_P100-1995", NULL } }, /* * Source: HP PCL 5 Comparison Guide (P/N 5021-0329) pp B-13, 1996 */ { 2087, 775, STRING_ENCODING_IBM_775, SUPPORTED, 0, { "IBM775", "cp775", "csPC775Baltic", "ibm-775_P100-1996", "775", NULL } }, /* * Source: RFC 2319 */ { 2088, 21866, STRING_ENCODING_KOI8_U, IN_FULL_ICU, 0, { "KOI8-U", "ibm-1168", "ibm-1168_P100-2002", NULL } }, /* * Source: IBM See (http://www.iana.org/assignments/charset-reg/IBM00858) * [Mahdi] */ { 2089, 858, STRING_ENCODING_IBM_00858, SUPPORTED, 0, { "IBM00858", "CCSID00858", "CP00858", "PC-Multilingual-850+euro", "ibm-858", "cp858", "ibm-858_P100-1997", NULL } }, /* * Source: IBM See (http://www.iana.org/assignments/charset-reg/IBM00924) * [Mahdi] */ { 2090, 20924, STRING_ENCODING_IBM_00924, IN_FULL_ICU, 0, { "IBM00924", "CCSID00924", "CP00924", "ebcdic-Latin9--euro", NULL } }, /* * Source: IBM See (http://www.iana.org/assignments/charset-reg/IBM01140) * [Mahdi] */ { 2091, 1140, STRING_ENCODING_IBM_01140, IN_FULL_ICU, 0, { "IBM01140", "CCSID01140", "CP01140", "ebcdic-us-37+euro", "ibm-1140", "cp1140", "ibm-1140_P100-1997", NULL } }, /* * Source: IBM See (http://www.iana.org/assignments/charset-reg/IBM01141) * [Mahdi] */ { 2092, 1141, STRING_ENCODING_IBM_01141, IN_FULL_ICU, 0, { "IBM01141", "CCSID01141", "CP01141", "ebcdic-de-273+euro", "ibm-1141", "cp1141", "ibm-1141_P100-1997", NULL } }, /* * Source: IBM See (http://www.iana.org/assignments/charset-reg/IBM01142) * [Mahdi] */ { 2093, 1142, STRING_ENCODING_IBM_01142, IN_FULL_ICU, 0, { "IBM01142", "CCSID01142", "CP01142", "ebcdic-dk-277+euro", "ebcdic-no-277+euro", "ibm-1142", "cp1142", "ibm-1142_P100-1997", NULL } }, /* * Source: IBM See (http://www.iana.org/assignments/charset-reg/IBM01143) * [Mahdi] */ { 2094, 1143, STRING_ENCODING_IBM_01143, IN_FULL_ICU, 0, { "IBM01143", "CCSID01143", "CP01143", "ebcdic-fi-278+euro", "ebcdic-se-278+euro", "ibm-1143", "cp1143", "ibm-1143_P100-1997", NULL } }, /* * Source: IBM See (http://www.iana.org/assignments/charset-reg/IBM01144) * [Mahdi] */ { 2095, 1144, STRING_ENCODING_IBM_01144, IN_FULL_ICU, 0, { "IBM01144", "CCSID01144", "CP01144", "ebcdic-it-280+euro", "ibm-1144", "cp1144", "ibm-1144_P100-1997", NULL } }, /* * Source: IBM See (http://www.iana.org/assignments/charset-reg/IBM01145) * [Mahdi] */ { 2096, 1145, STRING_ENCODING_IBM_01145, IN_FULL_ICU, 0, { "IBM01145", "CCSID01145", "CP01145", "ebcdic-es-284+euro", "ibm-1145", "cp1145", "ibm-1145_P100-1997", NULL } }, /* * Source: IBM See (http://www.iana.org/assignments/charset-reg/IBM01146) * [Mahdi] */ { 2097, 1146, STRING_ENCODING_IBM_01146, IN_FULL_ICU, 0, { "IBM01146", "CCSID01146", "CP01146", "ebcdic-gb-285+euro", "ibm-1146", "cp1146", "ibm-1146_P100-1997", NULL } }, /* * Source: IBM See (http://www.iana.org/assignments/charset-reg/IBM01147) * [Mahdi] */ { 2098, 1147, STRING_ENCODING_IBM_01147, IN_FULL_ICU, 0, { "IBM01147", "CCSID01147", "CP01147", "ebcdic-fr-297+euro", "ibm-1147", "cp1147", "ibm-1147_P100-1997", NULL } }, /* * Source: IBM See (http://www.iana.org/assignments/charset-reg/IBM01148) * [Mahdi] */ { 2099, 1148, STRING_ENCODING_IBM_01148, IN_FULL_ICU, 0, { "IBM01148", "CCSID01148", "CP01148", "ebcdic-international-500+euro", "ibm-1148", "cp1148", "ibm-1148_P100-1997", NULL } }, /* * Source: IBM See (http://www.iana.org/assignments/charset-reg/IBM01149) * [Mahdi] */ { 2100, 1149, STRING_ENCODING_IBM_01149, IN_FULL_ICU, 0, { "IBM01149", "CCSID01149", "CP01149", "ebcdic-is-871+euro", "ibm-1149", "cp1149", "ibm-1149_P100-1997", NULL } }, /* * Source: See (http://www.iana.org/assignments/charset-reg/Big5-HKSCS) */ { 2101, WINUNDEF, STRING_ENCODING_BIG_5_HK, IN_FULL_ICU, 0, { "Big5-HKSCS", "ibm-1375_P100-2007", "ibm-1375", "big5hk", "HKSCS-BIG5", NULL } }, /* * Alternate ICU converter for Big-5-HKSCS */ { 2101, WINUNDEF, STRING_ENCODING_IBM_5471, IN_FULL_ICU, 0, { "ibm-5471_P100-2006", "ibm-5471", "MS950_HKSCS", "hkbig5", NULL } }, /* * Source: IBM1047 (EBCDIC Latin 1/Open Systems) * http://www-1.ibm.com/servers/eserver/iseries/software/globalization/ * pdf/cp01047z.pdf */ { 2102, 1047, STRING_ENCODING_IBM_1047, IN_FULL_ICU, 0, { "IBM1047", "IBM-1047", "cp1047", "1047", "ibm-1047_P100-1995", NULL } }, /* * Source: See (http://www.iana.org/assignments/charset-reg/PTCP154) * Not supported by ICU */ { 2103, WINUNDEF, STRING_ENCODING_PTCP154, UNSUPPORTED, 0, { "PTCP154", "csPTCP154", "PT154", "CP154", "Cyrillic-Asian", NULL } }, /* * Source: See (http://www.amiga.ultranet.ru/Amiga-1251.html) * Not supported by ICU */ { 2104, WINUNDEF, STRING_ENCODING_AMIGA_1251, UNSUPPORTED, 0, { "Amiga-1251", "Ami1251", "Amiga1251", "Ami-1251", NULL } }, /* * Source: See * Aliases: None * Not supported by ICU */ { 2105, WINUNDEF, STRING_ENCODING_KOI7_SWITCHED, UNSUPPORTED, 0, { "KOI7-switched", NULL } }, /* * Source: See * [Thibault] * Not supported by ICU */ { 2106, WINUNDEF, STRING_ENCODING_BRF, UNSUPPORTED, 0, { "BRF", "csBRF", NULL } }, /* * Source: See * [Kalyanasundaram] * Not supported by ICU */ { 2107, WINUNDEF, STRING_ENCODING_TSCII, UNSUPPORTED, 0, { "TSCII", "csTSCII", NULL } }, /* * Source: Microsoft * (http://www.iana.org/assignments/charset-reg/windows-1250) [Lazhintseva] */ { 2250, 1250, STRING_ENCODING_WINDOWS_1250, SUPPORTED, 0, { "windows-1250", "ibm-5346_P100-1998", "ibm-5346", "cp1250", "ibm-1250_P100-1995", "ibm-1250", NULL } }, /* * Source: Microsoft * (http://www.iana.org/assignments/charset-reg/windows-1251) [Lazhintseva] */ { 2251, 1251, STRING_ENCODING_WINDOWS_1251, SUPPORTED, 0, { "windows-1251", "ibm-5347_P100-1998", "ibm-5347", "cp1251", "ANSI1251", "ibm-1251_P100-1995", "ibm-1251", NULL } }, /* * Source: Microsoft * (http://www.iana.org/assignments/charset-reg/windows-1252) [Wendt] */ { 2252, 1252, STRING_ENCODING_WINDOWS_1252, SUPPORTED, 0, { "windows-1252", "ibm-5348_P100-1997", "ibm-5348", "cp1252", "ibm-1252_P100-2000", "ibm-1252", NULL } }, /* * Source: Microsoft * (http://www.iana.org/assignments/charset-reg/windows-1253) [Lazhintseva] */ { 2253, 1253, STRING_ENCODING_WINDOWS_1253, SUPPORTED, 0, { "windows-1253", "ibm-5349_P100-1998", "ibm-5349", "cp1253", "ibm-1253", "ibm-1253_P100-1995", NULL } }, /* * Source: Microsoft * (http://www.iana.org/assignments/charset-reg/windows-1254) [Lazhintseva] */ { 2254, 1254, STRING_ENCODING_WINDOWS_1254, SUPPORTED, 0, { "windows-1254", "ibm-5350_P100-1998", "ibm-5350", "cp1254", "ibm-1254", "ibm-1254_P100-1995", NULL } }, /* * Source: Microsoft * (http://www.iana.org/assignments/charset-reg/windows-1255) [Lazhintseva] */ { 2255, 1255, STRING_ENCODING_WINDOWS_1255, SUPPORTED, 0, { "windows-1255", "ibm-9447_P100-2002", "ibm-9447", "cp1255", "ibm-5351", "ibm-5351_P100-1998", NULL } }, /* * Source: Microsoft * (http://www.iana.org/assignments/charset-reg/windows-1256) [Lazhintseva] */ { 2256, 1256, STRING_ENCODING_WINDOWS_1256, SUPPORTED, 0, { "windows-1256", "ibm-9448_X100-2005", "ibm-9448", "cp1256", "ibm-5352", "ibm-5352_P100-1998", NULL } }, /* * Source: Microsoft * (http://www.iana.org/assignments/charset-reg/windows-1257) [Lazhintseva] */ { 2257, 1257, STRING_ENCODING_WINDOWS_1257, SUPPORTED, 0, { "windows-1257", "ibm-9449_P100-2002", "ibm-9449", "cp1257", "ibm-5353", "ibm-5353_P100-1998", NULL } }, /* * Source: Microsoft * (http://www.iana.org/assignments/charset-reg/windows-1258) [Lazhintseva] */ { 2258, 1258, STRING_ENCODING_WINDOWS_1258, SUPPORTED, 0, { "windows-1258", "ibm-5354_P100-1998", "ibm-5354", "cp1258", "ibm-1258", "ibm-1258_P100-1997", NULL } }, /* * Source: Thai Industrial Standards Institute (TISI) * [Tantsetthi] */ { 2259, WINUNDEF, STRING_ENCODING_TIS_620, SUPPORTED, 0, { "TIS-620", "windows-874-2000", "MS874", NULL } }, /* * Windows specific entries for which there is no corresponding IANA mapping */ /* * Windows-709: Arabic (ASMO-449+, BCON V4) * Not supported by ICU */ { MIBUNDEF, 709, STRING_ENCODING_WINDOWS_709, UNSUPPORTED, 0, { "Windows-709", "ASMO-449+", "BCON_V4", NULL } }, /* * Windows-710: Arabic - Transparent Arabic * Not supported by ICU */ { MIBUNDEF, 710, STRING_ENCODING_WINDOWS_710, UNSUPPORTED, 0, { "Windows-710", NULL } }, /* * DOS-720: Arabic (Transparent ASMO); Arabic (DOS) */ { MIBUNDEF, 720, STRING_ENCODING_WINDOWS_720, SUPPORTED, 0, { "Windows-720", "DOS-720", "DOS_720", "ibm-720", "ibm-720_P100-1997", NULL } }, /* * ibm737: OEM Greek (formerly 437G); Greek (DOS) */ { MIBUNDEF, 737, STRING_ENCODING_WINDOWS_737, SUPPORTED, 0, { "Windows-737", "IBM737", "cp737", "737", "ibm-737_P100-1997", NULL } }, /* * cp875: IBM EBCDIC Greek Modern * ICU doesn't have "Windows-875" as an alias, use "cp875" */ { MIBUNDEF, 875, STRING_ENCODING_WINDOWS_875, IN_FULL_ICU, 0, { "cp875", "ibm-875", "IBM875", "875", "ibm-875_P100-1995", NULL } }, /* * Johab: Korean (Johab) * Not supported by ICU */ { MIBUNDEF, 1361, STRING_ENCODING_WINDOWS_1361, UNSUPPORTED, 0, { "Windows-1361", "Johab", NULL } }, /* * macintosh: MAC Roman; Western European (Mac) * using the encoding names "mac" and "macintosh" * is probably a bad idea here */ { MIBUNDEF, 10000, STRING_ENCODING_WINDOWS_10000, IN_FULL_ICU, 0, { "Windows-10000", NULL } }, /* * x-mac-japanese: Japanese (Mac) * Not supported by ICU */ { MIBUNDEF, 10001, STRING_ENCODING_WINDOWS_10001, UNSUPPORTED, 0, { "Windows-10001", "x-mac-japanese", NULL } }, /* * x-mac-chinesetrad: MAC Traditional Chinese (Big5); * Chinese Traditional (Mac) * Not supported by ICU */ { MIBUNDEF, 10002, STRING_ENCODING_WINDOWS_10002, UNSUPPORTED, 0, { "Windows-10002", "x-mac-chinesetrad", NULL } }, /* * x-mac-korean: Korean (Mac) * Not supported by ICU */ { MIBUNDEF, 10003, STRING_ENCODING_WINDOWS_10003, UNSUPPORTED, 0, { "Windows-10003", "x-mac-korean", NULL } }, /* * x-mac-arabic: Arabic (Mac) * Not supported by ICU */ { MIBUNDEF, 10004, STRING_ENCODING_WINDOWS_10004, UNSUPPORTED, 0, { "Windows-10004", "x-mac-arabic", NULL } }, /* * x-mac-hebrew: Hebrew (Mac) * Not supported by ICU */ { MIBUNDEF, 10005, STRING_ENCODING_WINDOWS_10005, UNSUPPORTED, 0, { "Windows-10005", "x-mac-hebrew", NULL } }, /* * x-mac-greek: Greek (Mac) */ { MIBUNDEF, 10006, STRING_ENCODING_WINDOWS_10006, IN_FULL_ICU, 0, { "Windows-10006", "x-mac-greek", "macgr", "macos-6_2-10.4", NULL } }, /* * x-mac-cyrillic: Cyrillic (Mac) */ { MIBUNDEF, 10007, STRING_ENCODING_WINDOWS_10007, IN_FULL_ICU, 0, { "Windows-10007", "x-mac-cyrillic", "maccy", "mac-cyrillic", "macos-7_3-10.2", NULL } }, /* * x-mac-chinesesimp: MAC Simplified Chinese (GB 2312); * Chinese Simplified (Mac) * Not supported by ICU */ { MIBUNDEF, 10008, STRING_ENCODING_WINDOWS_10008, UNSUPPORTED, 0, { "Windows-10008", "x-mac-chinesesimp", NULL } }, /* * x-mac-romanian: Romanian (Mac) * Not supported by ICU */ { MIBUNDEF, 10010, STRING_ENCODING_WINDOWS_10010, UNSUPPORTED, 0, { "Windows-10010", "x-mac-romanian", NULL } }, /* * x-mac-ukrainian: Ukrainian (Mac) * Not supported by ICU */ { MIBUNDEF, 10017, STRING_ENCODING_WINDOWS_10017, UNSUPPORTED, 0, { "Windows-10017", "x-mac-ukrainian", NULL } }, /* * x-mac-thai: Thai (Mac) * Not supported by ICU */ { MIBUNDEF, 10021, STRING_ENCODING_WINDOWS_10021, UNSUPPORTED, 0, { "Windows-10021", "x-mac-thai", NULL } }, /* * x-mac-ce: MAC Latin 2; Central European (Mac) */ { MIBUNDEF, 10029, STRING_ENCODING_WINDOWS_10029, IN_FULL_ICU, 0, { "Windows-10029", "x-mac-ce", "macce", "maccentraleurope", "x-mac-centraleurroman", "macos-29-10.2", NULL } }, /* * x-mac-icelandic: Icelandic (Mac) * Not supported by ICU */ { MIBUNDEF, 10079, STRING_ENCODING_WINDOWS_10079, UNSUPPORTED, 0, { "Windows-10079", "x-mac-icelandic", NULL } }, /* * x-mac-turkish: Turkish (Mac) */ { MIBUNDEF, 10081, STRING_ENCODING_WINDOWS_10081, IN_FULL_ICU, 0, { "Windows-10081", "x-mac-turkish", "mactr", "macos-35-10.2", NULL } }, /* * x-mac-croatian: Croatian (Mac) * Not supported by ICU */ { MIBUNDEF, 10082, STRING_ENCODING_WINDOWS_10082, UNSUPPORTED, 0, { "Windows-10082", "x-mac-croatian", NULL } }, /* * x-Chinese_CNS: CNS Taiwan; Chinese Traditional (CNS) * Not supported by ICU */ { MIBUNDEF, 20000, STRING_ENCODING_WINDOWS_20000, UNSUPPORTED, 0, { "Windows-20000", "x-Chinese_CNS", NULL } }, /* * x-cp20001: TCA Taiwan * Not supported by ICU */ { MIBUNDEF, 20001, STRING_ENCODING_WINDOWS_20001, UNSUPPORTED, 0, { "Windows-20001", "x-cp20001", NULL } }, /* * x_Chinese-Eten: Eten Taiwan; Chinese Traditional (Eten) * Not supported by ICU */ { MIBUNDEF, 20002, STRING_ENCODING_WINDOWS_20002, UNSUPPORTED, 0, { "Windows-20002", "x_Chinese-Eten", NULL } }, /* * x-cp20003: IBM5550 Taiwan * Not supported by ICU */ { MIBUNDEF, 20003, STRING_ENCODING_WINDOWS_20003, UNSUPPORTED, 0, { "Windows-20003", "x-cp20003", NULL } }, /* * x-cp20004: TeleText Taiwan * Not supported by ICU */ { MIBUNDEF, 20004, STRING_ENCODING_WINDOWS_20004, UNSUPPORTED, 0, { "Windows-20004", "x-cp20004", NULL } }, /* * x-cp20005: Wang Taiwan * Not supported by ICU */ { MIBUNDEF, 20005, STRING_ENCODING_WINDOWS_20005, UNSUPPORTED, 0, { "Windows-20005", "x-cp20005", NULL } }, /* * x-IA5: IA5 (IRV International Alphabet No. 5, 7-bit); * Western European (IA5) * Not supported by ICU */ { MIBUNDEF, 20105, STRING_ENCODING_WINDOWS_20105, UNSUPPORTED, 0, { "Windows-20105", "x-IA5", NULL } }, /* * x-IA5-German: IA5 German (7-bit) * Not supported by ICU */ { MIBUNDEF, 20106, STRING_ENCODING_WINDOWS_20106, UNSUPPORTED, 0, { "Windows-20106", "x-IA5-German", NULL } }, /* * x-IA5-Swedish: IA5 Swedish (7-bit) * Not supported by ICU */ { MIBUNDEF, 20107, STRING_ENCODING_WINDOWS_20107, UNSUPPORTED, 0, { "Windows-20107", "x-IA5-Swedish", NULL } }, /* * x-IA5-Norwegian: IA5 Norwegian (7-bit) * Not supported by ICU */ { MIBUNDEF, 20108, STRING_ENCODING_WINDOWS_20108, UNSUPPORTED, 0, { "Windows-20108", "x-IA5-Norwegian", NULL } }, /* * x-cp20269: ISO 6937 Non-Spacing Accent * Not supported by ICU */ { MIBUNDEF, 20269, STRING_ENCODING_WINDOWS_20269, UNSUPPORTED, 0, { "Windows-20269", "x-cp20269", NULL } }, /* * x-EBCDIC-KoreanExtended: IBM EBCDIC Korean Extended * Not supported by ICU */ { MIBUNDEF, 20833, STRING_ENCODING_WINDOWS_20833, UNSUPPORTED, 0, { "Windows-20833", "x-EBCDIC-KoreanExtended", NULL } }, /* * x-cp20949: Korean Wansung * Not supported by ICU */ { MIBUNDEF, 20949, STRING_ENCODING_WINDOWS_20949, UNSUPPORTED, 0, { "Windows-20949", "x-cp20949", NULL } }, /* * cp1025: IBM EBCDIC Cyrillic Serbian-Bulgarian * ICU doesn't have alias "Windows-21025", use "cp1025" */ { MIBUNDEF, 21025, STRING_ENCODING_WINDOWS_21025, IN_FULL_ICU, 0, { "cp1025", "ibm-1025", "1025", "ibm-1025_P100-1995", NULL } }, /* * Windows-21027: (deprecated) * Not supported by ICU */ { MIBUNDEF, 21027, STRING_ENCODING_WINDOWS_21027, UNSUPPORTED, 0, { "Windows-21027", NULL } }, /* * x-Europa: Europa 3 * Not supported by ICU */ { MIBUNDEF, 29001, STRING_ENCODING_WINDOWS_29001, UNSUPPORTED, 0, { "Windows-29001", "x-Europa", NULL } }, /* * iso-8859-8-i: ISO 8859-8 Hebrew; Hebrew (ISO-Logical) * Windows duplicate of ISO-8859-8 (Windows-28598) * ICU doesn't have alias "Windows-38598", use * "iso-8859-8-i" */ { MIBUNDEF, 38598, STRING_ENCODING_WINDOWS_38598, IN_FULL_ICU, 0, { "iso-8859-8-i", NULL } }, /* * csISO2022JP: ISO 2022 Japanese with halfwidth Katakana; * Japanese (JIS-Allow 1 byte Kana) * handled by ICU with ISO-2022-JP */ { MIBUNDEF, 50221, STRING_ENCODING_WINDOWS_50221, SUPPORTED, 0, { "csISO2022JP", NULL } }, /* * iso-2022-jp: ISO 2022 Japanese JIS X 0201-1989; * Japanese (JIS-Allow 1 byte Kana - SO/SI) * handled by ICU with ISO-2022-JP */ { MIBUNDEF, 50222, STRING_ENCODING_WINDOWS_50222, IN_FULL_ICU, 0, { "ISO-2022-JP", NULL } }, /* * Windows-50229: ISO 2022 Traditional Chinese * Not supported by ICU */ { MIBUNDEF, 50229, STRING_ENCODING_WINDOWS_50229, UNSUPPORTED, 0, { "Windows-50229", NULL } }, /* * Windows-50930: EBCDIC Japanese (Katakana) Extended * Not supported by ICU */ { MIBUNDEF, 50930, STRING_ENCODING_WINDOWS_50930, UNSUPPORTED, 0, { "Windows-50930", NULL } }, /* * Windows-50931: EBCDIC US-Canada and Japanese * Not supported by ICU */ { MIBUNDEF, 50931, STRING_ENCODING_WINDOWS_50931, UNSUPPORTED, 0, { "Windows-50931", NULL } }, /* * Windows-50933: EBCDIC Korean Extended and Korean * Not supported by ICU */ { MIBUNDEF, 50933, STRING_ENCODING_WINDOWS_50933, UNSUPPORTED, 0, { "Windows-50933", NULL } }, /* * Windows-50935: EBCDIC Simplified Chinese Extended and Simplified Chinese * Not supported by ICU */ { MIBUNDEF, 50935, STRING_ENCODING_WINDOWS_50935, UNSUPPORTED, 0, { "Windows-50935", NULL } }, /* * Windows-50936: EBCDIC Simplified Chinese * Not supported by ICU */ { MIBUNDEF, 50936, STRING_ENCODING_WINDOWS_50936, UNSUPPORTED, 0, { "Windows-50936", NULL } }, /* * Windows-50937: EBCDIC US-Canada and Traditional Chinese * Not supported by ICU */ { MIBUNDEF, 50937, STRING_ENCODING_WINDOWS_50937, UNSUPPORTED, 0, { "Windows-50937", NULL } }, /* * Windows-50939: EBCDIC Japanese (Latin) Extended and Japanese * Not supported by ICU */ { MIBUNDEF, 50939, STRING_ENCODING_WINDOWS_50939, UNSUPPORTED, 0, { "Windows-50939", NULL } }, /* * EUC-CN: EUC Simplified Chinese; Chinese Simplified (EUC) * Route to GB2312 */ { MIBUNDEF, 51936, STRING_ENCODING_WINDOWS_51936, IN_FULL_ICU, 0, { "EUC-CN", NULL } }, /* * Windows-51950: EUC Traditional Chinese * Not supported by ICU */ { MIBUNDEF, 51950, STRING_ENCODING_WINDOWS_51950, UNSUPPORTED, 0, { "Windows-51950", NULL } }, /* * x-iscii-de: ISCII Devanagari */ { MIBUNDEF, 57002, STRING_ENCODING_WINDOWS_57002, SUPPORTED, 0, { "Windows-57002", "x-iscii-de", "iscii-dev", "ibm-4902", NULL } }, /* * x-iscii-be: ISCII Bengali */ { MIBUNDEF, 57003, STRING_ENCODING_WINDOWS_57003, SUPPORTED, 0, { "Windows-57003", "x-iscii-be", "iscii-bng", NULL } }, /* * x-iscii-ta: ISCII Tamil */ { MIBUNDEF, 57004, STRING_ENCODING_WINDOWS_57004, SUPPORTED, 0, { "Windows-57004", "x-iscii-ta", "iscii-tml", NULL } }, /* * x-iscii-te: ISCII Telugu */ { MIBUNDEF, 57005, STRING_ENCODING_WINDOWS_57005, SUPPORTED, 0, { "Windows-57005", "x-iscii-te", "iscii-tlg", NULL } }, /* * x-iscii-as: ISCII Assamese */ { MIBUNDEF, 57006, STRING_ENCODING_WINDOWS_57006, SUPPORTED, 0, { "Windows-57006", "x-iscii-as", NULL } }, /* * x-iscii-or: ISCII Oriya */ { MIBUNDEF, 57007, STRING_ENCODING_WINDOWS_57007, SUPPORTED, 0, { "Windows-57007", "x-iscii-or", "iscii-ori", NULL } }, /* * x-iscii-ka: ISCII Kannada */ { MIBUNDEF, 57008, STRING_ENCODING_WINDOWS_57008, SUPPORTED, 0, { "Windows-57008", "x-iscii-ka", "iscii-knd", NULL } }, /* * x-iscii-ma: ISCII Malayalam */ { MIBUNDEF, 57009, STRING_ENCODING_WINDOWS_57009, SUPPORTED, 0, { "Windows-57009", "x-iscii-ma", "iscii-mlm", NULL } }, /* * x-iscii-gu: ISCII Gujarati */ { MIBUNDEF, 57010, STRING_ENCODING_WINDOWS_57010, SUPPORTED, 0, { "Windows-57010", "x-iscii-gu", "x-iscii-guj", NULL } }, /* * x-iscii-pa: ISCII Punjabi */ { MIBUNDEF, 57011, STRING_ENCODING_WINDOWS_57011, SUPPORTED, 0, { "Windows-57011", "x-iscii-pa", "iscii-gur", NULL } }, }; /* *----------------------------------------------------------------------------- * * UnicodeNormalizeEncodingName -- * * Normalizes a US-ASCII encoding name by discarding all * non-alphanumeric characters and converting to lower-case. * * Results: * The allocated, normalized encoding name in NUL-terminated * US-ASCII bytes. Caller must free. * * Side effects: * None * *----------------------------------------------------------------------------- */ char * UnicodeNormalizeEncodingName(const char *encodingName) // IN { char *result; char *currentResult; ASSERT(encodingName); result = Util_SafeMalloc(strlen(encodingName) + 1); currentResult = result; for (currentResult = result; *encodingName != '\0'; encodingName++) { // The explicit cast from char to int is necessary for Netware builds. if (isalnum((int) *encodingName)) { *currentResult = tolower(*encodingName); currentResult++; } } *currentResult = '\0'; return result; } /* *----------------------------------------------------------------------------- * * UnicodeIANALookup -- * * Lookup an encoding name in the IANA cross reference table. * * Results: * The index of the encoding within the table * -1 if the encoding is not found * * Side effects: * None * *----------------------------------------------------------------------------- */ static int UnicodeIANALookup(const char *encodingName) // IN { /* * Thread-safe hash table to speed up encoding name -> IANA table * index lookups. */ static Atomic_Ptr htPtr; static HashTable *encCache = NULL; char *name = NULL; char *candidate = NULL; const char *p; int i; int j; int acp; void *idx; size_t windowsPrefixLen = sizeof "windows-" - 1 /* NUL */; if (UNLIKELY(encCache == NULL)) { encCache = HashTable_AllocOnce(&htPtr, 128, HASH_ISTRING_KEY | HASH_FLAG_ATOMIC | HASH_FLAG_COPYKEY, free); } if (encCache && HashTable_Lookup(encCache, encodingName, &idx)) { return (int)(uintptr_t)idx; } /* * check for Windows-xxxx encoding names generated from GetACP() * code page numbers, see: CodeSetOld_GetCurrentCodeSet() */ if ( strncmp(encodingName, "windows-", windowsPrefixLen) == 0 || strncmp(encodingName, "Windows-", windowsPrefixLen) == 0) { p = encodingName + windowsPrefixLen; acp = 0; // The explicit cast from char to int is necessary for Netware builds. while (*p && isdigit((int)*p)) { acp *= 10; acp += *p - '0'; p++; } if (!*p) { for (i = 0; i < ARRAYSIZE(xRef); i++) { if (xRef[i].winACP == acp) { goto done; } } } } // Try the raw names first to avoid the expense of normalizing everything. for (i = 0; i < ARRAYSIZE(xRef); i++) { for (j = 0; (p = xRef[i].names[j]) != NULL; j++) { if (strcmp(encodingName, p) == 0) { goto done; } } } name = UnicodeNormalizeEncodingName(encodingName); for (i = 0; i < ARRAYSIZE(xRef); i++) { for (j = 0; (p = xRef[i].names[j]) != NULL; j++) { candidate = UnicodeNormalizeEncodingName(p); if (strcmp(name, candidate) == 0) { goto done; } free(candidate); } } free(name); /* * Did not find a matching name. Don't validate encoding names * here, unrecognized encoding will be caught when converting * from name to enum. */ Log("%s: Did not find an IANA match for encoding \"%s\"\n", __FUNCTION__, encodingName); return -1; done: free(name); free(candidate); if (encCache) { HashTable_Insert(encCache, encodingName, (void *)(uintptr_t)i); } return i; } /* *----------------------------------------------------------------------------- * * Unicode_EncodingEnumToName -- * * Converts a StringEncoding enum value to the equivalent * encoding name. * * Results: * A NUL-terminated US-ASCII string containing the name of the * encoding. Encodings follow the preferred MIME encoding name * from IANA's Character Sets standard. * * Side effects: * None * *----------------------------------------------------------------------------- */ const char * Unicode_EncodingEnumToName(StringEncoding encoding) // IN { int i; encoding = Unicode_ResolveEncoding(encoding); /* If you hit this, you probably need to call Unicode_Init() */ ASSERT(encoding != STRING_ENCODING_UNKNOWN); /* * Look for a match in the xRef table. If found, return the * preferred MIME name. Whether ICU supports this encoding or * not isn't material here. */ for (i = 0; i < ARRAYSIZE(xRef); i++) { if (encoding == xRef[i].encoding) { return xRef[i].names[xRef[i].preferredMime]; } } Log("%s: Unknown encoding %d.\n", __FUNCTION__, encoding); NOT_REACHED(); } /* *----------------------------------------------------------------------------- * * Unicode_EncodingNameToEnum -- * * Converts a NUL-terminated US-ASCII string encoding name * to the equivalent enum. * * Results: * The StringEncoding enum value corresponding to the name, or * STRING_ENCODING_UNKNOWN if the encoding name is not supported. * * Inside tools all recognized local encodings are supported. * If the local encoding is not available in our copy of ICU, * fall back to the guest's facilities for converting between * the local encoding and UTF-8. * * Side effects: * In tools, finding an unsupported encoding disables ICU and * switches to codesetOld support. * *----------------------------------------------------------------------------- */ StringEncoding Unicode_EncodingNameToEnum(const char *encodingName) // IN { int idx; idx = UnicodeIANALookup(encodingName); if (idx < 0) { return STRING_ENCODING_UNKNOWN; } if (xRef[idx].isSupported) { return xRef[idx].encoding; } #if defined(VMX86_TOOLS) && (!defined(OPEN_VM_TOOLS) || defined(USE_ICU)) if (idx == UnicodeIANALookup(CodeSet_GetCurrentCodeSet())) { CodeSet_DontUseIcu(); return xRef[idx].encoding; } #endif return STRING_ENCODING_UNKNOWN; } /* *----------------------------------------------------------------------------- * * UnicodeGetCurrentEncodingInternal -- * * Calls CodeSet_GetCurrentCodeSet() and returns the corresponding * encoding. * * Results: * The current encoding. * * Side effects: * None. * *----------------------------------------------------------------------------- */ StringEncoding UnicodeGetCurrentEncodingInternal(void) { StringEncoding encoding = Unicode_EncodingNameToEnum(CodeSet_GetCurrentCodeSet()); ASSERT(Unicode_IsEncodingValid(encoding)); return encoding; } /* *----------------------------------------------------------------------------- * * Unicode_GetCurrentEncoding -- * * Return the current encoding (corresponding to * CodeSet_GetCurrentCodeSet()). * * Results: * The current encoding. * * Side effects: * Since the return value of CodeSet_GetCurrentCodeSet() and our * look-up table do not change, we memoize the value. * *----------------------------------------------------------------------------- */ StringEncoding Unicode_GetCurrentEncoding(void) { static StringEncoding encoding = STRING_ENCODING_UNKNOWN; if (UNLIKELY(encoding == STRING_ENCODING_UNKNOWN)) { encoding = UnicodeGetCurrentEncodingInternal(); } return encoding; } /* *----------------------------------------------------------------------------- * * Unicode_ResolveEncoding -- * * Resolves a meta-encoding enum value (e.g. STRING_ENCODING_DEFAULT) to * a concrete one (e.g. STRING_ENCODING_UTF8). * * Results: * A StringEncoding enum value. May return STRING_ENCODING_UNKNOWN. * * Side effects: * None * *----------------------------------------------------------------------------- */ StringEncoding Unicode_ResolveEncoding(StringEncoding encoding) // IN: { if (encoding == STRING_ENCODING_DEFAULT) { encoding = Unicode_GetCurrentEncoding(); } ASSERT(Unicode_IsEncodingValid(encoding)); return encoding; } /* *----------------------------------------------------------------------------- * * Unicode_IsEncodingValid -- * * Checks whether we support the given encoding. * * Results: * TRUE if supported, FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool Unicode_IsEncodingValid(StringEncoding encoding) // IN { return encoding >= STRING_ENCODING_FIRST && encoding < STRING_ENCODING_MAX_SPECIFIED; } /* *----------------------------------------------------------------------------- * * UnicodeInitInternal -- * * Convert argv and environment from default encoding into * unicode and initialize the cache of the native code set name * used to resolve STRING_ENCODING_DEFAULT. * * wargv takes precedence over argv as input if both are * specified, likewise with wenvp/envp. * * Results: * returns on success * errors are terminal * * Side effects: * Calling CodeSet_GetCurrentCodeSet() initializes the cache of the * native code set name. The cached name is used to resolve references * to STRING_ENCODING_DEFAULT in unicode functions. * *----------------------------------------------------------------------------- */ static void UnicodeInitInternal(int argc, // IN const char *icuDataDir, // IN utf16_t **wargv, // IN/OUT (OPT) utf16_t **wenvp, // IN/OUT (OPT) char ***argv, // IN/OUT (OPT) char ***envp) // IN/OUT (OPT) { #if !defined(__APPLE__) && !defined(VMX86_SERVER) char **list; StringEncoding encoding; const char *currentCodeSetName; #endif Bool success = FALSE; char panicMsg[1024]; static volatile Bool inited = FALSE; static Atomic_uint32 locked = {0}; panicMsg[0] = '\0'; /* * This function must be callable multiple times. We can't depend * on lib/sync, so cheese it. */ while (1 == Atomic_ReadIfEqualWrite(&locked, 0, 1)) { #if !defined(__FreeBSD__) usleep(250 * 1000); #endif } if (inited) { success = TRUE; goto exit; } /* * Always init the codeset module first. */ if (!CodeSet_Init(icuDataDir)) { snprintf(panicMsg, sizeof panicMsg, "Failed to initialize codeset.\n"); goto exit; } // UTF-8 native encoding for these two #if !defined(__APPLE__) && !defined(VMX86_SERVER) currentCodeSetName = CodeSet_GetCurrentCodeSet(); encoding = Unicode_EncodingNameToEnum(currentCodeSetName); if (!Unicode_IsEncodingValid(encoding)) { snprintf(panicMsg, sizeof panicMsg, "Unsupported local character encoding \"%s\".\n", currentCodeSetName); goto exit; } if (wargv) { list = Unicode_AllocList((char **)wargv, argc + 1, STRING_ENCODING_UTF16); if (!list) { snprintf(panicMsg, sizeof panicMsg, "Unicode_AllocList1 failed.\n"); goto exit; } *argv = list; } else if (argv) { list = Unicode_AllocList(*argv, argc + 1, STRING_ENCODING_DEFAULT); if (!list) { snprintf(panicMsg, sizeof panicMsg, "Unicode_AllocList2 failed.\n"); goto exit; } *argv = list; } if (wenvp) { list = Unicode_AllocList((char **)wenvp, -1, STRING_ENCODING_UTF16); if (!list) { snprintf(panicMsg, sizeof panicMsg, "Unicode_AllocList3 failed.\n"); goto exit; } *envp = list; } else if (envp) { list = Unicode_AllocList(*envp, -1, STRING_ENCODING_DEFAULT); if (!list) { snprintf(panicMsg, sizeof panicMsg, "Unicode_AllocList4 failed.\n"); goto exit; } *envp = list; } #endif // !__APPLE__ && !VMX86_SERVER inited = TRUE; success = TRUE; exit: Atomic_Write(&locked, 0); if (!success) { panicMsg[sizeof panicMsg - 1] = '\0'; Panic("%s", panicMsg); exit(1); } } void Unicode_InitW(int argc, // IN utf16_t **wargv, // IN/OUT (OPT) utf16_t **wenvp, // IN/OUT (OPT) char ***argv, // IN/OUT (OPT) char ***envp) // IN/OUT (OPT) { UnicodeInitInternal(argc, NULL, wargv, wenvp, argv, envp); } void Unicode_InitEx(int argc, // IN char ***argv, // IN/OUT (OPT) char ***envp, // IN/OUT (OPT) const char *icuDataDir) // IN (OPT) { UnicodeInitInternal(argc, icuDataDir, NULL, NULL, argv, envp); } void Unicode_Init(int argc, // IN char ***argv, // IN/OUT (OPT) char ***envp) // IN/OUT (OPT) { UnicodeInitInternal(argc, NULL, NULL, NULL, argv, envp); } #ifdef TEST_CUSTOM_ICU_DATA_FILE /* *----------------------------------------------------------------------------- * * UnicodeICUTest -- * * Test custom ICU data files * * Checks string encodings for whether they are supported in * the xRef cross reference table and calls ICU with the * encodings to try to convert a simple ASCII string. Note * that GB-2312-80 (Chinese) does not support ASCII, so it * is expected to fail the conversion. * * To test custom ICU files, change the second arg in the call to * UnicodeInitInternal() above to the *directory* containing the ICU * data file, and add a call to this function. Note that the name of * the data file is hard coded to "icudt44l.dat" in lib/misc/codeset.c. * Also note that in devel builds, lib/misc/codeset.c will override the * icu directory argument with a path to the toolchain, so that may need * to be disabled, too. * * Results: * Prints results to stdout. * * Side effects: * *----------------------------------------------------------------------------- */ void UnicodeICUTest(void) { StringEncoding enc, enc2; const char *name; Bool supported; Bool redirected; Bool canGetBytes; for (enc = STRING_ENCODING_FIRST; enc < STRING_ENCODING_MAX_SPECIFIED; enc++ ) { name = Unicode_EncodingEnumToName(enc); enc2 = Unicode_EncodingNameToEnum(name); redirected = FALSE; if (enc2 == STRING_ENCODING_UNKNOWN) { supported = FALSE; } else { supported = TRUE; if (enc != enc2) { redirected = TRUE; // xRef mapped to different entry } } canGetBytes = Unicode_CanGetBytesWithEncoding("Hello world", enc); printf("%s: supported:%s redirected:%s works:%s result:%s\n", name, supported ? "yes" : "no ", redirected ? "yes" : "no ", canGetBytes ? "yes" : "no ", (supported && enc != STRING_ENCODING_GB_2312_80) == canGetBytes ? "pass" : "FAIL"); } } #endif open-vm-tools-9.4.0-1280544/lib/unicode/unicodeICU.c0000644765153500003110000003305612220061556017775 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * unicodeICU.c -- * * Unicode functionality that depends on the third-party ICU * library. */ #include #include #include #include #include #include "util.h" #include "unicodeBase.h" #include "unicodeICU.h" /* *----------------------------------------------------------------------------- * * Unicode_CompareWithLocale -- * * Compares two strings for equivalence under the collation rules * of the specified locale. * * The caller can specify ignoring differences in accents, case, * or punctuation. * * Results: * -1 if str1 < str2, 0 if str1 == str2, 1 if str1 > str2. * * Side effects: * None * *----------------------------------------------------------------------------- */ int Unicode_CompareWithLocale(ConstUnicode str1, // IN ConstUnicode str2, // IN const char *locale, // IN UnicodeCompareOption compareOption) // IN { UCollationResult compareResult; UColAttributeValue comparisonStrength; UErrorCode status = U_ZERO_ERROR; int result; UCollator *coll; UCharIterator str1Iter; UCharIterator str2Iter; uiter_setUTF8(&str1Iter, (const char *)str1, -1); uiter_setUTF8(&str2Iter, (const char *)str2, -1); switch (compareOption) { case UNICODE_COMPARE_DEFAULT: comparisonStrength = UCOL_DEFAULT; break; case UNICODE_COMPARE_IGNORE_ACCENTS: comparisonStrength = UCOL_PRIMARY; break; case UNICODE_COMPARE_IGNORE_CASE: comparisonStrength = UCOL_SECONDARY; break; case UNICODE_COMPARE_IGNORE_PUNCTUATION: comparisonStrength = UCOL_TERTIARY; break; default: NOT_IMPLEMENTED(); } coll = ucol_open(locale, &status); ASSERT(U_SUCCESS(status)); ASSERT(coll); if (U_FAILURE(status) || !coll) { return -1; } // Normalize all strings to NFD before comparing. ucol_setAttribute(coll, UCOL_NORMALIZATION_MODE, UCOL_ON, &status); ucol_setAttribute(coll, UCOL_STRENGTH, comparisonStrength, &status); ASSERT(U_SUCCESS(status)); compareResult = ucol_strcollIter(coll, &str1Iter, &str2Iter, &status); ucol_close(coll); if (U_FAILURE(status)) { // We'll probably only get here if the input wasn't UTF-8. ASSERT(U_SUCCESS(status)); return -1; } switch (compareResult) { case UCOL_LESS: result = -1; break; case UCOL_EQUAL: result = 0; break; case UCOL_GREATER: result = 1; break; default: NOT_IMPLEMENTED(); } return result; } /* *----------------------------------------------------------------------------- * * Unicode_Normalize -- * * Creates a Unicode string by normalizing the input string * into a Unicode normal form. * * Normalization Form C ("precomposed") ensures that accented * characters use as few Unicode code points as possible. This * form is often used on Windows and Linux hosts. * * Example: small letter e with acute -> U+00E9 * * Normalization Form D ("decomposed") ensures that accented * characters (e with accent acute) use separate Unicode code * points for the base letter and accents. This form is used on * Mac OS hosts. * * Example: small letter e with acute -> U+0065 U+0301 * * Results: * The allocated Unicode string, or NULL on failure. * Caller must free with Unicode_Free(). * * Side effects: * None * *----------------------------------------------------------------------------- */ Unicode Unicode_Normalize(ConstUnicode str, // IN UnicodeNormalizationForm form) // IN { UNormalizationMode mode; UChar *uchars; Unicode result; int32_t normalizedLen; UErrorCode status = U_ZERO_ERROR; UCharIterator strIter; UBool neededToNormalize = FALSE; uiter_setUTF8(&strIter, (const char *)str, -1); switch (form) { case UNICODE_NORMAL_FORM_C: mode = UNORM_NFC; break; case UNICODE_NORMAL_FORM_D: mode = UNORM_NFD; break; default: NOT_REACHED(); } normalizedLen = unorm_next(&strIter, NULL, 0, mode, 0, TRUE, &neededToNormalize, &status); if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) { // We expect U_BUFFER_OVERFLOW_ERROR here. Anything else is a problem. ASSERT(U_SUCCESS(status)); return NULL; } uchars = Util_SafeMalloc(sizeof *uchars * normalizedLen); // Reset back to the beginning of the UTF-8 input. (*strIter.move)(&strIter, 0, UITER_START); status = U_ZERO_ERROR; normalizedLen = unorm_next(&strIter, uchars, normalizedLen, mode, 0, TRUE, &neededToNormalize, &status); if (U_FAILURE(status)) { ASSERT(U_SUCCESS(status)); return NULL; } result = Unicode_AllocWithLength(uchars, normalizedLen * 2, STRING_ENCODING_UTF16); free(uchars); return result; } /* *----------------------------------------------------------------------------- * * Unicode_ToLower -- * * Creates a Unicode string by lower-casing the input string using * the rules of the specified locale. * * The resulting string may not be the same length as the input * string. * * Pass NULL for the locale to use the process's default locale. * * Results: * The allocated Unicode string, or NULL on failure. * Caller must free with Unicode_Free(). * * Side effects: * None * *----------------------------------------------------------------------------- */ Unicode Unicode_ToLower(ConstUnicode str, // IN const char *locale) // IN { UCaseMap *caseMap; UErrorCode status = U_ZERO_ERROR; char *utf8Dest; const char *utf8Src = (const char *)str; int32_t utf8SrcLen = strlen(utf8Src); int32_t destCapacity = utf8SrcLen + 1; int32_t destLen; Unicode result = NULL; /* * XXX TODO: This and the two following functions are substantially * identical. Refactor them! (Note that ucasemap_utf8ToTitle * takes a non-const UCaseMap, so we can't just use pointers to * functions unless we cast.) */ // Most lower-case operations don't change the length of the string. utf8Dest = (char *)Util_SafeMalloc(destCapacity); caseMap = ucasemap_open(locale, 0, &status); if (U_FAILURE(status)) { goto out; } destLen = ucasemap_utf8ToLower(caseMap, utf8Dest, destCapacity, utf8Src, utf8SrcLen, &status); if (status != U_BUFFER_OVERFLOW_ERROR) { goto out; } // If we need a bigger buffer, then reallocate and retry. destCapacity = destLen + 1; utf8Dest = (char *)Util_SafeRealloc(utf8Dest, destCapacity); status = U_ZERO_ERROR; destLen = ucasemap_utf8ToLower(caseMap, utf8Dest, destCapacity, utf8Src, utf8SrcLen, &status); out: ucasemap_close(caseMap); if (U_SUCCESS(status) && status != U_STRING_NOT_TERMINATED_WARNING) { result = (Unicode)utf8Dest; } else { ASSERT(U_SUCCESS(status)); ASSERT(status != U_STRING_NOT_TERMINATED_WARNING); } return result; } /* *----------------------------------------------------------------------------- * * Unicode_ToUpper -- * * Creates a Unicode string by upper-casing the input string using * the rules of the specified locale. * * The resulting string may not be the same length as the input * string. * * Pass NULL for the locale to use the process's default locale. * * Results: * The allocated Unicode string, or NULL on failure. * Caller must free with Unicode_Free(). * * Side effects: * None * *----------------------------------------------------------------------------- */ Unicode Unicode_ToUpper(ConstUnicode str, // IN const char *locale) // IN { UCaseMap *caseMap; UErrorCode status = U_ZERO_ERROR; char *utf8Dest; const char *utf8Src = (const char *)str; int32_t utf8SrcLen = strlen(utf8Src); int32_t destCapacity = utf8SrcLen + 1; int32_t destLen; Unicode result = NULL; // Most upper-case operations don't change the length of the string. utf8Dest = (char *)Util_SafeMalloc(destCapacity); caseMap = ucasemap_open(locale, 0, &status); if (U_FAILURE(status)) { goto out; } destLen = ucasemap_utf8ToUpper(caseMap, utf8Dest, destCapacity, utf8Src, utf8SrcLen, &status); if (status != U_BUFFER_OVERFLOW_ERROR) { goto out; } // If we need a bigger buffer, then reallocate and retry. destCapacity = destLen + 1; utf8Dest = (char *)Util_SafeRealloc(utf8Dest, destCapacity); status = U_ZERO_ERROR; destLen = ucasemap_utf8ToUpper(caseMap, utf8Dest, destCapacity, utf8Src, utf8SrcLen, &status); out: ucasemap_close(caseMap); if (U_SUCCESS(status) && status != U_STRING_NOT_TERMINATED_WARNING) { result = (Unicode)utf8Dest; } else { ASSERT(U_SUCCESS(status)); ASSERT(status != U_STRING_NOT_TERMINATED_WARNING); } return result; } /* * "ucasemap_utf8ToTitle" is not in version 3.6 of the ICU library, * which appears to be the default on many systems... * * XXX Currently HAVE_ICU_38 is only set by the open-source tools * build (based on what it detects on the current system) because that * is the only entity currently capable of compiling with USE_ICU. */ #ifdef HAVE_ICU_38 /* *----------------------------------------------------------------------------- * * Unicode_ToTitle -- * * Creates a Unicode string by title-casing the input string using * the rules of the specified locale. * * The resulting string may not be the same length as the input * string. * * Pass NULL for the locale to use the process's default locale. * * Results: * The allocated Unicode string, or NULL on failure. * Caller must free with Unicode_Free(). * * Side effects: * None * *----------------------------------------------------------------------------- */ Unicode Unicode_ToTitle(ConstUnicode str, // IN const char *locale) // IN { UCaseMap *caseMap; UErrorCode status = U_ZERO_ERROR; char *utf8Dest; const char *utf8Src = (const char *)str; int32_t utf8SrcLen = strlen(utf8Src); int32_t destCapacity = utf8SrcLen + 1; int32_t destLen; Unicode result = NULL; // Most title-case operations don't change the length of the string. utf8Dest = (char *)Util_SafeMalloc(destCapacity); caseMap = ucasemap_open(locale, 0, &status); if (U_FAILURE(status)) { goto out; } destLen = ucasemap_utf8ToTitle(caseMap, utf8Dest, destCapacity, utf8Src, utf8SrcLen, &status); if (status != U_BUFFER_OVERFLOW_ERROR) { goto out; } // If we need a bigger buffer, then reallocate and retry. destCapacity = destLen + 1; utf8Dest = (char *)Util_SafeRealloc(utf8Dest, destCapacity); status = U_ZERO_ERROR; destLen = ucasemap_utf8ToTitle(caseMap, utf8Dest, destCapacity, utf8Src, utf8SrcLen, &status); out: ucasemap_close(caseMap); if (U_SUCCESS(status) && status != U_STRING_NOT_TERMINATED_WARNING) { result = (Unicode)utf8Dest; } else { ASSERT(U_SUCCESS(status)); ASSERT(status != U_STRING_NOT_TERMINATED_WARNING); } return result; } #endif // HAVE_ICU_38 open-vm-tools-9.4.0-1280544/lib/unicode/unicodeStatic.c0000644765153500003110000001164012220061556020577 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * unicodeStatic.c -- * * Manages memory for static ConstUnicode literal strings * created like: * * ConstUnicode c = U_UNESCAPE("Copyright \\u00A9 VMware, Inc."); * * Uses two HashTables to hold static ConstUnicode strings. Static * ConstUnicode strings are keyed off the ASCII bytes passed to the * static macros. * * Unescaped strings are kept separate from escaped strings so * users can expect a literal "\\" to stay as-is by default. * * This implementation exists to works around gcc's lack of an * intrinsic 16-bit wide character type; wchar_t on gcc is 32 * bits wide, which is not useful for most Unicode algorithms. * * Note that the Win32 compiler does have an intrinsic 16-bit * wide character type (L"foo"), so we can optimize for that case * in a later implementation. * * If GCC later offers an intrinsic 16-bit wide character type, * we can completely get rid of this implementation. */ #include "vmware.h" #include "hashTable.h" #include "vm_atomic.h" #include "hashTable.h" #include "unicodeBase.h" #include "unicodeInt.h" #include "util.h" /* These are Implicitly initialized to NULL */ static Atomic_Ptr UnicodeStringTable; static Atomic_Ptr UnicodeUnescapedStringTable; /* *----------------------------------------------------------------------------- * * UnicodeHashFree -- * * Called by the hash table functions when a value must be replaced. * * Results: * The argument, a unicode, is freed. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void UnicodeHashFree(void *v) // IN: { Unicode_Free((Unicode) v); } /* *----------------------------------------------------------------------------- * * Unicode_GetStatic -- * * Helper function for the U_UNESCAPE() macro. * * Given a NUL-terminated ASCII string, returns a ConstUnicode * string containing the string's contents. * * If unescape is TRUE, then \\uABCD becomes the Unicode code * point U+ABCD and \\U001FABCD becomes the Unicode code point * U+1FABCD in the resulting string. * * Results: * A ConstUnicode string. Memory is managed inside this module; * caller does not need to free. * * Side effects: * Creates the UnicodeStringTable and UnicodeUnescapedStringTable hash * tables if it don't yet exist. * Creates and inserts a Unicode string into the appropriate static * string table if the key 'asciiBytes' is not found in the table. * *----------------------------------------------------------------------------- */ ConstUnicode Unicode_GetStatic(const char *asciiBytes, // IN Bool unescape) // IN { Unicode result = NULL; HashTable *stringTable; if (unescape) { stringTable = HashTable_AllocOnce(&UnicodeUnescapedStringTable, 4096, HASH_FLAG_ATOMIC | HASH_STRING_KEY, UnicodeHashFree); } else { stringTable = HashTable_AllocOnce(&UnicodeStringTable, 4096, HASH_FLAG_ATOMIC | HASH_STRING_KEY, UnicodeHashFree); } /* * Attempt a lookup for the key value; if it is found things are easy and * fine. Otherwise HashTable_LookupOrInsert is used to attempt to enter * the data in a racey manner. Should multiple threads attempt to enter * the same key concurrently one thread will get the entered data and the * other threads will detect that their entries were rejected; they * discard their copies of the data and use the entered data (values * will be stable). */ if (!HashTable_Lookup(stringTable, asciiBytes, (void **) &result)) { Unicode newData = UnicodeAllocStatic(asciiBytes, unescape); if (newData) { result = HashTable_LookupOrInsert(stringTable, asciiBytes, newData); if (result != newData) { Unicode_Free(newData); } } } return result; } open-vm-tools-9.4.0-1280544/lib/unicode/unicodeCommon.c0000644765153500003110000002334412220061556020604 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * unicodeCommon.c -- * * Functions common to all implementations of lib/unicode. */ #include #include #include "vmware.h" #include "escape.h" #include "vm_assert.h" #include "unicodeBase.h" #include "unicodeInt.h" #include "unicodeTypes.h" // Array of byte values we want Escape_Do() to escape when logging. static const int NonPrintableBytesToEscape[256] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // Control characters. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // More control characters. 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, 1, 0, 0, 0, // Backslash 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, 1, // DEL 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; /* *----------------------------------------------------------------------------- * * Unicode_EscapeBuffer -- * * Escape non-printable bytes of the buffer with \xAB, where 0xAB * is the non-printable byte value. * * Results: * The allocated, NUL-terminated, US-ASCII string containing the * escaped buffer. Caller must free the buffer. * * Side effects: * None * *----------------------------------------------------------------------------- */ char * Unicode_EscapeBuffer(const void *buffer, // IN ssize_t lengthInBytes, // IN StringEncoding encoding) // IN { encoding = Unicode_ResolveEncoding(encoding); if (lengthInBytes == -1) { lengthInBytes = Unicode_LengthInBytes(buffer, encoding); } /* * The buffer could have NULs or 8-bit values inside. Escape it. */ return Escape_DoString("\\x", NonPrintableBytesToEscape, buffer, lengthInBytes, NULL); } /* *----------------------------------------------------------------------------- * * UnicodeSanityCheck -- * * Simple sanity checks on buffers of specified encodings. * * Results: * TRUE if the buffer passed the sanity check for the specified encoding, * FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool UnicodeSanityCheck(const void *buffer, // IN ssize_t lengthInBytes, // IN StringEncoding encoding) // IN { ASSERT(Unicode_IsEncodingValid(encoding)); /* * Sanity check US-ASCII here, so we can fast-path its conversion * to Unicode later. */ if (encoding == STRING_ENCODING_US_ASCII) { const uint8 *asciiBytes = (const uint8 *) buffer; if (lengthInBytes == -1) { for (; *asciiBytes != '\0'; asciiBytes++) { if (*asciiBytes >= 0x80) { return FALSE; } } } else { ssize_t i; for (i = 0; i < lengthInBytes; i++) { if (asciiBytes[i] >= 0x80) { return FALSE; } } } } return TRUE; } /* *----------------------------------------------------------------------------- * * Unicode_LengthInBytes -- * * Compute the length in bytes of a string in a given encoding. * * Results: * The number of bytes. * * Side effects: * None * *----------------------------------------------------------------------------- */ ssize_t Unicode_LengthInBytes(const void *buffer, // IN StringEncoding encoding) // IN { ssize_t len; encoding = Unicode_ResolveEncoding(encoding); switch (encoding) { case STRING_ENCODING_UTF32_LE: case STRING_ENCODING_UTF32_BE: case STRING_ENCODING_UTF32_XE: { const int32 *p; for (p = buffer; *p != 0; p++) { } len = (const char *) p - (const char *) buffer; break; } case STRING_ENCODING_UTF16_LE: case STRING_ENCODING_UTF16_BE: case STRING_ENCODING_UTF16_XE: { const utf16_t *p; for (p = buffer; *p != 0; p++) { } len = (const char *) p - (const char *) buffer; break; } default: // XXX assume 8-bit encoding with no embedded null len = strlen(buffer); } return len; } /* *----------------------------------------------------------------------------- * * Unicode_UTF16Strlen -- * * Gets the number of code units in NUL-terminated UTF-16 array. * * Results: * The number of code units in the array. * * Side effects: * None * *----------------------------------------------------------------------------- */ ssize_t Unicode_UTF16Strlen(const utf16_t *utf16) // IN { ssize_t length; for (length = 0; utf16[length]; length++) { // Count the number of code units until we hit NUL. } return length; } /* *----------------------------------------------------------------------------- * * Unicode_UTF16Strdup -- * * Duplicates a UTF-16 string. * * Results: * Returns an allocated copy of the input UTF-16 string. The caller * is responsible for freeing it. * * Panics on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ utf16_t * Unicode_UTF16Strdup(const utf16_t *utf16) // IN: May be NULL. { utf16_t *copy; ssize_t numBytes; // Follow Util_SafeStrdup semantics. if (utf16 == NULL) { return NULL; } numBytes = (Unicode_UTF16Strlen(utf16) + 1 /* NUL */) * sizeof *copy; copy = Util_SafeMalloc(numBytes); memcpy(copy, utf16, numBytes); return copy; } /* *----------------------------------------------------------------------------- * * Unicode_AllocWithLength -- * * Allocates a new Unicode string given a buffer with both length * in bytes and string encoding specified. * * If lengthInBytes is -1, then buffer must be NUL-terminated. * Otherwise, buffer must be of the specified length, but does * not need to be NUL-terminated. * * If buffer is NULL, then NULL is returned. * In this case, lengthInBytes must be 0 or -1, consistent with * an empty string. * * Note that regardless of the encoding of the buffer passed to this * function, the returned string can hold any Unicode characters. * * If the buffer contains an invalid sequence of the specified * encoding or memory could not be allocated, logs the buffer, * and panics. * * Results: * An allocated Unicode string containing the decoded characters * in buffer, or NULL if input is NULL. * Caller must pass the string to Unicode_Free to free. * * Side effects: * None * *----------------------------------------------------------------------------- */ Unicode Unicode_AllocWithLength(const void *buffer, // IN: ssize_t lengthInBytes, // IN: StringEncoding encoding) // IN: { Unicode result; ASSERT(lengthInBytes >= 0 || lengthInBytes == -1); if (buffer == NULL) { ASSERT(lengthInBytes <= 0); return NULL; } encoding = Unicode_ResolveEncoding(encoding); if (lengthInBytes == -1) { lengthInBytes = Unicode_LengthInBytes(buffer, encoding); } result = UnicodeAllocInternal(buffer, lengthInBytes, encoding, FALSE); if (result == NULL) { char *escapedBuffer = Unicode_EscapeBuffer(buffer, lengthInBytes, encoding); /* * Log and panic on failure. */ Log("%s: Couldn't convert invalid buffer [%s] from %s to Unicode.\n", __FUNCTION__, escapedBuffer ? escapedBuffer : "(couldn't escape bytes)", Unicode_EncodingEnumToName(encoding)); free(escapedBuffer); PANIC(); } return result; } /* *----------------------------------------------------------------------------- * * Unicode_CanGetBytesWithEncoding -- * * Tests if the given Unicode string can be converted * losslessly to the specified encoding. * * Results: * TRUE if the string can be converted, FALSE if it cannot. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool Unicode_CanGetBytesWithEncoding(ConstUnicode ustr, // IN: StringEncoding encoding) // IN: { void *tmp; if (ustr == NULL) { return TRUE; } tmp = UnicodeGetAllocBytesInternal(ustr, encoding, -1, NULL); if (tmp == NULL) { return FALSE; } free(tmp); return TRUE; } open-vm-tools-9.4.0-1280544/lib/unicode/unicodeSimpleCaseFolding.c0000644765153500003110000010337712220061556022711 0ustar dtormts/* ********************************************************** * Copyright 2007 VMware, Inc. All rights reserved. * **********************************************************/ /* * unicodeSimpleCaseFolding.c -- * * Simple case folding tables generated from Unicode 5.0.0's * CaseFolding-5.0.0.txt data file. Data file obtained from: * * http://unicode.org/Public/UNIDATA/CaseFolding.txt * * Table generated using extract_fold.c from * bora/vmcore/frobos/clib/fd32/unicode/extract_fold.c. * * Copyright of CaseFolding.txt: * * Copyright (C) 1991-2007 Unicode, Inc. All rights * reserved. Distributed under the Terms of Use in * http://www.unicode.org/copyright.html. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of the Unicode data files and any associated * documentation (the "Data Files") or Unicode software and any * associated documentation (the "Software") to deal in the Data * Files or Software without restriction, including without * limitation the rights to use, copy, modify, merge, publish, * distribute, and/or sell copies of the Data Files or Software, * and to permit persons to whom the Data Files or Software are * furnished to do so, provided that (a) the above copyright * notice(s) and this permission notice appear with all copies of * the Data Files or Software, (b) both the above copyright * notice(s) and this permission notice appear in associated * documentation, and (c) there is clear notice in each modified * Data File or in the Software as well as in the documentation * associated with the Data File(s) or Software that the data or * software has been modified. * * THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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 THE DATA FILES OR SOFTWARE. */ #include "vmware.h" #include "unicodeTypes.h" static const utf16_t page_00[256] = { 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x03BC, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00D7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00DF, 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF }; static const utf16_t page_01[256] = { 0x0101, 0x0101, 0x0103, 0x0103, 0x0105, 0x0105, 0x0107, 0x0107, 0x0109, 0x0109, 0x010B, 0x010B, 0x010D, 0x010D, 0x010F, 0x010F, 0x0111, 0x0111, 0x0113, 0x0113, 0x0115, 0x0115, 0x0117, 0x0117, 0x0119, 0x0119, 0x011B, 0x011B, 0x011D, 0x011D, 0x011F, 0x011F, 0x0121, 0x0121, 0x0123, 0x0123, 0x0125, 0x0125, 0x0127, 0x0127, 0x0129, 0x0129, 0x012B, 0x012B, 0x012D, 0x012D, 0x012F, 0x012F, 0x0130, 0x0131, 0x0133, 0x0133, 0x0135, 0x0135, 0x0137, 0x0137, 0x0138, 0x013A, 0x013A, 0x013C, 0x013C, 0x013E, 0x013E, 0x0140, 0x0140, 0x0142, 0x0142, 0x0144, 0x0144, 0x0146, 0x0146, 0x0148, 0x0148, 0x0149, 0x014B, 0x014B, 0x014D, 0x014D, 0x014F, 0x014F, 0x0151, 0x0151, 0x0153, 0x0153, 0x0155, 0x0155, 0x0157, 0x0157, 0x0159, 0x0159, 0x015B, 0x015B, 0x015D, 0x015D, 0x015F, 0x015F, 0x0161, 0x0161, 0x0163, 0x0163, 0x0165, 0x0165, 0x0167, 0x0167, 0x0169, 0x0169, 0x016B, 0x016B, 0x016D, 0x016D, 0x016F, 0x016F, 0x0171, 0x0171, 0x0173, 0x0173, 0x0175, 0x0175, 0x0177, 0x0177, 0x00FF, 0x017A, 0x017A, 0x017C, 0x017C, 0x017E, 0x017E, 0x0073, 0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188, 0x0188, 0x0256, 0x0257, 0x018C, 0x018C, 0x018D, 0x01DD, 0x0259, 0x025B, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268, 0x0199, 0x0199, 0x019A, 0x019B, 0x026F, 0x0272, 0x019E, 0x0275, 0x01A1, 0x01A1, 0x01A3, 0x01A3, 0x01A5, 0x01A5, 0x0280, 0x01A8, 0x01A8, 0x0283, 0x01AA, 0x01AB, 0x01AD, 0x01AD, 0x0288, 0x01B0, 0x01B0, 0x028A, 0x028B, 0x01B4, 0x01B4, 0x01B6, 0x01B6, 0x0292, 0x01B9, 0x01B9, 0x01BA, 0x01BB, 0x01BD, 0x01BD, 0x01BE, 0x01BF, 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C6, 0x01C6, 0x01C6, 0x01C9, 0x01C9, 0x01C9, 0x01CC, 0x01CC, 0x01CC, 0x01CE, 0x01CE, 0x01D0, 0x01D0, 0x01D2, 0x01D2, 0x01D4, 0x01D4, 0x01D6, 0x01D6, 0x01D8, 0x01D8, 0x01DA, 0x01DA, 0x01DC, 0x01DC, 0x01DD, 0x01DF, 0x01DF, 0x01E1, 0x01E1, 0x01E3, 0x01E3, 0x01E5, 0x01E5, 0x01E7, 0x01E7, 0x01E9, 0x01E9, 0x01EB, 0x01EB, 0x01ED, 0x01ED, 0x01EF, 0x01EF, 0x01F0, 0x01F3, 0x01F3, 0x01F3, 0x01F5, 0x01F5, 0x0195, 0x01BF, 0x01F9, 0x01F9, 0x01FB, 0x01FB, 0x01FD, 0x01FD, 0x01FF, 0x01FF }; static const utf16_t page_02[256] = { 0x0201, 0x0201, 0x0203, 0x0203, 0x0205, 0x0205, 0x0207, 0x0207, 0x0209, 0x0209, 0x020B, 0x020B, 0x020D, 0x020D, 0x020F, 0x020F, 0x0211, 0x0211, 0x0213, 0x0213, 0x0215, 0x0215, 0x0217, 0x0217, 0x0219, 0x0219, 0x021B, 0x021B, 0x021D, 0x021D, 0x021F, 0x021F, 0x019E, 0x0221, 0x0223, 0x0223, 0x0225, 0x0225, 0x0227, 0x0227, 0x0229, 0x0229, 0x022B, 0x022B, 0x022D, 0x022D, 0x022F, 0x022F, 0x0231, 0x0231, 0x0233, 0x0233, 0x0234, 0x0235, 0x0236, 0x0237, 0x0238, 0x0239, 0x2C65, 0x023C, 0x023C, 0x019A, 0x2C66, 0x023F, 0x0240, 0x0242, 0x0242, 0x0180, 0x0289, 0x028C, 0x0247, 0x0247, 0x0249, 0x0249, 0x024B, 0x024B, 0x024D, 0x024D, 0x024F, 0x024F, 0x0250, 0x0251, 0x0252, 0x0253, 0x0254, 0x0255, 0x0256, 0x0257, 0x0258, 0x0259, 0x025A, 0x025B, 0x025C, 0x025D, 0x025E, 0x025F, 0x0260, 0x0261, 0x0262, 0x0263, 0x0264, 0x0265, 0x0266, 0x0267, 0x0268, 0x0269, 0x026A, 0x026B, 0x026C, 0x026D, 0x026E, 0x026F, 0x0270, 0x0271, 0x0272, 0x0273, 0x0274, 0x0275, 0x0276, 0x0277, 0x0278, 0x0279, 0x027A, 0x027B, 0x027C, 0x027D, 0x027E, 0x027F, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0286, 0x0287, 0x0288, 0x0289, 0x028A, 0x028B, 0x028C, 0x028D, 0x028E, 0x028F, 0x0290, 0x0291, 0x0292, 0x0293, 0x0294, 0x0295, 0x0296, 0x0297, 0x0298, 0x0299, 0x029A, 0x029B, 0x029C, 0x029D, 0x029E, 0x029F, 0x02A0, 0x02A1, 0x02A2, 0x02A3, 0x02A4, 0x02A5, 0x02A6, 0x02A7, 0x02A8, 0x02A9, 0x02AA, 0x02AB, 0x02AC, 0x02AD, 0x02AE, 0x02AF, 0x02B0, 0x02B1, 0x02B2, 0x02B3, 0x02B4, 0x02B5, 0x02B6, 0x02B7, 0x02B8, 0x02B9, 0x02BA, 0x02BB, 0x02BC, 0x02BD, 0x02BE, 0x02BF, 0x02C0, 0x02C1, 0x02C2, 0x02C3, 0x02C4, 0x02C5, 0x02C6, 0x02C7, 0x02C8, 0x02C9, 0x02CA, 0x02CB, 0x02CC, 0x02CD, 0x02CE, 0x02CF, 0x02D0, 0x02D1, 0x02D2, 0x02D3, 0x02D4, 0x02D5, 0x02D6, 0x02D7, 0x02D8, 0x02D9, 0x02DA, 0x02DB, 0x02DC, 0x02DD, 0x02DE, 0x02DF, 0x02E0, 0x02E1, 0x02E2, 0x02E3, 0x02E4, 0x02E5, 0x02E6, 0x02E7, 0x02E8, 0x02E9, 0x02EA, 0x02EB, 0x02EC, 0x02ED, 0x02EE, 0x02EF, 0x02F0, 0x02F1, 0x02F2, 0x02F3, 0x02F4, 0x02F5, 0x02F6, 0x02F7, 0x02F8, 0x02F9, 0x02FA, 0x02FB, 0x02FC, 0x02FD, 0x02FE, 0x02FF }; static const utf16_t page_03[256] = { 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, 0x0308, 0x0309, 0x030A, 0x030B, 0x030C, 0x030D, 0x030E, 0x030F, 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317, 0x0318, 0x0319, 0x031A, 0x031B, 0x031C, 0x031D, 0x031E, 0x031F, 0x0320, 0x0321, 0x0322, 0x0323, 0x0324, 0x0325, 0x0326, 0x0327, 0x0328, 0x0329, 0x032A, 0x032B, 0x032C, 0x032D, 0x032E, 0x032F, 0x0330, 0x0331, 0x0332, 0x0333, 0x0334, 0x0335, 0x0336, 0x0337, 0x0338, 0x0339, 0x033A, 0x033B, 0x033C, 0x033D, 0x033E, 0x033F, 0x0340, 0x0341, 0x0342, 0x0343, 0x0344, 0x03B9, 0x0346, 0x0347, 0x0348, 0x0349, 0x034A, 0x034B, 0x034C, 0x034D, 0x034E, 0x034F, 0x0350, 0x0351, 0x0352, 0x0353, 0x0354, 0x0355, 0x0356, 0x0357, 0x0358, 0x0359, 0x035A, 0x035B, 0x035C, 0x035D, 0x035E, 0x035F, 0x0360, 0x0361, 0x0362, 0x0363, 0x0364, 0x0365, 0x0366, 0x0367, 0x0368, 0x0369, 0x036A, 0x036B, 0x036C, 0x036D, 0x036E, 0x036F, 0x0370, 0x0371, 0x0372, 0x0373, 0x0374, 0x0375, 0x0376, 0x0377, 0x0378, 0x0379, 0x037A, 0x037B, 0x037C, 0x037D, 0x037E, 0x037F, 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x03AC, 0x0387, 0x03AD, 0x03AE, 0x03AF, 0x038B, 0x03CC, 0x038D, 0x03CD, 0x03CE, 0x0390, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03A2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x03CF, 0x03B2, 0x03B8, 0x03D2, 0x03D3, 0x03D4, 0x03C6, 0x03C0, 0x03D7, 0x03D9, 0x03D9, 0x03DB, 0x03DB, 0x03DD, 0x03DD, 0x03DF, 0x03DF, 0x03E1, 0x03E1, 0x03E3, 0x03E3, 0x03E5, 0x03E5, 0x03E7, 0x03E7, 0x03E9, 0x03E9, 0x03EB, 0x03EB, 0x03ED, 0x03ED, 0x03EF, 0x03EF, 0x03BA, 0x03C1, 0x03F2, 0x03F3, 0x03B8, 0x03B5, 0x03F6, 0x03F8, 0x03F8, 0x03F2, 0x03FB, 0x03FB, 0x03FC, 0x037B, 0x037C, 0x037D }; static const utf16_t page_04[256] = { 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x045D, 0x045E, 0x045F, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x045D, 0x045E, 0x045F, 0x0461, 0x0461, 0x0463, 0x0463, 0x0465, 0x0465, 0x0467, 0x0467, 0x0469, 0x0469, 0x046B, 0x046B, 0x046D, 0x046D, 0x046F, 0x046F, 0x0471, 0x0471, 0x0473, 0x0473, 0x0475, 0x0475, 0x0477, 0x0477, 0x0479, 0x0479, 0x047B, 0x047B, 0x047D, 0x047D, 0x047F, 0x047F, 0x0481, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x048B, 0x048B, 0x048D, 0x048D, 0x048F, 0x048F, 0x0491, 0x0491, 0x0493, 0x0493, 0x0495, 0x0495, 0x0497, 0x0497, 0x0499, 0x0499, 0x049B, 0x049B, 0x049D, 0x049D, 0x049F, 0x049F, 0x04A1, 0x04A1, 0x04A3, 0x04A3, 0x04A5, 0x04A5, 0x04A7, 0x04A7, 0x04A9, 0x04A9, 0x04AB, 0x04AB, 0x04AD, 0x04AD, 0x04AF, 0x04AF, 0x04B1, 0x04B1, 0x04B3, 0x04B3, 0x04B5, 0x04B5, 0x04B7, 0x04B7, 0x04B9, 0x04B9, 0x04BB, 0x04BB, 0x04BD, 0x04BD, 0x04BF, 0x04BF, 0x04CF, 0x04C2, 0x04C2, 0x04C4, 0x04C4, 0x04C6, 0x04C6, 0x04C8, 0x04C8, 0x04CA, 0x04CA, 0x04CC, 0x04CC, 0x04CE, 0x04CE, 0x04CF, 0x04D1, 0x04D1, 0x04D3, 0x04D3, 0x04D5, 0x04D5, 0x04D7, 0x04D7, 0x04D9, 0x04D9, 0x04DB, 0x04DB, 0x04DD, 0x04DD, 0x04DF, 0x04DF, 0x04E1, 0x04E1, 0x04E3, 0x04E3, 0x04E5, 0x04E5, 0x04E7, 0x04E7, 0x04E9, 0x04E9, 0x04EB, 0x04EB, 0x04ED, 0x04ED, 0x04EF, 0x04EF, 0x04F1, 0x04F1, 0x04F3, 0x04F3, 0x04F5, 0x04F5, 0x04F7, 0x04F7, 0x04F9, 0x04F9, 0x04FB, 0x04FB, 0x04FD, 0x04FD, 0x04FF, 0x04FF }; static const utf16_t page_05[256] = { 0x0501, 0x0501, 0x0503, 0x0503, 0x0505, 0x0505, 0x0507, 0x0507, 0x0509, 0x0509, 0x050B, 0x050B, 0x050D, 0x050D, 0x050F, 0x050F, 0x0511, 0x0511, 0x0513, 0x0513, 0x0514, 0x0515, 0x0516, 0x0517, 0x0518, 0x0519, 0x051A, 0x051B, 0x051C, 0x051D, 0x051E, 0x051F, 0x0520, 0x0521, 0x0522, 0x0523, 0x0524, 0x0525, 0x0526, 0x0527, 0x0528, 0x0529, 0x052A, 0x052B, 0x052C, 0x052D, 0x052E, 0x052F, 0x0530, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567, 0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F, 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577, 0x0578, 0x0579, 0x057A, 0x057B, 0x057C, 0x057D, 0x057E, 0x057F, 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0557, 0x0558, 0x0559, 0x055A, 0x055B, 0x055C, 0x055D, 0x055E, 0x055F, 0x0560, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567, 0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F, 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577, 0x0578, 0x0579, 0x057A, 0x057B, 0x057C, 0x057D, 0x057E, 0x057F, 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0587, 0x0588, 0x0589, 0x058A, 0x058B, 0x058C, 0x058D, 0x058E, 0x058F, 0x0590, 0x0591, 0x0592, 0x0593, 0x0594, 0x0595, 0x0596, 0x0597, 0x0598, 0x0599, 0x059A, 0x059B, 0x059C, 0x059D, 0x059E, 0x059F, 0x05A0, 0x05A1, 0x05A2, 0x05A3, 0x05A4, 0x05A5, 0x05A6, 0x05A7, 0x05A8, 0x05A9, 0x05AA, 0x05AB, 0x05AC, 0x05AD, 0x05AE, 0x05AF, 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7, 0x05B8, 0x05B9, 0x05BA, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF, 0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05C4, 0x05C5, 0x05C6, 0x05C7, 0x05C8, 0x05C9, 0x05CA, 0x05CB, 0x05CC, 0x05CD, 0x05CE, 0x05CF, 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x05EB, 0x05EC, 0x05ED, 0x05EE, 0x05EF, 0x05F0, 0x05F1, 0x05F2, 0x05F3, 0x05F4, 0x05F5, 0x05F6, 0x05F7, 0x05F8, 0x05F9, 0x05FA, 0x05FB, 0x05FC, 0x05FD, 0x05FE, 0x05FF }; static const utf16_t page_10[256] = { 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1008, 0x1009, 0x100A, 0x100B, 0x100C, 0x100D, 0x100E, 0x100F, 0x1010, 0x1011, 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017, 0x1018, 0x1019, 0x101A, 0x101B, 0x101C, 0x101D, 0x101E, 0x101F, 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027, 0x1028, 0x1029, 0x102A, 0x102B, 0x102C, 0x102D, 0x102E, 0x102F, 0x1030, 0x1031, 0x1032, 0x1033, 0x1034, 0x1035, 0x1036, 0x1037, 0x1038, 0x1039, 0x103A, 0x103B, 0x103C, 0x103D, 0x103E, 0x103F, 0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047, 0x1048, 0x1049, 0x104A, 0x104B, 0x104C, 0x104D, 0x104E, 0x104F, 0x1050, 0x1051, 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057, 0x1058, 0x1059, 0x105A, 0x105B, 0x105C, 0x105D, 0x105E, 0x105F, 0x1060, 0x1061, 0x1062, 0x1063, 0x1064, 0x1065, 0x1066, 0x1067, 0x1068, 0x1069, 0x106A, 0x106B, 0x106C, 0x106D, 0x106E, 0x106F, 0x1070, 0x1071, 0x1072, 0x1073, 0x1074, 0x1075, 0x1076, 0x1077, 0x1078, 0x1079, 0x107A, 0x107B, 0x107C, 0x107D, 0x107E, 0x107F, 0x1080, 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086, 0x1087, 0x1088, 0x1089, 0x108A, 0x108B, 0x108C, 0x108D, 0x108E, 0x108F, 0x1090, 0x1091, 0x1092, 0x1093, 0x1094, 0x1095, 0x1096, 0x1097, 0x1098, 0x1099, 0x109A, 0x109B, 0x109C, 0x109D, 0x109E, 0x109F, 0x2D00, 0x2D01, 0x2D02, 0x2D03, 0x2D04, 0x2D05, 0x2D06, 0x2D07, 0x2D08, 0x2D09, 0x2D0A, 0x2D0B, 0x2D0C, 0x2D0D, 0x2D0E, 0x2D0F, 0x2D10, 0x2D11, 0x2D12, 0x2D13, 0x2D14, 0x2D15, 0x2D16, 0x2D17, 0x2D18, 0x2D19, 0x2D1A, 0x2D1B, 0x2D1C, 0x2D1D, 0x2D1E, 0x2D1F, 0x2D20, 0x2D21, 0x2D22, 0x2D23, 0x2D24, 0x2D25, 0x10C6, 0x10C7, 0x10C8, 0x10C9, 0x10CA, 0x10CB, 0x10CC, 0x10CD, 0x10CE, 0x10CF, 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10D7, 0x10D8, 0x10D9, 0x10DA, 0x10DB, 0x10DC, 0x10DD, 0x10DE, 0x10DF, 0x10E0, 0x10E1, 0x10E2, 0x10E3, 0x10E4, 0x10E5, 0x10E6, 0x10E7, 0x10E8, 0x10E9, 0x10EA, 0x10EB, 0x10EC, 0x10ED, 0x10EE, 0x10EF, 0x10F0, 0x10F1, 0x10F2, 0x10F3, 0x10F4, 0x10F5, 0x10F6, 0x10F7, 0x10F8, 0x10F9, 0x10FA, 0x10FB, 0x10FC, 0x10FD, 0x10FE, 0x10FF }; static const utf16_t page_1E[256] = { 0x1E01, 0x1E01, 0x1E03, 0x1E03, 0x1E05, 0x1E05, 0x1E07, 0x1E07, 0x1E09, 0x1E09, 0x1E0B, 0x1E0B, 0x1E0D, 0x1E0D, 0x1E0F, 0x1E0F, 0x1E11, 0x1E11, 0x1E13, 0x1E13, 0x1E15, 0x1E15, 0x1E17, 0x1E17, 0x1E19, 0x1E19, 0x1E1B, 0x1E1B, 0x1E1D, 0x1E1D, 0x1E1F, 0x1E1F, 0x1E21, 0x1E21, 0x1E23, 0x1E23, 0x1E25, 0x1E25, 0x1E27, 0x1E27, 0x1E29, 0x1E29, 0x1E2B, 0x1E2B, 0x1E2D, 0x1E2D, 0x1E2F, 0x1E2F, 0x1E31, 0x1E31, 0x1E33, 0x1E33, 0x1E35, 0x1E35, 0x1E37, 0x1E37, 0x1E39, 0x1E39, 0x1E3B, 0x1E3B, 0x1E3D, 0x1E3D, 0x1E3F, 0x1E3F, 0x1E41, 0x1E41, 0x1E43, 0x1E43, 0x1E45, 0x1E45, 0x1E47, 0x1E47, 0x1E49, 0x1E49, 0x1E4B, 0x1E4B, 0x1E4D, 0x1E4D, 0x1E4F, 0x1E4F, 0x1E51, 0x1E51, 0x1E53, 0x1E53, 0x1E55, 0x1E55, 0x1E57, 0x1E57, 0x1E59, 0x1E59, 0x1E5B, 0x1E5B, 0x1E5D, 0x1E5D, 0x1E5F, 0x1E5F, 0x1E61, 0x1E61, 0x1E63, 0x1E63, 0x1E65, 0x1E65, 0x1E67, 0x1E67, 0x1E69, 0x1E69, 0x1E6B, 0x1E6B, 0x1E6D, 0x1E6D, 0x1E6F, 0x1E6F, 0x1E71, 0x1E71, 0x1E73, 0x1E73, 0x1E75, 0x1E75, 0x1E77, 0x1E77, 0x1E79, 0x1E79, 0x1E7B, 0x1E7B, 0x1E7D, 0x1E7D, 0x1E7F, 0x1E7F, 0x1E81, 0x1E81, 0x1E83, 0x1E83, 0x1E85, 0x1E85, 0x1E87, 0x1E87, 0x1E89, 0x1E89, 0x1E8B, 0x1E8B, 0x1E8D, 0x1E8D, 0x1E8F, 0x1E8F, 0x1E91, 0x1E91, 0x1E93, 0x1E93, 0x1E95, 0x1E95, 0x1E96, 0x1E97, 0x1E98, 0x1E99, 0x1E9A, 0x1E61, 0x1E9C, 0x1E9D, 0x1E9E, 0x1E9F, 0x1EA1, 0x1EA1, 0x1EA3, 0x1EA3, 0x1EA5, 0x1EA5, 0x1EA7, 0x1EA7, 0x1EA9, 0x1EA9, 0x1EAB, 0x1EAB, 0x1EAD, 0x1EAD, 0x1EAF, 0x1EAF, 0x1EB1, 0x1EB1, 0x1EB3, 0x1EB3, 0x1EB5, 0x1EB5, 0x1EB7, 0x1EB7, 0x1EB9, 0x1EB9, 0x1EBB, 0x1EBB, 0x1EBD, 0x1EBD, 0x1EBF, 0x1EBF, 0x1EC1, 0x1EC1, 0x1EC3, 0x1EC3, 0x1EC5, 0x1EC5, 0x1EC7, 0x1EC7, 0x1EC9, 0x1EC9, 0x1ECB, 0x1ECB, 0x1ECD, 0x1ECD, 0x1ECF, 0x1ECF, 0x1ED1, 0x1ED1, 0x1ED3, 0x1ED3, 0x1ED5, 0x1ED5, 0x1ED7, 0x1ED7, 0x1ED9, 0x1ED9, 0x1EDB, 0x1EDB, 0x1EDD, 0x1EDD, 0x1EDF, 0x1EDF, 0x1EE1, 0x1EE1, 0x1EE3, 0x1EE3, 0x1EE5, 0x1EE5, 0x1EE7, 0x1EE7, 0x1EE9, 0x1EE9, 0x1EEB, 0x1EEB, 0x1EED, 0x1EED, 0x1EEF, 0x1EEF, 0x1EF1, 0x1EF1, 0x1EF3, 0x1EF3, 0x1EF5, 0x1EF5, 0x1EF7, 0x1EF7, 0x1EF9, 0x1EF9, 0x1EFA, 0x1EFB, 0x1EFC, 0x1EFD, 0x1EFE, 0x1EFF }; static const utf16_t page_1F[256] = { 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07, 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07, 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x1F16, 0x1F17, 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x1F1E, 0x1F1F, 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27, 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27, 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37, 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37, 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x1F46, 0x1F47, 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x1F4E, 0x1F4F, 0x1F50, 0x1F51, 0x1F52, 0x1F53, 0x1F54, 0x1F55, 0x1F56, 0x1F57, 0x1F58, 0x1F51, 0x1F5A, 0x1F53, 0x1F5C, 0x1F55, 0x1F5E, 0x1F57, 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67, 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67, 0x1F70, 0x1F71, 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1F76, 0x1F77, 0x1F78, 0x1F79, 0x1F7A, 0x1F7B, 0x1F7C, 0x1F7D, 0x1F7E, 0x1F7F, 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87, 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87, 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97, 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97, 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7, 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7, 0x1FB0, 0x1FB1, 0x1FB2, 0x1FB3, 0x1FB4, 0x1FB5, 0x1FB6, 0x1FB7, 0x1FB0, 0x1FB1, 0x1F70, 0x1F71, 0x1FB3, 0x1FBD, 0x03B9, 0x1FBF, 0x1FC0, 0x1FC1, 0x1FC2, 0x1FC3, 0x1FC4, 0x1FC5, 0x1FC6, 0x1FC7, 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1FC3, 0x1FCD, 0x1FCE, 0x1FCF, 0x1FD0, 0x1FD1, 0x1FD2, 0x1FD3, 0x1FD4, 0x1FD5, 0x1FD6, 0x1FD7, 0x1FD0, 0x1FD1, 0x1F76, 0x1F77, 0x1FDC, 0x1FDD, 0x1FDE, 0x1FDF, 0x1FE0, 0x1FE1, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FE5, 0x1FE6, 0x1FE7, 0x1FE0, 0x1FE1, 0x1F7A, 0x1F7B, 0x1FE5, 0x1FED, 0x1FEE, 0x1FEF, 0x1FF0, 0x1FF1, 0x1FF2, 0x1FF3, 0x1FF4, 0x1FF5, 0x1FF6, 0x1FF7, 0x1F78, 0x1F79, 0x1F7C, 0x1F7D, 0x1FF3, 0x1FFD, 0x1FFE, 0x1FFF }; static const utf16_t page_21[256] = { 0x2100, 0x2101, 0x2102, 0x2103, 0x2104, 0x2105, 0x2106, 0x2107, 0x2108, 0x2109, 0x210A, 0x210B, 0x210C, 0x210D, 0x210E, 0x210F, 0x2110, 0x2111, 0x2112, 0x2113, 0x2114, 0x2115, 0x2116, 0x2117, 0x2118, 0x2119, 0x211A, 0x211B, 0x211C, 0x211D, 0x211E, 0x211F, 0x2120, 0x2121, 0x2122, 0x2123, 0x2124, 0x2125, 0x03C9, 0x2127, 0x2128, 0x2129, 0x006B, 0x00E5, 0x212C, 0x212D, 0x212E, 0x212F, 0x2130, 0x2131, 0x214E, 0x2133, 0x2134, 0x2135, 0x2136, 0x2137, 0x2138, 0x2139, 0x213A, 0x213B, 0x213C, 0x213D, 0x213E, 0x213F, 0x2140, 0x2141, 0x2142, 0x2143, 0x2144, 0x2145, 0x2146, 0x2147, 0x2148, 0x2149, 0x214A, 0x214B, 0x214C, 0x214D, 0x214E, 0x214F, 0x2150, 0x2151, 0x2152, 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215A, 0x215B, 0x215C, 0x215D, 0x215E, 0x215F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0x2180, 0x2181, 0x2182, 0x2184, 0x2184, 0x2185, 0x2186, 0x2187, 0x2188, 0x2189, 0x218A, 0x218B, 0x218C, 0x218D, 0x218E, 0x218F, 0x2190, 0x2191, 0x2192, 0x2193, 0x2194, 0x2195, 0x2196, 0x2197, 0x2198, 0x2199, 0x219A, 0x219B, 0x219C, 0x219D, 0x219E, 0x219F, 0x21A0, 0x21A1, 0x21A2, 0x21A3, 0x21A4, 0x21A5, 0x21A6, 0x21A7, 0x21A8, 0x21A9, 0x21AA, 0x21AB, 0x21AC, 0x21AD, 0x21AE, 0x21AF, 0x21B0, 0x21B1, 0x21B2, 0x21B3, 0x21B4, 0x21B5, 0x21B6, 0x21B7, 0x21B8, 0x21B9, 0x21BA, 0x21BB, 0x21BC, 0x21BD, 0x21BE, 0x21BF, 0x21C0, 0x21C1, 0x21C2, 0x21C3, 0x21C4, 0x21C5, 0x21C6, 0x21C7, 0x21C8, 0x21C9, 0x21CA, 0x21CB, 0x21CC, 0x21CD, 0x21CE, 0x21CF, 0x21D0, 0x21D1, 0x21D2, 0x21D3, 0x21D4, 0x21D5, 0x21D6, 0x21D7, 0x21D8, 0x21D9, 0x21DA, 0x21DB, 0x21DC, 0x21DD, 0x21DE, 0x21DF, 0x21E0, 0x21E1, 0x21E2, 0x21E3, 0x21E4, 0x21E5, 0x21E6, 0x21E7, 0x21E8, 0x21E9, 0x21EA, 0x21EB, 0x21EC, 0x21ED, 0x21EE, 0x21EF, 0x21F0, 0x21F1, 0x21F2, 0x21F3, 0x21F4, 0x21F5, 0x21F6, 0x21F7, 0x21F8, 0x21F9, 0x21FA, 0x21FB, 0x21FC, 0x21FD, 0x21FE, 0x21FF }; static const utf16_t page_24[256] = { 0x2400, 0x2401, 0x2402, 0x2403, 0x2404, 0x2405, 0x2406, 0x2407, 0x2408, 0x2409, 0x240A, 0x240B, 0x240C, 0x240D, 0x240E, 0x240F, 0x2410, 0x2411, 0x2412, 0x2413, 0x2414, 0x2415, 0x2416, 0x2417, 0x2418, 0x2419, 0x241A, 0x241B, 0x241C, 0x241D, 0x241E, 0x241F, 0x2420, 0x2421, 0x2422, 0x2423, 0x2424, 0x2425, 0x2426, 0x2427, 0x2428, 0x2429, 0x242A, 0x242B, 0x242C, 0x242D, 0x242E, 0x242F, 0x2430, 0x2431, 0x2432, 0x2433, 0x2434, 0x2435, 0x2436, 0x2437, 0x2438, 0x2439, 0x243A, 0x243B, 0x243C, 0x243D, 0x243E, 0x243F, 0x2440, 0x2441, 0x2442, 0x2443, 0x2444, 0x2445, 0x2446, 0x2447, 0x2448, 0x2449, 0x244A, 0x244B, 0x244C, 0x244D, 0x244E, 0x244F, 0x2450, 0x2451, 0x2452, 0x2453, 0x2454, 0x2455, 0x2456, 0x2457, 0x2458, 0x2459, 0x245A, 0x245B, 0x245C, 0x245D, 0x245E, 0x245F, 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, 0x246A, 0x246B, 0x246C, 0x246D, 0x246E, 0x246F, 0x2470, 0x2471, 0x2472, 0x2473, 0x2474, 0x2475, 0x2476, 0x2477, 0x2478, 0x2479, 0x247A, 0x247B, 0x247C, 0x247D, 0x247E, 0x247F, 0x2480, 0x2481, 0x2482, 0x2483, 0x2484, 0x2485, 0x2486, 0x2487, 0x2488, 0x2489, 0x248A, 0x248B, 0x248C, 0x248D, 0x248E, 0x248F, 0x2490, 0x2491, 0x2492, 0x2493, 0x2494, 0x2495, 0x2496, 0x2497, 0x2498, 0x2499, 0x249A, 0x249B, 0x249C, 0x249D, 0x249E, 0x249F, 0x24A0, 0x24A1, 0x24A2, 0x24A3, 0x24A4, 0x24A5, 0x24A6, 0x24A7, 0x24A8, 0x24A9, 0x24AA, 0x24AB, 0x24AC, 0x24AD, 0x24AE, 0x24AF, 0x24B0, 0x24B1, 0x24B2, 0x24B3, 0x24B4, 0x24B5, 0x24D0, 0x24D1, 0x24D2, 0x24D3, 0x24D4, 0x24D5, 0x24D6, 0x24D7, 0x24D8, 0x24D9, 0x24DA, 0x24DB, 0x24DC, 0x24DD, 0x24DE, 0x24DF, 0x24E0, 0x24E1, 0x24E2, 0x24E3, 0x24E4, 0x24E5, 0x24E6, 0x24E7, 0x24E8, 0x24E9, 0x24D0, 0x24D1, 0x24D2, 0x24D3, 0x24D4, 0x24D5, 0x24D6, 0x24D7, 0x24D8, 0x24D9, 0x24DA, 0x24DB, 0x24DC, 0x24DD, 0x24DE, 0x24DF, 0x24E0, 0x24E1, 0x24E2, 0x24E3, 0x24E4, 0x24E5, 0x24E6, 0x24E7, 0x24E8, 0x24E9, 0x24EA, 0x24EB, 0x24EC, 0x24ED, 0x24EE, 0x24EF, 0x24F0, 0x24F1, 0x24F2, 0x24F3, 0x24F4, 0x24F5, 0x24F6, 0x24F7, 0x24F8, 0x24F9, 0x24FA, 0x24FB, 0x24FC, 0x24FD, 0x24FE, 0x24FF }; static const utf16_t page_2C[256] = { 0x2C30, 0x2C31, 0x2C32, 0x2C33, 0x2C34, 0x2C35, 0x2C36, 0x2C37, 0x2C38, 0x2C39, 0x2C3A, 0x2C3B, 0x2C3C, 0x2C3D, 0x2C3E, 0x2C3F, 0x2C40, 0x2C41, 0x2C42, 0x2C43, 0x2C44, 0x2C45, 0x2C46, 0x2C47, 0x2C48, 0x2C49, 0x2C4A, 0x2C4B, 0x2C4C, 0x2C4D, 0x2C4E, 0x2C4F, 0x2C50, 0x2C51, 0x2C52, 0x2C53, 0x2C54, 0x2C55, 0x2C56, 0x2C57, 0x2C58, 0x2C59, 0x2C5A, 0x2C5B, 0x2C5C, 0x2C5D, 0x2C5E, 0x2C2F, 0x2C30, 0x2C31, 0x2C32, 0x2C33, 0x2C34, 0x2C35, 0x2C36, 0x2C37, 0x2C38, 0x2C39, 0x2C3A, 0x2C3B, 0x2C3C, 0x2C3D, 0x2C3E, 0x2C3F, 0x2C40, 0x2C41, 0x2C42, 0x2C43, 0x2C44, 0x2C45, 0x2C46, 0x2C47, 0x2C48, 0x2C49, 0x2C4A, 0x2C4B, 0x2C4C, 0x2C4D, 0x2C4E, 0x2C4F, 0x2C50, 0x2C51, 0x2C52, 0x2C53, 0x2C54, 0x2C55, 0x2C56, 0x2C57, 0x2C58, 0x2C59, 0x2C5A, 0x2C5B, 0x2C5C, 0x2C5D, 0x2C5E, 0x2C5F, 0x2C61, 0x2C61, 0x026B, 0x1D7D, 0x027D, 0x2C65, 0x2C66, 0x2C68, 0x2C68, 0x2C6A, 0x2C6A, 0x2C6C, 0x2C6C, 0x2C6D, 0x2C6E, 0x2C6F, 0x2C70, 0x2C71, 0x2C72, 0x2C73, 0x2C74, 0x2C76, 0x2C76, 0x2C77, 0x2C78, 0x2C79, 0x2C7A, 0x2C7B, 0x2C7C, 0x2C7D, 0x2C7E, 0x2C7F, 0x2C81, 0x2C81, 0x2C83, 0x2C83, 0x2C85, 0x2C85, 0x2C87, 0x2C87, 0x2C89, 0x2C89, 0x2C8B, 0x2C8B, 0x2C8D, 0x2C8D, 0x2C8F, 0x2C8F, 0x2C91, 0x2C91, 0x2C93, 0x2C93, 0x2C95, 0x2C95, 0x2C97, 0x2C97, 0x2C99, 0x2C99, 0x2C9B, 0x2C9B, 0x2C9D, 0x2C9D, 0x2C9F, 0x2C9F, 0x2CA1, 0x2CA1, 0x2CA3, 0x2CA3, 0x2CA5, 0x2CA5, 0x2CA7, 0x2CA7, 0x2CA9, 0x2CA9, 0x2CAB, 0x2CAB, 0x2CAD, 0x2CAD, 0x2CAF, 0x2CAF, 0x2CB1, 0x2CB1, 0x2CB3, 0x2CB3, 0x2CB5, 0x2CB5, 0x2CB7, 0x2CB7, 0x2CB9, 0x2CB9, 0x2CBB, 0x2CBB, 0x2CBD, 0x2CBD, 0x2CBF, 0x2CBF, 0x2CC1, 0x2CC1, 0x2CC3, 0x2CC3, 0x2CC5, 0x2CC5, 0x2CC7, 0x2CC7, 0x2CC9, 0x2CC9, 0x2CCB, 0x2CCB, 0x2CCD, 0x2CCD, 0x2CCF, 0x2CCF, 0x2CD1, 0x2CD1, 0x2CD3, 0x2CD3, 0x2CD5, 0x2CD5, 0x2CD7, 0x2CD7, 0x2CD9, 0x2CD9, 0x2CDB, 0x2CDB, 0x2CDD, 0x2CDD, 0x2CDF, 0x2CDF, 0x2CE1, 0x2CE1, 0x2CE3, 0x2CE3, 0x2CE4, 0x2CE5, 0x2CE6, 0x2CE7, 0x2CE8, 0x2CE9, 0x2CEA, 0x2CEB, 0x2CEC, 0x2CED, 0x2CEE, 0x2CEF, 0x2CF0, 0x2CF1, 0x2CF2, 0x2CF3, 0x2CF4, 0x2CF5, 0x2CF6, 0x2CF7, 0x2CF8, 0x2CF9, 0x2CFA, 0x2CFB, 0x2CFC, 0x2CFD, 0x2CFE, 0x2CFF }; static const utf16_t page_FF[256] = { 0xFF00, 0xFF01, 0xFF02, 0xFF03, 0xFF04, 0xFF05, 0xFF06, 0xFF07, 0xFF08, 0xFF09, 0xFF0A, 0xFF0B, 0xFF0C, 0xFF0D, 0xFF0E, 0xFF0F, 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17, 0xFF18, 0xFF19, 0xFF1A, 0xFF1B, 0xFF1C, 0xFF1D, 0xFF1E, 0xFF1F, 0xFF20, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0xFF3B, 0xFF3C, 0xFF3D, 0xFF3E, 0xFF3F, 0xFF40, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0xFF5B, 0xFF5C, 0xFF5D, 0xFF5E, 0xFF5F, 0xFF60, 0xFF61, 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67, 0xFF68, 0xFF69, 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, 0xFF6E, 0xFF6F, 0xFF70, 0xFF71, 0xFF72, 0xFF73, 0xFF74, 0xFF75, 0xFF76, 0xFF77, 0xFF78, 0xFF79, 0xFF7A, 0xFF7B, 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F, 0xFF80, 0xFF81, 0xFF82, 0xFF83, 0xFF84, 0xFF85, 0xFF86, 0xFF87, 0xFF88, 0xFF89, 0xFF8A, 0xFF8B, 0xFF8C, 0xFF8D, 0xFF8E, 0xFF8F, 0xFF90, 0xFF91, 0xFF92, 0xFF93, 0xFF94, 0xFF95, 0xFF96, 0xFF97, 0xFF98, 0xFF99, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D, 0xFF9E, 0xFF9F, 0xFFA0, 0xFFA1, 0xFFA2, 0xFFA3, 0xFFA4, 0xFFA5, 0xFFA6, 0xFFA7, 0xFFA8, 0xFFA9, 0xFFAA, 0xFFAB, 0xFFAC, 0xFFAD, 0xFFAE, 0xFFAF, 0xFFB0, 0xFFB1, 0xFFB2, 0xFFB3, 0xFFB4, 0xFFB5, 0xFFB6, 0xFFB7, 0xFFB8, 0xFFB9, 0xFFBA, 0xFFBB, 0xFFBC, 0xFFBD, 0xFFBE, 0xFFBF, 0xFFC0, 0xFFC1, 0xFFC2, 0xFFC3, 0xFFC4, 0xFFC5, 0xFFC6, 0xFFC7, 0xFFC8, 0xFFC9, 0xFFCA, 0xFFCB, 0xFFCC, 0xFFCD, 0xFFCE, 0xFFCF, 0xFFD0, 0xFFD1, 0xFFD2, 0xFFD3, 0xFFD4, 0xFFD5, 0xFFD6, 0xFFD7, 0xFFD8, 0xFFD9, 0xFFDA, 0xFFDB, 0xFFDC, 0xFFDD, 0xFFDE, 0xFFDF, 0xFFE0, 0xFFE1, 0xFFE2, 0xFFE3, 0xFFE4, 0xFFE5, 0xFFE6, 0xFFE7, 0xFFE8, 0xFFE9, 0xFFEA, 0xFFEB, 0xFFEC, 0xFFED, 0xFFEE, 0xFFEF, 0xFFF0, 0xFFF1, 0xFFF2, 0xFFF3, 0xFFF4, 0xFFF5, 0xFFF6, 0xFFF7, 0xFFF8, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFE, 0xFFFF }; static const utf16_t *pages[256] = { page_00, page_01, page_02, page_03, page_04, page_05, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, page_10, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, page_1E, page_1F, NULL, page_21, NULL, NULL, page_24, NULL, NULL, NULL, NULL, NULL, NULL, NULL, page_2C, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, page_FF }; /* *----------------------------------------------------------------------------- * * UnicodeSimpleCaseFold -- * * Performs simple Unicode case folding on the input UTF-16 code * unit for case-insensitive, locale-agnostic matching of strings. * * Case folding means the code unit is upper-cased, then lower-cased. * * "Simple" means: * * 1) Only code points between U+0000 and U+FFFF are handled. * (Case-sensitive Deseret characters between U+10400 and * U+10427 are not handled.) * * 2) Code units that would normally grow in length when folded * (German sharp S U+00DF: 'straBe' -> 'STRASSE' -> 'strasse') * are ignored. * * Case folding does not handle normalization, so decomposed * (A followed by ACCENT ACUTE) characters do not match precomposed * (A WITH ACCENT ACCUTE) character. * * Results: * The case-folded code unit. * * Side effects: * None * *----------------------------------------------------------------------------- */ utf16_t UnicodeSimpleCaseFold(utf16_t codeUnit) // IN { const utf16_t *page = pages[codeUnit >> 8]; if (!page) { return codeUnit; } return page[codeUnit & 0xFF]; } open-vm-tools-9.4.0-1280544/lib/unicode/Makefile.in0000644765153500003110000004610212220061623017676 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @HAVE_ICU_TRUE@am__append_1 = unicodeICU.c subdir = lib/unicode DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libUnicode_la_LIBADD = am__libUnicode_la_SOURCES_DIST = unicodeCommon.c unicodeSimpleBase.c \ unicodeSimpleCaseFolding.c unicodeSimpleTypes.c \ unicodeSimpleOperations.c unicodeSimpleTransforms.c \ unicodeStatic.c unicodeICU.c @HAVE_ICU_TRUE@am__objects_1 = unicodeICU.lo am_libUnicode_la_OBJECTS = unicodeCommon.lo unicodeSimpleBase.lo \ unicodeSimpleCaseFolding.lo unicodeSimpleTypes.lo \ unicodeSimpleOperations.lo unicodeSimpleTransforms.lo \ unicodeStatic.lo $(am__objects_1) libUnicode_la_OBJECTS = $(am_libUnicode_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libUnicode_la_SOURCES) DIST_SOURCES = $(am__libUnicode_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libUnicode.la libUnicode_la_SOURCES = unicodeCommon.c unicodeSimpleBase.c \ unicodeSimpleCaseFolding.c unicodeSimpleTypes.c \ unicodeSimpleOperations.c unicodeSimpleTransforms.c \ unicodeStatic.c $(am__append_1) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/unicode/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/unicode/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libUnicode.la: $(libUnicode_la_OBJECTS) $(libUnicode_la_DEPENDENCIES) $(EXTRA_libUnicode_la_DEPENDENCIES) $(LINK) $(libUnicode_la_OBJECTS) $(libUnicode_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unicodeCommon.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unicodeICU.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unicodeSimpleBase.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unicodeSimpleCaseFolding.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unicodeSimpleOperations.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unicodeSimpleTransforms.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unicodeSimpleTypes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unicodeStatic.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/unicode/unicodeSimpleTransforms.c0000644765153500003110000004330312220061556022661 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * unicodeSimpleTransforms.c -- * * Simple UTF-8 implementation of unicodeTransforms.h interface. */ #include "vmware.h" #include "unicodeBase.h" #include "unicodeInt.h" #include "unicodeTransforms.h" static INLINE Bool UnicodeSimpleIsWhiteSpace(utf16_t codeUnit); /* * Tables generated from bora/lib/unicode/makeWhitespacePages.c, * running against ICU 3.8 (which implements Unicode 5.0.0). * * The table wspg_XY denotes the whitespace characters in the Unicode * range U+XY00 to U+XYFF (where XY is the hexadecimal upper byte of * the 16-bit Unicode code point value). */ static const Bool wspg_00[256] = { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* * TODO: U+00A0 (no-break space) is not treated as whitespace by * ICU's UnicodeString::trim(). Do we want to do the same? */ TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, }; static const Bool wspg_16[256] = { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, }; static const Bool wspg_18[256] = { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, }; static const Bool wspg_20[256] = { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, }; static const Bool wspg_30[256] = { TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, }; static const Bool *whitespacePages[256] = { wspg_00, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, wspg_16, NULL, wspg_18, NULL, NULL, NULL, NULL, NULL, NULL, NULL, wspg_20, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, wspg_30, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; typedef enum { UNICODE_TRIMLEFT = 0x1, UNICODE_TRIMRIGHT = 0x2, UNICODE_TRIMBOTH = (UNICODE_TRIMLEFT | UNICODE_TRIMRIGHT), } UnicodeTrimSide; /* *----------------------------------------------------------------------------- * * UnicodeSimpleIsWhiteSpace -- * * Checks if the UTF-16 code unit represents white space. * * Results: * TRUE if the code unit represents white space, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE Bool UnicodeSimpleIsWhiteSpace(utf16_t codeUnit) // IN { const Bool *page = whitespacePages[codeUnit >> 8]; if (!page) { return FALSE; } return page[codeUnit & 0xFF]; } /* *----------------------------------------------------------------------------- * * Unicode_FoldCase -- * * Creates a Unicode string with standardized case by performing * simple case folding (upper-case, then lower-case) on the * input string. * * Results: * The allocated Unicode string. Caller must free with Unicode_Free(). * * Side effects: * None * *----------------------------------------------------------------------------- */ Unicode Unicode_FoldCase(ConstUnicode str) // IN { Unicode folded; utf16_t *utf16; utf16_t *utf16Current; ASSERT(str); utf16 = Unicode_GetAllocBytes(str, STRING_ENCODING_UTF16); utf16Current = utf16; while (*utf16Current) { *utf16Current = UnicodeSimpleCaseFold(*utf16Current); utf16Current++; } folded = Unicode_AllocWithUTF16(utf16); free(utf16); return folded; } /* *----------------------------------------------------------------------------- * * UnicodeTrimInternal -- * * Creates a Unicode string by trimming whitespace from the beginning * and/or end of the input string, depending on the input parameter "side". * * Results: * The allocated Unicode string. Caller must free with Unicode_Free(). * * Side effects: * None * *----------------------------------------------------------------------------- */ static Unicode UnicodeTrimInternal(ConstUnicode str, // IN UnicodeTrimSide side) // IN { Unicode trimmed; utf16_t *utf16; utf16_t *utf16Start; utf16_t *utf16End; ASSERT(str); utf16 = Unicode_GetAllocBytes(str, STRING_ENCODING_UTF16); utf16Start = utf16; utf16End = utf16 + Unicode_UTF16Strlen(utf16); if (side & UNICODE_TRIMLEFT) { while (utf16Start != utf16End && UnicodeSimpleIsWhiteSpace(*utf16Start)) { utf16Start++; } } if (side & UNICODE_TRIMRIGHT) { while (utf16End != utf16Start && UnicodeSimpleIsWhiteSpace(*(utf16End - 1))) { utf16End--; } } *utf16End = 0; trimmed = Unicode_AllocWithUTF16(utf16Start); free(utf16); return trimmed; } /* *----------------------------------------------------------------------------- * * Unicode_Trim -- * * Creates a Unicode string by trimming whitespace from the beginning * and end of the input string. * * Results: * The allocated Unicode string. Caller must free with Unicode_Free(). * * Side effects: * None * *----------------------------------------------------------------------------- */ Unicode Unicode_Trim(ConstUnicode str) // IN { return UnicodeTrimInternal(str, UNICODE_TRIMBOTH); } /* *----------------------------------------------------------------------------- * * Unicode_TrimLeft -- * * Creates a Unicode string by trimming whitespace from the beginning of the * input string. * * Results: * The allocated Unicode string. Caller must free with Unicode_Free(). * * Side effects: * None * *----------------------------------------------------------------------------- */ Unicode Unicode_TrimLeft(ConstUnicode str) // IN { return UnicodeTrimInternal(str, UNICODE_TRIMLEFT); } /* *----------------------------------------------------------------------------- * * Unicode_TrimRight -- * * Creates a Unicode string by trimming whitespace from the end of the * input string. * * Results: * The allocated Unicode string. Caller must free with Unicode_Free(). * * Side effects: * None * *----------------------------------------------------------------------------- */ Unicode Unicode_TrimRight(ConstUnicode str) // IN { return UnicodeTrimInternal(str, UNICODE_TRIMRIGHT); } open-vm-tools-9.4.0-1280544/lib/rpcVmx/0000755765153500003110000000000012220061623015457 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/rpcVmx/rpcvmx.c0000644765153500003110000001615612220061556017160 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #include #include #include #include #include "guest_msg_def.h" #include "message.h" #include "rpcout.h" #include "rpcvmx.h" #include "str.h" typedef struct { char logBuf[RPCVMX_MAX_LOG_LEN + sizeof "log"]; unsigned int logOffset; } RpcVMXState; static RpcVMXState RpcVMX = { "log ", sizeof "log" }; /* *---------------------------------------------------------------------------- * * RpcVMX_LogSetPrefix * * Allows callers to set a prefix to prepend to the log output. If the * prefix overflows the (static) prefix space available, it is rejected * and the prefix is reset to nothing. Each call to VMXLog_SetPrefix * replaces the previously set prefix. * * Results: * TRUE if the prefix was accepted, FALSE otherwise. * * Side effects: * All subsequent calls to RpcVMX_Log() will have the prefix string * prepended. * *---------------------------------------------------------------------------- */ void RpcVMX_LogSetPrefix(const char *prefix) { size_t prefixLen = strlen(prefix); if (prefixLen + sizeof "log" >= sizeof RpcVMX.logBuf - 1) { /* * Somebody passed a huge prefix. Don't do that! */ RpcVMX.logOffset = sizeof "log"; return; } Str_Strcpy(RpcVMX.logBuf + sizeof "log", prefix, sizeof RpcVMX.logBuf - sizeof "log"); RpcVMX.logOffset = (unsigned int)(sizeof "log" + prefixLen); } /* *---------------------------------------------------------------------------- * * RpcVMX_LogGetPrefix -- * * Returns a read-only pointer to the currently set prefix string. The * client should make a copy if it wants to e.g. save the previous * prefix and then restore it. * * Results: * Current prefix string, empty string if no prefix is set. * * Side effects: * None. * *---------------------------------------------------------------------------- */ const char * RpcVMX_LogGetPrefix(const char *prefix) { RpcVMX.logBuf[RpcVMX.logOffset] = '\0'; return RpcVMX.logBuf + sizeof "log"; } /* *---------------------------------------------------------------------------- * * RpcVMX_Log -- * * Passes through to RpcVMX_LogV but takes arguments inline. * * Results: * None. * * Side effects: * See RpcVMX_LogV. * *---------------------------------------------------------------------------- */ void RpcVMX_Log(const char *fmt, ...) { va_list args; va_start(args, fmt); RpcVMX_LogV(fmt, args); va_end(args); } /* *---------------------------------------------------------------------------- * * RpcVMX_LogV -- * * Construct an output string using the provided format string and * argument list, then send it to the VMX using the RPCI "log" command. * * Results: * None. * * Side effects: * Lots of silly memory allocation. * *---------------------------------------------------------------------------- */ void RpcVMX_LogV(const char *fmt, va_list args) { int payloadLen; payloadLen = Str_Vsnprintf(RpcVMX.logBuf + RpcVMX.logOffset, sizeof RpcVMX.logBuf - RpcVMX.logOffset, fmt, args); if (payloadLen < 1) { /* * Overflow. We need more space in the buffer. Just set the length to * the buffer size and send the (truncated) log message. */ payloadLen = sizeof RpcVMX.logBuf - RpcVMX.logOffset; } RpcOut_SendOneRaw(RpcVMX.logBuf, RpcVMX.logOffset + payloadLen, NULL, NULL); } /* *---------------------------------------------------------------------------- * * RpcVMX_ConfigGetString -- * * Look up a config variable in the VMX's config file and return its * value as a string. The caller should free the string using free() when * done. * * Results: * The value of the variable if it was set, or a copy of the default * value string if the variable was not set. * * Side effects: * Allocates memory which the caller must free(). * *---------------------------------------------------------------------------- */ char * RpcVMX_ConfigGetString(const char *defval, const char *var) { char *value; if (!RpcOut_sendOne(&value, NULL, "info-get guestinfo.%s", var)) { /* Get rid of the old value first. */ free(value); value = NULL; if (defval) { /* * We have to dup the default, because of our contract: values we * return must always be freed by the caller. */ value = strdup(defval); } } return value; } /* *---------------------------------------------------------------------------- * * RpcVMX_ConfigGetBool -- * * Same as RpcVMX_ConfigGetString, but convert the value to a boolean * and return it. * * Results: * Value of config variable as a Bool, or the default value if the config * variable was not set *or* could not be converted to a Bool. * * Side effects: * Perturbs the heap. * *---------------------------------------------------------------------------- */ Bool RpcVMX_ConfigGetBool(Bool defval, const char *var) { char *value = RpcVMX_ConfigGetString(NULL, var); Bool ret = defval; if (value) { if (!Str_Strcasecmp(value, "TRUE")) { ret = TRUE; } else if (!Str_Strcasecmp(value, "FALSE")) { ret = FALSE; } free(value); } return ret; } /* *---------------------------------------------------------------------------- * * RpcVMX_ConfigGetLong -- * * Same as RpcVMX_ConfigGetString, but convert the value to an integer. * XXX We use atoi, so there's no error checking. If you care, use * RpcVMX_ConfigGetString and do the conversion yourself. * * Results: * The value of the config variable as a 32-bit integer if it was set, * the default value if it was not set, and 0 if there was an error * converting the value to an integer. * * Side effects: * Perturbs the heap. * *---------------------------------------------------------------------------- */ int32 RpcVMX_ConfigGetLong(int32 defval, const char *var) { char *value = RpcVMX_ConfigGetString(NULL, var); int32 ret = defval; if (value) { ret = atoi(value); free(value); } return ret; } open-vm-tools-9.4.0-1280544/lib/rpcVmx/Makefile.am0000644765153500003110000000172012220061556017520 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libRpcVmx.la libRpcVmx_la_SOURCES = libRpcVmx_la_SOURCES += rpcvmx.c open-vm-tools-9.4.0-1280544/lib/rpcVmx/Makefile.in0000644765153500003110000004353412220061623017535 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/rpcVmx DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libRpcVmx_la_LIBADD = am_libRpcVmx_la_OBJECTS = rpcvmx.lo libRpcVmx_la_OBJECTS = $(am_libRpcVmx_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libRpcVmx_la_SOURCES) DIST_SOURCES = $(libRpcVmx_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libRpcVmx.la libRpcVmx_la_SOURCES = rpcvmx.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/rpcVmx/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/rpcVmx/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libRpcVmx.la: $(libRpcVmx_la_OBJECTS) $(libRpcVmx_la_DEPENDENCIES) $(EXTRA_libRpcVmx_la_DEPENDENCIES) $(LINK) $(libRpcVmx_la_OBJECTS) $(libRpcVmx_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpcvmx.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/slashProc/0000755765153500003110000000000012220061623016136 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/slashProc/net.c0000644765153500003110000006070512220061556017105 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file net.c * * Parses assorted /proc/net nodes. */ #include #include #include #include #include #include #include "vmware.h" #include "panic.h" #include "slashProc.h" #include "slashProcNetInt.h" #include "netutil.h" /* * Local data. */ #define PROC_NET_SNMP "/proc/net/snmp" #define PROC_NET_SNMP6 "/proc/net/snmp6" #define PROC_NET_ROUTE "/proc/net/route" #define PROC_NET_ROUTE6 "/proc/net/ipv6_route" /** * @brief Evaluate an expression with a regular expression match. * * Convenience wrapper to fetch a regular expression match result, evaluate * it as an argument in some expression, and then free it. * * @param[in] matchInfo GMatchInfo RE context. * @param[in] matchIndex Match index. * @param[in] expr Expression to evaluate. Must contain @c MATCH as * placeholder where matched value will be inserted. */ #define MATCHEXPR(matchInfo, matchIndex, expr) do { \ gchar *MATCH = g_match_info_fetch(matchInfo, matchIndex); \ expr; \ g_free(MATCH); \ } while(0) /** * Override-able @c /proc/net/snmp path. Useful for debugging. */ static const char *pathToNetSnmp = PROC_NET_SNMP; /** * Override-able @c /proc/net/snmp6 path. Useful for debugging. */ static const char *pathToNetSnmp6 = PROC_NET_SNMP6; /** * Override-able @c /proc/net/route path. Useful for debugging. */ static const char *pathToNetRoute = PROC_NET_ROUTE; /** * Override-able @c /proc/net/ipv6_route path. Useful for debugging. */ static const char *pathToNetRoute6 = PROC_NET_ROUTE6; /* * Private function prototypes. */ static void Ip6StringToIn6Addr(const char *ip6String, struct in6_addr *in6_addr); static guint64 MatchToGuint64(const GMatchInfo *matchInfo, const gint matchIndex, gint base); /* * Library private functions. */ #ifdef VMX86_DEVEL /* ****************************************************************************** * SlashProcNetSetPathSnmp -- */ /** * * @brief Overrides @ref pathToNetSnmp. Useful for debugging. * * @param[in] newPathToNetSnmp New path to used in place of @ref PROC_NET_SNMP. * If @c NULL, @ref pathToNewSnmp reverts to @ref * PROC_NET_SNMP. * ****************************************************************************** */ void SlashProcNetSetPathSnmp(const char *newPathToNetSnmp) { pathToNetSnmp = newPathToNetSnmp ? newPathToNetSnmp : PROC_NET_SNMP; } /* ****************************************************************************** * SlashProcNetSetPathSnmp6 -- */ /** * * @brief Overrides @ref pathToNetSnmp6. Useful for debugging. * * @sa SlashProcNetSetPathSnmp * ****************************************************************************** */ void SlashProcNetSetPathSnmp6(const char *newPathToNetSnmp6) { pathToNetSnmp6 = newPathToNetSnmp6 ? newPathToNetSnmp6 : PROC_NET_SNMP6; } /* ****************************************************************************** * SlashProcNetSetPathRoute -- */ /** * * @brief Overrides @ref pathToNetRoute. Useful for debugging. * * @sa SlashProcNetSetPathSnmp * ****************************************************************************** */ void SlashProcNetSetPathRoute(const char *newPathToNetRoute) { pathToNetRoute = newPathToNetRoute ? newPathToNetRoute : PROC_NET_ROUTE; } /* ****************************************************************************** * SlashProcNetSetPathRoute6 -- */ /** * * @brief Overrides @ref pathToNetRoute6. Useful for debugging. * * @sa SlashProcNetSetPathSnmp * ****************************************************************************** */ void SlashProcNetSetPathRoute6(const char *newPathToNetRoute6) { pathToNetRoute6 = newPathToNetRoute6 ? newPathToNetRoute6 : PROC_NET_ROUTE6; } #endif // ifdef VMX86_DEVEL /* * Library public functions. */ /* ****************************************************************************** * SlashProcNet_GetSnmp -- */ /** * * @brief Reads @ref pathToNetSnmp and returns contents as a * GHashTable(gchar *key, guint64 *value). * * Example usage: * @code * GHashTable *netSnmp = SlashProcNet_GetSnmp(); * guint64 *inDiscards = g_hash_table_lookup(netSnmp, "IpInDiscards"); * @endcode * * @note Caller should free the returned @c GHashTable with * @c g_hash_table_destroy. * @note This routine creates persistent GLib GRegexs. * * @return On failure, NULL. On success, a valid @c GHashTable. * @todo Provide a case-insensitive key comparison function. * @todo Consider init/cleanup routines to not "leak" GRegexs. * ****************************************************************************** */ GHashTable * SlashProcNet_GetSnmp(void) { GHashTable *myHashTable = NULL; GIOChannel *myChannel = NULL; GIOStatus keyIoStatus; GIOStatus valIoStatus; gchar *myKeyLine = NULL; gchar *myValLine = NULL; Bool parseError = FALSE; int fd = -1; static GRegex *myKeyRegex = NULL; static GRegex *myValRegex = NULL; if (myKeyRegex == NULL) { myKeyRegex = g_regex_new("^(\\w+): (\\w+ )*(\\w+)$", G_REGEX_OPTIMIZE, 0, NULL); myValRegex = g_regex_new("^(\\w+): (-?\\d+ )*(-?\\d+)$", G_REGEX_OPTIMIZE, 0, NULL); ASSERT(myKeyRegex); ASSERT(myValRegex); } if ((fd = g_open(pathToNetSnmp, O_RDONLY)) == -1) { return NULL; } myChannel = g_io_channel_unix_new(fd); myHashTable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); /* * Expected format: * * pfx0: key0 key1 key2 ... keyN * pfx0: val0 val1 val2 ... valN * ... * pfxN: ... */ while ((keyIoStatus = g_io_channel_read_line(myChannel, &myKeyLine, NULL, NULL, NULL)) == G_IO_STATUS_NORMAL && (valIoStatus = g_io_channel_read_line(myChannel, &myValLine, NULL, NULL, NULL)) == G_IO_STATUS_NORMAL) { GMatchInfo *keyMatchInfo = NULL; GMatchInfo *valMatchInfo = NULL; gchar **myKeys = NULL; gchar **myVals = NULL; gchar **myKey = NULL; gchar **myVal = NULL; gchar *keyPrefix = NULL; gchar *valPrefix = NULL; /* * Per format above, we expect a pair of lines with a matching prefix. */ { if (!g_regex_match(myKeyRegex, myKeyLine, 0, &keyMatchInfo) || !g_regex_match(myValRegex, myValLine, 0, &valMatchInfo)) { parseError = TRUE; goto badIteration; } keyPrefix = g_match_info_fetch(keyMatchInfo, 1); valPrefix = g_match_info_fetch(valMatchInfo, 1); ASSERT(keyPrefix); ASSERT(valPrefix); if (strcmp(keyPrefix, valPrefix)) { parseError = TRUE; goto badIteration; } } myKeys = g_strsplit(myKeyLine, " ", 0); myVals = g_strsplit(myValLine, " ", 0); /* * Iterate over the columns, combining the column keys with the prefix * to form the new key name. (I.e., "Ip: InDiscards" => "IpInDiscards".) */ for (myKey = &myKeys[1], myVal = &myVals[1]; *myKey && *myVal; myKey++, myVal++) { gchar *hashKey; guint64 *myIntVal = NULL; hashKey = g_strjoin(NULL, keyPrefix, *myKey, NULL); g_strstrip(hashKey); /* * By virtue of having matched the above regex, this conversion * must hold. */ myIntVal = g_new(guint64, 1); *myIntVal = g_ascii_strtoull(*myVal, NULL, 10); /* * If our input contains duplicate keys, which I really don't see * happening, the latter value overrides the former. * * NB: myHashTable claims ownership of hashKey. */ g_hash_table_insert(myHashTable, hashKey, myIntVal); } /* * Make sure the column counts matched. If we succeeded, both pointers * should now be NULL. */ if (*myKey || *myVal) { parseError = TRUE; } badIteration: g_match_info_free(keyMatchInfo); g_match_info_free(valMatchInfo); g_free(keyPrefix); g_free(valPrefix); g_strfreev(myKeys); g_strfreev(myVals); g_free(myKeyLine); g_free(myValLine); myKeyLine = NULL; myValLine = NULL; if (parseError) { break; } } /* * Error conditions: * Hash table empty: Unable to parse any input. * myKeyLine != NULL: Failed to read "key" and "value" lines during * same loop iteration. * parseError == TRUE: See loop body above. */ if (keyIoStatus == G_IO_STATUS_ERROR || valIoStatus == G_IO_STATUS_ERROR || g_hash_table_size(myHashTable) == 0 || parseError) { g_hash_table_destroy(myHashTable); myHashTable = NULL; } g_free(myKeyLine); g_free(myValLine); myKeyLine = NULL; myValLine = NULL; close(fd); g_io_channel_unref(myChannel); return myHashTable; } /* ****************************************************************************** * SlashProcNet_GetSnmp6 -- */ /** * * @brief Reads @ref pathToNetSnmp6 and returns contents as a * GHashTable(gchar *key, guint64 *value). * * Example usage: * @code * GHashTable *netSnmp6 = SlashProcNet_GetSnmp6(); * guint64 *raw6Discards = g_hash_table_lookup(netSnmp6, "Ip6InDiscards"); * @endcode * * @note Caller should free the returned @c GHashTable with * @c g_hash_table_destroy. * @note This routine creates persistent GLib GRegexs. * * @return On failure, NULL. On success, a valid @c GHashTable. * @todo Provide a case-insensitive key comparison function. * @todo Consider init/cleanup routines to not "leak" GRegexs. * ****************************************************************************** */ GHashTable * SlashProcNet_GetSnmp6(void) { GHashTable *myHashTable = NULL; GIOChannel *myChannel = NULL; GIOStatus ioStatus; gchar *myInputLine = NULL; Bool parseError = FALSE; int fd = -1; static GRegex *myRegex = NULL; if (myRegex == NULL) { myRegex = g_regex_new("^(\\w+)\\s+(-?\\d+)\\s*$", G_REGEX_OPTIMIZE, 0, NULL); ASSERT(myRegex); } if ((fd = g_open(pathToNetSnmp6, O_RDONLY)) == -1) { return NULL; } myChannel = g_io_channel_unix_new(fd); myHashTable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); /* * Expected format: * * key1 value1 * key2 value2 * ... * keyN valueN */ while ((ioStatus = g_io_channel_read_line(myChannel, &myInputLine, NULL, NULL, NULL)) == G_IO_STATUS_NORMAL) { GMatchInfo *matchInfo = NULL; if (g_regex_match(myRegex, myInputLine, 0, &matchInfo)) { gchar *myKey = NULL; gchar *myVal = NULL; guint64 *myIntVal = NULL; myKey = g_match_info_fetch(matchInfo, 1); myVal = g_match_info_fetch(matchInfo, 2); /* * By virtue of having matched the above regex, this conversion * must hold. */ myIntVal = g_new(guint64, 1); *myIntVal = g_ascii_strtoull(myVal, NULL, 10); /* * The hash table will take ownership of myKey and myIntVal. We're * still responsible for myVal. */ g_hash_table_insert(myHashTable, myKey, myIntVal); g_free(myVal); } else { parseError = TRUE; } g_match_info_free(matchInfo); g_free(myInputLine); myInputLine = NULL; if (parseError) { break; } } if (ioStatus == G_IO_STATUS_ERROR || g_hash_table_size(myHashTable) == 0 || parseError) { g_hash_table_destroy(myHashTable); myHashTable = NULL; } close(fd); g_io_channel_unref(myChannel); return myHashTable; } /* ****************************************************************************** * SlashProcNet_GetRoute -- */ /** * * @brief Reads @ref pathToNetRoute and returns a @c GPtrArray of * struct rtentrys. * * Example usage: * @code * GPtrArray *rtArray; * guint i; * rtArray = SlashProcNet_GetRoute(); * for (i = 0; i < rtArray->len; i++) { * struct rtentry *myRoute = g_ptr_array_index(rtArray, i); * // Do something with myRoute->rt_dst. * } * SlashProcNet_FreeRoute(rtArray); * @endcode * * @note Caller is responsible for freeing the @c GPtrArray with * SlashProcNet_FreeRoute. * @note This routine creates persistent GLib GRegexs. * * @return On failure, NULL. On success, a valid @c GPtrArray. * @todo Consider init/cleanup routines to not "leak" GRegexs. * @todo Consider rewriting, integrating with libdnet. * ****************************************************************************** */ GPtrArray * SlashProcNet_GetRoute(void) { GIOChannel *myChannel = NULL; GIOStatus myIoStatus; GPtrArray *myArray = NULL; gchar *myLine = NULL; int fd = -1; static GRegex *myFieldsRE = NULL; static GRegex *myValuesRE = NULL; if (myFieldsRE == NULL) { myFieldsRE = g_regex_new("^Iface\\s+Destination\\s+Gateway\\s+Flags\\s+" "RefCnt\\s+Use\\s+Metric\\s+Mask\\s+MTU\\s+" "Window\\s+IRTT\\s*$", 0, 0, NULL); myValuesRE = g_regex_new("^(\\w+)\\s+([[:xdigit:]]{8})\\s+" "([[:xdigit:]]{8})\\s+([[:xdigit:]]{4})\\s+" "\\d+\\s+\\d+\\s+(\\d+)\\s+" "([[:xdigit:]]{8})\\s+(\\d+)\\s+\\d+\\s+(\\d+)\\s*$", 0, 0, NULL); ASSERT(myFieldsRE); ASSERT(myValuesRE); } /* * 1. Open pathToNetRoute, associate it with a GIOChannel. */ if ((fd = g_open(pathToNetRoute, O_RDONLY)) == -1) { Warning("%s: open(%s): %s\n", __func__, pathToNetRoute, g_strerror(errno)); return NULL; } myChannel = g_io_channel_unix_new(fd); /* * 2. Sanity check the header, making sure it matches what we expect. * (It's -extremely- unlikely this will change, but we should check * anyway.) */ myIoStatus = g_io_channel_read_line(myChannel, &myLine, NULL, NULL, NULL); if (myIoStatus != G_IO_STATUS_NORMAL || g_regex_match(myFieldsRE, myLine, 0, NULL) == FALSE) { goto out; } g_free(myLine); myLine = NULL; myArray = g_ptr_array_new(); /* * 3. For each line... */ while ((myIoStatus = g_io_channel_read_line(myChannel, &myLine, NULL, NULL, NULL)) == G_IO_STATUS_NORMAL) { GMatchInfo *myMatchInfo = NULL; struct rtentry *myEntry = NULL; struct sockaddr_in *sin = NULL; Bool parseError = FALSE; /* * 3a. Validate with regex. */ if (!g_regex_match(myValuesRE, myLine, 0, &myMatchInfo)) { parseError = TRUE; goto badIteration; } /* * 3b. Allocate new rtentry, add to array. This simplifies the cleanup * code path. */ myEntry = g_new0(struct rtentry, 1); g_ptr_array_add(myArray, myEntry); /* * 3c. Copy contents to new struct rtentry. */ myEntry->rt_dev = g_match_info_fetch(myMatchInfo, 1); sin = (struct sockaddr_in *)&myEntry->rt_dst; sin->sin_family = AF_INET; sin->sin_addr.s_addr = MatchToGuint64(myMatchInfo, 2, 16); sin = (struct sockaddr_in *)&myEntry->rt_gateway; sin->sin_family = AF_INET; sin->sin_addr.s_addr = MatchToGuint64(myMatchInfo, 3, 16); sin = (struct sockaddr_in *)&myEntry->rt_genmask; sin->sin_family = AF_INET; sin->sin_addr.s_addr = MatchToGuint64(myMatchInfo, 6, 16); myEntry->rt_flags = MatchToGuint64(myMatchInfo, 4, 16); myEntry->rt_metric = MatchToGuint64(myMatchInfo, 5, 10); myEntry->rt_mtu = MatchToGuint64(myMatchInfo, 7, 10); myEntry->rt_irtt = MatchToGuint64(myMatchInfo, 8, 10); badIteration: g_free(myLine); myLine = NULL; g_match_info_free(myMatchInfo); myMatchInfo = NULL; if (parseError) { break; } } if (myArray && myIoStatus != G_IO_STATUS_EOF) { SlashProcNet_FreeRoute(myArray); myArray = NULL; } out: g_free(myLine); close(fd); g_io_channel_unref(myChannel); return myArray; } /* ****************************************************************************** * SlashProcNet_FreeRoute -- */ /** * * @brief Frees memory associated with a GPtrArray allocated by * SlashProcNet_GetRoute. * * @param[in] routeArray Array to free. * ****************************************************************************** */ void SlashProcNet_FreeRoute(GPtrArray *routeArray) { int i; if (routeArray == NULL) { return; } for (i = 0; i < routeArray->len; i++) { struct rtentry *myEntry = g_ptr_array_index(routeArray, i); ASSERT(myEntry->rt_dev); g_free(myEntry->rt_dev); g_free(myEntry); } g_ptr_array_free(routeArray, TRUE); } /* ****************************************************************************** * SlashProcNet_GetRoute6 -- */ /** * * @brief Reads @ref pathToNetRoute6 and returns a @c GPtrArray of * struct in6_rtmsgs. * * Example usage: * @code * GPtrArray *rtArray; * guint i; * rtArray = SlashProcNet_GetRoute6(); * for (i = 0; i < rtArray->len; i++) { * struct in6_rtmsg *myRoute = g_ptr_array_index(rtArray, i); * // Do something with myRoute->rtmsg_dst. * } * SlashProcNet_FreeRoute6(rtArray, TRUE); * @endcode * * @note Caller is responsible for freeing the @c GPtrArray with * SlashProcNet_FreeRoute6. * @note This routine creates persistent GLib GRegexs. * * @return On failure, NULL. On success, a valid @c GPtrArray. * @todo Consider init/cleanup routines to not "leak" GRegexs. * @todo Consider rewriting, integrating with libdnet. * ****************************************************************************** */ GPtrArray * SlashProcNet_GetRoute6(void) { GIOChannel *myChannel = NULL; GIOStatus myIoStatus; GPtrArray *myArray = NULL; gchar *myLine = NULL; Bool parseError = FALSE; int fd = -1; static GRegex *myValuesRE = NULL; if (myValuesRE == NULL) { myValuesRE = g_regex_new("^([[:xdigit:]]{32}) ([[:xdigit:]]{2}) " "([[:xdigit:]]{32}) ([[:xdigit:]]{2}) " "([[:xdigit:]]{32}) ([[:xdigit:]]{8}) " "[[:xdigit:]]{8} [[:xdigit:]]{8} " "([[:xdigit:]]{8})\\s+(\\w+)\\s*$", 0, 0, NULL); ASSERT(myValuesRE); } /* * 1. Open pathToNetRoute6, associate it with a GIOChannel. */ if ((fd = g_open(pathToNetRoute6, O_RDONLY)) == -1) { Warning("%s: open(%s): %s\n", __func__, pathToNetRoute, g_strerror(errno)); return NULL; } myChannel = g_io_channel_unix_new(fd); myArray = g_ptr_array_new(); while ((myIoStatus = g_io_channel_read_line(myChannel, &myLine, NULL, NULL, NULL)) == G_IO_STATUS_NORMAL) { struct in6_rtmsg *myEntry = NULL; GMatchInfo *myMatchInfo = NULL; if (!g_regex_match(myValuesRE, myLine, 0, &myMatchInfo)) { parseError = TRUE; goto badIteration; } myEntry = g_new0(struct in6_rtmsg, 1); g_ptr_array_add(myArray, myEntry); MATCHEXPR(myMatchInfo, 1, Ip6StringToIn6Addr(MATCH, &myEntry->rtmsg_dst)); MATCHEXPR(myMatchInfo, 3, Ip6StringToIn6Addr(MATCH, &myEntry->rtmsg_src)); MATCHEXPR(myMatchInfo, 5, Ip6StringToIn6Addr(MATCH, &myEntry->rtmsg_gateway)); myEntry->rtmsg_dst_len = MatchToGuint64(myMatchInfo, 2, 16); myEntry->rtmsg_src_len = MatchToGuint64(myMatchInfo, 4, 16); myEntry->rtmsg_metric = MatchToGuint64(myMatchInfo, 6, 16); myEntry->rtmsg_flags = MatchToGuint64(myMatchInfo, 7, 16); MATCHEXPR(myMatchInfo, 8, myEntry->rtmsg_ifindex = NetUtil_GetIfIndex(MATCH)); badIteration: g_free(myLine); myLine = NULL; g_match_info_free(myMatchInfo); myMatchInfo = NULL; if (parseError) { break; } } if (myArray && myIoStatus != G_IO_STATUS_EOF) { SlashProcNet_FreeRoute6(myArray); myArray = NULL; } g_free(myLine); myLine = NULL; close(fd); g_io_channel_unref(myChannel); return myArray; } /* ****************************************************************************** * SlashProcNet_FreeRoute6 -- */ /** * * @brief Frees memory associated with a GPtrArray allocated by * SlashProcNet_GetRoute6. * * @param[in] routeArray Array to free. * ****************************************************************************** */ void SlashProcNet_FreeRoute6(GPtrArray *routeArray) { int i; if (routeArray == NULL) { return; } for (i = 0; i < routeArray->len; i++) { struct rtentry *myEntry = g_ptr_array_index(routeArray, i); g_free(myEntry); } g_ptr_array_free(routeArray, TRUE); } /* * Private functions. */ /* ****************************************************************************** * Ip6StringToIn6Addr -- */ /** * * @brief Parses a @c /proc/net/ipv6_route hexadecimal IPv6 address and * records it in a struct in6_addr. * * @param[in] ip6String Source string. * @param[out] in6_addr Output struct. * ****************************************************************************** */ static void Ip6StringToIn6Addr(const char *ip6String, struct in6_addr *in6_addr) { unsigned int i; ASSERT(strlen(ip6String) == 32); for (i = 0; i < 16; i++) { int nmatched; nmatched = sscanf(&ip6String[2 * i], "%2hhx", &in6_addr->s6_addr[i]); ASSERT(nmatched == 1); } } /* ****************************************************************************** * MatchToGuint64 -- */ /** * * @brief Wrapper around @c g_ascii_strtoull and @c g_match_info_fetch. * * @param[in] matchInfo Source regular expression match context. * @param[in] matchIndex Match number to fetch. * @param[in] base Base represented by matched string. * (See @c g_ascii_strtoull docs.) * ****************************************************************************** */ static guint64 MatchToGuint64(const GMatchInfo *matchInfo, const gint matchIndex, gint base) { guint64 retval; MATCHEXPR(matchInfo, matchIndex, retval = g_ascii_strtoull(MATCH, NULL, base)); return retval; } open-vm-tools-9.4.0-1280544/lib/slashProc/Makefile.am0000644765153500003110000000207612220061556020204 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libSlashProc.la libSlashProc_la_SOURCES = libSlashProc_la_SOURCES += net.c libSlashProc_la_CPPFLAGS = libSlashProc_la_CPPFLAGS += @GLIB2_CPPFLAGS@ AM_CFLAGS = $(DNET_CPPFLAGS) open-vm-tools-9.4.0-1280544/lib/slashProc/slashProcNetInt.h0000644765153500003110000000260612220061556021400 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file netInt.h * * SlashProcNet internal bits. */ #ifndef _SLASHPROCNETINT_H_ #define _SLASHPROCNETINT_H_ #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #ifdef VMX86_DEVEL EXTERN void SlashProcNetSetPathSnmp(const char *newPathToNetSnmp); EXTERN void SlashProcNetSetPathSnmp6(const char *newPathToNetSnmp6); EXTERN void SlashProcNetSetPathRoute(const char *newPathToNetRoute); EXTERN void SlashProcNetSetPathRoute6(const char *newPathToNetRoute6); #endif // ifdef VMX86_DEVEL #endif // ifndef _SLASHPROCNETINT_H_ open-vm-tools-9.4.0-1280544/lib/slashProc/Makefile.in0000644765153500003110000004565112220061623020216 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/slashProc DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libSlashProc_la_LIBADD = am_libSlashProc_la_OBJECTS = libSlashProc_la-net.lo libSlashProc_la_OBJECTS = $(am_libSlashProc_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libSlashProc_la_SOURCES) DIST_SOURCES = $(libSlashProc_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libSlashProc.la libSlashProc_la_SOURCES = net.c libSlashProc_la_CPPFLAGS = @GLIB2_CPPFLAGS@ AM_CFLAGS = $(DNET_CPPFLAGS) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/slashProc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/slashProc/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libSlashProc.la: $(libSlashProc_la_OBJECTS) $(libSlashProc_la_DEPENDENCIES) $(EXTRA_libSlashProc_la_DEPENDENCIES) $(LINK) $(libSlashProc_la_OBJECTS) $(libSlashProc_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libSlashProc_la-net.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libSlashProc_la-net.lo: net.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSlashProc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libSlashProc_la-net.lo -MD -MP -MF $(DEPDIR)/libSlashProc_la-net.Tpo -c -o libSlashProc_la-net.lo `test -f 'net.c' || echo '$(srcdir)/'`net.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libSlashProc_la-net.Tpo $(DEPDIR)/libSlashProc_la-net.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='net.c' object='libSlashProc_la-net.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSlashProc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libSlashProc_la-net.lo `test -f 'net.c' || echo '$(srcdir)/'`net.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/misc/0000755765153500003110000000000012220061622015132 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/misc/dynarray.c0000644765153500003110000001030512220061556017134 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * dynarray.c -- * * Dynamic array of objects -- tonyc */ #include #include "vmware.h" #include "dynarray.h" /* *----------------------------------------------------------------------------- * * DynArray_Init -- * * Initialize the dynamic array * * Results: * TRUE on success. FALSE on failure. * * Side effects: * See above * *----------------------------------------------------------------------------- */ Bool DynArray_Init(DynArray *a, // IN/OUT unsigned int count, // IN size_t width) // IN { ASSERT(a); DynBuf_Init(&a->buf); a->width = width; return DynArray_SetCount(a, count); } /* *----------------------------------------------------------------------------- * * DynArray_Destroy -- * * Destroy the array * * Results: * None * * Side effects: * See above * *----------------------------------------------------------------------------- */ void DynArray_Destroy(DynArray *a) // IN/OUT { ASSERT(a); DynBuf_Destroy(&a->buf); } /* *----------------------------------------------------------------------------- * * DynArray_SetCount -- * * Sets the number of elements in the array. This may enlarge * the size of the array. * * Results: * TRUE on success * FALSE on failure (not enough memory) * * Side effects: * May resize the array * *----------------------------------------------------------------------------- */ Bool DynArray_SetCount(DynArray *a, // IN/OUT unsigned int c) // IN { size_t needed, allocated; ASSERT(a); needed = c * a->width; allocated = DynBuf_GetAllocatedSize(&a->buf); if (allocated < needed) { if (!DynBuf_Enlarge(&a->buf, needed)) { return FALSE; } } DynBuf_SetSize(&a->buf, needed); return TRUE; } /* *----------------------------------------------------------------------------- * * DynArray_AllocCount -- * * Returns the actual size of the array. If you want the effective * size, use DynArray_Count. Technically, you don't need this API * unless you're doing trimming (i.e. Don't bother trimming if * DynArray_AllocCount is within some threshold of DynArray_Count. * It won't buy you much). * * XXX: This is relatively slow, since we do an integer division. * Avoid calling this in inner loops. * * Results: * See above. * * Side effects: * None. * *----------------------------------------------------------------------------- */ unsigned int DynArray_AllocCount(const DynArray *a) // IN { ASSERT(a); return (unsigned int) (DynBuf_GetAllocatedSize(&a->buf) / a->width); } /* *----------------------------------------------------------------------------- * * DynArray_QSort -- * * A wrapper for the quicksort function. Sorts the DynArray * according to the provided comparison function. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void DynArray_QSort(DynArray *a, // IN/OUT DynArrayCmp compare) // IN { uint8 *arrayBuf; ASSERT(a); ASSERT(compare); arrayBuf = DynBuf_Get(&a->buf); qsort(arrayBuf, DynArray_Count(a), a->width, compare); } open-vm-tools-9.4.0-1280544/lib/misc/codesetOld.h0000644765153500003110000001407712220061556017407 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * codesetOld.h -- * * The old codeset implementation that depends on system libraries. * Used for fallback if ICU isn't available. * */ #ifndef __CODESET_OLD_H__ # define __CODESET_OLD_H__ #include "dynbuf.h" #include "codeset.h" // for CURRENT_IS_UTF8 /* * These systems use iconv and nl_langinfo. * See the definition of CURRENT_IS_UTF8. */ #if !defined(CURRENT_IS_UTF8) && !defined(_WIN32) #define USE_ICONV #endif Bool CodeSetOld_GenericToGenericDb(char const *codeIn, // IN char const *bufIn, // IN size_t sizeIn, // IN char const *codeOut, // IN unsigned int flags, // IN DynBuf *db); // IN/OUT Bool CodeSetOld_GenericToGeneric(const char *codeIn, // IN const char *bufIn, // IN size_t sizeIn, // IN const char *codeOut, // IN unsigned int flags, // IN char **bufOut, // IN/OUT size_t *sizeOut); // IN/OUT Bool CodeSetOld_Utf8ToCurrent(char const *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSetOld_CurrentToUtf8(char const *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSetOld_Utf16leToUtf8Db(char const *bufIn, // IN size_t sizeIn, // IN DynBuf *db); // IN Bool CodeSetOld_Utf16leToUtf8(char const *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSetOld_Utf8ToUtf16le(char const *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSetOld_CurrentToUtf16le(char const *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSetOld_Utf16leToCurrent(char const *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSetOld_Utf16beToCurrent(char const *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSetOld_Utf8Normalize(const char *bufIn, // IN size_t sizeIn, // IN Bool precomposed, // IN DynBuf *db); // OUT Bool CodeSetOld_Utf8FormDToUtf8FormC(char const *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSetOld_Utf8FormCToUtf8FormD(char const *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSetOld_Utf16beToUtf8(char const *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSetOld_Utf16beToUtf8Db(char const *bufIn, // IN size_t sizeIn, // IN DynBuf *db); // IN Bool CodeSetOld_AsciiToUtf8(const char *bufIn, // IN size_t sizeIn, // IN unsigned int flags, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSetOld_AsciiToUtf8Db(char const *bufIn, // IN size_t sizeIn, // IN unsigned int flags, // IN DynBuf *db); // OUT Bool CodeSetOld_Utf8ToAscii(const char *bufIn, // IN size_t sizeIn, // IN unsigned int flags, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSetOld_Utf8ToAsciiDb(char const *bufIn, // IN size_t sizeIn, // IN unsigned int flags, // IN DynBuf *db); // OUT const char * CodeSetOld_GetCurrentCodeSet(void); Bool CodeSetOld_IsEncodingSupported(const char *name); // IN Bool CodeSetOld_Validate(const char *buf, // IN: the string size_t size, // IN: length of string const char *code); // IN: encoding Bool CodeSetOld_Init(const char *dataDir); // UNUSED #endif /* __CODESET_OLD_H__ */ open-vm-tools-9.4.0-1280544/lib/misc/codesetOld.c0000644765153500003110000017140212220061556017376 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * codesetOld.c -- * * The old codeset implementation that depends on system libraries. * Used for fallback if ICU isn't available. */ #if defined(_WIN32) # include # include # include #else # if defined(__linux__) # define _GNU_SOURCE // see nl_langinfo_l explanation below # endif # include # include # include # include #endif #if defined(__APPLE__) # include /* for CFString */ #endif #include "vmware.h" #include "codeset.h" #include "codesetOld.h" #include "unicodeTypes.h" #include "util.h" #include "str.h" #if defined(USE_ICONV) /* * Use nl_langinfo_l on Linux. To get the nl_langinfo_l * related definitions in local.h, we need to define _GNU_SOURCE, * which has to be done above because one of the other standard include * files sucks it in. */ #include #if defined(__linux__) && !defined(LC_CTYPE_MASK) // Prior to glibc 2.3 #define LC_CTYPE_MASK (1 << LC_CTYPE) #define locale_t __locale_t #define newlocale __newlocale #define freelocale __freelocale #define nl_langinfo_l __nl_langinfo_l #endif #include #include #include #endif #if defined(__FreeBSD__) || defined(sun) static const char nul[] = {'\0', '\0'}; #else static const wchar_t nul = L'\0'; #endif #ifndef USE_ICONV static Bool CodeSetOldIso88591ToUtf8Db(char const *bufIn, size_t sizeIn, unsigned int flags, DynBuf *db); #endif #if defined __ANDROID__ #include "vm_basic_asm.h" /* * Android doesn't have swab(). */ void swab(const void *__restrict src, // IN/OUT void *__restrict dest, // IN/OUT ssize_t nbytes) // IN { const uint16 *p = src; uint16 *q = dest; ssize_t i; for (i = 0; i < nbytes / sizeof(*p); i++) { q[i] = Bswap16(p[i]); } } #endif #if defined(CURRENT_IS_UTF8) || defined(_WIN32) /* *----------------------------------------------------------------------------- * * CodeSetOldDuplicateStr -- * * Duplicate input string, appending zero terminator to its end. Only * used on Windows and on platforms where current encoding is always * UTF-8, on other iconv-capable platforms we just use iconv even for * UTF-8 to UTF-8 translation. * * Results: * TRUE on success * FALSE on failure * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool CodeSetOldDuplicateStr(const char *bufIn, // IN: Input string size_t sizeIn, // IN: Input string length char **bufOut, // OUT: "Converted" string size_t *sizeOut) // OUT/OPT: Length of string { char *myBufOut; size_t newSize = sizeIn + sizeof *myBufOut; if (newSize < sizeIn) { // Prevent integer overflow return FALSE; } myBufOut = malloc(newSize); if (myBufOut == NULL) { return FALSE; } memcpy(myBufOut, bufIn, sizeIn); myBufOut[sizeIn] = '\0'; *bufOut = myBufOut; if (sizeOut) { *sizeOut = sizeIn; } return TRUE; } #endif /* *----------------------------------------------------------------------------- * * CodeSetOldDynBufFinalize -- * * Append NUL terminator to the buffer, and return pointer to buffer * and its data size (before appending terminator). Destroys buffer * on failure. * * Results: * TRUE on success * FALSE on failure * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool CodeSetOldDynBufFinalize(Bool ok, // IN: Earlier steps succeeded DynBuf *db, // IN: Buffer with converted string char **bufOut, // OUT: Converted string size_t *sizeOut) // OUT/OPT: Length of string in bytes { if (!ok || !DynBuf_Append(db, &nul, sizeof nul) || !DynBuf_Trim(db)) { DynBuf_Destroy(db); return FALSE; } *bufOut = DynBuf_Get(db); if (sizeOut) { *sizeOut = DynBuf_GetSize(db) - sizeof nul; } return TRUE; } /* *----------------------------------------------------------------------------- * * CodeSetOldUtf8ToUtf16leDb -- * * Append the content of a buffer (that uses the UTF-8 encoding) to a * DynBuf (that uses the UTF-16LE encoding) * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool CodeSetOldUtf8ToUtf16leDb(const char *bufIn, // IN: size_t sizeIn, // IN: DynBuf *db) // IN: { const char *bufEnd = bufIn + sizeIn; size_t currentSize; size_t allocatedSize; uint16 *buf; currentSize = DynBuf_GetSize(db); allocatedSize = DynBuf_GetAllocatedSize(db); buf = (uint16 *)((char *)DynBuf_Get(db) + currentSize); while (bufIn < bufEnd) { size_t neededSize; uint32 uniChar; int n = CodeSet_GetUtf8(bufIn, bufEnd, &uniChar); if (n <= 0) { return FALSE; } bufIn += n; /* * Here we have UCS-4 character in uniChar, between 0 and 0x7FFFFFFF. * Let's convert it to UTF-16. */ /* Non-paired surrogates are illegal in UTF-16. */ if (uniChar >= 0xD800 && uniChar < 0xE000) { return FALSE; } if (uniChar < 0x10000) { neededSize = currentSize + sizeof *buf; } else if (uniChar < 0x110000) { neededSize = currentSize + 2 * sizeof *buf; } else { /* This character cannot be represented in UTF-16. */ return FALSE; } if (allocatedSize < neededSize) { if (DynBuf_Enlarge(db, neededSize) == FALSE) { return FALSE; } allocatedSize = DynBuf_GetAllocatedSize(db); ASSERT(neededSize <= allocatedSize); buf = (uint16 *)((char *)DynBuf_Get(db) + currentSize); } if (uniChar < 0x10000) { *buf++ = uniChar; } else { *buf++ = 0xD800 + ((uniChar - 0x10000) >> 10); *buf++ = 0xDC00 + ((uniChar - 0x10000) & 0x3FF); } currentSize = neededSize; } /* All went fine, update buffer size. */ DynBuf_SetSize(db, currentSize); return TRUE; } #if defined(_WIN32) // { static DWORD GetInvalidCharsFlag(void); /* * Win32-specific remarks: here is my understanding of those terms as of * 2002/02/12: * * ANSI code page * The character set used internally by Windows applications (when they are * not fully Unicode). * * OEM code page * The character set used by MS-DOS and stored in the FAT filesystem. * * --hpreg */ /* *----------------------------------------------------------------------------- * * CodeSetOldGenericToUtf16leDb -- * * Append the content of a buffer (that uses the specified encoding) to a * DynBuf (that uses the UTF-16LE encoding) --hpreg * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool CodeSetOldGenericToUtf16leDb(UINT codeIn, // IN: char const *bufIn, // IN: size_t sizeIn, // IN: DynBuf *db) // IN: { /* * Undocumented: calling MultiByteToWideChar() with sizeIn == 0 returns 0 * with GetLastError() set to ERROR_INVALID_PARAMETER. Isn't this API * robust? --hpreg */ if (sizeIn) { size_t initialSize; DWORD flags = GetInvalidCharsFlag(); Bool invalidCharsCheck = ((flags & MB_ERR_INVALID_CHARS) != 0); initialSize = DynBuf_GetSize(db); for (;;) { int result; int resultReverse; DWORD error = ERROR_SUCCESS; if (DynBuf_Enlarge(db, sizeof(wchar_t)) == FALSE) { return FALSE; } /* * Must fail if bufIn has any invalid characters. * So MB_ERR_INVALID_CHARS added, otherwise can * lead to security issues see bug 154114. */ result = MultiByteToWideChar(codeIn, flags, bufIn, sizeIn, (wchar_t *)((char *)DynBuf_Get(db) + initialSize), (DynBuf_GetAllocatedSize(db) - initialSize) / sizeof(wchar_t)); if (0 == result) { error = GetLastError(); // may be ERROR_NO_UNICODE_TRANSLATION } /* * Success if: result is > 0 and is the same number * of characters as the input string contains. If there * are any invalid characters, the Win2K SP4 or later will * fail, but for earlier OS versions, these invalid characters * will be dropped. Thus only succeed if we have no dropped * characters. * For the older platforms which don't fail for invalid characters * we see if the reverse conversion of the converted string * yields the same string size that was passed in. * If not, then dropped characters so fail. */ if (!invalidCharsCheck) { resultReverse = WideCharToMultiByte(codeIn, 0, (wchar_t *)((char *)DynBuf_Get(db) + initialSize), result, NULL, 0, 0, 0); } if (result > 0 && (invalidCharsCheck || (sizeIn == resultReverse))) { DynBuf_SetSize(db, initialSize + result * sizeof(wchar_t)); break; } if (result > 0 && (!invalidCharsCheck && sizeIn != resultReverse)) { return FALSE; } ASSERT(result == 0); if (error != ERROR_INSUFFICIENT_BUFFER) { return FALSE; } /* Need a larger buffer --hpreg */ } } return TRUE; } /* *----------------------------------------------------------------------------- * * CodeSetOldUtf16leToGeneric -- * * Append the content of a buffer (that uses the UTF-16LE encoding) to a * DynBuf (that uses the specified encoding) --hpreg * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool CodeSetOldUtf16leToGeneric(char const *bufIn, // IN: size_t sizeIn, // IN: UINT codeOut, // IN: DynBuf *db) // IN: { /* * Undocumented: calling WideCharToMultiByte() with sizeIn == 0 returns 0 * with GetLastError() set to ERROR_INVALID_PARAMETER. Isn't this API * robust? --hpreg */ if (sizeIn) { size_t initialSize; Bool canHaveSubstitution = codeOut != CP_UTF8 && codeOut != CP_UTF7; initialSize = DynBuf_GetSize(db); for (;;) { int result; DWORD error; BOOL usedSubstitution = FALSE; if (DynBuf_Enlarge(db, 1) == FALSE) { return FALSE; } result = WideCharToMultiByte(codeOut, canHaveSubstitution ? WC_NO_BEST_FIT_CHARS : 0, (wchar_t const *)bufIn, sizeIn / sizeof(wchar_t), (char *)DynBuf_Get(db) + initialSize, DynBuf_GetAllocatedSize(db) - initialSize, NULL, canHaveSubstitution ? &usedSubstitution : NULL); if (usedSubstitution) { return FALSE; } if (result > 0) { DynBuf_SetSize(db, initialSize + result); break; } ASSERT(result == 0); /* Must come first --hpreg */ error = GetLastError(); if (error != ERROR_INSUFFICIENT_BUFFER) { return FALSE; } /* Need a larger buffer --hpreg */ } } /* * Undocumented: if the input buffer is not NUL-terminated, the output * buffer will not be NUL-terminated either --hpreg */ return TRUE; } /* *----------------------------------------------------------------------------- * * CodeSetOldUtf16leToCurrent -- * * Convert the content of a buffer (that uses the UTF-16LE encoding) into * another buffer (that uses the current encoding) --hpreg * * Results: * TRUE on success: '*bufOut' contains the allocated, NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool CodeSetOldUtf16leToCurrent(char const *bufIn, // IN: size_t sizeIn, // IN: char **bufOut, // OUT: size_t *sizeOut) // OUT: { DynBuf db; Bool ok; DynBuf_Init(&db); /* XXX We should probably use CP_THREAD_ACP on Windows 2000/XP --hpreg */ ok = CodeSetOldUtf16leToGeneric(bufIn, sizeIn, CP_ACP, &db); return CodeSetOldDynBufFinalize(ok, &db, bufOut, sizeOut); } #endif // } #if defined(__APPLE__) /* *----------------------------------------------------------------------------- * * CodeSetOld_Utf8Normalize -- * * Convert the content of a buffer (that uses the UTF-8 encoding) into * another buffer (that uses the UTF-8 encoding) that is in precomposed * (Normalization Form C) or decomposed (Normalization Form D). * * Results: * TRUE on success: '*bufOut' contains a NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * '*bufOut' contains the allocated, NUL terminated buffer. * *----------------------------------------------------------------------------- */ Bool CodeSetOld_Utf8Normalize(char const *bufIn, // IN: size_t sizeIn, // IN: Bool precomposed, // IN: DynBuf *db) // OUT: { Bool ok = FALSE; CFStringRef str = NULL; CFMutableStringRef mutStr = NULL; CFIndex len, lenMut; size_t initialSize = DynBuf_GetSize(db); str = CFStringCreateWithCString(NULL, bufIn, kCFStringEncodingUTF8); if (str == NULL) { goto exit; } mutStr = CFStringCreateMutableCopy(NULL, 0, str); if (mutStr == NULL) { goto exit; } /* * Normalize the string, Form C - precomposed or D, not. */ CFStringNormalize(mutStr, (precomposed ? kCFStringNormalizationFormC : kCFStringNormalizationFormD)); /* * Get the number (in terms of UTF-16 code units) * of characters in a string. */ lenMut = CFStringGetLength(mutStr); /* * Retrieve the maximum number of bytes a string of a * specified length (in UTF-16 code units) will take up * if encoded in a specified encoding. */ len = CFStringGetMaximumSizeForEncoding(lenMut, kCFStringEncodingUTF8); if (len + 1 > initialSize) { if (DynBuf_Enlarge(db, len + 1 - initialSize) == FALSE) { ok = FALSE; goto exit; } } /* * Copies the character contents of a string to a local C * string buffer after converting the characters to UTF-8. */ ok = CFStringGetCString(mutStr, (char *)DynBuf_Get(db), len + 1, kCFStringEncodingUTF8); if (ok) { /* Remove the NUL terminator that the above includes. */ DynBuf_SetSize(db, strlen((char *)DynBuf_Get(db))); } exit: if (str) { CFRelease(str); } if (mutStr) { CFRelease(mutStr); } return ok; } #endif /* defined(__APPLE__) */ /* * Linux-specific remarks: * * We use UTF-16 instead of UCS-2, because Windows 2000 introduces support * for basic input, output, and simple sorting of surrogates. * * We use UTF-16LE instead of UTF-16 so that iconv() does not prepend a BOM. * * --hpreg */ #if defined(USE_ICONV) // { /* *----------------------------------------------------------------------------- * * CodeSetOldGetCodeSetFromLocale -- * * Extract the native code set from LC_CTYPE. * * Results: * * The name of the current code set on success. The return value depends * on how LC_CTYPE is set in the locale, even if setlocale has not been * previously called. * * Side effects: * * May briefly set and restore locale on some systems, which is not * thread-safe. * *----------------------------------------------------------------------------- */ static char * CodeSetOldGetCodeSetFromLocale(void) { char *codeset; #if defined(__linux__) locale_t new = newlocale(LC_CTYPE_MASK, "", NULL); if (!new) { /* * If the machine is configured incorrectly (no current locale), * newlocale() could return NULL. Try to fall back on the "C" * locale. */ new = newlocale(LC_CTYPE_MASK, "C", NULL); ASSERT(new); } codeset = Util_SafeStrdup(nl_langinfo_l(CODESET, new)); freelocale(new); #elif defined(sun) char *locale = setlocale(LC_CTYPE, NULL); if (!setlocale(LC_CTYPE, "")) { /* * If the machine is configured incorrectly (no current locale), * setlocale() can fail. Try to fall back on the "C" locale. */ setlocale(LC_CTYPE, "C"); } codeset = Util_SafeStrdup(nl_langinfo(CODESET)); setlocale(LC_CTYPE, locale); #else #error #endif return codeset; } #endif // } USE_ICONV /* *----------------------------------------------------------------------------- * * CodeSetOld_GetCurrentCodeSet -- * * Return native code set name - always "UTF-8" on Apple, FreeBSD, * old Linux, and ESX. Obtained from GetACP on Windows and * nl_langinfo on Linux, Solaris, etc. On first invocation * initialize a cache with the code set name. * * Results: * * The name of the current code set on success. On systems that * use iconv the return value depends on how LC_CTYPE is set in the * locale, even if setlocale has not been previously called. * * Side effects: * * During first invocation may briefly set and restore locale on * some systems, which is not thread-safe. * *----------------------------------------------------------------------------- */ const char * CodeSetOld_GetCurrentCodeSet(void) { #if defined(CURRENT_IS_UTF8) return "UTF-8"; #elif defined(_WIN32) static char ret[20]; // max is "windows-4294967296" if (ret[0] == '\0') { Str_Sprintf(ret, sizeof(ret), "windows-%u", GetACP()); } return ret; #elif defined(USE_ICONV) static char *cachedCodeset; /* * Mirror GLib behavior: * * $G_FILENAME_ENCODING can have one or more encoding names * in a comma separated list. * * If the first entry in $G_FILENAME_ENCODING is set to * "@locale", get the code set from the environment. * * If the first entry in $G_FILENAME_ENCODING is not set to * "@locale", then it is the encoding name. * * If $G_FILENAME_ENCODING is not set and $G_BROKEN_FILENAMES * is set, the get the code set from the environment. * * If none of the above are met, the code set is UTF-8. * * XXX - TODO - Support multiple encodings in the list. * While G_FILENAME_ENCODING is documented to be a list, * the current implementation (GLib 2.16) ignores all but * the first entry when converting to/from UTF-8. */ if (!cachedCodeset) { char *gFilenameEncoding = getenv("G_FILENAME_ENCODING"); char *p; if (gFilenameEncoding && *gFilenameEncoding) { gFilenameEncoding = Util_SafeStrdup(gFilenameEncoding); p = strchr(gFilenameEncoding, ','); if (p) { *p = '\0'; } if (!strcmp(gFilenameEncoding, "@locale")) { free(gFilenameEncoding); cachedCodeset = CodeSetOldGetCodeSetFromLocale(); return cachedCodeset; } cachedCodeset = gFilenameEncoding; return cachedCodeset; } if (getenv("G_BROKEN_FILENAMES")) { cachedCodeset = CodeSetOldGetCodeSetFromLocale(); return cachedCodeset; } cachedCodeset = "UTF-8"; } return cachedCodeset; #else #error #endif } #if defined(USE_ICONV) // { /* *----------------------------------------------------------------------------- * * CodeSetOldIconvOpen -- * * Open iconv translator with requested flags. Currently only no flags, * and both CSGTG_TRANSLIT and CSGTG_IGNORE together are supported, as * this is only thing we need. If translit/ignore convertor fails, * then non-transliterating conversion is used. * * Results: * (iconv_t)-1 on failure * iconv handle on success * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE_SINGLE_CALLER iconv_t CodeSetOldIconvOpen(const char *codeIn, // IN: const char *codeOut, // IN: unsigned int flags) // IN: { #ifdef __linux__ if (flags) { char *codeOutExt; ASSERT(flags == (CSGTG_TRANSLIT | CSGTG_IGNORE)); /* * We should be using //TRANSLIT,IGNORE, but glibc versions older than * 2.3.4 (in particular, the version that ships with redhat linux 9.0) * are subtly broken when passing options with a comma, in such a way * that iconv_open will succeed but iconv_close can crash. For now, we * only use TRANSLIT and bail out after the first non-translitible * character. */ codeOutExt = Str_Asprintf(NULL, "%s//TRANSLIT", codeOut); if (codeOutExt) { iconv_t cd = iconv_open(codeOutExt, codeIn); free(codeOutExt); if (cd != (iconv_t)-1) { return cd; } } } #endif return iconv_open(codeOut, codeIn); } /* *----------------------------------------------------------------------------- * * CodeSetOld_GenericToGenericDb -- * * Append the content of a buffer (that uses the specified encoding) to a * DynBuf (that uses the specified encoding). --hpreg * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSetOld_GenericToGenericDb(char const *codeIn, // IN: char const *bufIn, // IN: size_t sizeIn, // IN: char const *codeOut, // IN: unsigned int flags, // IN: DynBuf *db) // IN/OUT: { iconv_t cd; ASSERT(codeIn); ASSERT(sizeIn == 0 || bufIn); ASSERT(codeOut); ASSERT(db); // XXX make CodeSetOldIconvOpen happy if (flags != 0) { flags = CSGTG_TRANSLIT | CSGTG_IGNORE; } cd = CodeSetOldIconvOpen(codeIn, codeOut, flags); if (cd == (iconv_t)-1) { return FALSE; } for (;;) { size_t size; size_t newSize; char *out; char *outOrig; size_t outLeft; size_t status; /* * Every character we care about can occupy at most * 4 bytes - UCS-4 is 4 bytes, UTF-16 is 2+2 bytes, * and UTF-8 is also at most 4 bytes for all * characters under 0x1FFFFF. * * If we allocate too small buffer nothing critical * happens except that in //IGNORE case some * implementations might return EILSEQ instead of * E2BIG. By having at least 4 bytes available we * can be sure that at least one character is * converted each call to iconv(). */ size = DynBuf_GetSize(db); newSize = size + 4; if (newSize < size) { // Prevent integer overflow. goto error; } if (DynBuf_Enlarge(db, newSize) == FALSE) { goto error; } out = (int8 *)DynBuf_Get(db) + size; outOrig = out; outLeft = DynBuf_GetAllocatedSize(db) - size; /* * From glibc 2.2 onward bufIn is no longer const due to a change * in the standard. However, the implementation of iconv doesn't * change bufIn so a simple cast is safe. --plangdale */ #ifdef __linux__ status = iconv(cd, (char **)&bufIn, &sizeIn, &out, &outLeft); #else status = iconv(cd, &bufIn, &sizeIn, &out, &outLeft); #endif DynBuf_SetSize(db, size + out - outOrig); /* * If all input characters were consumed, we are done. * Otherwise if at least one character was produced by conversion * then just increase buffer size and try again - with //IGNORE * iconv() returns an error (EILSEQ) but still processes as * many characters as possible. If no characters were produced, * then consult error code - do not consult return value in other * cases, it can be either random positive value (if some * characters were transliterated) or even -1 with errno set to * EILSEQ (if some characters were ignored). */ if (sizeIn == 0) { break; } if (out == outOrig) { if (status != -1) { goto error; } /* * Some libc implementations (one on ESX3, and one on Ganesh's * box) silently ignore //IGNORE. So if caller asked for * getting conversion done at any cost, just return success * even if failure occured. User will get truncated * message, but that's our best. We have no idea whether * incoming encoding is 8bit, 16bit, or what, so we cannot * skip over characters in input stream and recover :-( */ if ((flags & CSGTG_IGNORE) && errno == EILSEQ) { break; } if (errno != E2BIG) { goto error; } } /* Need a larger buffer --hpreg */ } if (iconv_close(cd) < 0) { return FALSE; } return TRUE; error: iconv_close(cd); return FALSE; } #else // USE_ICONV } { /* *----------------------------------------------------------------------------- * * CodeSetOld_GenericToGenericDb * * This non-iconv version can only handle common encodings. * * Results: * TRUE on success * FALSE on failure * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool CodeSetOld_GenericToGenericDb(char const *codeIn, // IN: char const *bufIn, // IN: size_t sizeIn, // IN: char const *codeOut, // IN: unsigned int flags, // IN: DynBuf *db) // IN/OUT: { Bool ret = FALSE; StringEncoding encIn = Unicode_EncodingNameToEnum(codeIn); StringEncoding encOut = Unicode_EncodingNameToEnum(codeOut); StringEncoding rawCurEnc = Unicode_GetCurrentEncoding(); char *bufOut = NULL; size_t sizeOut; /* * Trivial case. */ if ((0 == sizeIn) || (NULL == bufIn)) { ret = TRUE; goto exit; } if (encIn == encOut) { if (encIn == STRING_ENCODING_UTF8) { if (!CodeSetOld_Utf8ToUtf16le(bufIn, sizeIn, &bufOut, &sizeOut)) { goto exit; } } else if (encIn == STRING_ENCODING_UTF16_LE) { if (!CodeSetOld_Utf16leToUtf8(bufIn, sizeIn, &bufOut, &sizeOut)) { goto exit; } } else if (encIn == STRING_ENCODING_UTF16_BE) { if (!CodeSetOld_Utf16beToUtf8(bufIn, sizeIn, &bufOut, &sizeOut)) { goto exit; } } else if (encIn == STRING_ENCODING_US_ASCII) { if (!CodeSetOld_AsciiToUtf8(bufIn, sizeIn, 0, &bufOut, &sizeOut)) { goto exit; } } else if (encIn == rawCurEnc) { if (!CodeSetOld_CurrentToUtf8(bufIn, sizeIn, &bufOut, &sizeOut)) { goto exit; } } free(bufOut); bufOut = NULL; if (!DynBuf_Append(db, bufIn, sizeIn)) { goto exit; } } else if (rawCurEnc == encIn) { if (STRING_ENCODING_UTF8 == encOut) { if (!CodeSetOld_CurrentToUtf8(bufIn, sizeIn, &bufOut, &sizeOut)) { goto exit; } } else if (STRING_ENCODING_UTF16_LE == encOut) { if (!CodeSetOld_CurrentToUtf16le(bufIn, sizeIn, &bufOut, &sizeOut)) { goto exit; } } else { goto exit; } } else if (STRING_ENCODING_UTF8 == encIn) { if (rawCurEnc == encOut) { if (!CodeSetOld_Utf8ToCurrent(bufIn, sizeIn, &bufOut, &sizeOut)) { goto exit; } } else if (STRING_ENCODING_UTF16_LE == encOut) { if (!CodeSetOldUtf8ToUtf16leDb(bufIn, sizeIn, db)) { goto exit; } } else if (STRING_ENCODING_US_ASCII == encOut) { if (!CodeSetOld_Utf8ToAsciiDb(bufIn, sizeIn, flags, db)) { goto exit; } } else { goto exit; } } else if (STRING_ENCODING_UTF16_LE == encIn) { if (rawCurEnc == encOut) { if (!CodeSetOld_Utf16leToCurrent(bufIn, sizeIn, &bufOut, &sizeOut)) { goto exit; } } else if (STRING_ENCODING_UTF8 == encOut) { if (!CodeSetOld_Utf16leToUtf8Db(bufIn, sizeIn, db)) { goto exit; } } else { goto exit; } } else if (STRING_ENCODING_UTF16_BE == encIn) { if (rawCurEnc == encOut) { if (!CodeSetOld_Utf16beToCurrent(bufIn, sizeIn, &bufOut, &sizeOut)) { goto exit; } } else if (STRING_ENCODING_UTF8 == encOut) { if (!CodeSetOld_Utf16beToUtf8Db(bufIn, sizeIn, db)) { goto exit; } } else { goto exit; } } else if (STRING_ENCODING_US_ASCII == encIn) { if (STRING_ENCODING_UTF8 == encOut) { if (!CodeSetOld_AsciiToUtf8Db(bufIn, sizeIn, flags, db)) { goto exit; } } else { goto exit; } } else if (STRING_ENCODING_ISO_8859_1 == encIn) { if (STRING_ENCODING_UTF8 == encOut) { if (!CodeSetOldIso88591ToUtf8Db(bufIn, sizeIn, flags, db)) { goto exit; } } else { goto exit; } } else { goto exit; } if (bufOut != NULL) { if (DynBuf_GetSize(db) == 0) { DynBuf_Attach(db, sizeOut, bufOut); bufOut = NULL; } else { if (!DynBuf_Append(db, bufOut, sizeOut)) { goto exit; } } } ret = TRUE; exit: free(bufOut); return ret; } #endif // USE_ICONV } /* *----------------------------------------------------------------------------- * * CodeSetOld_GenericToGeneric -- * * Non-db version of CodeSetOld_GenericToGenericDb. * * Results: * TRUE on success, plus allocated string * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSetOld_GenericToGeneric(const char *codeIn, // IN: const char *bufIn, // IN: size_t sizeIn, // IN: const char *codeOut, // IN: unsigned int flags, // IN: char **bufOut, // OUT: size_t *sizeOut) // OUT: { DynBuf db; Bool ok; DynBuf_Init(&db); ok = CodeSetOld_GenericToGenericDb(codeIn, bufIn, sizeIn, codeOut, flags, &db); return CodeSetOldDynBufFinalize(ok, &db, bufOut, sizeOut); } /* * Generic remarks: here is my understanding of those terms as of 2001/12/27: * * BOM * Byte-Order Mark * * BMP * Basic Multilingual Plane. This plane comprises the first 2^16 code * positions of ISO/IEC 10646's canonical code space * * UCS * Universal Character Set. Encoding form specified by ISO/IEC 10646 * * UCS-2 * Directly store all Unicode scalar value (code point) from U+0000 to * U+FFFF on 2 bytes. Consequently, this representation can only hold * characters in the BMP * * UCS-4 * Directly store a Unicode scalar value (code point) from U-00000000 to * U-FFFFFFFF on 4 bytes * * UTF * Abbreviation for Unicode (or UCS) Transformation Format * * UTF-8 * Unicode (or UCS) Transformation Format, 8-bit encoding form. UTF-8 is the * Unicode Transformation Format that serializes a Unicode scalar value * (code point) as a sequence of 1 to 6 bytes * * UTF-16 * UCS-2 + surrogate mechanism: allow to encode some non-BMP Unicode * characters in a UCS-2 string, by using 2 2-byte units. See the Unicode * standard, v2.0 * * UTF-32 * Directly store all Unicode scalar value (code point) from U-00000000 to * U-0010FFFF on 4 bytes. This is a subset of UCS-4 * * --hpreg */ /* *----------------------------------------------------------------------------- * * CodeSetOld_Utf8ToCurrent -- * * Convert the content of a buffer (that uses the UTF-8 encoding) into * another buffer (that uses the current encoding) --hpreg * * Results: * TRUE on success: '*bufOut' contains the allocated, NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSetOld_Utf8ToCurrent(char const *bufIn, // IN: size_t sizeIn, // IN: char **bufOut, // OUT: size_t *sizeOut) // OUT: { #if defined(CURRENT_IS_UTF8) return CodeSetOldDuplicateStr(bufIn, sizeIn, bufOut, sizeOut); #elif defined(USE_ICONV) DynBuf db; Bool ok; DynBuf_Init(&db); ok = CodeSetOld_GenericToGenericDb("UTF-8", bufIn, sizeIn, CodeSetOld_GetCurrentCodeSet(), 0, &db); return CodeSetOldDynBufFinalize(ok, &db, bufOut, sizeOut); #elif defined(_WIN32) char *buf; size_t size; Bool status; if (CodeSetOld_Utf8ToUtf16le(bufIn, sizeIn, &buf, &size) == FALSE) { return FALSE; } status = CodeSetOldUtf16leToCurrent(buf, size, bufOut, sizeOut); free(buf); return status; #else #error #endif } /* *----------------------------------------------------------------------------- * * CodeSetOld_CurrentToUtf8 -- * * Convert the content of a buffer (that uses the current encoding) into * another buffer (that uses the UTF-8 encoding) --hpreg * * Results: * TRUE on success: '*bufOut' contains the allocated, NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSetOld_CurrentToUtf8(char const *bufIn, // IN: size_t sizeIn, // IN: char **bufOut, // OUT: size_t *sizeOut) // OUT: { #if defined(CURRENT_IS_UTF8) return CodeSetOldDuplicateStr(bufIn, sizeIn, bufOut, sizeOut); #elif defined(USE_ICONV) DynBuf db; Bool ok; DynBuf_Init(&db); ok = CodeSetOld_GenericToGenericDb(CodeSetOld_GetCurrentCodeSet(), bufIn, sizeIn, "UTF-8", 0, &db); return CodeSetOldDynBufFinalize(ok, &db, bufOut, sizeOut); #elif defined(_WIN32) char *buf; size_t size; Bool status; if (CodeSetOld_CurrentToUtf16le(bufIn, sizeIn, &buf, &size) == FALSE) { return FALSE; } status = CodeSetOld_Utf16leToUtf8(buf, size, bufOut, sizeOut); free(buf); return status; #else #error #endif } /* *----------------------------------------------------------------------------- * * CodeSetOld_Utf16leToUtf8Db -- * * Append the content of a buffer (that uses the UTF-16LE encoding) to a * DynBuf (that uses the UTF-8 encoding). --hpreg * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSetOld_Utf16leToUtf8Db(char const *bufIn, // IN size_t sizeIn, // IN DynBuf *db) // IN { const uint16 *utf16In; size_t numCodeUnits; size_t codeUnitIndex; if (sizeIn % sizeof *utf16In != 0) { return FALSE; } utf16In = (const uint16 *)bufIn; numCodeUnits = sizeIn / 2; for (codeUnitIndex = 0; codeUnitIndex < numCodeUnits; codeUnitIndex++) { uint32 codePoint; uint8 *dbBytes; size_t size; size_t newSize; if (utf16In[codeUnitIndex] < 0xD800 || utf16In[codeUnitIndex] > 0xDFFF) { // Non-surrogate UTF-16 code units directly represent a code point. codePoint = utf16In[codeUnitIndex]; } else { static const uint32 SURROGATE_OFFSET = (0xD800 << 10UL) + 0xDC00 - 0x10000; uint16 surrogateLead = utf16In[codeUnitIndex]; uint16 surrogateTrail; // We need one more code unit for the trailing surrogate. codeUnitIndex++; if (codeUnitIndex == numCodeUnits) { return FALSE; } surrogateTrail = utf16In[codeUnitIndex]; // Ensure we have a lead surrogate followed by a trail surrogate. if (surrogateLead > 0xDBFF || surrogateTrail < 0xDC00 || surrogateTrail > 0xDFFF) { return FALSE; } /* * To get a code point between 0x10000 and 0x10FFFF (2^16 to * (2^21) - 1): * * 1) Ensure surrogateLead is in the range [0xD800, 0xDBFF] * * 2) Ensure surrogateTrail is in the range [0xDC00, 0xDFFF] * * 3) Mask off all but the low 10 bits of lead and shift that * left 10 bits: ((surrogateLead << 10) - (0xD800 << 10)) * -> result [0, 0xFFC00] * * 4) Add to that the low 10 bits of trail: (surrogateTrail - 0xDC00) * -> result [0, 0xFFFFF] * * 5) Add to that 0x10000: * -> result [0x10000, 0x10FFFF] */ codePoint = ((uint32)surrogateLead << 10UL) + (uint32)surrogateTrail - SURROGATE_OFFSET; ASSERT(codePoint >= 0x10000 && codePoint <= 0x10FFFF); } size = DynBuf_GetSize(db); newSize = size + 4; // We'll need at most 4 more bytes for this code point. if ((newSize < size) || // Prevent integer overflow (DynBuf_GetAllocatedSize(db) < newSize && DynBuf_Enlarge(db, newSize) == FALSE)) { return FALSE; } dbBytes = (uint8 *)DynBuf_Get(db) + size; // Convert the code point to UTF-8. if (codePoint <= 0x007F) { // U+0000 - U+007F: 1 byte of UTF-8. dbBytes[0] = codePoint; size += 1; } else if (codePoint <= 0x07FF) { // U+0080 - U+07FF: 2 bytes of UTF-8. dbBytes[0] = 0xC0 | (codePoint >> 6); dbBytes[1] = 0x80 | (codePoint & 0x3F); size += 2; } else if (codePoint <= 0xFFFF) { // U+0800 - U+FFFF: 3 bytes of UTF-8. dbBytes[0] = 0xE0 | (codePoint >> 12); dbBytes[1] = 0x80 | ((codePoint >> 6) & 0x3F); dbBytes[2] = 0x80 | (codePoint & 0x3F); size += 3; } else { /* * U+10000 - U+10FFFF: 4 bytes of UTF-8. * * See the surrogate pair handling block above for the math * that ensures we're in the range [0x10000, 0x10FFFF] here. */ ASSERT(codePoint <= 0x10FFFF); dbBytes[0] = 0xF0 | (codePoint >> 18); dbBytes[1] = 0x80 | ((codePoint >> 12) & 0x3F); dbBytes[2] = 0x80 | ((codePoint >> 6) & 0x3F); dbBytes[3] = 0x80 | (codePoint & 0x3F); size += 4; } DynBuf_SetSize(db, size); } return TRUE; } /* *----------------------------------------------------------------------------- * * CodeSetOld_Utf16leToUtf8 -- * * Convert the content of a buffer (that uses the UTF-16LE encoding) into * another buffer (that uses the UTF-8 encoding). --hpreg * * The operation is inversible (its inverse is CodeSetOld_Utf8ToUtf16le). * * Results: * TRUE on success: '*bufOut' contains the allocated, NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSetOld_Utf16leToUtf8(char const *bufIn, // IN: size_t sizeIn, // IN: char **bufOut, // OUT: size_t *sizeOut) // OUT: { DynBuf db; Bool ok; DynBuf_Init(&db); ok = CodeSetOld_Utf16leToUtf8Db(bufIn, sizeIn, &db); return CodeSetOldDynBufFinalize(ok, &db, bufOut, sizeOut); } /* *----------------------------------------------------------------------------- * * CodeSetOld_Utf8ToUtf16le -- * * Convert the content of a buffer (that uses the UTF-8 encoding) into * another buffer (that uses the UTF-16LE encoding). --hpreg * * The operation is inversible (its inverse is CodeSetOld_Utf16leToUtf8). * * Results: * TRUE on success: '*bufOut' contains the allocated, NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSetOld_Utf8ToUtf16le(char const *bufIn, // IN: size_t sizeIn, // IN: char **bufOut, // OUT: size_t *sizeOut) // OUT: { DynBuf db; Bool ok; DynBuf_Init(&db); ok = CodeSetOldUtf8ToUtf16leDb(bufIn, sizeIn, &db); return CodeSetOldDynBufFinalize(ok, &db, bufOut, sizeOut); } /* *----------------------------------------------------------------------------- * * CodeSetOld_Utf8FormDToUtf8FormC -- * * Convert the content of a buffer (that uses the UTF-8 encoding) * which is in normal form D (decomposed) into another buffer * (that uses the UTF-8 encoding) and is normalized as * precomposed (Normalization Form C). * * Results: * TRUE on success: '*bufOut' contains a NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * '*bufOut' contains the allocated, NUL terminated buffer. * *----------------------------------------------------------------------------- */ Bool CodeSetOld_Utf8FormDToUtf8FormC(char const *bufIn, // IN: size_t sizeIn, // IN: char **bufOut, // OUT: size_t *sizeOut) // OUT: { #if defined(__APPLE__) DynBuf db; Bool ok; DynBuf_Init(&db); ok = CodeSetOld_Utf8Normalize(bufIn, sizeIn, TRUE, &db); return CodeSetOldDynBufFinalize(ok, &db, bufOut, sizeOut); #else NOT_IMPLEMENTED(); #endif } /* *----------------------------------------------------------------------------- * * CodeSetOld_Utf8FormCToUtf8FormD -- * * Convert the content of a buffer (that uses the UTF-8 encoding) * which is in normal form C (precomposed) into another buffer * (that uses the UTF-8 encoding) and is normalized as * decomposed (Normalization Form D). * * Results: * TRUE on success: '*bufOut' contains a NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * '*bufOut' contains the allocated, NUL terminated buffer. * *----------------------------------------------------------------------------- */ Bool CodeSetOld_Utf8FormCToUtf8FormD(char const *bufIn, // IN: size_t sizeIn, // IN: char **bufOut, // OUT: size_t *sizeOut) // OUT: { #if defined(__APPLE__) DynBuf db; Bool ok; DynBuf_Init(&db); ok = CodeSetOld_Utf8Normalize(bufIn, sizeIn, FALSE, &db); return CodeSetOldDynBufFinalize(ok, &db, bufOut, sizeOut); #else NOT_IMPLEMENTED(); #endif } /* *----------------------------------------------------------------------------- * * CodeSetOld_CurrentToUtf16le -- * * Convert the content of a buffer (that uses the current encoding) into * another buffer (that uses the UTF-16LE encoding). * * Results: * TRUE on success: '*bufOut' contains the allocated, NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSetOld_CurrentToUtf16le(char const *bufIn, // IN: size_t sizeIn, // IN: char **bufOut, // OUT: size_t *sizeOut) // OUT: { DynBuf db; Bool ok; DynBuf_Init(&db); #if defined(CURRENT_IS_UTF8) ok = CodeSetOldUtf8ToUtf16leDb(bufIn, sizeIn, &db); #elif defined(USE_ICONV) ok = CodeSetOld_GenericToGenericDb(CodeSetOld_GetCurrentCodeSet(), bufIn, sizeIn, "UTF-16LE", 0, &db); #elif defined(_WIN32) /* XXX We should probably use CP_THREAD_ACP on Windows 2000/XP. */ ok = CodeSetOldGenericToUtf16leDb(CP_ACP, bufIn, sizeIn, &db); #else #error #endif return CodeSetOldDynBufFinalize(ok, &db, bufOut, sizeOut); } /* *----------------------------------------------------------------------------- * * CodeSetOld_Utf16leToCurrent -- * * Convert the content of a buffer (that uses the UTF-16 little endian * encoding) into another buffer (that uses the current encoding) * * Results: * TRUE on success: '*bufOut' contains the allocated, NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSetOld_Utf16leToCurrent(char const *bufIn, // IN: size_t sizeIn, // IN: char **bufOut, // OUT: size_t *sizeOut) // OUT: { #if defined(CURRENT_IS_UTF8) return CodeSetOld_Utf16leToUtf8(bufIn, sizeIn, bufOut, sizeOut); #elif defined(USE_ICONV) DynBuf db; Bool ok; DynBuf_Init(&db); ok = CodeSetOld_GenericToGenericDb("UTF-16LE", bufIn, sizeIn, CodeSetOld_GetCurrentCodeSet(), 0, &db); return CodeSetOldDynBufFinalize(ok, &db, bufOut, sizeOut); #elif defined(_WIN32) return CodeSetOldUtf16leToCurrent(bufIn, sizeIn, bufOut, sizeOut); #else #error #endif } /* *----------------------------------------------------------------------------- * * CodeSetOld_Utf16beToCurrent -- * * Convert the content of a buffer (that uses the UTF-16 big endian * encoding) into another buffer (that uses the current encoding) * * Results: * TRUE on success: '*bufOut' contains the allocated, NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSetOld_Utf16beToCurrent(char const *bufIn, // IN: size_t sizeIn, // IN: char **bufOut, // OUT: size_t *sizeOut) // OUT: { #if defined(CURRENT_IS_UTF8) Bool status; char *temp; if ((temp = malloc(sizeIn)) == NULL) { return FALSE; } ASSERT((sizeIn & 1) == 0); ASSERT((ssize_t) sizeIn >= 0); swab(bufIn, temp, sizeIn); status = CodeSetOld_Utf16leToUtf8(temp, sizeIn, bufOut, sizeOut); free(temp); return status; #elif defined(USE_ICONV) DynBuf db; Bool ok; DynBuf_Init(&db); ok = CodeSetOld_GenericToGenericDb("UTF-16BE", bufIn, sizeIn, CodeSetOld_GetCurrentCodeSet(), 0, &db); return CodeSetOldDynBufFinalize(ok, &db, bufOut, sizeOut); #elif defined(_WIN32) char c; char *bufIn_dup; int i; Bool status = FALSE; bufIn_dup = NULL; /* sizeIn must be even */ ASSERT((sizeIn & 1) == 0); /* Make a non-const copy */ bufIn_dup = malloc(sizeIn); if (bufIn_dup == NULL) { goto error; } memcpy(bufIn_dup, bufIn, sizeIn); /* Swap pairs of bytes */ for (i = 0; i < sizeIn; i += 2) { c = bufIn_dup[i]; bufIn_dup[i] = bufIn_dup[i + 1]; bufIn_dup[i + 1] = c; } status = CodeSetOldUtf16leToCurrent(bufIn_dup, sizeIn, bufOut, sizeOut); error: free(bufIn_dup); return status; #else #error #endif } /* *----------------------------------------------------------------------------- * * CodeSetOld_Utf16beToUtf8 -- * * Convert the content of a buffer (that uses the UTF-16BE encoding) into * another buffer (that uses the UTF-8 encoding). * * Results: * TRUE on success: '*bufOut' contains the allocated, NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSetOld_Utf16beToUtf8(char const *bufIn, // IN: size_t sizeIn, // IN: char **bufOut, // OUT: size_t *sizeOut) // OUT: { DynBuf db; Bool ok; DynBuf_Init(&db); ok = CodeSetOld_Utf16beToUtf8Db(bufIn, sizeIn, &db); return CodeSetOldDynBufFinalize(ok, &db, bufOut, sizeOut); } /* *----------------------------------------------------------------------------- * * CodeSetOld_Utf16beToUtf8Db -- * * Append the content of a buffer (that uses the UTF-16BE encoding) to a * DynBuf (that uses the UTF-8 encoding). * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSetOld_Utf16beToUtf8Db(char const *bufIn, // IN: size_t sizeIn, // IN: DynBuf *db) // IN: { int i; char *temp; Bool ret = FALSE; if ((temp = malloc(sizeIn)) == NULL) { return ret; } ASSERT((sizeIn & 1) == 0); ASSERT((ssize_t) sizeIn >= 0); for (i = 0; i < sizeIn; i += 2) { temp[i] = bufIn[i + 1]; temp[i + 1] = bufIn[i]; } ret = CodeSetOld_Utf16leToUtf8Db(temp, sizeIn, db); free(temp); return ret; } /* *----------------------------------------------------------------------------- * * CodeSet_AsciiToUtf8 -- * * Convert ASCII to UTF-8 * * Results: * On success, TRUE and conversion result in bufOut and sizeOut. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool CodeSetOld_AsciiToUtf8(const char *bufIn, // IN: size_t sizeIn, // IN: unsigned int flags, // IN: char **bufOut, // OUT: size_t *sizeOut) // OUT: { DynBuf db; Bool ok; DynBuf_Init(&db); ok = CodeSetOld_AsciiToUtf8Db(bufIn, sizeIn, flags, &db); return CodeSetOldDynBufFinalize(ok, &db, bufOut, sizeOut); } /* *----------------------------------------------------------------------------- * * CodeSet_AsciiToUtf8Db -- * * Convert ASCII to UTF-8 * * Results: * On success, TRUE and conversion result appended to db. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool CodeSetOld_AsciiToUtf8Db(char const *bufIn, // IN: size_t sizeIn, // IN: unsigned int flags, // IN: DynBuf *db) // OUT: { size_t oldSize = DynBuf_GetSize(db); size_t i; size_t last = 0; for (i = 0; i < sizeIn; i++) { if (UNLIKELY((unsigned char) bufIn[i] >= 0x80)) { if (flags == 0) { DynBuf_SetSize(db, oldSize); return FALSE; } DynBuf_Append(db, bufIn + last, i - last); if ((flags & CSGTG_TRANSLIT) != 0) { DynBuf_Append(db, "\xef\xbf\xbd", 3); } last = i + 1; } } DynBuf_Append(db, bufIn + last, i - last); return TRUE; } /* *----------------------------------------------------------------------------- * * CodeSet_Utf8ToAscii -- * * Convert UTF-8 to ASCII * * Results: * On success, TRUE and conversion result in bufOut and sizeOut. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool CodeSetOld_Utf8ToAscii(const char *bufIn, // IN: size_t sizeIn, // IN: unsigned int flags, // IN: char **bufOut, // OUT: size_t *sizeOut) // OUT: { DynBuf db; Bool ok; DynBuf_Init(&db); ok = CodeSetOld_Utf8ToAsciiDb(bufIn, sizeIn, flags, &db); return CodeSetOldDynBufFinalize(ok, &db, bufOut, sizeOut); } /* *----------------------------------------------------------------------------- * * CodeSet_Utf8ToAsciiDb -- * * Convert UTF-8 to ASCII * * Results: * On success, TRUE and conversion result appended to db. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool CodeSetOld_Utf8ToAsciiDb(char const *bufIn, // IN: size_t sizeIn, // IN: unsigned int flags, // IN: DynBuf *db) // OUT: { size_t oldSize = DynBuf_GetSize(db); uint8 *p = (uint8 *) bufIn; uint8 *end = (uint8 *) bufIn + sizeIn; uint8 *last = p; for (; p < end; p++) { if (UNLIKELY(*p >= 0x80)) { int n; if (flags == 0) { DynBuf_SetSize(db, oldSize); return FALSE; } DynBuf_Append(db, last, p - last); if ((flags & CSGTG_TRANSLIT) != 0) { DynBuf_Append(db, "\x1a", 1); } if ((n = CodeSet_GetUtf8((char *) p, (char *) end, NULL)) > 0) { p += n - 1; } last = p + 1; } } DynBuf_Append(db, last, p - last); return TRUE; } #ifndef USE_ICONV /* *----------------------------------------------------------------------------- * * CodeSetOldIso88591ToUtf8Db -- * * Convert ISO-8859-1 to UTF-8 * * Results: * On success, TRUE and conversion result appended to db. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool CodeSetOldIso88591ToUtf8Db(char const *bufIn, // IN: size_t sizeIn, // IN: unsigned int flags, // IN: DynBuf *db) // OUT: { size_t i; size_t last = 0; for (i = 0; i < sizeIn; i++) { unsigned int c = (unsigned char)bufIn[i]; if (UNLIKELY(c >= 0x80)) { unsigned char buf[2]; buf[0] = 0xC0 | (c >> 6); buf[1] = 0x80 | (c & 0x3F); DynBuf_Append(db, bufIn + last, i - last); DynBuf_Append(db, buf, sizeof buf); last = i + 1; } } DynBuf_Append(db, bufIn + last, i - last); return TRUE; } #endif #if defined(_WIN32) /* *----------------------------------------------------------------------------- * * GetInvalidCharsFlag -- * * The flag MB_ERR_INVALID_CHARS can only be passed to MultiByteToWideChar * on Win2000 SP4 or later. If it's passed to an NT or 9x system, * MultiByteToWideChar fails with ERR_INVALID_FLAGS. * * Results: * returns MB_ERR_INVALID_CHARS if this flag is supported under current OS * returns zero if the flag would case MultiByteToWideChar failure. * * Side effects: * none * *----------------------------------------------------------------------------- */ static DWORD GetInvalidCharsFlag(void) { static volatile Bool bFirstCall = TRUE; static DWORD retval; OSVERSIONINFOEX osvi; BOOL bOsVersionInfoEx; if (!bFirstCall) { // We can return a cached result for subsequent calls return retval; } /* * Try calling GetVersionEx using the OSVERSIONINFOEX structure. */ ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); if(!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) &osvi))) { /* * If GetVersionEx failed, we are running something earlier than NT4+SP6, * thus we cannot use MB_ERR_INVALID_CHARS */ retval = 0; bFirstCall = FALSE; return retval; } if (osvi.dwMajorVersion > 5) { retval = MB_ERR_INVALID_CHARS; // Vista or later } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion > 0) { retval = MB_ERR_INVALID_CHARS; // XP, 2003 } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 && osvi.wServicePackMajor >= 4) { // Win2000 + SP4 retval = MB_ERR_INVALID_CHARS; } else { retval = 0; // Do not use MB_ERR_INVALID_CHARS on this OS. } bFirstCall = FALSE; return retval; } #endif /* *----------------------------------------------------------------------------- * * CodeSetOld_IsEncodingSupported -- * * Not really from the old codeset file, but we need a non-ICU way * of doing this. Asking lib/unicode to cross-reference the * encoding name with its internal list is functionally equivalent * to what Unicode_IsEncodingSupported used to do (and still does * if no ICU support is built-in). * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSetOld_IsEncodingSupported(const char *name) // IN: { ASSERT(name); return (STRING_ENCODING_UNKNOWN != Unicode_EncodingNameToEnum(name)); } /* *----------------------------------------------------------------------------- * * CodeSetOld_Validate -- * * Validate a string in the given encoding. * * Results: * TRUE if string is valid, * FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSetOld_Validate(const char *buf, // IN: the string size_t size, // IN: length of string const char *code) // IN: encoding { DynBuf db; Bool ok; if (size == 0) { return TRUE; } DynBuf_Init(&db); ok = CodeSetOld_GenericToGenericDb(code, buf, size, "UTF-8", CSGTG_NORMAL, &db); DynBuf_Destroy(&db); return ok; } /* *----------------------------------------------------------------------------- * * CodeSetOld_Init -- * * No-op. * * Results: * TRUE. * * Side effects: * See above * *----------------------------------------------------------------------------- */ Bool CodeSetOld_Init(UNUSED_PARAM(const char *dataDir)) // IN: { return TRUE; } open-vm-tools-9.4.0-1280544/lib/misc/machineID.c0000644765153500003110000003554312220061556017137 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * machineID.c -- * * Obtain "universally unique" identification information. */ #include #include #include #include #include #include #include #if defined(_WIN32) // Windows #include #include #include #endif #include "vmware.h" #include "hostinfo.h" #include "util.h" #include "log.h" #include "str.h" #include "err.h" #include "vm_product.h" #include "vm_atomic.h" #define LOGLEVEL_MODULE main #include "loglevel_user.h" #if defined(_WIN32) // Windows /* *---------------------------------------------------------------------- * * FindWindowsAdapter -- * * Search the list of networking interfaces for an appropriate choice. * * A suitable adapter either must contain or must not contain a * (simple) pattern string as specified by the findPattern argument. * * Results: * IP_ADAPTER_INFO pointer or NULL if no suitable choice can be made. * * Side effects: * None. * *---------------------------------------------------------------------- */ static IP_ADAPTER_INFO * FindWindowsAdapter(IP_ADAPTER_INFO *head, // IN: char *pattern, // IN: Bool findPattern) // IN: { IP_ADAPTER_INFO *adapterInfo; IP_ADAPTER_INFO *adapterChoice = NULL; ASSERT(head); ASSERT(pattern); for (adapterInfo = head; adapterInfo; adapterInfo = adapterInfo->Next) { // Bias - only ethernet adapters; more likely to be local if (adapterInfo->AddressLength == 6) { Bool takeIt = FALSE; if ((adapterInfo->Description == NULL) || (*adapterInfo->Description == '\0')) { takeIt = TRUE; } else { char *p = strstr(adapterInfo->Description, pattern); if (((p != NULL) && findPattern) || ((p == NULL) && !findPattern)) { takeIt = TRUE; } } if (takeIt) { adapterChoice = adapterInfo; break; } } } return adapterChoice; } /* *---------------------------------------------------------------------- * * ObtainHardwareID -- * * Locate and return the hardwareID for this machine. * * Results: * 0 No errors occured * >0 failure (errno) * * Side effects: * None. * * Note: * Return the MAC address of a suitable networking interface. * The hardwareID will be zero if nothing suitable could be found. * *---------------------------------------------------------------------- */ static int ObtainHardwareID(uint64 *hardwareID) // OUT: { void *buf; DWORD status; HMODULE dllHandle; IP_ADAPTER_INFO *adapterList; IP_ADAPTER_INFO *adapterChoice; DWORD (WINAPI *getAdaptersFn)(IP_ADAPTER_INFO *, ULONG *); ULONG bufLen = 0; // Deal with BUG 21643 dllHandle = LoadLibrary(TEXT("icmp.dll")); FreeLibrary(dllHandle); if (!dllHandle) { Warning("%s Failed to load icmp.dll.\n", __FUNCTION__); return EINVAL; } dllHandle = LoadLibrary(TEXT("IpHlpApi.dll")); if (!dllHandle) { Warning("%s Failed to load iphlpapi.dll.\n", __FUNCTION__); return EINVAL; } getAdaptersFn = (void *) GetProcAddress(dllHandle, "GetAdaptersInfo"); if (!getAdaptersFn) { FreeLibrary(dllHandle); Warning("%s Failed to find GetAdaptersInfo.\n", __FUNCTION__); return EINVAL; } // Force GetAdaptersInfo to provide the amount of memory necessary. status = (*getAdaptersFn)(NULL, &bufLen); switch (status) { case ERROR_NOT_SUPPORTED: Warning("%s GetAdaptersInfo is not supported.\n", __FUNCTION__); // fall through case ERROR_NO_DATA: FreeLibrary(dllHandle); *hardwareID = 0; return 0; break; case ERROR_BUFFER_OVERFLOW: case NO_ERROR: break; default: FreeLibrary(dllHandle); Warning("%s GetAdaptersInfo failure %d: %d.\n", __FUNCTION__, __LINE__, status); return EINVAL; } buf = malloc(bufLen); if (buf == NULL) { FreeLibrary(dllHandle); return ENOMEM; } adapterList = (IP_ADAPTER_INFO *) buf; status = (*getAdaptersFn)(adapterList, &bufLen); FreeLibrary(dllHandle); if (status != NO_ERROR) { // something is seriously wrong; worked before... Warning("%s GetAdaptersInfo failure %d: %d.\n", __FUNCTION__, __LINE__, status); free(buf); return EINVAL; } // Try to find real hardware. adapterChoice = FindWindowsAdapter(adapterList, PRODUCT_GENERIC_NAME, FALSE); if (adapterChoice == NULL) { *hardwareID = 0; } else { union bytes { uint64 data; char bytes[8]; } x; x.bytes[0] = adapterChoice->Address[0]; x.bytes[1] = adapterChoice->Address[1]; x.bytes[2] = adapterChoice->Address[2]; x.bytes[3] = adapterChoice->Address[3]; x.bytes[4] = adapterChoice->Address[4]; x.bytes[5] = adapterChoice->Address[5]; x.bytes[6] = '\0'; x.bytes[7] = '\0'; *hardwareID = x.data; } free(buf); return 0; } #elif defined(__APPLE__) // MacOS X #include #include #include #include /* *---------------------------------------------------------------------- * * CheckEthernet -- * * Determine if "en" exists and, if so, return its MAC address. * * Results: * NULL interface doesn't exist or isn't usable * !NULL interface exists and is usable * * Side effects: * None. * *---------------------------------------------------------------------- */ static struct ifaddrs * CheckEthernet(struct ifaddrs *ifp, // IN: uint32 n) // IN: { struct ifaddrs *p; char name[8]; // Construct the interface name Str_Sprintf(name, sizeof name, "en%u", n); // Go through the list and see if this interface exists and is usable. p = ifp; while (p != NULL) { if ((strcmp(p->ifa_name, name) == 0) && (p->ifa_addr != NULL) && (p->ifa_addr->sa_family == AF_LINK)) { break; } p = p->ifa_next; } return p; } /* *---------------------------------------------------------------------- * * ObtainHardwareID -- * * Locate and return the hardwareID for this machine. * * Results: * 0 No errors occured * >0 failure (errno) * * Side effects: * None. * * Note: * Return the MAC address of a suitable networking interface. * The hardwareID will be zero if nothing suitable could be found. * *---------------------------------------------------------------------- */ static int ObtainHardwareID(uint64 *hardwareID) // OUT: { uint32 i; struct ifaddrs *p; struct ifaddrs *ifp; // Attempt to get the list of networking interfaces if (getifaddrs(&ifp) == -1) { int saveErrno = errno; Warning("%s getifaddrs failure: %s.\n", __FUNCTION__, Err_Errno2String(saveErrno)); return saveErrno; } // search through a "reasonable" number of interfaces for (i = 0, *hardwareID = 0; i < 8; i++) { p = CheckEthernet(ifp, i); if (p != NULL) { memcpy(hardwareID, LLADDR((struct sockaddr_dl *)p->ifa_addr), ETHER_ADDR_LEN); break; } } freeifaddrs(ifp); return 0; } #elif defined(linux) || defined __ANDROID__ #include #include #include #include #if defined __ANDROID__ #include // For SOCK_DGRAM etc. #endif /* *---------------------------------------------------------------------- * * CheckEthernet -- * * Determine if "eth" exists and, if so, return its MAC address * * Results: * 0 No errors occured * >0 failure (errno) * * Side effects: * None. * *---------------------------------------------------------------------- */ static int CheckEthernet(uint32 n, // IN: char *machineID) // OUT: { int fd; int erc; struct ifreq ifreq; int saveErrno; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd == -1) { return errno; } /* get the MAC address of eth */ Str_Sprintf(ifreq.ifr_name, IFNAMSIZ, "eth%u", n); erc = ioctl(fd, SIOCGIFHWADDR, &ifreq); saveErrno = errno; close(fd); if (erc == -1) { return saveErrno; } machineID[0] = ifreq.ifr_hwaddr.sa_data[0] & 0xFF; machineID[1] = ifreq.ifr_hwaddr.sa_data[1] & 0xFF; machineID[2] = ifreq.ifr_hwaddr.sa_data[2] & 0xFF; machineID[3] = ifreq.ifr_hwaddr.sa_data[3] & 0xFF; machineID[4] = ifreq.ifr_hwaddr.sa_data[4] & 0xFF; machineID[5] = ifreq.ifr_hwaddr.sa_data[5] & 0xFF; machineID[6] = '\0'; machineID[7] = '\0'; return 0; } /* *---------------------------------------------------------------------- * * ObtainHardwareID -- * * Locate the hardwareID for this machine. * * Results: * 0 No errors occured * >0 failure (errno) * * Side effects: * None. * * Note: * Return the MAC address of a suitable networking interface. * The hardwareID will be zero if nothing suitable could be found. * * This is a "good enough" initial hack but will need to be revisited. * Ideally checks should be made for sysfs (Linux 2.6 and later) and, * if present, search through the information and try to insure that * the ethernet chosen is on the motherboard. * *---------------------------------------------------------------------- */ static int ObtainHardwareID(uint64 *hardwareID) // OUT: { uint32 i; // search through a "reasonable" number of interfaces for (i = 0; i < 8; i++) { int erc; erc = CheckEthernet(i, (char *) hardwareID); if (erc == 0) { return 0; } else { if (erc != ENODEV) { Warning("%s unexpected failure: %d.\n", __FUNCTION__, erc); return erc; } } } *hardwareID = 0; return 0; } #else // Not a specifically code OS #include /* *---------------------------------------------------------------------- * * ObtainHardwareID -- * * Locate the hardwareID for this machine. * * Results: * 0 No errors occured * >0 failure (errno) * * Side effects: * None. * * Note: * This is a dummy to catch an uncoded OS. *---------------------------------------------------------------------- */ static int ObtainHardwareID(uint64 *hardwareID) // OUT: { *hardwareID = gethostid(); return 0; } #endif // Not a specifically code OS /* *---------------------------------------------------------------------- * * HostNameHash -- * * Return the hash value of a string. * * Results: * The hash value of the string. * * Side effects: * None. * * Note: * This uses the DBJ2 hash algorithm. * *---------------------------------------------------------------------- */ static uint32 HostNameHash(unsigned char *str) // IN: { uint32 c; uint32 hash = 5381; while ((c = *str++) != '\0') { hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ } return hash; } /* *---------------------------------------------------------------------- * * Hostinfo_MachineID -- * * Return the machine ID information. * * There are two pieces of identification returned: a hash of the * hostname and and a hardware identifier. If either of them is * unavailable they will be given a value of zero. * * The hardware identifier should be extracted from a piece of hardware * that has individual discrimination - each "part" is uniquely labelled. * The MAC address of an ethernet and the WWN of a FibreChannel HBA are * perfect examples. * * Results: * The values are returned. * * Side effects: * The hardware identifier should persistent across system reboots and * resets as long of the hardware is available. * * Currently the Windows implementation is used only for file locking - * not system identification - so any acceptable piece of hardware * may be used, even if it changes during a reboot. * *---------------------------------------------------------------------- */ void Hostinfo_MachineID(uint32 *hostNameHash, // OUT: uint64 *hostHardwareID) // OUT: { static Atomic_Ptr cachedHardwareID; static Atomic_Ptr cachedHostNameHash; uint64 *tmpHardwareID; uint32 *tmpNameHash; ASSERT(hostNameHash); ASSERT(hostHardwareID); tmpNameHash = Atomic_ReadPtr(&cachedHostNameHash); if (!tmpNameHash) { char *hostName; tmpNameHash = Util_SafeMalloc(sizeof *tmpNameHash); // 4 bytes (32 bits) of host name information hostName = (char *) Hostinfo_HostName(); if (hostName == NULL) { Warning("%s Hostinfo_HostName failure; providing default.\n", __FUNCTION__); *tmpNameHash = 0; } else { *tmpNameHash = HostNameHash((unsigned char *) hostName); free(hostName); } if (Atomic_ReadIfEqualWritePtr(&cachedHostNameHash, NULL, tmpNameHash)) { free(tmpNameHash); tmpNameHash = Atomic_ReadPtr(&cachedHostNameHash); } } *hostNameHash = *tmpNameHash; tmpHardwareID = Atomic_ReadPtr(&cachedHardwareID); if (!tmpHardwareID) { int erc; tmpHardwareID = Util_SafeMalloc(sizeof *tmpHardwareID); // 8 bytes (64 bits) of hardware information erc = ObtainHardwareID(tmpHardwareID); if (erc != 0) { Warning("%s ObtainHardwareID failure (%s); providing default.\n", __FUNCTION__, Err_Errno2String(erc)); *tmpHardwareID = 0; } if (Atomic_ReadIfEqualWritePtr(&cachedHardwareID, NULL, tmpHardwareID)) { free(tmpHardwareID); tmpHardwareID = Atomic_ReadPtr(&cachedHardwareID); } } *hostHardwareID = *tmpHardwareID; } open-vm-tools-9.4.0-1280544/lib/misc/vmstdio.c0000644765153500003110000001664212220061556017002 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vmstdio.c -- * * Functions that operate on FILE objects --hpreg */ #include #include #include #include "vmware.h" #include "dynbuf.h" #include "vmstdio.h" /* *----------------------------------------------------------------------------- * * SuperFgets -- * * The fgets() API is poorly designed: it doesn't return how many bytes * were written to the buffer. Hence this function --hpreg * * In addition, this function recognizes three variants of end-of-line * markers regardless of the platform: \n, \r\n and \r. The exception * is that on Windows, \r\n is recognized only if the file is opened * in text mode. In binary mode, the \r and \n are interpreted as two * separate end-of-line markers. * * As input, *count is the size of bufIn. * * Results: * It returns bufIn on success and NULL on error. The line terminator * and NUL terminator are not stored in bufIn. On success, '*count' is * the number of bytes written to the buffer. * * Side effects: * If the line read is terminated by a standalone '\r' (legacy Mac), the * next character is pushed back using ungetc. Thus, that character may * be lost if the caller performs any write operation on the stream * (including fseek, fflush, etc.) subsequently without an intervening * read operation. * *----------------------------------------------------------------------------- */ static void * SuperFgets(FILE *stream, // IN: size_t *count, // IN/OUT: void *bufIn) // OUT: { char *buf = (char *)bufIn; size_t size = 0; ASSERT(stream); ASSERT(buf); ASSERT(count); ASSERT(*count); /* * Keep reading until a line terminator is found or *count is reached. * The line terminator itself is not written into the buffer. * Clear errno so that we can distinguish between end-of-file and error. */ errno = 0; for (size = 0; size < *count; size++) { int c; c = getc(stream); if (c == EOF) { if (errno) { /* getc returned an error. */ return NULL; } else { /* Found an end-of-file line terminator. */ break; } } if (c == '\n') { /* Found a Unix line terminator */ break; } if (c == '\r') { #ifndef _WIN32 /* * Look ahead to see if it is a \r\n line terminator. * On Windows platform, getc() returns one '\n' for a \r\n two-byte * sequence (for files opened in text mode), so we can skip the * look-ahead. */ c = getc(stream); if (c != EOF && c != '\n') { /* Found a legacy Mac line terminator */ if (ungetc(c, stream) == EOF) { return NULL; } } /* Forget that we peeked. */ clearerr(stream); #endif break; } buf[size] = c; } *count = size; return buf; } /* *----------------------------------------------------------------------------- * * StdIO_ReadNextLine -- * * Read the next line from a stream. * * A line is defined as an arbitrary long sequence of arbitrary bytes, * that ends with the first occurrence of one of these line terminators: * . \r\n (the ANSI way, in text mode) * . \n (the UNIX way) * . \r (the Legacy Mac (pre-OS X) way) * . end-of-stream * * Note that on Windows, getc() returns one '\n' for a \r\n two-byte * sequence only if the file is opened in text mode. Therefore \r\r\n * will be interpreted as two newlines in text mode ('\r' followed by * '\r\n'), but three newlines in binary mode ('\r', '\r', '\n'). * * If maxBufLength is non-zero at most maxBufLength bytes will be * allocated. * * Results: * StdIO_Success on success: '*buf' is an allocated, NUL terminated buffer * that contains the line (excluding the line * terminator). If not NULL, '*count' contains * the size of the buffer (excluding the NUL * terminator) * StdIO_EOF if there is no next line (end of stream) * StdIO_Error on failure: errno is set accordingly * * Side effects: * If the line read is terminated by a standalone '\r' (legacy Mac), the * next character is pushed back using ungetc. Thus, that character may * be lost if the caller performs any write operation on the stream * (including fseek, fflush, etc.) subsequently without an intervening * read operation. * *----------------------------------------------------------------------------- */ StdIO_Status StdIO_ReadNextLine(FILE *stream, // IN: char **buf, // OUT: size_t maxBufLength, // IN: size_t *count) // OUT: { DynBuf b; ASSERT(stream); ASSERT(buf); DynBuf_Init(&b); for (;;) { char *data; size_t size; size_t max; size_t nr; /* * The dynamic buffer must be at least 2 bytes large, so that at least * 1 stream byte and fgets()'s NUL byte can fit --hpreg */ if (DynBuf_Enlarge(&b, 2) == FALSE) { errno = ENOMEM; goto error; } /* Read the next chunk of line directly in the dynamic buffer --hpreg */ data = DynBuf_Get(&b); size = DynBuf_GetSize(&b); if (maxBufLength != 0 && size > maxBufLength) { errno = E2BIG; goto error; } max = DynBuf_GetAllocatedSize(&b); nr = max - size; if (SuperFgets(stream, &nr, data + size) == NULL) { goto error; } size += nr; DynBuf_SetSize(&b, size); if (size < max) { /* SuperFgets() found end-of-line */ if (size == 0 && feof(stream)) { /* Reached end-of-file before reading anything */ DynBuf_Destroy(&b); return StdIO_EOF; } break; } /* * No line terminator found yet, we need a larger buffer to do the next * SuperFgets() --hpreg */ } /* There is a line in the buffer --hpreg */ /* NUL terminator --hpreg */ if (DynBuf_Append(&b, "", 1) == FALSE) { errno = ENOMEM; goto error; } *buf = DynBuf_Get(&b); if (count) { *count = DynBuf_GetSize(&b) - 1; } return StdIO_Success; error: DynBuf_Destroy(&b); return StdIO_Error; } open-vm-tools-9.4.0-1280544/lib/misc/hostinfoPosix.c0000644765153500003110000027661612220061556020202 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(sun) #include #endif #include #if defined(__FreeBSD__) || defined(__APPLE__) # include #endif #if !defined(__APPLE__) #define TARGET_OS_IPHONE 0 #endif #if defined(__APPLE__) #include #include #if !TARGET_OS_IPHONE #include #endif #include #include #include #include #include #include #include #if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 // Must run on Mac OS versions < 10.7 # include #endif #elif defined(__FreeBSD__) #if !defined(RLIMIT_AS) # if defined(RLIMIT_VMEM) # define RLIMIT_AS RLIMIT_VMEM # else # define RLIMIT_AS RLIMIT_RSS # endif #endif #else #if !defined(USING_AUTOCONF) || defined(HAVE_SYS_VFS_H) #include #endif #if !defined(sun) && !defined __ANDROID__ && (!defined(USING_AUTOCONF) || (defined(HAVE_SYS_IO_H) && defined(HAVE_SYS_SYSINFO_H))) #include #include #ifndef HAVE_SYSINFO #define HAVE_SYSINFO 1 #endif #endif #endif #if defined(__APPLE__) || defined(__FreeBSD__) #include #endif #ifdef __linux__ #include #endif #if !defined(_PATH_DEVNULL) #define _PATH_DEVNULL "/dev/null" #endif #include "vmware.h" #include "hostType.h" #include "hostinfo.h" #include "hostinfoInt.h" #include "safetime.h" #include "vm_version.h" #include "str.h" #include "err.h" #include "msg.h" #include "log.h" #include "posix.h" #include "file.h" #include "backdoor_def.h" #include "util.h" #include "vmstdio.h" #include "su.h" #include "vm_atomic.h" #if defined(__i386__) || defined(__x86_64__) #include "x86cpuid.h" #endif #include "unicode.h" #include "guest_os.h" #include "dynbuf.h" #include "strutil.h" #if defined(VMX86_SERVER) #include "uwvmkAPI.h" #include "uwvmk.h" #include "vmkSyscall.h" #endif #define LGPFX "HOSTINFO:" #define MAX_LINE_LEN 128 #define SYSTEM_BITNESS_32 "i386" #define SYSTEM_BITNESS_64_SUN "amd64" #define SYSTEM_BITNESS_64_LINUX "x86_64" #define SYSTEM_BITNESS_MAXLEN \ MAX(sizeof SYSTEM_BITNESS_32, \ MAX(sizeof SYSTEM_BITNESS_64_SUN, \ sizeof SYSTEM_BITNESS_64_LINUX)) struct hostinfoOSVersion { int hostinfoOSVersion[4]; char *hostinfoOSVersionString; }; static Atomic_Ptr hostinfoOSVersion; #define DISTRO_BUF_SIZE 255 typedef struct lsb_distro_info { char *name; char *scanstring; } LSBDistroInfo; static const LSBDistroInfo lsbFields[] = { {"DISTRIB_ID=", "DISTRIB_ID=%s"}, {"DISTRIB_RELEASE=", "DISTRIB_RELEASE=%s"}, {"DISTRIB_CODENAME=", "DISTRIB_CODENAME=%s"}, {"DISTRIB_DESCRIPTION=", "DISTRIB_DESCRIPTION=%s"}, {NULL, NULL}, }; typedef struct distro_info { char *name; char *filename; } DistroInfo; static const DistroInfo distroArray[] = { {"OracleLinux", "/etc/oracle-release"}, {"RedHat", "/etc/redhat-release"}, {"RedHat", "/etc/redhat_version"}, {"Sun", "/etc/sun-release"}, {"SuSE", "/etc/SuSE-release"}, {"SuSE", "/etc/novell-release"}, {"SuSE", "/etc/sles-release"}, {"Debian", "/etc/debian_version"}, {"Debian", "/etc/debian_release"}, {"Mandrake", "/etc/mandrake-release"}, {"Mandriva", "/etc/mandriva-release"}, {"Mandrake", "/etc/mandrakelinux-release"}, {"TurboLinux", "/etc/turbolinux-release"}, {"Fedora Core", "/etc/fedora-release"}, {"Gentoo", "/etc/gentoo-release"}, {"Novell", "/etc/nld-release"}, {"Ubuntu", "/etc/lsb-release"}, {"Annvix", "/etc/annvix-release"}, {"Arch", "/etc/arch-release"}, {"Arklinux", "/etc/arklinux-release"}, {"Aurox", "/etc/aurox-release"}, {"BlackCat", "/etc/blackcat-release"}, {"Cobalt", "/etc/cobalt-release"}, {"Conectiva", "/etc/conectiva-release"}, {"Immunix", "/etc/immunix-release"}, {"Knoppix", "/etc/knoppix_version"}, {"Linux-From-Scratch", "/etc/lfs-release"}, {"Linux-PPC", "/etc/linuxppc-release"}, {"MkLinux", "/etc/mklinux-release"}, {"PLD", "/etc/pld-release"}, {"Slackware", "/etc/slackware-version"}, {"Slackware", "/etc/slackware-release"}, {"SMEServer", "/etc/e-smith-release"}, {"Solaris", "/etc/release"}, {"Tiny Sofa", "/etc/tinysofa-release"}, {"UltraPenguin", "/etc/ultrapenguin-release"}, {"UnitedLinux", "/etc/UnitedLinux-release"}, {"VALinux", "/etc/va-release"}, {"Yellow Dog", "/etc/yellowdog-release"}, {NULL, NULL}, }; #if defined __ANDROID__ /* * Android doesn't support getloadavg() or iopl(). */ #define NO_GETLOADAVG #define NO_IOPL #endif /* *---------------------------------------------------------------------- * * HostinfoOSVersionInit -- * * Compute the OS version information * * Results: * None. * * Side effects: * hostinfoOS* variables are filled in. * *---------------------------------------------------------------------- */ static void HostinfoOSVersionInit(void) { struct hostinfoOSVersion *version; struct utsname u; char *extra; char *p; if (Atomic_ReadPtr(&hostinfoOSVersion)) { return; } if (uname(&u) < 0) { Warning("%s: unable to get host OS version (uname): %s\n", __FUNCTION__, Err_Errno2String(errno)); NOT_IMPLEMENTED(); } version = Util_SafeCalloc(1, sizeof *version); version->hostinfoOSVersionString = Util_SafeStrndup(u.release, sizeof u.release); ASSERT(ARRAYSIZE(version->hostinfoOSVersion) >= 4); /* * The first three numbers are separated by '.', if there is * a fourth number, it's probably separated by '.' or '-', * but it could be preceded by anything. */ extra = Util_SafeCalloc(1, sizeof u.release); if (sscanf(u.release, "%d.%d.%d%s", &version->hostinfoOSVersion[0], &version->hostinfoOSVersion[1], &version->hostinfoOSVersion[2], extra) < 1) { Warning("%s: unable to parse host OS version string: %s\n", __FUNCTION__, u.release); NOT_IMPLEMENTED(); } /* * If there is a 4th number, use it, otherwise use 0. * Explicitly skip over any non-digits, including '-' */ p = extra; while (*p && !isdigit(*p)) { p++; } sscanf(p, "%d", &version->hostinfoOSVersion[3]); free(extra); if (Atomic_ReadIfEqualWritePtr(&hostinfoOSVersion, NULL, version)) { free(version->hostinfoOSVersionString); free(version); } } /* *---------------------------------------------------------------------- * * Hostinfo_OSVersionString -- * * Returns the host version information as returned in the * release field of uname(2) * * Results: * const char * - pointer to static buffer containing the release * * Side effects: * None * *---------------------------------------------------------------------- */ const char * Hostinfo_OSVersionString(void) { struct hostinfoOSVersion *version; HostinfoOSVersionInit(); version = Atomic_ReadPtr(&hostinfoOSVersion); return version->hostinfoOSVersionString; } /* *---------------------------------------------------------------------- * * Hostinfo_OSVersion -- * * Host OS release info. * * Results: * The i-th component of a dotted release string. * 0 if i is greater than the number of components we support. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Hostinfo_OSVersion(unsigned int i) // IN: { struct hostinfoOSVersion *version; HostinfoOSVersionInit(); version = Atomic_ReadPtr(&hostinfoOSVersion); return (i < ARRAYSIZE(version->hostinfoOSVersion)) ? version->hostinfoOSVersion[i] : 0; } /* *---------------------------------------------------------------------- * * Hostinfo_GetTimeOfDay -- * * Return the current time of day according to the host. We want * UTC time (seconds since Jan 1, 1970). * * Results: * Time of day in microseconds. * * Side effects: * None. * *---------------------------------------------------------------------- */ void Hostinfo_GetTimeOfDay(VmTimeType *time) // OUT: { struct timeval tv; gettimeofday(&tv, NULL); *time = ((int64)tv.tv_sec * 1000000) + tv.tv_usec; } /* *---------------------------------------------------------------------------- * * Hostinfo_GetSystemBitness -- * * Determines the operating system's bitness. * * Return value: * 32 or 64 on success. * -1 on failure. Check errno for more details of error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int Hostinfo_GetSystemBitness(void) { #if defined __linux__ struct utsname u; if (uname(&u) < 0) { return -1; } if (strstr(u.machine, SYSTEM_BITNESS_64_LINUX)) { return 64; } else { return 32; } #else char buf[SYSTEM_BITNESS_MAXLEN] = { '\0', }; # if defined __FreeBSD__ || defined __APPLE__ static int mib[2] = { CTL_HW, HW_MACHINE, }; size_t len = sizeof buf; if (sysctl(mib, ARRAYSIZE(mib), buf, &len, NULL, 0) == -1) { return -1; } # elif defined sun # if !defined SOL10 /* * XXX: This is bad. We define SI_ARCHITECTURE_K to what it is on Solaris * 10 so that we can use a single guestd build for Solaris 9 and 10. In the * future we should have the Solaris 9 build just return 32 -- since it did * not support 64-bit x86 -- and let the Solaris 10 headers define * SI_ARCHITECTURE_K, then have the installer symlink to the correct binary. * For now, though, we'll share a single build for both versions. */ # define SI_ARCHITECTURE_K 518 # endif if (sysinfo(SI_ARCHITECTURE_K, buf, sizeof buf) < 0) { return -1; } # endif if (strcmp(buf, SYSTEM_BITNESS_32) == 0) { return 32; } else if (strcmp(buf, SYSTEM_BITNESS_64_SUN) == 0 || strcmp(buf, SYSTEM_BITNESS_64_LINUX) == 0) { return 64; } return -1; #endif } #if !defined __APPLE__ /* *----------------------------------------------------------------------------- * * HostinfoGetOSShortName -- * * Returns distro information based on .vmx format (distroShort). * * Return value: * Overwrited the short name if we recognise the OS. * Otherwise leave the short name as it is. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HostinfoGetOSShortName(char *distro, // IN: full distro name char *distroShort, // OUT: short distro name int distroShortSize) // IN: size of short distro name { char *distroLower = NULL; /* Lower case distro name */ distroLower = calloc(strlen(distro) + 1, sizeof *distroLower); if (distroLower == NULL) { Warning("%s: could not allocate memory\n", __FUNCTION__); return; } Str_Strcpy(distroLower, distro, distroShortSize); distroLower = Str_ToLower(distroLower); if (strstr(distroLower, "red hat")) { if (strstr(distroLower, "enterprise")) { /* * Looking for "release x" here instead of "x" as there could be * build version which can be misleading. For example Red Hat * Enterprise Linux ES release 4 (Nahant Update 3) */ int release = 0; char *releaseStart = strstr(distroLower, "release"); if (releaseStart) { sscanf(releaseStart, "release %d", &release); if (release > 0) { snprintf(distroShort, distroShortSize, STR_OS_RED_HAT_EN"%d", release); } } if (release <= 0) { Warning("%s: could not read Red Hat Enterprise release version\n", __FUNCTION__); Str_Strcpy(distroShort, STR_OS_RED_HAT_EN, distroShortSize); } } else { Str_Strcpy(distroShort, STR_OS_RED_HAT, distroShortSize); } } else if (strstr(distroLower, "opensuse")) { Str_Strcpy(distroShort, STR_OS_OPENSUSE, distroShortSize); } else if (strstr(distroLower, "suse")) { if (strstr(distroLower, "enterprise")) { if (strstr(distroLower, "server 12") || strstr(distroLower, "desktop 12")) { Str_Strcpy(distroShort, STR_OS_SLES_12, distroShortSize); } else if (strstr(distroLower, "server 11") || strstr(distroLower, "desktop 11")) { Str_Strcpy(distroShort, STR_OS_SLES_11, distroShortSize); } else if (strstr(distroLower, "server 10") || strstr(distroLower, "desktop 10")) { Str_Strcpy(distroShort, STR_OS_SLES_10, distroShortSize); } else { Str_Strcpy(distroShort, STR_OS_SLES, distroShortSize); } } else if (strstr(distroLower, "sun")) { Str_Strcpy(distroShort, STR_OS_SUN_DESK, distroShortSize); } else if (strstr(distroLower, "novell")) { Str_Strcpy(distroShort, STR_OS_NOVELL, distroShortSize); } else { Str_Strcpy(distroShort, STR_OS_SUSE, distroShortSize); } } else if (strstr(distroLower, "mandrake")) { Str_Strcpy(distroShort, STR_OS_MANDRAKE, distroShortSize); } else if (strstr(distroLower, "turbolinux")) { Str_Strcpy(distroShort, STR_OS_TURBO, distroShortSize); } else if (strstr(distroLower, "sun")) { Str_Strcpy(distroShort, STR_OS_SUN_DESK, distroShortSize); } else if (strstr(distroLower, "annvix")) { Str_Strcpy(distroShort, STR_OS_ANNVIX, distroShortSize); } else if (strstr(distroLower, "arch")) { Str_Strcpy(distroShort, STR_OS_ARCH, distroShortSize); } else if (strstr(distroLower, "arklinux")) { Str_Strcpy(distroShort, STR_OS_ARKLINUX, distroShortSize); } else if (strstr(distroLower, "asianux server 3") || strstr(distroLower, "asianux client 3")) { Str_Strcpy(distroShort, STR_OS_ASIANUX_3, distroShortSize); } else if (strstr(distroLower, "asianux server 4") || strstr(distroLower, "asianux client 4")) { Str_Strcpy(distroShort, STR_OS_ASIANUX_4, distroShortSize); } else if (strstr(distroLower, "aurox")) { Str_Strcpy(distroShort, STR_OS_AUROX, distroShortSize); } else if (strstr(distroLower, "black cat")) { Str_Strcpy(distroShort, STR_OS_BLACKCAT, distroShortSize); } else if (strstr(distroLower, "cobalt")) { Str_Strcpy(distroShort, STR_OS_COBALT, distroShortSize); } else if (StrUtil_StartsWith(distroLower, "centos")) { Str_Strcpy(distroShort, STR_OS_CENTOS, distroShortSize); } else if (strstr(distroLower, "conectiva")) { Str_Strcpy(distroShort, STR_OS_CONECTIVA, distroShortSize); } else if (strstr(distroLower, "debian")) { if (strstr(distroLower, "4.0")) { Str_Strcpy(distroShort, STR_OS_DEBIAN_4, distroShortSize); } else if (strstr(distroLower, "5.0")) { Str_Strcpy(distroShort, STR_OS_DEBIAN_5, distroShortSize); } else if (strstr(distroLower, "6.0")) { Str_Strcpy(distroShort, STR_OS_DEBIAN_6, distroShortSize); } else if (strstr(distroLower, "7.0")) { Str_Strcpy(distroShort, STR_OS_DEBIAN_7, distroShortSize); } } else if (StrUtil_StartsWith(distroLower, "enterprise linux") || StrUtil_StartsWith(distroLower, "oracle")) { /* * [root@localhost ~]# lsb_release -sd * "Enterprise Linux Enterprise Linux Server release 5.4 (Carthage)" * * Not sure why they didn't brand their releases as "Oracle Enterprise * Linux". Oh well. It's fixed in 6.0, though. */ Str_Strcpy(distroShort, STR_OS_ORACLE, distroShortSize); } else if (strstr(distroLower, "fedora")) { Str_Strcpy(distroShort, STR_OS_FEDORA, distroShortSize); } else if (strstr(distroLower, "gentoo")) { Str_Strcpy(distroShort, STR_OS_GENTOO, distroShortSize); } else if (strstr(distroLower, "immunix")) { Str_Strcpy(distroShort, STR_OS_IMMUNIX, distroShortSize); } else if (strstr(distroLower, "linux-from-scratch")) { Str_Strcpy(distroShort, STR_OS_LINUX_FROM_SCRATCH, distroShortSize); } else if (strstr(distroLower, "linux-ppc")) { Str_Strcpy(distroShort, STR_OS_LINUX_PPC, distroShortSize); } else if (strstr(distroLower, "mandriva")) { Str_Strcpy(distroShort, STR_OS_MANDRIVA, distroShortSize); } else if (strstr(distroLower, "mklinux")) { Str_Strcpy(distroShort, STR_OS_MKLINUX, distroShortSize); } else if (strstr(distroLower, "pld")) { Str_Strcpy(distroShort, STR_OS_PLD, distroShortSize); } else if (strstr(distroLower, "slackware")) { Str_Strcpy(distroShort, STR_OS_SLACKWARE, distroShortSize); } else if (strstr(distroLower, "sme server")) { Str_Strcpy(distroShort, STR_OS_SMESERVER, distroShortSize); } else if (strstr(distroLower, "tiny sofa")) { Str_Strcpy(distroShort, STR_OS_TINYSOFA, distroShortSize); } else if (strstr(distroLower, "ubuntu")) { Str_Strcpy(distroShort, STR_OS_UBUNTU, distroShortSize); } else if (strstr(distroLower, "ultra penguin")) { Str_Strcpy(distroShort, STR_OS_ULTRAPENGUIN, distroShortSize); } else if (strstr(distroLower, "united linux")) { Str_Strcpy(distroShort, STR_OS_UNITEDLINUX, distroShortSize); } else if (strstr(distroLower, "va linux")) { Str_Strcpy(distroShort, STR_OS_VALINUX, distroShortSize); } else if (strstr(distroLower, "yellow dog")) { Str_Strcpy(distroShort, STR_OS_YELLOW_DOG, distroShortSize); } free(distroLower); } /* *----------------------------------------------------------------------------- * * HostinfoReadDistroFile -- * * Look for a distro version file /etc/xxx-release. * Once found, read the file in and figure out which distribution. * * Return value: * Returns TRUE on success and FALSE on failure. * Returns distro information verbatium from /etc/xxx-release (distro). * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool HostinfoReadDistroFile(char *filename, // IN: distro version file name int distroSize, // IN: size of OS distro name buffer char *distro) // OUT: full distro name { int fd = -1; int buf_sz; struct stat st; Bool ret = FALSE; char *distroOrig = NULL; char distroPart[DISTRO_BUF_SIZE]; char *tmpDistroPos = NULL; int i = 0; /* It's OK for the file to not exist, don't warn for this. */ if ((fd = Posix_Open(filename, O_RDONLY)) == -1) { return FALSE; } if (fstat(fd, &st)) { Warning("%s: could not stat the file %s: %d\n", __FUNCTION__, filename, errno); goto out; } if (st.st_size == 0) { Warning("%s: Cannot work with empty file.\n", __FUNCTION__); goto out; } buf_sz = st.st_size; if (buf_sz >= distroSize) { Warning("%s: input buffer too small\n", __FUNCTION__); goto out; } distroOrig = calloc(distroSize, sizeof *distroOrig); if (distroOrig == NULL) { Warning("%s: could not allocate memory\n", __FUNCTION__); goto out; } if (read(fd, distroOrig, buf_sz) != buf_sz) { Warning("%s: could not read file %s: %d\n", __FUNCTION__, filename, errno); goto out; } distroOrig[buf_sz - 1] = '\0'; /* * For the case where we do have a release file in the LSB format, * but there is no LSB module, let's parse the LSB file for possible fields. */ distro[0] = '\0'; for (i = 0; lsbFields[i].name != NULL; i++) { tmpDistroPos = strstr(distroOrig, lsbFields[i].name); if (tmpDistroPos) { sscanf(tmpDistroPos, lsbFields[i].scanstring, distroPart); if (distroPart[0] == '"') { char *tmpMakeNull = NULL; tmpDistroPos += strlen(lsbFields[i].name) + 1; tmpMakeNull = strchr(tmpDistroPos + 1 , '"'); if (tmpMakeNull) { *tmpMakeNull = '\0'; Str_Strcat(distro, tmpDistroPos, distroSize); *tmpMakeNull = '"' ; } } else { Str_Strcat(distro, distroPart, distroSize); } Str_Strcat(distro, " ", distroSize); } } if (distro[0] == '\0') { /* Copy original string. What we got wasn't LSB compliant. */ Str_Strcpy(distro, distroOrig, distroSize); } ret = TRUE; out: if (fd != -1) { close(fd); } free(distroOrig); return ret; } #endif /* *---------------------------------------------------------------------- * * HostinfoGetCmdOutput -- * * Run a cmd & get its cmd line output * * Results: * An allocated string or NULL if an error occurred. * * Side effects: * The cmd is run. * *---------------------------------------------------------------------- */ static char * HostinfoGetCmdOutput(const char *cmd) // IN: { DynBuf db; FILE *stream; char *out = NULL; DynBuf_Init(&db); stream = Posix_Popen(cmd, "r"); if (stream == NULL) { Warning("Unable to get output of command \"%s\"\n", cmd); return NULL; } for (;;) { char *line = NULL; size_t size; switch (StdIO_ReadNextLine(stream, &line, 0, &size)) { case StdIO_Error: goto closeIt; break; case StdIO_EOF: break; case StdIO_Success: break; default: ASSERT_NOT_IMPLEMENTED(FALSE); } if (line == NULL) { break; } /* size does -not- include the NUL terminator. */ DynBuf_Append(&db, line, size + 1); free(line); } if (DynBuf_Get(&db)) { out = (char *) DynBuf_AllocGet(&db); } closeIt: DynBuf_Destroy(&db); pclose(stream); return out; } /* *----------------------------------------------------------------------------- * * HostinfoOSData -- * * Determine the OS short (.vmx format) and long names. * * Return value: * Returns TRUE on success and FALSE on failure. * * Side effects: * Cache values are set when returning TRUE. * *----------------------------------------------------------------------------- */ Bool HostinfoOSData(void) { struct utsname buf; unsigned int lastCharPos; char osName[MAX_OS_NAME_LEN]; char osNameFull[MAX_OS_FULLNAME_LEN]; static Atomic_uint32 mutex = {0}; /* * Use uname to get complete OS information. */ if (uname(&buf) < 0) { Warning("%s: uname failed %d\n", __FUNCTION__, errno); return FALSE; } if (strlen(buf.sysname) + strlen(buf.release) + 3 > sizeof osNameFull) { Warning("%s: Error: buffer too small\n", __FUNCTION__); return FALSE; } Str_Strcpy(osName, STR_OS_EMPTY, sizeof osName); Str_Sprintf(osNameFull, sizeof osNameFull, "%s %s", buf.sysname, buf.release); #if defined __APPLE__ { /* * The easiest way is to invoke "system_profiler" and hope that the * format of its unlocalized output will never change. * * Alternatively, we could do what system_profiler does and use the * CFPropertyList/CFDIctionary APIs to parse * /System/Library/CoreServices/{Server,System}Version.plist. * * On a MacBookPro4,1 (and possibly other models), invoking * "system_profiler" can take several seconds: it seems to spin up the CD * drive as a side-effect. So use "system_profiler SPSoftwareDataType" * instead. */ char *sysname = HostinfoGetCmdOutput( "/usr/sbin/system_profiler SPSoftwareDataType" " | /usr/bin/grep 'System Version:'" " | /usr/bin/cut -d : -f 2"); if (sysname) { char *trimmed = Unicode_Trim(sysname); ASSERT_MEM_ALLOC(trimmed); free(sysname); Str_Snprintf(osNameFull, sizeof osNameFull, "%s", trimmed); free(trimmed); } else { Log("%s: Failed to get output of system_profiler.\n", __FUNCTION__); /* Fall back to returning the original osNameFull. */ } Str_Snprintf(osName, sizeof osName, "%s%d", STR_OS_MACOS, Hostinfo_OSVersion(0)); } #else // XXX Use compile-time instead of run-time checks for these as well. if (strstr(osNameFull, "Linux")) { char distro[DISTRO_BUF_SIZE]; char distroShort[DISTRO_BUF_SIZE]; static int const distroSize = sizeof distro; char *lsbOutput; int majorVersion; /* * Write default distro string depending on the kernel version. If * later we find more detailed information this will get overwritten. */ majorVersion = Hostinfo_OSVersion(0); if (majorVersion < 2 || (majorVersion == 2 && Hostinfo_OSVersion(1) < 4)) { Str_Strcpy(distro, STR_OS_OTHER_FULL, distroSize); Str_Strcpy(distroShort, STR_OS_OTHER, distroSize); } else if (majorVersion == 2 && Hostinfo_OSVersion(1) < 6) { Str_Strcpy(distro, STR_OS_OTHER_24_FULL, distroSize); Str_Strcpy(distroShort, STR_OS_OTHER_24, distroSize); } else if (majorVersion == 2) { Str_Strcpy(distro, STR_OS_OTHER_26_FULL, distroSize); Str_Strcpy(distroShort, STR_OS_OTHER_26, distroSize); } else { Str_Strcpy(distro, STR_OS_OTHER_3X_FULL, distroSize); Str_Strcpy(distroShort, STR_OS_OTHER_3X, distroSize); } /* * Try to get OS detailed information from the lsb_release command. */ lsbOutput = HostinfoGetCmdOutput("lsb_release -sd 2>/dev/null"); if (!lsbOutput) { int i; /* * Try to get more detailed information from the version file. */ for (i = 0; distroArray[i].filename != NULL; i++) { if (HostinfoReadDistroFile(distroArray[i].filename, distroSize, distro)) { break; } } /* * If we failed to read every distro file, exit now, before calling * strlen on the distro buffer (which wasn't set). */ if (distroArray[i].filename == NULL) { Warning("%s: Error: no distro file found\n", __FUNCTION__); return FALSE; } } else { char *lsbStart = lsbOutput; char *quoteEnd = NULL; if (lsbStart[0] == '"') { lsbStart++; quoteEnd = strchr(lsbStart, '"'); if (quoteEnd) { *quoteEnd = '\0'; } } Str_Strcpy(distro, lsbStart, distroSize); free(lsbOutput); } HostinfoGetOSShortName(distro, distroShort, distroSize); if (strlen(distro) + strlen(osNameFull) + 2 > sizeof osNameFull) { Warning("%s: Error: buffer too small\n", __FUNCTION__); return FALSE; } Str_Strcat(osNameFull, " ", sizeof osNameFull); Str_Strcat(osNameFull, distro, sizeof osNameFull); if (strlen(distroShort) + 1 > sizeof osName) { Warning("%s: Error: buffer too small\n", __FUNCTION__); return FALSE; } Str_Strcpy(osName, distroShort, sizeof osName); } else if (strstr(osNameFull, "FreeBSD")) { size_t nameLen = sizeof STR_OS_FREEBSD - 1; size_t releaseLen = 0; char *dashPtr; /* * FreeBSD releases report their version as "x.y-RELEASE". We'll be * naive look for the first dash, and use everything before it as the * version number. */ dashPtr = Str_Strchr(buf.release, '-'); if (dashPtr != NULL) { releaseLen = dashPtr - buf.release; } if (nameLen + releaseLen + 1 > sizeof osName) { Warning("%s: Error: buffer too small\n", __FUNCTION__); return FALSE; } Str_Strcpy(osName, STR_OS_FREEBSD, sizeof osName); } else if (strstr(osNameFull, "SunOS")) { size_t nameLen = sizeof STR_OS_SOLARIS - 1; size_t releaseLen = 0; char solarisRelease[3] = ""; /* * Solaris releases report their version as "x.y". For our supported * releases it seems that x is always "5", and is ignored in favor of * "y" for the version number. */ if (sscanf(buf.release, "5.%2[0-9]", solarisRelease) == 1) { releaseLen = strlen(solarisRelease); } if (nameLen + releaseLen + 1 > sizeof osName) { Warning("%s: Error: buffer too small\n", __FUNCTION__); return FALSE; } Str_Snprintf(osName, sizeof osName, "%s%s", STR_OS_SOLARIS, solarisRelease); } #endif if (Hostinfo_GetSystemBitness() == 64) { if (strlen(osName) + sizeof STR_OS_64BIT_SUFFIX > sizeof osName) { Warning("%s: Error: buffer too small\n", __FUNCTION__); return FALSE; } Str_Strcat(osName, STR_OS_64BIT_SUFFIX, sizeof osName); } /* * Before returning, truncate the \n character at the end of the full name. */ lastCharPos = strlen(osNameFull) - 1; if (osNameFull[lastCharPos] == '\n') { osNameFull[lastCharPos] = '\0'; } /* * Serialize access. Collisions should be rare - plus the value will * get cached and this won't get called anymore. */ while (Atomic_ReadWrite(&mutex, 1)); // Spinlock. if (!HostinfoOSNameCacheValid) { Str_Strcpy(HostinfoCachedOSName, osName, sizeof HostinfoCachedOSName); Str_Strcpy(HostinfoCachedOSFullName, osNameFull, sizeof HostinfoCachedOSFullName); HostinfoOSNameCacheValid = TRUE; } Atomic_Write(&mutex, 0); // unlock return TRUE; } /* *----------------------------------------------------------------------------- * * Hostinfo_CPUCounts -- * * Get a count of CPUs for the host. * pkgs := total number of sockets/packages * cores := total number of actual cores (not including hyperthreads) * logical := total schedulable threads, as seen by host scheduler * Depending on available host OS interfaces, these numbers may be * either "active" or "possible", so do not depend upon them for * precision. * * As an example, a 2 socket Nehalem (4 cores + HT) would return: * pkgs = 2, cores = 8, logical = 16 * * Again, this interface is generally not useful b/c of its potential * inaccuracy (especially with hotplug!) and because it is only implemented * for a few OSes. * * If you are trying to use this interface, it probably means you are doing * something 'clever' with licensing. Don't. * * Results: * TRUE if sane numbers are populated, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool Hostinfo_CPUCounts(uint32 *logical, // OUT uint32 *cores, // OUT uint32 *pkgs) // OUT { #if defined __APPLE__ /* * Lame logic. Because Apple doesn't really expose this info, * we'd only use it for licensing anyway, and we just plain * don't need it on Apple except that VMHS stuffs it somewhere * and may result in a division-by-zero if we don't provide it. */ *logical = Hostinfo_NumCPUs(); *pkgs = *logical > 4 ? 2 : 1; *cores = *logical / *pkgs; return TRUE; #elif defined __linux__ FILE *f; char *line; unsigned count = 0, coresPerProc = 0, siblingsPerProc = 0; f = Posix_Fopen("/proc/cpuinfo", "r"); if (f == NULL) { return FALSE; } while (StdIO_ReadNextLine(f, &line, 0, NULL) == StdIO_Success) { if (strncmp(line, "processor", strlen("processor")) == 0) { count++; } /* Assume all processors are identical, so just read the first. */ if (coresPerProc == 0) { sscanf(line, "cpu cores : %u", &coresPerProc); } if (siblingsPerProc == 0) { sscanf(line, "siblings : %u", &siblingsPerProc); } free(line); } fclose(f); *logical = count; *pkgs = siblingsPerProc > 0 ? count / siblingsPerProc : count; *cores = coresPerProc > 0 ? *pkgs * coresPerProc : *pkgs; Log(LGPFX" This machine has %u physical CPUS, %u total cores, and %u " "logical CPUs.\n", *pkgs, *cores, *logical); return TRUE; #else NOT_IMPLEMENTED(); #endif } /* *----------------------------------------------------------------------------- * * Hostinfo_NumCPUs -- * * Get the number of logical CPUs on the host. If the CPUs are * hyperthread-capable, this number may be larger than the number of * physical CPUs. For example, if the host has four hyperthreaded * physical CPUs with 2 logical CPUs apiece, this function returns 8. * * This function returns the number of CPUs that the host presents to * applications, which is what we want in the vast majority of cases. We * would only ever care about the number of physical CPUs for licensing * purposes. * * Results: * On success, the number of CPUs (> 0) the host tells us we have. * On failure, 0xFFFFFFFF (-1). * * Side effects: * None * *----------------------------------------------------------------------------- */ uint32 Hostinfo_NumCPUs(void) { #if defined(sun) static int count = 0; if (count <= 0) { count = sysconf(_SC_NPROCESSORS_CONF); } return count; #elif defined(__APPLE__) uint32 out; size_t outSize = sizeof out; /* * Quoting sys/sysctl.h: * " * These are the support HW selectors for sysctlbyname. Parameters that * are byte counts or frequencies are 64 bit numbers. All other parameters * are 32 bit numbers. * ... * hw.activecpu - The number of processors currently available for executing * threads. Use this number to determine the number threads * to create in SMP aware applications. This number can * change when power management modes are changed. * " * * Apparently the only way to retrieve this info is by name, and I have * verified the info changes when you dynamically switch a CPU * offline/online. --hpreg */ if (sysctlbyname("hw.activecpu", &out, &outSize, NULL, 0) == -1) { return -1; } return out; #elif defined(__FreeBSD__) uint32 out; size_t outSize = sizeof out; #if __FreeBSD__version >= 500019 if (sysctlbyname("kern.smp.cpus", &out, &outSize, NULL, 0) == -1) { return -1; } #else if (sysctlbyname("machdep.smp_cpus", &out, &outSize, NULL, 0) == -1) { if (errno == ENOENT) { out = 1; } else { return -1; } } #endif return out; #else static int count = 0; if (count <= 0) { FILE *f; char *line; #if defined(VMX86_SERVER) if (HostType_OSIsVMK()) { VMK_ReturnStatus status = VMKernel_GetNumCPUsUsed(&count); if (status != VMK_OK) { count = 0; return -1; } return count; } #endif f = Posix_Fopen("/proc/cpuinfo", "r"); if (f == NULL) { return -1; } while (StdIO_ReadNextLine(f, &line, 0, NULL) == StdIO_Success) { if (strncmp(line, "processor", strlen("processor")) == 0) { count++; } free(line); } fclose(f); if (count == 0) { return -1; } } return count; #endif } /* *---------------------------------------------------------------------- * * Hostinfo_OSIsSMP -- * * Host OS SMP capability. * * Results: * TRUE is host OS is SMP capable. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool Hostinfo_OSIsSMP(void) { uint32 ncpu; #if defined(__APPLE__) size_t ncpuSize = sizeof ncpu; if (sysctlbyname("hw.ncpu", &ncpu, &ncpuSize, NULL, 0) == -1) { return FALSE; } #else ncpu = Hostinfo_NumCPUs(); if (ncpu == 0xFFFFFFFF) { return FALSE; } #endif return ncpu > 1 ? TRUE : FALSE; } /* *----------------------------------------------------------------------------- * * Hostinfo_NameGet -- * * Return the fully qualified host name of the host. * Thread-safe. --hpreg * * Results: * The (memorized) name on success * NULL on failure * * Side effects: * A host name resolution can occur. * *----------------------------------------------------------------------------- */ Unicode Hostinfo_NameGet(void) { Unicode result; static Atomic_Ptr state; /* Implicitly initialized to NULL. --hpreg */ result = Atomic_ReadPtr(&state); if (UNLIKELY(result == NULL)) { Unicode before; result = Hostinfo_HostName(); before = Atomic_ReadIfEqualWritePtr(&state, NULL, result); if (before) { Unicode_Free(result); result = before; } } return result; } /* *----------------------------------------------------------------------------- * * Hostinfo_GetUser -- * * Return current user name, or NULL if can't tell. * XXX Not thread-safe (somebody could do a setenv()). --hpreg * * Results: * User name. Must be free()d by caller. * * Side effects: * No. * *----------------------------------------------------------------------------- */ Unicode Hostinfo_GetUser(void) { char buffer[BUFSIZ]; struct passwd pw; struct passwd *ppw = &pw; Unicode env = NULL; Unicode name = NULL; if ((Posix_Getpwuid_r(getuid(), &pw, buffer, sizeof buffer, &ppw) == 0) && (ppw != NULL)) { if (ppw->pw_name) { name = Unicode_Duplicate(ppw->pw_name); } } if (!name) { env = Posix_Getenv("USER"); if (env) { name = Unicode_Duplicate(env); } } return name; } /* *----------------------------------------------------------------------------- * * HostinfoGetLoadAverage -- * * Returns system average load. * * Results: * TRUE on success, FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool HostinfoGetLoadAverage(float *avg0, // IN/OUT: float *avg1, // IN/OUT: float *avg2) // IN/OUT: { #if !defined(NO_GETLOADAVG) && (defined(__linux__) && !defined(__UCLIBC__)) || defined(__APPLE__) double avg[3]; int res; res = getloadavg(avg, 3); if (res < 3) { NOT_TESTED_ONCE(); return FALSE; } if (avg0) { *avg0 = (float) avg[0]; } if (avg1) { *avg1 = (float) avg[1]; } if (avg2) { *avg2 = (float) avg[2]; } return TRUE; #else /* * Not implemented. This function is currently only used in the vmx, so * getloadavg is always available to us. If the linux tools ever need this, * we can go back to having a look at the output of /proc/loadavg, but * let's not do that now as long as it's not necessary. */ NOT_IMPLEMENTED(); return FALSE; #endif } /* *----------------------------------------------------------------------------- * * Hostinfo_GetLoadAverage -- * * Returns system average load * 100. * * Results: * TRUE/FALSE * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool Hostinfo_GetLoadAverage(uint32 *avg) // IN/OUT: { float avg0 = 0; if (!HostinfoGetLoadAverage(&avg0, NULL, NULL)) { return FALSE; } *avg = (uint32) 100 * avg0; return TRUE; } /* *----------------------------------------------------------------------------- * * Hostinfo_LogLoadAverage -- * * Logs system average load. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void Hostinfo_LogLoadAverage(void) { float avg0 = 0, avg1 = 0, avg2 = 0; if (HostinfoGetLoadAverage(&avg0, &avg1, &avg2)) { Log("LOADAVG: %.2f %.2f %.2f\n", avg0, avg1, avg2); } } /* *----------------------------------------------------------------------------- * * HostinfoGetTimeOfDayMonotonic -- * * Return the system time as indicated by Hostinfo_GetTimeOfDay(), with * locking to ensure monotonicity. * * Uses OS native locks as lib/lock is not available in lib/misc. This * is safe because nothing occurs while locked that can be reentrant. * * Results: * The time in microseconds is returned. Zero upon error. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static VmTimeType HostinfoGetTimeOfDayMonotonic(void) { VmTimeType newTime; VmTimeType curTime; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static VmTimeType lastTimeBase; static VmTimeType lastTimeRead; static VmTimeType lastTimeReset; pthread_mutex_lock(&mutex); // Use native mechanism, just like Windows Hostinfo_GetTimeOfDay(&curTime); if (curTime == 0) { newTime = 0; goto exit; } /* * Don't let time be negative or go backward. We do this by tracking a * base and moving forward from there. */ newTime = lastTimeBase + (curTime - lastTimeReset); if (newTime < lastTimeRead) { lastTimeReset = curTime; lastTimeBase = lastTimeRead + 1; newTime = lastTimeBase + (curTime - lastTimeReset); } lastTimeRead = newTime; exit: pthread_mutex_unlock(&mutex); return newTime; } /* *----------------------------------------------------------------------------- * * HostinfoSystemTimerMach -- * HostinfoSystemTimerPosix -- * * Returns system time based on a monotonic, nanosecond-resolution, * fast timer provided by the (relevant) operating system. * * Caller should check return value, as some variants may not be known * to be absent until runtime. Where possible, these functions collapse * into constants at compile-time. * * Results: * TRUE if timer is available; FALSE to indicate unavailability. * If available, the current time is returned via 'result'. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool HostinfoSystemTimerMach(VmTimeType *result) // OUT { #if __APPLE__ # define vmx86_apple 1 typedef struct { double scalingFactor; Bool unity; } timerData; VmTimeType raw; timerData *ptr; static Atomic_Ptr atomic; /* Implicitly initialized to NULL. --mbellon */ /* * On Mac OS a commpage timer is used. Such timers are ensured to never * go backwards - and be valid across all processes. */ /* Ensure that the time base values are correct. */ ptr = Atomic_ReadPtr(&atomic); if (UNLIKELY(ptr == NULL)) { mach_timebase_info_data_t timeBase; timerData *try = Util_SafeMalloc(sizeof *try); mach_timebase_info(&timeBase); try->scalingFactor = ((double) timeBase.numer) / ((double) timeBase.denom); try->unity = ((timeBase.numer == 1) && (timeBase.denom == 1)); if (Atomic_ReadIfEqualWritePtr(&atomic, NULL, try)) { free(try); } ptr = Atomic_ReadPtr(&atomic); } raw = mach_absolute_time(); if (LIKELY(ptr->unity)) { *result = raw; } else { *result = ((double) raw) * ptr->scalingFactor; } return TRUE; #else # define vmx86_apple 0 return FALSE; #endif } static Bool HostinfoSystemTimerPosix(VmTimeType *result) // OUT { #if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK) # define vmx86_posix 1 /* Weak declaration to avoid librt.so dependency */ extern int clock_gettime(clockid_t clk_id, struct timespec *tp) __attribute__ ((weak)); /* Assignment is idempotent (expected to always be same answer). */ static volatile enum { UNKNOWN, PRESENT, FAILED } hasGetTime = UNKNOWN; struct timespec ts; int ret; switch (hasGetTime) { case FAILED: break; case UNKNOWN: if (clock_gettime == NULL) { /* librt.so is not present. No clock_gettime() */ hasGetTime = FAILED; break; } ret = clock_gettime(CLOCK_MONOTONIC, &ts); if (ret != 0) { hasGetTime = FAILED; /* * Well-understood error codes: * ENOSYS, OS does not implement syscall * EINVAL, OS implements syscall but not CLOCK_MONOTONIC */ if (errno != ENOSYS && errno != EINVAL) { Log("%s: failure, err %d!\n", __FUNCTION__, errno); } break; } hasGetTime = PRESENT; /* Fall through to 'case PRESENT' */ case PRESENT: ret = clock_gettime(CLOCK_MONOTONIC, &ts); ASSERT(ret == 0); *result = (VmTimeType)ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec; return TRUE; } return FALSE; #else #if vmx86_server && defined(GLIBC_VERSION_23) # error Posix clock_gettime support required on ESX #endif # define vmx86_posix 0 /* No Posix support for clock_gettime() */ return FALSE; #endif } /* *----------------------------------------------------------------------------- * * Hostinfo_SystemTimerNS -- * * Return the time. * - These timers are documented to never go backwards. * - These timers may take locks * * NOTES: * These are the routines to use when performing timing measurements. * * The value returned is valid (finish-time - start-time) only within a * single process. Don't send a time measurement obtained with these * routines to another process and expect a relative time measurement * to be correct. * * The actual resolution of these "clocks" are undefined - it varies * depending on hardware, OSen and OS versions. * * *** NOTE: This function and all children must be callable * while RANK_logLock is held. *** * * Results: * The time in nanoseconds is returned. Zero upon error. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VmTimeType Hostinfo_SystemTimerNS(void) { VmTimeType result; if ((vmx86_apple && HostinfoSystemTimerMach(&result)) || (vmx86_posix && HostinfoSystemTimerPosix(&result))) { /* Host provides monotonic clock source. */ return result; } else { /* GetTimeOfDay is microseconds. */ return HostinfoGetTimeOfDayMonotonic() * 1000; } } #undef vmx86_apple #undef vmx86_posix /* *----------------------------------------------------------------------------- * * Hostinfo_LogMemUsage -- * Log system memory usage. * * Results: * System memory usage is logged. * * Side effects: * No. * *----------------------------------------------------------------------------- */ void Hostinfo_LogMemUsage(void) { int fd = Posix_Open("/proc/self/statm", O_RDONLY); if (fd != -1) { size_t len; char buf[64]; len = read(fd, buf, sizeof buf); close(fd); if (len != -1) { int a[7] = { 0 }; buf[len < sizeof buf ? len : sizeof buf - 1] = '\0'; sscanf(buf, "%d %d %d %d %d %d %d", &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6]); Log("RUSAGE size=%d resident=%d share=%d trs=%d lrs=%d drs=%d dt=%d\n", a[0], a[1], a[2], a[3], a[4], a[5], a[6]); } } } /* *---------------------------------------------------------------------- * * Hostinfo_ResetProcessState -- * * Clean up signal handlers and file descriptors before an exec(). * Fds which need to be kept open can be passed as an array. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void Hostinfo_ResetProcessState(const int *keepFds, // IN: size_t numKeepFds) // IN: { int s, fd; struct sigaction sa; struct rlimit rlim; /* * Disable itimers before resetting the signal handlers. * Otherwise, the process may still receive timer signals: * SIGALRM, SIGVTARLM, or SIGPROF. */ struct itimerval it; it.it_value.tv_sec = it.it_value.tv_usec = 0; it.it_interval.tv_sec = it.it_interval.tv_usec = 0; setitimer(ITIMER_REAL, &it, NULL); setitimer(ITIMER_VIRTUAL, &it, NULL); setitimer(ITIMER_PROF, &it, NULL); for (s = 1; s <= NSIG; s++) { sa.sa_handler = SIG_DFL; sigfillset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sigaction(s, &sa, NULL); } for (fd = (int) sysconf(_SC_OPEN_MAX) - 1; fd > STDERR_FILENO; fd--) { size_t i; for (i = 0; i < numKeepFds; i++) { if (fd == keepFds[i]) { break; } } if (i == numKeepFds) { (void) close(fd); } } if (getrlimit(RLIMIT_AS, &rlim) == 0) { rlim.rlim_cur = rlim.rlim_max; setrlimit(RLIMIT_AS, &rlim); } #ifdef __linux__ /* * Drop iopl to its default value. * iopl() is not implemented in userworlds */ if (!vmx86_server) { int err; uid_t euid; euid = Id_GetEUid(); /* At this point, _unless we are running as root_, we shouldn't have root privileges --hpreg */ ASSERT(euid != 0 || getuid() == 0); Id_SetEUid(0); #if defined NO_IOPL NOT_IMPLEMENTED(); errno = ENOSYS; #else err = iopl(0); #endif Id_SetEUid(euid); ASSERT_NOT_IMPLEMENTED(err == 0); } #endif } /* *----------------------------------------------------------------------------- * * Hostinfo_Daemonize -- * * Cross-platform daemon(3)-like wrapper. * * Restarts the current process as a daemon, given the path to the * process (usually from Hostinfo_GetModulePath). This means: * * * You're detached from your parent. (Your parent doesn't * need to wait for you to exit.) * * Your process no longer has a controlling terminal or * process group. * * Your stdin/stdout/stderr fds are redirected to /dev/null. All * other descriptors, except for the ones that are passed in the * parameter keepFds, are closed. * * Your signal handlers are reset to SIG_DFL in the daemonized * process, and all the signals are unblocked. * * Your main() function is called with the specified NULL-terminated * argument list. * * (Don't forget that the first string in args is argv[0] -- the * name of the process). * * Unless 'flags' contains HOSTINFO_DAEMONIZE_NOCHDIR, then the * current directory of the daemon process is set to "/". * * Unless 'flags' contains HOSTINFO_DAEMONIZE_NOCLOSE, then all stdio * file descriptors of the daemon process are redirected to /dev/null. * This is true even if the stdio descriptors are included in keepFds, * i.e. the list of fds to be kept open. * * If 'flags' contains HOSTINFO_DAEMONIZE_EXIT, then upon successful * launch of the daemon, the original process will exit. * * If pidPath is non-NULL, then upon success, writes the PID * (as a US-ASCII string followed by a newline) of the daemon * process to that path. * * If 'flags' contains HOSTINFO_DAEMONIZE_LOCKPID and pidPath is * non-NULL, then an exclusive flock(2) is taken on pidPath to prevent * multiple instances of the service from running. * * Results: * FALSE if the process could not be daemonized. errno contains * the error on failure. * TRUE if 'flags' does not contain HOSTINFO_DAEMONIZE_EXIT and * the process was daemonized. * Otherwise, if the process was daemonized, this function does * not return, and flow continues from your own main() function. * * Side effects: * The current process is restarted with the given arguments. * The process state is reset (see Hostinfo_ResetProcessState). * A new session is created (so the process has no controlling terminal). * *----------------------------------------------------------------------------- */ Bool Hostinfo_Daemonize(const char *path, // IN: NUL-terminated UTF-8 // path to exec char * const *args, // IN: NULL-terminated UTF-8 // argv list HostinfoDaemonizeFlags flags, // IN: flags const char *pidPath, // IN/OPT: NUL-terminated // UTF-8 path to write PID const int *keepFds, // IN/OPT: array of fds to be // kept open size_t numKeepFds) // IN: number of fds in // keepFds { /* * We use the double-fork method to make a background process whose * parent is init instead of the original process. * * We do this instead of calling daemon(), because daemon() is * deprecated on Mac OS 10.5 hosts, and calling it causes a compiler * warning. * * We must exec() after forking, because Mac OS library frameworks * depend on internal Mach ports, which are not correctly propagated * across fork calls. exec'ing reinitializes the frameworks, which * causes them to reopen their Mach ports. */ int pidPathFd = -1; int childPid; int pipeFds[2] = { -1, -1 }; uint32 err = EINVAL; char *pathLocalEncoding = NULL; char **argsLocalEncoding = NULL; int *tempFds = NULL; size_t numTempFds = numKeepFds + 1; sigset_t sig; ASSERT_ON_COMPILE(sizeof (errno) <= sizeof err); ASSERT(args); ASSERT(path); ASSERT(numKeepFds == 0 || keepFds); if (pidPath) { pidPathFd = Posix_Open(pidPath, O_WRONLY | O_CREAT, 0644); if (pidPathFd == -1) { err = errno; Warning("%s: Couldn't open PID path [%s], error %u.\n", __FUNCTION__, pidPath, err); errno = err; return FALSE; } /* * Lock this file to take a mutex on daemonizing this process. The child * will keep this file descriptor open for as long as it is running. * * flock(2) is a BSD extension (also supported on Linux) which creates a * lock that is inherited by the child after fork(2). fcntl(2) locks do * not have this property. Solaris only supports fcntl(2) locks. */ #ifndef sun if ((flags & HOSTINFO_DAEMONIZE_LOCKPID) && flock(pidPathFd, LOCK_EX | LOCK_NB) == -1) { err = errno; Warning("%s: Lock held on PID path [%s], error %u, not daemonizing.\n", __FUNCTION__, pidPath, err); errno = err; close(pidPathFd); return FALSE; } #endif numTempFds++; } if (pipe(pipeFds) == -1) { err = errno; Warning("%s: Couldn't create pipe, error %u.\n", __FUNCTION__, err); pipeFds[0] = pipeFds[1] = -1; goto cleanup; } tempFds = malloc(sizeof tempFds[0] * numTempFds); if (!tempFds) { err = errno; Warning("%s: Couldn't allocate memory, error %u.\n", __FUNCTION__, err); goto cleanup; } if (keepFds) { memcpy(tempFds, keepFds, sizeof tempFds[0] * numKeepFds); } tempFds[numKeepFds++] = pipeFds[1]; if (pidPath) { tempFds[numKeepFds++] = pidPathFd; } if (fcntl(pipeFds[1], F_SETFD, 1) == -1) { err = errno; Warning("%s: Couldn't set close-on-exec for fd %d, error %u.\n", __FUNCTION__, pipeFds[1], err); goto cleanup; } /* Convert the strings from UTF-8 before we fork. */ pathLocalEncoding = Unicode_GetAllocBytes(path, STRING_ENCODING_DEFAULT); if (!pathLocalEncoding) { Warning("%s: Couldn't convert path [%s] to default encoding.\n", __FUNCTION__, path); goto cleanup; } argsLocalEncoding = Unicode_GetAllocList(args, STRING_ENCODING_DEFAULT, -1); if (!argsLocalEncoding) { Warning("%s: Couldn't convert arguments to default encoding.\n", __FUNCTION__); goto cleanup; } childPid = fork(); switch (childPid) { case -1: err = errno; Warning("%s: Couldn't fork first child, error %u.\n", __FUNCTION__, err); goto cleanup; case 0: /* We're the first child. Continue on. */ break; default: { /* We're the original process. Check if the first child exited. */ int status; close(pipeFds[1]); waitpid(childPid, &status, 0); if (WIFEXITED(status) && WEXITSTATUS(status) != EXIT_SUCCESS) { Warning("%s: Child %d exited with error %d.\n", __FUNCTION__, childPid, WEXITSTATUS(status)); goto cleanup; } else if (WIFSIGNALED(status)) { Warning("%s: Child %d exited with signal %d.\n", __FUNCTION__, childPid, WTERMSIG(status)); goto cleanup; } /* * Check if the second child exec'ed successfully. If it had * an error, it will write a uint32 errno to this pipe before * exiting. Otherwise, its end of the pipe will be closed on * exec and this call will fail as expected. * The assumption is that we don't get a partial read. In case, * it did happen, we can detect it by the number of bytes read. */ while (TRUE) { int res = read(pipeFds[0], &err, sizeof err); if (res > 0) { Warning("%s: Child could not exec %s, read %d, error %u.\n", __FUNCTION__, path, res, err); goto cleanup; } else if ((res == -1) && (errno == EINTR)) { continue; } break; } err = 0; goto cleanup; } } /* * Close all fds except for the write end of the error pipe (which we've * already set to close on successful exec), the pid file, and the ones * requested by the caller. Also reset the signal mask to unblock all * signals. fork() clears pending signals. */ Hostinfo_ResetProcessState(tempFds, numKeepFds); free(tempFds); tempFds = NULL; sigfillset(&sig); sigprocmask(SIG_UNBLOCK, &sig, NULL); if (!(flags & HOSTINFO_DAEMONIZE_NOCLOSE) && setsid() == -1) { Warning("%s: Couldn't create new session, error %d.\n", __FUNCTION__, errno); _exit(EXIT_FAILURE); } switch (fork()) { case -1: { Warning("%s: Couldn't fork second child, error %d.\n", __FUNCTION__, errno); _exit(EXIT_FAILURE); } case 0: // We're the second child. Continue on. break; default: /* * We're the first child. We don't need to exist any more. * * Exiting here causes the second child to be reparented to the * init process, so the original process doesn't need to wait * for the child we forked off. */ _exit(EXIT_SUCCESS); } /* * We can't use our i18n wrappers for file manipulation at this * point, since we've forked; internal library mutexes might be * invalid. */ if (!(flags & HOSTINFO_DAEMONIZE_NOCHDIR) && chdir("/") == -1) { uint32 err = errno; Warning("%s: Couldn't chdir to /, error %u.\n", __FUNCTION__, err); /* Let the original process know we failed to chdir. */ if (write(pipeFds[1], &err, sizeof err) == -1) { Warning("%s: Couldn't write to parent pipe: %u, " "original error: %u.\n", __FUNCTION__, errno, err); } _exit(EXIT_FAILURE); } if (!(flags & HOSTINFO_DAEMONIZE_NOCLOSE)) { int fd; fd = open(_PATH_DEVNULL, O_RDONLY); if (fd != -1) { dup2(fd, STDIN_FILENO); close(fd); } fd = open(_PATH_DEVNULL, O_WRONLY); if (fd != -1) { dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); close(fd); } } if (pidPath) { int64 pid; char pidString[32]; int pidStringLen; ASSERT_ON_COMPILE(sizeof (pid_t) <= sizeof pid); ASSERT(pidPathFd >= 0); pid = getpid(); pidStringLen = Str_Sprintf(pidString, sizeof pidString, "%"FMT64"d\n", pid); if (pidStringLen <= 0) { err = EINVAL; if (write(pipeFds[1], &err, sizeof err) == -1) { Warning("%s: Couldn't write to parent pipe: %u, original " "error: %u.\n", __FUNCTION__, errno, err); } _exit(EXIT_FAILURE); } if (ftruncate(pidPathFd, 0) == -1) { err = errno; Warning("%s: Couldn't truncate path [%s], error %d.\n", __FUNCTION__, pidPath, err); if (write(pipeFds[1], &err, sizeof err) == -1) { Warning("%s: Couldn't write to parent pipe: %u, original " "error: %u.\n", __FUNCTION__, errno, err); } _exit(EXIT_FAILURE); } if (write(pidPathFd, pidString, pidStringLen) != pidStringLen) { err = errno; Warning("%s: Couldn't write PID to path [%s], error %d.\n", __FUNCTION__, pidPath, err); if (write(pipeFds[1], &err, sizeof err) == -1) { Warning("%s: Couldn't write to parent pipe: %u, original " "error: %u.\n", __FUNCTION__, errno, err); } _exit(EXIT_FAILURE); } if (fsync(pidPathFd) == -1) { err = errno; Warning("%s: Couldn't flush PID to path [%s], error %d.\n", __FUNCTION__, pidPath, err); if (write(pipeFds[1], &err, sizeof err) == -1) { Warning("%s: Couldn't write to parent pipe: %u, original " "error: %u.\n", __FUNCTION__, errno, err); } _exit(EXIT_FAILURE); } /* Leave pidPathFd open to hold the mutex until this process exits. */ if (!(flags & HOSTINFO_DAEMONIZE_LOCKPID)) { close(pidPathFd); } } if (execv(pathLocalEncoding, argsLocalEncoding) == -1) { err = errno; Warning("%s: Couldn't exec %s, error %d.\n", __FUNCTION__, path, err); /* Let the original process know we failed to exec. */ if (write(pipeFds[1], &err, sizeof err) == -1) { Warning("%s: Couldn't write to parent pipe: %u, " "original error: %u.\n", __FUNCTION__, errno, err); } _exit(EXIT_FAILURE); } NOT_REACHED(); cleanup: free(tempFds); if (pipeFds[0] != -1) { close(pipeFds[0]); } if (pipeFds[1] != -1) { close(pipeFds[1]); } Util_FreeStringList(argsLocalEncoding, -1); free(pathLocalEncoding); if (err == 0) { if (flags & HOSTINFO_DAEMONIZE_EXIT) { _exit(EXIT_SUCCESS); } } else { if (pidPath) { /* * Unlink pidPath on error before closing pidPathFd to avoid racing * with another process attempting to daemonize and unlinking the * file it created instead. */ Posix_Unlink(pidPath); } errno = err; } if (pidPath) { close(pidPathFd); } return err == 0; } #if !defined(__APPLE__) && !defined(__FreeBSD__) /* *---------------------------------------------------------------------- * * HostinfoGetCpuInfo -- * * Get some attribute from /proc/cpuinfo for a given CPU * * Results: * On success: Allocated, NUL-terminated attribute string. * On failure: NULL. * * Side effects: * None. * *---------------------------------------------------------------------- */ static char * HostinfoGetCpuInfo(int nCpu, // IN: char *name) // IN: { FILE *f; char *line; int cpu = 0; char *value = NULL; f = Posix_Fopen("/proc/cpuinfo", "r"); if (f == NULL) { Warning(LGPFX" %s: Unable to open /proc/cpuinfo\n", __FUNCTION__); return NULL; } while (cpu <= nCpu && StdIO_ReadNextLine(f, &line, 0, NULL) == StdIO_Success) { char *s; char *e; if ((s = strstr(line, name)) && (s = strchr(s, ':'))) { s++; e = s + strlen(s); /* Skip leading and trailing while spaces */ for (; s < e && isspace(*s); s++); for (; s < e && isspace(e[-1]); e--); *e = 0; /* Free previous value */ free(value); value = strdup(s); ASSERT_MEM_ALLOC(value); cpu++; } free(line); } fclose(f); return value; } #endif /* *----------------------------------------------------------------------------- * * Hostinfo_GetRatedCpuMhz -- * * Get the rated CPU speed of a given processor. * Return value is in MHz. * * Results: * TRUE on success, FALSE on failure * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool Hostinfo_GetRatedCpuMhz(int32 cpuNumber, // IN: uint32 *mHz) // OUT: { #if defined(__APPLE__) || defined(__FreeBSD__) # if defined(__APPLE__) # define CPUMHZ_SYSCTL_NAME "hw.cpufrequency_max" # elif __FreeBSD__version >= 50011 # define CPUMHZ_SYSCTL_NAME "hw.clockrate" # endif # if defined(CPUMHZ_SYSCTL_NAME) uint32 hz; size_t hzSize = sizeof hz; /* 'cpuNumber' is ignored: Intel Macs are always perfectly symmetric. */ if (sysctlbyname(CPUMHZ_SYSCTL_NAME, &hz, &hzSize, NULL, 0) == -1) { return FALSE; } *mHz = hz / 1000000; return TRUE; # else return FALSE; # endif #else #if defined(VMX86_SERVER) if (HostType_OSIsVMK()) { uint32 tscKhzEstimate; VMK_ReturnStatus status = VMKernel_GetTSCkhzEstimate(&tscKhzEstimate); /* * The TSC frequency matches the CPU frequency in all modern CPUs. * Regardless, the TSC frequency is a much better estimate of * reality than failing or returning zero. */ *mHz = tscKhzEstimate / 1000; return (status == VMK_OK); } #endif { float fMhz = 0; char *readVal = HostinfoGetCpuInfo(cpuNumber, "cpu MHz"); if (readVal == NULL) { return FALSE; } if (sscanf(readVal, "%f", &fMhz) == 1) { *mHz = (unsigned int)(fMhz + 0.5); } free(readVal); } return TRUE; #endif } #if defined(__APPLE__) || defined(__FreeBSD__) /* *----------------------------------------------------------------------------- * * HostinfoGetSysctlStringAlloc -- * * Obtains the value of a string-type host sysctl. * * Results: * On success: Allocated, NUL-terminated string. * On failure: NULL. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static char * HostinfoGetSysctlStringAlloc(char const *sysctlName) // IN { char *desc; size_t descSize; if (sysctlbyname(sysctlName, NULL, &descSize, NULL, 0) == -1) { return NULL; } desc = malloc(descSize); if (!desc) { return NULL; } if (sysctlbyname(sysctlName, desc, &descSize, NULL, 0) == -1) { free(desc); return NULL; } return desc; } #endif /* *----------------------------------------------------------------------------- * * Hostinfo_GetCpuDescription -- * * Get the descriptive name associated with a given CPU. * * Results: * On success: Allocated, NUL-terminated string. * On failure: NULL. * * Side effects: * None. * *----------------------------------------------------------------------------- */ char * Hostinfo_GetCpuDescription(uint32 cpuNumber) // IN: { #if defined(__APPLE__) /* 'cpuNumber' is ignored: Intel Macs are always perfectly symmetric. */ return HostinfoGetSysctlStringAlloc("machdep.cpu.brand_string"); #elif defined(__FreeBSD__) return HostinfoGetSysctlStringAlloc("hw.model"); #else #ifdef VMX86_SERVER if (HostType_OSIsVMK()) { char mName[48]; /* VMKernel treats mName as an in/out parameter so terminate it. */ mName[0] = '\0'; if (VMKernel_GetCPUModelName(cpuNumber, mName, sizeof(mName)) == VMK_OK) { mName[sizeof(mName) - 1] = '\0'; return strdup(mName); } return NULL; } #endif return HostinfoGetCpuInfo(cpuNumber, "model name"); #endif } /* *---------------------------------------------------------------------- * * Hostinfo_Execute -- * * Start program 'path'. If 'wait' is TRUE, wait for program * to complete and return exit status. * * Results: * Exit status of 'path'. * * Side effects: * Run a separate program. * *---------------------------------------------------------------------- */ int Hostinfo_Execute(const char *path, // IN: char * const *args, // IN: Bool wait, // IN: const int *keepFds, // IN/OPT: array of fds to be kept open size_t numKeepFds) // IN: number of fds in keepFds { int pid; int status; if (path == NULL) { return 1; } pid = fork(); if (pid == -1) { return -1; } if (pid == 0) { Hostinfo_ResetProcessState(keepFds, numKeepFds); Posix_Execvp(path, args); exit(127); } if (wait) { for (;;) { if (waitpid(pid, &status, 0) == -1) { if (errno == ECHILD) { return 0; // This sucks. We really don't know. } if (errno != EINTR) { return -1; } } else { return status; } } } else { return 0; } } #ifdef __APPLE__ /* * How to retrieve kernel zone information. A little bit of history * --- * 1) In Mac OS versions < 10.6, we could retrieve kernel zone information like * zprint did, i.e. by invoking the host_zone_info() Mach call. * * osfmk/mach/mach_host.defs defines both arrays passed to host_zone_info() * as 'out' parameters, but the implementation of the function in * osfmk/kern/zalloc.c clearly treats them as 'inout' parameters. This issue * is confirmed in practice: the input values passed by the user process are * ignored. Now comes the scary part: is the input of the kernel function * deterministically invalid, or is it some non-deterministic garbage (in * which case the kernel could corrupt the user address space)? The answer * is in the Mach IPC code. A cursory kernel debugging session seems to * imply that the input pointer values are garbage, but the input size * values are always 0. So host_zone_info() seems safe to use in practice. * * 2) In Mac OS 10.6, Apple introduced the 64-bit kernel. * * 2.1) They modified host_zone_info() to always returns KERN_NOT_SUPPORTED * when the sizes (32-bit or 64-bit) of the user and kernel virtual * address spaces do not match. Was bug 377049. * * zprint got away with it by re-executing itself to match the kernel. * * 2.2) They broke the ABI for 64-bit user processes: the * 'zone_info.zi_*_size' fields are 32-bit in the Mac OS 10.5 SDK, and * 64-bit in the Mac OS 10.6 SDK. So a 64-bit user process compiled * against the Mac OS 10.5 SDK works with the Mac OS 10.5 (32-bit) * kernel but fails with the Mac OS 10.6 64-bit kernel. * * zprint in Mac OS 10.6 is compiled against the Mac OS 10.6 SDK, so it * got away with it. * * The above two things made it very impractical for us to keep calling * host_zone_info(). Instead we invoked zprint and parsed its non-localized * output. * * 3) In Mac OS 10.7, Apple cleaned their mess and solved all the above * problems by introducing a new mach_zone_info() Mach call. So this is what * we use now, when available. Was bug 816610. * * 4) In Mac OS 10.8, Apple appears to have modified mach_zone_info() to always * return KERN_INVALID_HOST(!) when the calling process (not the calling * thread!) is not root. */ #if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 // Must run on Mac OS versions < 10.7 /* *----------------------------------------------------------------------------- * * HostinfoGetKernelZoneElemSizeZprint -- * * Retrieve the size of the elements in a named kernel zone, by invoking * zprint. * * Results: * On success: the size (in bytes) > 0. * On failure: 0. * * Side effects: * None * *----------------------------------------------------------------------------- */ static size_t HostinfoGetKernelZoneElemSizeZprint(char const *name) // IN: Kernel zone name { size_t retval = 0; struct { size_t retval; } volatile *shared; pid_t child; pid_t pid; /* * popen(3) incorrectly executes the shell with the identity of the calling * process, ignoring a potential per-thread identity. And starting with * Mac OS 10.6 it is even worse: if there is a per-thread identity, * popen(3) removes it! * * So we run this code in a separate process which runs with the same * identity as the current thread. */ shared = mmap(NULL, sizeof *shared, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); if (shared == (void *)-1) { Warning("%s: mmap error %d.\n", __FUNCTION__, errno); return retval; } // In case the child is terminated before it can set it. shared->retval = retval; child = fork(); if (child == (pid_t)-1) { Warning("%s: fork error %d.\n", __FUNCTION__, errno); munmap((void *)shared, sizeof *shared); return retval; } // This executes only in the child process. if (!child) { size_t nameLen; FILE *stream; Bool parsingProperties = FALSE; ASSERT(name); nameLen = strlen(name); ASSERT(nameLen && *name != '\t'); stream = popen("/usr/bin/zprint -C", "r"); if (!stream) { Warning("%s: popen error %d.\n", __FUNCTION__, errno); exit(EXIT_SUCCESS); } for (;;) { char *line; size_t lineLen; if (StdIO_ReadNextLine(stream, &line, 0, &lineLen) != StdIO_Success) { break; } if (parsingProperties) { if ( // Not a property line anymore. Property not found. lineLen < 1 || memcmp(line, "\t", 1) // Property found. || sscanf(line, " elem_size: %"FMTSZ"u bytes", &shared->retval) == 1) { free(line); break; } } else if (!(lineLen < nameLen + 6 || memcmp(line, name, nameLen) || memcmp(line + nameLen, " zone:", 6))) { // Zone found. parsingProperties = TRUE; } free(line); } pclose(stream); exit(EXIT_SUCCESS); } /* * This executes only in the parent process. * Wait for the child to terminate, and return its retval. */ do { int status; pid = waitpid(child, &status, 0); } while ((pid == -1) && (errno == EINTR)); ASSERT_NOT_IMPLEMENTED(pid == child); retval = shared->retval; munmap((void *)shared, sizeof *shared); return retval; } #endif /* *----------------------------------------------------------------------------- * * Hostinfo_GetKernelZoneElemSize -- * * Retrieve the size of the elements in a named kernel zone. * * Results: * On success: the size (in bytes) > 0. * On failure: 0. * * Side effects: * None * *----------------------------------------------------------------------------- */ size_t Hostinfo_GetKernelZoneElemSize(char const *name) // IN: Kernel zone name { #if MAC_OS_X_VERSION_MAX_ALLOWED < 1070 // Compiles against SDK version < 10.7 typedef struct { char mzn_name[80]; } mach_zone_name_t; typedef struct { uint64_t mzi_count; uint64_t mzi_cur_size; uint64_t mzi_max_size; uint64_t mzi_elem_size; uint64_t mzi_alloc_size; uint64_t mzi_sum_size; uint64_t mzi_exhaustible; uint64_t mzi_collectable; } mach_zone_info_t; #endif size_t result = 0; mach_zone_name_t *namesPtr; mach_msg_type_number_t namesSize; mach_zone_info_t *infosPtr; mach_msg_type_number_t infosSize; kern_return_t kr; mach_msg_type_number_t i; #if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 // Must run on Mac OS versions < 10.7 kern_return_t (*mach_zone_info)(host_t host, mach_zone_name_t **names, mach_msg_type_number_t *namesCnt, mach_zone_info_t **info, mach_msg_type_number_t *infoCnt) = dlsym(RTLD_DEFAULT, "mach_zone_info"); if (!mach_zone_info) { return HostinfoGetKernelZoneElemSizeZprint(name); } #endif ASSERT(name); kr = mach_zone_info(mach_host_self(), &namesPtr, &namesSize, &infosPtr, &infosSize); if (kr != KERN_SUCCESS) { Warning("%s: mach_zone_info failed %u.\n", __FUNCTION__, kr); return result; } ASSERT(namesSize == infosSize); for (i = 0; i < namesSize; i++) { if (!strcmp(namesPtr[i].mzn_name, name)) { result = infosPtr[i].mzi_elem_size; /* Check that nothing of value was lost during the cast. */ ASSERT(result == infosPtr[i].mzi_elem_size); break; } } ASSERT_ON_COMPILE(sizeof namesPtr <= sizeof (vm_address_t)); kr = vm_deallocate(mach_task_self(), (vm_address_t)namesPtr, namesSize * sizeof *namesPtr); ASSERT(kr == KERN_SUCCESS); ASSERT_ON_COMPILE(sizeof infosPtr <= sizeof (vm_address_t)); kr = vm_deallocate(mach_task_self(), (vm_address_t)infosPtr, infosSize * sizeof *infosPtr); ASSERT(kr == KERN_SUCCESS); return result; } /* *----------------------------------------------------------------------------- * * Hostinfo_GetHardwareModel -- * * Obtains the hardware model identifier (i.e. "MacPro5,1") from the host. * * Results: * On success: Allocated, NUL-terminated string. * On failure: NULL. * * Side effects: * None. * *----------------------------------------------------------------------------- */ char * Hostinfo_GetHardwareModel(void) { return HostinfoGetSysctlStringAlloc("hw.model"); } #endif /* __APPLE__ */ /* *----------------------------------------------------------------------------- * * Hostinfo_SystemUpTime -- * * Return system uptime in microseconds. * * Please note that the actual resolution of this "clock" is undefined - * it varies between OSen and OS versions. Use Hostinfo_SystemTimerUS * whenever possible. * * Results: * System uptime in microseconds or zero in case of a failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VmTimeType Hostinfo_SystemUpTime(void) { #if defined(__APPLE__) return Hostinfo_SystemTimerUS(); #elif defined(__linux__) int res; double uptime; int fd; char buf[256]; static Atomic_Int fdStorage = { -1 }; static Atomic_uint32 logFailedPread = { 1 }; /* * /proc/uptime does not exist on Visor. Use syscall instead. * Discovering Visor is a run-time check with a compile-time hint. */ if (vmx86_server && HostType_OSIsPureVMK()) { uint64 uptime; #ifdef VMX86_SERVER if (UNLIKELY(VMKernel_GetUptimeUS(&uptime) != VMK_OK)) { Log("%s: failure!\n", __FUNCTION__); uptime = 0; // A timer read failure - this is really bad! } #endif return uptime; } fd = Atomic_ReadInt(&fdStorage); /* Do we need to open the file the first time through? */ if (UNLIKELY(fd == -1)) { fd = open("/proc/uptime", O_RDONLY); if (fd == -1) { Warning(LGPFX" Failed to open /proc/uptime: %s\n", Err_Errno2String(errno)); return 0; } /* Try to swap ours in. If we lose the race, close our fd */ if (Atomic_ReadIfEqualWriteInt(&fdStorage, -1, fd) != -1) { close(fd); } /* Get the winning fd - either ours or theirs, doesn't matter anymore */ fd = Atomic_ReadInt(&fdStorage); } ASSERT(fd != -1); res = pread(fd, buf, sizeof buf - 1, 0); if (res == -1) { /* * In case some kernel broke pread (like 2.6.28-rc1), have a fall-back * instead of spewing the log. This should be rare. Using a lock * around lseek and read does not work here as it will deadlock with * allocTrack/fileTrack enabled. */ if (Atomic_ReadIfEqualWrite(&logFailedPread, 1, 0) == 1) { Warning(LGPFX" Failed to pread /proc/uptime: %s\n", Err_Errno2String(errno)); } fd = open("/proc/uptime", O_RDONLY); if (fd == -1) { Warning(LGPFX" Failed to retry open /proc/uptime: %s\n", Err_Errno2String(errno)); return 0; } res = read(fd, buf, sizeof buf - 1); close(fd); if (res == -1) { Warning(LGPFX" Failed to read /proc/uptime: %s\n", Err_Errno2String(errno)); return 0; } } ASSERT(res < sizeof buf); buf[res] = '\0'; if (sscanf(buf, "%lf", &uptime) != 1) { Warning(LGPFX" Failed to parse /proc/uptime\n"); return 0; } return uptime * 1000 * 1000; #else NOT_IMPLEMENTED(); #endif } #if !defined(__APPLE__) /* *---------------------------------------------------------------------- * * HostinfoFindEntry -- * * Search a buffer for a pair `STRING DIGITS' * and return the number DIGITS, or 0 when fail. * * Results: * TRUE on success, FALSE on failure * * Side effects: * None * *---------------------------------------------------------------------- */ static Bool HostinfoFindEntry(char *buffer, // IN: Buffer char *string, // IN: String sought unsigned int *value) // OUT: Value { char *p = strstr(buffer, string); unsigned int val; if (p == NULL) { return FALSE; } p += strlen(string); while (*p == ' ' || *p == '\t') { p++; } if (*p < '0' || *p > '9') { return FALSE; } val = strtoul(p, NULL, 10); if ((errno == ERANGE) || (errno == EINVAL)) { return FALSE; } *value = val; return TRUE; } /* *---------------------------------------------------------------------- * * HostinfoGetMemInfo -- * * Get some attribute from /proc/meminfo * Return value is in KB. * * Results: * TRUE on success, FALSE on failure * * Side effects: * None. * *---------------------------------------------------------------------- */ static Bool HostinfoGetMemInfo(char *name, // IN: unsigned int *value) // OUT: { size_t len; char buffer[4096]; int fd = Posix_Open("/proc/meminfo", O_RDONLY); if (fd == -1) { Warning(LGPFX" %s: Unable to open /proc/meminfo\n", __FUNCTION__); return FALSE; } len = read(fd, buffer, sizeof buffer - 1); close(fd); if (len == -1) { return FALSE; } buffer[len] = '\0'; return HostinfoFindEntry(buffer, name, value); } /* *----------------------------------------------------------------------------- * * HostinfoSysinfo -- * * Retrieve system information on a Linux system. * * Results: * TRUE on success: '*totalRam', '*freeRam', '*totalSwap' and '*freeSwap' * are set if not NULL * FALSE on failure * * Side effects: * None. * * This seems to be a very expensive call: like 5ms on 1GHz P3 running * RH6.1 Linux 2.2.12-20. Yes, that's 5 milliseconds. So caller should * take care. -- edward * *----------------------------------------------------------------------------- */ static Bool HostinfoSysinfo(uint64 *totalRam, // OUT: Total RAM in bytes uint64 *freeRam, // OUT: Free RAM in bytes uint64 *totalSwap, // OUT: Total swap in bytes uint64 *freeSwap) // OUT: Free swap in bytes { #ifdef HAVE_SYSINFO // Found in linux/include/kernel.h for a 2.5.6 kernel --hpreg struct vmware_sysinfo { long uptime; /* Seconds since boot */ unsigned long loads[3]; /* 1, 5, and 15 minute load averages */ unsigned long totalram; /* Total usable main memory size */ unsigned long freeram; /* Available memory size */ unsigned long sharedram; /* Amount of shared memory */ unsigned long bufferram; /* Memory used by buffers */ unsigned long totalswap; /* Total swap space size */ unsigned long freeswap; /* swap space still available */ unsigned short procs; /* Number of current processes */ unsigned short pad; /* explicit padding for m68k */ unsigned long totalhigh; /* Total high memory size */ unsigned long freehigh; /* Available high memory size */ unsigned int mem_unit; /* Memory unit size in bytes */ // Padding: libc5 uses this.. char _f[20 - 2 * sizeof(long) - sizeof(int)]; }; struct vmware_sysinfo si; if (sysinfo((struct sysinfo *)&si) < 0) { return FALSE; } if (si.mem_unit == 0) { /* * Kernel versions < 2.3.23. Those kernels used a smaller sysinfo * structure, whose last meaningful field is 'procs' --hpreg */ si.mem_unit = 1; } if (totalRam) { *totalRam = (uint64)si.totalram * si.mem_unit; } if (freeRam) { *freeRam = (uint64)si.freeram * si.mem_unit; } if (totalSwap) { *totalSwap = (uint64)si.totalswap * si.mem_unit; } if (freeSwap) { *freeSwap = (uint64)si.freeswap * si.mem_unit; } return TRUE; #else // ifdef HAVE_SYSINFO NOT_IMPLEMENTED(); #endif // ifdef HAVE_SYSINFO } #endif // ifndef __APPLE__ #if defined(__linux__) || defined(__FreeBSD__) || defined(sun) /* *----------------------------------------------------------------------------- * * HostinfoGetLinuxMemoryInfoInPages -- * * Obtain the minimum memory to be maintained, total memory available, * and free memory available on the host (Linux) in pages. * * Results: * TRUE on success: '*minSize', '*maxSize' and '*currentSize' are set * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HostinfoGetLinuxMemoryInfoInPages(unsigned int *minSize, // OUT: unsigned int *maxSize, // OUT: unsigned int *currentSize) // OUT: { uint64 total; uint64 free; unsigned int cached = 0; /* * Note that the free memory provided by linux does not include buffer and * cache memory. Linux tries to use the free memory to cache file. Most of * those memory can be freed immediately when free memory is low, * so for our purposes it should be counted as part of the free memory . * There is no good way to collect the useable free memory in 2.2 and 2.4 * kernel. * * Here is our solution: The free memory we report includes cached memory. * Mmapped memory is reported as cached. The guest RAM memory, which is * mmaped to a ram file, therefore make up part of the cached memory. We * exclude the size of the guest RAM from the amount of free memory that we * report here. Since we don't know about the RAM size of other VMs, we * leave that to be done in serverd/MUI. */ if (HostinfoSysinfo(&total, &free, NULL, NULL) == FALSE) { return FALSE; } /* * Convert to pages and round up total memory to the nearest multiple of 8 * or 32 MB, since the "total" amount of memory reported by Linux is the * total physical memory - amount used by the kernel. */ if (total < (uint64)128 * 1024 * 1024) { total = ROUNDUP(total, (uint64)8 * 1024 * 1024); } else { total = ROUNDUP(total, (uint64)32 * 1024 * 1024); } *minSize = 128; // XXX - Figure out this value *maxSize = total / PAGE_SIZE; HostinfoGetMemInfo("Cached:", &cached); if (currentSize) { *currentSize = free / PAGE_SIZE + cached / (PAGE_SIZE / 1024); } return TRUE; } /* *----------------------------------------------------------------------------- * * HostinfoGetSwapInfoInPages -- * * Obtain the total swap and free swap on the host (Linux) in * pages. * * Results: * TRUE on success: '*totalSwap' and '*freeSwap' are set if not NULL * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool Hostinfo_GetSwapInfoInPages(unsigned int *totalSwap, // OUT: unsigned int *freeSwap) // OUT: { uint64 total; uint64 free; if (HostinfoSysinfo(NULL, NULL, &total, &free) == FALSE) { return FALSE; } if (totalSwap != NULL) { *totalSwap = total / PAGE_SIZE; } if (freeSwap != NULL) { *freeSwap = free / PAGE_SIZE; } return TRUE; } #endif /* *----------------------------------------------------------------------------- * * Hostinfo_GetMemoryInfoInPages -- * * Obtain the minimum memory to be maintained, total memory available, * and free memory available on the host in pages. * * Results: * TRUE on success: '*minSize', '*maxSize' and '*currentSize' are set * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool Hostinfo_GetMemoryInfoInPages(unsigned int *minSize, // OUT: unsigned int *maxSize, // OUT: unsigned int *currentSize) // OUT: { #if defined(__APPLE__) mach_msg_type_number_t count; vm_statistics_data_t stat; kern_return_t error; uint64_t memsize; size_t memsizeSize = sizeof memsize; /* * Largely inspired by * darwinsource-10.4.5/top-15/libtop.c::libtop_p_vm_sample(). */ count = HOST_VM_INFO_COUNT; error = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t) &stat, &count); if (error != KERN_SUCCESS || count != HOST_VM_INFO_COUNT) { Warning("%s: Unable to retrieve host vm stats.\n", __FUNCTION__); return FALSE; } // XXX Figure out this value. *minSize = 128; /* * XXX Hopefully this includes cached memory as well. We should check. * No. It returns only completely used pages. */ *currentSize = stat.free_count; /* * Adding up the stat values does not sum to 100% of physical memory. * The correct value is available from sysctl so we do that instead. */ if (sysctlbyname("hw.memsize", &memsize, &memsizeSize, NULL, 0) == -1) { Warning("%s: Unable to retrieve host vm hw.memsize.\n", __FUNCTION__); return FALSE; } *maxSize = memsize / PAGE_SIZE; return TRUE; #elif defined(VMX86_SERVER) uint64 total; uint64 free; VMK_ReturnStatus status; if (VmkSyscall_Init(FALSE, NULL, 0)) { status = VMKernel_GetMemSize(&total, &free); if (status == VMK_OK) { *minSize = 128; *maxSize = total / PAGE_SIZE; *currentSize = free / PAGE_SIZE; return TRUE; } } return FALSE; #else return HostinfoGetLinuxMemoryInfoInPages(minSize, maxSize, currentSize); #endif } /* *----------------------------------------------------------------------------- * * Hostinfo_GetModulePath -- * * Retrieve the full path to the executable. Not supported under VMvisor. * * The value can be controlled by the invoking user, so the calling code * should perform extra checks if it is going to use the value to * open/exec content in a security-sensitive context. * * Results: * On success: The allocated, NUL-terminated file path. * Note: This path can be a symbolic or hard link; it's just one * possible path to access the executable. * * On failure: NULL. * * Side effects: * None * *----------------------------------------------------------------------------- */ Unicode Hostinfo_GetModulePath(uint32 priv) // IN: { Unicode path; #if defined(__APPLE__) uint32_t pathSize = FILE_MAXPATH; #else uid_t uid = -1; #endif if ((priv != HGMP_PRIVILEGE) && (priv != HGMP_NO_PRIVILEGE)) { Warning("%s: invalid privilege parameter\n", __FUNCTION__); return NULL; } #if defined(__APPLE__) path = Util_SafeMalloc(pathSize); if (_NSGetExecutablePath(path, &pathSize)) { Warning(LGPFX" %s: _NSGetExecutablePath failed.\n", __FUNCTION__); free(path); return NULL; } #else #if defined(VMX86_SERVER) if (HostType_OSIsVMK()) { return NULL; } #endif // "/proc/self/exe" only exists on Linux 2.2+. ASSERT(Hostinfo_OSVersion(0) > 2 || (Hostinfo_OSVersion(0) == 2 && Hostinfo_OSVersion(1) >= 2)); if (priv == HGMP_PRIVILEGE) { uid = Id_BeginSuperUser(); } path = Posix_ReadLink("/proc/self/exe"); if (priv == HGMP_PRIVILEGE) { Id_EndSuperUser(uid); } if (path == NULL) { Warning(LGPFX" %s: readlink failed: %s\n", __FUNCTION__, Err_Errno2String(errno)); } #endif return path; } /* *---------------------------------------------------------------------- * * Hostinfo_GetLibraryPath -- * * Try and deduce the path to the library where the specified * address resides. Expected usage is that the caller will pass * in the address of one of the caller's own functions. * * Not implemented on MacOS. * * Results: * The path (which MAY OR MAY NOT BE ABSOLUTE) or NULL on failure. * * Side effects: * Memory is allocated. * *---------------------------------------------------------------------- */ char * Hostinfo_GetLibraryPath(void *addr) // IN { #ifdef __linux__ Dl_info info; if (dladdr(addr, &info)) { return Unicode_Alloc(info.dli_fname, STRING_ENCODING_DEFAULT); } return NULL; #else return NULL; #endif } /* *---------------------------------------------------------------------- * * Hostinfo_QueryProcessExistence -- * * Determine if a PID is "alive" or "dead". Failing to be able to * do this perfectly, do not make any assumption - say the answer * is unknown. * * Results: * HOSTINFO_PROCESS_QUERY_ALIVE Process is alive * HOSTINFO_PROCESS_QUERY_DEAD Process is dead * HOSTINFO_PROCESS_QUERY_UNKNOWN Don't know * * Side effects: * None * *---------------------------------------------------------------------- */ HostinfoProcessQuery Hostinfo_QueryProcessExistence(int pid) // IN: { HostinfoProcessQuery ret; int err = (kill(pid, 0) == -1) ? errno : 0; switch (err) { case 0: case EPERM: ret = HOSTINFO_PROCESS_QUERY_ALIVE; break; case ESRCH: ret = HOSTINFO_PROCESS_QUERY_DEAD; break; default: ret = HOSTINFO_PROCESS_QUERY_UNKNOWN; break; } return ret; } open-vm-tools-9.4.0-1280544/lib/misc/vthreadBase.c0000644765153500003110000011275412220061556017546 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vthreadBase.c -- * * Base thread management functionality. Does not care whether threads * are used or not. * * For full thread management (e.g. creation/destruction), see lib/thread. * * Major exposed functions and their properties: * VThreadBase_CurName - Returns a thread name. Will try to assign * a default name if none exists, but if called * reentrantly (e.g. due to ASSERT) will supply * a failsafe name instead. * VThreadBase_CurID - Always populates a VThreadID; will Panic if * this fails (extremely unlikely). * VThreadBase_SetName - Sets current thread name. Assigns a VThreadID * if one is not already present. * * Functions useful for implementing a full thread library: * VThreadBase_InitWithTLS - Sets up thread with a specific VThreadID * and name. Client supplies TLS store. * VThreadBase_SetNoIDFunc - The NoID function is called whenever an * unknown thread is seen; it must call * VThreadBase_InitWithTLS to assign a * VThreadID. Note that this function * runs with all signals masked! * VThreadBase_ForgetSelf - Clears the VThreadID for current thread, * to clean up resource usage prior to thread * exit. * Historical quirks: * * Default thread numbering starts at VTHREAD_MAX_VCPUs + 2 * to allow VThread_IsVCPU() to run efficiently. * * Most other code uses VThread_Foo instead of VThreadBase_Foo; the * public header file uses inlines to convert names. * * VThreadBase is self-initializing; by default, threads will be given * names like "vthread-1", "vthread-32", etc. Use VThread_SetName to * provide more meaningful names (often, this is the only initialization * needed). * * The default implementation supports an (effectively) unlimited number * of threads, and OS-specific primitives may be used to start the * threads. If lib/thread is used on top of this library, the lib/thread * NoID function may introduce a smaller limit. * * On Windows and Mac, there is no way to compile single-threaded, * so just make all the multi-threaded calls. * * On Linux, use some more complex logic to operate in two modes: * - if _REENTRANT is defined (or implied by -pthread), link * directly to all multithreaded symbols. * - otherwise, compile in fake-pthread functions and choose at * runtime whether to use them, depending on if pthreads are loaded. */ #if defined __linux__ && !defined _REENTRANT # define FAKE_PTHREADS #endif #if defined _WIN32 # include #else # if defined(sun) && !defined(_XOPEN_SOURCE) /* * Solaris headers don't define constants we need unless * the Posix standard is somewhat modern. Most of our builds * set this; we should chase down the oversight. */ # define _XOPEN_SOURCE 500 # endif # include # include # include # include #endif #include #include /* snprintf */ #include "vmware.h" #include "vm_atomic.h" #include "vthreadBase.h" #include "str.h" #include "util.h" #include "hashTable.h" #include "hostinfo.h" /* * Table of thread types * ===================== * OS Thread type TLS key type Max TLS keys * ----------------------------------------------------------------- * Windows HANDLE / void * DWORD 0xFFFFFFFF * (Posix) (pthread_t) (pthread_key_t) (PTHREAD_KEYS_MAX) * Linux unsigned long unsigned int 1024 * OS X 10.5 struct _opaque * unsigned long 512 * Solaris 10 unsigned int unsigned int 128 * FreeBSD 8 struct pthread * int 256 */ #if defined _WIN32 typedef DWORD VThreadBaseKeyType; #define VTHREADBASE_INVALID_KEY (VThreadBaseKeyType)(TLS_OUT_OF_INDEXES) #else typedef pthread_key_t VThreadBaseKeyType; /* PTHREAD_KEYS_MAX not defined on Android. */ #if defined __linux__ && !defined PTHREAD_KEYS_MAX #define VTHREADBASE_INVALID_KEY (VThreadBaseKeyType)(1024) #else #define VTHREADBASE_INVALID_KEY (VThreadBaseKeyType)(PTHREAD_KEYS_MAX) #endif #endif static void VThreadBaseSimpleNoID(void); static void VThreadBaseSimpleFreeID(void *tlsData); static void VThreadBaseSafeDeleteTLS(void *data); static struct { Atomic_Int key; Atomic_Int dynamicID; Atomic_Int numThreads; Atomic_Ptr nativeHash; void (*noIDFunc)(void); void (*freeIDFunc)(void *); } vthreadBaseGlobals = { { VTHREADBASE_INVALID_KEY }, { VTHREAD_ALLOCSTART_ID }, { 0 }, { 0 }, VThreadBaseSimpleNoID, VThreadBaseSimpleFreeID, }; #if defined FAKE_PTHREADS /* * glibc can either be used with pthreads or without. * * Nominally, glibc-without-pthreads is useful in cases like embedded systems * where the overhead of libpthread (in terms of memory or CPU time) is not * justified. Unfortunately for us, ESX userworlds are close enough to * embedded systems that it's easier to navigate the pain than argue in favor * of linking extraneous libraries. (Eventually, we should just link.) * * A quick run-through of all the different ways to run a Linux program: * * Compile with -pthread: (best, but uncommon) * Compiler passes -pthread to gcc, which implicitly defines _REENTRANT. * If this constant is defined, it is OK to link directly to all pthread * symbols: the program is known multithreaded at compile-time. We will * also accept somebody passing -D_REENTRANT as an indication they know * what they are doing and want compile-time threading support. * * Compile without -pthread, link with -lpthread (common) * Running multi-threaded, but this cannot be distinguised from running * single-threaded without peeking into the dynamic linker. * at run-time. * * Compile without -pthread, link without -lpthread, dlopen("libpthread.so") * This is broken. libc starts using a simplified pthread implementation, * then the dynamic load changes the implementation mid-stream. Any locks * created before the dynamic open are thus unsafe. DO NOT DO THIS. * * Compile without -pthread, link without -lpthread, no dlopen() (common) * Running single-threaded. * * * After much experimentation, the only sane way to construct VThreadBase is * with weak symbols, and require a ((sym != NULL) ? pthread_sym : fake_sym) * construct for all pthread symbols used herein. This approach has two * downsides: * - extra branch on all TLS lookups (though easily predicted) * - some compilers (gcc-4.1.0, gcc-4.1.1) have a buggy weak-symbol * optimizer. * Both of these downsides can be avoided by passing -D_REENTRANT to * the compilation of this environment and supplying -lpthread at link time. * * Rejected approaches: * - use dl_xxx to detect libpthread and link at runtime. This adds a libdl * dependency that is as bad as the libpthread dependency in the first place. * - use __libc_dlxxx@_GLIBC_PRIVATE symbols to detect libpthread and link * at runtime. This works; however, 'rpm' refuses to package binaries * with @_GLIBC_PRIVATE symbols and so builds break. * - use a fake TLS backed by a locked hash table. Unfortunately, * pthread_mutex_lock isn't async-signal-safe and we do read TLS within * our signal handlers. (Oddly enough, pthread_getspecific is not marked * as async-signal-safe either, but it happens to work fine.) * - use a fake TLS backed by an atomic hash table. Alas, our atomic * hash tables are insert-only, which causes a memory leak even if threads * exit cleanly. * * If anything here ever breaks, the best thing to do is simply admit that * this is the 21st century and always compile with -pthread. */ #if defined __GNUC__ /* gcc-4.1.0 and gcc-4.1.1 have buggy weak-symbol optimization. */ # if __GNUC__ == 4 && __GNUC_MINOR__ == 1 && \ (__GNUC_PATCHLEVEL__ == 0 || __GNUC_PATCHLEVEL__ == 1) # error Cannot build VThreadBase with weak symbols: buggy gcc version # endif #endif extern int pthread_key_create(pthread_key_t *key, void (*destr_function)(void *)) __attribute__ ((weak)); extern int pthread_key_delete(pthread_key_t key) __attribute__ ((weak)); extern int pthread_setspecific(pthread_key_t key, const void *pointer) __attribute__ ((weak)); extern void * pthread_getspecific(pthread_key_t key) __attribute__ ((weak)); extern int pthread_sigmask(int how, const sigset_t *newmask, sigset_t *oldmask) __attribute__ ((weak)); static const pthread_key_t nothreadTLSKey = 0x12345; /* Chosen to be obvious */ static void *nothreadTLSData; /* *----------------------------------------------------------------------------- * * fake_key_create -- * fake_key_delete -- * fake_setspecific -- * fake_getspecific -- * fake_sigmask -- * * Trivial implementations of equivalent pthread functions, to be used * when the weak pthread_xxx symbols are not defined (e.g. when * libpthread.so is not loaded). * * These versions always succeed and are hard-coded to assume one thread. * * NOTE: These functions will not work if libpthread is dlopen()ed. * That said, any pthread functions (like pthread_mutex_lock) also * will not work, so we have lost nothing. * * Results: * See pthread_xxx; these versions always succeed. * * Side effects: * See pthread_xxx. * *----------------------------------------------------------------------------- */ static int fake_key_create(pthread_key_t *key, void (*destr_function)(void *)) { *key = nothreadTLSKey; return 0; } static int fake_key_delete(pthread_key_t key) { /* * fake_key_delete will not be called if there are no threads because: * - fake_key_create does not fail with no threads * - single threads cannot race with themselves in VThreadBaseGetKey * (a race requires deleting extra keys) */ NOT_REACHED(); } static int fake_setspecific(pthread_key_t key, const void *pointer) { ASSERT(key == nothreadTLSKey); ASSERT(Atomic_Read(&vthreadBaseGlobals.numThreads) <= 1); nothreadTLSData = (void *)pointer; return 0; } static void * fake_getspecific(pthread_key_t key) { ASSERT(key == nothreadTLSKey); ASSERT(Atomic_Read(&vthreadBaseGlobals.numThreads) <= 1); return nothreadTLSData; } static int fake_sigmask(int how, const sigset_t *newmask, sigset_t *oldmask) { /* * Verified against glibc sources: pthread_sigmask and sigprocmask * use the same implementation for any kernel that supports * the rt_sigprocmask syscall (and all kernels we support do). */ return sigprocmask(how, newmask, oldmask); } /* * Replace all pthread_xxx calls with a runtime choice. This * code is not quite optimal; if perfection is necessary, * compile with -D_REENTRANT to link directly to pthreads. */ #define WRAP_WEAK(_fn) \ ((pthread_##_fn != NULL) ? pthread_##_fn : fake_##_fn) #define pthread_key_create WRAP_WEAK(key_create) #define pthread_key_delete WRAP_WEAK(key_delete) #define pthread_getspecific WRAP_WEAK(getspecific) #define pthread_setspecific WRAP_WEAK(setspecific) #define pthread_sigmask WRAP_WEAK(sigmask) #endif /* FAKE_PTHREADS */ /* * Code to mask all asynchronous signals * * There are some stretches where an async signal will cause reentrancy, * and that breaks allocating a VThreadID and/or setting the TLS slot * atomically. So mask all asynchronous signals; synchronous signals * (which are generally fatal) are still OK. * * Though these functions can return errors; it is not worthwhile to check * them because the inputs are hard-coded. The only errors allowed * are EINVAL for invalid argument (and they are all hardcoded valid) and * EFAULT for the addresses (and a stack pointer will not EFAULT). Besides, * these routines are used in code paths that cannot Panic without creating * a Panic-loop. */ #if defined _WIN32 #define NO_ASYNC_SIGNALS_START do { #define NO_ASYNC_SIGNALS_END } while (0) #else #define NO_ASYNC_SIGNALS_START \ do { \ sigset_t setMask, oldMask; \ sigfillset(&setMask); \ sigdelset(&setMask, SIGBUS); \ sigdelset(&setMask, SIGSEGV); \ sigdelset(&setMask, SIGILL); \ sigdelset(&setMask, SIGABRT); \ pthread_sigmask(SIG_BLOCK, &setMask, &oldMask); #define NO_ASYNC_SIGNALS_END \ pthread_sigmask(SIG_SETMASK, &oldMask, NULL); \ } while(0) #endif /* *----------------------------------------------------------------------------- * * VThreadBaseGetKey -- * * Get the host-specific TLS slot. * * Failure to allocate a TLS slot is immediately fatal. Note that * a TLS slot is generally allocated at the first of: * - VThread_Init() (e.g. uses lib/thread) * - VThread_SetName() * - a Posix signal * - a lock acquisition * Since most Panic paths do look up a thread name (and thus need a TLS * slot), a program that does not want to Panic-loop should call * one of the above functions very early to "prime" the TLS slot. * * Results: * OS-specific TLS key. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static VThreadBaseKeyType VThreadBaseGetKey(void) { VThreadBaseKeyType key = Atomic_Read(&vthreadBaseGlobals.key); if (key == VTHREADBASE_INVALID_KEY) { VThreadBaseKeyType newKey; #if defined _WIN32 newKey = TlsAlloc(); ASSERT_NOT_IMPLEMENTED(newKey != VTHREADBASE_INVALID_KEY); #else Bool success = pthread_key_create(&newKey, &VThreadBaseSafeDeleteTLS) == 0; if (success && newKey == 0) { /* * Leak TLS key 0. System libraries have a habit of destroying * it. See bugs 702818 and 773420. */ success = pthread_key_create(&newKey, &VThreadBaseSafeDeleteTLS) == 0; } ASSERT_NOT_IMPLEMENTED(success); #endif if (Atomic_ReadIfEqualWrite(&vthreadBaseGlobals.key, VTHREADBASE_INVALID_KEY, newKey) != VTHREADBASE_INVALID_KEY) { /* Race: someone else init'd */ #if defined _WIN32 TlsFree(newKey); #else pthread_key_delete(newKey); #endif } key = Atomic_Read(&vthreadBaseGlobals.key); ASSERT(key != VTHREADBASE_INVALID_KEY); } return key; } /* *----------------------------------------------------------------------------- * * VThreadBaseGetNativeHash -- * * Get the default hash table of native thread IDs. This is used by * the "simple" allocation function to enable re-using of VThreadIDs. * * Results: * An atomic HashTable *. * * Side effects: * Allocates the HashTable on first call. * *----------------------------------------------------------------------------- */ static HashTable * VThreadBaseGetNativeHash(void) { return HashTable_AllocOnce(&vthreadBaseGlobals.nativeHash, 128, HASH_INT_KEY | HASH_FLAG_ATOMIC, NULL); } /* *----------------------------------------------------------------------------- * * VThreadBaseRaw -- * * Get the per-thread data, but do not assign data if not present. * * Inlined; hitting TLS needs to be a fastpath. * * Results: * A VThreadBaseData *, or NULL if thread has not been initialized. * * Side effects: * Does NOT assign data to the TLS slot. * *----------------------------------------------------------------------------- */ static INLINE VThreadBaseData * VThreadBaseRaw(void) { VThreadBaseKeyType key = Atomic_Read(&vthreadBaseGlobals.key); if (UNLIKELY(key == VTHREADBASE_INVALID_KEY)) { key = VThreadBaseGetKey(); /* Non-inlined slow path */ } #if defined _WIN32 return (VThreadBaseData *) TlsGetValue(key); #else return (VThreadBaseData *) pthread_getspecific(key); #endif } /* *----------------------------------------------------------------------------- * * VThreadBaseCooked -- * * Get the per-thread data, and assign if there is no data. * * Results: * A VThreadBaseData *. Will succeed or ASSERT. * * Side effects: * Can assign a dynamic VThreadID to the current thread. * *----------------------------------------------------------------------------- */ static VThreadBaseData * VThreadBaseCooked(void) { VThreadBaseData *base = VThreadBaseRaw(); ASSERT(vthreadBaseGlobals.noIDFunc); if (UNLIKELY(base == NULL)) { /* Just saw a new thread. Ensure atomics are correct... */ Atomic_Init(); /* * The code between the last pthread_getspecific and the eventual * call to pthread_setspecific either needs to run with async signals * blocked or tolerate reentrancy. Simpler to just block the signals. * See bugs 295686 & 477318. Here, the problem is that we could allocate * two VThreadIDs (via a signal during the NoID callback). */ NO_ASYNC_SIGNALS_START; if (VThreadBaseRaw() == NULL) { (*vthreadBaseGlobals.noIDFunc)(); } NO_ASYNC_SIGNALS_END; base = VThreadBaseRaw(); ASSERT(base); } return base; } /* *----------------------------------------------------------------------------- * * VThreadBase_CurID -- * * Get the current thread ID. * * Results: * A VThreadID. Always succeeds. * * Side effects: * May assign a dynamic VThreadID if this thread is not known. * *----------------------------------------------------------------------------- */ VThreadID VThreadBase_CurID(void) { return VThreadBaseCooked()->id; } /* *----------------------------------------------------------------------------- * * VThreadBase_CurName -- * * Get the current thread name. * * This function always returns, at some level of reentrancy. That is, * the first call either returns successfully or Panics; the Panic may * reentrantly call this function, and that reentrant call always * returns. * * Results: * The current thread name. * * Side effects: * None. * *----------------------------------------------------------------------------- */ const char * VThreadBase_CurName(void) { static Atomic_Int curNameRecursion; VThreadBaseData *base = VThreadBaseRaw(); if (LIKELY(base != NULL)) { return base->name; } else if (Atomic_Read(&curNameRecursion) == 0) { /* Unnamed thread, try to name it. */ Atomic_Inc(&curNameRecursion); base = VThreadBaseCooked(); /* Assigns name as side effect */ Atomic_Dec(&curNameRecursion); return base->name; } else { /* * Unnamed thread, but naming it failed (recursed back to here). * The heuristic is not perfect (a second unnamed thread could * be looking for a name while the first thread names itself), * but getting here nonrecursively is unlikely and we cannot * do better about detection without thread-local storage, and * in the recursive case thread-local storage won't exist after * a failure to set up thread-local storage in the first place. * * This clause function should not ASSERT, Panic or call a Str_ * function (that can ASSERT or Panic), as the Panic handler is * very likey to query the thread name and end up right back here. * Thus, use a static buffer for a partly-sane name and hope the * Panic handler dumps enough information to figure out what went * wrong. */ static char name[48]; uintptr_t hostTid; #if defined(_WIN32) hostTid = GetCurrentThreadId(); #elif defined(__linux__) hostTid = pthread_self(); #elif defined(__APPLE__) hostTid = (uintptr_t)(void*)pthread_self(); #else hostTid = 0; #endif snprintf(name, sizeof name - 1 /* keep buffer NUL-terminated */, "host-%"FMTPD"u", hostTid); return name; } } /* *----------------------------------------------------------------------------- * * VThreadBase_InitWithTLS -- * * (Atomic) VThreadBase initialization, using caller-managed memory. * Gets the VThreadID and thread name from within that caller-managed * memory, so both must be populated. * * Always "succeeds" in initialization; the return value is useful * as an indication of whether this was the first initialization. * * Note: will NEVER overwrite an existing TLS allocation. May return a * different VThreadID than requested; this is logged and considered a bug, * code that cares about the assigned VThreadID should be using lib/thread * to manage threads, not native OS primitives. (However, there is code * like that today, so we cannot ASSERT.) * * Results: * TRUE if this is the first initialization (e.g. TLS uses supplied * pointer), FALSE otherwise. * * Side effects: * Sets TLS if this is the first initialization. * *----------------------------------------------------------------------------- */ Bool VThreadBase_InitWithTLS(VThreadBaseData *base) // IN: caller-managed storage { Bool firstTime, success; /* Require key allocation before TLS read */ VThreadBaseKeyType key = VThreadBaseGetKey(); ASSERT(base != NULL && base->id != VTHREAD_INVALID_ID); NO_ASYNC_SIGNALS_START; if (VThreadBaseRaw() == NULL) { #if defined _WIN32 /* * Windows potentially has the async-signal problem mentioned * below due to APCs, but in practice it will not happen: * APCs only get serviced at a few points (Sleep or WaitFor calls), * and we obviously do not make those between TlsGetValue and * TlsSetValue. */ success = TlsSetValue(key, base); #else /* * The code between the check of pthread_getspecific and the eventually * call to pthread_setspecific MUST run with async signals blocked, see * bugs 295686 & 477318. Here, the problem is that we could * accidentally set the TLS slot twice (it's not atomic). */ success = pthread_setspecific(key, base) == 0; #endif firstTime = TRUE; } else { success = TRUE; firstTime = FALSE; } NO_ASYNC_SIGNALS_END; /* Try not to ASSERT while signals are blocked */ ASSERT_NOT_IMPLEMENTED(success); ASSERT(!firstTime || (base == VThreadBaseRaw())); if (firstTime) { Atomic_Inc(&vthreadBaseGlobals.numThreads); } else { VThreadBaseData *realBase = VThreadBaseRaw(); /* * If this happens, it means: * 1) A thread was created w/o lib/thread but caller tried to initialize * it with a specific VThreadID. This shouldn't happen: callers * should either use lib/thread or not try to initialize VThreadIDs. * Or, * 2) An asynchronous signal interrupted the process of assigning * a VThreadID and resulted in multiple allocation. This either * means the cooking function is broken - it should block signals - or * an ASSERT triggered while setting up the VThreadID. */ Log("VThreadBase reinitialization, old: %d %s, new: %d %s.\n", realBase->id, realBase->name, base->id, base->name); } return firstTime; } /* *----------------------------------------------------------------------------- * * VThreadBaseSafeDeleteTLS -- * * Safely delete the TLS slot. Called when manually "forgetting" a thread, * or (for Posix) at TLS destruction (so we can forget the pthread_t). * * Some of the cleanups have to be performed with a valid TLS slot so * e.g. AllocTrack knows the current thread. Note that the argument is * 'void *' only so this can serve as a TLS destructor. * * Results: * None. * * Side effects: * Temporarily sets TLS, and restores it before returning. * *----------------------------------------------------------------------------- */ static void VThreadBaseSafeDeleteTLS(void *tlsData) { VThreadBaseData *data = tlsData; if (data != NULL) { if (vthreadBaseGlobals.freeIDFunc != NULL) { VThreadBaseKeyType key = VThreadBaseGetKey(); Bool success; VThreadBaseData tmpData = *data; /* * Cleanup routines (specifically, Log()) need to be called with * valid TLS, so switch to a stack-based TLS slot containing just * enough for the VThreadBase services, clean up, then clear the * TLS slot. */ #if defined _WIN32 success = TlsSetValue(key, &tmpData); #else success = pthread_setspecific(key, &tmpData) == 0; #endif ASSERT_NOT_IMPLEMENTED(success); if (vmx86_debug) { Log("Forgetting VThreadID %d (\"%s\").\n", data->id, data->name); } (*vthreadBaseGlobals.freeIDFunc)(data); #if defined _WIN32 success = TlsSetValue(key, NULL); #else success = pthread_setspecific(key, NULL) == 0; #endif ASSERT_NOT_IMPLEMENTED(success); } Atomic_Dec(&vthreadBaseGlobals.numThreads); } } /* *----------------------------------------------------------------------------- * * VThreadBase_ForgetSelf -- * * Forget the TLS parts of a thread. * * If not intending to reallocate TLS, avoid querying the thread's * VThread_CurID or VThread_CurName between this call and thread * destruction. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VThreadBase_ForgetSelf(void) { VThreadBaseKeyType key = VThreadBaseGetKey(); VThreadBaseData *data = VThreadBaseRaw(); Bool success; #if defined _WIN32 success = TlsSetValue(key, NULL); #else success = pthread_setspecific(key, NULL) == 0; #endif ASSERT_NOT_IMPLEMENTED(success); VThreadBaseSafeDeleteTLS(data); } /* *----------------------------------------------------------------------------- * * VThreadBase_SetName -- * * Override the default thread name with a new name. * * Historical: this subsumes the behavior of the old * lib/nothread VThread_Init, replacing it with something that is * optional. * * Results: * None. * * Side effects: * If current thread does not have a TLS block, one is allocated. * *----------------------------------------------------------------------------- */ void VThreadBase_SetName(const char *name) // IN: new name { uint32 len = strlen(name); VThreadBaseData *base = VThreadBaseCooked(); ASSERT(name); if (len >= sizeof base->name) { if (vmx86_debug) { Warning("%s: thread name (%s) exceeds maximum length (%u)\n", __FUNCTION__, name, (uint32) sizeof base->name -1); } len = sizeof base->name - 1; } memcpy(base->name, name, len); base->name[len] = '\0'; } /* *----------------------------------------------------------------------------- * * VThreadBaseGetNative -- * * Gets a native representation of the thread ID, which can be stored * in a pointer. * * Results: * Native representation of a thread ID. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE void * VThreadBaseGetNative(void) { /* All thread types must fit into a uintptr_t so we can set them atomically. */ #ifdef _WIN32 /* * On Windows, use a ThreadId instead of the thread handle, to avoid * holding a reference that is hard to clean up. */ ASSERT_ON_COMPILE(sizeof (DWORD) <= sizeof (void*)); return (void *)(uintptr_t)GetCurrentThreadId(); #else ASSERT_ON_COMPILE(sizeof (pthread_t) <= sizeof (void*)); return (void *)(uintptr_t)pthread_self(); #endif } #ifdef _WIN32 /* *----------------------------------------------------------------------------- * * VThreadBaseNativeIsAlive -- * * Determine if the thread described by the native thread ID is alive. * * The algorithm is not perfect - native thread IDs can be reused * by the host OS. But in such cases we will simply fail to reclaim * VThreadIDs, and such cases are rare. * * Results: * TRUE if alive, may have (rare) false positives. * FALSE if definitely dead. * * Side effects: * Makes OS calls to determine thread liveliness. * *----------------------------------------------------------------------------- */ static Bool VThreadBaseNativeIsAlive(void *native) { // Different access level due to impersonation see PR#780775 HANDLE hThread = OpenThread(Hostinfo_OpenThreadBits(), FALSE, (DWORD)(uintptr_t)native); if (hThread == NULL) { /* * An access denied error tells us that the process is alive despite * the inability of accessing its information. Commonly, access denied * occurs when a process is trying to completely protect itself (e.g. * a virus checker). */ return (GetLastError() == ERROR_ACCESS_DENIED) ? TRUE : FALSE; } else { DWORD exitCode; BOOL success = GetExitCodeThread(hThread, &exitCode); ASSERT(success); /* No known ways GetExitCodeThread can fail */ CloseHandle(hThread); return exitCode == STILL_ACTIVE; } } #endif /* *----------------------------------------------------------------------------- * * VThreadBaseSimpleNoID -- * * Default implementation of a function that is called whenever a thread * is found that contains no VThreadID. * * This implementation recycles VThreadIDs of dead threads, trying to keep * the VThreadID namespace compacted as much as possible. * * Results: * None. * * Side effects: * After running, this thread has a VThreadID with a default name. * (Or Panics before returning.) * *----------------------------------------------------------------------------- */ static void VThreadBaseSimpleNoID(void) { VThreadID newID; Bool reused = FALSE; Bool result; void *newNative = VThreadBaseGetNative(); HashTable *ht = VThreadBaseGetNativeHash(); VThreadBaseData *base; /* Require key allocation before TLS read */ VThreadBaseGetKey(); /* Before allocating a new ID, try to reclaim any old IDs. */ for (newID = 0; newID < Atomic_Read(&vthreadBaseGlobals.dynamicID); newID++) { void *newKey = (void *)(uintptr_t)newID; /* * Windows: any entry that is found and not (alive or NULL) * is reclaimable. The check is slightly racy, but the race * would only cause missing a reclaim which isn't a problem. * Posix: thread exit is hooked (via TLS destructor) and sets * entries to NULL, so any entry that is NULL is reclaimable. */ #ifdef _WIN32 void *oldNative; reused = HashTable_Lookup(ht, newKey, &oldNative) && (oldNative == NULL || !VThreadBaseNativeIsAlive(oldNative)) && HashTable_ReplaceIfEqual(ht, newKey, oldNative, newNative); #else reused = HashTable_ReplaceIfEqual(ht, newKey, NULL, newNative); #endif if (reused) { break; } } if (!reused) { void *newKey; newID = Atomic_FetchAndInc(&vthreadBaseGlobals.dynamicID); /* * Detect VThreadID overflow (~0 is used as a sentinel). * Leave a space of ~10 IDs, since the increment and bounds-check * are not atomic. */ ASSERT_NOT_IMPLEMENTED(newID < VTHREAD_INVALID_ID - 10); newKey = (void *)(uintptr_t)newID; result = HashTable_Insert(ht, newKey, newNative); ASSERT_NOT_IMPLEMENTED(result); } /* ID picked. Now do the important stuff. */ base = Util_SafeCalloc(1, sizeof *base); base->id = newID; Str_Sprintf(base->name, sizeof base->name, "vthread-%u", newID); result = VThreadBase_InitWithTLS(base); ASSERT(result); if (vmx86_debug && reused) { Log("VThreadBase reused VThreadID %d.\n", newID); } if (Atomic_Read(&vthreadBaseGlobals.numThreads) > 1) { LOG_ONCE(("VThreadBase detected multiple threads.\n")); } } /* *----------------------------------------------------------------------------- * * VThreadBaseSimpleFreeID -- * * Default TLS storage destructor. * * The SimpleNoID function uses malloc'd memory to allow an unlimited * number of VThreads in the process, and uses a hash table to track * live VThreadIDs so to allow VThreadID recycling. Both of these * require cleanup. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void VThreadBaseSimpleFreeID(void *tlsData) { HashTable *ht = VThreadBaseGetNativeHash(); VThreadBaseData *data = tlsData; const void *hashKey = (const void *)(uintptr_t)data->id; HashTable_ReplaceOrInsert(ht, hashKey, NULL); free(data); } /* *----------------------------------------------------------------------------- * * VThreadBase_SetNoIDFunc -- * * Sets the hook function to be called when a thread is found with * no VThreadID. The hook function is expected to call * VThreadBase_InitWithTLS() with a valid new ID. * * On Posix, this callback is called with signals masked to prevent * accidental double-allocation of IDs. On Windows, the constraint is * that the callback cannot service an APC between allocating an ID and * initializing the thread with that ID, as such is likely * to accidentally double-allocate IDs. * * An optional destructor can be supplied to clean up memory. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VThreadBase_SetNoIDFunc(void (*hookFunc)(void), // IN: new hook function void (*destroyFunc)(void *)) // IN/OPT: new TLS destructor { ASSERT(hookFunc); /* * The hook function can only be set once, and must be set before * any VThreadIDs are allocated so that the hook can control the VThreadID * namespace. * * If the process has had only a single thread, that thread can be forgotten * via VThreadBase_ForgetSelf() and this function safely called. */ ASSERT(vthreadBaseGlobals.noIDFunc == VThreadBaseSimpleNoID && Atomic_Read(&vthreadBaseGlobals.numThreads) == 0); vthreadBaseGlobals.noIDFunc = hookFunc; vthreadBaseGlobals.freeIDFunc = destroyFunc; } #if !defined _WIN32 /* *----------------------------------------------------------------------------- * * VThreadBase_IsInSignal -- * * Accessor for whether current thread is or is not in a signal. * lib/sig handles keeping this accurate. * * Results: * Returns TRUE if a signal handler is somewhere on the stack. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool VThreadBase_IsInSignal(void) { VThreadBaseData *base = VThreadBaseCooked(); return Atomic_Read(&base->signalNestCount) > 0; } /* *----------------------------------------------------------------------------- * * VThreadBase_SetIsInSignal -- * * Marks the current thread as or as not being inside a signal * handler. * * Results: * None. * * Side effects: * As above. * *----------------------------------------------------------------------------- */ void VThreadBase_SetIsInSignal(VThreadID tid, // IN: Bool isInSignal) // IN: { VThreadBaseData *base = VThreadBaseCooked(); /* It is an error to clear isInSignal while not in a signal. */ ASSERT(Atomic_Read(&base->signalNestCount) > 0 || isInSignal); Atomic_Add(&base->signalNestCount, isInSignal ? 1 : -1); } /* *----------------------------------------------------------------------------- * * VThreadBase_SigMask -- * * Wrapper for pthread_sigmask that uses VThreadBase's no-dependency * magic to get the effects of pthread_sigmask without actually * depending on lib/pthread. * * Results: * See 'man pthread_setmask'. * * Side effects: * See 'man pthread_setmask'. * *----------------------------------------------------------------------------- */ int VThreadBase_SigMask(int how, // IN: const sigset_t *newmask, // IN: sigset_t *oldmask) // IN: { return pthread_sigmask(how, newmask, oldmask); } #endif open-vm-tools-9.4.0-1280544/lib/misc/dynbuf.c0000644765153500003110000002221312220061556016573 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * dynbuf.c -- * * Dynamic buffers --hpreg */ #include #include #include #include "vmware.h" #include "dynbuf.h" /* *----------------------------------------------------------------------------- * * DynBuf_Init -- * * Dynamic buffer constructor --hpreg * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void DynBuf_Init(DynBuf *b) // OUT: { ASSERT(b); b->data = NULL; b->size = 0; b->allocated = 0; } /* *----------------------------------------------------------------------------- * * DynBuf_Destroy -- * * Dynamic buffer destructor --hpreg * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void DynBuf_Destroy(DynBuf *b) // IN/OUT: { ASSERT(b); free(b->data); DynBuf_Init(b); } /* *----------------------------------------------------------------------------- * * DynBuf_AllocGet -- * * Retrieve a pointer to the data contained in a dynamic buffer. Return * a copy of that data. * * Results: * The pointer to the data. NULL on out of memory failure. * * Side effects: * Allocates memory. * *----------------------------------------------------------------------------- */ void * DynBuf_AllocGet(DynBuf const *b) // IN { void *new_data; ASSERT(b); new_data = malloc(b->size); if (new_data) { memcpy(new_data, b->data, b->size); } return new_data; } /* *----------------------------------------------------------------------------- * * DynBuf_Attach -- * * Grants ownership of the specified buffer to the DynBuf * object. If there is an existing buffer, it is freed. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ void DynBuf_Attach(DynBuf *b, // IN size_t size, // IN void *data) // IN { ASSERT(b); ASSERT((size == 0) == (data == NULL)); free(b->data); b->data = data; b->size = b->allocated = size; } /* *----------------------------------------------------------------------------- * * DynBuf_Detach -- * * Releases ownership of the buffer stored in the DynBuf object, * and returns a pointer to it. * * Results: * The pointer to the data. * * Side effects: * None * *----------------------------------------------------------------------------- */ void * DynBuf_Detach(DynBuf *b) // IN { void *data; ASSERT(b); data = b->data; b->data = NULL; b->allocated = 0; return data; } /* *----------------------------------------------------------------------------- * * DynBufRealloc -- * * Reallocate a dynamic buffer --hpreg * * Results: * TRUE on success * FALSE on failure (not enough memory) * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool DynBufRealloc(DynBuf *b, // IN: size_t newAllocated) // IN: { void *new_data; ASSERT(b); new_data = realloc(b->data, newAllocated); if (new_data == NULL && newAllocated) { /* Not enough memory */ return FALSE; } b->data = new_data; b->allocated = newAllocated; return TRUE; } /* *----------------------------------------------------------------------------- * * DynBuf_Enlarge -- * * Enlarge a dynamic buffer. The resulting dynamic buffer is guaranteed to * be larger than the one you passed, and at least 'minSize' bytes * large --hpreg * * Results: * TRUE on success * FALSE on failure (not enough memory) * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool DynBuf_Enlarge(DynBuf *b, // IN: size_t minSize) // IN: { size_t newAllocated; ASSERT(b); newAllocated = b->allocated ? #if defined(DYNBUF_DEBUG) b->allocated + 1 #else /* * Double the previously allocated size if it is less * than 256KB; otherwise grow it linearly by 256KB */ (b->allocated < 256 * 1024 ? b->allocated * 2 : b->allocated + 256 * 1024) #endif : #if defined(DYNBUF_DEBUG) 1 #else /* * Initial size: 1 KB. Most buffers are smaller than * that --hpreg */ 1 << 10 #endif ; if (minSize > newAllocated) { newAllocated = minSize; } /* * Prevent integer overflow. We can use this form of checking specifically * because a multiple by 2 is used (in the worst case). This type of * checking does not work in the general case. */ if (newAllocated < b->allocated) { return FALSE; } return DynBufRealloc(b, newAllocated); } /* *----------------------------------------------------------------------------- * * DynBuf_Append -- * * Append data at the end of a dynamic buffer. 'size' is the size of the * data. If it is <= 0, no operation is performed --hpreg * * Results: * TRUE on success * FALSE on failure (not enough memory) * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool DynBuf_Append(DynBuf *b, // IN void const *data, // IN size_t size) // IN { size_t new_size; ASSERT(b); if (size <= 0) { return TRUE; } ASSERT(data); new_size = b->size + size; if (new_size < b->size) { // Prevent integer overflow return FALSE; } if (new_size > b->allocated) { /* Not enough room */ if (DynBuf_Enlarge(b, new_size) == FALSE) { return FALSE; } } memcpy(b->data + b->size, data, size); b->size = new_size; return TRUE; } /* *----------------------------------------------------------------------------- * * DynBuf_SafeInternalAppend -- * * Append data at the end of a dynamic buffer. Memory allocation failure * are handled the same way as Util_SafeMalloc, that is to say, with a * Panic. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void DynBuf_SafeInternalAppend(DynBuf *b, // IN void const *data, // IN size_t size, // IN char const *file, // IN unsigned int lineno) // IN { if (!DynBuf_Append(b, data, size)) { Panic("Unrecoverable memory allocation failure at %s:%u\n", file, lineno); } } /* *----------------------------------------------------------------------------- * * DynBuf_Trim -- * * Reallocate a dynamic buffer to the exact size it occupies --hpreg * * Results: * TRUE on success * FALSE on failure (not enough memory) * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool DynBuf_Trim(DynBuf *b) // IN { ASSERT(b); return DynBufRealloc(b, b->size); } /* *----------------------------------------------------------------------------- * * DynBuf_Copy -- * * Copies all data and metadata from src dynbuff to dest dynbuf. * * Dest should be an initialized DynBuf of alloced length zero * to prevent memory leaks. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool DynBuf_Copy(DynBuf *src, // IN DynBuf *dest) // OUT { ASSERT(src); ASSERT(dest); ASSERT(!dest->data); dest->data = malloc(src->allocated); if (dest->data == NULL) { return FALSE; } dest->size = src->size; dest->allocated = src->allocated; memcpy(dest->data, src->data, src->size); return TRUE; } open-vm-tools-9.4.0-1280544/lib/misc/base64.c0000644765153500003110000004745312220061556016405 0ustar dtormts/* * Copyright (c) 1996, 1998 by Internet Software Consortium. * * 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM 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. */ /* * Portions Copyright (c) 1995 by International Business Machines, Inc. * * International Business Machines, Inc. (hereinafter called IBM) grants * permission under its copyrights to use, copy, modify, and distribute this * Software with or without fee, provided that the above copyright notice and * all paragraphs of this notice appear in all copies, and that the name of IBM * not be used in connection with the marketing of any product incorporating * the Software or modifications thereof, without specific, written prior * permission. * * To the extent it has a right to do so, IBM grants an immunity from suit * under its patents, if any, for the use, sale or manufacture of products to * the extent that such products are used for performing Domain Name System * dynamic updates in TCP/IP networks by means of the Software. No immunity is * granted for any product per se or for any other function of any product. * * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include #include #include #include #include #include "vm_basic_types.h" #include "vm_assert.h" #include "base64.h" static const char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const char Pad64 = '='; // Special markers enum { ILLEGAL = -1, EOM = -2, WS = -3 }; /* * Reverse byte map used for decoding. Except for specials (negative values), contains the index * into Base64[] where given value is found, ie: base64Reverse[Base64[n]] = n, for 0 <= n < 64 * * This static initialization replaces, and should have identical result to, this runtime init: * * for (i = 0; i < 256; ++i) { * base64Reverse[i] = isspace(i) ? WS : ILLEGAL; * } * base64Reverse['\0'] = EOM; * base64Reverse['='] = EOM; * for (i = 0; Base64[i]; ++i) { * base64Reverse[(unsigned)Base64[i]] = (char) i; * } */ static const signed char base64Reverse[256] = { EOM, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* 00-07 */ ILLEGAL, WS, WS, WS, WS, WS, ILLEGAL, ILLEGAL, /* 08-0F */ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* 10-17 */ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* 18-1F */ WS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* 20-27 */ ILLEGAL, ILLEGAL, ILLEGAL, 62, ILLEGAL, ILLEGAL, ILLEGAL, 63, /* 28-2F */ 52, 53, 54, 55, 56, 57, 58, 59, /* 30-37 */ 60, 61, ILLEGAL, ILLEGAL, ILLEGAL, EOM, ILLEGAL, ILLEGAL, /* 38-3F */ ILLEGAL, 0, 1, 2, 3, 4, 5, 6, /* 40-47 */ 7, 8, 9, 10, 11, 12, 13, 14, /* 48-4F */ 15, 16, 17, 18, 19, 20, 21, 22, /* 50-57 */ 23, 24, 25, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* 58-5F */ ILLEGAL, 26, 27, 28, 29, 30, 31, 32, /* 60-67 */ 33, 34, 35, 36, 37, 38, 39, 40, /* 68-6F */ 41, 42, 43, 44, 45, 46, 47, 48, /* 70-77 */ 49, 50, 51, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* 78-7F */ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* 80-87 */ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* 88-8F */ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* 90-97 */ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* 98-9F */ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* A0-A7 */ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* A8-AF */ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* B0-B7 */ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* B8-BF */ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* C0-C7 */ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* C8-CF */ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* D0-D7 */ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* D8-DF */ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* E0-E7 */ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* E8-EF */ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /* F0-F7 */ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL }; /* F8-FF */ /* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) The following encoding technique is taken from RFC 1521 by Borenstein and Freed. It is reproduced here in a slightly edited form for convenience. A 65-character subset of US-ASCII is used, enabling 6 bits to be represented per printable character. (The extra 65th character, "=", is used to signify a special processing function.) The encoding process represents 24-bit groups of input bits as output strings of 4 encoded characters. Proceeding from left to right, a 24-bit input group is formed by concatenating 3 8-bit input groups. These 24 bits are then treated as 4 concatenated 6-bit groups, each of which is translated into a single digit in the base64 alphabet. Each 6-bit group is used as an index into an array of 64 printable characters. The character referenced by the index is placed in the output string. Table 1: The Base64 Alphabet Value Encoding Value Encoding Value Encoding Value Encoding 0 A 17 R 34 i 51 z 1 B 18 S 35 j 52 0 2 C 19 T 36 k 53 1 3 D 20 U 37 l 54 2 4 E 21 V 38 m 55 3 5 F 22 W 39 n 56 4 6 G 23 X 40 o 57 5 7 H 24 Y 41 p 58 6 8 I 25 Z 42 q 59 7 9 J 26 a 43 r 60 8 10 K 27 b 44 s 61 9 11 L 28 c 45 t 62 + 12 M 29 d 46 u 63 / 13 N 30 e 47 v 14 O 31 f 48 w (pad) = 15 P 32 g 49 x 16 Q 33 h 50 y Special processing is performed if fewer than 24 bits are available at the end of the data being encoded. A full encoding quantum is always completed at the end of a quantity. When fewer than 24 input bits are available in an input group, zero bits are added (on the right) to form an integral number of 6-bit groups. Padding at the end of the data is performed using the '=' character. Since all base64 input is an integral number of octets, only the ------------------------------------------------- following cases can arise: (1) the final quantum of encoding input is an integral multiple of 24 bits; here, the final unit of encoded output will be an integral multiple of 4 characters with no "=" padding, (2) the final quantum of encoding input is exactly 8 bits; here, the final unit of encoded output will be two characters followed by two "=" padding characters, or (3) the final quantum of encoding input is exactly 16 bits; here, the final unit of encoded output will be three characters followed by one "=" padding character. */ /* *---------------------------------------------------------------------------- * * Base64_Encode -- * * Base64-encodes srcLength bytes from src and stores result in dst. * * Results: * TRUE if the destination held enough space for the decoded result, * FALSE otherwise. * * Side effects: * Updates dstSize with the number of encoded bytes (excluding the * terminating '\0'). * *---------------------------------------------------------------------------- */ Bool Base64_Encode(uint8 const *src, // IN: size_t srcSize, // IN: char *dst, // OUT: size_t dstMax, // IN: max result length, including NUL byte size_t *dstSize) // OUT: result length, may be NULL { char *dst0 = dst; ASSERT(src || srcSize == 0); ASSERT(dst); if (4 * ((srcSize + 2) / 3) >= dstMax) { if (dstSize) { *dstSize = 0; } return FALSE; } while (LIKELY(srcSize > 2)) { dst[0] = Base64[src[0] >> 2]; dst[1] = Base64[(src[0] & 0x03) << 4 | src[1] >> 4]; dst[2] = Base64[(src[1] & 0x0f) << 2 | src[2] >> 6]; dst[3] = Base64[src[2] & 0x3f]; srcSize -= 3; src += 3; dst += 4; } /* Now we worry about padding. */ if (LIKELY(srcSize--)) { uint8 src1 = srcSize ? src[1] : 0; dst[0] = Base64[src[0] >> 2]; dst[1] = Base64[(src[0] & 0x03) << 4 | src1 >> 4]; dst[2] = srcSize ? Base64[(src1 & 0x0f) << 2] : Pad64; dst[3] = Pad64; dst += 4; } dst[0] = '\0'; /* Returned value doesn't count \0. */ if (dstSize) { *dstSize = dst - dst0; } return TRUE; } #ifdef __I_WANT_TO_TEST_THIS__ main() { struct { char *in, *out; } tests[] = { {"", ""}, {"MQ==", "1"}, {"MTI=", "12"}, {"MTIz", "123"}, {"MTIzNA==", "1234"}, {"SGVsbG8gRWR3YXJkIGFuZCBKb2huIQ==","Hello Edward and John!"}, {NULL, NULL} }, *test; size_t bufMax; if (1) { for (bufMax = 0; bufMax < 7; ++bufMax) { char buf[999]; size_t bufSize; if (bufMax == 6) { bufMax = sizeof buf; } printf("\nBuffer size %ld:\n", bufMax); test = tests; for (; test->in; ++test) { Bool r; r = Base64_Decode(test->in, buf, bufMax, &bufSize); if ((bufMax > strlen(test->out)) && (bufSize < strlen(test->out))) { printf("Decoding of %s failed. Decoded size %ld < expected %ld\n", test->in, bufSize, strlen(test->out)); } if (memcmp(test->out, buf, bufSize) != 0) { printf("Decoding of %s failed. Got %s (%ld), not %s\n", test->in, buf, bufSize, test->out); } else { printf("Good: %s -> %s (%ld)\n", test->in, buf, bufSize); } r = Base64_Encode(test->out, strlen(test->out), buf, bufMax, &bufSize); buf[bufMax] = 0; if (bufMax <= strlen(test->in) && r == 0) { printf("Good: %s. Failed for bufMax %ld (required %ld)\n", test->out, bufMax, strlen(test->in)); } else { if (!r || bufSize != strlen(test->in) || strncmp(test->in, buf, bufSize) != 0) { printf("Encoding of %s failed. r = %d. Got %s (%ld), not %s\n", test->out, r, buf, bufSize, test->in); } else { printf("Good: %s -> %s (%ld)\n", test->out, buf, bufSize); } } } } } for (bufMax = 0; bufMax < 100000; ++bufMax) { char random_in[8000]; char random_out[16000]; size_t bufSize; Bool r = Base64_Encode(random_in, sizeof random_in, random_out, sizeof random_out, &bufSize); if (!r) { printf("Encoding failed.\n"); } } } #endif /* *---------------------------------------------------------------------------- * * Base64_Decode -- * * Skips all whitespace anywhere. Converts characters, four at * a time, starting at (or after) src from base - 64 numbers into three * 8 bit bytes in the target area. Returns the number of data bytes * stored at the target in the provided out parameter. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool Base64_Decode(char const *in, // IN: uint8 *out, // OUT: size_t outSize, // IN: size_t *dataLength) // OUT: { return Base64_ChunkDecode(in, -1, out, outSize, dataLength); } /* *---------------------------------------------------------------------------- * * Base64_ChunkDecode -- * * Skips all whitespace anywhere. Converts characters, four at * a time, starting at (or after) src from base - 64 numbers into three * 8 bit bytes in the target area. Conversion stops after inSize (which * must be a multiple of 4) characters, or an EOM marker. Returns the * number of data bytes stored at the target in the provided out parameter. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool Base64_ChunkDecode(char const *in, // IN: size_t inSize, // IN: uint8 *out, // OUT: size_t outSize, // IN: size_t *dataLength) // OUT: { uint32 b = 0; int n = 0; uintptr_t i = 0; size_t inputIndex = 0; ASSERT(in); ASSERT(out || outSize == 0); ASSERT(dataLength); ASSERT((inSize == -1) || (inSize % 4) == 0); *dataLength = 0; i = 0; for (;inputIndex < inSize;) { int p = base64Reverse[(unsigned char)in[inputIndex]]; if (UNLIKELY(p < 0)) { switch (p) { case WS: inputIndex++; break; case EOM: *dataLength = i; return TRUE; case ILLEGAL: default: return FALSE; } } else { inputIndex++; if (UNLIKELY(i >= outSize)) { return FALSE; } b = (b << 6) | p; n += 6; if (LIKELY(n >= 8)) { n -= 8; out[i++] = b >> n; } } } *dataLength = i; return TRUE; } /* *---------------------------------------------------------------------------- * * Base64_ValidEncoding -- * * Returns TRUE if the specified input buffer is valid Base64 input. * * Results: * TRUE or FALSE. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool Base64_ValidEncoding(char const *src, // IN: size_t srcLength) // IN: { size_t i; ASSERT(src); for (i = 0; i < srcLength; i++) { uint8 c = src[i]; /* MSVC CRT will die on negative arguments to is* */ if (!isalpha(c) && !isdigit(c) && c != '+' && c != '=' && c != '/') { return FALSE; } } return TRUE; } /* *---------------------------------------------------------------------------- * * Base64_EncodedLength -- * * Given a binary buffer, how many bytes would it take to encode it. * * Results: * Number of bytes needed to encode, including terminating NUL byte. * * Side effects: * None. * *---------------------------------------------------------------------------- */ size_t Base64_EncodedLength(uint8 const *src, // IN: size_t srcLength) // IN: { return ((srcLength + 2) / 3 * 4) + 1; } /* *---------------------------------------------------------------------------- * * Base64_DecodedLength -- * * Given a base64 encoded string, how many bytes do we need to decode it. * Assumes no whitespace. This is not necessarily the length of the * decoded data (Base64_Decode requires a few extra bytes... don't blame * me, I didn't write it). * * Results: * Number of bytes needed to decode input. * * Side effects: * None. * *---------------------------------------------------------------------------- */ size_t Base64_DecodedLength(char const *src, // IN: size_t srcLength) // IN: { size_t length; ASSERT(src); length = srcLength / 4 * 3; // PR 303173 - do the following check to avoid a negative value returned // from this function. Note: length can only be in a multiple of 3 if (length > 2) { if (src[srcLength-1] == '=') { length--; } if (src[srcLength-2] == '=') { length--; } } return length; } /* *----------------------------------------------------------------------------- * * Base64_EasyEncode -- * * Base64-encode 'data' into a NUL-terminated string. * * Results: * On success: TRUE. '*target' is set to an allocated string, that the * caller must eventually free(). * On failure: FALSE. '*target' is set to NULL. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool Base64_EasyEncode(const uint8 *src, // IN: data to encode size_t srcLength, // IN: data size char **target) // OUT: encoded string { Bool succeeded = FALSE; size_t size; ASSERT(src); ASSERT(target); size = Base64_EncodedLength(src, srcLength); *target = (char *) malloc(size); if (!*target) { goto exit; } if (!Base64_Encode(src, srcLength, *target, size, NULL)) { goto exit; } succeeded = TRUE; exit: if (!succeeded) { free(*target); *target = NULL; } return succeeded; } /* *----------------------------------------------------------------------------- * * Base64_EasyDecode -- * * Base64-decode 'src' into a buffer. * * Results: * TRUE on success, FALSE otherwise, plus the decoded data on success. * Caller must free 'target' with free(). * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool Base64_EasyDecode(const char *src, // IN: data to decode uint8 **target, // OUT: decoded data size_t *targSize) // OUT: data size { Bool succeeded = FALSE; size_t theDataSize; uint8 *theData; ASSERT(src); ASSERT(target); ASSERT(targSize); theDataSize = Base64_DecodedLength(src, strlen(src)); theData = (uint8 *) malloc(theDataSize); if (!theData) { goto exit; } if (!Base64_Decode(src, theData, theDataSize, &theDataSize)) { free(theData); goto exit; } *target = theData; *targSize = theDataSize; succeeded = TRUE; exit: if (!succeeded) { *target = NULL; *targSize = 0; } return succeeded; } open-vm-tools-9.4.0-1280544/lib/misc/posixPosix.c0000644765153500003110000017725712220061556017514 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #if !defined(_POSIX_PTHREAD_SEMANTICS) && defined(sun) #define _POSIX_PTHREAD_SEMANTICS 1 // Needed to get POSIX-correct getpw*_r() on Solaris #endif #define UNICODE_BUILDING_POSIX_WRAPPERS #if __linux__ #define _GNU_SOURCE // Needed to get euidaccess() #endif #include #include #include #include #include #include #include #include #include #include "su.h" #include #include #include #include #include #if defined(__APPLE__) #include #include #include #include #include #include #include #include #include #include #elif defined(__FreeBSD__) #include #include #elif defined(sun) #include #include #else #include #include #include #endif #if (!defined(__FreeBSD__) || __FreeBSD_release >= 503001) && !defined __ANDROID__ #define VM_SYSTEM_HAS_GETPWNAM_R 1 #define VM_SYSTEM_HAS_GETPWUID_R 1 #define VM_SYSTEM_HAS_GETGRNAM_R 1 #endif # if defined(__FreeBSD__) # include // PATH_MAX # else # include // PATH_MAX # endif #include "vmware.h" #include "posixInt.h" #if defined(sun) #include "hashTable.h" // For setenv emulation #endif #include "vm_basic_defs.h" static struct passwd *GetpwInternal(struct passwd *pw); static int GetpwInternal_r(struct passwd *pw, char *buf, size_t size, struct passwd **ppw); #if defined __ANDROID__ /* * Android doesn't support getmntent_r(), getpwent() or setmntent(). */ #define NO_GETMNTENT_R #define NO_GETPWENT #define NO_SETMNTENT EXTERN int truncate(const char *, off_t); #endif /* *---------------------------------------------------------------------- * * Posix_Open -- * * Open a file using POSIX open. * * Results: * -1 error * >= 0 success (file descriptor) * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Open(ConstUnicode pathName, // IN: int flags, // IN: ...) // IN: { char *path; mode_t mode = 0; int fd; if (!PosixConvertToCurrent(pathName, &path)) { return -1; } if ((flags & O_CREAT) != 0) { va_list a; /* * The FreeBSD tools compiler * (toolchain/lin32/gcc-4.1.2-5/bin/i686-freebsd5.0-gcc) * wants us to use va_arg(a, int) instead of va_arg(a, mode_t), * so oblige. -- edward */ va_start(a, flags); ASSERT_ON_COMPILE(sizeof (int) >= sizeof(mode_t)); mode = va_arg(a, int); va_end(a); } fd = open(path, flags, mode); free(path); return fd; } /* *---------------------------------------------------------------------- * * Posix_Creat -- * * Create a file via POSIX creat() * * Results: * -1 Error * >= 0 File descriptor (success) * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Creat(ConstUnicode pathName, // IN: mode_t mode) // IN: { return Posix_Open(pathName, O_CREAT | O_WRONLY | O_TRUNC, mode); } /* *---------------------------------------------------------------------- * * Posix_Fopen -- * * Open a file via POSIX fopen() * * Results: * A file pointer, or NULL on error. * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ FILE * Posix_Fopen(ConstUnicode pathName, // IN: const char *mode) // IN: { char *path; FILE *stream; ASSERT(mode); if (!PosixConvertToCurrent(pathName, &path)) { return NULL; } stream = fopen(path, mode); free(path); return stream; } /* *---------------------------------------------------------------------- * * Posix_Stat -- * * POSIX stat() * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Stat(ConstUnicode pathName, // IN: struct stat *statbuf) // IN: { char *path; int ret; if (!PosixConvertToCurrent(pathName, &path)) { return -1; } ret = stat(path, statbuf); free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_Chmod -- * * POSIX chmod() * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Chmod(ConstUnicode pathName, // IN: mode_t mode) // IN: { char *path; int ret; if (!PosixConvertToCurrent(pathName, &path)) { return -1; } ret = chmod(path, mode); free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_Rename -- * * POSIX rename(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Rename(ConstUnicode fromPathName, // IN: ConstUnicode toPathName) // IN: { char *toPath; char *fromPath; int result; if (!PosixConvertToCurrent(fromPathName, &fromPath)) { return -1; } if (!PosixConvertToCurrent(toPathName, &toPath)) { free(fromPath); return -1; } result = rename(fromPath, toPath); free(toPath); free(fromPath); return result; } /* *---------------------------------------------------------------------- * * Posix_Unlink -- * * POSIX unlink(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Unlink(ConstUnicode pathName) // IN: { char *path; int ret; if (!PosixConvertToCurrent(pathName, &path)) { return -1; } ret = unlink(path); free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_Rmdir -- * * POSIX rmdir(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Rmdir(ConstUnicode pathName) // IN: { char *path; int ret; if (!PosixConvertToCurrent(pathName, &path)) { return -1; } ret = rmdir(path); free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_Freopen -- * * Open a file via POSIX freopen() * * Results: * -1 Error * >= 0 File descriptor (success) * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ FILE * Posix_Freopen(ConstUnicode pathName, // IN: const char *mode, // IN: FILE *input_stream) // IN: { char *path; FILE *stream; ASSERT(mode); if (!PosixConvertToCurrent(pathName, &path)) { return NULL; } stream = freopen(path, mode, input_stream); free(path); return stream; } /* *---------------------------------------------------------------------- * * Posix_Access -- * * POSIX access(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Access(ConstUnicode pathName, // IN: int mode) // IN: { char *path; int ret; if (!PosixConvertToCurrent(pathName, &path)) { return -1; } #if defined(VMX86_SERVER) /* * ESX can return EINTR making retries a necessity. This is a bug in * ESX that is being worked around here - POSIX says access cannot return * EINTR. */ do { ret = access(path, mode); } while ((ret == -1) && (errno == EINTR)); #else ret = access(path, mode); #endif free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_EuidAccess -- * * POSIX euidaccess(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_EuidAccess(ConstUnicode pathName, // IN: int mode) // IN: { #if defined(GLIBC_VERSION_24) char *path; int ret; if (!PosixConvertToCurrent(pathName, &path)) { return -1; } ret = euidaccess(path, mode); free(path); return ret; #else errno = ENOSYS; return -1; #endif } /* *---------------------------------------------------------------------- * * Posix_Utime -- * * POSIX utime(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Utime(ConstUnicode pathName, // IN: const struct utimbuf *times) // IN: { char *path; int ret; if (!PosixConvertToCurrent(pathName, &path)) { return -1; } ret = utime(path, times); free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_Perror -- * * POSIX perror() * * Results: * Appends error message corresponding to errno to the passed in string, * and puts the result on stderr. * * Side effects: * Message printed to stderr. * *---------------------------------------------------------------------- */ void Posix_Perror(ConstUnicode str) // IN: { char *tmpstr = Unicode_GetAllocBytes(str, STRING_ENCODING_DEFAULT); // ignore conversion error silently perror(tmpstr); free(tmpstr); } /* *---------------------------------------------------------------------- * * Posix_Pathconf -- * * POSIX pathconf() * * Results: * Returns the limit, -1 if limit doesn't exist or on error * * Side effects: * errno is set on error. * *---------------------------------------------------------------------- */ long Posix_Pathconf(ConstUnicode pathName, // IN: int name) // IN: { char *path; long ret; if (!PosixConvertToCurrent(pathName, &path)) { return -1; } ret = pathconf(path, name); free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_Popen -- * * Open a file using POSIX popen(). * * Results: * -1 error * >= 0 success (file descriptor) * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ FILE * Posix_Popen(ConstUnicode pathName, // IN: const char *mode) // IN: { char *path; FILE *stream; ASSERT(mode); if (!PosixConvertToCurrent(pathName, &path)) { return NULL; } stream = popen(path, mode); free(path); return stream; } /* *---------------------------------------------------------------------- * * Posix_Mknod -- * * POSIX mknod(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Mknod(ConstUnicode pathName, // IN: mode_t mode, // IN: dev_t dev) // IN: { char *path; int ret; if (!PosixConvertToCurrent(pathName, &path)) { return -1; } ret = mknod(path, mode, dev); free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_Chown -- * * POSIX chown(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Chown(ConstUnicode pathName, // IN: uid_t owner, // IN: gid_t group) // IN: { char *path; int ret; if (!PosixConvertToCurrent(pathName, &path)) { return -1; } ret = chown(path, owner, group); free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_Lchown -- * * POSIX lchown(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Lchown(ConstUnicode pathName, // IN: uid_t owner, // IN: gid_t group) // IN: { char *path; int ret; if (!PosixConvertToCurrent(pathName, &path)) { return -1; } ret = lchown(path, owner, group); free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_Link -- * * POSIX link(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Link(ConstUnicode pathName1, // IN: ConstUnicode pathName2) // IN: { char *path1; char *path2; int ret; if (!PosixConvertToCurrent(pathName1, &path1)) { return -1; } if (!PosixConvertToCurrent(pathName2, &path2)) { free(path1); return -1; } ret = link(path1, path2); free(path1); free(path2); return ret; } /* *---------------------------------------------------------------------- * * Posix_Symlink -- * * POSIX symlink(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Symlink(ConstUnicode pathName1, // IN: ConstUnicode pathName2) // IN: { char *path1; char *path2; int ret; if (!PosixConvertToCurrent(pathName1, &path1)) { return -1; } if (!PosixConvertToCurrent(pathName2, &path2)) { free(path1); return -1; } ret = symlink(path1, path2); free(path1); free(path2); return ret; } /* *---------------------------------------------------------------------- * * Posix_Mkfifo -- * * POSIX mkfifo(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Mkfifo(ConstUnicode pathName, // IN: mode_t mode) // IN: { char *path; int ret; if (!PosixConvertToCurrent(pathName, &path)) { return -1; } ret = mkfifo(path, mode); free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_Truncate -- * * POSIX truncate(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Truncate(ConstUnicode pathName, // IN: off_t length) // IN: { char *path; int ret; if (!PosixConvertToCurrent(pathName, &path)) { return -1; } ret = truncate(path, length); free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_Utimes -- * * POSIX utimes(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Utimes(ConstUnicode pathName, // IN: const struct timeval *times) // IN: { char *path; int ret; if (!PosixConvertToCurrent(pathName, &path)) { return -1; } ret = utimes(path, times); free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_Execl -- * * POSIX execl(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Execl(ConstUnicode pathName, // IN: ConstUnicode arg0, ...) // IN: { int ret = -1; char *path; va_list vl; char **argv = NULL; int i, count = 0; if (!PosixConvertToCurrent(pathName, &path)) { goto exit; } if (arg0) { count = 1; va_start(vl, arg0); while (va_arg(vl, char *)) { count ++; } va_end(vl); } argv = (char **) malloc(sizeof(char *) * (count + 1)); if (argv == NULL) { errno = ENOMEM; goto exit; } if (argv) { errno = 0; if (count > 0) { if (!PosixConvertToCurrent(arg0, &argv[0])) { goto exit; } va_start(vl, arg0); for (i = 1; i < count; i++) { if (!PosixConvertToCurrent(va_arg(vl, char *), &argv[i])) { va_end(vl); goto exit; } } va_end(vl); } argv[count] = NULL; if (errno != 0) { goto exit; } } ret = execv(path, argv); exit: if (argv) { Util_FreeStringList(argv, -1); } free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_Execlp -- * * POSIX execlp(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Execlp(ConstUnicode fileName, // IN: ConstUnicode arg0, // IN: ...) // IN: { int ret = -1; char *file; va_list vl; char **argv = NULL; int i, count = 0; if (!PosixConvertToCurrent(fileName, &file)) { goto exit; } if (arg0) { count = 1; va_start(vl, arg0); while (va_arg(vl, char *)) { count ++; } va_end(vl); } argv = (char **) malloc(sizeof(char *) * (count + 1)); if (argv == NULL) { errno = ENOMEM; goto exit; } if (argv) { errno = 0; if (count > 0) { if (!PosixConvertToCurrent(arg0, &argv[0])) { goto exit; } va_start(vl, arg0); for (i = 1; i < count; i++) { if (!PosixConvertToCurrent(va_arg(vl, char *), &argv[i])) { va_end(vl); goto exit; } } va_end(vl); } argv[count] = NULL; if (errno != 0) { goto exit; } } ret = execvp(file, argv); exit: if (argv) { Util_FreeStringList(argv, -1); } free(file); return ret; } /* *---------------------------------------------------------------------- * * Posix_Execv -- * * POSIX execv(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Execv(ConstUnicode pathName, // IN: Unicode const argVal[]) // IN: { int ret = -1; char *path; char **argv = NULL; if (!PosixConvertToCurrent(pathName, &path)) { goto exit; } if (!PosixConvertToCurrentList(argVal, &argv)) { goto exit; } ret = execv(path, argv); exit: if (argv) { Util_FreeStringList(argv, -1); } free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_Execve -- * * POSIX execve(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Execve(ConstUnicode pathName, // IN: Unicode const argVal[], // IN: Unicode const envPtr[]) // IN: { int ret = -1; char *path; char **argv = NULL; char **envp = NULL; if (!PosixConvertToCurrent(pathName, &path)) { goto exit; } if (!PosixConvertToCurrentList(argVal, &argv)) { goto exit; } if (!PosixConvertToCurrentList(envPtr, &envp)) { goto exit; } ret = execve(path, argv, envp); exit: if (argv) { Util_FreeStringList(argv, -1); } if (envp) { Util_FreeStringList(envp, -1); } free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_Execvp -- * * POSIX execvp(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Execvp(ConstUnicode fileName, // IN: Unicode const argVal[]) // IN: { int ret = -1; char *file; char **argv = NULL; if (!PosixConvertToCurrent(fileName, &file)) { goto exit; } if (!PosixConvertToCurrentList(argVal, &argv)) { goto exit; } ret = execvp(file, argv); exit: if (argv) { Util_FreeStringList(argv, -1); } free(file); return ret; } /* *---------------------------------------------------------------------- * * Posix_System -- * * POSIX system() * * Results: * Returns the status of command, or -1 on failure. * * Side effects: * errno is set on error. * *---------------------------------------------------------------------- */ int Posix_System(ConstUnicode command) // IN: { char *tmpcommand; int ret; if (!PosixConvertToCurrent(command, &tmpcommand)) { return -1; } ret = system(tmpcommand); free(tmpcommand); return ret; } /* *---------------------------------------------------------------------- * * Posix_Mkdir -- * * POSIX mkdir(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Mkdir(ConstUnicode pathName, // IN: mode_t mode) // IN: { char *path; int ret; if (!PosixConvertToCurrent(pathName, &path)) { return -1; } ret = mkdir(path, mode); free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_Chdir -- * * POSIX chdir(). * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Chdir(ConstUnicode pathName) // IN: { char *path; int ret; if (!PosixConvertToCurrent(pathName, &path)) { return -1; } ret = chdir(path); free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_RealPath -- * * POSIX realpath(). * * Results: * NULL Error * !NULL Success (result must be freed by the caller) * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ Unicode Posix_RealPath(ConstUnicode pathName) // IN: { char *path; char rpath[PATH_MAX]; char *p; if (!PosixConvertToCurrent(pathName, &path)) { return NULL; } p = realpath(path, rpath); free(path); return p == NULL ? NULL : Unicode_Alloc(rpath, STRING_ENCODING_DEFAULT); } /* *---------------------------------------------------------------------- * * Posix_ReadLink -- * * POSIX readlink(). * * Results: * NULL Error * !NULL Success (result must be freed by the caller) * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ Unicode Posix_ReadLink(ConstUnicode pathName) // IN: { char *path = NULL; Unicode result = NULL; if (PosixConvertToCurrent(pathName, &path)) { size_t size = 2 * 1024; while (TRUE) { char *linkPath = Util_SafeMalloc(size); ssize_t len = readlink(path, linkPath, size); if (len == -1) { free(linkPath); break; } if (len < size) { linkPath[len] = '\0'; // Add the missing NUL to path result = Unicode_Alloc(linkPath, STRING_ENCODING_DEFAULT); free(linkPath); break; } free(linkPath); size += 1024; } } free(path); return result; } /* *---------------------------------------------------------------------- * * Posix_Lstat -- * * POSIX lstat() * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Lstat(ConstUnicode pathName, // IN: struct stat *statbuf) // IN: { char *path; int ret; if (!PosixConvertToCurrent(pathName, &path)) { return -1; } ret = lstat(path, statbuf); free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_OpenDir -- * * POSIX opendir() * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ DIR * Posix_OpenDir(ConstUnicode pathName) // IN: { char *path; DIR *ret; if (!PosixConvertToCurrent(pathName, &path)) { return NULL; } ret = opendir(path); free(path); return ret; } /* *---------------------------------------------------------------------- * * Posix_Getenv -- * * POSIX getenv(). * * Results: * NULL The name was not found or an error occurred * !NULL The value associated with the name in UTF8. This does not * need to be freed. * * Side effects: * None * *---------------------------------------------------------------------- */ Unicode Posix_Getenv(ConstUnicode name) // IN: { char *rawName; char *rawValue; if (!PosixConvertToCurrent(name, &rawName)) { return NULL; } rawValue = getenv(rawName); free(rawName); if (rawValue == NULL) { return NULL; } return PosixGetenvHash(name, Unicode_Alloc(rawValue, STRING_ENCODING_DEFAULT)); } /* *---------------------------------------------------------------------- * * Posix_Putenv -- * * POSIX putenv(). This wrapper will only assert the string is ASCII. * putenv() should not be used. * * Results: * -1 Error * 0 Success * * Side effects: * Environment may be changed. * *---------------------------------------------------------------------- */ int Posix_Putenv(Unicode name) // IN: { ASSERT(Unicode_IsBufferValid(name, -1, STRING_ENCODING_US_ASCII)); return putenv(name); } /* *---------------------------------------------------------------------- * * Posix_Getpwnam -- * * POSIX getpwnam() * * Results: * Pointer to updated passwd struct on NULL on error. * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ struct passwd * Posix_Getpwnam(ConstUnicode name) // IN: { struct passwd *pw; char *tmpname; if (!PosixConvertToCurrent(name, &tmpname)) { return NULL; } pw = getpwnam(tmpname); free(tmpname); return GetpwInternal(pw); } /* *---------------------------------------------------------------------- * * Posix_Getpwuid -- * * POSIX getpwuid() * * Results: * Pointer to updated passwd struct on NULL on error. * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ struct passwd * Posix_Getpwuid(uid_t uid) // IN: { struct passwd *pw = getpwuid(uid); return GetpwInternal(pw); } /* *---------------------------------------------------------------------- * * GetpwInternal -- * * Helper function for Posix_Getpwnam, Posix_Getpwuid and Posix_Getpwent * * Results: * Pointer to updated passwd struct on NULL on error. * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ static struct passwd * GetpwInternal(struct passwd *pw) // IN: { int ret; static struct passwd spw = {0}; if (!pw) { return NULL; } /* Free static structure string pointers before reuse. */ free(spw.pw_passwd); spw.pw_passwd = NULL; free(spw.pw_dir); spw.pw_dir = NULL; free(spw.pw_name); spw.pw_name = NULL; #if !defined __ANDROID__ free(spw.pw_gecos); spw.pw_gecos = NULL; #endif free(spw.pw_shell); spw.pw_shell = NULL; #if defined(__FreeBSD__) free(spw.pw_class); spw.pw_class = NULL; #endif /* Fill out structure with new values. */ spw.pw_uid = pw->pw_uid; spw.pw_gid = pw->pw_gid; #if defined(__FreeBSD__) spw.pw_change = pw->pw_change; spw.pw_expire = pw->pw_expire; spw.pw_fields = pw->pw_fields; #endif #if !defined(sun) ret = ENOMEM; #else ret = EIO; #endif if (pw->pw_passwd && (spw.pw_passwd = Unicode_Alloc(pw->pw_passwd, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } if (pw->pw_dir && (spw.pw_dir = Unicode_Alloc(pw->pw_dir, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } if (pw->pw_name && (spw.pw_name = Unicode_Alloc(pw->pw_name, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } #if !defined __ANDROID__ if (pw->pw_gecos && (spw.pw_gecos = Unicode_Alloc(pw->pw_gecos, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } #endif if (pw->pw_shell && (spw.pw_shell = Unicode_Alloc(pw->pw_shell, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } #if defined(__FreeBSD__) if (pw->pw_class && (spw.pw_class = Unicode_Alloc(pw->pw_class, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } #endif ret = 0; exit: if (ret != 0) { errno = ret; return NULL; } return &spw; } #if !defined(sun) // { /* *---------------------------------------------------------------------- * * Posix_Statfs -- * * POSIX statfs() * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int Posix_Statfs(ConstUnicode pathName, // IN: struct statfs *statfsbuf) // IN: { char *path; int ret; if (!PosixConvertToCurrent(pathName, &path)) { return -1; } ret = statfs(path, statfsbuf); free(path); return ret; } #endif // } !defined(sun) /* *---------------------------------------------------------------------- * * Posix_Setenv -- * * POSIX setenv(). * * Results: * -1 Error * 0 Success * * Side effects: * Environment may be changed. * *---------------------------------------------------------------------- */ int Posix_Setenv(ConstUnicode name, // IN: ConstUnicode value, // IN: int overWrite) // IN: { int ret = -1; char *rawName = NULL; char *rawValue = NULL; if (!PosixConvertToCurrent(name, &rawName)) { goto exit; } if (!PosixConvertToCurrent(value, &rawValue)) { goto exit; } #if defined(sun) if (overWrite || !getenv(rawName)) { static HashTable *trackEnv = NULL; // Tracks values to avoid leaks. char *keyStr; char *fullStr; int fslen; int rawNameLen; int rawValueLen; if (!trackEnv) { trackEnv = HashTable_Alloc(16, HASH_STRING_KEY, free); } /* * In order to keep memory management and hash table manipulation simple, * each env var is stored as a memory block containing the NUL-terminated * environment variable name, followed immediately in memory by the * full argument to putenv ('varname=value'). */ rawNameLen = strlen(rawName) + 1; rawValueLen = strlen(rawValue) + 1; fslen = rawNameLen + rawValueLen + 1; // 1 is for '=' sign keyStr = malloc(rawNameLen + fslen); fullStr = keyStr + rawNameLen; /* * Use memcpy because Str_Snprintf() doesn't play well with non-UTF8 * strings. */ memcpy(keyStr, rawName, rawNameLen); memcpy(fullStr, rawName, rawNameLen); fullStr[rawNameLen - 1] = '='; memcpy(fullStr + rawNameLen, rawValue, rawValueLen); ret = putenv(fullStr); HashTable_Insert(trackEnv, keyStr, keyStr); // Any old value will be freed } else { ret = 0; } #else ret = setenv(rawName, rawValue, overWrite); #endif exit: free(rawName); free(rawValue); return ret; } /* *---------------------------------------------------------------------- * * Posix_Unsetenv -- * * POSIX unsetenv(). * * Results: * None. * * Side effects: * Environment may be changed. * *---------------------------------------------------------------------- */ void Posix_Unsetenv(ConstUnicode name) // IN: { char *rawName; if (!PosixConvertToCurrent(name, &rawName)) { return; } #if defined(sun) putenv(rawName); #else unsetenv(rawName); #endif free(rawName); } /*---------------------------------------------------------------------- * Posix_Getpwent -- * * POSIX getpwent() * * Results: * Pointer to updated passwd struct or NULL on error. * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ struct passwd * Posix_Getpwent(void) { #if defined NO_GETPWENT NOT_IMPLEMENTED(); errno = ENOSYS; return NULL; #else struct passwd *pw = getpwent(); return GetpwInternal(pw); #endif } #if !defined(VM_SYSTEM_HAS_GETPWNAM_R) || \ !defined(VM_SYSTEM_HAS_GETPWUID_R) || \ !defined(VM_SYSTEM_HAS_GETGRNAM_R) // { /* *----------------------------------------------------------------------------- * * CopyFieldIntoBuf -- * * Copies a field in a passwd/group structure into the supplied buffer, * and sets that pointer into dest. Used as a helper function for the * EmulateGet* routines. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * Updates *buf and *bufLen to allocate space for the copied field. * *----------------------------------------------------------------------------- */ static Bool CopyFieldIntoBuf(const char *src, // IN: char **dest, // OUT: char **buf, // OUT size_t *bufLen) // OUT: { if (src) { size_t needLen = strlen(src) + 1; if (*bufLen < needLen) { return FALSE; } *dest = *buf; memcpy(*dest, src, needLen); *buf += needLen; *bufLen -= needLen; } else { *dest = NULL; } return TRUE; } #endif // } #if !defined(VM_SYSTEM_HAS_GETPWNAM_R) || !defined(VM_SYSTEM_HAS_GETPWUID_R) // { /* *----------------------------------------------------------------------------- * * PasswdCopy -- * * Copies a password structure as part of emulating the getpw*_r routines. * * Results: * 'new' if successful, NULL otherwise. * * Side effects: * Modifies 'buf' * *----------------------------------------------------------------------------- */ static struct passwd * PasswdCopy(struct passwd *orig, // IN struct passwd *new, // IN/OUT char *buf, // IN size_t bufLen) // IN { if (!orig) { return NULL; } *new = *orig; if (!CopyFieldIntoBuf(orig->pw_name, &new->pw_name, &buf, &bufLen)) { return NULL; } if (!CopyFieldIntoBuf(orig->pw_passwd, &new->pw_passwd, &buf, &bufLen)) { return NULL; } #if !defined __ANDROID__ if (!CopyFieldIntoBuf(orig->pw_gecos, &new->pw_gecos, &buf, &bufLen)) { return NULL; } #endif if (!CopyFieldIntoBuf(orig->pw_dir, &new->pw_dir, &buf, &bufLen)) { return NULL; } if (!CopyFieldIntoBuf(orig->pw_shell, &new->pw_shell, &buf, &bufLen)) { return NULL; } #ifdef __FreeBSD__ if (!CopyFieldIntoBuf(orig->pw_class, &new->pw_class, &buf, &bufLen)) { return NULL; } #endif return new; } #endif // } #ifndef VM_SYSTEM_HAS_GETPWNAM_R // { /* *----------------------------------------------------------------------------- * * EmulateGetpwnam_r -- * * Emulates getpwnam_r() for old/odd systems that don't have it * * Results: * None. * * Side effects: * Data may be stored in 'buf'. * *----------------------------------------------------------------------------- */ static int EmulateGetpwnam_r(const char *name, // IN struct passwd *pwbuf, // IN/OUT char *buf, // IN size_t buflen, // IN struct passwd **pwbufp) // IN/OUT { static Atomic_uint32 mutex = {0}; struct passwd *pw; int savedErrno; ASSERT(pwbuf); ASSERT(name); ASSERT(buf); ASSERT(pwbufp); /* * XXX Use YIELD() here when it works on FreeBSD. */ while (Atomic_ReadWrite(&mutex, 1)); // Spinlock. pw = getpwnam(name); savedErrno = errno; *pwbufp = PasswdCopy(pw, pwbuf, buf, buflen); Atomic_Write(&mutex, 0); if (pw) { return 0; } else if (savedErrno) { return savedErrno; } else { return ENOENT; } } #endif #ifndef VM_SYSTEM_HAS_GETPWUID_R /* *----------------------------------------------------------------------------- * * EmulateGetpwuid_r -- * * Emulates getpwuid_r() for old/odd systems that don't have it * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int EmulateGetpwuid_r(uid_t uid, // IN: struct passwd *pwbuf, // IN/OUT: char *buf, // IN: size_t buflen, // IN: struct passwd **pwbufp) // IN/OUT: { static Atomic_uint32 mutex = {0}; struct passwd *pw; int savedErrno; ASSERT(pwbuf); ASSERT(buf); ASSERT(pwbufp); /* * XXX Use YIELD() here when it works on FreeBSD. */ while (Atomic_ReadWrite(&mutex, 1)); // Spinlock pw = getpwuid(uid); savedErrno = errno; *pwbufp = PasswdCopy(pw, pwbuf, buf, buflen); Atomic_Write(&mutex, 0); if (pw) { return 0; } else if (savedErrno) { return savedErrno; } else { return ENOENT; } } #endif // } #ifndef VM_SYSTEM_HAS_GETGRNAM_R // { /* *----------------------------------------------------------------------------- * * GroupCopy -- * * Copies a password structure as part of emulating the getgr*_r routines. * * Results: * 'new' if successful, NULL otherwise. * * Side effects: * Modifies 'buf' * *----------------------------------------------------------------------------- */ static struct group * GroupCopy(struct group *orig, // IN: struct group *new, // IN/OUT: char *buf, // IN: size_t bufLen) // IN: { if (!orig) { return NULL; } *new = *orig; if (!CopyFieldIntoBuf(orig->gr_name, &new->gr_name, &buf, &bufLen)) { return NULL; } if (!CopyFieldIntoBuf(orig->gr_passwd, &new->gr_passwd, &buf, &bufLen)) { return NULL; } if (orig->gr_mem) { int i; uintptr_t alignLen; char **newGrMem; /* * Before putting the gr_mem 'char **' array into 'buf', aligns the * buffer to a pointer-size boundary. */ alignLen = ((((uintptr_t) buf) + (sizeof(void *) - 1)) & ~(sizeof(void *) - 1)); alignLen -= ((uintptr_t) buf); if (bufLen < alignLen) { return NULL; } buf += alignLen; bufLen -= alignLen; /* * Count the number of items in the gr_mem array, and then copy them all. */ for (i = 0; orig->gr_mem[i]; i++); i++; // need space for a terminating NULL if (bufLen < (i * sizeof(void *))) { return NULL; } newGrMem = (char **)buf; buf += i * sizeof(void *); bufLen -= i * sizeof(void *); for (i = 0; orig->gr_mem[i]; i++, newGrMem++) { size_t flen; flen = strlen(orig->gr_mem[i]) + 1; if (bufLen < flen) { return NULL; } *newGrMem = buf; memcpy(*newGrMem, orig->gr_mem[i], flen); buf += flen; bufLen -= flen; } *newGrMem = NULL; } return new; } #endif // } #ifndef VM_SYSTEM_HAS_GETGRNAM_R // { /* *----------------------------------------------------------------------------- * * EmulateGetgrnam_r -- * * Emulates getgrnam_r() for old/odd systems that don't have it * * Results: * None. * * Side effects: * Data may be stored in 'buf'. * *----------------------------------------------------------------------------- */ static int EmulateGetgrnam_r(const char *name, // IN: struct group *grbuf, // IN/OUT: char *buf, // IN: size_t buflen, // IN: struct group **grbufp) // IN/OUT: { static Atomic_uint32 mutex = {0}; struct group *gr; int savedErrno; ASSERT(grbuf); ASSERT(name); ASSERT(buf); ASSERT(grbufp); /* * XXX Use YIELD() here once it is available on FreeBSD */ while (Atomic_ReadWrite(&mutex, 1)); // Spinlock gr = getgrnam(name); savedErrno = errno; *grbufp = GroupCopy(gr, grbuf, buf, buflen); Atomic_Write(&mutex, 0); if (gr) { return 0; } else if (savedErrno) { return savedErrno; } else { return ENOENT; } } #endif // } /* *---------------------------------------------------------------------- * * Posix_Getpwnam_r -- * * POSIX getpwnam_r() * * Results: * Returns 0 with success and pointer to updated passwd struct * or returns error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Posix_Getpwnam_r(ConstUnicode name, // IN: struct passwd *pw, // IN: char *buf, // IN: size_t size, // IN: struct passwd **ppw) // OUT: { int ret; char *tmpname; if (!PosixConvertToCurrent(name, &tmpname)) { /* * Act like nonexistent user, almost. * While getpwnam_r() returns 0 on nonexistent user, * we will return the errno instead. */ *ppw = NULL; return errno; } #if defined(VM_SYSTEM_HAS_GETPWNAM_R) ret = getpwnam_r(tmpname, pw, buf, size, ppw); #else ret = EmulateGetpwnam_r(tmpname, pw, buf, size, ppw); #endif free(tmpname); // ret is errno on failure, *ppw is NULL if no matching entry found. if (ret != 0 || *ppw == NULL) { return ret; } return GetpwInternal_r(pw, buf, size, ppw); } /* *---------------------------------------------------------------------- * * Posix_Getpwuid_r -- * * POSIX getpwuid_r() * * Results: * Returns 0 with success and pointer to updated passwd struct * or returns error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Posix_Getpwuid_r(uid_t uid, // IN: struct passwd *pw, // IN: char *buf, // IN: size_t size, // IN: struct passwd **ppw) // OUT: { int ret; #if defined(VM_SYSTEM_HAS_GETPWNAM_R) ret = getpwuid_r(uid, pw, buf, size, ppw); #else ret = EmulateGetpwuid_r(uid, pw, buf, size, ppw); #endif if (ret != 0 || *ppw == NULL) { // ret is errno on failure, *ppw is NULL if no matching entry found. return ret; } return GetpwInternal_r(pw, buf, size, ppw); } /* *---------------------------------------------------------------------- * * GetpwInternal_r -- * * Helper function for Posix_Getpwnam_r and Posix_Getpwuid_r * * Results: * Returns 0 with success and pointer to updated passwd struct * or returns error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int GetpwInternal_r(struct passwd *pw, // IN: char *buf, // IN: size_t size, // IN: struct passwd **ppw) // OUT: { int ret; char *pwname = NULL; char *passwd = NULL; #if !defined __ANDROID__ char *gecos = NULL; #endif char *dir = NULL; char *shell = NULL; size_t n; /* * Maybe getpwnam_r didn't use supplied struct, but we don't care. * We just fix up the one it gives us. */ pw = *ppw; /* * Convert strings to UTF-8 */ ret = ENOMEM; if (pw->pw_name && (pwname = Unicode_Alloc(pw->pw_name, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } if (pw->pw_passwd && (passwd = Unicode_Alloc(pw->pw_passwd, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } #if !defined __ANDROID__ if (pw->pw_gecos && (gecos = Unicode_Alloc(pw->pw_gecos, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } #endif if (pw->pw_dir && (dir = Unicode_Alloc(pw->pw_dir, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } if (pw->pw_shell && (shell = Unicode_Alloc(pw->pw_shell, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } /* * Put UTF-8 strings into the structure. */ ret = ERANGE; n = 0; if (pwname) { size_t len = strlen(pwname) + 1; if (n + len > size || n + len < n) { goto exit; } pw->pw_name = memcpy(buf + n, pwname, len); n += len; } if (passwd != NULL) { size_t len = strlen(passwd) + 1; if (n + len > size || n + len < n) { goto exit; } pw->pw_passwd = memcpy(buf + n, passwd, len); n += len; } #if !defined __ANDROID__ if (gecos) { size_t len = strlen(gecos) + 1; if (n + len > size || n + len < n) { goto exit; } pw->pw_gecos = memcpy(buf + n, gecos, len); n += len; } #endif if (dir) { size_t len = strlen(dir) + 1; if (n + len > size || n + len < n) { goto exit; } pw->pw_dir = memcpy(buf + n, dir, len); n += len; } if (shell) { size_t len = strlen(shell) + 1; if (n + len > size || n + len < n) { goto exit; } pw->pw_shell = memcpy(buf + n, shell, len); n += len; } ret = 0; exit: free(passwd); free(dir); free(pwname); #if !defined __ANDROID__ free(gecos); #endif free(shell); return ret; } #if !defined(sun) // { /* *---------------------------------------------------------------------- * * Posix_GetGroupList -- * * POSIX getgrouplist() * * Results: * Returns number of groups found, or -1 if *ngroups is * smaller than number of groups found. Also returns * the list of groups. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Posix_GetGroupList(ConstUnicode user, // IN: gid_t group, // IN: gid_t *groups, // OUT: int *ngroups) // IN/OUT: { char *tmpuser; int ret; if (!PosixConvertToCurrent(user, &tmpuser)) { /* * Act like nonexistent user. * The supplied gid is always returned, so there's exactly * one group. * While the man page doesn't say, the return value is * the same as *ngroups in the success case. * * Should we always return -1 instead? * * -- edward */ int n = *ngroups; *ngroups = 1; if (n < 1) { return -1; } ASSERT(groups != NULL); *groups = group; return 1; } ret = getgrouplist(tmpuser, group, groups, ngroups); free(tmpuser); return ret; } #endif // } /* *---------------------------------------------------------------------- * Posix_Getgrnam -- * * POSIX getgrnam() * * Results: * Pointer to updated group struct on NULL on error. * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ struct group * Posix_Getgrnam(ConstUnicode name) // IN: { struct group *gr; char *tmpname; int ret; static struct group sgr = {0}; if (!PosixConvertToCurrent(name, &tmpname)) { return NULL; } gr = getgrnam(tmpname); free(tmpname); if (!gr) { return NULL; } /* Free static structure string pointers before reuse. */ free(sgr.gr_name); sgr.gr_name = NULL; free(sgr.gr_passwd); sgr.gr_passwd = NULL; if (sgr.gr_mem != NULL) { Unicode_FreeList(sgr.gr_mem, -1); sgr.gr_mem = NULL; } /* Fill out structure with new values. */ sgr.gr_gid = gr->gr_gid; ret = ENOMEM; if (gr->gr_passwd && (sgr.gr_passwd = Unicode_Alloc(gr->gr_passwd, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } if (gr->gr_name && (sgr.gr_name = Unicode_Alloc(gr->gr_name, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } if (gr->gr_mem) { sgr.gr_mem = Unicode_AllocList(gr->gr_mem, -1, STRING_ENCODING_DEFAULT); } ret = 0; exit: if (ret != 0) { errno = ret; return NULL; } return &sgr; } /* *---------------------------------------------------------------------- * * Posix_Getgrnam_r -- * * POSIX getgrnam_r() * * Results: * Returns 0 with success and pointer to updated group struct * or returns error code. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Posix_Getgrnam_r(ConstUnicode name, // IN: struct group *gr, // IN: char *buf, // IN: size_t size, // IN: struct group **pgr) // OUT: { int ret, i; char *tmpname; char *grname = NULL; char *grpasswd = NULL; char **grmem = NULL; size_t n; if (!PosixConvertToCurrent(name, &tmpname)) { /* * Act like nonexistent group, almost. * While getgrnam_r() returns 0 on nonexistent group, * we will return the errno instead. */ *pgr = NULL; return errno; } #if defined(VM_SYSTEM_HAS_GETGRNAM_R) ret = getgrnam_r(tmpname, gr, buf, size, pgr); #else ret = EmulateGetgrnam_r(tmpname, gr, buf, size, pgr); #endif free(tmpname); // ret is errno on failure, *pgr is NULL if no matching entry found. if (ret != 0 || *pgr == NULL) { return ret; } /* * Maybe getgrnam_r didn't use supplied struct, but we don't care. * We just fix up the one it gives us. */ gr = *pgr; /* * Convert strings to UTF-8 */ ret = ENOMEM; if (gr->gr_name && (grname = Unicode_Alloc(gr->gr_name, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } if (gr->gr_passwd && (grpasswd = Unicode_Alloc(gr->gr_passwd, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } if (gr->gr_mem) { grmem = Unicode_AllocList(gr->gr_mem, -1, STRING_ENCODING_DEFAULT); } /* * Put UTF-8 strings into the structure. */ ret = ERANGE; n = 0; if (grname) { size_t len = strlen(grname) + 1; if (n + len > size) { goto exit; } gr->gr_name = memcpy(buf + n, grname, len); n += len; } if (grpasswd != NULL) { size_t len = strlen(grpasswd) + 1; if (n + len > size) { goto exit; } gr->gr_passwd = memcpy(buf + n, grpasswd, len); n += len; } if (grmem) { for (i = 0; grmem[i]; i++) { size_t len = strlen(grmem[i]) + 1; if (n + len > size) { goto exit; } gr->gr_mem[i] = memcpy(buf + n, grmem[i], len); n += len; } } ret = 0; exit: free(grpasswd); free(grname); if (grmem) { Unicode_FreeList(grmem, -1); } return ret; } #if !defined(sun) // { #if !defined(__APPLE__) && !defined(__FreeBSD__) // { /* *---------------------------------------------------------------------- * * Posix_Mount -- * * POSIX mount() * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error. On success, filesystem is mounted. * *---------------------------------------------------------------------- */ int Posix_Mount(ConstUnicode source, // IN: ConstUnicode target, // IN: const char *filesystemtype, // IN: unsigned long mountflags, // IN: const void *data) // IN: { int ret = -1; char *tmpsource = NULL; char *tmptarget = NULL; if (!PosixConvertToCurrent(source, &tmpsource)) { goto exit; } if (!PosixConvertToCurrent(target, &tmptarget)) { goto exit; } ret = mount(tmpsource, tmptarget, filesystemtype, mountflags, data); exit: free(tmpsource); free(tmptarget); return ret; } /* *---------------------------------------------------------------------- * * Posix_Umount -- * * POSIX umount() * * Results: * -1 Error * 0 Success * * Side effects: * errno is set on error. On success, filesystem is unmounted. * *---------------------------------------------------------------------- */ int Posix_Umount(ConstUnicode target) // IN: { char *tmptarget; int ret; if (!PosixConvertToCurrent(target, &tmptarget)) { return -1; } ret = umount(tmptarget); free(tmptarget); return ret; } /* *---------------------------------------------------------------------- * * Posix_Setmntent -- * * Open a file via POSIX setmntent() * * Results: * NULL Error * !NULL File stream * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ FILE * Posix_Setmntent(ConstUnicode pathName, // IN: const char *mode) // IN: { #if defined NO_SETMNTENT NOT_IMPLEMENTED(); errno = ENOSYS; return NULL; #else char *path; FILE *stream; ASSERT(mode != NULL); if (!PosixConvertToCurrent(pathName, &path)) { return NULL; } stream = setmntent(path, mode); free(path); return stream; #endif } /* *---------------------------------------------------------------------- * * Posix_Getmntent -- * * POSIX getmntent() * * Results: * Pointer to updated mntent struct or NULL on error. * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ struct mntent * Posix_Getmntent(FILE *fp) // IN: { int ret; struct mntent *m; static struct mntent sm = {0}; m = getmntent(fp); if (!m) { return NULL; } /* Free static structure string pointers before reuse. */ free(sm.mnt_fsname); sm.mnt_fsname = NULL; free(sm.mnt_dir); sm.mnt_dir = NULL; free(sm.mnt_type); sm.mnt_type = NULL; free(sm.mnt_opts); sm.mnt_opts = NULL; /* Fill out structure with new values. */ sm.mnt_freq = m->mnt_freq; sm.mnt_passno = m->mnt_passno; ret = ENOMEM; if (m->mnt_fsname && (sm.mnt_fsname = Unicode_Alloc(m->mnt_fsname, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } if (m->mnt_dir && (sm.mnt_dir = Unicode_Alloc(m->mnt_dir, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } if (m->mnt_type && (sm.mnt_type = Unicode_Alloc(m->mnt_type, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } if (m->mnt_opts && (sm.mnt_opts = Unicode_Alloc(m->mnt_opts, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } ret = 0; exit: if (ret != 0) { errno = ret; return NULL; } return &sm; } /* *---------------------------------------------------------------------- * * Posix_Getmntent_r -- * * POSIX getmntent_r() * * Results: * Pointer to updated mntent struct or NULL on error. * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ struct mntent * Posix_Getmntent_r(FILE *fp, // IN: struct mntent *m, // IN: char *buf, // IN: int size) // IN: { #if defined NO_GETMNTENT_R NOT_IMPLEMENTED(); errno = ENOSYS; return NULL; #else int ret; char *fsname = NULL; char *dir = NULL; char *type = NULL; char *opts = NULL; size_t n; if (!getmntent_r(fp, m, buf, size)) { return NULL; } /* * Convert strings to UTF-8 */ ret = ENOMEM; if (m->mnt_fsname && (fsname = Unicode_Alloc(m->mnt_fsname, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } if (m->mnt_dir && (dir = Unicode_Alloc(m->mnt_dir, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } if (m->mnt_type && (type = Unicode_Alloc(m->mnt_type, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } if (m->mnt_opts && (opts = Unicode_Alloc(m->mnt_opts, STRING_ENCODING_DEFAULT)) == NULL) { goto exit; } /* * Put UTF-8 strings into the structure. */ ret = ERANGE; n = 0; if (fsname) { int len = strlen(fsname) + 1; if (n + len > size || n + len < n) { goto exit; } m->mnt_fsname = memcpy(buf + n, fsname, len); n += len; } if (dir != NULL) { int len = strlen(dir) + 1; if (n + len > size || n + len < n) { goto exit; } m->mnt_dir = memcpy(buf + n, dir, len); n += len; } if (type) { int len = strlen(type) + 1; if (n + len > size || n + len < n) { goto exit; } m->mnt_type = memcpy(buf + n, type, len); n += len; } if (opts) { size_t len = strlen(opts) + 1; if (n + len > size || n + len < n) { goto exit; } m->mnt_opts = memcpy(buf + n, opts, len); n += len; } ret = 0; exit: free(fsname); free(dir); free(type); free(opts); if (ret != 0) { errno = ret; return NULL; } return m; #endif // defined __ANDROID__ } /* *---------------------------------------------------------------------------- * * Posix_Printf -- * * POSIX printf. * * Returns: * Returns the number of characters printed out or a negative value on * failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int Posix_Printf(ConstUnicode format, // IN: ...) // IN: { va_list args; Unicode output; char *outCurr; int numChars; va_start(args, format); output = Str_Vasprintf(NULL, format, args); va_end(args); if (!PosixConvertToCurrent(output, &outCurr)) { return -1; } numChars = printf("%s", outCurr); free(output); free(outCurr); return numChars; } /* *---------------------------------------------------------------------------- * * Posix_Fprintf -- * * POSIX fprintf. * * Returns: * Returns the number of characters printed out or a negative value on * failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int Posix_Fprintf(FILE *stream, // IN: ConstUnicode format, // IN: ...) // IN: { va_list args; Unicode output; char *outCurr; int nOutput; va_start(args, format); output = Str_Vasprintf(NULL, format, args); va_end(args); if (!PosixConvertToCurrent(output, &outCurr)) { return -1; } nOutput = fprintf(stream, "%s", outCurr); free(output); free(outCurr); return nOutput; } #endif // } !defined(__APPLE__) && !defined(__FreeBSD) #else // } !defined(sun) { /* *---------------------------------------------------------------------- * * Posix_Getmntent -- * * POSIX getmntent() for Solaris * * Results: * -1 EOF * 0 Success * >0 Error * * Side effects: * None. * *---------------------------------------------------------------------- */ int Posix_Getmntent(FILE *fp, // IN: struct mnttab *mp) // IN: { int ret; static struct mnttab m = {0}; ret = getmntent(fp, mp); if (ret == 0) { free(m.mnt_special); free(m.mnt_mountp); free(m.mnt_fstype); free(m.mnt_mntopts); free(m.mnt_time); m.mnt_special = Unicode_Alloc(mp->mnt_special, STRING_ENCODING_DEFAULT); m.mnt_mountp = Unicode_Alloc(mp->mnt_mountp, STRING_ENCODING_DEFAULT); m.mnt_fstype = Unicode_Alloc(mp->mnt_fstype, STRING_ENCODING_DEFAULT); m.mnt_mntopts = Unicode_Alloc(mp->mnt_mntopts, STRING_ENCODING_DEFAULT); m.mnt_time = Unicode_Alloc(mp->mnt_time, STRING_ENCODING_DEFAULT); mp->mnt_special = m.mnt_special; mp->mnt_mountp = m.mnt_mountp; mp->mnt_fstype = m.mnt_fstype; mp->mnt_mntopts = m.mnt_mntopts; mp->mnt_time = m.mnt_time; } return ret; } #endif // } !defined(sun) /* *---------------------------------------------------------------------- * * Posix_MkTemp -- * * POSIX mktemp(). It is implemented via mkstemp() to avoid * warning about using dangerous mktemp() API - but note that * it suffers from all mktemp() problems - caller has to use * O_EXCL when creating file, and retry if file already exists. * * Results: * NULL Error * !NULL Success (result must be freed by the caller) * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ Unicode Posix_MkTemp(ConstUnicode pathName) // IN: { Unicode result = NULL; char *path; int fd; if (!PosixConvertToCurrent(pathName, &path)) { return NULL; } fd = mkstemp(path); if (fd >= 0) { close(fd); unlink(path); result = Unicode_Alloc(path, STRING_ENCODING_DEFAULT); } free(path); return result; } open-vm-tools-9.4.0-1280544/lib/misc/hostinfo.c0000644765153500003110000002226112220061556017140 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * hostinfo.c -- * * Platform-independent code that calls into hostinfo-specific * code. */ #include "vmware.h" #include #if defined(__i386__) || defined(__x86_64__) #include "cpuid_info.h" #endif #include "hostinfo.h" #include "hostinfoInt.h" #include "str.h" #include "util.h" #include "str.h" #include "dynbuf.h" #include "backdoor_def.h" #define LOGLEVEL_MODULE hostinfo #include "loglevel_user.h" #define LGPFX "HOSTINFO:" /* * HostinfoOSData caches its returned value. */ volatile Bool HostinfoOSNameCacheValid = FALSE; char HostinfoCachedOSName[MAX_OS_NAME_LEN]; char HostinfoCachedOSFullName[MAX_OS_FULLNAME_LEN]; #if defined(__i386__) || defined(__x86_64__) /* *----------------------------------------------------------------------------- * * HostInfoGetCpuidStrSection -- * * Append a section (either low or high) of CPUID as a string in DynBuf. * E.g. * 00000000:00000005756E65476C65746E49656E69- * 00000001:00000F4A000208000000649DBFEBFBFF- * or * 80000000:80000008000000000000000000000000- * 80000001:00000000000000000000000120100000- * 80000008:00003024000000000000000000000000- * * The returned eax of args[0] is used to determine the upper bound for * the following input arguments. And the input args should be in * ascending order. * * Results: * None. The string will be appended in buf. * * Side effect: * None * *----------------------------------------------------------------------------- */ static void HostInfoGetCpuidStrSection(const uint32 args[], // IN: input eax arguments const size_t args_size, // IN: size of the argument array DynBuf *buf) // IN/OUT: result string in DynBuf { static const char format[] = "%08X:%08X%08X%08X%08X-"; CPUIDRegs reg; uint32 max_arg; char temp[64]; int i; __GET_CPUID(args[0], ®); max_arg = reg.eax; if (max_arg < args[0]) { Warning(LGPFX" No CPUID information available. Based = %08X.\n", args[0]); return; } DynBuf_Append(buf, temp, Str_Sprintf(temp, sizeof temp, format, args[0], reg.eax, reg.ebx, reg.ecx, reg.edx)); for (i = 1; i < args_size && args[i] <= max_arg; i++) { ASSERT(args[i] > args[i - 1]); // Ascending order. __GET_CPUID(args[i], ®); DynBuf_Append(buf, temp, Str_Sprintf(temp, sizeof temp, format, args[i], reg.eax, reg.ebx, reg.ecx, reg.edx)); } } /* *----------------------------------------------------------------------------- * * Hostinfo_GetCpuidStr -- * * Get the basic and extended CPUID as a string. E.g. * 00000000:00000005756E65476C65746E49656E69- * 00000001:00000F4A000208000000649DBFEBFBFF- * 80000000:80000008000000000000000000000000- * 80000001:00000000000000000000000120100000- * 80000008:00003024000000000000000000000000 * * If the extended CPUID is not available, only returns the basic CPUID. * * Results: * The CPUID string if the processor supports the CPUID instruction and * this is a processor we recognize. It should never fail, since it * would at least return leaf 0. Caller needs to free the returned string. * * Side effect: * None * *----------------------------------------------------------------------------- */ char * Hostinfo_GetCpuidStr(void) { static const uint32 basic_args[] = {0x0, 0x1, 0xa}; static const uint32 extended_args[] = {0x80000000, 0x80000001, 0x80000008}; DynBuf buf; char *result; DynBuf_Init(&buf); HostInfoGetCpuidStrSection(basic_args, ARRAYSIZE(basic_args), &buf); HostInfoGetCpuidStrSection(extended_args, ARRAYSIZE(extended_args), &buf); // Trim buffer and set NULL character to replace last '-'. DynBuf_Trim(&buf); result = (char*)DynBuf_Get(&buf); ASSERT(result && result[0]); // We should at least get result from eax = 0x0. result[DynBuf_GetSize(&buf) - 1] = '\0'; return DynBuf_Detach(&buf); } #endif // defined(__i386__) || defined(__x86_64__) /* *----------------------------------------------------------------------------- * * Hostinfo_GetCpuid -- * * Get cpuid information for a CPU. Which CPU the information is for * depends on the OS scheduler. We are assuming that all CPUs in * the system have identical numbers of cores and threads. * * Results: * TRUE if the processor supports the cpuid instruction and this * is a process we recognize, FALSE otherwise. * * Side effect: * None * *----------------------------------------------------------------------------- */ Bool Hostinfo_GetCpuid(HostinfoCpuIdInfo *info) // OUT { #if defined(__i386__) || defined(__x86_64__) CPUIDSummary cpuid; CPUIDRegs id0; /* * Can't do cpuid = {0} as an initializer above because gcc throws * some idiotic warning. */ memset(&cpuid, 0, sizeof(cpuid)); /* * Get basic and extended CPUID info. */ __GET_CPUID(0, &id0); cpuid.id0.numEntries = id0.eax; if (0 == cpuid.id0.numEntries) { Warning(LGPFX" No CPUID information available.\n"); return FALSE; } *(uint32*)(cpuid.id0.name + 0) = id0.ebx; *(uint32*)(cpuid.id0.name + 4) = id0.edx; *(uint32*)(cpuid.id0.name + 8) = id0.ecx; *(uint32*)(cpuid.id0.name + 12) = 0; __GET_CPUID(1, (CPUIDRegs*)&cpuid.id1); __GET_CPUID(0xa, (CPUIDRegs*)&cpuid.ida); __GET_CPUID(0x80000000, (CPUIDRegs*)&cpuid.id80); __GET_CPUID(0x80000001, (CPUIDRegs*)&cpuid.id81); __GET_CPUID(0x80000008, (CPUIDRegs*)&cpuid.id88); /* * Calculate vendor information. */ if (0 == strcmp(cpuid.id0.name, CPUID_INTEL_VENDOR_STRING_FIXED)) { info->vendor = CPUID_VENDOR_INTEL; } else if (strcmp(cpuid.id0.name, CPUID_AMD_VENDOR_STRING_FIXED) == 0) { info->vendor = CPUID_VENDOR_AMD; } else { info->vendor = CPUID_VENDOR_UNKNOWN; } /* * Pull out versioning and feature information. */ info->version = cpuid.id1.version; info->family = CPUID_GET(1, EAX, FAMILY, cpuid.id1.version); info->model = CPUID_GET(1, EAX, MODEL, cpuid.id1.version); info->stepping = CPUID_GET(1, EAX, STEPPING, cpuid.id1.version); info->type = (cpuid.id1.version >> 12) & 0x0003; info->extfeatures = cpuid.id1.ecxFeatures; info->features = cpuid.id1.edxFeatures; return TRUE; #else // defined(__i386__) || defined(__x86_64__) return FALSE; #endif // defined(__i386__) || defined(__x86_64__) } /* *----------------------------------------------------------------------------- * * Hostinfo_GetOSName -- * * Query the operating system and build a string to identify it. * * Examples: * Windows: (BUILD ) * example: Windows XP Professional Service Pack 2 (Build 2600) * * Linux: * example: Linux 2.4.18-3 Red Hat Linux release 7.3 (Valhalla) * * Return value: * NULL Unable to obtain the OS name. * !NULL The OS name. The caller is responsible for freeing it. * * Side effects: * Memory is allocated. * *----------------------------------------------------------------------------- */ char * Hostinfo_GetOSName(void) { char *name; Bool data = HostinfoOSNameCacheValid ? TRUE : HostinfoOSData(); if (data) { name = Util_SafeStrdup(HostinfoCachedOSFullName); } else { name = NULL; } return name; } /* *----------------------------------------------------------------------------- * * Hostinfo_GetOSGuestString -- * * Query the operating system and build a string to identify it. The * returned string is the same as you'd see in a VM's .vmx file. * * Return value: * NULL Unable to obtain the OS name. * !NULL The OS name. The caller is responsible for freeing it. * * Side effects: * Memory is allocated. * *----------------------------------------------------------------------------- */ char * Hostinfo_GetOSGuestString(void) { char *name; Bool data = HostinfoOSNameCacheValid ? TRUE : HostinfoOSData(); if (data) { name = Util_SafeStrdup(HostinfoCachedOSName); } else { name = NULL; } return name; } open-vm-tools-9.4.0-1280544/lib/misc/util_misc.c0000644765153500003110000005462112220061556017304 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * util.c -- * * misc util functions */ #if defined(_WIN32) #include // also includes windows.h #include #include #define getpid() _getpid() #endif #include "vm_ctype.h" #include "safetime.h" #include #include #include #include #include #include #include #include #if !defined(_WIN32) # if defined(linux) # include // for SYS_gettid # endif # include # include #endif #if defined(__APPLE__) || defined(__FreeBSD__) #include #endif #include "vmware.h" #include "msg.h" #include "util.h" #include "str.h" /* For HARD_EXPIRE --hpreg */ #include "vm_version.h" #include "su.h" #include "escape.h" #include "posix.h" #include "unicode.h" #if defined(_WIN32) #include "win32u.h" #include "win32util.h" #endif /* * ESX with userworld VMX */ #if defined(VMX86_SERVER) #include "hostType.h" #include "user_layout.h" #endif char *gHomeDirOverride = NULL; /* *----------------------------------------------------------------------------- * * Util_GetCanonicalPath -- * * Canonicalizes a path name. * * Results: * A freshly allocated canonicalized path name. * * Side effects: * None. * *----------------------------------------------------------------------------- */ char * Util_GetCanonicalPath(const char *path) // IN: { char *canonicalPath = NULL; #if defined(__linux__) || defined(__APPLE__) canonicalPath = Posix_RealPath(path); #elif defined(_WIN32) char driveSpec[4]; Bool remoteDrive = FALSE; if (!path || !*path) { return NULL; } memcpy(driveSpec, path, 3); driveSpec[3] = '\0'; if (strchr(VALID_DIRSEPS, driveSpec[0]) && strchr(VALID_DIRSEPS, driveSpec[1])) { remoteDrive = TRUE; } else { remoteDrive = (GetDriveTypeA(driveSpec) == DRIVE_REMOTE); } /* * If the path is *potentially* a path to remote share, we do not * call GetLongPathName, because if the remote server is unreachable, * that function could hang. We sacrifice two things by doing so: * 1. The UNC path could refer to the local host and we incorrectly * assume remote. * 2. We do not resolve 8.3 names for remote paths. */ if (remoteDrive) { canonicalPath = Util_SafeStrdup(path); } else { canonicalPath = W32Util_RobustGetLongPath(path); } #else NOT_IMPLEMENTED(); #endif return canonicalPath; } #if defined(_WIN32) /* *----------------------------------------------------------------------------- * * Util_GetCanonicalPathForHash -- * * Utility function to both get the canonical version of the input path * and produce a unique case-insensitive version of the path suitable * for use as a seed to hash functions. * * Results: * Canonicalized UTF-8 pathname suitable for use in hashing. * * Side effects: * None. * *----------------------------------------------------------------------------- */ char * Util_GetCanonicalPathForHash(const char *path) // IN: UTF-8 { char *ret = NULL; char *cpath = Util_GetCanonicalPath(path); if (cpath != NULL) { ret = Unicode_FoldCase(cpath); free(cpath); } return ret; } /* *----------------------------------------------------------------------------- * * UtilGetLegacyEncodedString -- * * Takes a UTF-8 string, and allocates a new string in legacy encoding. * This is necessary to maintain compatibility with older versions of * the product, which may have stored strings (paths) in legacy * encoding. Hence, the use of WideCharToMultiByte(). * * Results: * An allocated string in legacy encoding (MBCS when applicable). * NULL on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static char* UtilGetLegacyEncodedString(const char *path) // IN: UTF-8 { char *ret = NULL; char *cpath = Util_GetCanonicalPath(path); if (cpath != NULL) { char *apath = NULL; int retlen; WCHAR *wcpath = Unicode_GetAllocUTF16(cpath); /* First get the length of multibyte string */ int alen = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, wcpath, -1, NULL, 0, NULL, NULL); if (alen > 0) { /* Now get the converted string */ ret = Util_SafeMalloc(alen); retlen = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, wcpath, -1, ret, alen, NULL, NULL); if (retlen != alen) { free(ret); ret = NULL; } } free(cpath); free(wcpath); } return ret; } /* *----------------------------------------------------------------------------- * * Util_CompatGetCanonicalPath -- * * Canonicalizes a path name (compatibility version). * * Results: * A freshly allocated canonicalized path name in legacy encoding * (MBCS when applicable). * * Side effects: * None. * *----------------------------------------------------------------------------- */ char * Util_CompatGetCanonicalPath(const char *path) // IN: UTF-8 { char *cpath = Util_GetCanonicalPath(path); char *ret = NULL; if (cpath != NULL) { ret = UtilGetLegacyEncodedString(cpath); free(cpath); } return ret; } #endif /* *----------------------------------------------------------------------------- * * Util_CanonicalPathsIdentical -- * * Utility function to compare two paths that have already been made * canonical. This function exists to mask platform differences in * path case-sensitivity. * * XXX: This implementation makes assumptions about the host filesystem's * case sensitivity without any regard to what filesystem the * provided paths actually use. There are many ways to break this * assumption, on any of our supported host OSes! The return value * of this function cannot be trusted. * * Results: * TRUE if the paths are equivalenr, FALSE if they are not. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool Util_CanonicalPathsIdentical(const char *path1, // IN: const char *path2) // IN: { ASSERT(path1); ASSERT(path2); #if defined(linux) return (strcmp(path1, path2) == 0); #elif defined(_WIN32) return (_stricmp(path1, path2) == 0); #elif defined(__APPLE__) return (strcasecmp(path1, path2) == 0); #else NOT_IMPLEMENTED(); #endif } /* *----------------------------------------------------------------------------- * * Util_IsAbsolutePath -- * * Checks if the given path is absolute. * * Results: * TRUE if the path is absolute, FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool Util_IsAbsolutePath(const char *path) // IN: path to check { #if defined(__linux__) || defined(__APPLE__) // path[0] is valid even for the empty string. return path && path[0] == DIRSEPC; #elif defined(_WIN32) // if the length is 2, path[2] will be valid because of the null terminator. if (!path || strlen(path) < 2) { return FALSE; } // :\path if (CType_IsAlpha(path[0]) && path[1] == ':' && path[2] == DIRSEPC) { return TRUE; } // UNC paths if (path[0] == DIRSEPC && path[1] == DIRSEPC) { return TRUE; } return FALSE; #else NOT_IMPLEMENTED(); #endif NOT_REACHED(); } /* *----------------------------------------------------------------------------- * * Util_GetPrime -- * * Find next prime. * * Results: * The smallest prime number greater than or equal to n0. * * Side effects: * None. * *----------------------------------------------------------------------------- */ unsigned Util_GetPrime(unsigned n0) // IN: { unsigned i, ii, n, nn; /* * Keep the main algorithm clean by catching edge cases here. * There is no 32-bit prime larger than 4294967291. */ ASSERT_NOT_IMPLEMENTED(n0 <= 4294967291U); if (n0 <= 2) { return 2; } for (n = n0 | 1;; n += 2) { /* * Run through the numbers 3,5, ..., sqrt(n) and check that none divides * n. We exploit the identity (i + 2)^2 = i^2 + 4i + 4 to incrementially * maintain the square of i (and thus save a multiplication each * iteration). * * 65521 is the largest prime below 0xffff, which is where * we can stop. Using it instead of 0xffff avoids overflowing ii. */ nn = MIN(n, 65521U * 65521U); for (i = 3, ii = 9;; ii += 4*i+4, i += 2) { if (ii > nn) { return n; } if (n % i == 0) { break; } } } } #if defined(linux) && !defined(__ANDROID__) /* * Android has its own gettid. gettid has been declared in * and defined as an extern function in . */ /* *----------------------------------------------------------------------------- * * gettid -- * * Retrieve unique thread identification suitable for kill or setpriority. * Do not call this function directly, use Util_GetCurrentThreadId() * instead. * * Results: * Unique thread identification on success. * (pid_t)-1 on error, errno set (when kernel does not support this call) * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE pid_t gettid(void) { #if defined(SYS_gettid) return (pid_t)syscall(SYS_gettid); #else return -1; #endif } #endif /* *----------------------------------------------------------------------------- * * Util_GetCurrentThreadId -- * * Retrieves a unique thread identification suitable to identify a thread * to kill it or change its scheduling priority. * * Results: * Unique thread identification on success. * ASSERTs on failure (should not happen). * * Side effects: * None. * *----------------------------------------------------------------------------- */ Util_ThreadID Util_GetCurrentThreadId(void) { #if defined(linux) || defined __ANDROID__ /* * It is possible that two threads can enter gettid() path simultaneously, * both eventually clearing useTid to zero. It does not matter - only * problem which can happen is that useTid will be set to zero twice. * And it has no impact on useTid value... */ static int useTid = 1; #if defined(VMX86_SERVER) && defined(GLIBC_VERSION_25) static __thread pid_t tid = -1; #else pid_t tid; #endif if (useTid) { #if defined(VMX86_SERVER) && defined(GLIBC_VERSION_25) if (tid != -1) { return tid; } #endif tid = gettid(); if (tid != (pid_t)-1) { return tid; } ASSERT(errno == ENOSYS); useTid = 0; } tid = getpid(); ASSERT(tid != (pid_t)-1); return tid; #elif defined(sun) pid_t tid; tid = getpid(); ASSERT(tid != (pid_t)-1); return tid; #elif defined(__APPLE__) || defined(__FreeBSD__) ASSERT_ON_COMPILE(sizeof(Util_ThreadID) == sizeof(pthread_t)); return pthread_self(); #elif defined(_WIN32) return GetCurrentThreadId(); #else #error "Unknown platform" #endif } /* *----------------------------------------------------------------------------- * * UtilIsAlphaOrNum -- * * Checks if character is a numeric digit or a letter of the * english alphabet. * * Results: * Returns TRUE if character is a digit or a letter, FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool UtilIsAlphaOrNum(char ch) //IN { if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) { return TRUE; } else { return FALSE; } } #ifndef _WIN32 /* *----------------------------------------------------------------------------- * * UtilGetHomeDirectory -- * * Retrieves the home directory for a user, given their passwd struct. * * Results: * Returns user's home directory or NULL if it fails. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static char * UtilGetHomeDirectory(struct passwd *pwd) // IN/OPT: user passwd struct { if (pwd && pwd->pw_dir) { return Util_SafeStrdup(pwd->pw_dir); } else { return NULL; } } /* *----------------------------------------------------------------------------- * * UtilGetLoginName -- * * Retrieves the login name for a user, given their passwd struct. * * Results: * Returns user's login name or NULL if it fails. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static char * UtilGetLoginName(struct passwd *pwd) // IN/OPT: user passwd struct { if (pwd && pwd->pw_name) { return Util_SafeStrdup(pwd->pw_name); } else { return NULL; } } /* *---------------------------------------------------------------------- * * UtilDoTildeSubst -- * * Given a string following a tilde, this routine returns the * corresponding home directory. * * Results: * A string containing the home directory in native format. The * returned string is a newly allocated string which may/must be * freed by the caller. * * Side effects: * None. * * Credit: derived from J.K.Ousterhout's Tcl *---------------------------------------------------------------------- */ static Unicode UtilDoTildeSubst(ConstUnicode user) // IN: name of user { Unicode str = NULL; struct passwd *pwd = NULL; if (gHomeDirOverride) { /* * Allow code to override the tilde expansion for things like unit tests. * See: Util_OverrideHomeDir */ return Util_SafeStrdup(gHomeDirOverride); } if (*user == '\0') { #if defined(__APPLE__) /* * The HOME environment variable is not always set on Mac OS. * (was bug 841728) */ if (str == NULL) { pwd = Posix_Getpwuid(getuid()); if (pwd == NULL) { Log("Could not get passwd for current user.\n"); } } #else // !defined(__APPLE__) str = Unicode_Duplicate(Posix_Getenv("HOME")); if (str == NULL) { Log("Could not expand environment variable HOME.\n"); } #endif // !defined(__APPLE__) } else { pwd = Posix_Getpwnam(user); if (pwd == NULL) { Log("Could not get passwd for user '%s'.\n", user); } } if (str == NULL && pwd != NULL) { str = UtilGetHomeDirectory(pwd); endpwent(); if (str == NULL) { Log("Could not get home directory for user.\n"); } } return str; } #endif // !_WIN32 /* *---------------------------------------------------------------------- * * Util_ExpandString -- * * converts the strings by expanding "~", "~user" and environment * variables * * Results: * * Return a newly allocated string. The caller is responsible * for deallocating it. * * Return NULL in case of error. * * Side effects: * memory allocation * * Bugs: * the handling of enviroment variable references is very * simplistic: there can be only one in a pathname segment * and it must appear last in the string * *---------------------------------------------------------------------- */ #define UTIL_MAX_PATH_CHUNKS 100 Unicode Util_ExpandString(ConstUnicode fileName) // IN file path to expand { Unicode copy = NULL; Unicode result = NULL; int nchunk = 0; char *chunks[UTIL_MAX_PATH_CHUNKS]; int chunkSize[UTIL_MAX_PATH_CHUNKS]; Bool freeChunk[UTIL_MAX_PATH_CHUNKS]; char *cp; int i; ASSERT(fileName); copy = Unicode_Duplicate(fileName); /* * quick exit */ if (!Unicode_StartsWith(fileName, "~") && Unicode_Find(fileName, "$") == UNICODE_INDEX_NOT_FOUND) { return copy; } /* * XXX Because the rest part of code depends pretty heavily from * character pointer operations we want to leave it as-is and * don't want to re-work it with using unicode library. However * it's acceptable only until our Unicode type is utf-8 and * until code below works correctly with utf-8. */ /* * Break string into nice chunks for separate expansion. * * The rule for terminating a ~ expansion is historical. -- edward */ nchunk = 0; for (cp = copy; *cp;) { size_t len; if (*cp == '$') { char *p; for (p = cp + 1; UtilIsAlphaOrNum(*p) || *p == '_'; p++) { } len = p - cp; #if !defined(_WIN32) } else if (cp == copy && *cp == '~') { len = strcspn(cp, DIRSEPS); #endif } else { len = strcspn(cp, "$"); } if (nchunk >= UTIL_MAX_PATH_CHUNKS) { Log("%s: Filename \"%s\" has too many chunks.\n", __FUNCTION__, UTF8(fileName)); goto out; } chunks[nchunk] = cp; chunkSize[nchunk] = len; freeChunk[nchunk] = FALSE; nchunk++; cp += len; } /* * Expand leanding ~ */ #if !defined(_WIN32) if (chunks[0][0] == '~') { char save = (cp = chunks[0])[chunkSize[0]]; cp[chunkSize[0]] = 0; ASSERT(!freeChunk[0]); chunks[0] = UtilDoTildeSubst(chunks[0] + 1); cp[chunkSize[0]] = save; if (chunks[0] == NULL) { /* It could not be expanded, therefore leave as original. */ chunks[0] = cp; } else { /* It was expanded, so adjust the chunks. */ chunkSize[0] = strlen(chunks[0]); freeChunk[0] = TRUE; } } #endif /* * Expand $ */ for (i = 0; i < nchunk; i++) { char save; Unicode expand = NULL; char buf[100]; #if defined(_WIN32) utf16_t bufW[100]; #endif cp = chunks[i]; if (*cp != '$' || chunkSize[i] == 1) { /* * Skip if the chuck has only the $ character. * $ will be kept as a part of the pathname. */ continue; } save = cp[chunkSize[i]]; cp[chunkSize[i]] = 0; /* * $PID and $USER are interpreted specially. * Others are just getenv(). */ expand = Unicode_Duplicate(Posix_Getenv(cp + 1)); if (expand != NULL) { } else if (strcasecmp(cp + 1, "PID") == 0) { Str_Snprintf(buf, sizeof buf, "%"FMTPID, getpid()); expand = Util_SafeStrdup(buf); } else if (strcasecmp(cp + 1, "USER") == 0) { #if !defined(_WIN32) struct passwd *pwd = Posix_Getpwuid(getuid()); expand = UtilGetLoginName(pwd); endpwent(); #else DWORD n = ARRAYSIZE(bufW); if (GetUserNameW(bufW, &n)) { expand = Unicode_AllocWithUTF16(bufW); } #endif if (expand == NULL) { expand = Unicode_Duplicate("unknown"); } } else { Log("Environment variable '%s' not defined in '%s'.\n", cp + 1, fileName); #if !defined(_WIN32) /* * Strip off the env variable string from the pathname. */ expand = Unicode_Duplicate(""); #else // _WIN32 /* * The problem is we have really no way to distinguish the caller's * intention is a dollar sign ($) is used as a part of the pathname * or as an environment variable. * * If the token does not expand to an environment variable, * then assume it is a part of the pathname. Do not strip it * off like it is done in linux host (see above) * * XXX We should also consider using %variable% convention instead * of $variable for Windows platform. */ Str_Strcpy(buf, cp, 100); expand = Unicode_AllocWithUTF8(buf); #endif } cp[chunkSize[i]] = save; ASSERT(expand != NULL); ASSERT(!freeChunk[i]); chunks[i] = expand; if (chunks[i] == NULL) { Log("%s: Cannot allocate memory to expand \"%s\" in \"%s\".\n", __FUNCTION__, expand, UTF8(fileName)); goto out; } chunkSize[i] = strlen(expand); freeChunk[i] = TRUE; } /* * Put all the chunks back together. */ { int size = 1; // 1 for the terminating null for (i = 0; i < nchunk; i++) { size += chunkSize[i]; } result = malloc(size); } if (result == NULL) { Log("%s: Cannot allocate memory for the expansion of \"%s\".\n", __FUNCTION__, UTF8(fileName)); goto out; } cp = result; for (i = 0; i < nchunk; i++) { memcpy(cp, chunks[i], chunkSize[i]); cp += chunkSize[i]; } *cp = 0; out: /* * Clean up and return. */ for (i = 0; i < nchunk; i++) { if (freeChunk[i]) { free(chunks[i]); } } free(copy); return result; } /* *---------------------------------------------------------------------- * * Util_OverrideHomeDir -- * * This function changes the behavior of Util_ExpandPath so that * it will expand "~" to the provided path rather than the current * user's home directory. * * This function is not thread safe, so a best practice is to * invoke it once at the begining of program execution, much like * an *_Init() function. It should also never be called more than * once. * * Results: * None * * Side effects: * Future calls to Util_ExpandPath will substitute "~" with the * given path. * *---------------------------------------------------------------------- */ void Util_OverrideHomeDir(const char *path) // IN { ASSERT(!gHomeDirOverride); gHomeDirOverride = Util_SafeStrdup(path); } open-vm-tools-9.4.0-1280544/lib/misc/sha1.c0000644765153500003110000001602112220061556016140 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* SHA-1 in C Originally released by Steve Reid into the 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 */ /* 12/15/98: JEB: Removed main and moved prototypes to sha1.h Made SHA1Transform a static function */ #if defined(USERLEVEL) || defined(_WIN32) # include # if defined(_WIN32) # include # endif #endif #if defined(sun) && !defined(SOL9) #include #endif #if defined(__FreeBSD__) # if defined(_KERNEL) # include # include # else # include # endif #endif #if defined(__APPLE__) # include #endif #include "vmware.h" #ifdef VMKBOOT #include "vm_libc.h" #endif #if defined(VMKERNEL) #include "vmkernel.h" #include "vm_libc.h" #endif /* VMKERNEL */ #include "sha1.h" #include "vm_basic_asm.h" #include "vmk_exports.h" /* If the endianess is not defined (it is done in string.h of glibc 2.1.1), we default to LE --hpreg */ #ifndef LITTLE_ENDIAN # define LITTLE_ENDIAN /* This should be #define'd if true. */ #endif #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) #define F0(w,x,y) ((w&(x^y))^y) #define F1(w,x,y) (w^x^y) #define F2(w,x,y) (((w|x)&y)|(w&x)) #define F3(w,x,y) (w^x^y) typedef union { unsigned char c[64]; uint32 l[16]; } CHAR64LONG16; static void R(CHAR64LONG16 *block, uint32 *f, int i) { uint32 a, b, c, d, e, round, blk; a = f[0]; b = f[1]; c = f[2]; d = f[3]; e = f[4]; f[1] = a; f[2] = rol(b, 30); f[3] = c; f[4] = d; if (i < 20) { round = 0x5A827999 + F0(b,c,d); } else if (i < 40) { round = 0x6ED9EBA1 + F1(b,c,d); } else if (i < 60) { round = 0x8F1BBCDC + F2(b,c,d); } else { round = 0xCA62C1D6 + F3(b,c,d); } if (i < 16) { #ifdef LITTLE_ENDIAN blk = Bswap(block->l[i]); #else blk = block->l[i]; #endif } else { blk = rol(block->l[(i+13) & 15] ^ block->l[(i+8) & 15] ^ block->l[(i+2) & 15] ^ block->l[i & 15], 1); } block->l[i & 15] = blk; f[0] = e + round + blk + rol(a, 5); } /* Hash a single 512-bit block. This is the core of the algorithm. */ static void _SHA1Transform(uint32 state[5], unsigned char buffer[64]) { int i; uint32 f[5]; CHAR64LONG16* block = (CHAR64LONG16*)buffer; /* Copy context->state[] to working vars */ for (i = 0; i < 5; i++) { f[i] = state[i]; } for (i = 0; i < 80; i++) { R(block, f, i); } /* Add the working vars back into context.state[] */ for (i = 0; i < 5; i++) { state[i] += f[i]; } } #ifdef SHA1HANDSOFF static void SHA1Transform(uint32 state[5], const unsigned char buffer[64]) #else static void SHA1Transform(uint32 state[5], unsigned char buffer[64]) #endif { #ifdef SHA1HANDSOFF unsigned char workspace[64]; /* Do not do that work in _SHA1Transform, otherwise gcc 2.7.2.3 will go south and allocate a stack frame of 0x9c8 bytes, that immediately leads to a stack smash and a host reset */ memcpy(workspace, buffer, sizeof(workspace)); _SHA1Transform(state, workspace); #else _SHA1Transform(state, buffer); #endif } /* 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; } VMK_KERNEL_EXPORT(SHA1Init); /* Run your data through this. */ #ifdef SHA1HANDSOFF void SHA1Update(SHA1_CTX* context, const unsigned char *data, size_t len) #else void SHA1Update(SHA1_CTX* context, unsigned char *data, size_t len) #endif { size_t i, j; j = (context->count[0] >> 3) & 63; if ((context->count[0] += (uint32) (len << 3)) < (len << 3)) context->count[1]++; context->count[1] += (uint32) (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); } VMK_KERNEL_EXPORT(SHA1Update); /* Add padding and return the message digest. */ void SHA1Final(unsigned char digest[SHA1_HASH_LEN], SHA1_CTX* context) { size_t i, j; unsigned char finalcount[8]; for (i = 0; i < 8; i++) { finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ } SHA1Update(context, (unsigned char *)"\200", 1); while ((context->count[0] & 504) != 448) { SHA1Update(context, (unsigned char *)"\0", 1); } SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ for (i = 0; i < SHA1_HASH_LEN; i++) { digest[i] = (unsigned char) ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); } /* Wipe variables */ i = j = 0; memset(context->buffer, 0, 64); memset(context->state, 0, SHA1_HASH_LEN); 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 } VMK_KERNEL_EXPORT(SHA1Final); open-vm-tools-9.4.0-1280544/lib/misc/hostinfoHV.c0000644765153500003110000004125412220061556017401 0ustar dtormts/********************************************************* * Copyright (C) 2011 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * hostinfoHV.c -- * * Code to detect different hypervisors and features. */ #include #include "vmware.h" #if defined(__i386__) || defined(__x86_64__) # include "cpuid_info.h" # include "backdoor_def.h" # include "backdoor_types.h" #endif #include "hostinfo.h" #include "util.h" #define LGPFX "HOSTINFO:" #define LOGLEVEL_MODULE hostinfo #include "loglevel_user.h" /* *---------------------------------------------------------------------- * * Hostinfo_HypervisorCPUIDSig -- * * Get the hypervisor signature string from CPUID. * * Results: * Unqualified 16 byte nul-terminated hypervisor string * String may contain garbage and caller must free * * Side effects: * None * *---------------------------------------------------------------------- */ char * Hostinfo_HypervisorCPUIDSig(void) { uint32 *name = NULL; #if defined(__i386__) || defined(__x86_64__) CPUIDRegs regs; __GET_CPUID(1, ®s); if (!CPUID_ISSET(1, ECX, HYPERVISOR, regs.ecx)) { return NULL; } regs.ebx = 0; regs.ecx = 0; regs.edx = 0; __GET_CPUID(0x40000000, ®s); if (regs.eax < 0x40000000) { Log(LGPFX" CPUID hypervisor bit is set, but no " "hypervisor vendor signature is present\n"); } name = Util_SafeMalloc(4 * sizeof *name); name[0] = regs.ebx; name[1] = regs.ecx; name[2] = regs.edx; name[3] = 0; #endif // defined(__i386__) || defined(__x86_64__) return (char *)name; } /* *---------------------------------------------------------------------- * * Hostinfo_TouchXen -- * * Check for Xen. * * Official way is to call Hostinfo_HypervisorCPUIDSig(), which * returns a hypervisor string. This is a secondary check * that guards against a backdoor failure. See PR156185, * http://xenbits.xensource.com/xen-unstable.hg?file/6a383beedf83/tools/misc/xen-detect.c * (Canonical way is /proc/xen, but CPUID is better). * * Results: * TRUE if we are running in a Xen dom0 or domU. * Linux: * Illegal instruction exception on real hardware. * Obscure Xen implementations might return FALSE. * Windows: * FALSE on real hardware. * * Side effects: * Linux: Will raise exception on native hardware. * Windows: None. * *---------------------------------------------------------------------- */ Bool Hostinfo_TouchXen(void) { #if defined(linux) && (defined(__i386__) || defined(__x86_64__)) #define XEN_CPUID 0x40000000 CPUIDRegs regs; uint32 name[4]; /* * PV mode: ud2a "xen" cpuid (faults on native hardware). * (Only Linux can run PV, so skip others here). * Since PV cannot trap CPUID, this is a Xen hook. */ regs.eax = XEN_CPUID; __asm__ __volatile__( "xchgl %%ebx, %0" "\n\t" "ud2a ; .ascii \"xen\" ; cpuid" "\n\t" "xchgl %%ebx, %0" : "=&r" (regs.ebx), "=&c" (regs.ecx), "=&d" (regs.edx) : "a" (regs.eax) ); name[0] = regs.ebx; name[1] = regs.ecx; name[2] = regs.edx; name[3] = 0; if (0 == strcmp(CPUID_XEN_HYPERVISOR_VENDOR_STRING, (const char*)name)) { return TRUE; } /* Passed checks. But native and anything non-Xen would #UD before here. */ NOT_TESTED(); Log("Xen detected but hypervisor unrecognized (Xen variant?)\n"); Log("CPUID 0x4000 0000: eax=%x ebx=%x ecx=%x edx=%x\n", regs.eax, regs.ebx, regs.ecx, regs.edx); #endif return FALSE; } /* *---------------------------------------------------------------------- * * Hostinfo_SLC64Supported -- * * Access the backdoor with an SLC64 control query. This is used * to determine if we are running in a VM that supports SLC64. * This function should only be called after determining that the * backdoor is present with Hostinfo_TouchBackdoor(). * * Results: * TRUE if the outer VM supports SLC64. * FALSE otherwise. * * Side effects: * Exception if not in a VM, so don't do that! * *---------------------------------------------------------------------- */ Bool Hostinfo_SLC64Supported(void) { #if defined(__i386__) || defined(__x86_64__) return Hostinfo_VCPUInfoBackdoor(BDOOR_CMD_VCPU_SLC64); #else return FALSE; #endif } /* *---------------------------------------------------------------------- * * Hostinfo_NestedHVReplaySupported -- * * Access the backdoor with a HV replay control query. This is used * to determine if we are running in a VM that supports nested HV replay. * This function should only be called after determining that the * backdoor is present with Hostinfo_TouchBackdoor(). * * Results: * TRUE if the outer VM supports nexted HV replay. * FALSE otherwise. * * Side effects: * Exception if not in a VM, so don't do that! * *---------------------------------------------------------------------- */ Bool Hostinfo_NestedHVReplaySupported(void) { #if defined(__i386__) || defined(__x86_64__) return Hostinfo_VCPUInfoBackdoor(BDOOR_CMD_VCPU_HV_REPLAY_OK); #else return FALSE; #endif } /* *---------------------------------------------------------------------- * * Hostinfo_SynchronizedVTSCs -- * * Access the backdoor to determine if the VCPUs' TSCs are * synchronized. * * Results: * TRUE if the outer VM provides synchronized VTSCs. * FALSE otherwise. * * Side effects: * Exception if not in a VM, so don't do that! * *---------------------------------------------------------------------- */ Bool Hostinfo_SynchronizedVTSCs(void) { #if defined(__i386__) || defined(__x86_64__) return Hostinfo_VCPUInfoBackdoor(BDOOR_CMD_VCPU_SYNC_VTSCS); #else return FALSE; #endif } #if defined(_WIN32) #if defined(_WIN64) // from touchBackdoorMasm64.asm void Hostinfo_BackdoorInOut(Backdoor_proto *myBp); #endif /* *---------------------------------------------------------------------- * * Hostinfo_TouchBackDoor -- * * Access the backdoor. This is used to determine if we are * running in a VM or on a physical host. On a physical host * this should generate a GP which we catch and thereby determine * that we are not in a VM. However some OSes do not handle the * GP correctly and the process continues running returning garbage. * In this case we check the EBX register which should be * BDOOR_MAGIC if the IN was handled in a VM. Based on this we * return either TRUE or FALSE. * * Results: * TRUE if we succesfully accessed the backdoor, FALSE or segfault * if not. * * Side effects: * Exception if not in a VM. * *---------------------------------------------------------------------- */ Bool Hostinfo_TouchBackDoor(void) { uint32 ebxval; #if defined(_WIN64) Backdoor_proto bp; bp.in.ax.quad = BDOOR_MAGIC; bp.in.size = ~BDOOR_MAGIC; bp.in.cx.quad = BDOOR_CMD_GETVERSION; bp.in.dx.quad = BDOOR_PORT; Hostinfo_BackdoorInOut(&bp); ebxval = bp.out.bx.words.low; #else // _WIN64 _asm { push edx push ecx push ebx mov ecx, BDOOR_CMD_GETVERSION mov ebx, ~BDOOR_MAGIC mov eax, BDOOR_MAGIC mov dx, BDOOR_PORT in eax, dx mov ebxval, ebx pop ebx pop ecx pop edx } #endif // _WIN64 return (ebxval == BDOOR_MAGIC) ? TRUE : FALSE; } /* *---------------------------------------------------------------------- * * Hostinfo_TouchVirtualPC -- * * Access MS Virtual PC's backdoor. This is used to determine if * we are running in a MS Virtual PC or on a physical host. Works * the same as Hostinfo_TouchBackDoor, except the entry to MS VPC * is an invalid opcode instead or writing to a port. Since * MS VPC is 32-bit only, the WIN64 path returns FALSE. * See: See: http://www.codeproject.com/KB/system/VmDetect.aspx * * Results: * TRUE if we succesfully accessed MS Virtual PC, FALSE or * segfault if not. * * Side effects: * Exception if not in a VM. * *---------------------------------------------------------------------- */ Bool Hostinfo_TouchVirtualPC(void) { #if defined(_WIN64) return FALSE; // MS Virtual PC is 32-bit only #else // _WIN32 uint32 ebxval; _asm { push ebx mov ebx, 0 mov eax, 1 // Virtual PC function number // execute invalid opcode to call into MS Virtual PC __emit 0Fh __emit 3Fh __emit 07h __emit 0Bh mov ebxval, ebx pop ebx } return !ebxval; // ebx is zero if inside Virtual PC #endif } /* *---------------------------------------------------------------------- * * Hostinfo_NestingSupported -- * * Access the backdoor with a nesting control query. This is used * to determine if we are running in a VM that supports nesting. * This function should only be called after determining that the * backdoor is present with Hostinfo_TouchBackdoor(). * * Results: * TRUE if the outer VM supports nesting. * FALSE otherwise. * * Side effects: * Exception if not in a VM, so don't do that! * *---------------------------------------------------------------------- */ Bool Hostinfo_NestingSupported(void) { uint32 cmd = NESTING_CONTROL_QUERY << 16 | BDOOR_CMD_NESTING_CONTROL; uint32 result; #if defined(_WIN64) Backdoor_proto bp; bp.in.ax.quad = BDOOR_MAGIC; bp.in.cx.quad = cmd; bp.in.dx.quad = BDOOR_PORT; Hostinfo_BackdoorInOut(&bp); result = bp.out.ax.words.low; #else _asm { push edx push ecx mov ecx, cmd mov eax, BDOOR_MAGIC mov dx, BDOOR_PORT in eax, dx mov result, eax pop ecx pop edx } #endif if (result >= NESTING_CONTROL_QUERY && result != ~0U) { return TRUE; } return FALSE; } /* *---------------------------------------------------------------------- * * Hostinfo_VCPUInfoBackdoor -- * * Access the backdoor with an VCPU info query. This is used to * determine whether a VCPU supports a particular feature, * determined by 'bit'. This function should only be called after * determining that the backdoor is present with * Hostinfo_TouchBackdoor(). * * Results: * TRUE if the outer VM supports the feature. * FALSE otherwise. * * Side effects: * Exception if not in a VM, so don't do that! * *---------------------------------------------------------------------- */ Bool Hostinfo_VCPUInfoBackdoor(unsigned bit) { uint32 cmd = BDOOR_CMD_GET_VCPU_INFO; uint32 result; #if defined(_WIN64) Backdoor_proto bp; bp.in.ax.quad = BDOOR_MAGIC; bp.in.cx.quad = cmd; bp.in.dx.quad = BDOOR_PORT; Hostinfo_BackdoorInOut(&bp); result = bp.out.ax.words.low; #else _asm { push edx push ecx mov ecx, cmd mov eax, BDOOR_MAGIC mov dx, BDOOR_PORT in eax, dx mov result, eax pop ecx pop edx } #endif /* If reserved bit is 1, this command wasn't implemented. */ return (result & (1 << BDOOR_CMD_VCPU_RESERVED)) == 0 && (result & (1 << bit)) != 0; } #else /* *---------------------------------------------------------------------- * * Hostinfo_TouchBackDoor -- * * Access the backdoor. This is used to determine if we are * running in a VM or on a physical host. On a physical host * this should generate a GP which we catch and thereby determine * that we are not in a VM. However some OSes do not handle the * GP correctly and the process continues running returning garbage. * In this case we check the EBX register which should be * BDOOR_MAGIC if the IN was handled in a VM. Based on this we * return either TRUE or FALSE. * * Results: * TRUE if we succesfully accessed the backdoor, FALSE or segfault * if not. * * Side effects: * Exception if not in a VM. * *---------------------------------------------------------------------- */ Bool Hostinfo_TouchBackDoor(void) { #if defined(__i386__) || defined(__x86_64__) uint32 eax; uint32 ebx; uint32 ecx; __asm__ __volatile__( # if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler. "xchgl %%ebx, %1" "\n\t" "inl %%dx, %%eax" "\n\t" "xchgl %%ebx, %1" : "=a" (eax), "=&rm" (ebx), # else "inl %%dx, %%eax" : "=a" (eax), "=b" (ebx), # endif "=c" (ecx) : "0" (BDOOR_MAGIC), "1" (~BDOOR_MAGIC), "2" (BDOOR_CMD_GETVERSION), "d" (BDOOR_PORT) ); if (ebx == BDOOR_MAGIC) { return TRUE; } #endif return FALSE; } /* *---------------------------------------------------------------------- * * Hostinfo_TouchVirtualPC -- * * Access MS Virtual PC's backdoor. This is used to determine if * we are running in a MS Virtual PC or on a physical host. Works * the same as Hostinfo_TouchBackDoor, except the entry to MS VPC * is an invalid opcode instead or writing to a port. Since * MS VPC is 32-bit only, the 64-bit path returns FALSE. * See: http://www.codeproject.com/KB/system/VmDetect.aspx * * Results: * TRUE if we succesfully accessed MS Virtual PC, FALSE or * segfault if not. * * Side effects: * Exception if not in a VM. * *---------------------------------------------------------------------- */ Bool Hostinfo_TouchVirtualPC(void) { #if defined vm_x86_64 return FALSE; #else uint32 ebxval; __asm__ __volatile__ ( # if defined __PIC__ // %ebx is reserved by the compiler. "xchgl %%ebx, %1" "\n\t" ".long 0x0B073F0F" "\n\t" "xchgl %%ebx, %1" : "=&rm" (ebxval) : "a" (1), "0" (0) # else ".long 0x0B073F0F" : "=b" (ebxval) : "a" (1), "b" (0) # endif ); return !ebxval; // %%ebx is zero if inside Virtual PC #endif } /* *---------------------------------------------------------------------- * * Hostinfo_NestingSupported -- * * Access the backdoor with a nesting control query. This is used * to determine if we are running inside a VM that supports nesting. * This function should only be called after determining that the * backdoor is present with Hostinfo_TouchBackdoor(). * * Results: * TRUE if the outer VM supports nesting. * FALSE otherwise. * * Side effects: * Exception if not in a VM, so don't do that! * *---------------------------------------------------------------------- */ Bool Hostinfo_NestingSupported(void) { #if defined(__i386__) || defined(__x86_64__) uint32 cmd = NESTING_CONTROL_QUERY << 16 | BDOOR_CMD_NESTING_CONTROL; uint32 result; __asm__ __volatile__( "inl %%dx, %%eax" : "=a" (result) : "0" (BDOOR_MAGIC), "c" (cmd), "d" (BDOOR_PORT) ); if (result >= NESTING_CONTROL_QUERY && result != ~0U) { return TRUE; } #endif return FALSE; } /* *---------------------------------------------------------------------- * * Hostinfo_VCPUInfoBackdoor -- * * Access the backdoor with an VCPU info query. This is used to * determine whether a VCPU supports a particular feature, * determined by 'bit'. This function should only be called after * determining that the backdoor is present with * Hostinfo_TouchBackdoor(). * * Results: * TRUE if the outer VM supports the feature. * FALSE otherwise. * * Side effects: * Exception if not in a VM, so don't do that! * *---------------------------------------------------------------------- */ Bool Hostinfo_VCPUInfoBackdoor(unsigned bit) { #if defined(__i386__) || defined(__x86_64__) uint32 result; __asm__ __volatile__( "inl %%dx, %%eax" : "=a" (result) : "0" (BDOOR_MAGIC), "c" (BDOOR_CMD_GET_VCPU_INFO), "d" (BDOOR_PORT) ); /* If reserved bit is 1, this command wasn't implemented. */ return (result & (1 << BDOOR_CMD_VCPU_RESERVED)) == 0 && (result & (1 << bit)) != 0; #endif return FALSE; } #endif open-vm-tools-9.4.0-1280544/lib/misc/posixDlopen.c0000644765153500003110000000320512220061556017610 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #define UNICODE_BUILDING_POSIX_WRAPPERS #include #include #include #if !defined(_WIN32) #include #endif #include "vmware.h" #include "posixInt.h" #if !defined(_WIN32) /* *---------------------------------------------------------------------- * * Posix_Dlopen -- * * POSIX dlopen() * * Results: * NULL Error * !NULL Success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ void * Posix_Dlopen(ConstUnicode pathName, // IN: int flag) // IN: { char *path; void *ret; if (!PosixConvertToCurrent(pathName, &path)) { return NULL; } ret = dlopen(path, flag); free(path); return ret; } #endif open-vm-tools-9.4.0-1280544/lib/misc/msgfmt.c0000644765153500003110000022506312220061556016611 0ustar dtormts/* ********************************************************** * Copyright 2007 VMware, Inc. All rights reserved. * **********************************************************/ /* * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * 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. */ /* * msgfmt.c -- * * MsgFmt: format messages for the Msg module */ #ifdef VMKERNEL #include "vmkernel.h" #include "vm_types.h" #include "vm_libc.h" #else #include #include #include #include #include #if defined(__FreeBSD__) #include #endif #if !defined(_WIN32) && !defined(SOL9) && \ (!defined(__FreeBSD__) || __FreeBSD_version >= 500029) #include #endif #if !defined(__FreeBSD__) || __FreeBSD_version >= 400017 #include #endif #include "vmware.h" #include "bsdfmt.h" #include "err.h" #endif #include "msgfmt.h" #ifdef HAS_BSD_PRINTF #include #include #include "msgid.h" #endif /* * Older versions of FreeBSD don't have C99 support (stdint), and also * do not have wide character support. Re-implement the stuff we need * in those cases. */ #if defined(__FreeBSD__) && __FreeBSD_version <= 320001 static INLINE const wchar_t * wmemchr(const wchar_t *s, wchar_t c, size_t n) { size_t i; for (i = 0; i < n; i++) { if (s[i] == c) { return &s[i]; } } return NULL; } static INLINE size_t wcslen(const wchar_t *s) { size_t i; for (i = 0; s[i]; i++); return i; } #endif /* * The vmkernel doesn't have the Str module, malloc(), or * some of the standard C string functions. * The only ones we really need are Str_Vsnprintf() and memchr(). */ #ifdef VMKERNEL // { typedef int32 wchar_t; typedef int32 wint_t; typedef int64 intmax_t; typedef size_t ptrdiff_t; #define STUB(t, f, a) \ static INLINE t f a { NOT_IMPLEMENTED(); return (t) 0;} #define VSTUB(f, a) \ static INLINE void f a { NOT_IMPLEMENTED(); } STUB(char *, Str_Vasprintf, (char **b, const char *f, va_list a)) STUB(void *, malloc, (size_t s)) STUB(void *, realloc, (void *p, size_t s)) STUB(wchar_t *, wmemchr, (const wchar_t *s, wchar_t c, size_t n)) STUB(size_t, wcslen, (const wchar_t *s)) STUB(char *, strdup, (const char *s)) VSTUB(free, (void *p)) #undef STUB #undef VSTUB typedef int Err_Number; #define ERR_INVALID (-1) static INLINE Err_Number Err_String2Errno(const char *string) { return ERR_INVALID; } #ifdef VMX86_DEBUG static INLINE Err_Number Err_String2ErrnoDebug(const char *string) { return ERR_INVALID; } #endif static INLINE int Str_Vsnprintf(char *str, size_t size, const char *format, va_list ap) { int n = vsnprintf(str, size, format, ap); ASSERT(n >= 0); if (n >= size) { str[size - 1] = '\0'; n = -1; } return n; } static INLINE const void * memchr(const void *s, int c, size_t n) { const uint8 *p = s; const uint8 *e = p + n; while (p < e) { if (*p++ == c) { return p; } } return NULL; } #endif // } #if defined __ANDROID__ /* * Android doesn't support dtoa(). */ #define NO_DTOA #endif /* * Local data */ typedef struct MsgFmtParseState { MsgFmt_Arg *args; int numArgs; int maxArgs; char *error; /* * Allocator state for caller-supplied buffer. */ void *buf; char *bufp; char *bufe; } MsgFmtParseState; /* d, i, o, u, x, X, e, E, f, F, g, G, a, A, c, s, C, S, p, and n --hpreg */ static int const isSpecifier[] = { 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, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; /* * Local functions */ static MsgFmt_SpecFunc MsgFmtGetArg1; static int MsgFmtAToI(char const **start, char const *end); static void MsgFmtError(MsgFmtParseState *state, const char *fmt, ...); static void MsgFmtAllocInit(MsgFmtParseState *state, void *buf, size_t size); static void *MsgFmtAlloc(MsgFmtParseState *state, size_t size); static Bool MsgFmtAllocArgs(MsgFmtParseState *state, int n); static char *MsgFmtVasprintf(MsgFmtParseState *state, const char *fmt, va_list args); static void MsgFmtFreeAll(MsgFmtParseState *state); static size_t MsgFmtBufUsed(MsgFmtParseState *state); #ifdef HAS_BSD_PRINTF static int MsgFmtSnprintfWork(char **outbuf, size_t bufSize, const char *fmt0, const struct MsgFmt_Arg *args, int numArgs); #endif /* *----------------------------------------------------------------------------- * * MsgFmt_ParseWin32 -- * * Convert the Win32 representation of a format string into another * representation --hpreg * * XXX I haven't implemented %0 and %n, because they suck: * . they mix content and presentation * . they have nothing to do with parameters and hence have no * equivalent in other systems * * Results: * 0 on success * -1 on failure: out of memory * -2 on failure: invalid 'in' * * Side effects: * None * *----------------------------------------------------------------------------- */ int MsgFmt_ParseWin32(MsgFmt_LitFunc *litFunc, // IN MsgFmt_SpecFunc *specFunc, // IN void *clientData, // IN char const *in) // IN { char const *startUnescaped; unsigned int sm; char const *pos = 0 /* Compiler warning --hpreg */; char const *type = 0 /* Compiler warning --hpreg */; int status; startUnescaped = in; sm = 0; for (; *in != '\0'; in++) { /* Unsigned does matter --hpreg */ unsigned char ubyte; ubyte = *in; switch (sm) { case 2: /* Found %<1-9>... --hpreg */ if (ubyte >= '0' && ubyte <= '9') { break; } if (ubyte == '!') { type = in + 1; sm = 3; break; } if ((status = (*litFunc)(clientData, startUnescaped, pos - 1 - startUnescaped)) < 0 || (status = (*specFunc)(clientData, pos, in - pos, "s", 1)) < 0) { return status; } startUnescaped = in; sm = 0; /* Fall through --hpreg */ case 0: /* Found --hpreg */ if (ubyte == '%') { pos = in + 1; sm = 1; } break; case 1: /* Found % --hpreg */ if (ubyte >= '1' && ubyte <= '9') { sm = 2; } else { ASSERT_NOT_IMPLEMENTED(ubyte != '0' && ubyte != 'n'); status = (*litFunc)(clientData, startUnescaped, in - 1 - startUnescaped); if (status < 0) { return status; } startUnescaped = in; sm = 0; } break; case 3: /* Found %<1-9>...!... --hpreg */ if (ubyte == '!') { if ( (status = (*litFunc)(clientData, startUnescaped, pos - 1 - startUnescaped)) < 0 || (status = (*specFunc)(clientData, pos, type - 1 - pos, type, in - type)) < 0) { return status; } startUnescaped = in + 1; sm = 0; } break; default: NOT_IMPLEMENTED(); break; } } switch (sm) { case 0: status = (*litFunc)(clientData, startUnescaped, in - startUnescaped); if (status < 0) { return status; } break; case 2: if ( (status = (*litFunc)(clientData, startUnescaped, pos - 1 - startUnescaped)) < 0 || (status = (*specFunc)(clientData, pos, in - pos, "s", 1)) < 0) { return status; } break; case 1: case 3: return -2; break; default: NOT_IMPLEMENTED(); break; } return 0; } /* *----------------------------------------------------------------------------- * * MsgFmt_Parse -- * * Parse a message format. * * Results: * 0 on success * -1 on failure: out of memory * -2 on failure: invalid 'in' * * Side effects: * None * *----------------------------------------------------------------------------- */ int MsgFmt_Parse(MsgFmt_LitFunc *litFunc, // IN MsgFmt_SpecFunc *specFunc, // IN void *clientData, // IN char const *in) // IN { char const *startUnescaped; unsigned int sm; unsigned int counter; int status; char const *startEscaped = 0 /* Compiler warning --hpreg */; char const *type = 0 /* Compiler warning --hpreg */; Bool usePos = FALSE /* Compiler warning --hpreg */; startUnescaped = in; sm = 0; counter = 0; for (; *in != '\0'; in++) { /* Unsigned does matter --hpreg */ unsigned char ubyte; ubyte = *in; switch (sm) { case 0: /* Found --hpreg */ if (ubyte == '%') { sm = 1; } break; case 1: /* Found % --hpreg */ if (ubyte == '%') { if (litFunc != NULL && (status = (*litFunc)(clientData, startUnescaped, in - 1 - startUnescaped)) < 0) { return status; } startUnescaped = in; sm = 0; break; } startEscaped = in; type = in; if (ubyte >= '1' && ubyte <= '9') { sm = 2; break; } sm = 3; /* Fall through --hpreg */ case 3: /* Found %<1-9>...$... or %... --hpreg */ variant3: if (isSpecifier[ubyte]) { char const *pos; char const *posEnd; char posBuf[10 /* 32 bits unsigned in decimal --hpreg */]; if (counter) { if (usePos != (startEscaped != type)) { return -2; } } else { usePos = (startEscaped != type); } counter++; if (usePos) { pos = startEscaped; posEnd = type - 1; } else { char *current; unsigned int value; current = posBuf + sizeof(posBuf); posEnd = current; value = counter; ASSERT(value); do { current--; ASSERT(current >= posBuf); *current = '0' + value % 10; value /= 10; } while (value); pos = current; } if (litFunc != NULL && (status = (*litFunc)(clientData, startUnescaped, startEscaped - 1 - startUnescaped)) < 0) { return status; } if ((status = (*specFunc)(clientData, pos, posEnd - pos, type, in + 1 - type)) < 0) { return status; } startUnescaped = in + 1; sm = 0; break; } /* Digits for field width & precision, zero for leading zeroes, and dot for separator between width and precision. */ if ((ubyte >= '0' && ubyte <= '9') || ubyte == '.') { break; } /* Flags */ if (ubyte == '#' || ubyte == '-' || ubyte == ' ' || ubyte == '+' || ubyte == '\'') { break; } /* Length modifiers */ if (ubyte == 'L' || ubyte == 'l' || ubyte == 'h' || ubyte == 'z' || ubyte == 'Z' || ubyte == 't' || ubyte == 'q' || ubyte == 'j' || ubyte == 'I') { break; } return -2; case 2: /* Found %<1-9>... --hpreg */ if (ubyte >= '0' && ubyte <= '9') { break; } if (ubyte == '$') { type = in + 1; sm = 3; break; } sm = 3; goto variant3; default: NOT_IMPLEMENTED(); break; } } if (sm) { return -2; } if (litFunc != NULL && (status = (*litFunc)(clientData, startUnescaped, in - startUnescaped)) < 0) { return status; } return 0; } /* *----------------------------------------------------------------------------- * * MsgFmt_ParseSpec -- * * Given a format specifier (the % stuff), return its contituent parts. * * Results: * 0 on success, -2 (bad format) on failure. * Out parameters: * Width and precision are -1 if not specified. * Length modifier is '\0' if not specified. * Length modifier of "ll", "I64", or "q" is returned as 'L'. * (This means we freely allow %llf and %qf, which is not strictly * correct. However, glibc printf allows them (as well as %Ld), * and they mean the same thing.) * Length modifier of "hh" is returned as 'H'. * Length modifier of "Z" is returned as 'z', for compatibility * with old glibc. * On failure, some or all of the out parameters may be modified * in an undefined manner. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int MsgFmt_ParseSpec(char const *pos, // IN: n$ location unsigned int posSize, // IN: n$ length char const *type, // IN: specifier after position unsigned int typeSize, // IN: size of above int *position, // OUT: argument position int *flags, // OUT: flags int *width, // OUT: width int *precision, // OUT: precision char *lengthMod, // OUT: length modifier char *conversion) // OUT: conversion specifier { char const *p = type; char const *end = type + typeSize; /* * Convert argument position to int. * Fail if not a good decimal number greater than 0. */ { char const *posEnd = pos + posSize; *position = MsgFmtAToI(&pos, posEnd); if (*position <= 0 || pos != posEnd) { return -2; } } /* * The format specifier is, in this order, * zero or more flags * an optional width (a decimal number or *) * an optional precision (. followed by optional decimal number or *) * an optional length modifier (l, L, ll, z, etc.) * conversion specifier (a character) * * The rest of this module does not recognize * as width or precision, * so we don't do it here either. * * glibc 2.2 supports the I flag, which we don't. Instead, we * support the I, I32, and I64 length modifiers used by Microsoft. */ /* * Flags */ *flags = 0; for (; p < end; p++) { switch (*p) { case '#': *flags |= MSGFMT_FLAG_ALT; continue; case '0': *flags |= MSGFMT_FLAG_ZERO; continue; case '-': *flags |= MSGFMT_FLAG_MINUS; continue; case ' ': *flags |= MSGFMT_FLAG_SPACE; continue; case '+': *flags |= MSGFMT_FLAG_PLUS; continue; case '\'': *flags |= MSGFMT_FLAG_QUOTE; continue; default: break; } break; } /* * Width */ if (p >= end || *p < '1' || *p > '9') { *width = -1; } else { *width = MsgFmtAToI(&p, end); if (*width < 0) { return -2; } } /* * Precision */ if (p >= end || *p != '.') { *precision = -1; } else { p++; *precision = MsgFmtAToI(&p, end); if (*precision < 0) { return -2; } } /* * Length modifier */ if (p >= end) { return -2; } *lengthMod = '\0'; switch (*p) { case 'h': p++; if (p >= end || *p != 'h') { *lengthMod = 'h'; } else { p++; *lengthMod = 'H'; } break; case 'l': p++; if (p >= end || *p != 'l') { *lengthMod = 'l'; } else { p++; *lengthMod = 'L'; } break; case 'I': /* * Microsoft: * I64 is 64-bit number. For us, the same as L. * I32 is 32-bit number. For us, nothing. * I is size_t. */ if (p + 2 < end && p[1] == '6' && p[2] == '4') { p += 3; *lengthMod = 'L'; } else if (p + 2 < end && p[1] == '3' && p[2] == '2') { p += 3; } else { p++; *lengthMod = 'z'; } break; case 'q': p++; *lengthMod = 'L'; break; case 'Z': p++; *lengthMod = 'z'; break; case 'L': case 'j': case 'z': case 't': *lengthMod = *p++; break; } /* * Conversion specifier * * Return false if no conversion specifier or not the last character. */ if (p + 1 == end && isSpecifier[(unsigned char) *p]) { *conversion = *p; return 0; } return -2; } /* *----------------------------------------------------------------------------- * * MsgFmtAToI -- * * Convert numeric string to integer. * The range is 0 to MAX_INT32 (nonnegative 32-bit signed int). * Empty string or a string that does not begin with * a digit is treated as 0. * * Results: * The number or -1 on overflow. * Start pointer updated to point to first nonnumeric character. * or first character before overflow. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int MsgFmtAToI(char const **start, // IN/OUT: string pointer char const *end) // IN: end of string { char const *p; int n = 0; ASSERT_ON_COMPILE(sizeof (int) >= 4); for (p = *start; p < end && *p >= '0' && *p <= '9'; p++) { if (n > MAX_INT32 / 10) { n = -1; break; } n *= 10; n += *p - '0'; if (n < 0) { n = -1; break; } } *start = p; return n; } /* *----------------------------------------------------------------------------- * * MsgFmt_GetArgs -- * * Parse a format string and return the arguments implied by it. * * Results: * TRUE on sucess. * Out parameters: * The array of MsgFmt_Arg structures. * The number of arguments. * An error string on failure. * * Side effects: * Memory is allocated. * *----------------------------------------------------------------------------- */ Bool MsgFmt_GetArgs(const char *fmt, // IN: format string va_list va, // IN: the argument list MsgFmt_Arg **args, // OUT: the returned arguments int *numArgs, // OUT: number of returned arguments char **error) // OUT: error string { return MsgFmt_GetArgsWithBuf(fmt, va, args, numArgs, error, NULL, NULL); } /* *----------------------------------------------------------------------------- * * MsgFmt_GetArgsWithBuf -- * * Parse a format string and return the arguments implied by it. * * If buf is supplied, allocate memory there instead of with malloc(). * * Results: * TRUE on sucess. * Out parameters: * The array of MsgFmt_Arg structures. * The number of arguments. * An error string on failure. * The amount of buf used (if caller supplied buf) * * Side effects: * Memory may be allocated. * *----------------------------------------------------------------------------- */ Bool MsgFmt_GetArgsWithBuf(const char *fmt, // IN: format string va_list va, // IN: the argument list MsgFmt_Arg **args, // OUT: the returned arguments int *numArgs, // OUT: number of returned arguments char **error, // OUT: error string void *buf, // OUT: memory to store output size_t *bufSize) // IN/OUT: size of buf / // amount of buf used { MsgFmtParseState state; int status; int i; memset(&state, 0, sizeof state); if (buf != NULL) { ASSERT(bufSize != NULL); MsgFmtAllocInit(&state, buf, *bufSize); } /* * First pass: parse format to get argument information */ status = MsgFmt_Parse(NULL, MsgFmtGetArg1, &state, fmt); if (status < 0) { goto bad; } /* * Second pass: get argument values * * While we can store most values directly in the MsgFmt_Arg * structure, strings have to be copied into allocated space. * When precision is specified (see comment about it in * MsgFmtGetArg1()), we copy at most that many bytes because * that's how many printf() looks at, and we must not touch * memory beyond what printf() would. */ for (i = 0; i < state.numArgs; i++) { MsgFmt_Arg *a = state.args + i; switch (a->type) { case MSGFMT_ARG_INVALID: MsgFmtError(&state, "MsgFmt_GetArgs: gap in arguments at position %d", i + 1); goto bad; break; case MSGFMT_ARG_INT32: ASSERT_ON_COMPILE(sizeof (int) == sizeof (int32)); a->v.signed32 = va_arg(va, int); break; case MSGFMT_ARG_INT64: ASSERT_ON_COMPILE(sizeof (long long) == sizeof (int64)); a->v.signed64 = va_arg(va, long long); break; case MSGFMT_ARG_PTR32: // we can only handle this case if native pointer is 4 bytes ASSERT(sizeof (void *) == sizeof (uint32)); a->v.unsigned32 = (uint32) (uintptr_t) va_arg(va, void *); break; case MSGFMT_ARG_PTR64: // we can only handle this case if native pointer is 8 bytes ASSERT(sizeof (void *) == sizeof (uint64)); a->v.unsigned64 = (uint64) (uintptr_t) va_arg(va, void *); break; #ifndef NO_FLOATING_POINT case MSGFMT_ARG_FLOAT64: ASSERT_ON_COMPILE(sizeof (double) == 8); a->v.float64 = va_arg(va, double); break; #endif case MSGFMT_ARG_STRING8: { const char *p = va_arg(va, char *); size_t n; Err_Number errorNumber; ASSERT_ON_COMPILE(sizeof (char) == sizeof (int8)); ASSERT_ON_COMPILE(offsetof(MsgFmt_Arg, v.string8) == offsetof(MsgFmt_Arg, v.ptr)); if (p == NULL) { a->v.string8 = NULL; } else { if (a->p.precision < 0) { n = strlen(p); } else { const char *q; n = a->p.precision; q = memchr(p, '\0', n); if (q != NULL) { n = q - p; } } // yes, sizeof (int8) is 1. a->v.string8 = MsgFmtAlloc(&state, n + 1); if (a->v.string8 == NULL) { status = -1; goto bad; } memcpy(a->v.string8, p, n); a->v.string8[n] = '\0'; } errorNumber = Err_String2Errno(p); #ifdef VMX86_DEBUG if (errorNumber == ERR_INVALID && p != NULL) { // p may not be null terminated, so use string8 errorNumber = Err_String2ErrnoDebug(a->v.string8char); if (errorNumber != ERR_INVALID) { // Err_String2ErrnoDebug already logged its info Log("%s: failed to look up copied error string at %p.\n", __FUNCTION__, p); } } #endif if (errorNumber != ERR_INVALID) { ASSERT_NOT_IMPLEMENTED(MSGFMT_CURRENT_PLATFORM != MSGFMT_PLATFORM_UNKNOWN); ASSERT_ON_COMPILE(sizeof errorNumber == sizeof a->e.number); a->type = MSGFMT_ARG_ERRNO; a->e.platform = MSGFMT_CURRENT_PLATFORM; a->e.number = errorNumber; break; } break; } case MSGFMT_ARG_STRING16: case MSGFMT_ARG_STRING32: { // we can only handle the case when native wchar_t matches // the string char size const wchar_t *p = va_arg(va, wchar_t *); size_t n; ASSERT(a->type == MSGFMT_ARG_STRING16 ? sizeof (wchar_t) == sizeof (int16) : sizeof (wchar_t) == sizeof (int32)); ASSERT_ON_COMPILE(offsetof(MsgFmt_Arg, v.string16) == offsetof(MsgFmt_Arg, v.ptr)); ASSERT_ON_COMPILE(offsetof(MsgFmt_Arg, v.string32) == offsetof(MsgFmt_Arg, v.ptr)); if (p == NULL) { a->v.ptr = NULL; } else { if (a->p.precision < 0) { n = wcslen(p); } else { const wchar_t *q; n = a->p.precision; q = wmemchr(p, 0, n); if (q != NULL) { n = q - p; } } a->v.ptr = MsgFmtAlloc(&state, sizeof (wchar_t) * (n + 1)); if (a->v.ptr == NULL) { status = -1; goto bad; } memcpy(a->v.ptr, p, sizeof (wchar_t) * n); ((wchar_t *) a->v.ptr)[n] = 0; } break; } case MSGFMT_ARG_ERRNO: // there shouldn't be this case here default: NOT_REACHED(); } // clear private data memset(&a->p, 0, sizeof a->p); } /* * Pass results back */ if (args == NULL) { MsgFmtFreeAll(&state); } else { *args = state.args; } if (numArgs != NULL) { *numArgs = state.numArgs; } if (bufSize != NULL) { *bufSize = MsgFmtBufUsed(&state); } ASSERT(state.error == NULL); *error = NULL; return TRUE; bad: if (state.error == NULL) { switch (status) { case -1: MsgFmtError(&state, "MsgFmt_GetArgs: out of memory"); break; case -2: MsgFmtError(&state, "MsgFmt_GetArgs: error in format string"); break; default: MsgFmtError(&state, "MsgFmt_GetArgs: error %d", status); } } ASSERT(state.args == NULL); // MsgFmtError() frees args *error = state.error; return FALSE; } /* *----------------------------------------------------------------------------- * * MsgFmtGetArg1 -- * * Process one format specifier for MsgFmt_GetArgs(). * Called by MsgFmt_Parse(). * * Results: * 0 on success, * negative status on failure (see MsgFmt_Parse()). * error string in state.error on failure. * * Side effects: * Memory is allocated. * *----------------------------------------------------------------------------- */ static int MsgFmtGetArg1(void *clientData, // IN: state const char *pos, // IN: n$ location unsigned int posSize, // IN: n$ length char const *type, // IN: specifier after position unsigned int typeSize) // IN: size of above { MsgFmtParseState *state = clientData; MsgFmt_Arg *a; int position; int flags; int width; int precision; char lengthMod; char conversion; MsgFmt_ArgType argType = MSGFMT_ARG_INVALID; int status; /* * Parse format specifier */ status = MsgFmt_ParseSpec(pos, posSize, type, typeSize, &position, &flags, &width, &precision, &lengthMod, &conversion); if (status < 0) { MsgFmtError(state, "MsgFmtGetArg1: bad specifier, " "status %d, pos \"%.*s\", type \"%.*s\"", status, posSize, pos, typeSize, type); return status; } /* * Make room in argument array if necessary. */ if (position > state->numArgs) { if (!MsgFmtAllocArgs(state, position)) { MsgFmtError(state, "MsgFmtGetArg1: out of memory at arg %d", position); return -1; } state->numArgs = position; } /* * Fill in argument structure based on the format specifier. * * For strings, the precision argument is the maximum length * to print. We need to keep track of it so MsgFmt_GetArgs() * can know how many characters to squirrel away, in case * the string isn't null terminated, is very long, or falls off * the end of the world. * * In all other cases, the precision is unimportant to us * and we don't keep it around. */ a = state->args + position - 1; switch (conversion) { case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': switch (lengthMod) { // all of these take an int argument, they just print differently case '\0': case 'h': case 'H': ASSERT_ON_COMPILE(sizeof (int) == sizeof (int32)); argType = MSGFMT_ARG_INT32; break; case 'l': ASSERT_ON_COMPILE(sizeof (long) == sizeof (int32) || sizeof (long) == sizeof (int64)); if (sizeof (long) == sizeof (int32)) { argType = MSGFMT_ARG_INT32; } else { argType = MSGFMT_ARG_INT64; } break; case 'j': #ifndef _WIN32 // no intmax_t, bsd_vsnprintf() uses 64 bits ASSERT_ON_COMPILE(sizeof (intmax_t) == sizeof (int64)); #endif case 'L': ASSERT_ON_COMPILE(sizeof (long long) == sizeof (int64)); argType = MSGFMT_ARG_INT64; break; case 't': ASSERT_ON_COMPILE(sizeof (ptrdiff_t) == sizeof (size_t)); case 'z': ASSERT_ON_COMPILE(sizeof (size_t) == sizeof (int32) || sizeof (size_t) == sizeof (int64)); if (sizeof (size_t) == sizeof (int32)) { argType = MSGFMT_ARG_INT32; } else { argType = MSGFMT_ARG_INT64; } break; default: NOT_REACHED(); } break; case 'e': case 'E': case 'f': case 'F': case 'g': case 'G': case 'a': case 'A': #ifndef NO_FLOATING_POINT switch (lengthMod) { // l h hh t z are not defined by man page, but allowed by glibc case '\0': case 'l': case 'h': case 'H': case 't': case 'z': ASSERT_ON_COMPILE(sizeof (double) == 8); argType = MSGFMT_ARG_FLOAT64; break; // j is not defined by man page, but allowed by glibc case 'L': case 'j': /* * We don't do %Lf because it's not that useful to us, and * long double has a number of implementations. For example, * on Win32 it's the same as double, and it would have a hard * time dealing with a bigger one passed to it. * We can just coerce it down to a double at the source, * but then why bother? */ MsgFmtError(state, "MsgFmtGetArg1: %%%c%c not supported, " "pos \"%.*s\", type \"%.*s\"", lengthMod, conversion, posSize, pos, typeSize, type); return -2; default: NOT_REACHED(); } break; #else MsgFmtError(state, "MsgFmtGetArg1: %%%c%c not supported, " "pos \"%.*s\", type \"%.*s\"", lengthMod, conversion, posSize, pos, typeSize, type); return -2; #endif /*! NO_FLOATING_POINT */ case 'c': switch (lengthMod) { // h hh t z not defined by man page, but allowed by glibc case '\0': case 'h': case 'H': case 't': case 'z': ASSERT_ON_COMPILE(sizeof (int) == sizeof (int32)); argType = MSGFMT_ARG_INT32; break; // j ll L not defined by man page nor actually supported case 'l': case 'j': case 'L': goto caseC; default: NOT_REACHED(); } break; case 'C': caseC: // man page says it's a wint_t argument, but we assume promotion to int ASSERT_ON_COMPILE(sizeof (wint_t) <= sizeof (int) && sizeof (int) == sizeof (int32)); argType = MSGFMT_ARG_INT32; break; case 's': // we interpret the length modifier like we do for %c switch (lengthMod) { case '\0': case 'h': case 'H': case 't': case 'z': ASSERT_ON_COMPILE(sizeof (char) == sizeof (int8)); argType = MSGFMT_ARG_STRING8; break; case 'l': case 'j': case 'L': goto caseS; default: NOT_REACHED(); } // keep track of maximum string length, see block comment above a->p.precision = precision; ASSERT(a->v.ptr == NULL); break; case 'S': caseS: #if defined __ANDROID__ ASSERT_ON_COMPILE(sizeof (wchar_t) == sizeof (int16) || sizeof (wchar_t) == sizeof (int32) || sizeof (wchar_t) == sizeof (int8)); #else ASSERT_ON_COMPILE(sizeof (wchar_t) == sizeof (int16) || sizeof (wchar_t) == sizeof (int32)); #endif if (sizeof (wchar_t) == sizeof (int16)) { argType = MSGFMT_ARG_STRING16; #if defined __ANDROID__ } else if (sizeof (wchar_t) == sizeof (int8)) { argType = MSGFMT_ARG_STRING8; #endif } else { argType = MSGFMT_ARG_STRING32; } // keep track of maximum string length, see block comment above a->p.precision = precision; ASSERT(a->v.ptr == NULL); break; case 'p': ASSERT_ON_COMPILE(sizeof (void *) == sizeof (int32) || sizeof (void *) == sizeof (int64)); if (sizeof (void *) == sizeof (int32)) { argType = MSGFMT_ARG_PTR32; } else { argType = MSGFMT_ARG_PTR64; } break; case 'n': MsgFmtError(state, "MsgFmtGetArg1: %%n not supported, " "pos \"%.*s\", type \"%.*s\"", posSize, pos, typeSize, type); return -2; // MsgFmt_ParseSpec() doesn't do %m, and we don't see %% default: MsgFmtError(state, "MsgFmtGetArg1: %%%c not understood, " "pos \"%.*s\", type \"%.*s\"", conversion, posSize, pos, typeSize, type); NOT_REACHED(); } ASSERT(argType != MSGFMT_ARG_INVALID); if (a->type != MSGFMT_ARG_INVALID && a->type != argType) { MsgFmtError(state, "MsgFmtGetArg1: incompatible specifiers for argument %d, " "old type %d, new type %d, pos \"%.*s\", type \"%.*s\"", position, a->type, argType, posSize, pos, typeSize, type); return -2; } a->type = argType; return 0; } /* *----------------------------------------------------------------------------- * * MsgFmtError -- * * Format an error string and squirrel it away. * * Results: * Error string returned in state variable. * * Side effects: * Memory may be allocated. * *----------------------------------------------------------------------------- */ static void MsgFmtError(MsgFmtParseState *state, // IN/OUT: state structure const char *fmt, // IN: error format ...) // IN: error args { va_list args; ASSERT(state->error == NULL); // free up space (in call-supplied buffer) for error string MsgFmtFreeAll(state); va_start(args, fmt); state->error = MsgFmtVasprintf(state, fmt, args); va_end(args); } /* *----------------------------------------------------------------------------- * * MsgFmt_FreeArgs -- * * Free an array of MsgFmt_Arg structures. * Do not call this on an array in a caller-supplied * buffer from MsgFmt_GetArgsWithBuf(). * * Results: * None. * * Side effects: * Memory is freed. * *----------------------------------------------------------------------------- */ void MsgFmt_FreeArgs(MsgFmt_Arg *args, // IN/OUT: arguments to free int numArgs) // IN: number of arguments { int i; for (i = 0; i < numArgs; i++) { switch (args[i].type) { case MSGFMT_ARG_STRING8: case MSGFMT_ARG_STRING16: case MSGFMT_ARG_STRING32: case MSGFMT_ARG_ERRNO: free(args[i].v.ptr); break; default: ; } } free(args); } /* *----------------------------------------------------------------------------- * * MsgFmtAllocInit -- * * Initialize allocator for caller-supplied buffer. * * Results: * None. * * Side effects: * As described. * *----------------------------------------------------------------------------- */ static void MsgFmtAllocInit(MsgFmtParseState *state, // IN/OUT: state structure void *buf, // IN: buffer size_t size) // IN: size to allocate { state->bufp = state->buf = buf; state->bufe = state->bufp + size; } /* *----------------------------------------------------------------------------- * * MsgFmtAlloc -- * * Allocate memory from malloc() or from supplied buffer. * * Results: * Pointer or NULL on failure. * * Side effects: * Memory allocated or state updated. * *----------------------------------------------------------------------------- */ static void * MsgFmtAlloc(MsgFmtParseState *state, // IN/OUT: state structure size_t size) // IN: size to allocate { void *p; if (state->buf == NULL) { p = malloc(size); } else { if (state->bufe - state->bufp < size) { return NULL; } p = state->bufp; state->bufp += size; } return p; } /* *----------------------------------------------------------------------------- * * MsgFmtAllocArgs -- * * Grow MsgFmt_Arg array to accomodate new entry. * * Results: * TRUE on success. * State updated. * * Side effects: * Memory may be allocated. * *----------------------------------------------------------------------------- */ static Bool MsgFmtAllocArgs(MsgFmtParseState *state, // IN/OUT: state structure int n) // IN: 1-based argument number { if (n <= state->maxArgs) { return TRUE; } /* * If using malloc, then reallocate() the array with some slack. * If using our own buffer, just grow it exactly. */ if (state->buf == NULL) { void *p; n = MAX(4, n + state->maxArgs); p = realloc(state->args, n * sizeof *state->args); if (p == NULL) { return FALSE; } state->args = p; } else { if (state->args == NULL) { // first time state->args = (void *) state->bufp; } else { // growing: there must be nothing after the args array ASSERT((void *) state->bufp == state->args + state->maxArgs); } if ((char *) (state->args + n) > state->bufe) { return FALSE; } state->bufp = (char *) (state->args + n); } memset(state->args + state->maxArgs, 0, sizeof *state->args * (n - state->maxArgs)); state->maxArgs = n; return TRUE; } /* *----------------------------------------------------------------------------- * * MsgFmtVasprintf -- * * Format a string in allocated space. * * Results: * String. * * Side effects: * Memory allocated or state updated. * Panic if can't allocate. * *----------------------------------------------------------------------------- */ static char * MsgFmtVasprintf(MsgFmtParseState *state, // IN/OUT: state structure const char *fmt, // IN: error format va_list args) // IN: error args { char *p; ASSERT(state->error == NULL); if (state->buf == NULL) { p = Str_Vasprintf(NULL, fmt, args); ASSERT_MEM_ALLOC(p != NULL); } else { int n; p = state->bufp; // Str_Vsnprintf() may truncate n = Str_Vsnprintf(p, (char *)state->bufe - p, fmt, args); state->bufp = (n < 0) ? state->bufe : state->bufp + n + 1; } return p; } /* *----------------------------------------------------------------------------- * * MsgFmtFreeAll -- * * Free all memory associated with current MsgFmt_Arg array. * * Results: * State updated. * * Side effects: * Memory may be freed. * *----------------------------------------------------------------------------- */ static void MsgFmtFreeAll(MsgFmtParseState *state) // IN/OUT: state structure { if (state->args == NULL) return; if (state->buf == NULL) { MsgFmt_FreeArgs(state->args, state->numArgs); } else { state->bufp = state->buf; } state->numArgs = state->maxArgs = 0; state->args = NULL; } /* *----------------------------------------------------------------------------- * * MsgFmtBufUsed -- * * Return the amount of space used in the caller supplied buffer. * * Results: * size_t * * Side effects: * None. * *----------------------------------------------------------------------------- */ static size_t MsgFmtBufUsed(MsgFmtParseState *state) // IN: state structure { if (state->buf == NULL) { return 0; } else { return state->bufp - (char *)state->buf; } } /* *----------------------------------------------------------------------------- * * MsgFmt_SwizzleArgs -- * * Pointer swizzling. Flattens pointers in the MsgFmt_Arg array by * converting them to offsets relative to the start of the args array. * This should only be invoked if the MsgFmt_Arg array was allocated * from a caller-supplied buffer from MsgFmt_GetArgsWithBuf. * * Results: * None. * * Side effects: * For all i such that args[i] is a string parameter, * args[i].v.offset is set to the offset from args to the start * of the string, or to 0 if the string was NULL. * *----------------------------------------------------------------------------- */ void MsgFmt_SwizzleArgs(MsgFmt_Arg *args, int numArgs) { int i; int8* bufStart = (int8*)args; for (i = 0; i < numArgs; i++) { switch (args[i].type) { case MSGFMT_ARG_STRING8: case MSGFMT_ARG_STRING16: case MSGFMT_ARG_STRING32: if (args[i].v.ptr == NULL) { // offset is never 0 otherwise args[i].v.offset = 0; } else { args[i].v.offset = (int8*)args[i].v.ptr - bufStart; } break; default: break; } } } /* *----------------------------------------------------------------------------- * * MsgFmt_GetSwizzledString -- * * Helper for pointer un-swizzling. Obtains the pointer encoded * by a swizzled argument, if it is a string and the pointer is * within the proper bounds. * * Results: * NULL and a non-zero return value if the given argument is not * a string, or the pointer is out of bounds (below the end of * the args array or above the end of the buffer), or the string * is not null-terminated within the buffer. * * Exception to the above: an offset of 0 is used to encode the * NULL pointer. In this case, yields NULL and returns zero. * * Otherwise, yields a pointer to the string and returns zero. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int MsgFmt_GetSwizzledString(const MsgFmt_Arg *args, // IN: argument array int numArgs, // IN: size of the array int i, // IN: index into the array const void *bufEnd, // IN: string space bound const int8 **str) // OUT: the string { const int8 *bufStart = (const int8*)args; const int8 *strStart = (const int8*)(args + numArgs); const int8 *strEnd = bufEnd; switch(args[i].type) { case MSGFMT_ARG_STRING8: case MSGFMT_ARG_STRING16: case MSGFMT_ARG_STRING32: if (args[i].v.offset == 0) { // offset is never 0 otherwise *str = NULL; return 0; } else { const int8 *ptr = args[i].v.offset + bufStart; if (ptr < strStart || ptr >= strEnd || memchr(ptr, '\0', strEnd - ptr) == NULL) { *str = NULL; return -1; } else { *str = ptr; return 0; } } break; default: *str = NULL; return -1; } NOT_REACHED(); } /* *----------------------------------------------------------------------------- * * MsgFmt_UnswizzleArgs -- * * Pointer un-swizzling. Re-instates the pointers in the arg array. * This should only be invoked if the MsgFmt_Arg array was previously * swizzled using MsgFmt_SwizzleArgs. * * If a reconstituted pointer would be out of range -- i.e., * before the end of the args array or after the provided * end-of-buffer pointer -- it is replaced with NULL and an error * is returned. This is also done if the resulting string is not * null-terminated within the provided bound. * * Results: * 0 on success; -1 in case of bad pointer. * * Side effects: * For all i such that args[i] is a string parameter, sets * args[i].v.ptr to the string previously encoded as an offset, * or to NULL if the offset was 0, or to NULL in case of error. * *----------------------------------------------------------------------------- */ int MsgFmt_UnswizzleArgs(MsgFmt_Arg *args, // IN/OUT: the arguments (+ strings) int numArgs, // IN: number of arguments void *bufEnd) // IN: string space bound { int i; int failures = 0; for (i = 0; i < numArgs; i++) { switch (args[i].type) { case MSGFMT_ARG_STRING8: case MSGFMT_ARG_STRING16: case MSGFMT_ARG_STRING32: if (MsgFmt_GetSwizzledString(args, numArgs, i, bufEnd, (const int8**)&args[i].v.ptr) != 0) { ++failures; } break; default: break; } } return failures > 0 ? -1 : 0; } /* *----------------------------------------------------------------------------- * * MsgFmt_CopyArgs -- * * Copy all args from the given 'copyArgs' array. * * Results: * Pointer to copied args array. * * Side effects: * Allocates memory for new args array. * *----------------------------------------------------------------------------- */ MsgFmt_Arg* MsgFmt_CopyArgs(MsgFmt_Arg* copyArgs, // IN: Args to be copied int numArgs) // IN: number of args { MsgFmt_Arg *args; int i; args = malloc(numArgs * sizeof(MsgFmt_Arg)); if (args == NULL) { return NULL; } memcpy(args, copyArgs, numArgs * sizeof(MsgFmt_Arg)); for (i = 0; i < numArgs; i++) { switch (args[i].type) { case MSGFMT_ARG_STRING8: case MSGFMT_ARG_ERRNO: if (args[i].v.string8 != NULL) { args[i].v.string8char = strdup(copyArgs[i].v.string8char); if (args[i].v.string8 == NULL) { MsgFmt_FreeArgs(args, i); return NULL; } } break; case MSGFMT_ARG_STRING16: case MSGFMT_ARG_STRING32: /* * We don't care about these types. */ NOT_IMPLEMENTED(); break; default: break; } } return args; } #ifdef HAS_BSD_PRINTF // { /* *----------------------------------------------------------------------------- * * MsgFmt_Snprintf -- * * MsgFmt_Arg version of Str_Vsnprintf(). * * Results: * Number of character written, not including null termination, * or number of characters would have been written on overflow. * (This is exactly the same as vsnprintf(), but different * from Str_Vsnprintf().) * String is always null terminated, even on overflow. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int MsgFmt_Snprintf(char *buf, // OUT: formatted string size_t size, // IN: size of buffer const char *format, // IN: format const MsgFmt_Arg *args, // IN: message arguments int numArgs) // IN: number of arguments { return MsgFmtSnprintfWork(&buf, size, format, args, numArgs); } /* *----------------------------------------------------------------------------- * * MsgFmt_Asprintf -- * * MsgFmt_Arg version of Str_Vasprintf(). * * Results: * Allocated string on success. * NULL on failure. * Length of returned string (not including null termination) * in *length (if length != NULL). * * Side effects: * None. * *----------------------------------------------------------------------------- */ char * MsgFmt_Asprintf(size_t *length, // OUT: length of returned string const char *format, // IN: format const MsgFmt_Arg *args, // IN: message arguments int numArgs) // IN: number of arguments { char *p = NULL; int n = MsgFmtSnprintfWork(&p, 0, format, args, numArgs); if (n < 0) { return NULL; } if (length != NULL) { *length = n; } return p; } static int MsgFmtSnprintfWork(char **outbuf, size_t bufSize, const char *fmt0, const MsgFmt_Arg *args, int numArgs) { char *fmt; /* format string */ int ch; /* character from fmt */ int n; /* handy integer (short term usage) */ char *cp; /* handy char pointer (short term usage) */ BSDFmt_IOV *iovp; /* for PRINT macro */ int flags; /* flags as above */ int ret; /* return value accumulator */ int width; /* width from format (%8d), or 0 */ int prec; /* precision from format; <0 for N/A */ char sign; /* sign prefix (' ', '+', '-', or \0) */ char thousands_sep; /* locale specific thousands separator */ const char *grouping; /* locale specific numeric grouping rules */ #ifndef NO_FLOATING_POINT /* * We can decompose the printed representation of floating * point numbers into several parts, some of which may be empty: * * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ * A B ---C--- D E F * * A: 'sign' holds this value if present; '\0' otherwise * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal * C: cp points to the string MMMNNN. Leading and trailing * zeros are not in the string and must be added. * D: expchar holds this character; '\0' if no exponent, e.g. %f * F: at least two digits for decimal, at least one digit for hex */ char *decimal_point; /* locale specific decimal point */ #if defined __ANDROID__ static char dp = '.'; #endif int signflag; /* true if float is negative */ union { /* floating point arguments %[aAeEfFgG] */ double dbl; long double ldbl; } fparg; int expt; /* integer value of exponent */ char expchar; /* exponent character: [eEpP\0] */ char *dtoaend; /* pointer to end of converted digits */ int expsize; /* character count for expstr */ int lead; /* sig figs before decimal or group sep */ int ndig; /* actual number of digits returned by dtoa */ char expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */ char *dtoaresult; /* buffer allocated by dtoa */ int nseps; /* number of group separators with ' */ int nrepeats; /* number of repeats of the last group */ #endif uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ int base; /* base for [diouxX] conversion */ int dprec; /* a copy of prec if [diouxX], 0 otherwise */ int realsz; /* field size expanded by dprec, sign, etc */ int size; /* size of converted field or string */ int prsize; /* max size of printed field */ const char *xdigs; /* digits for %[xX] conversion */ BSDFmt_UIO uio; /* output information: summary */ BSDFmt_IOV iov[BSDFMT_NIOV]; /* ... and individual io vectors */ char buf[INT_CONV_BUF];/* buffer with space for digits of uintmax_t */ char ox[2]; /* space for 0x; ox[1] is either x, X, or \0 */ int nextarg; /* 1-based argument index */ const MsgFmt_Arg *a; char *convbuf; /* wide to multibyte conversion result */ BSDFmt_StrBuf sbuf; /* * BEWARE, these `goto error' on error, and PAD uses `n'. */ #define PRINT(ptr, len) { \ iovp->iov_base = (ptr); \ iovp->iov_len = (len); \ uio.uio_resid += (len); \ iovp++; \ if (++uio.uio_iovcnt >= BSDFMT_NIOV) { \ if (BSDFmt_SPrint(&sbuf, &uio)) \ goto error; \ iovp = iov; \ } \ } #define PAD(howmany, with) { \ if ((n = (howmany)) > 0) { \ while (n > PADSIZE) { \ PRINT(with, PADSIZE); \ n -= PADSIZE; \ } \ PRINT(with, n); \ } \ } #define PRINTANDPAD(p, ep, len, with) do { \ int n2 = (ep) - (p); \ if (n2 > (len)) \ n2 = (len); \ if (n2 > 0) \ PRINT((p), n2); \ PAD((len) - (n2 > 0 ? n2 : 0), (with)); \ } while(0) #define FLUSH() { \ if (uio.uio_resid && BSDFmt_SPrint(&sbuf, &uio)) \ goto error; \ uio.uio_iovcnt = 0; \ iovp = iov; \ } #define FETCHARG(a, i) do { \ int ii = (i) - 1; \ if (ii >= numArgs) { \ sbuf.error = TRUE; \ goto error; \ } \ (a) = args + ii; \ } while (FALSE) /* * Get * arguments, including the form *nn$. */ #define GETASTER(val) do { \ int n2 = 0; \ char *cp = fmt; \ const MsgFmt_Arg *a; \ while (is_digit(*cp)) { \ n2 = 10 * n2 + to_digit(*cp); \ cp++; \ } \ if (*cp == '$') { \ FETCHARG(a, n2); \ fmt = cp + 1; \ } else { \ FETCHARG(a, nextarg++); \ } \ if (a->type != MSGFMT_ARG_INT32) { \ sbuf.error = TRUE; \ goto error; \ } \ val = a->v.signed32; \ } while (FALSE) xdigs = xdigs_lower; thousands_sep = '\0'; grouping = NULL; convbuf = NULL; #ifndef NO_FLOATING_POINT dtoaresult = NULL; #if defined __ANDROID__ /* * Struct lconv is not working! For decimal_point, * using '.' instead is a workaround. */ NOT_TESTED(); decimal_point = &dp; #else decimal_point = localeconv()->decimal_point; #endif #endif fmt = (char *)fmt0; nextarg = 1; uio.uio_iov = iovp = iov; uio.uio_resid = 0; uio.uio_iovcnt = 0; ret = 0; /* * Set up output string buffer structure. */ sbuf.alloc = *outbuf == NULL; sbuf.error = FALSE; sbuf.buf = *outbuf; sbuf.size = bufSize; sbuf.index = 0; /* * If asprintf(), allocate initial buffer based on format length. * Empty format only needs one byte. * Otherwise, round up to multiple of 64. */ if (sbuf.alloc) { size_t n = strlen(fmt0) + 1; // +1 for \0 if (n > 1) { n = ROUNDUP(n, 64); } if ((sbuf.buf = malloc(n * sizeof (char))) == NULL) { sbuf.error = TRUE; goto error; } sbuf.size = n; } // shut compile up #ifndef NO_FLOATING_POINT expt = 0; expchar = 0; dtoaend = NULL; expsize = 0; lead = 0; ndig = 0; nseps = 0; nrepeats = 0; #endif ujval = 0; /* * Scan the format for conversions (`%' character). */ for (;;) { for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) /* void */; if ((n = fmt - cp) != 0) { if ((unsigned)ret + n > INT_MAX) { ret = EOF; goto error; } PRINT(cp, n); ret += n; } if (ch == '\0') goto done; fmt++; /* skip over '%' */ flags = 0; dprec = 0; width = 0; prec = -1; sign = '\0'; ox[1] = '\0'; rflag: ch = *fmt++; reswitch: switch (ch) { case ' ': /*- * ``If the space and + flags both appear, the space * flag will be ignored.'' * -- ANSI X3J11 */ if (!sign) sign = ' '; goto rflag; case '#': flags |= ALT; goto rflag; case '*': /*- * ``A negative field width argument is taken as a * - flag followed by a positive field width.'' * -- ANSI X3J11 * They don't exclude field widths read from args. */ GETASTER (width); if (width >= 0) goto rflag; width = -width; /* FALLTHROUGH */ case '-': flags |= LADJUST; goto rflag; case '+': sign = '+'; goto rflag; case '\'': flags |= GROUPING; #if defined __ANDROID__ /* * Struct lconv is not working! The code below is a workaround. */ NOT_TESTED(); thousands_sep = ','; #else thousands_sep = *(localeconv()->thousands_sep); grouping = localeconv()->grouping; #endif goto rflag; case '.': if ((ch = *fmt++) == '*') { GETASTER (prec); goto rflag; } prec = 0; while (is_digit(ch)) { prec = 10 * prec + to_digit(ch); ch = *fmt++; } goto reswitch; case '0': /*- * ``Note that 0 is taken as a flag, not as the * beginning of a field width.'' * -- ANSI X3J11 */ flags |= ZEROPAD; goto rflag; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': n = 0; do { n = 10 * n + to_digit(ch); ch = *fmt++; } while (is_digit(ch)); if (ch == '$') { nextarg = n; goto rflag; } width = n; goto reswitch; case 'h': if (flags & SHORTINT) { flags &= ~SHORTINT; flags |= CHARINT; } else flags |= SHORTINT; goto rflag; case 'j': flags |= INTMAXT; goto rflag; case 'I': /* could be I64 - long long int is 64bit */ if (fmt[0] == '6' && fmt[1] == '4') { fmt += 2; flags |= LLONGINT; goto rflag; } /* could be I32 - normal int is 32bit */ if (fmt[0] == '3' && fmt[1] == '2') { fmt += 2; /* flags |= normal integer - it is 32bit for all our targets */ goto rflag; } /* * I alone - use Microsoft's semantic as size_t modifier. We do * not support glibc's semantic to use alternative digits. */ flags |= SIZET; goto rflag; case 'l': if (flags & LONGINT) { flags &= ~LONGINT; flags |= LLONGINT; } else flags |= LONGINT; goto rflag; case 'L': case 'q': flags |= LLONGINT; /* not necessarily */ goto rflag; case 't': flags |= PTRDIFFT; goto rflag; case 'Z': case 'z': flags |= SIZET; goto rflag; case 'C': flags |= LONGINT; /*FALLTHROUGH*/ case 'c': FETCHARG(a, nextarg++); if (a->type != MSGFMT_ARG_INT32) { sbuf.error = TRUE; goto error; } if (flags & LONGINT) { static const mbstate_t initial; mbstate_t mbs; size_t mbseqlen; mbs = initial; // XXX must deal with mismatch between wchar_t size mbseqlen = wcrtomb(cp = buf, (wchar_t)a->v.signed32, &mbs); if (mbseqlen == (size_t)-1) { sbuf.error = TRUE; goto error; } size = (int)mbseqlen; } else { *(cp = buf) = a->v.signed32; size = 1; } sign = '\0'; break; case 'D': flags |= LONGINT; /*FALLTHROUGH*/ case 'd': case 'i': FETCHARG(a, nextarg++); if ((flags & (INTMAXT|LLONGINT)) != 0) { if (a->type == MSGFMT_ARG_INT64) { ujval = a->v.signed64; } else { sbuf.error = TRUE; goto error; } } else if ((flags & (SIZET|PTRDIFFT|LONGINT)) != 0) { if (a->type == MSGFMT_ARG_INT64) { ujval = a->v.signed64; } else if (a->type == MSGFMT_ARG_INT32) { ujval = (intmax_t) a->v.signed32; } else { sbuf.error = TRUE; goto error; } } else if ((flags & SHORTINT) != 0) { if (a->type == MSGFMT_ARG_INT32) { ujval = (intmax_t) (short) a->v.signed32; } else { sbuf.error = TRUE; goto error; } } else if ((flags & CHARINT) != 0) { if (a->type == MSGFMT_ARG_INT32) { ujval = (intmax_t) (signed char) a->v.signed32; } else { sbuf.error = TRUE; goto error; } } else { if (a->type == MSGFMT_ARG_INT32) { ujval = (intmax_t) a->v.signed32; } else { sbuf.error = TRUE; goto error; } } if ((intmax_t)ujval < 0) { ujval = -ujval; sign = '-'; } base = 10; goto number; #ifndef NO_FLOATING_POINT case 'e': case 'E': expchar = ch; if (prec < 0) /* account for digit before decpt */ prec = DEFPREC + 1; else prec++; goto fp_begin; case 'f': case 'F': expchar = '\0'; goto fp_begin; case 'g': case 'G': expchar = ch - ('g' - 'e'); if (prec == 0) prec = 1; fp_begin: if (flags & LLONGINT) { sbuf.error = TRUE; goto error; } if (prec < 0) prec = DEFPREC; if (dtoaresult != NULL) freedtoa(dtoaresult); FETCHARG(a, nextarg++); if (a->type != MSGFMT_ARG_FLOAT64) { sbuf.error = TRUE; goto error; } fparg.dbl = a->v.float64; #if defined NO_DTOA NOT_TESTED(); dtoaresult = NULL; sbuf.error = TRUE; goto error; #else dtoaresult = cp = dtoa(fparg.dbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend); #endif if (expt == 9999) expt = INT_MAX; if (signflag) sign = '-'; if (expt == INT_MAX) { /* inf or nan */ if (*cp == 'N') { cp = (ch >= 'a') ? "nan" : "NAN"; sign = '\0'; } else cp = (ch >= 'a') ? "inf" : "INF"; size = 3; break; } flags |= FPT; ndig = dtoaend - cp; if (ch == 'g' || ch == 'G') { if (expt > -4 && expt <= prec) { /* Make %[gG] smell like %[fF] */ expchar = '\0'; if (flags & ALT) prec -= expt; else prec = ndig - expt; if (prec < 0) prec = 0; } else { /* * Make %[gG] smell like %[eE], but * trim trailing zeroes if no # flag. */ if (!(flags & ALT)) prec = ndig; } } if (expchar) { expsize = BSDFmt_Exponent(expstr, expt - 1, expchar); size = expsize + prec; if (prec > 1 || flags & ALT) ++size; } else { /* space for digits before decimal point */ if (expt > 0) size = expt; else /* "0" */ size = 1; /* space for decimal pt and following digits */ if (prec || flags & ALT) size += prec + 1; if (grouping && expt > 0) { /* space for thousands' grouping */ nseps = nrepeats = 0; lead = expt; while (*grouping != CHAR_MAX) { if (lead <= *grouping) break; lead -= *grouping; if (*(grouping+1)) { nseps++; grouping++; } else nrepeats++; } size += nseps + nrepeats; } else lead = expt; } break; #endif /* !NO_FLOATING_POINT */ case 'n': sbuf.error = TRUE; goto error; case 'O': flags |= LONGINT; /*FALLTHROUGH*/ case 'o': base = 8; goto get_unsigned; case 'p': /*- * ``The argument shall be a pointer to void. The * value of the pointer is converted to a sequence * of printable characters, in an implementation- * defined manner.'' * -- ANSI X3J11 */ FETCHARG(a, nextarg++); if (a->type == MSGFMT_ARG_PTR32) { ujval = a->v.unsigned32; } else if (a->type == MSGFMT_ARG_PTR64) { ujval = a->v.unsigned64; } else { sbuf.error = TRUE; goto error; } base = 16; xdigs = xdigs_upper; flags = flags | INTMAXT; /* * PR 103201 * VisualC sscanf doesn't grok '0x', so prefix zeroes. */ // ox[1] = 'x'; goto nosign; case 'S': flags |= LONGINT; /*FALLTHROUGH*/ case 's': FETCHARG(a, nextarg++); if (flags & LONGINT) { wchar_t *wcp; #if defined __ANDROID__ ASSERT_ON_COMPILE(sizeof (wchar_t) == sizeof (int16) || sizeof (wchar_t) == sizeof (int32) || sizeof (wchar_t) == sizeof (int8)); if ((sizeof (wchar_t) == sizeof (int16) && a->type != MSGFMT_ARG_STRING16) || (sizeof (wchar_t) == sizeof (int32) && a->type != MSGFMT_ARG_STRING32) || (sizeof (wchar_t) == sizeof (int8) && a->type != MSGFMT_ARG_STRING8)) { #else ASSERT_ON_COMPILE(sizeof (wchar_t) == 2 || sizeof (wchar_t) == 4); if (sizeof (wchar_t) == 2 ? a->type != MSGFMT_ARG_STRING16 : a->type != MSGFMT_ARG_STRING32) { #endif sbuf.error = TRUE; goto error; } if ((wcp = (wchar_t *) a->v.ptr) == NULL) cp = "(null)"; else { if (convbuf != NULL) free(convbuf); convbuf = BSDFmt_WCharToUTF8(wcp, prec); if (convbuf == NULL) { sbuf.error = TRUE; goto error; } cp = convbuf; } } else { if (a->type != MSGFMT_ARG_STRING8 && a->type != MSGFMT_ARG_ERRNO) { sbuf.error = TRUE; goto error; } /* * Use localized string (in localString) if available. * Strip off Msg ID if unlocalized string has one. * Use (null) for null pointer. */ if (a->p.localString != NULL) { cp = a->p.localString; } else if (a->v.string8 != NULL) { cp = (char *) Msg_StripMSGID(a->v.string8char); } else { cp = "(null)"; } } if (prec >= 0) { /* * We can use strlen here because the string is always * terminated, unlike the string passed to MsgFmt_GetArgs. * However, it's somewhat faster to use memchr. */ char *p = memchr(cp, 0, prec); if (p != NULL) { size = p - cp; if (size > prec) size = prec; } else size = prec; } else size = strlen(cp); sign = '\0'; break; case 'U': flags |= LONGINT; /*FALLTHROUGH*/ case 'u': base = 10; goto get_unsigned; case 'X': xdigs = xdigs_upper; goto hex; case 'x': xdigs = xdigs_lower; hex: base = 16; if (flags & ALT) ox[1] = ch; flags &= ~GROUPING; get_unsigned: FETCHARG(a, nextarg++); if ((flags & (INTMAXT|LLONGINT)) != 0) { if (a->type == MSGFMT_ARG_INT64) { ujval = a->v.unsigned64; } else { sbuf.error = TRUE; goto error; } } else if ((flags & (SIZET|PTRDIFFT|LONGINT)) != 0) { if (a->type == MSGFMT_ARG_INT64) { ujval = a->v.unsigned64; } else if (a->type == MSGFMT_ARG_INT32) { ujval = (uintmax_t) a->v.unsigned32; } else { sbuf.error = TRUE; goto error; } } else if ((flags & SHORTINT) != 0) { if (a->type == MSGFMT_ARG_INT32) { ujval = (intmax_t) (unsigned short) a->v.unsigned32; } else { sbuf.error = TRUE; goto error; } } else if ((flags & CHARINT) != 0) { if (a->type == MSGFMT_ARG_INT32) { ujval = (intmax_t) (unsigned char) a->v.unsigned32; } else { sbuf.error = TRUE; goto error; } } else { if (a->type == MSGFMT_ARG_INT32) { ujval = (intmax_t) a->v.unsigned32; } else { sbuf.error = TRUE; goto error; } } if (ujval == 0) /* squash 0x/X if zero */ ox[1] = '\0'; /* unsigned conversions */ nosign: sign = '\0'; /*- * ``... diouXx conversions ... if a precision is * specified, the 0 flag will be ignored.'' * -- ANSI X3J11 */ number: if ((dprec = prec) >= 0) flags &= ~ZEROPAD; /*- * ``The result of converting a zero value with an * explicit precision of zero is no characters.'' * -- ANSI X3J11 * * ``The C Standard is clear enough as is. The call * printf("%#.0o", 0) should print 0.'' * -- Defect Report #151 */ cp = buf + INT_CONV_BUF; if (ujval != 0 || prec != 0 || (flags & ALT && base == 8)) cp = BSDFmt_UJToA(ujval, cp, base, flags & ALT, xdigs, flags & GROUPING, thousands_sep, grouping); size = buf + INT_CONV_BUF - cp; if (size > INT_CONV_BUF) /* should never happen */ abort(); break; default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') goto done; /* pretend it was %c with argument ch */ cp = buf; *cp = ch; size = 1; sign = '\0'; break; } /* * All reasonable formats wind up here. At this point, `cp' * points to a string which (if not flags&LADJUST) should be * padded out to `width' places. If flags&ZEROPAD, it should * first be prefixed by any sign or other prefix; otherwise, * it should be blank padded before the prefix is emitted. * After any left-hand padding and prefixing, emit zeroes * required by a decimal [diouxX] precision, then print the * string proper, then emit zeroes required by any leftover * floating precision; finally, if LADJUST, pad with blanks. * * Compute actual size, so we know how much to pad. * size excludes decimal prec; realsz includes it. */ realsz = dprec > size ? dprec : size; if (sign) realsz++; if (ox[1]) realsz += 2; prsize = width > realsz ? width : realsz; if ((unsigned)ret + prsize > INT_MAX) { ret = EOF; goto error; } /* right-adjusting blank padding */ if ((flags & (LADJUST|ZEROPAD)) == 0) PAD(width - realsz, blanks); /* prefix */ if (sign) PRINT(&sign, 1); if (ox[1]) { /* ox[1] is either x, X, or \0 */ ox[0] = '0'; PRINT(ox, 2); } /* right-adjusting zero padding */ if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) PAD(width - realsz, zeroes); /* leading zeroes from decimal precision */ PAD(dprec - size, zeroes); /* the string or number proper */ #ifndef NO_FLOATING_POINT if ((flags & FPT) == 0) { PRINT(cp, size); } else { /* glue together f_p fragments */ if (!expchar) { /* %[fF] or sufficiently short %[gG] */ if (expt <= 0) { PRINT(zeroes, 1); if (prec || flags & ALT) PRINT(decimal_point, 1); PAD(-expt, zeroes); /* already handled initial 0's */ prec += expt; } else { PRINTANDPAD(cp, dtoaend, lead, zeroes); cp += lead; if (grouping) { while (nseps>0 || nrepeats>0) { if (nrepeats > 0) nrepeats--; else { grouping--; nseps--; } PRINT(&thousands_sep, 1); PRINTANDPAD(cp,dtoaend, *grouping, zeroes); cp += *grouping; } if (cp > dtoaend) cp = dtoaend; } if (prec || flags & ALT) PRINT(decimal_point,1); } PRINTANDPAD(cp, dtoaend, prec, zeroes); } else { /* %[eE] or sufficiently long %[gG] */ if (prec > 1 || flags & ALT) { buf[0] = *cp++; buf[1] = *decimal_point; PRINT(buf, 2); PRINT(cp, ndig-1); PAD(prec - ndig, zeroes); } else /* XeYYY */ PRINT(cp, 1); PRINT(expstr, expsize); } } #else PRINT(cp, size); #endif /* left-adjusting padding (always blank) */ if (flags & LADJUST) PAD(width - realsz, blanks); /* finally, adjust ret */ ret += prsize; FLUSH(); /* copy out the I/O vectors */ } done: FLUSH(); /* * Always null terminate, unless buffer is size 0. */ ASSERT(!sbuf.error && ret >= 0); if (sbuf.size <= 0) { ASSERT(!sbuf.alloc); } else { ASSERT(sbuf.index < sbuf.size); sbuf.buf[sbuf.index] = '\0'; } error: #ifndef NO_FLOATING_POINT if (dtoaresult != NULL) freedtoa(dtoaresult); #endif if (convbuf != NULL) free(convbuf); if (sbuf.error) { ret = EOF; } // return allocated buffer on success, free it on failure if (sbuf.alloc) { if (ret < 0) { free(sbuf.buf); } else { *outbuf = sbuf.buf; } } return (ret); /* NOTREACHED */ #undef PRINT #undef PAD #undef PRINTANDPAD #undef FLUSH #undef FETCHARG #undef GETASTER } #endif // } open-vm-tools-9.4.0-1280544/lib/misc/iovector.c0000644765153500003110000006104112220061556017140 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * iovector.c -- * * I/O vector management code. */ #ifdef _WIN32 #include #endif #include "vmware.h" #include "util.h" #include "iovector.h" #define LGPFX "IOV: " /* * Structure used when duplicating iov. */ struct VMIOVecAndEntries { VMIOVec iov; /* has to be first */ struct iovec e[0]; }; /* *--------------------------------------------------------------------------- * * IOV_Log -- * * Logs the content of an iov to the log file. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ void IOV_Log(const VMIOVec *iov) // IN { if (iov) { uint32 i; Log("###### dumping content of iov ######\n"); Log("%s\n", iov->read ? "READ" : "WRITE"); Log("startSector = %"FMT64"d\n", iov->startSector); Log("numSectors = %"FMT64"d\n", iov->numSectors); Log("numBytes = %"FMT64"d\n", iov->numBytes); Log("numEntries = %d\n", iov->numEntries); for (i = 0; i < iov->numEntries; i++) { Log(" entries[%d] = %p / %"FMTSZ"u\n", i, iov->entries[i].iov_base, (size_t)iov->entries[i].iov_len); } } else { Log("###### iov is NULL!! ######\n"); } } /* *--------------------------------------------------------------------------- * * IOV_Zero -- * * Zeros the content of an iov. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ void IOV_Zero(VMIOVec *iov) // IN { uint64 numBytesLeft; int i; ASSERT(iov); ASSERT(iov->read); numBytesLeft = iov->numBytes; i = 0; while (numBytesLeft > 0) { size_t c = MIN(numBytesLeft, iov->entries[i].iov_len); void *buf; ASSERT_NOT_IMPLEMENTED(i < iov->numEntries); buf = iov->entries[i].iov_base; ASSERT(buf && buf != LAZY_ALLOC_MAGIC); memset(buf, 0, c); numBytesLeft -= c; i++; } } /* *--------------------------------------------------------------------------- * * IOV_Allocate -- * * Allocates a brand new iov to be freed with IOV_Free. * * Results: * A VMIOVec*. * * Side effects: * None. * *--------------------------------------------------------------------------- */ VMIOVec* IOV_Allocate(int numEntries) // IN { struct VMIOVecAndEntries *iov; iov = Util_SafeMalloc(sizeof *iov + numEntries * sizeof(struct iovec)); iov->iov.entries = iov->e; iov->iov.allocEntries = NULL; iov->iov.numEntries = numEntries; return &iov->iov; } /* *--------------------------------------------------------------------------- * * IOV_DuplicateStatic -- * * Duplicate an iov, potentially using a static'ly allocated array of * struct iovec. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ void IOV_DuplicateStatic(VMIOVec *iovIn, // IN int numStaticEntries, // IN struct iovec *staticEntries, // IN VMIOVec *iovOut) // OUT { ASSERT(staticEntries); ASSERT(iovIn); ASSERT(iovOut); Util_Memcpy(iovOut, iovIn, sizeof *iovOut); if (iovIn->numEntries <= numStaticEntries) { iovOut->allocEntries = NULL; iovOut->entries = staticEntries; } else { iovOut->allocEntries = Util_SafeMalloc(iovIn->numEntries * sizeof(struct iovec)); iovOut->entries = iovOut->allocEntries; } Util_Memcpy(iovOut->entries, iovIn->entries, iovIn->numEntries * sizeof(struct iovec)); } /* *--------------------------------------------------------------------------- * * IOV_MakeSingleIOV -- * * Fills in an iov. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ void IOV_MakeSingleIOV(VMIOVec* v, // IN/OUT struct iovec* entry, // IN SectorType startSector, // IN SectorType dataLen, // IN uint32 sectorSize, // IN uint8* buffer, // IN Bool read) // IN { ASSERT(v); ASSERT(entry); v->read = read; v->startSector = startSector; v->numSectors = dataLen; v->numBytes = dataLen * sectorSize; v->numEntries = 1; v->entries = entry; v->allocEntries = entry; entry->iov_base = (char *)buffer; entry->iov_len = (size_t) v->numBytes; } /* *----------------------------------------------------------------------------- * * IOV_IsZero -- * * Tell if an iov is full of zeros. Used when we are about to write an iov * in a grain, if it's zero and the grain does not exist, we just do * nothing. * * Result: * TRUE/FALSE * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool IOV_IsZero(VMIOVec* iov) // IN: the iov to scan { uint32 i; for (i = 0; i < iov->numEntries; i++) { if (!Util_BufferIsEmpty(iov->entries[i].iov_base, iov->entries[i].iov_len)) { return FALSE; } } return TRUE; } /* *---------------------------------------------------------------------------- * * IOVSplitList -- * * Utility function to split an iovec (byte granularity scatter-gather * array) into two-- an initial one that's exactly a whole number of * sectors long, and the remainder. If the table entry that finishes * off the requested region is actually larger than the amount of space * left in the region, it is truncated and the remaining bytes and * their location are returned in overlap. The size of the region is * passed in via regionV->numSectors, and the rest of regionV is * filled in with to describe a request for exactly that region. * * Results: * Pointer to the first remaining entry from the original entries list. * * Side effects: * overlap filled in if the original entries list doesn't have a clean * break on the region boundary, otherwise overlap->iov_len == 0. * Also in cases over overlap, the last entry of entries is truncated. * *---------------------------------------------------------------------------- */ static struct iovec * IOVSplitList(VMIOVec *regionV, // IN/OUT: VMIOVec for this region struct iovec *entries, // IN/OUT: iovec to be split struct iovec *endPtr, // IN: pointer to after last entry struct iovec *overlap, // OUT: overlap info if last truncated uint32 sectorSize) // IN: # bytes in a sector { struct iovec *curEntry; curEntry = entries; regionV->entries = curEntry; regionV->numEntries = 0; regionV->numBytes = 0; ASSERT(curEntry < endPtr); /* Better be at least one entry */ do { regionV->numEntries++; regionV->numBytes += curEntry->iov_len; if (regionV->numBytes > regionV->numSectors * sectorSize) { int spillover; spillover = (int) (regionV->numBytes - regionV->numSectors * sectorSize); ASSERT(spillover < curEntry->iov_len); ASSERT(spillover > 0); /* * Truncate the last overlapping entry and store the excess. After * we finish this region, we'll smash this last entry with its * remainder and just move on to the next region. */ regionV->numBytes -= spillover; curEntry->iov_len -= spillover; overlap->iov_len = spillover; overlap->iov_base = (char *)curEntry->iov_base + curEntry->iov_len; break; } else if (regionV->numBytes == regionV->numSectors * sectorSize) { /* * Clean finish. The last entry for this region will be handled * with no overlap, so increment past it for the start of the next * region's entries. */ overlap->iov_len = 0; curEntry++; break; } curEntry++; } while (curEntry < endPtr); ASSERT(regionV->numBytes == regionV->numSectors * sectorSize); return curEntry; } /* *---------------------------------------------------------------------------- * * IOV_Split -- * * Utility function useful for iterating over VMIOVec. You setup * numSectors and then pass in the vector for the whole remaining * transfer. The code creates a VMIOVec to describe the subset of the * transfer contained in the region and adjusts origV so that it describes * the remainder. * * Results: * a VMIOVec* describing the first numSectors sectors of origV. * * Side effects: * See above-- origV is split into regionV and the remainder with * overlap filled in if the last entry of the region straddled the * boundary. Otherwise overlap->iov_len is set to zero. * *---------------------------------------------------------------------------- */ VMIOVec* IOV_Split(VMIOVec *origV, // IN/OUT: VMIOVec for whole xfer SectorType numSectors, // IN uint32 sectorSize) // IN: # bytes in a sector { struct VMIOVecAndEntries *v; int cpySize; VMIOVec* iov; ASSERT(origV); ASSERT(numSectors > 0); ASSERT(numSectors <= origV->numSectors); /* * The resulting iov cannot have more entries than the incoming one. */ v = Util_SafeMalloc(sizeof *v + origV->numEntries * sizeof(struct iovec)); iov = &v->iov; Util_Memcpy(iov, origV, sizeof *iov); iov->allocEntries = NULL; iov->numSectors = numSectors; /* * Handle lazy allocation of backing store. */ if (origV->entries->iov_base == LAZY_ALLOC_MAGIC && origV->entries->iov_len == 0) { ASSERT(origV->numEntries == 1); iov->entries = v->e; Util_Memcpy(iov->entries, origV->entries, sizeof(struct iovec)); iov->numBytes = iov->numSectors * sectorSize; origV->startSector += numSectors; origV->numSectors -= numSectors; origV->numBytes -= iov->numBytes; return iov; } /* See if the region is the whole thing */ if (origV->numSectors == numSectors) { cpySize = origV->numEntries * sizeof *origV->entries; iov->entries = v->e; Util_Memcpy(iov->entries, origV->entries, cpySize); origV->startSector += numSectors; origV->numSectors = 0; origV->numEntries = 0; origV->numBytes = 0; } else { void* tmpPtr; struct iovec overlap = { 0, }; origV->startSector += numSectors; origV->numSectors -= numSectors; origV->entries = IOVSplitList(iov, origV->entries, origV->entries + origV->numEntries, &overlap, sectorSize); cpySize = iov->numEntries * sizeof *iov->entries; tmpPtr = iov->entries; iov->entries = v->e; Util_Memcpy(iov->entries, tmpPtr, cpySize); origV->numEntries -= iov->numEntries; if (overlap.iov_len != 0) { origV->entries->iov_len = overlap.iov_len; origV->entries->iov_base = overlap.iov_base; origV->numEntries++; } origV->numBytes -= iov->numBytes; } ASSERT(iov->numEntries > 0); return iov; } /* *--------------------------------------------------------------------------- * * IOV_WriteIovToBuf -- * * This function takes an iov and a buffer as input and writes the content * of the buffers pointed to by the iov into buf. * * Result: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ void IOV_WriteIovToBuf(struct iovec* entries, // IN int numEntries, // IN uint8* bufOut, // OUT size_t bufSize) // IN { size_t count = 0; int i; ASSERT(entries); ASSERT(bufOut); for (i = 0; i < numEntries; i++) { size_t numBytes; ASSERT(entries[i].iov_base); ASSERT(entries[i].iov_base != LAZY_ALLOC_MAGIC); numBytes = MIN(bufSize - count, entries[i].iov_len); Util_Memcpy(&bufOut[count], entries[i].iov_base, numBytes); count += numBytes; if (count >= bufSize) { return; } ASSERT_NOT_IMPLEMENTED(count <= bufSize); } } /* *--------------------------------------------------------------------------- * * IOV_Duplicate -- * * Allocates a brand new iov, the resulting iov should be free'd using * IOV_Free. * * Result: * A duplicated iov. * * Side effects: * None. * *--------------------------------------------------------------------------- */ VMIOVec* IOV_Duplicate(VMIOVec* iovIn) // IN { struct VMIOVecAndEntries* v; v = Util_SafeMalloc(sizeof *v + iovIn->numEntries * sizeof(struct iovec)); Util_Memcpy(&v->iov, iovIn, sizeof *iovIn); v->iov.allocEntries = NULL; v->iov.entries = v->e; Util_Memcpy(v->iov.entries, iovIn->entries, iovIn->numEntries * sizeof(struct iovec)); return &v->iov; } /* *--------------------------------------------------------------------------- * * IOV_Free -- * * Frees an iov. * * Result: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ void IOV_Free(VMIOVec* iov) // IN { ASSERT(iov); if (iov->allocEntries) { free(iov->allocEntries); iov->allocEntries = NULL; } free(iov); } /* *--------------------------------------------------------------------------- * * IOV_WriteBufToIov -- * * This function copies the content of bufIn into the buffer pointed to by * entries. It basically does the opposite of IOV_WriteIovToBuf. * * Result: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ void IOV_WriteBufToIov(const uint8* bufIn, // IN size_t bufSize, // IN struct iovec* entries, // OUT int numEntries) // IN { size_t count = 0; int i; ASSERT(entries); ASSERT_BUG(29009, bufIn); for (i = 0; i < numEntries; i++) { size_t numBytes; ASSERT(entries[i].iov_base); ASSERT(entries[i].iov_base != LAZY_ALLOC_MAGIC); numBytes = MIN(bufSize - count, entries[i].iov_len); Util_Memcpy(entries[i].iov_base, &bufIn[count], numBytes); count += numBytes; if (count >= bufSize) { return; } ASSERT_NOT_IMPLEMENTED(count <= bufSize); } } /* *--------------------------------------------------------------------------- * * IOVFindFirstEntryOffset -- * * This function takes an iov and a byte offset and returns the * index of the first entry and offset in that entry where copy starts. * * Result: * If offset is within iov, returns the index of the first entry and * sets entryOffset. Otherwise, return numEntries. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int IOVFindFirstEntryOffset(struct iovec* entries, // IN int numEntries, // IN size_t iovOffset, // IN size_t *entryOffsetp) // OUT { size_t entryLen = 0, entryOffset = 0; int i; ASSERT(entries); ASSERT(entryOffsetp); /* find the entry where to start */ for (i = 0; (iovOffset >= entryOffset) && (i < numEntries); i++) { entryLen = entries[i].iov_len; entryOffset += entryLen; } if (iovOffset >= entryOffset) { /* iov offset is outside the iov - copy nothing */ Log(LGPFX"%s:%d i %d (of %d), offsets: entry %"FMTSZ"u, iov %"FMTSZ"u " "invalid iov offset\n", __FILE__, __LINE__, i, numEntries, entryOffset, iovOffset); return numEntries; } /* i is index in next entry. Set entryOffset to offset in current entry */ entryOffset = iovOffset - (entryOffset - entryLen); ASSERT(entryOffset < entryLen); *entryOffsetp = entryOffset; return i - 1; } /* *--------------------------------------------------------------------------- * * IOV_WriteIovToBufPlus -- * * This function takes an iov and a buffer as input and writes the content * of the buffers pointed to by the iov into buf. * It is similar to IOV_WriteIovToBuf but copy may start at any point * within the iov and may only partially overlap. * iovOffset is the offset in bytes within the iov where to start copying. * * Result: * Returns the number of bytes copied. * * Side effects: * None. * *--------------------------------------------------------------------------- */ size_t IOV_WriteIovToBufPlus(struct iovec* entries, // IN int numEntries, // IN uint8* bufOut, // OUT size_t bufSize, // IN size_t iovOffset) // IN { size_t entryLen, entryOffset; size_t count = bufSize; int i; ASSERT_BUG(29009, bufOut); i = IOVFindFirstEntryOffset(entries, numEntries, iovOffset, &entryOffset); for (; count && (i < numEntries); i++) { char *base = (char *)(entries[i].iov_base) + entryOffset; size_t iov_len = entries[i].iov_len; ASSERT(entries[i].iov_base || entries[i].iov_len == 0); ASSERT(entries[i].iov_base != LAZY_ALLOC_MAGIC); if (iov_len <= 0) { continue; } entryLen = MIN(count, iov_len - entryOffset); Util_Memcpy(bufOut, base, entryLen); count -= entryLen; bufOut += entryLen; entryOffset = 0; } ASSERT(count <= bufSize); return bufSize - count; } /* *--------------------------------------------------------------------------- * * IOV_WriteBufToIovPlus -- * * This function copies the content of bufIn into the buffer pointed to by * entries. It is similar to IOV_WriteBufToIov but the buffer may be * copied anywhere within the iov and may only partially overlap. * iovOffset is the offset in bytes within the iov where to start copying. * * Result: * Returns the number of bytes copied. * * Side effects: * None. * *--------------------------------------------------------------------------- */ size_t IOV_WriteBufToIovPlus(uint8* bufIn, // IN size_t bufSize, // IN struct iovec* entries, // OUT int numEntries, // IN size_t iovOffset) // IN { size_t entryLen, entryOffset; size_t count = bufSize; int i; ASSERT_BUG(29009, bufIn); i = IOVFindFirstEntryOffset(entries, numEntries, iovOffset, &entryOffset); for (; count && (i < numEntries); i++) { char *base = (char *)(entries[i].iov_base) + entryOffset; size_t iov_len = entries[i].iov_len; ASSERT_BUG(33859, entries[i].iov_base || entries[i].iov_len == 0); ASSERT(entries[i].iov_base != LAZY_ALLOC_MAGIC); if (iov_len <= 0) { continue; } entryLen = MIN(count, iov_len - entryOffset); Util_Memcpy(base, bufIn, entryLen); count -= entryLen; bufIn += entryLen; entryOffset = 0; } ASSERT(count <= bufSize); return bufSize - count; } /* *--------------------------------------------------------------------------- * * IOV_WriteIovToIov -- * * This function copies the overlapping portion from the source iov * to the target iov, that is the region defined by: * startSector = MAX(srcIov->startSector, dstIov->startSector) * numSectors = MIN(, ) - startSector. * * sectorSizeShift is conversion factor between sector and byte. * * NOTE: assume that iov->numBytes is the actual number of bytes to copy. * Do not copy beyond numBytes for either src or dst iov. * * Result: * Returns the number of bytes copied. * * Side effects: * None. * *--------------------------------------------------------------------------- */ size_t IOV_WriteIovToIov(VMIOVec *srcIov, // IN VMIOVec *dstIov, // OUT uint32 sectorSizeShift) // IN { size_t entryLen = 0, srcEntryOffset, copyLen, retval; uint64 srcStartByte, dstStartByte, startByte, endByte; int64 count, srcIovOffset, dstIovOffset; struct iovec *srcEntries = srcIov->entries; uint32 srcNumEntries = srcIov->numEntries; struct iovec *dstEntries = dstIov->entries; uint32 dstNumEntries = dstIov->numEntries; int i; ASSERT(srcIov); ASSERT(dstIov); /* find start byte address for src, dst and common region */ srcStartByte = srcIov->startSector << sectorSizeShift; dstStartByte = dstIov->startSector << sectorSizeShift; startByte = MAX(srcStartByte, dstStartByte); /* find num bytes and end byte address for common region */ endByte = srcStartByte + srcIov->numBytes; count = dstStartByte + dstIov->numBytes; endByte = MIN(endByte, count); count = endByte - startByte; /* count is number of bytes to copy, [startByte,endByte) is region to copy */ if (count <= 0) { /* no overlap */ Log(LGPFX"%s:%d iov [%"FMT64"u:%"FMT64"u] and [%"FMT64"u:%"FMT64"u] - " "no overlap!\n", __FILE__, __LINE__, srcIov->startSector, srcIov->numSectors, dstIov->startSector, dstIov->numSectors); return 0; } srcEntries = srcIov->entries; ASSERT(srcEntries); ASSERT(dstIov->entries); /* srcIovOffset is byte offset where to start copy in src iov */ srcIovOffset = startByte - srcStartByte; /* dstIovOffset is byte offset where to start copy in dst iov */ dstIovOffset = startByte - dstStartByte; ASSERT(srcIovOffset >= 0); ASSERT(dstIovOffset >= 0); retval = (size_t)count; /* first find the src entry where to start */ i = IOVFindFirstEntryOffset(srcEntries, srcNumEntries, (size_t) srcIovOffset, &srcEntryOffset); for (; count && (i < srcNumEntries); i++) { size_t iov_len = srcEntries[i].iov_len; ASSERT(srcEntries[i].iov_base || srcEntries[i].iov_len == 0); ASSERT(srcEntries[i].iov_base != LAZY_ALLOC_MAGIC); if (iov_len <= 0) { continue; } entryLen = MIN(count, iov_len - srcEntryOffset); copyLen = IOV_WriteBufToIovPlus( (uint8 *)(srcEntries[i].iov_base) + srcEntryOffset, entryLen, dstEntries, dstNumEntries, dstIovOffset); if (copyLen == 0) { /* finished */ break; } ASSERT(copyLen <= entryLen); count -= copyLen; dstIovOffset += copyLen; srcEntryOffset = 0; } ASSERT(count <= retval); return retval - count; } #ifdef VMX86_DEBUG /* *----------------------------------------------------------------------------- * * IOV_Assert -- * * Checks that the 'numEntries' iovecs in 'iov' are non-null and have * nonzero lengths. * * Meant to be called via IOV_ASSERT macro. * * Results: * None. * * Side effects: * Assert-fails if the iovec is invalid. * *----------------------------------------------------------------------------- */ void IOV_Assert (struct iovec *iov, // IN: iovec to check uint32 numEntries) // IN: # of entries in 'iov' { ASSERT(iov); ASSERT(numEntries); for (; numEntries-- > 0; iov++) { ASSERT(iov->iov_base); ASSERT(iov->iov_len); } } #endif open-vm-tools-9.4.0-1280544/lib/misc/hostType.c0000644765153500003110000001511512220061556017126 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * hostType.c -- * * Platform-independent code that calls into hostType-specific * code to determine the host OS type. */ #include #include #include "vmware.h" #include "hostType.h" #include "str.h" /* * XXX see bug 651592 for how to make this not warn on newer linux hosts * that have deprecated sysctl. */ #if defined(VMX86_SERVER) || ((defined(VMX86_VPX) || defined(VMX86_VMACORE)) && defined(linux)) #include #include #include #include #include "uwvmkAPI.h" #define DO_REAL_HOST_CHECK #endif #define LGPFX "HOSTTYPE:" /* *---------------------------------------------------------------------- * * HostTypeOSVMKernelType -- * * Are we running on a flavor of VMKernel? Only if the KERN_OSTYPE * sysctl returns one of USERWORLD_SYSCTL_KERN_OSTYPE, * USERWORLD_SYSCTL_VISOR_OSTYPE or USERWORLD_SYSCTL_VISOR64_OSTYPE * * Results: * 4 if running in a VMvisor UserWorld on the 64-bit vmkernel in ESX. * 3 if running directly in a UserWorld on the 64-bit vmkernel** in ESX. * 2 if running in a VMvisor UserWorld on the vmkernel in ESX. * 1 if running directly in a UserWorld on the vmkernel in ESX. * 0 if running on the COS or in a non-server product. * * **Note that 64-bit vmkernel in ESX does not currently exist. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int HostTypeOSVMKernelType(void) { #ifdef DO_REAL_HOST_CHECK static int vmkernelType = -1; if (vmkernelType == -1) { char osname[128]; size_t osnameLength; int kernOsTypeCtl[] = { CTL_KERN, KERN_OSTYPE }; int rc; osnameLength = sizeof(osname); rc = sysctl(kernOsTypeCtl, ARRAYSIZE(kernOsTypeCtl), osname, &osnameLength, 0, 0); if (rc == 0) { osnameLength = MAX(sizeof (osname), osnameLength); /* * XXX Yes, this is backwards in order of probability now, but we * call it only once and anyway someday it won't be backwards ... */ if (! strncmp(osname, USERWORLD_SYSCTL_VISOR64_OSTYPE, osnameLength)) { vmkernelType = 4; } else if (! strncmp(osname, USERWORLD_SYSCTL_KERN64_OSTYPE, osnameLength)) { vmkernelType = 3; } else if (! strncmp(osname, USERWORLD_SYSCTL_VISOR_OSTYPE, osnameLength)) { vmkernelType = 2; } else if (! strncmp(osname, USERWORLD_SYSCTL_KERN_OSTYPE, osnameLength)) { vmkernelType = 1; } else { vmkernelType = 0; } } else { /* * XXX too many of the callers don't define Warning. See bug 125455 */ vmkernelType = 0; } } return (vmkernelType); #else /* Non-linux builds are never running in a userworld */ return 0; #endif } /* *---------------------------------------------------------------------- * * HostType_OSIsVMK -- * * Are we running on the VMKernel (_any_ varient)? True if KERN_OSTYPE * sysctl returns _any_ of * * "UserWorld/VMKernel" * "VMKernel" * "UserWorld/VMKernel64" * "VMKernel64" * * Results: * TRUE if running in a UserWorld on the vmkernel in ESX. * FALSE if running on the COS or in a non-server product. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool HostType_OSIsVMK(void) { return (HostTypeOSVMKernelType() > 0); } /* *---------------------------------------------------------------------- * * HostType_OSIsPureVMK -- * * Are we running on the VMvisor VMKernel (_any_ bitness)? True if * KERN_OSTYPE sysctl returns "VMKernel" or "VMKernel64". * * Results: * TRUE if running in a VMvisor UserWorld on the vmkernel in ESX. * FALSE if running on any other type of ESX or in a non-server product. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool HostType_OSIsPureVMK(void) { return (HostTypeOSVMKernelType() == 2 || HostTypeOSVMKernelType() == 4); } /* *---------------------------------------------------------------------- * * HostType_OSIsVMK64 -- * * Are we running on a 64-bit VMKernel? Only if the KERN_OSTYPE * sysctl returns "UserWorld/VMKernel64" or "VMKernel64". * * Results: * TRUE if running in a UserWorld on a 64-bit vmkernel in ESX or VMvisor. * FALSE if running on a 32-bit VMkernel in ESX or in a non-server product. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool HostType_OSIsVMK64(void) { return (HostTypeOSVMKernelType() == 3 || HostTypeOSVMKernelType() == 4); } /* *---------------------------------------------------------------------- * * HostType_OSIsSimulator -- * * Are we running on an ESX host simulator? Check presence of the * mockup file. * * Results: * TRUE if mockup file exists * FALSE if the file doesn't exist * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool HostType_OSIsSimulator(void) { #ifdef DO_REAL_HOST_CHECK static int simulatorType = -1; if (simulatorType == -1) { if (access("/etc/vmware/hostd/mockupEsxHost.txt", 0) != -1) { simulatorType = 1; } else { simulatorType = 0; } } return (simulatorType == 1); #else /* We are only interested in the case where VMX86_SERVER or friends are defined */ return FALSE; #endif } open-vm-tools-9.4.0-1280544/lib/misc/logFixed.c0000644765153500003110000001774512220061556017063 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #include "vmware.h" #include "vm_basic_asm.h" /* *----------------------------------------------------------------------------- * * LogFixed_Base2 -- * * Return log2(value) expressed as the ratio of two uint32 numbers. * * Results: * As expected. * * Side effects: * None * * NOTE: * The log2(x) can be approximated as: * * log2(x) = log2((1 + N) * 2^P) * = P + log2(1 + N) * = P + table[index] * * where index are less significant bits than P, masked to whatever number * of bits are necessary to ensure the accuracy goal. Thus, P is the bit * number of the highest bit set; shifts are used to position the lower * order bits to provide the requested number of index bits. * * The number of index bits is TABLE_BITS, the size of the table, * 1 << TABLE_BITS. * * The table entries are computed as the numerator of a fraction of * BINARY_BASE: * * table[i] = BINARY_BASE * * log2(1.0 + (((double) i) / (double) TABLE_SIZE))) * * which allows log2(x) to be expressed as: * * log2(x) = ((BINARY_BASE * P) + table[index]) / BINARY_BASE * * maxError = 2.821500E-03; avgError = 1.935068E-05 over the range * 1 to 2E6. The test program is below. * *----------------------------------------------------------------------------- */ #define BINARY_BASE (64 * 1024) #define TABLE_BITS 8 static const uint16 log2Table[] = { 0, 368, 735, 1101, 1465, 1828, 2190, 2550, 2909, 3266, 3622, 3977, 4331, 4683, 5034, 5383, 5731, 6078, 6424, 6769, 7112, 7454, 7794, 8134, 8472, 8809, 9145, 9480, 9813, 10146, 10477, 10807, 11136, 11463, 11790, 12115, 12440, 12763, 13085, 13406, 13726, 14045, 14363, 14680, 14995, 15310, 15624, 15936, 16248, 16558, 16868, 17176, 17484, 17790, 18096, 18400, 18704, 19006, 19308, 19608, 19908, 20207, 20505, 20801, 21097, 21392, 21686, 21980, 22272, 22563, 22854, 23143, 23432, 23720, 24007, 24293, 24578, 24862, 25146, 25429, 25710, 25991, 26272, 26551, 26829, 27107, 27384, 27660, 27935, 28210, 28483, 28756, 29028, 29300, 29570, 29840, 30109, 30377, 30644, 30911, 31177, 31442, 31707, 31971, 32234, 32496, 32757, 33018, 33278, 33538, 33796, 34054, 34312, 34568, 34824, 35079, 35334, 35588, 35841, 36093, 36345, 36596, 36847, 37096, 37346, 37594, 37842, 38089, 38336, 38582, 38827, 39071, 39315, 39559, 39801, 40044, 40285, 40526, 40766, 41006, 41245, 41483, 41721, 41959, 42195, 42431, 42667, 42902, 43136, 43370, 43603, 43836, 44068, 44299, 44530, 44760, 44990, 45219, 45448, 45676, 45904, 46131, 46357, 46583, 46808, 47033, 47257, 47481, 47704, 47927, 48149, 48371, 48592, 48813, 49033, 49253, 49472, 49690, 49909, 50126, 50343, 50560, 50776, 50992, 51207, 51421, 51635, 51849, 52062, 52275, 52487, 52699, 52910, 53121, 53331, 53541, 53751, 53960, 54168, 54376, 54584, 54791, 54998, 55204, 55410, 55615, 55820, 56024, 56228, 56432, 56635, 56837, 57040, 57242, 57443, 57644, 57844, 58044, 58244, 58443, 58642, 58841, 59039, 59236, 59433, 59630, 59827, 60023, 60218, 60413, 60608, 60802, 60996, 61190, 61383, 61576, 61768, 61960, 62152, 62343, 62534, 62724, 62914, 63104, 63293, 63482, 63671, 63859, 64047, 64234, 64421, 64608, 64794, 64980, 65165, 65351 }; void LogFixed_Base2(uint64 value, // IN: uint32 *numerator, // OUT: uint32 *denominator) // OUT: { uint32 index; uint32 rawBits; uint32 maxBits; uint32 highBit; uint32 bitsOver; ASSERT_ON_COMPILE(ARRAYSIZE(log2Table) == (1 << TABLE_BITS)); highBit = mssb64_0(value); ASSERT(highBit != -1); if (highBit <= TABLE_BITS) { index = (value << (TABLE_BITS - highBit)) & ((1 << TABLE_BITS) - 1); *numerator = (BINARY_BASE * highBit) + log2Table[index]; *denominator = BINARY_BASE; return; } /* * If additional bits are available, use them to interpolate the table * to decrease the errors (especially the average). Bound the number of * additional bits as there is only a limited amount of bits available * from the interpolation table. */ bitsOver = highBit - TABLE_BITS; if (bitsOver > 16) { bitsOver = 16; } maxBits = TABLE_BITS + bitsOver; rawBits = (value >> (highBit - maxBits)) & ((1 << maxBits) - 1); index = rawBits >> bitsOver; *numerator = (BINARY_BASE * highBit) + log2Table[index]; if (index < (1 << TABLE_BITS) - 1) { uint32 extraBits = rawBits & ((1 << bitsOver) - 1); uint16 delta = log2Table[index + 1] - log2Table[index]; *numerator += (extraBits * delta) / (1 << bitsOver); } *denominator = BINARY_BASE; } /* *----------------------------------------------------------------------------- * * LogFixed_Base10 -- * * Return log10(value) expressed as the ratio of two uint32 numbers. * * Results: * As expected. * * Side effects: * None * * NOTE: * Start with the identity: * * log10(x) = log2(x) / log2(10) * * Write as a fraction: * * log2Numer / (log2Denom * log2(10)) * * log2(10) is 3.321928 * * maxError = 8.262237E-04; avgError = -1.787911E-05 over the range * 1 to 2E6. The test program is below. * *----------------------------------------------------------------------------- */ #define LOG10_BASE2 3.321928 void LogFixed_Base10(uint64 value, // IN: uint32 *numerator, // OUT: uint32 *denominator) // OUT: { uint32 log2Numerator = 0; uint32 log2Denominator = 0; LogFixed_Base2(value, &log2Numerator, &log2Denominator); *numerator = log2Numerator; *denominator = LOG10_BASE2 * BINARY_BASE; } #if defined(TEST_PROG) #include #include #include #define LOG_TESTS 2000000 main() { uint32 i; double sumLog2 = 0.0; double sumLog10 = 0.0; double maxErrorLog2 = 1E-30; double maxErrorLog10 = 1E-30; uint32 value = 1; for (i = 0; i < LOG_TESTS; i++) { double delta; double realLog; double fudgedLog; uint32 numerator; uint32 denominator; realLog = log2((double) value); LogFixed_Base2((uint64) value, &numerator, &denominator); fudgedLog = ((double) numerator) / ((double) denominator); delta = realLog - fudgedLog; if (delta > maxErrorLog2) { maxErrorLog2 = delta; } sumLog2 += delta; realLog = log10((double) value); LogFixed_Base10((uint64) value, &numerator, &denominator); fudgedLog = ((double) numerator) / ((double) denominator); delta = realLog - fudgedLog; if (delta > maxErrorLog10) { maxErrorLog10 = delta; } sumLog10 += delta; value++; } printf("LogFixed_BaseTwo: maxError = %E; avgError = %E\n", maxErrorLog2, sumLog2/((double) LOG_TESTS)); printf("LogFixed_BaseTen: maxError = %E; avgError = %E\n", maxErrorLog10, sumLog10/((double) LOG_TESTS)); } #endif open-vm-tools-9.4.0-1280544/lib/misc/posixInt.h0000644765153500003110000001316712220061556017136 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * posixInt.h -- * * Internal definitions for the Posix wrapper module. */ #ifndef _POSIXINT_H_ #define _POSIXINT_H_ #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #include "posix.h" #include "unicode.h" #include "hashTable.h" #include "vm_atomic.h" #include "util.h" #include "str.h" #ifndef _WIN32 // { /* *---------------------------------------------------------------------- * * PosixConvertToCurrent -- * * Utility function to convert a Unicode string * to the current encoding. * * Results: * TRUE on success. * Conversion result in *out or NULL on failure. * errno is untouched on success, set to UNICODE_CONVERSION_ERRNO * on failure. * * Side effects: * As described. * *---------------------------------------------------------------------- */ static INLINE Bool PosixConvertToCurrent(ConstUnicode in, // IN: string to convert char **out) // OUT: conversion result { int e = errno; char *p = Unicode_GetAllocBytes(in, STRING_ENCODING_DEFAULT); Bool success = p != NULL || in == NULL; if (success) { errno = e; *out = p; } else { errno = UNICODE_CONVERSION_ERRNO; *out = NULL; } return success; } /* *---------------------------------------------------------------------- * * PosixConvertToCurrentList -- * * Utility function to convert a list of Unicode strings * to the current encoding. * Return NULL if list is NULL. * * Results: * TRUE on success. * Conversion result in *out or NULL on failure. * errno is untouched on success, set to UNICODE_CONVERSION_ERRNO * on failure. * * Side effects: * As described. * *---------------------------------------------------------------------- */ static INLINE Bool PosixConvertToCurrentList(Unicode const *in, // IN: list to convert char ***out) // OUT: conversion result { int e = errno; char **p; Bool success; if (in == NULL) { p = NULL; success = TRUE; } else { p = Unicode_GetAllocList(in, -1, STRING_ENCODING_DEFAULT); success = p != NULL; } if (!success) { e = UNICODE_CONVERSION_ERRNO; } *out = p; errno = e; return success; } #endif // } /* * Hash table for Posix_Getenv */ typedef struct PosixEnvEntry { Atomic_Ptr value; Atomic_Ptr lastValue; } PosixEnvEntry; static INLINE void PosixEnvFree(void *v) { // never called NOT_REACHED(); } /* *----------------------------------------------------------------------------- * * PosixGetenvHash -- * * Save away Unicode result for Posix_Getenv() to make * it persistent. * * Results: * The value. * * Side effects: * The passed-in value string may be saved in a hash table, * or it may be freed. * *----------------------------------------------------------------------------- */ static INLINE_SINGLE_CALLER Unicode PosixGetenvHash(ConstUnicode name, // IN Unicode value) // IN/OUT: may be freed { static Atomic_Ptr htPtr; HashTable *ht; Unicode oldValue; PosixEnvEntry *e; /* * Don't need to save NULL. */ if (value == NULL) { return value; } ht = HashTable_AllocOnce(&htPtr, 128, HASH_FLAG_ATOMIC | HASH_FLAG_COPYKEY | HASH_STRING_KEY, PosixEnvFree); /* * We have to allow any number of concurrent getenv()'s. * So if the saved value is the same, don't change it, * and if it must change, all the threads together must * establish a single new value. * * On the other hand, we don't have to support concurrent * getenv() and setenv(). */ for (;;) { /* * If not in hash table, then insert and return. */ if (!HashTable_Lookup(ht, name, (void **) &e)) { e = Util_SafeMalloc(sizeof *e); Atomic_WritePtr(&e->value, value); Atomic_WritePtr(&e->lastValue, NULL); if (!HashTable_Insert(ht, name, e)) { free(e); continue; } break; } /* * If old value is the same, then use it. */ oldValue = Atomic_ReadPtr(&e->value); if (Str_Strcmp(oldValue, value) == 0) { Unicode_Free(value); value = oldValue; break; } /* * If value has changed, use new value, but don't free old * value yet because somebody else may be going through this * same code and still using it. Because we don't need * to care about concurrent setenv(), a single lastValue * slot is sufficient. */ if (Atomic_ReadIfEqualWritePtr(&e->value, oldValue, value) == oldValue) { oldValue = Atomic_ReadWritePtr(&e->lastValue, oldValue); Unicode_Free(oldValue); break; } } return value; } #endif // ifndef _POSIXINT_H_ open-vm-tools-9.4.0-1280544/lib/misc/escape.c0000644765153500003110000005072412220061556016554 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * escape.c -- * * Buffer escaping --hpreg */ #include #include "vmware.h" #include "dynbuf.h" #include "escape.h" /* * Table to use to quickly convert an ASCII hexadecimal digit character into a * decimal number. If the input is not an hexadecimal digit character, the * output is -1 --hpreg */ static int const Hex2Dec[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }; /* * Table to use to quickly convert a decimal number into an ASCII hexadecimal * digit character --hpreg */ static char const Dec2Hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', }; /* *----------------------------------------------------------------------------- * * Escape_DoString -- * * Escape a buffer --hpreg * * Results: * The escaped, allocated, NUL terminated buffer on success. If not NULL, * '*sizeOut' contains the size of the buffer (excluding the NUL * terminator) * NULL on failure (not enough memory) * * Side effects: * None * *----------------------------------------------------------------------------- */ void * Escape_DoString(const char *escStr, // IN int const *bytesToEsc, // IN void const *bufIn, // IN size_t sizeIn, // IN size_t *sizeOut) // OUT/OPT { char const *buf; DynBuf b; size_t startUnescaped; size_t index; size_t escStrLen; ASSERT(escStr); escStrLen = strlen(escStr); ASSERT(escStrLen > 0); ASSERT(bytesToEsc); /* Unsigned does matter --hpreg */ ASSERT(bytesToEsc[(unsigned char)escStr[0]]); buf = (char const *)bufIn; ASSERT(buf); DynBuf_Init(&b); startUnescaped = 0; for (index = 0; index < sizeIn; index++) { /* Unsigned does matter --hpreg */ unsigned char ubyte; char escSeq[2]; ubyte = buf[index]; if (bytesToEsc[ubyte]) { /* We must escape that byte --hpreg */ escSeq[0] = Dec2Hex[ubyte >> 4]; escSeq[1] = Dec2Hex[ubyte & 0xF]; if (DynBuf_Append(&b, &buf[startUnescaped], index - startUnescaped) == FALSE || DynBuf_Append(&b, escStr, escStrLen) == FALSE || DynBuf_Append(&b, escSeq, sizeof escSeq) == FALSE) { goto nem; } startUnescaped = index + 1; } } if (/* Last unescaped chunk (if any) --hpreg */ DynBuf_Append(&b, &buf[startUnescaped], index - startUnescaped) == FALSE || /* NUL terminator --hpreg */ DynBuf_Append(&b, "", 1) == FALSE || DynBuf_Trim(&b) == FALSE) { goto nem; } if (sizeOut) { *sizeOut = DynBuf_GetSize(&b) - 1; } return DynBuf_Get(&b); nem: DynBuf_Destroy(&b); return NULL; } /* *----------------------------------------------------------------------------- * * Escape_Do -- * * Escape a buffer * * Results: * The escaped, allocated, NUL terminated buffer on success. If not NULL, * '*sizeOut' contains the size of the buffer (excluding the NUL * terminator) * NULL on failure (not enough memory) * * Side effects: * None * *----------------------------------------------------------------------------- */ void * Escape_Do(char escByte, // IN int const *bytesToEsc, // IN void const *bufIn, // IN size_t sizeIn, // IN size_t *sizeOut) // OUT/OPT { const char escStr[] = { escByte, '\0' }; return Escape_DoString(escStr, bytesToEsc, bufIn, sizeIn, sizeOut); } /* *----------------------------------------------------------------------------- * * Escape_Undo -- * * Unescape a buffer --hpreg * * Results: * The unescaped, allocated, NUL terminated buffer on success. If not NULL, * '*sizeOut' contains the size of the buffer (excluding the NUL * terminator) * NULL on failure (not enough memory) * * Side effects: * None * *----------------------------------------------------------------------------- */ void * Escape_Undo(char escByte, // IN void const *bufIn, // IN size_t sizeIn, // IN size_t *sizeOut) // OUT/OPT { char const *buf; DynBuf b; unsigned int state; size_t startUnescaped; size_t index; int h = 0; /* Compiler warning --hpreg */ int l; buf = (char const *)bufIn; ASSERT(buf); DynBuf_Init(&b); startUnescaped = 0; state = 0; for (index = 0; index < sizeIn; index++) { /* Unsigned does matter --hpreg */ unsigned char ubyte; ubyte = buf[index]; switch (state) { case 0: /* Found --hpreg */ if (ubyte == escByte) { state = 1; } break; case 1: /* Found --hpreg */ h = Hex2Dec[ubyte]; state = h >= 0 ? 2 : 0; break; case 2: /* Found --hpreg */ l = Hex2Dec[ubyte]; if (l >= 0) { char escaped; escaped = h << 4 | l; if (DynBuf_Append(&b, &buf[startUnescaped], index - 2 - startUnescaped) == FALSE || DynBuf_Append(&b, &escaped, 1) == FALSE) { goto nem; } startUnescaped = index + 1; } state = 0; break; default: NOT_IMPLEMENTED(); break; } } if (/* Last unescaped chunk (if any) --hpreg */ DynBuf_Append(&b, &buf[startUnescaped], index - startUnescaped) == FALSE || /* NUL terminator --hpreg */ DynBuf_Append(&b, "", 1) == FALSE || DynBuf_Trim(&b) == FALSE) { goto nem; } if (sizeOut) { *sizeOut = DynBuf_GetSize(&b) - 1; } return DynBuf_Get(&b); nem: DynBuf_Destroy(&b); return NULL; } /* *----------------------------------------------------------------------------- * * Escape_AnsiToUnix -- * * Convert any occurrence of \r\n into \n --hpreg * * Results: * The allocated, NUL terminated buffer on success. If not NULL, * '*sizeOut' contains the size of the buffer (excluding the NUL * terminator) * NULL on failure (not enough memory) * * Side effects: * None * *----------------------------------------------------------------------------- */ void * Escape_AnsiToUnix(void const *bufIn, // IN size_t sizeIn, // IN size_t *sizeOut) // OUT/OPT { char const *buf; DynBuf b; unsigned int state; size_t startUnescaped; size_t index; buf = (char const *)bufIn; ASSERT(buf); DynBuf_Init(&b); startUnescaped = 0; state = 0; /* * Identify all chunks in buf (\r\n being the chunk separator), and copy * them into b --hpreg */ for (index = 0; index < sizeIn; index++) { char byte; byte = buf[index]; switch (state) { case 1: /* Found \r --hpreg */ state = 0; if (byte == '\n') { if (DynBuf_Append(&b, &buf[startUnescaped], index - 1 - startUnescaped) == FALSE) { goto nem; } startUnescaped = index; break; } /* Fall through --hpreg */ case 0: /* Found --hpreg */ if (byte == '\r') { state = 1; } break; default: NOT_IMPLEMENTED(); break; } } if (/* Last unescaped chunk (if any) --hpreg */ DynBuf_Append(&b, &buf[startUnescaped], index - startUnescaped) == FALSE || /* NUL terminator --hpreg */ DynBuf_Append(&b, "", 1) == FALSE || DynBuf_Trim(&b) == FALSE) { goto nem; } if (sizeOut) { *sizeOut = DynBuf_GetSize(&b) - 1; } return DynBuf_Get(&b); nem: DynBuf_Destroy(&b); return NULL; } #if 0 /* Unit test suite for Escape_AnsiToUnix() --hpreg */ int main(int argc, char **argv) { static struct { const char *in; const char *out; } tests[] = { { "", "", }, { "a", "a", }, { "\ra", "\ra", }, { "\na", "\na", }, { "\r\na", "\na", }, { "\n\ra", "\n\ra", }, { "\r\r\na", "\r\na", }, { "\r\na\r", "\na\r", }, { "\r\na\r\n", "\na\n", }, }; unsigned int i; for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { char *out; out = Escape_AnsiToUnix(tests[i].in, strlen(tests[i].in), NULL); if (strcmp(out, tests[i].out) != 0) { printf("test %u failed: %s\n", i, out); exit(1); } free(out); } printf("all tests passed\n"); return 0; } #endif /* *----------------------------------------------------------------------------- * * Escape_Sh -- * * Escape a buffer so that it can be passed verbatim as part of an argument * on a shell command line. * * Results: * The escaped, allocated, NUL terminated buffer on success. If not NULL, * '*sizeOut' contains the size of the buffer (excluding the NUL * terminator) * NULL on failure (not enough memory) * * Side effects: * None * *----------------------------------------------------------------------------- */ void * Escape_Sh(void const *bufIn, // IN size_t sizeIn, // IN size_t *sizeOut) // OUT/OPT { static const char be[] = { '\'', }; static const char escSeq[] = { '\'', '"', '\'', '"', }; char const *buf; DynBuf b; size_t startUnescaped; size_t index; buf = (char const *)bufIn; ASSERT(buf); DynBuf_Init(&b); if (DynBuf_Append(&b, be, sizeof(be)) == FALSE) { goto nem; } startUnescaped = 0; for (index = 0; index < sizeIn; index++) { if (buf[index] == '\'') { /* We must escape that byte --hpreg */ if (DynBuf_Append(&b, &buf[startUnescaped], index - startUnescaped) == FALSE || DynBuf_Append(&b, escSeq, sizeof(escSeq)) == FALSE) { goto nem; } startUnescaped = index; } } if (/* Last unescaped chunk (if any) --hpreg */ DynBuf_Append(&b, &buf[startUnescaped], index - startUnescaped) == FALSE || DynBuf_Append(&b, be, sizeof(be)) == FALSE || /* NUL terminator --hpreg */ DynBuf_Append(&b, "", 1) == FALSE || DynBuf_Trim(&b) == FALSE) { goto nem; } if (sizeOut) { *sizeOut = DynBuf_GetSize(&b) - 1; } return DynBuf_Get(&b); nem: DynBuf_Destroy(&b); return NULL; } /* *----------------------------------------------------------------------------- * * Escape_BRE -- * * Escape a buffer so that it can be passed verbatim as part of a Basic * (a.k.a. obsolete) Regular Expression. * * Results: * The escaped, allocated, NUL terminated buffer on success. If not NULL, * '*sizeOut' contains the size of the buffer (excluding the NUL * terminator) * NULL on failure (not enough memory) * * Side effects: * None * *----------------------------------------------------------------------------- */ void * Escape_BRE(void const *bufIn, // IN size_t sizeIn, // IN size_t *sizeOut) // OUT/OPT { static const char escByte = '\\'; /* Escape ] [ ^ . * $ and 'escByte'. */ static const int bytesToEsc[] = { 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, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 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, 1, 1, 1, 1, 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, 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, 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, }; char const *buf; DynBuf b; size_t startUnescaped; size_t index; /* Unsigned does matter. */ ASSERT(bytesToEsc[(unsigned char)escByte]); buf = (char const *)bufIn; ASSERT(buf); DynBuf_Init(&b); startUnescaped = 0; for (index = 0; index < sizeIn; index++) { /* Unsigned does matter. */ unsigned char ubyte; ubyte = buf[index]; if (bytesToEsc[ubyte]) { /* We must escape that byte. */ if (DynBuf_Append(&b, &buf[startUnescaped], index - startUnescaped) == FALSE || DynBuf_Append(&b, &escByte, sizeof escByte) == FALSE) { goto nem; } startUnescaped = index; } } if (/* Last unescaped chunk (if any). */ DynBuf_Append(&b, &buf[startUnescaped], index - startUnescaped) == FALSE || /* NUL terminator. */ DynBuf_Append(&b, "", 1) == FALSE || DynBuf_Trim(&b) == FALSE) { goto nem; } if (sizeOut) { *sizeOut = DynBuf_GetSize(&b) - 1; } return DynBuf_Get(&b); nem: DynBuf_Destroy(&b); return NULL; } /* *----------------------------------------------------------------------------- * * Escape_StrChr -- * * Find the first occurence of c in bufIn that is not preceded by * escByte. * * XXX Doesn't handle recursive escaping, so * will skip that occurence of * * Results: * A pointer to the character, if found, NULL if not found. * * Side effects: * None * *----------------------------------------------------------------------------- */ const char * Escape_Strchr(char escByte, // IN const char *bufIn, // IN char c) // IN { size_t i; Bool escaped = FALSE; ASSERT(escByte != c); ASSERT(bufIn); for (i = 0; bufIn[i] != '\0'; i++) { if (escaped) { escaped = FALSE; } else { if (bufIn[i] == c) { return &bufIn[i]; } if (bufIn[i] == escByte) { escaped = TRUE; } } } return NULL; } /* *----------------------------------------------------------------------------- * * Escape_Unescape -- * * Removes all occurences of an escape character from a string, unless * the occurence is escaped. * * Results: * An allocated string. * * Side effects: * None. * *----------------------------------------------------------------------------- */ char * Escape_Unescape(char escByte, // IN const char *bufIn) // IN { DynBuf result; Bool escaped = FALSE; char nullbyte = '\0'; int i; ASSERT(bufIn); DynBuf_Init(&result); for (i = 0; bufIn[i]; i++) { if (bufIn[i] != escByte || escaped) { DynBuf_Append(&result, &(bufIn[i]), sizeof(char)); escaped = FALSE; } else { escaped = TRUE; } } DynBuf_Append(&result, &nullbyte, sizeof('\0')); return DynBuf_Get(&result); } /* *---------------------------------------------------------------------------- * * Escape_UnescapeCString -- * * Unescapes a C string that has been escaped using a '\n' -> "\n" or * ' ' -> "\040" type conversion. The former is a standard '\' escaping, * while the latter is an octal representation escaping. The unescaping is * done in-place within the provided buffer. * * This function assumes the string is NUL-terminated. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void Escape_UnescapeCString(char *buf) // IN/OUT { uint32 read = 0; uint32 write = 0; ASSERT(buf); while (buf[read] != '\0') { if (buf[read] == '\\') { uint32 val; if (buf[read + 1] == 'n') { buf[write] = '\n'; read++; } else if (buf[read + 1] == '\\') { buf[write] = '\\'; read++; } else if (sscanf(&buf[read], "\\%03o", &val) == 1) { buf[write] = (char)val; read += 3; } else { buf[write] = buf[read]; } } else { buf[write] = buf[read]; } read++; write++; } buf[write] = '\0'; } #if 0 /* Unit test suite for Escape_Sh() --hpreg */ int main(int argc, char **argv) { static struct { const char *in; const char *out; } tests[] = { { "", "''", }, { "a", "'a'", }, { "'a", "''\"'\"'a'", }, { "'a'", "''\"'\"'a'\"'\"''", }, { "a'a", "'a'\"'\"'a'", }, }; unsigned int i; for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { char *out; out = Escape_Sh(tests[i].in, strlen(tests[i].in), NULL); if (strcmp(out, tests[i].out) != 0) { printf("test %u failed: %s\n", i, out); exit(1); } free(out); } printf("all tests passed\n"); return 0; } #endif /* *----------------------------------------------------------------------------- * * Escape_Comma -- * * Use backslash character as an escape character to handle comma * character escaping. * * Results: * Returns a newly allocated string with comma and backslash characters * escaped. * * Side effects: * None. It is a caller responsibility to deallocate the result. * *----------------------------------------------------------------------------- */ char * Escape_Comma(const char *string) // IN { DynBuf b; if (NULL == string) { return NULL; } DynBuf_Init(&b); for (; *string; ++string) { char c = *string; if (c == ',' || c == '\\') { if (!DynBuf_Append(&b, "\\", 1)) { goto out_of_memory; } } if (!DynBuf_Append(&b, string, 1)) { goto out_of_memory; } } DynBuf_Append(&b, string, 1); return DynBuf_Get(&b); out_of_memory: DynBuf_Destroy(&b); return NULL; } #if 0 /* Unit test suite for Escape_Comma() */ int main(int argc, char **argv) { static struct { const char *in; const char *out; } tests[] = { { "123# ", "123# ", }, { "123,", "123\\,", }, { "'123\\", "'123\\\\", }, }; unsigned int i; for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { char *out; out = Escape_Comma(tests[i].in); if (strcmp(out, tests[i].out) != 0) { printf("test %u failed: \"%s\" : \"%s\"\n", i, tests[i].in, out); exit(1); } free(out); } printf("all tests passed\n"); return 0; } #endif open-vm-tools-9.4.0-1280544/lib/misc/hostname.c0000644765153500003110000001346012220061556017126 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * hostname.c -- * * Get the host name. */ #if defined(_WIN32) #include #include #endif #include #include #include #include #include "vmware.h" #include "str.h" #include "log.h" #include "hostinfo.h" #if defined(_WIN32) // Windows #include "win32u.h" #endif #include "unicode.h" #if defined(_WIN32) // Windows /* *---------------------------------------------------------------------- * * Hostinfo_HostName -- * * Return the fully qualified host name of the host. * * Results: * The host name on success; must be freed * NULL if unable to determine the name * * Side effects: * A host name resolution can occur * *---------------------------------------------------------------------- */ Unicode Hostinfo_HostName(void) { Unicode result; HMODULE dllHandle; struct hostent *myHostEnt; struct hostent *(WINAPI *GetHostByNameFn)(char *hostName); int (WINAPI *GetHostNameFn)(char *hostName, int size); char hostName[1024] = { '\0' }; result = Win32U_GetComputerNameEx(ComputerNamePhysicalDnsFullyQualified); if (result != NULL) { return result; } Warning("%s GetComputerNameEx failed: %d\n", __FUNCTION__, GetLastError()); dllHandle = LoadLibraryA("ws2_32"); if (!dllHandle) { Warning("%s Failed to load ws2_32, will try wsock32.\n", __FUNCTION__); dllHandle = LoadLibraryA("wsock32"); if (!dllHandle) { Warning("%s Failed to wsock32.\n", __FUNCTION__); return NULL; } } GetHostNameFn = (void *) GetProcAddress(dllHandle, "gethostname"); if (!GetHostNameFn) { Warning("%s Failed to find gethostname.\n", __FUNCTION__); FreeLibrary(dllHandle); return NULL; } if ((*GetHostNameFn)(hostName, sizeof hostName) == SOCKET_ERROR) { Warning("%s gethostname failed.\n", __FUNCTION__); FreeLibrary(dllHandle); return NULL; } GetHostByNameFn = (void *) GetProcAddress(dllHandle, "gethostbyname"); if (!GetHostByNameFn) { Warning("%s Failed to find gethostbyname.\n", __FUNCTION__); FreeLibrary(dllHandle); return Unicode_Alloc(hostName, STRING_ENCODING_DEFAULT); } myHostEnt = (*GetHostByNameFn)(hostName); FreeLibrary(dllHandle); if (myHostEnt == (struct hostent *) NULL) { Warning("%s gethostbyname failed.\n", __FUNCTION__); } else { Str_Strcpy(hostName, myHostEnt->h_name, sizeof hostName); } return Unicode_Alloc(hostName, STRING_ENCODING_DEFAULT); } #elif defined(__APPLE__) // MacOS X #define SYS_NMLN _SYS_NAMELEN #include #include #include #include #include #include /* *----------------------------------------------------------------------------- * * Hostinfo_HostName -- * * Return the fully qualified host name of the host. * * Results: * The host name on success; must be freed * NULL on failure * * Side effects: * A host name resolution can occur. * *----------------------------------------------------------------------------- */ Unicode Hostinfo_HostName(void) { struct utsname un; Unicode result = NULL; if ((uname(&un) == 0) && (*un.nodename != '\0')) { /* 'un.nodename' is already fully qualified. */ result = Unicode_Alloc(un.nodename, STRING_ENCODING_US_ASCII); } return result; } #elif defined(linux) #include #include #include /* *----------------------------------------------------------------------------- * * Hostinfo_HostName -- * * Return the fully qualified host name of the host. * * Results: * The host name on success; must be freed * NULL on failure * * Side effects: * A host name resolution can occur. * *----------------------------------------------------------------------------- */ Unicode Hostinfo_HostName(void) { struct utsname un; Unicode result = NULL; if ((uname(&un) == 0) && (*un.nodename != '\0')) { char *p; int error; struct hostent he; char buffer[1024]; struct hostent *phe = &he; /* * Fully qualify 'un.nodename'. If the name cannot be fully * qualified, use whatever unqualified name is available or bug * 139607 will occur. */ p = un.nodename; if ((gethostbyname_r(p, &he, buffer, sizeof buffer, &phe, &error) == 0) && phe) { p = phe->h_name; } result = Unicode_Alloc(p, STRING_ENCODING_US_ASCII); } return result; } #else // Not any specifically coded OS /* *----------------------------------------------------------------------------- * * Hostinfo_HostName -- * * Stub for uncoded OSen * * Results: * NULL * * Side effects: * None * *----------------------------------------------------------------------------- */ Unicode Hostinfo_HostName(void) { return NULL; } #endif open-vm-tools-9.4.0-1280544/lib/misc/miscSolaris.c0000644765153500003110000000377112220061556017604 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* *---------------------------------------------------------------------- * * miscSolaris -- * * Implementation of new Linux functions for Solaris. * *---------------------------------------------------------------------- */ #ifdef sun #include "vmware.h" #include #include #include /* *---------------------------------------------------------------------- * * daemon -- * * Implementation of function daemon() for Solaris. * * Results: * 0 if successful, -1 if failed. * * Side effects: * None * *---------------------------------------------------------------------- */ int daemon(int nochdir, // IN: int noclose) // IN: { int fd; switch (fork()) { case -1: return (-1); case 0: break; default: /* It is parent, so exit here. */ exit(0); } if (setsid() == -1) { return (-1); } if (!nochdir) { chdir("/"); } if (!noclose && (fd = open("/dev/null", O_RDWR, 0)) != -1) { dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); if (fd > 2) { close (fd); } } return (0); } #endif open-vm-tools-9.4.0-1280544/lib/misc/strutil.c0000644765153500003110000007101212220061556017013 0ustar dtormts/********************************************************* * Copyright (C) 1998-2012 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * strutil.c -- * * String utility functions. */ #include #include #include #include #if !defined(_WIN32) #include /* For strncasecmp */ #endif #include "vmware.h" #include "strutil.h" #include "str.h" #include "dynbuf.h" #include "vm_ctype.h" /* *----------------------------------------------------------------------------- * * StrUtil_GetNextToken -- * * Get the next token from a string after a given index w/o modifying the * original string. * * Results: * An allocated, NUL-terminated string containing the token. 'index' is * updated to point after the returned token * NULL if no tokens are left * * Side effects: * None * *----------------------------------------------------------------------------- */ char * StrUtil_GetNextToken(unsigned int *index, // IN/OUT: Index to start at const char *str, // IN : String to parse const char *delimiters) // IN : Chars separating tokens { unsigned int startIndex; unsigned int length; char *token; ASSERT(index); ASSERT(str); ASSERT(delimiters); ASSERT(*index <= strlen(str)); #define NOT_DELIMITER (Str_Strchr(delimiters, str[*index]) == NULL) /* Skip leading delimiters. */ for (; ; (*index)++) { if (str[*index] == '\0') { return NULL; } if (NOT_DELIMITER) { break; } } startIndex = *index; /* * Walk the string until we reach the end of it, or we find a * delimiter. */ for ((*index)++; str[*index] != '\0' && NOT_DELIMITER; (*index)++) { } #undef NOT_DELIMITER length = *index - startIndex; ASSERT(length); token = (char *)malloc(length + 1 /* NUL */); ASSERT_MEM_ALLOC(token); memcpy(token, str + startIndex, length); token[length] = '\0'; return token; } /* *----------------------------------------------------------------------------- * * StrUtil_GetNextIntToken -- * * Acts like StrUtil_GetNextToken except it returns an int32. * * Results: * TRUE if a valid int was parsed and 'out' contains the parsed int. * FALSE otherwise. Contents of 'out' are undefined. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool StrUtil_GetNextIntToken(int32 *out, // OUT : parsed int unsigned int *index, // IN/OUT: Index to start at const char *str, // IN : String to parse const char *delimiters) // IN : Chars separating tokens { char *resultStr; Bool valid = FALSE; ASSERT(out); ASSERT(index); ASSERT(str); ASSERT(delimiters); resultStr = StrUtil_GetNextToken(index, str, delimiters); if (resultStr == NULL) { return FALSE; } valid = StrUtil_StrToInt(out, resultStr); free(resultStr); return valid; } /* *----------------------------------------------------------------------------- * * StrUtil_GetNextUintToken -- * * Acts like StrUtil_GetNextIntToken except it returns an uint32. * * Results: * TRUE if a valid int was parsed and 'out' contains the parsed int. * FALSE otherwise. Contents of 'out' are undefined. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool StrUtil_GetNextUintToken(uint32 *out, // OUT : parsed int unsigned int *index, // IN/OUT: Index to start at const char *str, // IN : String to parse const char *delimiters) // IN : Chars separating tokens { char *resultStr; Bool valid = FALSE; ASSERT(out); ASSERT(index); ASSERT(str); ASSERT(delimiters); resultStr = StrUtil_GetNextToken(index, str, delimiters); if (resultStr == NULL) { return FALSE; } valid = StrUtil_StrToUint(out, resultStr); free(resultStr); return valid; } /* *----------------------------------------------------------------------------- * * StrUtil_GetNextInt64Token -- * * Acts like StrUtil_GetNextToken except it returns an int64. * * Results: * TRUE on a successful retrieval. FALSE otherwise. * Token is stored in 'out', which is left undefined in the FALSE case. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool StrUtil_GetNextInt64Token(int64 *out, // OUT: The output value unsigned int *index, // IN/OUT: Index to start at const char *str, // IN : String to parse const char *delimiters) // IN : Chars separating tokens { char *resultStr; Bool result; ASSERT(out); ASSERT(index); ASSERT(str); ASSERT(delimiters); resultStr = StrUtil_GetNextToken(index, str, delimiters); result = resultStr ? StrUtil_StrToInt64(out, resultStr) : FALSE; free(resultStr); return result; } /* *----------------------------------------------------------------------------- * * StrUtil_DecimalStrToUint -- * * Convert a string into an integer. * * Results: * TRUE if the conversion was successful, and 'out' contains the converted * result, and 'str' is updated to point to new place after last processed * digit. * FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool StrUtil_DecimalStrToUint(unsigned int *out, // OUT const char **str) // IN/OUT : String to parse { unsigned long val; char *ptr; ASSERT(out); ASSERT(str); errno = 0; val = strtoul(*str, &ptr, 10); if (ptr == *str || errno == ERANGE || val != (unsigned int)val) { return FALSE; } *str = ptr; *out = (unsigned int)val; return TRUE; } /* *----------------------------------------------------------------------------- * * StrUtil_StrToInt -- * * Convert a string into an integer. * * Results: * TRUE if the conversion was successful and 'out' contains the converted * result. * FALSE otherwise. 'out' is undefined. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool StrUtil_StrToInt(int32 *out, // OUT const char *str) // IN : String to parse { char *ptr; long val; ASSERT(out); ASSERT(str); errno = 0; val = strtol(str, &ptr, 0); *out = (int32)val; /* * Input must be complete, no overflow, and value read must fit into * 32 bits - both signed and unsigned values are accepted. */ return *ptr == '\0' && errno != ERANGE && (val == (int32)val || val == (uint32)val); } /* *----------------------------------------------------------------------------- * * StrUtil_StrToUint -- * * Convert a string into unsigned integer. * * Results: * TRUE if the conversion succeeded and 'out' contains the result. * FALSE otherwise. 'out' is undefined. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool StrUtil_StrToUint(uint32 *out, // OUT const char *str) // IN : String to parse { char *ptr; unsigned long val; ASSERT(out); ASSERT(str); errno = 0; val = strtoul(str, &ptr, 0); *out = (uint32)val; /* * Input must be complete, no overflow, and value read must fit into 32 * bits - both signed and unsigned values are accepted. */ return *ptr == '\0' && errno != ERANGE && (val == (uint32)val || val == (int32)val); } /* *----------------------------------------------------------------------------- * * StrUtil_StrToInt64 -- * * Convert a string into a 64bit integer. * * Results: * TRUE if conversion was successful, FALSE otherwise. * Value is stored in 'out', which is left undefined in the FALSE case. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool StrUtil_StrToInt64(int64 *out, // OUT: The output value const char *str) // IN : String to parse { char *ptr; ASSERT(out); ASSERT(str); errno = 0; #if defined(_WIN32) *out = _strtoi64(str, &ptr, 0); #elif defined(__FreeBSD__) *out = strtoq(str, &ptr, 0); #else *out = strtoll(str, &ptr, 0); #endif return ptr[0] == '\0' && errno != ERANGE; } /* *----------------------------------------------------------------------------- * * StrUtil_StrToUint64 -- * * Convert a string into an unsigned 64bit integer. * * Results: * TRUE if conversion was successful, FALSE otherwise. * Value is stored in 'out', which is left undefined in the FALSE case. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool StrUtil_StrToUint64(uint64 *out, // OUT: The output value const char *str) // IN : String to parse { char *ptr; ASSERT(out); ASSERT(str); errno = 0; #if defined(_WIN32) *out = _strtoui64(str, &ptr, 0); #elif defined(__FreeBSD__) *out = strtouq(str, &ptr, 0); #else *out = strtoull(str, &ptr, 0); #endif return ptr[0] == '\0' && errno != ERANGE && errno != EINVAL; } /* *----------------------------------------------------------------------------- * * StrUtil_StrToSizet -- * * Convert a string into an unsigned integer that is either 32-bits or * 64-bits long, depending on the underlying architecture. * * Results: * TRUE if conversion was successful, FALSE otherwise. * Value is stored in 'out', which is left undefined in the FALSE case. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool StrUtil_StrToSizet(size_t *out, // OUT: The output value const char *str) // IN : String to parse { char *ptr; ASSERT(out); ASSERT(str); errno = 0; #if defined VM_X86_64 ASSERT_ON_COMPILE(sizeof *out == sizeof(uint64)); # if defined(_WIN32) *out = _strtoui64(str, &ptr, 0); # elif defined(__FreeBSD__) *out = strtouq(str, &ptr, 0); # else *out = strtoull(str, &ptr, 0); # endif #else ASSERT_ON_COMPILE(sizeof *out == sizeof(uint32)); *out = strtoul(str, &ptr, 0); #endif return *ptr == '\0' && errno != ERANGE; } /* *----------------------------------------------------------------------------- * * StrUtil_StrToDouble -- * * Convert a string into a double. * * Results: * TRUE if the conversion was successful and 'out' contains the converted * result. * FALSE otherwise. 'out' is undefined. * * Side effects: * Modifies errno. * *----------------------------------------------------------------------------- */ Bool StrUtil_StrToDouble(double *out, // OUT: The output value const char *str) // IN : String to parse { char *ptr = NULL; ASSERT(out); ASSERT(str); errno = 0; *out = strtod(str, &ptr); /* * Input must be complete and no overflow. */ return *ptr == '\0' && errno != ERANGE; } /* *----------------------------------------------------------------------------- * * StrUtil_CapacityToBytes -- * * Converts a string containing a measure of capacity (such as * "100MB" or "1.5k") into an unadorned and primitive quantity of bytes * capacity. The comment before the switch statement describes the kinds * of capacity expressible. * * Results: * TRUE if conversion was successful, FALSE otherwise. * Value is stored in 'out', which is left undefined in the FALSE case. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool StrUtil_CapacityToBytes(uint64 *out, // OUT: The output value const char *str, // IN: String to parse unsigned int bytes) // IN: Bytes per unit in an // unadorned string { double quantity; char *rest; ASSERT(out); ASSERT(str); errno = 0; quantity = strtod(str, &rest); if (errno == ERANGE) { return FALSE; } /* Skip over any whitespace in the suffix. */ while (*rest == ' ' || *rest == '\t') { rest++; } if (*rest != '\0') { uint64 shift; Bool suffixOK = TRUE; /* * [kK], [mM], [gG], and [tT] represent kilo, mega, giga, and tera * byte quantities respectively. [bB] represents a singular byte * quantity. [sS] represents a sector quantity. * * For kilo, mega, giga, and tera we're OK with an additional byte * suffix. Otherwise, the presence of an additional suffix is an error. */ switch (*rest) { case 'b': case 'B': shift = 0; suffixOK = FALSE; break; case 's': case 'S': shift = 9; suffixOK = FALSE; break; case 'k': case 'K': shift = 10; break; case 'm': case 'M': shift = 20; break; case 'g': case 'G': shift = 30; break; case 't': case 'T': shift = 40; break; default : return FALSE; } switch(*++rest) { case '\0': break; case 'b': case 'B': if (suffixOK && !*++rest) { break; } /* FALLTHRU */ default: return FALSE; } quantity *= CONST64U(1) << shift; } else { /* * No suffix, so multiply by the number of bytes per unit as specified * by the caller. */ quantity *= bytes; } *out = quantity; return TRUE; } /* *----------------------------------------------------------------------------- * * StrUtil_CapacityToSectorType -- * * Converts a string containing a measure of disk capacity (such as * "100MB" or "1.5k") into an unadorned and primitive quantity of sector * capacity. * * Results: * TRUE if conversion was successful, FALSE otherwise. * Value is stored in 'out', which is left undefined in the FALSE case. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool StrUtil_CapacityToSectorType(SectorType *out, // OUT: The output value const char *str, // IN: String to parse unsigned int bytes) // IN: Bytes per unit in an // unadorned string { uint64 quantityInBytes; if (StrUtil_CapacityToBytes(&quantityInBytes, str, bytes) == FALSE) { return FALSE; } /* * Convert from "number of bytes" to "number of sectors", rounding up or * down appropriately. * * XXX: We should use DISKLIB_SECTOR_SIZE, but do we really want the * disklib header dependencies in this file? * */ *out = (SectorType)((quantityInBytes + 256) / 512); return TRUE; } /* *----------------------------------------------------------------------------- * * StrUtil_FormatSizeInBytes -- * * Format a size (in bytes) to a string in a user-friendly way. * * Example: 160041885696 -> "149.1 GB" * * Results: * The allocated, NUL-terminated string (not localized). * * Side effects: * None * *----------------------------------------------------------------------------- */ char * StrUtil_FormatSizeInBytesUnlocalized(uint64 size) // IN { /* * XXX TODO, BUG 199661: * This is a direct copy of Msg_FormatSizeInBytes without localization. * These two functions should ideally share the basic functionality, and * just differ in the string localization */ char const *fmt; double sizeInSelectedUnit; unsigned int precision; char *sizeFormat; char *sizeString; char *result; static const double epsilon = 0.01; double delta; if (size >= CONST64U(1) << 40 /* 1 TB */) { fmt = "%s TB"; sizeInSelectedUnit = (double)size / (CONST64U(1) << 40); precision = 1; } else if (size >= CONST64U(1) << 30 /* 1 GB */) { fmt = "%s GB"; sizeInSelectedUnit = (double)size / (CONST64U(1) << 30); precision = 1; } else if (size >= CONST64U(1) << 20 /* 1 MB */) { fmt = "%s MB"; sizeInSelectedUnit = (double)size / (CONST64U(1) << 20); precision = 1; } else if (size >= CONST64U(1) << 10 /* 1 KB */) { fmt = "%s KB"; sizeInSelectedUnit = (double)size / (CONST64U(1) << 10); precision = 1; } else if (size >= CONST64U(2) /* 2 bytes */) { fmt = "%s bytes"; sizeInSelectedUnit = (double)size; precision = 0; // No fractional byte. } else if (size >= CONST64U(1) /* 1 byte */) { fmt = "%s byte"; sizeInSelectedUnit = (double)size; precision = 0; // No fractional byte. } else { ASSERT(size == CONST64U(0) /* 0 bytes */); fmt = "%s bytes"; sizeInSelectedUnit = (double)size; precision = 0; // No fractional byte. } /* * We cast to uint32 instead of uint64 here because of a problem with the * NetWare Tools build. However, it's safe to cast to uint32 since we have * already reduced the range of sizeInSelectedUnit above. */ // If it would display with .0, round it off and display the integer value. delta = (uint32)(sizeInSelectedUnit + 0.5) - sizeInSelectedUnit; if (delta < 0) { delta = -delta; } if (delta <= epsilon) { precision = 0; sizeInSelectedUnit = (double)(uint32)(sizeInSelectedUnit + 0.5); } sizeFormat = Str_Asprintf(NULL, "%%.%uf", precision); sizeString = Str_Asprintf(NULL, sizeFormat, sizeInSelectedUnit); result = Str_Asprintf(NULL, fmt, sizeString); free(sizeFormat); free(sizeString); return result; } /* *---------------------------------------------------------------------- * * StrUtil_GetLongestLineLength -- * * Given a buffer with one or more lines * this function computes the length of the * longest line in a buffer. Input buffer is an array of * arbitrary bytes (including NUL character), line separator * is '\n', and is counted in line length. Like: * "", 0 => 0 * "\n", 1 => 1 * "X", 1 => 1 * "XX\n", 3 => 3 * "X\nY", 3 => 2 * "\n\n", 2 => 1 * * Results: * Returns the length of the longest line in the 'buf'. * * Side effects: * None. * *---------------------------------------------------------------------- */ size_t StrUtil_GetLongestLineLength(const char *buf, //IN size_t bufLength) //IN { size_t longest = 0; while (bufLength) { const char* next; size_t len; next = memchr(buf, '\n', bufLength); if (next) { next++; len = next - buf; } else { len = bufLength; } if (len > longest) { longest = len; } bufLength -= len; buf = next; } return longest; } /* *---------------------------------------------------------------------- * * StrUtil_StartsWith -- * * Determines if a string starts with another string. * * Results: * TRUE if 's' starts with 'prefix', FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool StrUtil_StartsWith(const char *s, // IN const char *prefix) // IN { ASSERT(s != NULL); ASSERT(prefix != NULL); while (*prefix && *prefix == *s) { prefix++; s++; } return *prefix == '\0'; } /* *---------------------------------------------------------------------- * * StrUtil_CaselessStartsWith -- * * A case-insensitive version of StrUtil_StartsWith. * * Results: * TRUE if 's' starts with 'prefix', FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool StrUtil_CaselessStartsWith(const char *s, // IN const char *prefix) // IN { ASSERT(s != NULL); ASSERT(prefix != NULL); return Str_Strncasecmp(s, prefix, strlen(prefix)) == 0; } /* *----------------------------------------------------------------------------- * * StrUtil_EndsWith -- * * Detects if a string ends with another string. * * Results: * TRUE if string 'suffix' is found at the end of string 's' * FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool StrUtil_EndsWith(const char *s, // IN const char *suffix) // IN { size_t slen; size_t suffixlen; ASSERT(s); ASSERT(suffix); slen = strlen(s); suffixlen = strlen(suffix); if (suffixlen > slen) { return FALSE; } return strcmp(s + slen - suffixlen, suffix) == 0; } /* *----------------------------------------------------------------------------- * * StrUtil_IsASCII -- * * Results: * Returns TRUE if the string contains only ASCII characters, FALSE * otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool StrUtil_IsASCII(const char *s) // IN { ASSERT(s != NULL); while (*s != '\0') { if (!CType_IsAscii(*s)) { return FALSE; } s++; } return TRUE; } /* *----------------------------------------------------------------------------- * * StrUtil_VDynBufPrintf -- * * This is a vprintf() variant which appends directly into a * dynbuf. The dynbuf is not NUL-terminated: The printf() result * is written immediately after the last byte in the DynBuf. * * This function does not use any temporary buffer. The printf() * result can be arbitrarily large. This function automatically * grows the DynBuf as necessary. * * Results: * TRUE on success, FALSE on memory allocation failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool StrUtil_VDynBufPrintf(DynBuf *b, // IN/OUT const char *fmt, // IN va_list args) // IN { /* * Arbitrary lower-limit on buffer size allocation, to avoid doing * many tiny enlarge operations. */ const size_t minAllocSize = 128; while (1) { int i; size_t size = DynBuf_GetSize(b); size_t allocSize = DynBuf_GetAllocatedSize(b); /* Make sure the buffer isn't still unallocated */ if (allocSize < minAllocSize) { Bool success = DynBuf_Enlarge(b, minAllocSize); if (!success) { return FALSE; } continue; } /* * Is there any allocated-but-not-occupied space? If so, try the printf. * If there was no space to begin with, or Str_Vsnprintf() ran out of * space, this will fail. */ if (allocSize - size > 0) { va_list tmpArgs; va_copy(tmpArgs, args); i = Str_Vsnprintf((char *) DynBuf_Get(b) + size, allocSize - size, fmt, tmpArgs); va_end(tmpArgs); } else { i = -1; } if (i >= 0) { /* * Success. Enlarge the buffer. * * The ASSERT here is to verify that printf() isn't lying * about the length of the string it wrote. This actually * happens, believe it or not. See bug 253674. */ ASSERT(i + size == allocSize || ((char *)DynBuf_Get(b))[i + size] == '\0'); DynBuf_SetSize(b, size + i); break; } else { /* * Failure. We must grow the buffer first. Note that this is * just a minimum size- dynbuf will probably decide to double * the actual reallocated buffer size. */ Bool success = DynBuf_Enlarge(b, size + minAllocSize); if (!success) { return FALSE; } } } return TRUE; } /* *----------------------------------------------------------------------------- * * StrUtil_DynBufPrintf -- * * A StrUtil_VDynBufPrintf() wrapper which takes a variadic argument list. * * Results: * TRUE on success, FALSE on memory allocation failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool StrUtil_DynBufPrintf(DynBuf *b, // IN/OUT const char *fmt, // IN ...) // IN { va_list args; Bool success; va_start(args, fmt); success = StrUtil_VDynBufPrintf(b, fmt, args); va_end(args); return success; } /* *----------------------------------------------------------------------------- * * StrUtil_SafeDynBufPrintf -- * * A 'safe' variant of StrUtil_SafeDynBufPrintf(), which catches * memory allocation failures and panics. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void StrUtil_SafeDynBufPrintf(DynBuf *b, // IN/OUT const char *fmt, // IN ...) // IN { va_list args; Bool success; va_start(args, fmt); success = StrUtil_VDynBufPrintf(b, fmt, args); va_end(args); ASSERT_MEM_ALLOC(success); } /* *----------------------------------------------------------------------------- * * StrUtil_SafeStrcat -- * * Given an input buffer, append another string and return the resulting * string. The input buffer is freed along the way. A fancy strcat(). * * Results: * New buffer returned via 'prefix' * * Side effects: * None. * *----------------------------------------------------------------------------- */ void StrUtil_SafeStrcat(char **prefix, // IN/OUT const char *str) // IN { char *tmp; size_t plen = *prefix != NULL ? strlen(*prefix) : 0; size_t slen = strlen(str); /* Check for overflow */ ASSERT_NOT_IMPLEMENTED((size_t)-1 - plen > slen + 1); tmp = realloc(*prefix, plen + slen + 1 /* NUL */); ASSERT_MEM_ALLOC(tmp); memcpy(tmp + plen, str, slen + 1 /* NUL */); *prefix = tmp; } /* *----------------------------------------------------------------------------- * * StrUtil_SafeStrcatFV -- * * Given an input buffer, append another string and return the resulting * string. The input buffer is freed along the way. A fancy vasprintf(). * * Results: * New buffer returned via 'prefix' * * Side effects: * None. * *----------------------------------------------------------------------------- */ void StrUtil_SafeStrcatFV(char **prefix, // IN/OUT const char *fmt, // IN va_list args) // IN { char *str = Str_SafeVasprintf(NULL, fmt, args); StrUtil_SafeStrcat(prefix, str); free(str); } /* *----------------------------------------------------------------------------- * * StrUtil_SafeStrcatF -- * * Given an input buffer, append another string and return the resulting * string. The input buffer is freed along the way. A fancy asprintf(). * * Results: * New buffer returned via 'prefix' * * Side effects: * None. * *----------------------------------------------------------------------------- */ void StrUtil_SafeStrcatF(char **prefix, // IN/OUT const char *fmt, // IN ...) // IN { va_list args; va_start(args, fmt); StrUtil_SafeStrcatFV(prefix, fmt, args); va_end(args); } open-vm-tools-9.4.0-1280544/lib/misc/Makefile.am0000644765153500003110000000362212220061556017177 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libMisc.la libMisc_la_SOURCES = libMisc_la_SOURCES += atomic.c libMisc_la_SOURCES += base64.c libMisc_la_SOURCES += codeset.c libMisc_la_SOURCES += codesetBase.c libMisc_la_SOURCES += codesetOld.c libMisc_la_SOURCES += dynarray.c libMisc_la_SOURCES += dynbuf.c libMisc_la_SOURCES += escape.c libMisc_la_SOURCES += hashTable.c libMisc_la_SOURCES += hostinfo.c libMisc_la_SOURCES += hostinfoHV.c libMisc_la_SOURCES += hostinfoPosix.c libMisc_la_SOURCES += hostname.c libMisc_la_SOURCES += hostType.c libMisc_la_SOURCES += idLinux.c libMisc_la_SOURCES += iovector.c libMisc_la_SOURCES += logFixed.c libMisc_la_SOURCES += machineID.c libMisc_la_SOURCES += miscSolaris.c libMisc_la_SOURCES += msgfmt.c libMisc_la_SOURCES += msgList.c libMisc_la_SOURCES += posixDlopen.c libMisc_la_SOURCES += posixPosix.c libMisc_la_SOURCES += random.c libMisc_la_SOURCES += timeutil.c libMisc_la_SOURCES += util_misc.c libMisc_la_SOURCES += utilMem.c libMisc_la_SOURCES += vmstdio.c libMisc_la_SOURCES += strutil.c libMisc_la_SOURCES += vthreadBase.c open-vm-tools-9.4.0-1280544/lib/misc/hostinfoInt.h0000644765153500003110000000250312220061556017615 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * hostinfoInt.h -- * * lib/misc Hostinfo_* private declarations. */ #ifndef _HOSTINFOINT_H_ #define _HOSTINFOINT_H_ #define MAX_OS_NAME_LEN 128 #define MAX_OS_FULLNAME_LEN 512 /* * Global variables */ extern volatile Bool HostinfoOSNameCacheValid; extern char HostinfoCachedOSName[MAX_OS_NAME_LEN]; extern char HostinfoCachedOSFullName[MAX_OS_FULLNAME_LEN]; /* * Global functions */ extern Bool HostinfoOSData(void); #endif // ifndef _HOSTINFOINT_H_ open-vm-tools-9.4.0-1280544/lib/misc/msgList.c0000644765153500003110000003456312220061556016741 0ustar dtormts/********************************************************* * Copyright (C) 2009-2011 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * msgList.c -- * * Utilities to manipulate (stateless) lists of messages. * See also msg.h. */ #include #include #include #include "vmware.h" #include "util.h" #include "str.h" #include "err.h" #include "msgList.h" #include "dynbuf.h" #define LOGLEVEL_MODULE main #include "loglevel_user.h" /* *----------------------------------------------------------------------------- * * MsgId2MsgList -- * * Create a MsgList item from the input message. Does not handle arguments; * the caller must handle those. * * Performs any needed sanity checks as well. * * Results: * A newly-allocated MsgList. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static MsgList * MsgId2MsgList(const char *idFmt) // IN message ID and English message { MsgList *m; const char *idp, *strp; /* All message strings must be prefixed by the message ID. */ ASSERT(Msg_HasMsgID(idFmt)); /* * Find the beginning of the ID (idp) and the string (strp). * The string should have the correct MSG_MAGIC(...)... form. */ idp = idFmt + MSG_MAGIC_LEN + 1; strp = strchr(idp, ')') + 1; m = Util_SafeMalloc(sizeof *m); m->format = Util_SafeStrdup(strp); m->next = NULL; m->args = NULL; m->numArgs = 0; if (vmx86_debug) { uint32 i; static const char *prfx[] = { "msg.", // bora/lib, VMX, ... "vob.", // Vmkernel OBservation "vpxa.", // VirtualCenter host agent "vpxd.", // VirtualCenter server "hostd.", // Host agent // Additional prefixes go here, but do not add "button." }; for (i = 0; i < ARRAYSIZE(prfx); i++) { if (!Str_Strncasecmp(idp, prfx[i], strlen(prfx[i]))) { break; } } if (i >= ARRAYSIZE(prfx)) { Panic("%s error: Invalid msg prefix in <%s>\n", __FUNCTION__, idp); } } m->id = Util_SafeStrndup(idp, strp - idp - 1 /* ')' character */); return m; } /* *----------------------------------------------------------------------------- * * MsgList_AppendStr -- * * Create a MsgList item from the input message. The input message MUST * have no arguments. Do not pass in formatted messages; use MsgList_Append * for that. This variant is only for MSGIDs that have no format arguments. * * If the incoming list pointer reference is NULL, operate in 'silent' * mode: skip all work (except preconditions). Note that in silent + * vmx86_debug mode, this code does all work and throws away the result, * to make sure all messages are parseable. * * Results: * New item is attached to 'list' (and '*list' is updated). * * Side effects: * Callers are responsible to free the returned MsgList. * *----------------------------------------------------------------------------- */ void MsgList_AppendStr(MsgList **list, // IN reference to existing list const char *id) // IN message ID and English message { ASSERT(id != NULL); /* Silently upgrade system errors to real MSGIDs. */ if (!Msg_HasMsgID(id)) { ASSERT(Err_String2Errno(id) != ERR_INVALID); /* On release builds, tolerate other messages that lack MSGIDs. */ MsgList_Append(list, MSGID(literal) "%s", id); return; } /* * The MsgList_AppendStr variant does not accept format strings. This * check disallows some legitimate strings, but it's probably easier * on the msgconv parser to just disallow all format-string-like things. */ ASSERT(strchr(id, '%') == NULL); /* * In silent mode, skip processing in release builds. Debug * builds can afford the speed cost to verify message is constructable. */ if (list != NULL || vmx86_debug) { MsgList *m = MsgId2MsgList(id); if (list != NULL) { m->next = *list; *list = m; } else { /* Silent mode, but constructed as a sanity test. Clean up. */ ASSERT(vmx86_debug); MsgList_Free(m); } } } /* *----------------------------------------------------------------------------- * * MsgList_VAppend -- * * Create a MsgList item from the message with va_list, * and attach it to the incoming list. * * If the incoming list pointer reference is NULL, operate in 'silent' * mode: skip all work (except preconditions). Note that in silent + * vmx86_debug mode, this code does all work and throws away the result, * to make sure all messages are parseable. * * Results: * New item is attached to 'list' (and '*list' is updated). * * Side effects: * Callers are responsible to free the returned MsgList. * *----------------------------------------------------------------------------- */ void MsgList_VAppend(MsgList **list, // IN reference to existing list const char *idFmt, // IN message ID and English message va_list args) // IN args { ASSERT(idFmt != NULL); if (!Msg_HasMsgID(idFmt)) { ASSERT(Err_String2Errno(idFmt) != ERR_INVALID); /* On release builds, tolerate other messages that lack MSGIDs. */ MsgList_Append(list, MSGID(literal) "%s", idFmt); return; } /* * In silent mode, skip processing in release builds. Debug * builds can afford the speed cost to verify message is constructable. */ if (list != NULL || vmx86_debug) { MsgList *m = MsgId2MsgList(idFmt); Bool status; char *error; status = MsgFmt_GetArgs(m->format, args, &m->args, &m->numArgs, &error); if (!status) { Log("%s error: %s\nformat <%s>\n", __FUNCTION__, error, m->format); PANIC(); } if (list != NULL) { m->next = *list; *list = m; } else { /* Silent mode, but constructed as a sanity test. Clean up. */ ASSERT(vmx86_debug); MsgList_Free(m); } } } /* *----------------------------------------------------------------------------- * * MsgList_Append -- * * Create the MsgList item from the message with va_list. * * Results: * New item is prepended to 'list' (and '*list' is new item). * * Side effects: * Callers are responsible to free the returned MsgList. * *----------------------------------------------------------------------------- */ void MsgList_Append(MsgList **list, // IN reference to existing list const char *idFmt, // IN message ID and English message ...) // IN args { va_list args; va_start(args, idFmt); MsgList_VAppend(list, idFmt, args); va_end(args); } /* *----------------------------------------------------------------------------- * * MsgList_AppendMsgList -- * * Append the 'messages' to an existing MsgList, 'list'. Memory * owner ship is transfered to 'list'. * * Results: * None. * * Side effects: * Callers are responsible to free the returned MsgList. * *----------------------------------------------------------------------------- */ void MsgList_AppendMsgList(MsgList **list, // IN/OUT MsgList *messages) // IN { if (list != NULL && messages != NULL) { MsgList *head = messages; while (messages->next != NULL) { messages = messages->next; } messages->next = *list; *list = head; } else { MsgList_Free(messages); } } /* *----------------------------------------------------------------------------- * * MsgList_VCreate -- * * Create the MsgList item from the message. * * Results: * New MsgList structure. * * Side effects: * Callers are responsible to free the returned MsgList. * *----------------------------------------------------------------------------- */ MsgList * MsgList_VCreate(const char *idFmt, // IN message ID and English message va_list args) // IN args { MsgList *ml = NULL; MsgList_VAppend(&ml, idFmt, args); return ml; } /* *----------------------------------------------------------------------------- * * MsgList_Create -- * * Create the MsgList item from the message with va_list. * * Results: * New MsgList structure. * * Side effects: * Callers are responsible to free the returned MsgList. * *----------------------------------------------------------------------------- */ MsgList * MsgList_Create(const char *idFmt, // IN message ID and English message ...) // IN args { MsgList *ml = NULL; va_list args; va_start(args, idFmt); MsgList_VAppend(&ml, idFmt, args); va_end(args); return ml; } /* *----------------------------------------------------------------------------- * * MsgList_CreateStr -- * * Create the MsgList item from the message with no format arguments. * * Results: * New MsgList structure. * * Side effects: * Callers are responsible to free the returned MsgList. * *----------------------------------------------------------------------------- */ MsgList * MsgList_CreateStr(const char *idFmt) // IN message ID and English message { MsgList *ml = NULL; MsgList_AppendStr(&ml, idFmt); return ml; } /* *---------------------------------------------------------------------- * * MsgList_Copy -- * * Makes a deep copy of the MsgList. * * Results: * Newly allocated MsgList. Use MsgList_Free() to free. * * Side effects: * None. * *---------------------------------------------------------------------- */ MsgList * MsgList_Copy(const MsgList *src) // IN: { MsgList *result = NULL; MsgList **pdst = &result; while (src != NULL) { MsgList *dst = Util_SafeMalloc(sizeof *dst); dst->id = Util_SafeStrdup(src->id); dst->format = Util_SafeStrdup(src->format); dst->args = MsgFmt_CopyArgs(src->args, src->numArgs); dst->numArgs = src->numArgs; dst->next = NULL; src = src->next; *pdst = dst; pdst = &dst->next; } return result; } /* *---------------------------------------------------------------------- * * MsgList_Free -- * * Frees the full MsgList chain. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void MsgList_Free(MsgList *messages) // IN: { MsgList *m; MsgList *next; for (m = messages; m != NULL; m = next) { free(m->format); free(m->id); MsgFmt_FreeArgs(m->args, m->numArgs); next = m->next; free(m); } } /* *---------------------------------------------------------------------- * * MsgList_GetMsgID -- * * Returns the "main" MSGID for the message stack. * * This is useful for Msg_Post, Msg_Hint, and Msg_Question, * all of which have the semantic that the generalized MSGID * is the MSGID of the last message in the stack. * * Results: * Returns pointer to something within the MsgList, or * NULL if the MsgList doesn't exist. * * Side effects: * None. * *---------------------------------------------------------------------- */ const char * MsgList_GetMsgID(const MsgList *messages) // IN: { if (messages == NULL) { return NULL; } while (messages->next != NULL) { messages = messages->next; } return messages->id; } /* *---------------------------------------------------------------------- * * MsgList_ToString -- * * Returns the English representation of a MsgList chain. Does NOT * localize. * * Results: * Allocated memory containing message. Successive messages * are separated by newlines. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * MsgList_ToString(const MsgList *messages) // IN: { char *result = NULL; if (messages != NULL) { size_t len = 0; char *formatted = MsgFmt_Asprintf(&len, messages->format, messages->args, messages->numArgs); const char *eol = (len > 0 && formatted != NULL && formatted[len - 1] == '\n') ? "" : "\n"; char *tail; if (messages->next != NULL) { tail = MsgList_ToString(messages->next); } else { tail = Util_SafeStrdup(""); } result = Str_SafeAsprintf(NULL, "%s%s%s", formatted, eol, tail); free(formatted); free(tail); } return result; } /* *---------------------------------------------------------------------- * * MsgList_Log -- * * Emits the English representation of a MsgList chain to Log(). * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void MsgList_Log(const MsgList *messages) // IN: { const MsgList *m; for (m = messages; m != NULL; m = m->next) { size_t len = 0; char *formatted = MsgFmt_Asprintf(&len, m->format, m->args, m->numArgs); Log("[%s] %s%s", m->id, formatted, (len > 0 && formatted != NULL && formatted[len - 1] == '\n') ? "" : "\n"); free(formatted); } } /* *---------------------------------------------------------------------- * * MsgList_Present -- * * Tests if the MsgList is empty. * * Results: * TRUE if there are appended messages; FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool MsgList_Present(const MsgList *messages) // IN: { return messages != NULL; } open-vm-tools-9.4.0-1280544/lib/misc/utilMem.c0000644765153500003110000002321412220061556016722 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * utilMem.c -- * * misc util functions */ #ifdef _WIN32 #include #endif #include #include #include #include "vm_assert.h" #ifdef __APPLE__ #include #if !defined TARGET_OS_IPHONE #define TARGET_OS_IPHONE 0 #endif #endif static NORETURN void UtilAllocationFailure0(void); static NORETURN void UtilAllocationFailure1(int bugNumber, const char *file, int lineno); static void UtilAllocationFailure0(void) { Panic("Unrecoverable memory allocation failure\n"); } static void UtilAllocationFailure1(int bugNumber, const char *file, int lineno) { if (bugNumber == -1) { Panic("Unrecoverable memory allocation failure at %s:%d\n", file, lineno); } else { Panic("Unrecoverable memory allocation failure at %s:%d. Bug " "number: %d\n", file, lineno, bugNumber); } } /* *----------------------------------------------------------------------------- * * UtilSafeMalloc0 -- * UtilSafeMalloc1 -- * Helper function for malloc * * Results: * Pointer to the dynamically allocated memory. * * Side effects: * May Panic if ran out of memory. * *----------------------------------------------------------------------------- */ void * UtilSafeMalloc0(size_t size) // IN: { void *result = malloc(size); if (result == NULL && size != 0) { UtilAllocationFailure0(); } return result; } void * UtilSafeMalloc1(size_t size, // IN: int bugNumber, // IN: const char *file, // IN: int lineno) // IN: { void *result = malloc(size); if (result == NULL && size != 0) { UtilAllocationFailure1(bugNumber, file, lineno); } return result; } /* *----------------------------------------------------------------------------- * * UtilSafeRealloc0 -- * UtilSafeRealloc1 -- * Helper function for realloc * * Results: * Pointer to the dynamically allocated memory. * * Side effects: * May Panic if ran out of memory. * *----------------------------------------------------------------------------- */ void * UtilSafeRealloc0(void *ptr, // IN: size_t size) // IN: { void *result = realloc(ptr, size); if (result == NULL && size != 0) { UtilAllocationFailure0(); } return result; } void * UtilSafeRealloc1(void *ptr, // IN: size_t size, // IN: int bugNumber, // IN: const char *file, // IN: int lineno) // IN: { void *result = realloc(ptr, size); if (result == NULL && size != 0) { UtilAllocationFailure1(bugNumber, file, lineno); } return result; } /* *----------------------------------------------------------------------------- * * UtilSafeCalloc0 -- * UtilSafeCalloc1 -- * Helper function for calloc * * Results: * Pointer to the dynamically allocated memory. * * Side effects: * May Panic if ran out of memory. * *----------------------------------------------------------------------------- */ void * UtilSafeCalloc0(size_t nmemb, // IN: size_t size) // IN: { void *result = calloc(nmemb, size); if (result == NULL && nmemb != 0 && size != 0) { UtilAllocationFailure0(); } return result; } void * UtilSafeCalloc1(size_t nmemb, // IN: size_t size, // IN: int bugNumber, // IN: const char *file, // IN: int lineno) // IN: { void *result = calloc(nmemb, size); if (result == NULL && nmemb != 0 && size != 0) { UtilAllocationFailure1(bugNumber, file, lineno); } return result; } /* *----------------------------------------------------------------------------- * * Util_SafeStrdup -- * Helper function for strdup * * Results: * Pointer to the dynamically allocated, duplicate string * * Side effects: * May Panic if ran out of memory. * *----------------------------------------------------------------------------- */ char * UtilSafeStrdup0(const char *s) // IN: { char *result; if (s == NULL) { return NULL; } #if defined(_WIN32) if ((result = _strdup(s)) == NULL) { #else if ((result = strdup(s)) == NULL) { #endif UtilAllocationFailure0(); } return result; } char * UtilSafeStrdup1(const char *s, // IN: int bugNumber, // IN: const char *file, // IN: int lineno) // IN: { char *result; if (s == NULL) { return NULL; } #if defined(_WIN32) if ((result = _strdup(s)) == NULL) { #else if ((result = strdup(s)) == NULL) { #endif UtilAllocationFailure1(bugNumber, file, lineno); } return result; } /* *----------------------------------------------------------------------------- * * Util_SafeStrndup -- * * Returns a string consisting of first n characters of 's' if 's' has * length >= 'n', otherwise returns a string duplicate of 's'. * * Results: * Pointer to the duplicated string. * * Side effects: * May Panic if ran out of memory. * *----------------------------------------------------------------------------- */ char * UtilSafeStrndup0(const char *s, // IN: size_t n) // IN: { size_t size; char *copy; const char *null; size_t newSize; if (s == NULL) { return NULL; } null = memchr(s, '\0', n); size = null ? null - s : n; newSize = size + 1; if (newSize < size) { // Prevent integer overflow copy = NULL; } else { copy = malloc(newSize); } if (copy == NULL) { UtilAllocationFailure0(); } copy[size] = '\0'; return (char *) memcpy(copy, s, size); } char * UtilSafeStrndup1(const char *s, // IN: size_t n, // IN: int bugNumber, // IN: const char *file, // IN: int lineno) // IN: { size_t size; char *copy; const char *null; size_t newSize; if (s == NULL) { return NULL; } null = memchr(s, '\0', n); size = null ? null - s : n; newSize = size + 1; if (newSize < size) { // Prevent integer overflow copy = NULL; } else { copy = malloc(newSize); } if (copy == NULL) { UtilAllocationFailure1(bugNumber, file, lineno); } copy[size] = '\0'; return (char *) memcpy(copy, s, size); } void * Util_Memcpy(void *dest, const void *src, size_t count) { #if defined(__x86_64__) || defined(__i386__) uintptr_t align = ((uintptr_t)dest | (uintptr_t)src | count); #if defined __GNUC__ #if defined(__x86_64__) size_t dummy0; void *dummy1; void *dummy2; if ((align & 7) == 0) { __asm__ __volatile__("\t" "cld" "\n\t" "rep ; movsq" "\n" : "=c" (dummy0), "=D" (dummy1), "=S" (dummy2) : "0" (count >> 3), "1" (dest), "2" (src) : "memory", "cc" ); return dest; } else if ((align & 3) == 0) { __asm__ __volatile__("\t" "cld" "\n\t" "rep ; movsd" "\n" : "=c" (dummy0), "=D" (dummy1), "=S" (dummy2) : "0" (count >> 2), "1" (dest), "2" (src) : "memory", "cc" ); return dest; } #elif defined(__i386__) size_t dummy0; void *dummy1; void *dummy2; if ((align & 3) == 0) { __asm__ __volatile__("\t" "cld" "\n\t" "rep ; movsd" "\n" : "=c" (dummy0), "=D" (dummy1), "=S" (dummy2) : "0" (count >> 2), "1" (dest), "2" (src) : "memory", "cc" ); return dest; } #endif #elif defined _MSC_VER #if defined(__x86_64__) if ((align & 7) == 0) { __movsq((uint64 *)dest, (uint64 *)src, count >> 3); return dest; } else if ((align & 3) == 0) { __movsd((unsigned long *)dest, (unsigned long *)src, count >> 2); return dest; } #elif defined(__i386__) if ((((uintptr_t)dest | (uintptr_t)src | count) & 3) == 0) { __movsd((unsigned long *)dest, (unsigned long *)src, count >> 2); return dest; } #endif #endif #endif memcpy(dest, src, count); return dest; } open-vm-tools-9.4.0-1280544/lib/misc/atomic.c0000644765153500003110000000442512220061556016565 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * atomic.c -- * * Support for atomic instructions. * * This is the user-level version. * The monitor-only version is in vmcore/vmm/main. */ #include "vmware.h" #include "vm_atomic.h" #if defined(__i386__) || defined(__x86_64__) #include "x86cpuid.h" #include "x86cpuid_asm.h" #endif #include "vm_basic_asm.h" #include "vmk_exports.h" Bool AtomicUseFence; VMK_KERNEL_EXPORT(AtomicUseFence); Bool atomicFenceInitialized; /* *----------------------------------------------------------------------------- * * AtomicInitFence -- * * Compute AtomicUseFence. * * This version of fence initialization doesn't take into account * the number of CPUs. Code that cares uses Atomic_SetFence() directly. * See Atomic_Init in vm_atomic.h. * * This code is rather weird because while the logic belongs * in x86cpuid.h, it's almost impossible to put this whole function * there, so here it is. -- edward * * Results: * None. * * Side effects: * As described. * *----------------------------------------------------------------------------- */ void AtomicInitFence(void) { Bool needFence = FALSE; #if defined(__i386__) || defined(__x86_64__) { CPUIDRegs regs; __GET_CPUID(0, ®s); if (CPUID_ID0RequiresFence(®s)) { __GET_CPUID(1, ®s); if (CPUID_ID1RequiresFence(®s)) { needFence = TRUE; } } } #endif Atomic_SetFence(needFence); } open-vm-tools-9.4.0-1280544/lib/misc/hashTable.c0000644765153500003110000005775612220061556017223 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * hashTable.c -- * * An implementation of hashtable with no removals. * For string keys. */ #include #include #include #include #ifdef _WIN32 #include #endif #include "vmware.h" #include "hashTable.h" #include "vm_basic_asm.h" #include "util.h" #include "str.h" #include "vm_atomic.h" #define HASH_ROTATE 5 /* * Pointer to hash table entry * * The assumption is that Atomic_ReadPtr() and Atomic_WritePtr() * are cheap, so can be used with nonatomic hash tables. * SETENTRYATOMIC() sets a link to point to a new entry * if the current value is the same as the old entry. * It returns TRUE on success. */ typedef Atomic_Ptr HashTableLink; #define ENTRY(l) ((HashTableEntry *) Atomic_ReadPtr(&(l))) #define SETENTRY(l, e) Atomic_WritePtr(&(l), e) #ifdef NO_ATOMIC_HASHTABLE #define SETENTRYATOMIC(l, old, new) (Atomic_WritePtr(&(l), new), TRUE) #else #define SETENTRYATOMIC(l, old, new) \ (Atomic_ReadIfEqualWritePtr(&(l), old, new) == (old)) #endif /* * An entry in the hashtable. */ typedef struct HashTableEntry { HashTableLink next; const void *keyStr; Atomic_Ptr clientData; } HashTableEntry; /* * The hashtable structure. */ struct HashTable { uint32 numEntries; uint32 numBits; int keyType; Bool atomic; Bool copyKey; HashTableFreeEntryFn freeEntryFn; HashTableLink *buckets; size_t numElements; }; /* * Local functions */ static HashTableEntry *HashTableLookup(HashTable *ht, const void *keyStr, uint32 hash); HashTableEntry *HashTableLookupOrInsert(HashTable *ht, const void *keyStr, void *clientData); /* *----------------------------------------------------------------------------- * * HashTableComputeHash -- * * Compute hash value based on key type and hash size. * * Results: * The hash value. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE uint32 HashTableComputeHash(HashTable *ht, // IN: hash table const void *s) // IN: string to hash { uint32 h = 0; switch (ht->keyType) { case HASH_STRING_KEY: { int c; unsigned char *keyPtr = (unsigned char *) s; while ((c = *keyPtr++)) { h ^= c; h = h << HASH_ROTATE | h >> (32 - HASH_ROTATE); } } break; case HASH_ISTRING_KEY: { int c; unsigned char *keyPtr = (unsigned char *) s; while ((c = tolower(*keyPtr++))) { h ^= c; h = h << HASH_ROTATE | h >> (32 - HASH_ROTATE); } } break; case HASH_INT_KEY: ASSERT_ON_COMPILE(sizeof s == 4 || sizeof s == 8); if (sizeof s == 4) { h = (uint32) (uintptr_t) s; } else { h = (uint32) (uintptr_t) s ^ (uint32) ((uint64) (uintptr_t) s >> 32); } h *= 48271; // http://www.google.com/search?q=48271+pseudorandom break; default: NOT_REACHED(); } { int numBits = ht->numBits; uint32 mask = MASK(numBits); for (; h > mask; h = (h & mask) ^ (h >> numBits)) { } } ASSERT(h < ht->numEntries); return h; } /* *----------------------------------------------------------------------------- * * HashTableEqualKeys -- * * Compare two keys based on key type * * Results: * TRUE if keys are equal. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE Bool HashTableEqualKeys(HashTable *ht, // IN: hash table const void *key1, // IN: key const void *key2) // IN: key { switch (ht->keyType) { case HASH_STRING_KEY: return Str_Strcmp((const char *) key1, (const char *) key2) == 0; case HASH_ISTRING_KEY: return Str_Strcasecmp((const char *) key1, (const char *) key2) == 0; default: return key1 == key2; } } /* *---------------------------------------------------------------------- * * HashTable_Alloc -- * * Create a hash table. * * Results: * The new hashtable. * * Side effects: * None. * *---------------------------------------------------------------------- */ HashTable * HashTable_Alloc(uint32 numEntries, // IN: must be a power of 2 int keyType, // IN: whether keys are strings HashTableFreeEntryFn fn) // IN: free entry function { HashTable *ht; ASSERT(numEntries > 0); if ((numEntries & (numEntries - 1)) != 0) { Panic("%s only takes powers of 2 \n", __FUNCTION__); } #ifdef NO_ATOMIC_HASHTABLE ASSERT_NOT_IMPLEMENTED((keyType & HASH_FLAG_ATOMIC) == 0); #endif ASSERT((keyType & HASH_FLAG_COPYKEY) == 0 || ((keyType & HASH_TYPE_MASK) == HASH_STRING_KEY || (keyType & HASH_TYPE_MASK) == HASH_ISTRING_KEY)); ht = Util_SafeMalloc(sizeof *ht); ASSERT_MEM_ALLOC(ht); ht->numBits = lssb32_0(numEntries); ht->numEntries = numEntries; ht->keyType = keyType & HASH_TYPE_MASK; ht->atomic = (keyType & HASH_FLAG_ATOMIC) != 0; ht->copyKey = (keyType & HASH_FLAG_COPYKEY) != 0; ht->freeEntryFn = fn; ht->buckets = Util_SafeCalloc(ht->numEntries, sizeof *ht->buckets); ht->numElements = 0; #ifndef NO_ATOMIC_HASHTABLE if (ht->atomic) { Atomic_Init(); } #endif return ht; } /* *---------------------------------------------------------------------- * * HashTable_AllocOnce -- * * Create a hash table and store it in the supplied Atomic_Ptr, * unless it's already been created. * * Results: * The new (or existing) hashtable. * * Side effects: * None. * *---------------------------------------------------------------------- */ HashTable * HashTable_AllocOnce(Atomic_Ptr *var, // IN/OUT: the atomic var uint32 numEntries, // IN: must be a power of 2 int keyType, // IN: whether keys are strings HashTableFreeEntryFn fn) // IN: free entry function { HashTable *ht; if ((ht = Atomic_ReadPtr(var)) == NULL) { HashTable *new = HashTable_Alloc(numEntries, keyType, fn); #ifdef NO_ATOMIC_HASHTABLE Atomic_WritePtr(var, new); #else Atomic_Init(); ht = Atomic_ReadIfEqualWritePtr(var, NULL, new); #endif if (ht == NULL) { ht = new; } else { HashTable_FreeUnsafe(new); } } ASSERT(ht == Atomic_ReadPtr(var)); return ht; } /* *---------------------------------------------------------------------- * * HashTable_Clear -- * * Clear all entries a hashtable by freeing them. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void HashTableClearInternal(HashTable *ht) // IN/OUT: { int i; ht->numElements = 0; for (i = 0; i < ht->numEntries; i++) { HashTableEntry *entry; while ((entry = ENTRY(ht->buckets[i])) != NULL) { SETENTRY(ht->buckets[i], ENTRY(entry->next)); if (ht->copyKey) { free((void *) entry->keyStr); } if (ht->freeEntryFn) { ht->freeEntryFn(Atomic_ReadPtr(&entry->clientData)); } free(entry); } } } void HashTable_Clear(HashTable *ht) // IN/OUT: { ASSERT(ht); ASSERT(!ht->atomic); HashTableClearInternal(ht); } /* *---------------------------------------------------------------------- * * HashTable_Free -- * * Free the hash table skeleton. Do not call this if the hashTable is * atomic; use HashTable_FreeUnsafe and HEED THE RESTRICTIONS! * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void HashTable_Free(HashTable *ht) // IN/OUT: { ASSERT(ht); ASSERT(!ht->atomic); HashTableClearInternal(ht); free(ht->buckets); free(ht); } /* *---------------------------------------------------------------------- * * HashTable_FreeUnsafe -- * * HashTable_Free for atomic hash tables. Non-atomic hash tables * should always use HashTable_Free. The caller should make sure * no other thread may access the hash table when this is called. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void HashTable_FreeUnsafe(HashTable *ht) // IN/OUT: { ASSERT(ht); HashTableClearInternal(ht); free(ht->buckets); free(ht); } /* *---------------------------------------------------------------------- * * HashTableLookup -- * * Core of the lookup function. * * Results: * A pointer to the found HashTableEntry or NULL if not found * * Side effects: * None. * *---------------------------------------------------------------------- */ static HashTableEntry * HashTableLookup(HashTable *ht, // IN: const void *keyStr, // IN: uint32 hash) // IN: { HashTableEntry *entry; for (entry = ENTRY(ht->buckets[hash]); entry != NULL; entry = ENTRY(entry->next)) { if (HashTableEqualKeys(ht, entry->keyStr, keyStr)) { return entry; } } return NULL; } /* *---------------------------------------------------------------------- * * HashTable_Lookup -- * * Lookup an element in a hashtable. * * Results: * TRUE if the entry was found. (the clientData is set) * FALSE otherwise * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool HashTable_Lookup(HashTable *ht, // IN: const void *keyStr, // IN: void **clientData) // OUT: { uint32 hash = HashTableComputeHash(ht, keyStr); HashTableEntry *entry = HashTableLookup(ht, keyStr, hash); if (entry == NULL) { return FALSE; } if (clientData) { *clientData = Atomic_ReadPtr(&entry->clientData); } return TRUE; } /* *---------------------------------------------------------------------- * * HashTable_Delete -- * * Delete an element from the hashtable. * * Results: * TRUE if the entry was found and subsequently removed * FALSE otherwise * * Side effects: * See above * *---------------------------------------------------------------------- */ Bool HashTable_Delete(HashTable *ht, // IN/OUT: the hash table const void *keyStr) // IN: key for the element to remove { return HashTable_LookupAndDelete(ht, keyStr, NULL); } /* *---------------------------------------------------------------------- * * HashTable_LookupAndDelete -- * * Look up an element in the hash table, then delete it. * * If clientData is specified, then the entry data is returned, * and the free function is not called. * * Results: * TRUE if the entry was found and subsequently removed * FALSE otherwise * Entry value is returned in *clientData. * * Side effects: * See above * *---------------------------------------------------------------------- */ Bool HashTable_LookupAndDelete(HashTable *ht, // IN/OUT: the hash table const void *keyStr, // IN: key for the element void **clientData) // OUT: return data { uint32 hash = HashTableComputeHash(ht, keyStr); HashTableLink *linkp; HashTableEntry *entry; ASSERT(!ht->atomic); for (linkp = &ht->buckets[hash]; (entry = ENTRY(*linkp)) != NULL; linkp = &entry->next) { if (HashTableEqualKeys(ht, entry->keyStr, keyStr)) { SETENTRY(*linkp, ENTRY(entry->next)); ht->numElements--; if (ht->copyKey) { free((void *) entry->keyStr); } if (clientData != NULL) { *clientData = Atomic_ReadPtr(&entry->clientData); } else if (ht->freeEntryFn) { ht->freeEntryFn(Atomic_ReadPtr(&entry->clientData)); } free(entry); return TRUE; } } return FALSE; } /* *---------------------------------------------------------------------- * * HashTable_Insert -- * * Insert an element into the hashtable. * * Unless the hash table was created with HASH_FLAG_COPYKEY, * the string key is not duplicated and thus cannot be freed until * the entry is deleted or the hash table is cleared or freed. * * Results: * FALSE if item already exists. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool HashTable_Insert(HashTable *ht, // IN/OUT: const void *keyStr, // IN: void *clientData) // IN: { return HashTableLookupOrInsert(ht, keyStr, clientData) == NULL; } /* *---------------------------------------------------------------------- * * HashTable_LookupOrInsert -- * * Look up an a key, return the element if found. * Otherwise, insert it into the hashtable and return it. * * Unless the hash table was created with HASH_FLAG_COPYKEY, * the string key is not duplicated and thus cannot be freed until * the entry is deleted or the hash table is cleared or freed. * * Results: * Old element or new one. * * Side effects: * None. * *---------------------------------------------------------------------- */ void * HashTable_LookupOrInsert(HashTable *ht, // IN/OUT: const void *keyStr, // IN: void *clientData) // IN: { HashTableEntry *entry = HashTableLookupOrInsert(ht, keyStr, clientData); return entry == NULL ? clientData : Atomic_ReadPtr(&entry->clientData); } /* *---------------------------------------------------------------------- * * HashTable_ReplaceOrInsert -- * * Look up an a key. If found, replace the existing clientData * and return TRUE. * Otherwise, insert new entry and return FALSE. * * Unless the hash table was created with HASH_FLAG_COPYKEY, * the string key is not duplicated and thus cannot be freed until * the entry is deleted or the hash table is cleared or freed. * * Results: * TRUE if replaced, FALSE if inserted. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool HashTable_ReplaceOrInsert(HashTable *ht, // IN/OUT: const void *keyStr, // IN: void *clientData) // IN: { HashTableEntry *entry = HashTableLookupOrInsert(ht, keyStr, clientData); if (entry == NULL) { return FALSE; } #ifndef NO_ATOMIC_HASHTABLE if (ht->atomic && ht->freeEntryFn) { void *old = Atomic_ReadWritePtr(&entry->clientData, clientData); ht->freeEntryFn(old); } else #endif { if (ht->freeEntryFn) { ht->freeEntryFn(Atomic_ReadPtr(&entry->clientData)); } Atomic_WritePtr(&entry->clientData, clientData); } return TRUE; } /* *---------------------------------------------------------------------- * * HashTable_ReplaceIfEqual -- * * Look up an a key. If found, replace the existing clientData * if it is the same as oldClientData and return TRUE. * Return FALSE otherwise. * * Results: * TRUE if replaced, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool HashTable_ReplaceIfEqual(HashTable *ht, // IN/OUT: const void *keyStr, // IN: void *oldClientData, // IN: void *newClientData) // IN: { uint32 hash = HashTableComputeHash(ht, keyStr); HashTableEntry *entry = HashTableLookup(ht, keyStr, hash); Bool retval = FALSE; if (entry == NULL) { return FALSE; } #ifndef NO_ATOMIC_HASHTABLE if (ht->atomic) { void *data = Atomic_ReadIfEqualWritePtr(&entry->clientData, oldClientData, newClientData); if (data == oldClientData) { retval = TRUE; if (ht->freeEntryFn != NULL) { ht->freeEntryFn(data); } } } else #endif if (Atomic_ReadPtr(&entry->clientData) == oldClientData) { retval = TRUE; if (ht->freeEntryFn) { ht->freeEntryFn(Atomic_ReadPtr(&entry->clientData)); } Atomic_WritePtr(&entry->clientData, newClientData); } return retval; } /* *---------------------------------------------------------------------- * * HashTableLookupOrInsert -- * * Look up an a key, return the entry if found. * Otherwise, insert it into the hashtable and return NULL. * * Results: * Old HashTableEntry or NULL. * * Side effects: * None. * *---------------------------------------------------------------------- */ HashTableEntry * HashTableLookupOrInsert(HashTable *ht, // IN/OUT: const void *keyStr, // IN: void *clientData) // IN: { uint32 hash = HashTableComputeHash(ht, keyStr); HashTableEntry *entry = NULL; HashTableEntry *oldEntry = NULL; HashTableEntry *head; again: head = ENTRY(ht->buckets[hash]); oldEntry = HashTableLookup(ht, keyStr, hash); if (oldEntry != NULL) { if (entry != NULL) { if (ht->copyKey) { free((void *) entry->keyStr); } free(entry); } return oldEntry; } if (entry == NULL) { entry = Util_SafeMalloc(sizeof *entry); if (ht->copyKey) { entry->keyStr = Util_SafeStrdup(keyStr); } else { entry->keyStr = keyStr; } Atomic_WritePtr(&entry->clientData, clientData); } SETENTRY(entry->next, head); if (ht->atomic) { if (!SETENTRYATOMIC(ht->buckets[hash], head, entry)) { goto again; } } else { SETENTRY(ht->buckets[hash], entry); } ht->numElements++; return NULL; } /* *---------------------------------------------------------------------- * * HashTable_GetNumElements -- * * Get the number of elements in the hash table. * * Atomic hash tables do not support this function because * the numElements field is not modified atomically so may be * incorrect. * * Results: * The number of elements. * * Side effects: * None. * *---------------------------------------------------------------------- */ size_t HashTable_GetNumElements(const HashTable *ht) // IN: { ASSERT(ht); ASSERT(!ht->atomic); return ht->numElements; } /* *---------------------------------------------------------------------- * * HashTable_KeyArray -- * * Returns an array of pointers to each key in the hash table. * * Results: * The key array plus its size. If the hash table is empty * 'size' is 0 and 'keys' is NULL. Free 'keys' array with free(). Do *not* * free the individual elements of the array. * * Side effects: * None. * *---------------------------------------------------------------------- */ void HashTable_KeyArray(const HashTable *ht, // IN: const void ***keys, // OUT: size_t *size) // OUT: { uint32 i; size_t j; ASSERT(ht); ASSERT(keys); ASSERT(size); ASSERT(!ht->atomic); *keys = NULL; *size = HashTable_GetNumElements(ht); if (0 == *size) { return; } /* alloc array */ *keys = Util_SafeMalloc(*size * sizeof **keys); /* fill array */ for (i = 0, j = 0; i < ht->numEntries; i++) { HashTableEntry *entry; for (entry = ENTRY(ht->buckets[i]); entry != NULL; entry = ENTRY(entry->next)) { (*keys)[j++] = entry->keyStr; } } } /* *---------------------------------------------------------------------- * * HashTable_ToArray -- * * Returns an array of pointers to each clientData structure in the * hash table. * * Results: * The clientData array plus its size. If the hash table is empty * 'size' is 0 and 'clientDatas' is NULL. Free with free(). * * Side effects: * None. * *---------------------------------------------------------------------- */ void HashTable_ToArray(const HashTable *ht, // IN: void ***clientDatas, // OUT: size_t *size) // OUT: { uint32 i; size_t j; ASSERT(ht); ASSERT(clientDatas); ASSERT(size); ASSERT(!ht->atomic); *clientDatas = NULL; *size = HashTable_GetNumElements(ht); if (0 == *size) { return; } /* alloc array */ *clientDatas = Util_SafeMalloc(*size * sizeof **clientDatas); /* fill array */ for (i = 0, j = 0; i < ht->numEntries; i++) { HashTableEntry *entry; for (entry = ENTRY(ht->buckets[i]); entry != NULL; entry = ENTRY(entry->next)) { (*clientDatas)[j++] = Atomic_ReadPtr(&entry->clientData); } } } /* *---------------------------------------------------------------------- * * HashTable_ForEach -- * * Walks the hashtable in an undetermined order, calling the * callback function for each value until either the callback * returns a non-zero value or all values have been walked * * Results: * 0 if all callback functions returned 0, otherwise the return * value of the first non-zero callback. * * Side effects: * None. * *---------------------------------------------------------------------- */ int HashTable_ForEach(const HashTable *ht, // IN: HashTableForEachCallback cb, // IN: void *clientData) // IN: { int i; ASSERT(ht); ASSERT(cb); for (i = 0; i < ht->numEntries; i++) { HashTableEntry *entry; for (entry = ENTRY(ht->buckets[i]); entry != NULL; entry = ENTRY(entry->next)) { int result = (*cb)(entry->keyStr, Atomic_ReadPtr(&entry->clientData), clientData); if (result) { return result; } } } return 0; } #if 0 /* *---------------------------------------------------------------------- * * HashPrint -- * * Print out the contents of a hashtable. Useful for * debugging the data structure & the hashing algorithm. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void HashPrint(HashTable *ht) // IN { int i; for (i = 0; i < ht->numEntries; i++) { HashTableEntry *entry; if (ht->buckets[i] == NULL) { continue; } printf("%4d: \n", i); for (entry = ENTRY(ht->buckets[i]); entry != NULL; entry = ENTRY(entry->next)) { if (ht->keyType == HASH_INT_KEY) { printf("\t%p\n", entry->keyStr); } else { printf("\t%s\n", entry->keyStr); } } } } #endif open-vm-tools-9.4.0-1280544/lib/misc/timeutil.c0000644765153500003110000011535412220061556017151 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * timeutil.c -- * * Miscellaneous time related utility functions. */ #include "safetime.h" #include "unicode.h" #if defined(_WIN32) # include #else # include #endif #include #include "vmware.h" /* For HARD_EXPIRE --hpreg */ #include "vm_version.h" #include "vm_basic_asm.h" #include "timeutil.h" #include "str.h" #include "util.h" #ifdef _WIN32 #include "win32u.h" #endif /* * NT time of the Unix epoch: * midnight January 1, 1970 UTC */ #define UNIX_EPOCH ((((uint64)369 * 365) + 89) * 24 * 3600 * 10000000) /* * NT time of the Unix 32 bit signed time_t wraparound: * 03:14:07 January 19, 2038 UTC */ #define UNIX_S32_MAX (UNIX_EPOCH + (uint64)0x80000000 * 10000000) /* * Local Definitions */ static void TimeUtilInit(TimeUtil_Date *d); static Bool TimeUtilLoadDate(TimeUtil_Date *d, const char *date); static const unsigned int *TimeUtilMonthDaysForYear(unsigned int year); static Bool TimeUtilIsValidDate(unsigned int year, unsigned int month, unsigned int day); /* * Function to guess Windows TZ Index and Name by using time offset in * a lookup table */ static int TimeUtilFindIndexAndNameByUTCOffset(int utcStdOffMins, const char **ptzName); #if defined(_WIN32) /* * Function to find Windows TZ Index by scanning registry */ static int Win32TimeUtilLookupZoneIndex(const char* targetName); #endif /* *---------------------------------------------------------------------- * * TimeUtil_MakeTime -- * * Converts a TimeUtil_Date to a time_t. * * Results: * A time_t. * * Side effects: * None. * *---------------------------------------------------------------------- */ time_t TimeUtil_MakeTime(const TimeUtil_Date *d) // IN { struct tm t; ASSERT(d != NULL); memset(&t, 0, sizeof t); t.tm_mday = d->day; t.tm_mon = d->month - 1; t.tm_year = d->year - 1900; t.tm_sec = d->second; t.tm_min = d->minute; t.tm_hour = d->hour; t.tm_isdst = -1; /* Unknown. */ return mktime(&t); } /* *---------------------------------------------------------------------- * * TimeUtil_StringToDate -- * * Initialize the date object with value from the string argument, * while the time will be left unmodified. * The string 'date' needs to be in the format of 'YYYYMMDD' or * 'YYYY/MM/DD' or 'YYYY-MM-DD'. * Unsuccesful initialization will leave the 'd' argument unmodified. * * Results: * TRUE or FALSE. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool TimeUtil_StringToDate(TimeUtil_Date *d, // IN/OUT char const *date) // IN { /* * Reduce the string to a known and handled format: YYYYMMDD. * Then, passed to internal function TimeUtilLoadDate. */ if (strlen(date) == 8) { /* 'YYYYMMDD' */ return TimeUtilLoadDate(d, date); } else if (strlen(date) == 10) { /* 'YYYY/MM/DD' */ char temp[16] = { 0 }; if (!(((date[4] != '/') || (date[7] != '/')) || ((date[4] != '-') || (date[7] != '-')))) { return FALSE; } Str_Strcpy(temp, date, sizeof(temp)); temp[4] = date[5]; temp[5] = date[6]; temp[6] = date[8]; temp[7] = date[9]; temp[8] = '\0'; return TimeUtilLoadDate(d, temp); } else { return FALSE; } } /* *---------------------------------------------------------------------- * * TimeUtil_DeltaDays -- * * Calculate the number of days between the two date arguments. * This function ignores the time. It will be as if the time * is midnight (00:00:00). * * Results: * number of days: * - 0 (if 'left' and 'right' are of the same date (ignoring the time). * - negative, if 'left' is of a later date than 'right' * - positive, if 'right' is of a later date than 'left' * * Side effects: * None. * *---------------------------------------------------------------------- */ int TimeUtil_DeltaDays(TimeUtil_Date const *left, // IN TimeUtil_Date const *right) // IN { TimeUtil_Date temp1; TimeUtil_Date temp2; TimeUtil_Date temp; int days = 0; Bool inverted = FALSE; ASSERT(left); ASSERT(right); ASSERT(TimeUtilIsValidDate(left->year, left->month, left->day)); ASSERT(TimeUtilIsValidDate(right->year, right->month, right->day)); TimeUtilInit(&temp1); TimeUtilInit(&temp2); TimeUtilInit(&temp); temp1.year = left->year; temp1.month = left->month; temp1.day = left->day; temp2.year = right->year; temp2.month = right->month; temp2.day = right->day; if (!TimeUtil_DateLowerThan(&temp1, &temp2) && !TimeUtil_DateLowerThan(&temp2, &temp1)) { return 0; } else if (TimeUtil_DateLowerThan(&temp1, &temp2)) { inverted = FALSE; } else if (TimeUtil_DateLowerThan(&temp2, &temp1)) { inverted = TRUE; temp = temp1; temp1 = temp2; temp2 = temp; } days = 1; TimeUtil_DaysAdd(&temp1, 1); while (TimeUtil_DateLowerThan(&temp1, &temp2)) { days++; TimeUtil_DaysAdd(&temp1, 1); } if (inverted) { return -days; } else { return days; } } /* *---------------------------------------------------------------------- * * TimeUtil_DaysSubtract -- * * Subtracts 'nr' days from 'd'. * * Simple algorithm - which can be improved as necessary: * - get rough days estimation, also guarantee that the estimation is * lower than the actual result. * - 'add' a day-by-day to arrive at actual result. * 'd' will be unchanged if the function failed. * * TODO: * This function can be combined with DaysAdd(), where it * accepts integer (positive for addition, negative for subtraction). * But, that cannot be done without changing the DaysAdd function * signature. * When this utility get rewritten, this can be updated. * * Results: * TRUE or FALSE. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool TimeUtil_DaysSubtract(TimeUtil_Date *d, // IN/OUT unsigned int nr) // IN { TimeUtil_Date temp; int subYear = 0; int subMonth = 0; int subDay = 0; TimeUtil_Date estRes; int estYear = 0; int estMonth = 0; int estDay = 0; unsigned int dayCount = nr; ASSERT(d); TimeUtilInit(&temp); TimeUtilInit(&estRes); /* * Use lower bound for the following conversion: * 365 (instead of 366) days in a year * 30 (instead of 31) days in a month. * * To account for February having fewer than 30 days, we will * intentionally subtract an additional 2 days for each year * and an additional 3 days. */ dayCount = dayCount + 3 + 2 * (dayCount / 365); subYear = dayCount / 365; dayCount = dayCount % 365; subMonth = dayCount / 30; subDay = dayCount % 30; estDay = d->day - subDay; while (estDay <= 0) { estDay = estDay + 30; subMonth++; } estMonth = d->month - subMonth; while (estMonth <= 0) { estMonth = estMonth + 12; subYear++; } estYear = d->year - subYear; if (estYear <= 0) { return FALSE; } /* * making sure on the valid range, without checking * for leap year, etc. */ if ((estDay > 28) && (estMonth == 2)) { estDay = 28; } estRes.year = estYear; estRes.month = estMonth; estRes.day = estDay; /* * we also copy the time from the original argument in making * sure that it does not play role in the comparison. */ estRes.hour = d->hour; estRes.minute = d->minute; estRes.second = d->second; /* * At this point, we should have an estimated result which * guaranteed to be lower than the actual result. Otherwise, * infinite loop will happen. */ ASSERT(TimeUtil_DateLowerThan(&estRes, d)); /* * Perform the actual precise adjustment * Done by moving up (moving forward) the estimated a day at a time * until they are the correct one (i.e. estDate + arg #day = arg date) */ temp = estRes; TimeUtil_DaysAdd(&temp, nr); while (TimeUtil_DateLowerThan(&temp, d)) { TimeUtil_DaysAdd(&temp, 1); TimeUtil_DaysAdd(&estRes, 1); } d->year = estRes.year; d->month = estRes.month; d->day = estRes.day; return TRUE; } /* *---------------------------------------------------------------------- * * TimeUtil_DaysAdd -- * * Add 'nr' days to a date. * This function can be optimized a lot if needed. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ void TimeUtil_DaysAdd(TimeUtil_Date *d, // IN/OUT unsigned int nr) // IN { const unsigned int *monthDays; unsigned int i; /* * Initialize the table */ monthDays = TimeUtilMonthDaysForYear(d->year); for (i = 0; i < nr; i++) { /* * Add 1 day to the date */ d->day++; if (d->day > monthDays[d->month]) { d->day = 1; d->month++; if (d->month > 12) { d->month = 1; d->year++; /* * Update the table */ monthDays = TimeUtilMonthDaysForYear(d->year); } } } } /* *---------------------------------------------------------------------- * * TimeUtil_PopulateWithCurrent -- * * Populate the given date object with the current date and time. * * If 'local' is TRUE, the time will be expressed in the local time * zone. Otherwise, the time will be expressed in UTC. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ void TimeUtil_PopulateWithCurrent(Bool local, // IN TimeUtil_Date *d) // OUT { #ifdef _WIN32 SYSTEMTIME currentTime; ASSERT(d); if (local) { GetLocalTime(¤tTime); } else { GetSystemTime(¤tTime); } d->year = currentTime.wYear; d->month = currentTime.wMonth; d->day = currentTime.wDay; d->hour = currentTime.wHour; d->minute = currentTime.wMinute; d->second = currentTime.wSecond; #else struct tm *currentTime; struct tm tmbuf; time_t utcTime; ASSERT(d); utcTime = time(NULL); if (local) { currentTime = localtime_r(&utcTime, &tmbuf); } else { currentTime = gmtime_r(&utcTime, &tmbuf); } ASSERT_NOT_IMPLEMENTED(currentTime); d->year = 1900 + currentTime->tm_year; d->month = currentTime->tm_mon + 1; d->day = currentTime->tm_mday; d->hour = currentTime->tm_hour; d->minute = currentTime->tm_min; d->second = currentTime->tm_sec; #endif // _WIN32 } /* *----------------------------------------------------------------------------- * * TimeUtil_GetTimeOfDay -- * * Get the current time for local timezone in seconds and micro-seconds. * same as gettimeofday on posix systems. Time is returned in the 'time' * variable. * * Results: * void * * Side effects: * None. * *----------------------------------------------------------------------------- */ void TimeUtil_GetTimeOfDay(TimeUtil_TimeOfDay *timeofday) { #ifdef _WIN32 FILETIME ft; uint64 tmptime = 0; ASSERT(timeofday != NULL); /* * May need to use QueryPerformanceCounter API if we need more * refinement/accuracy than what we are doing below. */ // Get the system time in UTC format. GetSystemTimeAsFileTime(&ft); // Convert ft structure to a uint64 containing the # of 100 ns from UTC. tmptime |= ft.dwHighDateTime; tmptime <<= 32; tmptime |= ft.dwLowDateTime; #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL // Convert file time to unix epoch. tmptime -= DELTA_EPOCH_IN_MICROSECS; // convert into microseconds (since the return is in 100 nseconds). tmptime /= 10; // Get the seconds and microseconds in the timeofday timeofday->seconds = (unsigned long)(tmptime / 1000000UL); timeofday->useconds = (unsigned long)(tmptime % 1000000UL); #undef DELTA_EPOCH_IN_MICROSECS #else struct timeval curTime; ASSERT(timeofday != NULL); gettimeofday(&curTime, NULL); timeofday->seconds = (unsigned long) curTime.tv_sec; timeofday->useconds = (unsigned long) curTime.tv_usec; #endif // _WIN32 } /* *---------------------------------------------------------------------- * * TimeUtil_DaysLeft -- * * Computes the number of days left before a given date * * Results: * 0: the given date is in the past * 1 to MAX_DAYSLEFT: if there are 1 to MAX_DAYSLEFT days left * MAX_DAYSLEFT+1 if there are more than MAX_DAYSLEFT days left * * Side effects: * None * *---------------------------------------------------------------------- */ unsigned int TimeUtil_DaysLeft(TimeUtil_Date const *d) // IN { TimeUtil_Date c; unsigned int i; /* Get the current local date. */ TimeUtil_PopulateWithCurrent(TRUE, &c); /* * Compute how many days we can add to the current date before reaching * the given date */ for (i = 0; i < MAX_DAYSLEFT + 1; i++) { if ((c.year > d->year) || (c.year == d->year && c.month > d->month) || (c.year == d->year && c.month == d->month && c.day >= d->day)) { /* current date >= given date */ return i; } TimeUtil_DaysAdd(&c, 1); } /* There are at least MAX_DAYSLEFT+1 days left */ return MAX_DAYSLEFT + 1; } /* *---------------------------------------------------------------------- * * TimeUtil_ExpirationLowerThan -- * * Determine if 'left' is lower than 'right' * * Results: * TRUE if yes * FALSE if no * * Side effects: * None * *---------------------------------------------------------------------- */ Bool TimeUtil_ExpirationLowerThan(TimeUtil_Expiration const *left, // IN TimeUtil_Expiration const *right) // IN { if (left->expires == FALSE) { return FALSE; } if (right->expires == FALSE) { return TRUE; } if (left->when.year < right->when.year) { return TRUE; } if (left->when.year > right->when.year) { return FALSE; } if (left->when.month < right->when.month) { return TRUE; } if (left->when.month > right->when.month) { return FALSE; } if (left->when.day < right->when.day) { return TRUE; } return FALSE; } /* *---------------------------------------------------------------------- * * TimeUtil_DateLowerThan -- * * Determine if 'left' is lower than 'right' * * Results: * TRUE if yes * FALSE if no * * Side effects: * None * *---------------------------------------------------------------------- */ Bool TimeUtil_DateLowerThan(TimeUtil_Date const *left, // IN TimeUtil_Date const *right) // IN { ASSERT(left); ASSERT(right); if (left->year < right->year) { return TRUE; } if (left->year > right->year) { return FALSE; } if (left->month < right->month) { return TRUE; } if (left->month > right->month) { return FALSE; } if (left->day < right->day) { return TRUE; } if (left->day > right->day) { return FALSE; } if (left->hour < right->hour) { return TRUE; } if (left->hour > right->hour) { return FALSE; } if (left->minute < right->minute) { return TRUE; } if (left->minute > right->minute) { return FALSE; } if (left->second < right->second) { return TRUE; } return FALSE; } /* *---------------------------------------------------------------------- * * TimeUtil_ProductExpiration -- * * Retrieve the expiration information associated to the product in 'e' * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ void TimeUtil_ProductExpiration(TimeUtil_Expiration *e) // OUT { /* * The hard_expire string is used by post-build processing scripts to * determine if a build is set to expire or not. */ #ifdef HARD_EXPIRE static char *hard_expire = "Expire"; (void)hard_expire; ASSERT(e); e->expires = TRUE; /* * Decode the hard-coded product expiration date. */ e->when.day = HARD_EXPIRE; e->when.year = e->when.day / ((DATE_MONTH_MAX + 1) * (DATE_DAY_MAX + 1)); e->when.day -= e->when.year * ((DATE_MONTH_MAX + 1) * (DATE_DAY_MAX + 1)); e->when.month = e->when.day / (DATE_DAY_MAX + 1); e->when.day -= e->when.month * (DATE_DAY_MAX + 1); e->daysLeft = TimeUtil_DaysLeft(&e->when); #else static char *hard_expire = "No Expire"; (void)hard_expire; ASSERT(e); e->expires = FALSE; #endif } /* *---------------------------------------------------------------------- * * TimeUtil_GetTimeFormat -- * * Converts a UTC time value to a human-readable string. * * Results: * Returns the a formatted string of the given UTC time. It is the * caller's responsibility to free this string. May return NULL. * * If Win32, the time will be formatted according to the current * locale. * * Side effects: * None * *---------------------------------------------------------------------- */ char * TimeUtil_GetTimeFormat(int64 utcTime, // IN Bool showDate, // IN Bool showTime) // IN { #ifdef _WIN32 SYSTEMTIME systemTime = { 0 }; char dateStr[100] = ""; char timeStr[100] = ""; if (!showDate && !showTime) { return NULL; } if (!TimeUtil_UTCTimeToSystemTime((const __time64_t) utcTime, &systemTime)) { return NULL; } Win32U_GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systemTime, NULL, dateStr, ARRAYSIZE(dateStr)); Win32U_GetTimeFormat(LOCALE_USER_DEFAULT, 0, &systemTime, NULL, timeStr, ARRAYSIZE(timeStr)); if (showDate && showTime) { return Str_Asprintf(NULL, "%s %s", dateStr, timeStr); } else { return Str_Asprintf(NULL, "%s", showDate ? dateStr : timeStr); } #else /* * On 32-bit systems the assignment of utcTime to time_t below will truncate * in the year 2038. Ignore it; there's nothing we can do. */ char *str; char buf[26]; const time_t t = (time_t) utcTime; // Implicit narrowing on 32-bit #if defined sun str = Util_SafeStrdup(ctime_r(&t, buf, sizeof buf)); #else str = Util_SafeStrdup(ctime_r(&t, buf)); #endif str[strlen(str) - 1] = '\0'; // Remove the trailing '\n'. return str; #endif // _WIN32 } /* *----------------------------------------------------------------------------- * * TimeUtil_NtTimeToUnixTime -- * * Convert from Windows NT time to Unix time. If NT time is outside of * Unix time range (1970-2038), returned time is nearest time valid in * Unix. * * Results: * 0 on success * non-zero if NT time is outside of valid range for UNIX * * Side effects: * None * *----------------------------------------------------------------------------- */ int TimeUtil_NtTimeToUnixTime(struct timespec *unixTime, // OUT: Time in Unix format VmTimeType ntTime) // IN: Time in Windows NT format { #ifndef VM_X86_64 ASSERT(unixTime); /* We assume that time_t is 32bit */ ASSERT(sizeof (unixTime->tv_sec) == 4); /* Cap NT time values that are outside of Unix time's range */ if (ntTime >= UNIX_S32_MAX) { unixTime->tv_sec = 0x7FFFFFFF; unixTime->tv_nsec = 0; return 1; } #else ASSERT(unixTime); #endif // VM_X86_64 if (ntTime < UNIX_EPOCH) { unixTime->tv_sec = 0; unixTime->tv_nsec = 0; return -1; } #ifdef __i386__ // only for 32-bit x86 { uint32 sec; uint32 nsec; Div643232(ntTime - UNIX_EPOCH, 10000000, &sec, &nsec); unixTime->tv_sec = sec; unixTime->tv_nsec = nsec * 100; } #else unixTime->tv_sec = (ntTime - UNIX_EPOCH) / 10000000; unixTime->tv_nsec = ((ntTime - UNIX_EPOCH) % 10000000) * 100; #endif // __i386__ return 0; } /* *----------------------------------------------------------------------------- * * TimeUtil_UnixTimeToNtTime -- * * Convert from Unix time to Windows NT time. * * Results: * The time in Windows NT format. * * Side effects: * None * *----------------------------------------------------------------------------- */ VmTimeType TimeUtil_UnixTimeToNtTime(struct timespec unixTime) // IN: Time in Unix format { return (VmTimeType)unixTime.tv_sec * 10000000 + unixTime.tv_nsec / 100 + UNIX_EPOCH; } #ifdef _WIN32 /* *---------------------------------------------------------------------- * * TimeUtil_UTCTimeToSystemTime -- * * Converts the time from UTC time to SYSTEMTIME * * Results: * TRUE if the time was converted successfully, FALSE otherwise. * * Side effects: * None * *---------------------------------------------------------------------- */ Bool TimeUtil_UTCTimeToSystemTime(const __time64_t utcTime, // IN SYSTEMTIME *systemTime) // OUT { int atmYear; int atmMonth; struct tm *atm; /* * _localtime64 support years up through 3000. At least it says * so. I'm getting garbage only after reaching year 4408. */ if (utcTime < 0 || utcTime > (60LL * 60 * 24 * 365 * (3000 - 1970))) { return FALSE; } atm = _localtime64(&utcTime); if (atm == NULL) { return FALSE; } atmYear = atm->tm_year + 1900; atmMonth = atm->tm_mon + 1; /* * Windows's SYSTEMTIME documentation says that these are limits... * Main reason for this test is to cut out negative values _localtime64 * likes to return for some inputs. */ if (atmYear < 1601 || atmYear > 30827 || atmMonth < 1 || atmMonth > 12 || atm->tm_wday < 0 || atm->tm_wday > 6 || atm->tm_mday < 1 || atm->tm_mday > 31 || atm->tm_hour < 0 || atm->tm_hour > 23 || atm->tm_min < 0 || atm->tm_min > 59 || /* Allow leap second, just in case... */ atm->tm_sec < 0 || atm->tm_sec > 60) { return FALSE; } systemTime->wYear = (WORD) atmYear; systemTime->wMonth = (WORD) atmMonth; systemTime->wDayOfWeek = (WORD) atm->tm_wday; systemTime->wDay = (WORD) atm->tm_mday; systemTime->wHour = (WORD) atm->tm_hour; systemTime->wMinute = (WORD) atm->tm_min; systemTime->wSecond = (WORD) atm->tm_sec; systemTime->wMilliseconds = 0; return TRUE; } #endif // _WIN32 /* *---------------------------------------------------------------------- * * TimeUtil_GetLocalWindowsTimeZoneIndexAndName -- * * Gets Windows TZ Index and Name for local time zone. * * Results: * -1 if there is any error, else the Windows Time Zone ID of the * current timezone (non-negative value). * * Side effects: * On non-Win32 platforms, calls localtime_r() which sets globals * variables (e.g. 'timezone' and 'tzname' for Linux) * *---------------------------------------------------------------------- */ int TimeUtil_GetLocalWindowsTimeZoneIndexAndName(char **ptzName) // OUT: returning TZ Name { int utcStdOffMins = 0; int winTimeZoneIndex = (-1); const char *tzNameByUTCOffset = NULL; *ptzName = NULL; #if defined(_WIN32) { TIME_ZONE_INFORMATION tz; if (GetTimeZoneInformation(&tz) == TIME_ZONE_ID_INVALID) { return (-1); } /* 'Bias' = diff between UTC and local standard time */ utcStdOffMins = 0 - tz.Bias; // already in minutes /* Find Windows TZ index */ *ptzName = Unicode_AllocWithUTF16(tz.StandardName); winTimeZoneIndex = Win32TimeUtilLookupZoneIndex(*ptzName); if (winTimeZoneIndex < 0) { Unicode_Free(*ptzName); *ptzName = NULL; } } #else // NOT _WIN32 { /* * Use localtime_r() to get offset between our local * time and UTC. This varies by platform. Also, the structure * fields are named "*gmt*" but the man pages claim offsets are * to UTC, not GMT. */ time_t now = time(NULL); struct tm tim; localtime_r(&now, &tim); #if defined(sun) /* * Offset is to standard (no need for DST adjustment). * Negative is east of prime meridian. */ utcStdOffMins = 0 - timezone/60; #else /* * FreeBSD, Apple, Linux only: * Offset is to local (need to adjust for DST). * Negative is west of prime meridian. */ utcStdOffMins = tim.tm_gmtoff/60; if (tim.tm_isdst) { utcStdOffMins -= 60; } #endif /* can't figure this out directly for non-Win32 */ winTimeZoneIndex = (-1); } #endif /* If we don't have it yet, look up windowsCode. */ if (winTimeZoneIndex < 0) { winTimeZoneIndex = TimeUtilFindIndexAndNameByUTCOffset(utcStdOffMins, &tzNameByUTCOffset); if (winTimeZoneIndex >= 0) { *ptzName = Unicode_AllocWithUTF8(tzNameByUTCOffset); } } return winTimeZoneIndex; } /* *********************************************************************** * * Local Functions * *********************************************************************** */ /* *---------------------------------------------------------------------- * * TimeUtilInit -- * * Initialize everything to zero * * Results: * None * * Side effects: * None. * *---------------------------------------------------------------------- */ static void TimeUtilInit(TimeUtil_Date *d) { ASSERT(d); d->year = 0; d->month = 0; d->day = 0; d->hour = 0; d->minute = 0; d->second = 0; return; } /* *---------------------------------------------------------------------- * * TimeUtilIsValidDate -- * * Check whether the args represent a valid date. * * Results: * TRUE or FALSE. * * Side effects: * None. * *---------------------------------------------------------------------- */ static Bool TimeUtilIsValidDate(unsigned int year, // IN unsigned int month, // IN unsigned int day) // IN { const unsigned int *monthDays; /* * Initialize the table */ monthDays = TimeUtilMonthDaysForYear(year); if ((year >= 1) && (month >= 1) && (month <= 12) && (day >= 1) && (day <= monthDays[month])) { return TRUE; } return FALSE; } /* *---------------------------------------------------------------------- * * TimeUtilMonthDaysForYear -- * * Return an array of days in months depending on whether the * argument represents a leap year. * * Results: * A pointer to an array of 13 ints representing the days in the * 12 months. There are 13 entries because month is 1-12. * * Side effects: * None. * *---------------------------------------------------------------------- */ static unsigned int const * TimeUtilMonthDaysForYear(unsigned int year) // IN { static const unsigned int leap[13] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; static const unsigned int common[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; return ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0)) ? leap : common; } /* *---------------------------------------------------------------------- * * TimeUtilLoadDate -- * * Initialize the date object with value from the string argument, * while the time will be left unmodified. * The string 'date' needs to be in the format of 'YYYYMMDD'. * Unsuccesful initialization will leave the 'd' argument unmodified. * * Results: * TRUE or FALSE. * * Side effects: * None. * *---------------------------------------------------------------------- */ static Bool TimeUtilLoadDate(TimeUtil_Date *d, // IN/OUT const char *date) // IN { char temp[16] = { 0 }; int i = 0; char *end = NULL; int32 year = 0; int32 month = 0; int32 day = 0; ASSERT(d); ASSERT(date); if (strlen(date) != 8) { return FALSE; } for (i = 0; i < strlen(date); i++) { if (isdigit((int) date[i]) == 0) { return FALSE; } } temp[0] = date[0]; temp[1] = date[1]; temp[2] = date[2]; temp[3] = date[3]; temp[4] = '\0'; year = strtol(temp, &end, 10); if (*end != '\0') { return FALSE; } temp[0] = date[4]; temp[1] = date[5]; temp[2] = '\0'; month = strtol(temp, &end, 10); if (*end != '\0') { return FALSE; } temp[0] = date[6]; temp[1] = date[7]; temp[2] = '\0'; day = strtol(temp, &end, 10); if (*end != '\0') { return FALSE; } if (!TimeUtilIsValidDate((unsigned int) year, (unsigned int) month, (unsigned int) day)) { return FALSE; } d->year = (unsigned int) year; d->month = (unsigned int) month; d->day = (unsigned int) day; return TRUE; } /* *---------------------------------------------------------------------- * * TimeUtilFindIndexAndNameByUTCOffset -- * * Private function. Scans a table for a given UTC-to-Standard * offset and returns the Windows TZ Index of the first match * found together with its Windows TZ Name. * * Results: * Returns Windows TZ Index (>=0) if found, else -1. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int TimeUtilFindIndexAndNameByUTCOffset(int utcStdOffMins, // IN: offset (in minutes) const char **ptzName) // OUT: returning TZ Name { static struct _tzinfo { int winTzIndex; char winTzName[256]; int utcStdOffMins; } TABLE[] = { /* * These values are from Microsoft's TimeZone documentation: * * http://technet.microsoft.com/en-us/library/cc749073.aspx */ { 0, "Dateline Standard Time", -720 }, // -12 { 1, "Samoa Standard Time", -660 }, // -11 { 2, "Hawaiian Standard Time", -600 }, // -10 { 3, "Alaskan Standard Time", -540 }, // -9 { 4, "Pacific Standard Time", -480 }, // -8 { 10, "Mountain Standard Time", -420 }, // -7 { 13, "Mountain Standard Time (Mexico)", -420 }, // -7 { 15, "US Mountain Standard Time", -420 }, // -7 { 20, "Central Standard Time", -360 }, // -6 { 25, "Canada Central Standard Time", -360 }, // -6 { 30, "Central Standard Time (Mexico)", -360 }, // -6 { 33, "Central America Standard Time", -360 }, // -6 { 35, "Eastern Standard Time", -300 }, // -5 { 40, "US Eastern Standard Time", -300 }, // -5 { 45, "SA Pacific Standard Time", -300 }, // -5 { 50, "Atlantic Standard Time", -240 }, // -4 { 55, "SA Western Standard Time", -240 }, // -4 { 56, "Pacific SA Standard Time", -240 }, // -4 { 60, "Newfoundland Standard Time", -210 }, // -3.5 { 65, "E. South America Standard Time", -180 }, // -3 { 70, "SA Eastern Standard Time", -180 }, // -3 { 73, "Greenland Standard Time", -180 }, // -3 { 75, "Mid-Atlantic Standard Time", -120 }, // -2 { 80, "Azores Standard Time", -60 }, // -1 { 83, "Cape Verde Standard Time", -60 }, // -1 { 85, "GMT Standard Time", 0 }, // 0 { 90, "Greenwich Standard Time", 0 }, // 0 { 110, "W. Europe Standard Time", 60 }, // +1 { 95, "Central Europe Standard Time", 60 }, // +1 { 100, "Central European Standard Time", 60 }, // +1 { 105, "Romance Standard Time", 60 }, // +1 { 113, "W. Central Africa Standard Time", 60 }, // +1 { 115, "E. Europe Standard Time", 120 }, // +2 { 120, "Egypt Standard Time", 120 }, // +2 { 125, "FLE Standard Time", 120 }, // +2 { 130, "GTB Standard Time", 120 }, // +2 { 135, "Israel Standard Time", 120 }, // +2 { 140, "South Africa Standard Time", 120 }, // +2 { 145, "Russian Standard Time", 180 }, // +3 { 150, "Arab Standard Time", 180 }, // +3 { 155, "E. Africa Standard Time", 180 }, // +3 { 158, "Arabic Standard Time", 180 }, // +3 { 160, "Iran Standard Time", 210 }, // +3.5 { 165, "Arabian Standard Time", 240 }, // +4 { 170, "Caucasus Standard Time", 240 }, // +4 { 175, "Afghanistan Standard Time", 270 }, // +4.5 { 180, "Ekaterinburg Standard Time", 300 }, // +5 { 185, "West Asia Standard Time", 300 }, // +5 { 190, "India Standard Time", 330 }, // +5.5 { 193, "Nepal Standard Time", 345 }, // +5.75 { 195, "Central Asia Standard Time", 360 }, // +6 { 200, "Sri Lanka Standard Time", 360 }, // +6 { 201, "N. Central Asia Standard Time", 360 }, // +6 { 203, "Myanmar Standard Time", 390 }, // +6.5 { 205, "SE Asia Standard Time", 420 }, // +7 { 207, "North Asia Standard Time", 420 }, // +7 { 210, "China Standard Time", 480 }, // +8 { 215, "Singapore Standard Time", 480 }, // +8 { 220, "Taipei Standard Time", 480 }, // +8 { 225, "W. Australia Standard Time", 480 }, // +8 { 227, "North Asia East Standard Time", 480 }, // +8 { 230, "Korea Standard Time", 540 }, // +9 { 235, "Tokyo Standard Time", 540 }, // +9 { 240, "Yakutsk Standard Time", 540 }, // +9 { 245, "AUS Central Standard Time", 570 }, // +9.5 { 250, "Cen. Australia Standard Time", 570 }, // +9.5 { 255, "AUS Eastern Standard Time", 600 }, // +10 { 260, "E. Australia Standard Time", 600 }, // +10 { 265, "Tasmania Standard Time", 600 }, // +10 { 270, "Vladivostok Standard Time", 600 }, // +10 { 275, "West Pacific Standard Time", 600 }, // +10 { 280, "Central Pacific Standard Time", 660 }, // +11 { 285, "Fiji Standard Time", 720 }, // +12 { 290, "New Zealand Standard Time", 720 }, // +12 { 300, "Tonga Standard Time", 780 }};// +13 size_t tableSize = ARRAYSIZE(TABLE); size_t look; int tzIndex = (-1); *ptzName = NULL; /* XXX Finds the first match, not necessariy the right match! */ for (look = 0; look < tableSize; look++) { if (TABLE[look].utcStdOffMins == utcStdOffMins) { tzIndex = TABLE[look].winTzIndex; *ptzName = TABLE[look].winTzName; break; } } return tzIndex; } #ifdef _WIN32 /* *---------------------------------------------------------------------- * * Win32TimeUtilLookupZoneIndex -- * * Private function. Gets current Std time zone name using Windows * API, then scans the registry to find the information about that zone, * and extracts the TZ Index. * * Parameters: * targetName Standard-time zone name to look for. * * Results: * Returns Windows TZ Index (>=0) if found. * Returns -1 if not found or if any error was encountered. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int Win32TimeUtilLookupZoneIndex(const char* targetName) { int timeZoneIndex = (-1); HKEY parentKey, childKey; char childKeyName[255]; int keyIndex, childKeyLen=255; DWORD rv; /* Open parent key containing timezone child keys */ if (Win32U_RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\" "Microsoft\\" "Windows NT\\" "CurrentVersion\\" "Time Zones", 0, KEY_READ, &parentKey) != ERROR_SUCCESS) { /* Failed to open registry */ return (-1); } /* Scan child keys, stopping if name is found */ keyIndex = 0; while ( timeZoneIndex < 0 && Win32U_RegEnumKeyEx(parentKey, keyIndex, childKeyName, &childKeyLen, 0,0,0,0) == ERROR_SUCCESS) { char *std; DWORD stdSize; /* Open child key */ rv = Win32U_RegOpenKeyEx(parentKey, childKeyName, 0, KEY_READ, &childKey); if (rv != ERROR_SUCCESS) { continue; } /* Get size of "Std" value */ if (Win32U_RegQueryValueEx(childKey, "Std", 0, 0, NULL, &stdSize) == ERROR_SUCCESS) { /* Get value of "Std" */ std = (char*) calloc(stdSize+1, sizeof(char)); if (std != NULL) { if (Win32U_RegQueryValueEx(childKey, "Std", 0, 0, (LPBYTE) std, &stdSize) == ERROR_SUCCESS) { /* Make sure there is at least one EOS */ std[stdSize] = '\0'; /* Is this the name we want? */ if (!strcmp(std, targetName)) { /* yes: look up value of "Index" */ DWORD val = 0; DWORD valSize = sizeof(val); if (Win32U_RegQueryValueEx(childKey, "Index", 0, 0, (LPBYTE) &val, &valSize) == ERROR_SUCCESS) { timeZoneIndex = val; } } } free(std); } } /* close this child key */ RegCloseKey(childKey); /* reset for next child key */ childKeyLen = 255; keyIndex++; } /* Close registry parent key */ RegCloseKey(parentKey); return timeZoneIndex; } #endif // _WIN32 open-vm-tools-9.4.0-1280544/lib/misc/codesetBase.c0000644765153500003110000002064712220061556017536 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * codesetBase.c -- * * Character set and encoding conversion functions, without ICU. */ #include #include "vmware.h" #include "codeset.h" #include "codesetOld.h" #include "util.h" /* *----------------------------------------------------------------------------- * * CodeSet_GetCurrentCodeSet -- * * Return native code set name. Always calls down to * CodeSetOld_GetCurrentCodeSet. See there for more details. * * Results: * See CodeSetOld_GetCurrentCodeSet. * * Side effects: * See CodeSetOld_GetCurrentCodeSet. * *----------------------------------------------------------------------------- */ const char * CodeSet_GetCurrentCodeSet(void) { return CodeSetOld_GetCurrentCodeSet(); } /* *----------------------------------------------------------------------------- * * CodeSet_GetUtf8 -- * * Parse the next UTF-8 sequence. * * Results: * 0 on failure. * Length of sequence and Unicode character in *uchar on success. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int CodeSet_GetUtf8(const char *string, // IN: string const char *end, // IN: end of string uint32 *uchar) // OUT: the Unicode character { uint8 *p = (uint8 *) string; uint8 *e; uint32 c; int len; ASSERT(string < end); c = *p; if (c < 0x80) { // ASCII: U+0000 - U+007F: 1 byte of UTF-8. len = 1; goto out; } if ((c < 0xc2) || (c > 0xf4)) { // 0x81 to 0xbf are not valid first bytes // 0xc0 and 0xc1 cannot appear in UTF-8, see below // leading char can not be > 0xf4, illegal as well return 0; } if (c < 0xe0) { // U+0080 - U+07FF: 2 bytes of UTF-8. c -= 0xc0; len = 2; } else if (c < 0xf0) { // U+0800 - U+FFFF: 3 bytes of UTF-8. c -= 0xe0; len = 3; } else { // U+10000 - U+10FFFF: 4 bytes of UTF-8. c -= 0xf0; len = 4; } if ((e = p + len) > (uint8 *) end) { // input too short return 0; } while (++p < e) { if ((*p & 0xc0) != 0x80) { // bad trailing byte return 0; } c <<= 6; c += *p - 0x80; } /* * Enforce shortest encoding. * UTF-8 mandates that shortest possible encoding is used, * as otherwise doing UTF-8 => anything => UTF-8 could bypass some * important tests, like '/' for path separator or \0 for string * termination. * * This test does not work for len == 2, but that case is handled * by requiring the first byte to be 0xc2 or greater (see above). */ if (c < 1U << (len * 5 - 4)) { return 0; } out: if (uchar != NULL) { *uchar = c; } return len; } /* *----------------------------------------------------------------------------- * * CodeSet_LengthInCodePoints -- * * Return the length of a UTF8 string in code points (the number of * unicode characters present in the string, not the length of the * string in bytes). * * Like strlen, the length returned does not include the terminating NUL. * * Results: * -1 on error * * Side effects: * None * *----------------------------------------------------------------------------- */ int CodeSet_LengthInCodePoints(const char *utf8) // IN: { char *p; char *end; uint32 codePoints = 0; ASSERT(utf8); p = (char *) utf8; end = p + strlen(utf8); while (p < end) { uint32 utf32; uint32 len = CodeSet_GetUtf8(p, end, &utf32); if (len == 0) { return -1; } p += len; codePoints++; } return codePoints; } /* *----------------------------------------------------------------------------- * * CodeSet_UTF8ToUTF32 -- * * Convert a UTF8 string into a UTF32 string. The result is returned as a * dynamically allocated string that the caller is responsible for. * * Results: * TRUE Input string was valid, converted string in *utf32 * FALSE Input string was invalid or internal error * * Side effects: * Allocates memory * *----------------------------------------------------------------------------- */ Bool CodeSet_UTF8ToUTF32(const char *utf8, // IN: char **utf32) // OUT: { char *p; char *end; uint32 *ptr; int codePoints; ASSERT(utf32); if (utf8 == NULL) { // NULL is not an error *utf32 = NULL; return TRUE; } codePoints = CodeSet_LengthInCodePoints(utf8); if (codePoints == -1) { *utf32 = NULL; return FALSE; } p = (char *) utf8; end = p + strlen(utf8); ptr = Util_SafeMalloc(sizeof(*ptr) * (codePoints + 1)); *utf32 = (char *) ptr; while (p < end) { p += CodeSet_GetUtf8(p, end, ptr++); } *ptr = 0; return TRUE; } /* *----------------------------------------------------------------------------- * * CodeSet_UTF32ToUTF8 -- * * Convert a UTF32 string into a UTF8 string. The result is returned as a * dynamically allocated string that the caller is responsible for. * * Results: * TRUE Input string was valid, converted string in *utf8 * FALSE Input string was invalid or internal error * * Side effects: * Allocates memory * *----------------------------------------------------------------------------- */ Bool CodeSet_UTF32ToUTF8(const char *utf32, // IN: char **utf8) // OUT: { uint32 i; uint8 *p; uint8 *q; uint32 len; union { uint32 word; uint8 bytes[4]; } value; ASSERT(utf8); if (utf32 == NULL) { // NULL is not an error *utf8 = NULL; return TRUE; } /* * Determine the length of the UTF32 string. A UTF32 string terminates * with four (4) bytes of zero (0). */ len = 0; p = (uint8 *) utf32; while (TRUE) { value.bytes[0] = *p++; value.bytes[1] = *p++; value.bytes[2] = *p++; value.bytes[3] = *p++; if (value.word == 0) { break; } len++; } /* * Now that we know the length, allocate the memory for the UTF8 string. * The UTF8 string length calculation ensures that there will always be * sufficient space to represent the UTF32 string. Most of the time this * will involved allocating too much memory however the memory wastage * will be very short lived and very small. */ *utf8 = Util_SafeMalloc((4 * len) + 1); // cover the NUL byte /* * Process the UTF32 string, converting each code point into its * UTF8 equivalent. */ p = (uint8 *) utf32; q = (uint8 *) *utf8; for (i = 0; i < len; i++) { value.bytes[0] = *p++; value.bytes[1] = *p++; value.bytes[2] = *p++; value.bytes[3] = *p++; if (value.word < 0x80) { // One byte case (ASCII) *q++ = value.word; } else if (value.word < 0x800) { // Two byte case *q++ = 0xC0 | (value.word >> 6); *q++ = 0x80 | (value.word & 0x3F); } else if (value.word < 0x10000) { // Three byte case *q++ = 0xE0 | (value.word >> 12); *q++ = 0x80 | ((value.word >> 6) & 0x3F); *q++ = 0x80 | (value.word & 0x3F); } else if (value.word < 0x110000) { // Four byte case *q++ = 0xF0 | (value.word >> 18); *q++ = 0x80 | ((value.word >> 12) & 0x3F); *q++ = 0x80 | ((value.word >> 6) & 0x3F); *q++ = 0x80 | (value.word & 0x3F); } else { // INVALID VALUE! free(*utf8); *utf8 = NULL; return FALSE; } } *q = '\0'; return TRUE; } open-vm-tools-9.4.0-1280544/lib/misc/random.c0000644765153500003110000002034712220061556016572 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * random.c -- * * Random bits generation. --hpreg */ #include #include #include #if defined(_WIN32) # include # include #else # include # include # include # define GENERIC_RANDOM_DEVICE "/dev/urandom" #endif #include "vmware.h" #include "random.h" #include "util.h" #if defined(_WIN32) /* *----------------------------------------------------------------------------- * * RandomBytesWin32 -- * * Generate 'size' bytes of cryptographically strong random bits in * 'buffer'. * * Results: * TRUE success * FALSE failure * *----------------------------------------------------------------------------- */ static Bool RandomBytesWin32(size_t size, // IN: void *buffer) // OUT: { HCRYPTPROV csp; if (size != (DWORD) size) { return FALSE; } if (CryptAcquireContext(&csp, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) == FALSE) { return FALSE; } if (CryptGenRandom(csp, (DWORD) size, buffer) == FALSE) { CryptReleaseContext(csp, 0); return FALSE; } if (CryptReleaseContext(csp, 0) == FALSE) { return FALSE; } return TRUE; } #else /* *----------------------------------------------------------------------------- * * RandomBytesPosix -- * * Generate 'size' bytes of cryptographically strong random bits in * 'buffer'. * * Results: * TRUE success * FALSE failure * *----------------------------------------------------------------------------- */ static Bool RandomBytesPosix(const char *name, // IN: size_t size, // IN: void *buffer) // OUT: { int fd = open(name, O_RDONLY); if (fd == -1) { Log("%s: failed to open %s: %s\n", __FUNCTION__, name, strerror(errno)); return FALSE; } /* * Although /dev/urandom does not block, it can return short reads. That * said, reads returning nothing should not happen. Just in case, track * those any that do appear. */ while (size > 0) { ssize_t bytesRead = read(fd, buffer, size); if ((bytesRead == 0) || ((bytesRead == -1) && (errno != EINTR))) { close(fd); if (bytesRead == 0) { Log("%s: zero length read while reading from %s\n", __FUNCTION__, name); } else { Log("%s: %"FMTSZ"u byte read failed while reading from %s: %s\n", __FUNCTION__, size, name, strerror(errno)); } return FALSE; } if (bytesRead > 0) { size -= bytesRead; buffer = ((uint8 *) buffer) + bytesRead; } } if (close(fd) == -1) { Log("%s: failed to close %s: %s\n", __FUNCTION__, name, strerror(errno)); } return TRUE; } #endif /* *----------------------------------------------------------------------------- * * Random_Crypto -- * * Generate 'size' bytes of cryptographically strong random bits in * 'buffer'. Use this function when you need non-predictable random * bits, typically in security applications, where the bits are generated * external to the application. * * DO NOT USE THIS FUNCTION UNLESS YOU HAVE AN ABSOLUTE, EXPLICIT * NEED FOR CRYPTOGRAPHICALLY VALID RANDOM NUMBERS. * * Results: * TRUE success * FALSE failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool Random_Crypto(size_t size, // IN: void *buffer) // OUT: { #if defined(_WIN32) return RandomBytesWin32(size, buffer); #else /* * We use /dev/urandom and not /dev/random because it is good enough and * because it cannot block. --hpreg */ return RandomBytesPosix(GENERIC_RANDOM_DEVICE, size, buffer); #endif } /* *----------------------------------------------------------------------------- * * Random_QuickSeed -- * * Creates a context for the quick random number generator and returns it. * * Results: * A pointer to the context used for the random number generator. The * context is dynamically allocated memory that must be freed by caller. * * Side Effects: * None * * NOTE: * Despite the look of the code this RNG is extremely fast. * *----------------------------------------------------------------------------- */ #define N 25 #define M 18 #define A 0x8EBFD028 #define S 7 #define B 0x2B5B2500 #define T 15 #define C 0xDB8B0000 #define L 16 struct rqContext { uint32 x[N]; int p, q; }; rqContext * Random_QuickSeed(uint32 seed) // IN: { struct rqContext *rs; const uint32 xx[N] = { 0x95F24DAB, 0x0B685215, 0xE76CCAE7, 0xAF3EC239, 0x715FAD23, 0x24A590AD, 0x69E4B5EF, 0xBF456141, 0x96BC1B7B, 0xA7BDF825, 0xC1DE75B7, 0x8858A9C9, 0x2DA87693, 0xB657F9DD, 0xFFDC8A9F, 0x8121DA71, 0x8B823ECB, 0x885D05F5, 0x4E20CD47, 0x5A9AD5D9, 0x512C0C03, 0xEA857CCD, 0x4CC1D30F, 0x8891A8A1, 0xA6B7AADB }; rs = (struct rqContext *) Util_SafeMalloc(sizeof *rs); if (rs != NULL) { uint32 i; for (i = 0; i < N; i++) { rs->x[i] = xx[i] ^ seed; } rs->p = N - 1; rs->q = N - M - 1; } return rs; } /* *----------------------------------------------------------------------------- * * Random_Quick -- * * Return uniformly distributed pseudo-random numbers in the range of 0 * and 2^32-1 using the (research grade) tGFSR algorithm tt800. The period * of this RNG is 2^(32*N) - 1 while generally having lower overhead than * Random_Crypto(). * * Results: * A random number in the specified range is returned. * * Side Effects: * The RNG context is modified for later use by Random_Quick. * * NOTE: * Despite the look of the code this RNG is extremely fast. * *----------------------------------------------------------------------------- */ uint32 Random_Quick(rqContext *rs) // IN/OUT: { uint32 y, z; ASSERT(rs); if (rs->p == N - 1) { rs->p = 0; } else { (rs->p)++; } if (rs->q == N - 1) { rs->q = 0; } else { (rs->q)++; } z = rs->x[(rs->p)]; y = rs->x[(rs->q)] ^ ( z >> 1 ); if (z % 2) { y ^= A; } if (rs->p == N - 1) { rs->x[0] = y; } else { rs->x[(rs->p) + 1] = y; } y ^= ( ( y << S ) & B ); y ^= ( ( y << T ) & C ); y ^= ( y >> L ); // improves bits return y; } /* *---------------------------------------------------------------------- * * Random_Simple -- * * Generates the next random number in the pseudo-random sequence * defined by the multiplicative linear congruential generator * S' = 33614 * S mod (2^31 - 1). This is the ACM "minimal standard * random number generator". Based on method described by D.G. Carta * in CACM, January 1990. * * Usage: provide previous random number as the seed for next one. * * Results: * A random integer number is returned. * * Side Effects: * None. * *---------------------------------------------------------------------- */ int Random_Simple(int seed) // IN: { uint64 product = 33614 * (uint64) seed; uint32 product_lo = (uint32) (product & 0xFFFFFFFF) >> 1; uint32 product_hi = product >> 32; int32 test = product_lo + product_hi; return test > 0 ? test : (test & 0x7FFFFFFF) + 1; } open-vm-tools-9.4.0-1280544/lib/misc/idLinux.c0000644765153500003110000005600412220061556016725 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * idLinux.c -- * * uid/gid helpers. */ #include #include #include #include #include #ifdef __APPLE__ #include #include #if !defined TARGET_OS_IPHONE #define TARGET_OS_IPHONE 0 #endif #if !TARGET_OS_IPHONE #include #include #endif #endif #if defined __ANDROID__ #include #endif #include "vmware.h" #include "su.h" #include "vm_atomic.h" #if defined(__linux__) /* * 64bit linux has no 16 bit versions and * the 32bit versions have the un-suffixed names. * And obviously, we're not using glibc 2.0 * for our 64bit builds! */ #ifdef VM_X86_64 #define SYS_setreuid32 (abort(), 0) #define SYS_setregid32 (abort(), 0) #define SYS_setresuid32 (abort(), 0) #define SYS_setresgid32 (abort(), 0) #define SYS_setuid32 (abort(), 0) #define SYS_setgid32 (abort(), 0) #endif /* * On 32bit systems: * Set to 1 when system supports 32bit uids, cleared to 0 when system * supports 16bit calls only. By default we assume that 32bit uids * are supported and clear this flag on first failure. * * On 64bit systems: * Only the 32bit uid syscalls exist, but they do not have the names * with the '32' suffix, so we get the behaviour we want by forcing * the code to use the unsuffixed syscalls. */ #ifdef VM_X86_64 static int uid32 = 0; #else static int uid32 = 1; #endif #endif // __linux__ #if defined(__APPLE__) && !TARGET_OS_IPHONE #include static AuthorizationRef IdAuthCreate(void); static AuthorizationRef IdAuthCreateWithFork(void); #endif #if !defined(__APPLE__) /* *---------------------------------------------------------------------------- * * Id_SetUid -- * * If calling thread has euid = 0, it sets real, effective and saved uid * to the specified value. * If calling thread has euid != 0, then only effective uid is set. * * Results: * 0 on success, -1 on failure, errno set * * Side effects: * errno may be modified on success * *---------------------------------------------------------------------------- */ int Id_SetUid(uid_t euid) // IN: new euid { #if defined(__FreeBSD__) || defined(sun) return setuid(euid); #elif defined(linux) || defined __ANDROID__ if (uid32) { int r = syscall(SYS_setuid32, euid); if (r != -1 || errno != ENOSYS) { return r; } uid32 = 0; } return syscall(SYS_setuid, euid); #else # error "Id_SetUid is not implemented for this platform" #endif } #endif /* *---------------------------------------------------------------------------- * * Id_SetGid -- * * If calling thread has euid = 0, it sets real, effective and saved gid * to the specified value. * If calling thread has euid != 0, then only effective gid is set. * * Results: * 0 on success, -1 on failure, errno set * * Side effects: * errno may be modified on success * *---------------------------------------------------------------------------- */ int Id_SetGid(gid_t egid) // IN: new egid { #if defined(__APPLE__) Warning("XXXMACOS: implement %s\n", __func__); return -1; #elif defined(sun) || defined(__FreeBSD__) return setgid(egid); #else if (uid32) { int r = syscall(SYS_setgid32, egid); if (r != -1 || errno != ENOSYS) { return r; } uid32 = 0; } return syscall(SYS_setgid, egid); #endif } /* *---------------------------------------------------------------------------- * * Id_SetRESUid -- * * Sets uid, euid and saved uid to the specified values. You can use -1 * for values which should not change. * * Results: * 0 on success, -1 on failure, errno set * * Side effects: * errno may be modified on success * *---------------------------------------------------------------------------- */ int Id_SetRESUid(uid_t uid, // IN: new uid uid_t euid, // IN: new effective uid uid_t suid) // IN: new saved uid { #if (defined(__FreeBSD__) && __FreeBSD_version >= 500043) return setresuid(uid, euid, suid); #elif defined(linux) if (uid32) { int r = syscall(SYS_setresuid32, uid, euid, suid); if (r != -1 || errno != ENOSYS) { return r; } uid32 = 0; } return syscall(SYS_setresuid, uid, euid, suid); #else Warning("XXX: implement %s\n", __func__); return -1; #endif } #if !defined(__APPLE__) /* *---------------------------------------------------------------------------- * * Id_SetRESGid -- * * Sets gid, egid and saved gid to the specified values. You can use -1 * for values which should not change. * * Results: * 0 on success, -1 on failure, errno set * * Side effects: * errno may be modified on success * *---------------------------------------------------------------------------- */ int Id_SetRESGid(gid_t gid, // IN: new gid gid_t egid, // IN: new effective gid gid_t sgid) // IN: new saved gid { #if (defined(__FreeBSD__) && __FreeBSD_version >= 500043) return setresgid(gid, egid, sgid); #elif defined(linux) if (uid32) { int r = syscall(SYS_setresgid32, gid, egid, sgid); if (r != -1 || errno != ENOSYS) { return r; } uid32 = 0; } return syscall(SYS_setresgid, gid, egid, sgid); #else Warning("XXX: implement %s\n", __func__); return -1; #endif } #endif /* *---------------------------------------------------------------------------- * * Id_SetREUid -- * * Sets uid and euid to the specified values. You can use -1 * for values which should not change. If you are changing uid, * or if you are changing euid to value which differs from old uid, * then saved uid is updated to new euid value. * * Results: * 0 on success, -1 on failure, errno set * * Side effects: * errno may be modified on success * *---------------------------------------------------------------------------- */ int Id_SetREUid(uid_t uid, // IN: new uid uid_t euid) // IN: new effective uid { #if defined(__APPLE__) Warning("XXXMACOS: implement %s\n", __func__); return -1; #elif defined(sun) || defined(__FreeBSD__) return setreuid(uid, euid); #else if (uid32) { int r = syscall(SYS_setreuid32, uid, euid); if (r != -1 || errno != ENOSYS) { return r; } uid32 = 0; } return syscall(SYS_setreuid, uid, euid); #endif } #if !defined(__APPLE__) /* *---------------------------------------------------------------------------- * * Id_SetREGid -- * * Sets gid and egid to the specified values. You can use -1 * for values which should not change. If you are changing gid, * or if you are changing egid to value which differs from old gid, * then saved gid is updated to new egid value. * * Results: * 0 on success, -1 on failure, errno set * * Side effects: * errno may be modified on success * *---------------------------------------------------------------------------- */ int Id_SetREGid(gid_t gid, // IN: new gid gid_t egid) // IN: new effective gid { #if defined(sun) || defined(__FreeBSD__) return setregid(gid, egid); #else if (uid32) { int r = syscall(SYS_setregid32, gid, egid); if (r != -1 || errno != ENOSYS) { return r; } uid32 = 0; } return syscall(SYS_setregid, gid, egid); #endif } #endif #if defined(__APPLE__) && !TARGET_OS_IPHONE /* *---------------------------------------------------------------------------- * * IdAuthCreate -- * * Create an Authorization session. * * An Authorization session remembers which process name and which * credentials created it, and how much time has elapsed since it last * prompted the user at the console to authenticate to grant the * Authorization session a specific right. * * Results: * On success: A ref to the Authorization session. * On failure: NULL. * * Side effects: * See IdAuthCreateWithFork. * *---------------------------------------------------------------------------- */ static AuthorizationRef IdAuthCreate(void) { /* * Bug 195868: If thread credentials are in use, we need to fork. * Otherwise, avoid forking, as it breaks Apple's detection of * whether the calling process is a GUI process. * * This is needed because AuthorizationRefs created by GUI * processes can be passed to non-GUI processes to allow them to * prompt for authentication with a dialog that automatically * steals focus from the current GUI app. (This is how the Mac UI * and VMX work today.) * * TODO: How should we handle single-threaded apps where uid != * euid or gid != egid? Some callers may expect us to check * against euid, others may expect us to check against uid. */ uid_t thread_uid; gid_t thread_gid; int ret; ret = syscall(SYS_gettid, &thread_uid, &thread_gid); if (ret != -1) { /* * We have per-thread UIDs in use, so Apple's authorization * APIs don't work. Fork so we can use them. */ return IdAuthCreateWithFork(); } else { if (errno != ESRCH) { Warning("%s: gettid failed, error %d.\n", __func__, errno); return NULL; } else { // Per-thread identities are not in use in this thread. AuthorizationRef auth; OSStatus ret; ret = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &auth); if (ret == errAuthorizationSuccess) { return auth; } else { ASSERT_ON_COMPILE(sizeof ret == sizeof (int32)); Warning("%s: AuthorizationCreate failed, error %d.\n", __func__, (int32)ret); return NULL; } } } } /* *---------------------------------------------------------------------------- * * IdAuthCreateWithFork -- * * Create an Authorization session. * * An Authorization session remembers which process name and which * credentials created it, and how much time has elapsed since it last * prompted the user at the console to authenticate to grant the * Authorization session a specific right. * * Results: * On success: A ref to the Authorization session. * On failure: NULL. * * Side effects: * The current process is forked. * *---------------------------------------------------------------------------- */ static AuthorizationRef IdAuthCreateWithFork(void) { int fds[2] = { -1, -1, }; pid_t child; AuthorizationRef auth = NULL; struct { Bool success; AuthorizationExternalForm ext; } data; uint8 buf; /* * XXX One more Apple bug related to thread credentials: * AuthorizationCreate() incorrectly uses process instead of thread * credentials. So for this code to properly work in the VMX for * example, we must do this elaborate fork/handshake dance. Fortunately * this function is only called once very early when a process starts. */ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) { Warning("%s: socketpair() failed.\n", __func__); goto out; } child = fork(); if (child < 0) { Warning("%s: fork() failed.\n", __func__); goto out; } if (child) { size_t rcvd; int status; pid_t result; // Parent: use fds[0] // Wait until the child has created its process ref to the auth session. for (rcvd = 0; rcvd < sizeof data; ) { ssize_t actual; actual = read(fds[0], (void *)&data + rcvd, sizeof data - rcvd); ASSERT(actual <= sizeof data - rcvd); if (actual < 0) { ASSERT(errno == EPIPE); Warning("%s: parent read() failed because child died.\n", __func__); data.success = FALSE; break; } rcvd += actual; } if (data.success) { if (AuthorizationCreateFromExternalForm(&data.ext, &auth) != errAuthorizationSuccess) { Warning("%s: parent AuthorizationCreateFromExternalForm() " "failed.\n", __func__); } } // Tell the child it can now destroy its process ref to the auth session. write(fds[0], &buf, sizeof buf); // Reap the child, looping if we get interrupted by a signal. do { result = waitpid(child, &status, 0); } while (result == -1 && errno == EINTR); ASSERT_NOT_IMPLEMENTED(result == child); } else { // Child: use fds[1] data.success = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &auth) == errAuthorizationSuccess; if (data.success) { data.success = AuthorizationMakeExternalForm(auth, &data.ext) == errAuthorizationSuccess; if (!data.success) { Warning("%s: child AuthorizationMakeExternalForm() failed.\n", __func__); } } else { Warning("%s: child AuthorizationCreate() failed.\n", __func__); } // Tell the parent it can now create a process ref to the auth session. if (write(fds[1], &data, sizeof data) == sizeof data) { /* * Wait until the child can destroy its process ref to the auth * session. */ for (;;) { ssize_t actual = read(fds[1], &buf, sizeof buf); ASSERT(actual <= sizeof buf); if (actual) { break; } } } /* * This implicitly: * o Destroys the child process ref to the Authorization session. * o Closes fds[0] and fds[1] */ exit(0); } out: close(fds[0]); close(fds[1]); return auth; } static Atomic_Ptr procAuth = { 0 }; /* *---------------------------------------------------------------------------- * * IdAuthGet -- * * Get a ref to the process' Authorization session. * * Results: * On success: The ref. * On failure: NULL. * * Side effects: * If the process' Authorization session does not exist yet, it is * created. * *---------------------------------------------------------------------------- */ static AuthorizationRef IdAuthGet(void) { if (UNLIKELY(Atomic_ReadPtr(&procAuth) == NULL)) { AuthorizationRef newProcAuth = IdAuthCreate(); if (Atomic_ReadIfEqualWritePtr(&procAuth, NULL, newProcAuth)) { // Someone else snuck in before we did. Free the new authorization. AuthorizationFree(newProcAuth, kAuthorizationFlagDefaults); } } ASSERT(Atomic_ReadPtr(&procAuth) != NULL); return Atomic_ReadPtr(&procAuth); } /* *---------------------------------------------------------------------------- * * Id_AuthGetLocal -- * * Get a local ref to the process' Authorization session. * * Results: * On success: The ref. * On failure: NULL. * * Side effects: * If the process' Authorization session does not exist yet, it is * created. * *---------------------------------------------------------------------------- */ void * Id_AuthGetLocal(void) { return (void *)IdAuthGet(); } /* *---------------------------------------------------------------------------- * * Id_AuthGetExternal -- * * Get a cross-process ref to the process' Authorization session. * * Results: * On success: An allocated cross-process ref. * On failure: NULL. * * Side effects: * None * *---------------------------------------------------------------------------- */ void * Id_AuthGetExternal(size_t *size) // OUT { AuthorizationRef auth; AuthorizationExternalForm *ext; auth = IdAuthGet(); if (!auth) { return NULL; } ext = malloc(sizeof *ext); if (!ext) { Warning("Unable to allocate an AuthorizationExternalForm.\n"); return NULL; } if (AuthorizationMakeExternalForm(auth, ext) != errAuthorizationSuccess) { Warning("AuthorizationMakeExternalForm() failed.\n"); free(ext); return NULL; } *size = sizeof *ext; return ext; } /* *---------------------------------------------------------------------------- * * Id_AuthSet -- * * Set the process' Authorization session to the Authorization session * referred to by a cross-process ref. * * Results: * On success: TRUE. * On failure: FALSE. * * Side effects: * None * *---------------------------------------------------------------------------- */ Bool Id_AuthSet(void const *buf, // IN size_t size) // IN { AuthorizationRef newProcAuth; AuthorizationExternalForm const *ext = (AuthorizationExternalForm const *)buf; if (!buf || size != sizeof *ext) { Warning("%s: Invalid argument.\n", __func__); return FALSE; } ASSERT(!Atomic_ReadPtr(&procAuth)); if (AuthorizationCreateFromExternalForm(ext, &newProcAuth) != errAuthorizationSuccess) { Warning("AuthorizationCreateFromExternalForm failed.\n"); return FALSE; } if (Atomic_ReadIfEqualWritePtr(&procAuth, NULL, newProcAuth)) { /* * This is meant to be called very early on in the life of the * process. If someone else has snuck in an authorization, * we're toast. */ NOT_IMPLEMENTED(); } return TRUE; } /* *---------------------------------------------------------------------------- * * Id_AuthCheck -- * * Check if 'right' is granted to the process' Authorization * session, using the specified localized UTF-8 description as * the prompt if it's non-NULL. * * Results: * TRUE if the right was granted, FALSE if the user cancelled, * entered the wrong password three times in a row, or if an * error was encountered, or if the Authorization session is * invalid or has not been granted the 'right'. * * Side effects: * If showDialogIfNeeded is set and the specified Authorization session * does not have the required privilege, displays a dialog to the user. * The dialog grabs keyboard focus if Id_AuthSet() was previously called * with a cross-process ref to a GUI process. * *---------------------------------------------------------------------------- */ Bool Id_AuthCheck(char const *right, // IN char const *localizedDescription, // IN: UTF-8 Bool showDialogIfNeeded) // IN { AuthorizationRef auth; AuthorizationItem rightsItems[1] = { { 0 } }; AuthorizationRights rights; AuthorizationItem environmentItems[1] = { { 0 } }; AuthorizationEnvironment environmentWithDescription = { 0 }; const AuthorizationEnvironment *environment = kAuthorizationEmptyEnvironment; auth = IdAuthGet(); if (!auth) { return FALSE; } rightsItems[0].name = right; rights.items = rightsItems; rights.count = ARRAYSIZE(rightsItems); /* * By default, the API displays a dialog saying "APPLICATIONNAME * requires that you type your password" (if you're an admin; the * message is different if you're not). * * If the localized description is present, the API uses that * description and appends a space followed by the above string. */ if (localizedDescription) { environmentItems[0].name = kAuthorizationEnvironmentPrompt; environmentItems[0].valueLength = strlen(localizedDescription); environmentItems[0].value = (void *)localizedDescription; environmentWithDescription.items = environmentItems; environmentWithDescription.count = ARRAYSIZE(environmentItems); environment = &environmentWithDescription; } /* * TODO: Is this actually thread-safe when multiple threads act on * the same AuthorizationRef? Apple's documentation doesn't * actually say whether it is or is not. */ return AuthorizationCopyRights(auth, &rights, environment, (showDialogIfNeeded ? kAuthorizationFlagInteractionAllowed | kAuthorizationFlagDefaults : kAuthorizationFlagDefaults) | kAuthorizationFlagExtendRights, NULL) == errAuthorizationSuccess; } #endif #if !defined(_WIN32) /* *---------------------------------------------------------------------------- * * Id_BeginSuperUser -- * * Transition the calling thread from whatever its current effective * user is to effectively root. * * Results: * Returns the uid of the effective user from before the transition to * effectively root. A "-1" is used to indicate that the thread was * already root when this routine was called. * * Side effects: * None * *---------------------------------------------------------------------------- */ uid_t Id_BeginSuperUser(void) { uid_t uid = Id_GetEUid(); ASSERT_NOT_IMPLEMENTED(uid != (uid_t) -1); if (uid == 0) { uid = (uid_t) -1; // already root; nothing to do } else { #if defined(__APPLE__) #if TARGET_OS_IPHONE Warning("XXXIOS: implement %s\n", __func__); #else syscall(SYS_settid, KAUTH_UID_NONE, KAUTH_GID_NONE /* Ignored. */); #endif #else Id_SetRESUid((uid_t) -1, (uid_t) 0, (uid_t) -1); // effectively root #endif } return uid; } /* *---------------------------------------------------------------------------- * * Id_EndSuperUser -- * * Transition the calling thread from effective root user to * another user. * * Results: * None * * Side effects: * When transitioning from being effectively root to the specified * user (uid) the effective gid of the calling thread may be lost. * *---------------------------------------------------------------------------- */ void Id_EndSuperUser(uid_t uid) // IN: { if ((uid != (uid_t) -1) && (uid != Id_GetEUid())) { ASSERT(uid != 0); // Don't allow cheating like this #if defined(__APPLE__) if (syscall(SYS_settid, uid, getgid()) == -1) { Log("Failed to release super user privileges.\n"); } #else Id_SetRESUid((uid_t) -1, uid, (uid_t) -1); // revert to uid #endif } } #endif open-vm-tools-9.4.0-1280544/lib/misc/Makefile.in0000644765153500003110000005113412220061622017203 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/misc DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libMisc_la_LIBADD = am_libMisc_la_OBJECTS = atomic.lo base64.lo codeset.lo codesetBase.lo \ codesetOld.lo dynarray.lo dynbuf.lo escape.lo hashTable.lo \ hostinfo.lo hostinfoHV.lo hostinfoPosix.lo hostname.lo \ hostType.lo idLinux.lo iovector.lo logFixed.lo machineID.lo \ miscSolaris.lo msgfmt.lo msgList.lo posixDlopen.lo \ posixPosix.lo random.lo timeutil.lo util_misc.lo utilMem.lo \ vmstdio.lo strutil.lo vthreadBase.lo libMisc_la_OBJECTS = $(am_libMisc_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libMisc_la_SOURCES) DIST_SOURCES = $(libMisc_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libMisc.la libMisc_la_SOURCES = atomic.c base64.c codeset.c codesetBase.c \ codesetOld.c dynarray.c dynbuf.c escape.c hashTable.c \ hostinfo.c hostinfoHV.c hostinfoPosix.c hostname.c hostType.c \ idLinux.c iovector.c logFixed.c machineID.c miscSolaris.c \ msgfmt.c msgList.c posixDlopen.c posixPosix.c random.c \ timeutil.c util_misc.c utilMem.c vmstdio.c strutil.c \ vthreadBase.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/misc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/misc/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libMisc.la: $(libMisc_la_OBJECTS) $(libMisc_la_DEPENDENCIES) $(EXTRA_libMisc_la_DEPENDENCIES) $(LINK) $(libMisc_la_OBJECTS) $(libMisc_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atomic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/base64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codeset.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codesetBase.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codesetOld.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dynarray.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dynbuf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/escape.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hashTable.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hostType.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hostinfo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hostinfoHV.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hostinfoPosix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hostname.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idLinux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iovector.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logFixed.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/machineID.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/miscSolaris.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msgList.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msgfmt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/posixDlopen.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/posixPosix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strutil.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timeutil.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utilMem.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util_misc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmstdio.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vthreadBase.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/misc/codeset.c0000644765153500003110000012524012220061556016736 0ustar dtormts/* ********************************************************** * Copyright 1998 VMware, Inc. All rights reserved. * **********************************************************/ /* * codeset.c -- * * Character set and encoding conversion functions, using ICU. * * * Some definitions borrow from header files from the ICU 1.8.1 * library. * * ICU 1.8.1 license follows: * * ICU License - ICU 1.8.1 and later * * COPYRIGHT AND PERMISSION NOTICE * * Copyright (c) 1995-2006 International Business Machines Corporation * and others * * All rights reserved. * * 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, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, provided that the above * copyright notice(s) and this permission notice appear in all * copies of the Software and that both the above copyright * notice(s) and this permission notice appear in supporting * documentation. * * 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 OF THIRD PARTY RIGHTS. IN NO EVENT * SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE * BE LIABLE FOR ANY CLAIM, OR 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. * * Except as contained in this notice, the name of a * copyright holder shall not be used in advertising or otherwise * to promote the sale, use or other dealings in this Software * without prior written authorization of the copyright holder. */ #if defined(_WIN32) # include # include # include #else # define _GNU_SOURCE # include # include # include # include # include # include "hostinfo.h" # include "hostType.h" #endif #if defined(__APPLE__) #include #endif #include #include "vmware.h" #include "vm_product.h" #include "vm_atomic.h" #if !defined(NO_ICU) # include "unicode/ucnv.h" # include "unicode/udata.h" # include "unicode/putil.h" #endif #include "file.h" #include "util.h" #include "codeset.h" #include "codesetOld.h" #include "str.h" #include "win32util.h" #if defined __APPLE__ # define LOCATION_WEAK # include "location.h" #endif /* * Macros */ #define CODESET_CAN_FALLBACK_ON_NON_ICU TRUE #if defined __APPLE__ # define POSIX_ICU_DIR DEFAULT_LIBDIRECTORY #elif !defined _WIN32 # if defined(VMX86_TOOLS) # define POSIX_ICU_DIR "/etc/vmware-tools" # else # define POSIX_ICU_DIR "/etc/vmware" # endif #endif /* * XXX These should be passed in from the build system, * but I don't have time to deal with bora-vmsoft. -- edward */ #define ICU_DATA_FILE "icudt44l.dat" #ifdef _WIN32 #define ICU_DATA_ITEM "icudt44l" #define ICU_DATA_FILE_W XCONC(L, ICU_DATA_FILE) #endif #ifdef VMX86_DEVEL #ifdef _WIN32 #define ICU_DATA_FILE_DIR "%TCROOT%/noarch/icu-data-4.4-1" #define ICU_DATA_FILE_DIR_W XCONC(L, ICU_DATA_FILE_DIR) #define ICU_DATA_FILE_PATH ICU_DATA_FILE_DIR_W DIRSEPS_W ICU_DATA_FILE_W #else #define ICU_DATA_FILE_DIR "/build/toolchain/noarch/icu-data-4.4-1" #define ICU_DATA_FILE_PATH ICU_DATA_FILE_DIR DIRSEPS ICU_DATA_FILE #endif #endif /* * Variables */ static Bool dontUseIcu = TRUE; /* * Functions */ #if !defined NO_ICU #ifdef _WIN32 /* *---------------------------------------------------------------------------- * * CodeSetGetModulePath -- * * Returns the wide-character current module path. We can't use * Win32U_GetModuleFileName because it invokes codeset.c conversion * routines. * * Returns: * NULL, or a utf16 string (free with free). * * Side effects: * None. * *---------------------------------------------------------------------------- */ static utf16_t * CodeSetGetModulePath(HANDLE hModule) // IN { utf16_t *pathW = NULL; DWORD size = MAX_PATH; while (TRUE) { DWORD res; pathW = realloc(pathW, size * (sizeof *pathW)); if (!pathW) { return NULL; } res = GetModuleFileNameW(hModule, pathW, size); if (res == 0) { /* fatal error */ goto exit; } else if (res == size) { /* * The buffer is too small; double its size. The maximum path length * on Windows is ~64KB so doubling will not push a DWORD into * integer overflow before success or error due to another reason * will occur. */ size *= 2; } else { /* success */ break; } } exit: return pathW; } #elif vmx86_devel && !defined(TEST_CUSTOM_ICU_DATA_FILE) // _WIN32 /* *----------------------------------------------------------------------------- * * CodeSetGetModulePath -- * * Retrieve the full path to the executable. Not supported under * VMvisor. Based on HostInfo_GetModulePath, simplified for safe * use before ICU is initialized. * * Results: * On success: The allocated, NUL-terminated file path. * Note: This path can be a symbolic or hard link; it's just one * possible path to access the executable. * * On failure: NULL. * * Side effects: * None * *----------------------------------------------------------------------------- */ static char * CodeSetGetModulePath(uint32 priv) { char path[PATH_MAX]; Bool ret = FALSE; #if defined(__APPLE__) uint32_t size; #else ssize_t size; uid_t uid = -1; #endif if ((priv != HGMP_PRIVILEGE) && (priv != HGMP_NO_PRIVILEGE)) { return NULL; } #if defined(__APPLE__) size = sizeof path; if (_NSGetExecutablePath(path, &size)) { goto exit; } #else #if defined(VMX86_SERVER) if (HostType_OSIsPureVMK()) { goto exit; } #endif if (priv == HGMP_PRIVILEGE) { uid = Id_BeginSuperUser(); } size = readlink("/proc/self/exe", path, sizeof path - 1); if (-1 == size) { if (priv == HGMP_PRIVILEGE) { Id_EndSuperUser(uid); } goto exit; } path[size] = '\0'; if (priv == HGMP_PRIVILEGE) { Id_EndSuperUser(uid); } #endif ret = TRUE; exit: if (ret) { return strdup(path); } else { return NULL; } } #endif // _WIN32 #endif // !NO_ICU /* *----------------------------------------------------------------------------- * * CodeSet_GetAltPathName -- * * The Unicode path is probably not compatible in the current encoding. * Try to convert the path into a short name so it may work with * local encoding. * * XXX -- this function is a temporary fix. It should be removed once * we fix the 3rd party library pathname issue. * * Results: * NULL, or a char string (free with free). * * Side effects: * None. * *----------------------------------------------------------------------------- */ char * CodeSet_GetAltPathName(const utf16_t *pathW) // IN { char *path = NULL; #if defined(_WIN32) DWORD res; utf16_t shortPathW[_MAX_PATH]; ASSERT(pathW); res = GetShortPathNameW(pathW, shortPathW, ARRAYSIZE(shortPathW)); if ((res == 0) || (res >= ARRAYSIZE(shortPathW))) { goto exit; } if (!CodeSetOld_Utf16leToCurrent((const char *)shortPathW, wcslen(shortPathW) * sizeof *shortPathW, &path, NULL)) { goto exit; } exit: #endif // _WIN32 return path; } /* *----------------------------------------------------------------------------- * * CodeSet_DontUseIcu -- * * Tell codeset not to load or use ICU (or stop using it if it's * already loaded). Codeset will fall back on codesetOld.c, which * relies on system internationalization APIs (and may have more * limited functionality). Not all APIs have a fallback, however * (namely GenericToGeneric). * * Results: * TRUE on success * FALSE on failure * * Side effects: * See above * *----------------------------------------------------------------------------- */ void CodeSet_DontUseIcu(void) { dontUseIcu = TRUE; } /* *----------------------------------------------------------------------------- * * CodeSet_Init -- * * Looks for ICU's data file in some platform-specific * directory. If present, inits ICU by feeding it the path to that * directory. If already inited, returns the current state (init * failed/succeeded). * * For Windows, CodeSet_Init is thread-safe (with critical section). * For Linux/Apple, call while single-threaded. * * *********** WARNING *********** * Do not call CodeSet_Init directly, it is called already by * Unicode_Init. Lots of code depends on codeset. Please call * Unicode_Init as early as possible. * ******************************* * * Results: * TRUE on success * FALSE on failure * * Side effects: * See above * *----------------------------------------------------------------------------- */ Bool CodeSet_Init(const char *icuDataDir) // IN: ICU data file location in Current code page. // Default is used if NULL. { #ifdef NO_ICU /* Nothing required if not using ICU. */ return TRUE; #else // NO_ICU DynBuf dbpath; #ifdef _WIN32 DWORD attribs; utf16_t *modPath = NULL; utf16_t *lastSlash; utf16_t *wpath; HANDLE hFile = INVALID_HANDLE_VALUE; HANDLE hMapping = NULL; void *memMappedData = NULL; #else struct stat finfo; #endif char *path = NULL; Bool ret = FALSE; DynBuf_Init(&dbpath); #ifdef USE_ICU /* * We're using system ICU, which finds its own data. So nothing to * do here. */ dontUseIcu = FALSE; ret = TRUE; goto exit; #endif /* * ********************* WARNING * Must avoid recursive calls into the codeset library here, hence * the idiotic hoop-jumping. DO NOT change any of these calls to * wrapper equivalents or call any other functions that may perform * string conversion. * ********************* WARNING */ #ifdef _WIN32 // { #if vmx86_devel && !defined(TEST_CUSTOM_ICU_DATA_FILE) /* * Devel builds use toolchain directory first. */ { WCHAR icuFilePath[MAX_PATH] = { 0 }; DWORD n = ExpandEnvironmentStringsW(ICU_DATA_FILE_PATH, icuFilePath, ARRAYSIZE(icuFilePath)); if (n > 0 && n < ARRAYSIZE(icuFilePath)) { attribs = GetFileAttributesW(icuFilePath); if ((INVALID_FILE_ATTRIBUTES != attribs) || (attribs & FILE_ATTRIBUTE_DIRECTORY) == 0) { if (!CodeSetOld_Utf16leToCurrent((const char *) icuFilePath, n * sizeof *icuFilePath, &path, NULL)) { goto exit; } goto found; } } } #endif if (icuDataDir) { /* * Data file must be in the specified directory. */ size_t length = strlen(icuDataDir); if (!DynBuf_Append(&dbpath, icuDataDir, length)) { goto exit; } if (length && icuDataDir[length - 1] != DIRSEPC) { if (!DynBuf_Append(&dbpath, DIRSEPS, strlen(DIRSEPS))) { goto exit; } } if (!DynBuf_Append(&dbpath, ICU_DATA_FILE, strlen(ICU_DATA_FILE)) || !DynBuf_Append(&dbpath, "\0", 1)) { goto exit; } /* * Check for file existence. */ attribs = GetFileAttributesA(DynBuf_Get(&dbpath)); if ((INVALID_FILE_ATTRIBUTES == attribs) || (attribs & FILE_ATTRIBUTE_DIRECTORY)) { goto exit; } path = (char *) DynBuf_Detach(&dbpath); } else { /* * Data file must be in the directory of the current module * (i.e. the module that contains CodeSet_Init()). */ HMODULE hModule = W32Util_GetModuleByAddress((void *) CodeSet_Init); if (!hModule) { goto exit; } modPath = CodeSetGetModulePath(hModule); if (!modPath) { goto exit; } lastSlash = wcsrchr(modPath, DIRSEPC_W); if (!lastSlash) { goto exit; } *lastSlash = L'\0'; if (!DynBuf_Append(&dbpath, modPath, wcslen(modPath) * sizeof(utf16_t)) || !DynBuf_Append(&dbpath, DIRSEPS_W, wcslen(DIRSEPS_W) * sizeof(utf16_t)) || !DynBuf_Append(&dbpath, ICU_DATA_FILE_W, wcslen(ICU_DATA_FILE_W) * sizeof(utf16_t)) || !DynBuf_Append(&dbpath, L"\0", 2)) { goto exit; } /* * Since u_setDataDirectory can't handle UTF-16, we would have to * now convert this path to local encoding. But that fails when * the module is in a path containing characters not in the * local encoding (see 282524). So we'll memory-map the file * instead and call udata_setCommonData() below. */ wpath = (utf16_t *) DynBuf_Get(&dbpath); hFile = CreateFileW(wpath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (INVALID_HANDLE_VALUE == hFile) { goto exit; } hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (NULL == hMapping) { goto exit; } memMappedData = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); if (NULL == memMappedData) { goto exit; } } #else // } _WIN32 { #if vmx86_devel && !defined(TEST_CUSTOM_ICU_DATA_FILE) { char *modPath; char *lastSlash; /* * Devel builds use toolchain directory first. */ if (stat(ICU_DATA_FILE_PATH, &finfo) >= 0 && !S_ISDIR(finfo.st_mode)) { if ((path = strdup(ICU_DATA_FILE_PATH)) == NULL) { goto exit; } goto found; } /* * Then we try module directory, if we can get it. */ modPath = CodeSetGetModulePath(HGMP_PRIVILEGE); if (modPath) { lastSlash = strrchr(modPath, DIRSEPC); if (lastSlash) { *lastSlash = '\0'; if (DynBuf_Append(&dbpath, modPath, strlen(modPath)) && DynBuf_Append(&dbpath, DIRSEPS, strlen(DIRSEPS)) && DynBuf_Append(&dbpath, ICU_DATA_FILE, strlen(ICU_DATA_FILE)) && DynBuf_Append(&dbpath, "\0", 1)) { if ((stat((const char *) DynBuf_Get(&dbpath), &finfo) >= 0) && !S_ISDIR(finfo.st_mode)) { free(modPath); path = DynBuf_Detach(&dbpath); goto found; } else { DynBuf_SetSize(&dbpath, 0); } } } free(modPath); } } #endif // vmx86_devel if (icuDataDir) { /* Use the caller-specified ICU data dir. */ if (!DynBuf_Append(&dbpath, icuDataDir, strlen(icuDataDir))) { goto exit; } } else { /* Use a default ICU data dir. */ # if defined __APPLE__ Location_GetLibrary_Type *Location_GetLibrary = Location_GetLibrary_Addr(); if (Location_GetLibrary) { char *libDir = Location_GetLibrary(); Bool success = libDir && DynBuf_Append(&dbpath, libDir, strlen(libDir)); free(libDir); if (!success) { goto exit; } } else # endif { if (!DynBuf_Append(&dbpath, POSIX_ICU_DIR, strlen(POSIX_ICU_DIR))) { goto exit; } } if (!DynBuf_Append(&dbpath, "/icu", strlen("/icu"))) { goto exit; } } if (!DynBuf_Append(&dbpath, DIRSEPS, strlen(DIRSEPS)) || !DynBuf_Append(&dbpath, ICU_DATA_FILE, strlen(ICU_DATA_FILE)) || !DynBuf_Append(&dbpath, "\0", 1)) { goto exit; } /* * Check for file existence. (DO NOT CHANGE TO 'stat' WRAPPER). */ path = (char *) DynBuf_Detach(&dbpath); if (stat(path, &finfo) < 0 || S_ISDIR(finfo.st_mode)) { goto exit; } #endif // } _WIN32 #if vmx86_devel && !defined(TEST_CUSTOM_ICU_DATA_FILE) found: #endif #ifdef _WIN32 if (memMappedData) { /* * Tell ICU to use this mapped data. */ UErrorCode uerr = U_ZERO_ERROR; ASSERT(memMappedData); udata_setCommonData(memMappedData, &uerr); if (uerr != U_ZERO_ERROR) { UnmapViewOfFile(memMappedData); goto exit; } udata_setAppData(ICU_DATA_ITEM, memMappedData, &uerr); if (uerr != U_ZERO_ERROR) { UnmapViewOfFile(memMappedData); goto exit; } } else { #endif /* * Tell ICU to use this directory. */ u_setDataDirectory(path); #ifdef _WIN32 } #endif dontUseIcu = FALSE; ret = TRUE; exit: if (!ret) { /* * There was an error initing ICU, but if we can fall back on * non-ICU (old CodeSet) then things are OK. */ if (CODESET_CAN_FALLBACK_ON_NON_ICU) { ret = TRUE; dontUseIcu = TRUE; #ifdef _WIN32 OutputDebugStringW(L"CodeSet_Init: no ICU\n"); #endif } } #ifdef _WIN32 free(modPath); if (hMapping) { CloseHandle(hMapping); } if (hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile); } #endif free(path); DynBuf_Destroy(&dbpath); return ret; #endif } #if defined(CURRENT_IS_UTF8) /* *----------------------------------------------------------------------------- * * CodeSetDuplicateUtf8Str -- * * Duplicate UTF-8 string, appending zero terminator to its end. * * Results: * TRUE on success * FALSE on failure * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool CodeSetDuplicateUtf8Str(const char *bufIn, // IN: Input string size_t sizeIn, // IN: Input string length char **bufOut, // OUT: "Converted" string size_t *sizeOut) // OUT/OPT: Length of string { char *myBufOut; size_t newSize = sizeIn + sizeof *myBufOut; if (newSize < sizeIn) { // Prevent integer overflow return FALSE; } myBufOut = malloc(newSize); if (myBufOut == NULL) { return FALSE; } memcpy(myBufOut, bufIn, sizeIn); myBufOut[sizeIn] = '\0'; *bufOut = myBufOut; if (sizeOut) { *sizeOut = sizeIn; } return TRUE; } #endif // defined(CURRENT_IS_UTF8) /* *----------------------------------------------------------------------------- * * CodeSetDynBufFinalize -- * * Append NUL terminator to the buffer, and return pointer to * buffer and its data size (before appending terminator). Destroys * buffer on failure. * * Results: * TRUE on success * FALSE on failure * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool CodeSetDynBufFinalize(Bool ok, // IN: Earlier steps succeeded DynBuf *db, // IN: Buffer with converted string char **bufOut, // OUT: Converted string size_t *sizeOut) // OUT/OPT: Length of string in bytes { /* * NUL can be as long as 4 bytes if UTF-32, make no assumptions. */ if (!ok || !DynBuf_Append(db, "\0\0\0\0", 4) || !DynBuf_Trim(db)) { DynBuf_Destroy(db); return FALSE; } *bufOut = DynBuf_Get(db); if (sizeOut) { *sizeOut = DynBuf_GetSize(db) - 4; } return TRUE; } /* *----------------------------------------------------------------------------- * * CodeSetUtf8ToUtf16le -- * * Append the content of a buffer (that uses the UTF-8 encoding) to a * DynBuf (that uses the UTF-16LE encoding) * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool CodeSetUtf8ToUtf16le(const char *bufIn, // IN size_t sizeIn, // IN DynBuf *db) // IN { return CodeSet_GenericToGenericDb("UTF-8", bufIn, sizeIn, "UTF-16LE", 0, db); } #if defined(__APPLE__) /* *----------------------------------------------------------------------------- * * CodeSet_Utf8Normalize -- * * Calls down to CodeSetOld_Utf8Normalize. * * Results: * See CodeSetOld_Utf8Normalize. * * Side effects: * See CodeSetOld_Utf8Normalize. * *----------------------------------------------------------------------------- */ Bool CodeSet_Utf8Normalize(const char *bufIn, // IN size_t sizeIn, // IN Bool precomposed, // IN DynBuf *db) // OUT { return CodeSetOld_Utf8Normalize(bufIn, sizeIn, precomposed, db); } #endif /* defined(__APPLE__) */ /* *----------------------------------------------------------------------------- * * CodeSet_GenericToGenericDb -- * * Append the content of a buffer (that uses the specified encoding) to a * DynBuf (that uses the specified encoding). * * Results: * TRUE on success * FALSE on failure * * Side effects: * String (sans NUL-termination) is appended to db. * *----------------------------------------------------------------------------- */ Bool CodeSet_GenericToGenericDb(const char *codeIn, // IN const char *bufIn, // IN size_t sizeIn, // IN const char *codeOut, // IN unsigned int flags, // IN DynBuf *db) // IN/OUT { #if defined(NO_ICU) return CodeSetOld_GenericToGenericDb(codeIn, bufIn, sizeIn, codeOut, flags, db); #else Bool result = FALSE; UErrorCode uerr; const char *bufInCur; const char *bufInEnd; UChar bufPiv[1024]; UChar *bufPivSource; UChar *bufPivTarget; UChar *bufPivEnd; char *bufOut; char *bufOutCur; char *bufOutEnd; size_t newSize; size_t bufOutSize; size_t bufOutOffset; UConverter *cvin = NULL; UConverter *cvout = NULL; UConverterToUCallback toUCb; UConverterFromUCallback fromUCb; ASSERT(codeIn); ASSERT(sizeIn == 0 || bufIn); ASSERT(codeOut); ASSERT(db); ASSERT((CSGTG_NORMAL == flags) || (CSGTG_TRANSLIT == flags) || (CSGTG_IGNORE == flags)); if (dontUseIcu) { // fall back return CodeSetOld_GenericToGenericDb(codeIn, bufIn, sizeIn, codeOut, flags, db); } /* * Trivial case. */ if ((0 == sizeIn) || (NULL == bufIn)) { result = TRUE; goto exit; } /* * Open converters. */ uerr = U_ZERO_ERROR; cvin = ucnv_open(codeIn, &uerr); if (!cvin) { goto exit; } uerr = U_ZERO_ERROR; cvout = ucnv_open(codeOut, &uerr); if (!cvout) { goto exit; } /* * Set callbacks according to flags. */ switch (flags) { case CSGTG_NORMAL: toUCb = UCNV_TO_U_CALLBACK_STOP; fromUCb = UCNV_FROM_U_CALLBACK_STOP; break; case CSGTG_TRANSLIT: toUCb = UCNV_TO_U_CALLBACK_SUBSTITUTE; fromUCb = UCNV_FROM_U_CALLBACK_SUBSTITUTE; break; case CSGTG_IGNORE: toUCb = UCNV_TO_U_CALLBACK_SKIP; fromUCb = UCNV_FROM_U_CALLBACK_SKIP; break; default: NOT_IMPLEMENTED(); break; } uerr = U_ZERO_ERROR; ucnv_setToUCallBack(cvin, toUCb, NULL, NULL, NULL, &uerr); if (U_ZERO_ERROR != uerr) { goto exit; } uerr = U_ZERO_ERROR; ucnv_setFromUCallBack(cvout, fromUCb, NULL, NULL, NULL, &uerr); if (U_ZERO_ERROR != uerr) { goto exit; } /* * Convert using ucnv_convertEx(). * As a starting guess, make the output buffer the same size as * the input string (with a fudge constant added in to avoid degen * cases). */ bufInCur = bufIn; bufInEnd = bufIn + sizeIn; newSize = sizeIn + 4; if (newSize < sizeIn) { // Prevent integer overflow goto exit; } bufOutSize = newSize; bufOutOffset = 0; bufPivSource = bufPiv; bufPivTarget = bufPiv; bufPivEnd = bufPiv + ARRAYSIZE(bufPiv); for (;;) { if (!DynBuf_Enlarge(db, bufOutSize)) { goto exit; } bufOut = DynBuf_Get(db); bufOutCur = bufOut + bufOutOffset; bufOutSize = DynBuf_GetAllocatedSize(db); bufOutEnd = bufOut + bufOutSize; uerr = U_ZERO_ERROR; ucnv_convertEx(cvout, cvin, &bufOutCur, bufOutEnd, &bufInCur, bufInEnd, bufPiv, &bufPivSource, &bufPivTarget, bufPivEnd, FALSE, TRUE, &uerr); if (!U_FAILURE(uerr)) { /* * "This was a triumph. I'm making a note here: HUGE SUCCESS. It's * hard to overstate my satisfaction." */ break; } if (U_BUFFER_OVERFLOW_ERROR != uerr) { // failure goto exit; } /* * Our guess at 'bufOutSize' was obviously wrong, just double it. * We'll be reallocating bufOut, so will need to recompute bufOutCur * based on bufOutOffset. */ newSize = 2 * bufOutSize; /* * Prevent integer overflow. We can use this form of checking * specifically because a multiple by 2 is used. This type of checking * does not work in the general case. */ if (newSize < bufOutSize) { goto exit; } bufOutSize = newSize; bufOutOffset = bufOutCur - bufOut; } /* * Set final size and return. */ DynBuf_SetSize(db, bufOutCur - bufOut); result = TRUE; exit: if (cvin) { ucnv_close(cvin); } if (cvout) { ucnv_close(cvout); } return result; #endif } /* *----------------------------------------------------------------------------- * * CodeSet_GenericToGeneric -- * * Non-db version of CodeSet_GenericToGenericDb. * * Results: * TRUE on success, plus allocated string * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSet_GenericToGeneric(const char *codeIn, // IN const char *bufIn, // IN size_t sizeIn, // IN const char *codeOut, // IN unsigned int flags, // IN char **bufOut, // OUT size_t *sizeOut) // OUT { DynBuf db; Bool ok; DynBuf_Init(&db); ok = CodeSet_GenericToGenericDb(codeIn, bufIn, sizeIn, codeOut, flags, &db); return CodeSetDynBufFinalize(ok, &db, bufOut, sizeOut); } /* * Generic remarks: here is my understanding of those terms as of 2001/12/27: * * BOM * Byte-Order Mark * * BMP * Basic Multilingual Plane. This plane comprises the first 2^16 code * positions of ISO/IEC 10646's canonical code space * * UCS * Universal Character Set. Encoding form specified by ISO/IEC 10646 * * UCS-2 * Directly store all Unicode scalar value (code point) from U+0000 to * U+FFFF on 2 bytes. Consequently, this representation can only hold * characters in the BMP * * UCS-4 * Directly store a Unicode scalar value (code point) from U-00000000 to * U-FFFFFFFF on 4 bytes * * UTF * Abbreviation for Unicode (or UCS) Transformation Format * * UTF-8 * Unicode (or UCS) Transformation Format, 8-bit encoding form. UTF-8 is the * Unicode Transformation Format that serializes a Unicode scalar value * (code point) as a sequence of 1 to 6 bytes * * UTF-16 * UCS-2 + surrogate mechanism: allow to encode some non-BMP Unicode * characters in a UCS-2 string, by using 2 2-byte units. See the Unicode * standard, v2.0 * * UTF-32 * Directly store all Unicode scalar value (code point) from U-00000000 to * U-0010FFFF on 4 bytes. This is a subset of UCS-4 * * --hpreg */ /* *----------------------------------------------------------------------------- * * CodeSet_Utf8ToCurrent -- * * Convert the content of a buffer (that uses the UTF-8 encoding) into * another buffer (that uses the current encoding). * * Results: * TRUE on success: '*bufOut' contains the allocated, NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSet_Utf8ToCurrent(const char *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut) // OUT { #if !defined(CURRENT_IS_UTF8) DynBuf db; Bool ok; #endif /* * Fallback if necessary. */ if (dontUseIcu) { return CodeSetOld_Utf8ToCurrent(bufIn, sizeIn, bufOut, sizeOut); } #if defined(CURRENT_IS_UTF8) return CodeSetDuplicateUtf8Str(bufIn, sizeIn, bufOut, sizeOut); #else DynBuf_Init(&db); ok = CodeSet_GenericToGenericDb("UTF-8", bufIn, sizeIn, CodeSet_GetCurrentCodeSet(), 0, &db); return CodeSetDynBufFinalize(ok, &db, bufOut, sizeOut); #endif } /* *----------------------------------------------------------------------------- * * CodeSet_CurrentToUtf8 -- * * Convert the content of a buffer (that uses the current encoding) into * another buffer (that uses the UTF-8 encoding). * * Results: * TRUE on success: '*bufOut' contains the allocated, NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSet_CurrentToUtf8(const char *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut) // OUT { #if !defined(CURRENT_IS_UTF8) DynBuf db; Bool ok; #endif /* * Fallback if necessary. */ if (dontUseIcu) { return CodeSetOld_CurrentToUtf8(bufIn, sizeIn, bufOut, sizeOut); } #if defined(CURRENT_IS_UTF8) return CodeSetDuplicateUtf8Str(bufIn, sizeIn, bufOut, sizeOut); #else DynBuf_Init(&db); ok = CodeSet_GenericToGenericDb(CodeSet_GetCurrentCodeSet(), bufIn, sizeIn, "UTF-8", 0, &db); return CodeSetDynBufFinalize(ok, &db, bufOut, sizeOut); #endif } /* *----------------------------------------------------------------------------- * * CodeSet_Utf16leToUtf8Db -- * * Append the content of a buffer (that uses the UTF-16LE encoding) to a * DynBuf (that uses the UTF-8 encoding). * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSet_Utf16leToUtf8Db(const char *bufIn, // IN size_t sizeIn, // IN DynBuf *db) // IN { /* * Fallback if necessary. */ if (dontUseIcu) { return CodeSetOld_Utf16leToUtf8Db(bufIn, sizeIn, db); } return CodeSet_GenericToGenericDb("UTF-16LE", bufIn, sizeIn, "UTF-8", 0, db); } /* *----------------------------------------------------------------------------- * * CodeSet_Utf16leToUtf8 -- * * Convert the content of a buffer (that uses the UTF-16LE encoding) into * another buffer (that uses the UTF-8 encoding). * * The operation is inversible (its inverse is CodeSet_Utf8ToUtf16le). * * Results: * TRUE on success: '*bufOut' contains the allocated, NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSet_Utf16leToUtf8(const char *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut) // OUT { DynBuf db; Bool ok; /* * Fallback if necessary. */ if (dontUseIcu) { return CodeSetOld_Utf16leToUtf8(bufIn, sizeIn, bufOut, sizeOut); } DynBuf_Init(&db); ok = CodeSet_Utf16leToUtf8Db(bufIn, sizeIn, &db); return CodeSetDynBufFinalize(ok, &db, bufOut, sizeOut); } /* *----------------------------------------------------------------------------- * * CodeSet_Utf8ToUtf16le -- * * Convert the content of a buffer (that uses the UTF-8 encoding) into * another buffer (that uses the UTF-16LE encoding). * * The operation is inversible (its inverse is CodeSet_Utf16leToUtf8). * * Results: * TRUE on success: '*bufOut' contains the allocated, NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSet_Utf8ToUtf16le(const char *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut) // OUT { DynBuf db; Bool ok; /* * Fallback if necessary. */ if (dontUseIcu) { return CodeSetOld_Utf8ToUtf16le(bufIn, sizeIn, bufOut, sizeOut); } DynBuf_Init(&db); ok = CodeSetUtf8ToUtf16le(bufIn, sizeIn, &db); return CodeSetDynBufFinalize(ok, &db, bufOut, sizeOut); } /* *----------------------------------------------------------------------------- * * CodeSet_Utf8FormDToUtf8FormC -- * * Convert the content of a buffer (that uses the UTF-8 encoding) * which is in normal form D (decomposed) into another buffer * (that uses the UTF-8 encoding) and is normalized as * precomposed (Normalization Form C). * * Results: * TRUE on success: '*bufOut' contains a NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * '*bufOut' contains the allocated, NUL terminated buffer. * *----------------------------------------------------------------------------- */ Bool CodeSet_Utf8FormDToUtf8FormC(const char *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut) // OUT { /* * Fallback if necessary. */ if (dontUseIcu) { return CodeSetOld_Utf8FormDToUtf8FormC(bufIn, sizeIn, bufOut, sizeOut); } #if defined(__APPLE__) { DynBuf db; Bool ok; DynBuf_Init(&db); ok = CodeSet_Utf8Normalize(bufIn, sizeIn, TRUE, &db); return CodeSetDynBufFinalize(ok, &db, bufOut, sizeOut); } #else NOT_IMPLEMENTED(); #endif } /* *----------------------------------------------------------------------------- * * CodeSet_Utf8FormCToUtf8FormD -- * * Convert the content of a buffer (that uses the UTF-8 encoding) * which is in normal form C (precomposed) into another buffer * (that uses the UTF-8 encoding) and is normalized as * decomposed (Normalization Form D). * * Results: * TRUE on success: '*bufOut' contains a NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * '*bufOut' contains the allocated, NUL terminated buffer. * *----------------------------------------------------------------------------- */ Bool CodeSet_Utf8FormCToUtf8FormD(const char *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut) // OUT { /* * Fallback if necessary. */ if (dontUseIcu) { return CodeSetOld_Utf8FormCToUtf8FormD(bufIn, sizeIn, bufOut, sizeOut); } #if defined(__APPLE__) { DynBuf db; Bool ok; DynBuf_Init(&db); ok = CodeSet_Utf8Normalize(bufIn, sizeIn, FALSE, &db); return CodeSetDynBufFinalize(ok, &db, bufOut, sizeOut); } #else NOT_IMPLEMENTED(); #endif } /* *----------------------------------------------------------------------------- * * CodeSet_CurrentToUtf16le -- * * Convert the content of a buffer (that uses the current encoding) into * another buffer (that uses the UTF-16LE encoding). * * Results: * TRUE on success: '*bufOut' contains the allocated, NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSet_CurrentToUtf16le(const char *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut) // OUT { DynBuf db; Bool ok; /* * Fallback if necessary. */ if (dontUseIcu) { return CodeSetOld_CurrentToUtf16le(bufIn, sizeIn, bufOut, sizeOut); } DynBuf_Init(&db); ok = CodeSet_GenericToGenericDb(CodeSet_GetCurrentCodeSet(), bufIn, sizeIn, "UTF-16LE", 0, &db); return CodeSetDynBufFinalize(ok, &db, bufOut, sizeOut); } /* *----------------------------------------------------------------------------- * * CodeSet_Utf16leToCurrent -- * * Convert the content of a buffer (that uses the UTF-16 little endian * encoding) into another buffer (that uses the current encoding) * * Results: * TRUE on success: '*bufOut' contains the allocated, NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSet_Utf16leToCurrent(const char *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut) // OUT { DynBuf db; Bool ok; /* * Fallback if necessary. */ if (dontUseIcu) { return CodeSetOld_Utf16leToCurrent(bufIn, sizeIn, bufOut, sizeOut); } DynBuf_Init(&db); ok = CodeSet_GenericToGenericDb("UTF-16LE", bufIn, sizeIn, CodeSet_GetCurrentCodeSet(), 0, &db); return CodeSetDynBufFinalize(ok, &db, bufOut, sizeOut); } /* *----------------------------------------------------------------------------- * * CodeSet_Utf16beToCurrent -- * * Convert the content of a buffer (that uses the UTF-16 big endian * encoding) into another buffer (that uses the current encoding) * * Results: * TRUE on success: '*bufOut' contains the allocated, NUL terminated buffer. * If not NULL, '*sizeOut' contains the size of the buffer * (excluding the NUL terminator) * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSet_Utf16beToCurrent(const char *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut) // OUT { DynBuf db; Bool ok; /* * Fallback if necessary. */ if (dontUseIcu) { return CodeSetOld_Utf16beToCurrent(bufIn, sizeIn, bufOut, sizeOut); } DynBuf_Init(&db); ok = CodeSet_GenericToGenericDb("UTF-16BE", bufIn, sizeIn, CodeSet_GetCurrentCodeSet(), 0, &db); return CodeSetDynBufFinalize(ok, &db, bufOut, sizeOut); } /* *----------------------------------------------------------------------------- * * CodeSet_IsEncodingSupported -- * * Ask ICU if it supports the specific encoding. * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSet_IsEncodingSupported(const char *name) // IN { #if defined(NO_ICU) return CodeSetOld_IsEncodingSupported(name); #else UConverter *cv; UErrorCode uerr; /* * Fallback if necessary. */ if (dontUseIcu) { return CodeSetOld_IsEncodingSupported(name); } /* * Try to open the encoding. */ uerr = U_ZERO_ERROR; cv = ucnv_open(name, &uerr); if (cv) { ucnv_close(cv); return TRUE; } return FALSE; #endif } /* *----------------------------------------------------------------------------- * * CodeSet_Validate -- * * Validate a string in the given encoding. * * Results: * TRUE if string is valid, * FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool CodeSet_Validate(const char *buf, // IN: the string size_t size, // IN: length of string const char *code) // IN: encoding { #if defined(NO_ICU) return CodeSetOld_Validate(buf, size, code); #else UConverter *cv; UErrorCode uerr; // ucnv_toUChars takes 32-bit int size ASSERT_NOT_IMPLEMENTED(size <= (size_t) MAX_INT32); if (size == 0) { return TRUE; } /* * Fallback if necessary. */ if (dontUseIcu) { return CodeSetOld_Validate(buf, size, code); } /* * Calling ucnv_toUChars() this way is the idiom to precompute * the length of the output. (See preflighting in the ICU User Guide.) * So if the error is not U_BUFFER_OVERFLOW_ERROR, then the input * is bad. */ uerr = U_ZERO_ERROR; cv = ucnv_open(code, &uerr); ASSERT_NOT_IMPLEMENTED(uerr == U_ZERO_ERROR); ucnv_setToUCallBack(cv, UCNV_TO_U_CALLBACK_STOP, NULL, NULL, NULL, &uerr); ASSERT_NOT_IMPLEMENTED(uerr == U_ZERO_ERROR); ucnv_toUChars(cv, NULL, 0, buf, size, &uerr); ucnv_close(cv); return uerr == U_BUFFER_OVERFLOW_ERROR; #endif } open-vm-tools-9.4.0-1280544/lib/xdg/0000755765153500003110000000000012220061624014763 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/xdg/Makefile.am0000644765153500003110000000175312220061556017031 0ustar dtormts################################################################################ ### Copyright 2010 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libXdg.la libXdg_la_CPPFLAGS = @GLIB2_CPPFLAGS@ libXdg_la_SOURCES = libXdg_la_SOURCES += xdg.c open-vm-tools-9.4.0-1280544/lib/xdg/xdg.c0000644765153500003110000000622312220061556015720 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * xdg.c -- * * vmware-xdg-* script wrapper library. */ #include #include #include #include #include #include #include "vmware.h" #include "vmstdio.h" #include "xdg.h" /* * Local data */ /* Name of helper script used by Xdg_DetectDesktopEnv. */ static const char xdgDetectDEExec[] = "vmware-xdg-detect-de"; /* * Global functions */ /* *----------------------------------------------------------------------------- * * Xdg_DetectDesktopEnv -- * * Captures output from external vmware-xdg-detect-de script to determine * which desktop environment we're running under. * * Results: * Returns a pointer to a string specifying the desktop environment on * success or "" on failure. * * This function only guarantees that the returned string matches the * pattern ^[A-Za-z0-9]*$. * * Side effects: * Allocates memory for outbuf on first call for duration of program. * Uses popen(), relying on $PATH, to find and execute xdgDetectDeExec. * Caller must not modify returned string. * *----------------------------------------------------------------------------- */ const char * Xdg_DetectDesktopEnv(void) { static char *outbuf = NULL; if (outbuf == NULL) { FILE *cmdPipe = popen(xdgDetectDEExec, "r"); if (cmdPipe) { static const size_t maxSize = sizeof "TEHLONGISTDESKTOPENVEVAR"; size_t outLen; // Doesn't include NUL. int status; if ( StdIO_ReadNextLine(cmdPipe, &outbuf, maxSize, &outLen) == StdIO_Success) { int i; for (i = 0; i < outLen; i++) { if (!isalnum(outbuf[i])) { g_debug("%s: received malformed input\n", __func__); free(outbuf); outbuf = NULL; break; } } } status = pclose(cmdPipe); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { g_debug("%s: %s did not exit cleanly (%x/%x)\n", __func__, xdgDetectDEExec, status, WEXITSTATUS(status)); free(outbuf); outbuf = NULL; } } if (outbuf == NULL) { outbuf = ""; } } return outbuf; } open-vm-tools-9.4.0-1280544/lib/xdg/Makefile.in0000644765153500003110000004533012220061624017035 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2010 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/xdg DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libXdg_la_LIBADD = am_libXdg_la_OBJECTS = libXdg_la-xdg.lo libXdg_la_OBJECTS = $(am_libXdg_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libXdg_la_SOURCES) DIST_SOURCES = $(libXdg_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libXdg.la libXdg_la_CPPFLAGS = @GLIB2_CPPFLAGS@ libXdg_la_SOURCES = xdg.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/xdg/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/xdg/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libXdg.la: $(libXdg_la_OBJECTS) $(libXdg_la_DEPENDENCIES) $(EXTRA_libXdg_la_DEPENDENCIES) $(LINK) $(libXdg_la_OBJECTS) $(libXdg_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libXdg_la-xdg.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libXdg_la-xdg.lo: xdg.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXdg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libXdg_la-xdg.lo -MD -MP -MF $(DEPDIR)/libXdg_la-xdg.Tpo -c -o libXdg_la-xdg.lo `test -f 'xdg.c' || echo '$(srcdir)/'`xdg.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libXdg_la-xdg.Tpo $(DEPDIR)/libXdg_la-xdg.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xdg.c' object='libXdg_la-xdg.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libXdg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libXdg_la-xdg.lo `test -f 'xdg.c' || echo '$(srcdir)/'`xdg.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/file/0000755765153500003110000000000012220061621015115 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/file/fileInt.h0000644765153500003110000002335612220061556016700 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * fileInt.h -- * * Things internal to the file library. */ #if !defined(__FILE_INTERNAL_H__) #define __FILE_INTERNAL_H__ #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #include "err.h" #include "posix.h" #include "file.h" #include "fileIO.h" #include "fileLock.h" #include "unicodeTypes.h" #include "memaligned.h" /* * Max supported file size is 64 TB. */ #define MAX_SUPPORTED_FILE_SIZE CONST64U(0x400000000000) #if defined __linux__ /* * These magic constants are used only for parsing Linux statfs data. * So they make sense only for Linux build. If you need them on other OSes, * think once more. */ #define ADFS_SUPER_MAGIC 0xadf5 #define AFFS_SUPER_MAGIC 0xADFF #define EXT_SUPER_MAGIC 0x137D #define EXT2_OLD_SUPER_MAGIC 0xEF51 #define EXT2_SUPER_MAGIC 0xEF53 #define EXT3_SUPER_MAGIC 0xEF53 #define EXT4_SUPER_MAGIC 0xEF53 #define HFSPLUS_SUPER_MAGIC 0x482B #define NFS_SUPER_MAGIC 0x6969 #define SMB_SUPER_MAGIC 0x517B #define ISOFS_SUPER_MAGIC 0x9660 #define JFFS2_SUPER_MAGIC 0x72b6 #define PROC_SUPER_MAGIC 0x9fa0 #define OPENPROM_SUPER_MAGIC 0x9fa1 #define USBDEVICE_SUPER_MAGIC 0x9fa2 #define AUTOFS_SUPER_MAGIC 0x0187 #if !defined(MSDOS_SUPER_MAGIC) #define MSDOS_SUPER_MAGIC 0x4D44 #endif #define XENIX_SUPER_MAGIC 0x012FF7B4 #define SYSV4_SUPER_MAGIC 0x012FF7B5 #define SYSV2_SUPER_MAGIC 0x012FF7B6 #define COH_SUPER_MAGIC 0x012FF7B7 #define UFS_SUPER_MAGIC 0x00011954 #define XFS_SUPER_MAGIC 0x58465342 #define VMFS_SUPER_MAGIC 0x2fABF15E #define TMPFS_SUPER_MAGIC 0x01021994 #define JFS_SUPER_MAGIC 0x3153464a #define AFS_SUPER_MAGIC 0x5346414F #define CIFS_SUPER_MAGIC 0xFF534D42 #if !defined(REISERFS_SUPER_MAGIC) #define REISERFS_SUPER_MAGIC 0x52654973 #endif #endif // linux #define LGPFX "FILE:" #define FILE_TYPE_REGULAR 0 #define FILE_TYPE_DIRECTORY 1 #define FILE_TYPE_BLOCKDEVICE 2 #define FILE_TYPE_CHARDEVICE 3 #define FILE_TYPE_SYMLINK 4 #define FILE_TYPE_FIFO 5 #define FILE_TYPE_SOCKET 6 #define FILE_TYPE_UNCERTAIN 7 typedef struct FileData { uint64 fileAccessTime; uint64 fileCreationTime; uint64 fileModificationTime; uint64 fileSize; int fileType; int fileMode; int fileOwner; int fileGroup; } FileData; #define FILE_MAX_WAIT_TIME_MS 2000 // maximum wait time in milliseconds void FileIOResolveLockBits(int *access); #if defined(_WIN32) int FileMapErrorToErrno(const char *functionName, Err_Number status); Bool FileRetryThisError(DWORD error, uint32 numCodes, DWORD *codes); int FileAttributesRetry(ConstUnicode pathName, uint32 msecMaxWaitTime, FileData *fileData); int FileDeletionRetry(ConstUnicode pathName, Bool handleLink, uint32 msecMaxWaitTime); int FileCreateDirectoryRetry(ConstUnicode pathName, int mask, uint32 msecMaxWaitTime); int FileRemoveDirectoryRetry(ConstUnicode pathName, uint32 msecMaxWaitTime); int FileListDirectoryRetry(ConstUnicode pathName, uint32 msecMaxWaitTime, Unicode **ids); #define FileAttributes(a, b) FileAttributesRetry((a), 0, (b)) #define FileDeletion(a, b) FileDeletionRetry((a), (b), 0) #define FileCreateDirectory(a, b) FileCreateDirectoryRetry((a), (b), 0) #define FileRemoveDirectory(a) FileRemoveDirectoryRetry((a), 0) #define FileListDirectoryRobust(a, b) \ FileListDirectoryRetry((a), FILE_MAX_WAIT_TIME_MS, (b)) #define FileAttributesRobust(a, b) \ FileAttributesRetry((a), FILE_MAX_WAIT_TIME_MS, (b)) #define FileRenameRobust(a, b) \ File_RenameRetry((a), (b), FILE_MAX_WAIT_TIME_MS) #define FileDeletionRobust(a, b) \ FileDeletionRetry((a), (b), FILE_MAX_WAIT_TIME_MS) #define FileCreateDirectoryRobust(a, b) \ FileCreateDirectoryRetry((a), (b), FILE_MAX_WAIT_TIME_MS) #define FileRemoveDirectoryRobust(a) \ FileRemoveDirectoryRetry((a), FILE_MAX_WAIT_TIME_MS) #else static INLINE int FileMapErrorToErrno(const char *functionName, Err_Number status) { return status; } char *FilePosixGetBlockDevice(char const *path); int FileAttributes(ConstUnicode pathName, FileData *fileData); int FileDeletion(ConstUnicode pathName, Bool handleLink); int FileCreateDirectory(ConstUnicode pathName, int mask); int FileRemoveDirectory(ConstUnicode pathName); #define FileListDirectoryRobust(a, b) File_ListDirectory((a), (b)) #define FileAttributesRobust(a, b) FileAttributes((a), (b)) #define FileRenameRobust(a, b) File_Rename((a), (b)) #define FileDeletionRobust(a, b) FileDeletion((a), (b)) #define FileCreateDirectoryRobust(a, b) FileCreateDirectory((a), (b)) #define FileRemoveDirectoryRobust(a) FileRemoveDirectory((a)) #endif typedef struct active_lock { struct active_lock *next; uint32 age; Bool marked; Unicode dirName; } ActiveLock; typedef struct lock_values { char *machineID; char *executionID; char *lockType; char *locationChecksum; Unicode memberName; unsigned int lamportNumber; Bool exclusivity; uint32 waitTime; uint32 msecMaxWaitTime; ActiveLock *lockList; } LockValues; #include "file_extensions.h" #define FILELOCK_SUFFIX "." LOCK_FILE_EXTENSION #define FILELOCK_DATA_SIZE 512 uint32 FileSleeper(uint32 msecMinSleepTime, uint32 msecMaxSleepTime); uint32 FileSimpleRandom(void); const char *FileLockGetMachineID(void); char *FileLockGetExecutionID(void); Bool FileLockMachineIDMatch(char *host, char *second); int FileLockMemberValues(ConstUnicode lockDir, ConstUnicode fileName, char *buffer, size_t size, LockValues *memberValues); FileLockToken *FileLockIntrinsic(ConstUnicode filePathName, Bool exclusivity, uint32 msecMaxWaitTime, int *err); int FileUnlockIntrinsic(FileLockToken *tokenPtr); Bool FileLockIsLocked(ConstUnicode filePath, int *err); Bool FileLockValidExecutionID(const char *executionID); Bool FileLockValidName(ConstUnicode fileName); void FileLockAppendMessage(MsgList **msgs, int err); Bool FileIsWritableDir(ConstUnicode dirName); UnicodeIndex FileFirstSlashIndex(ConstUnicode pathName, UnicodeIndex startIndex); FileIOResult FileIOCreateRetry(FileIODescriptor *fd, ConstUnicode pathName, int access, FileIOOpenAction action, int mode, uint32 msecMaxWaitTime); /* * FileIOAligned_* are useful on hosted platforms where malloc/memalign/valloc * for "large buffers" (in the range 64 KiB - 1 MiB) will generally fall * through to mmap/munmap, which is expensive due to page table modifications * and the attendant TLB flushing (which requires IPIs and possibly world * switches) on other threads running in the same address space. In particular, * on Mac OS 10.6.6 on a Westmere-class Mac Pro, mmap + memcpy + munmap adds * around a millisecond of CPU time and a hundred IPIs to a 512 KiB write. See * PR#685845. * * This isn't applicable to ESX because * 1. we don't use this path for disk IO * 2. we don't want to do extra large allocations * 3. we don't have the same alignment constraints * so simply define it away to nothing. * * Tools is another case, we can use this path for IO but we don't want to add * MXUserExclLock dependencies. */ #if defined(VMX86_TOOLS) || defined(VMX86_SERVER) #define FileIOAligned_PoolInit() /* nothing */ #define FileIOAligned_PoolExit() /* nothing */ #define FileIOAligned_PoolMalloc(sz) NULL #define FileIOAligned_PoolFree(ptr) FALSE #else void FileIOAligned_PoolInit(void); void FileIOAligned_PoolExit(void); void *FileIOAligned_PoolMalloc(size_t); Bool FileIOAligned_PoolFree(void *); #endif static INLINE void * FileIOAligned_Malloc(size_t sz) // IN: { void *buf = FileIOAligned_PoolMalloc(sz); if (!buf) { buf = Aligned_Malloc(sz); } return buf; } static INLINE void FileIOAligned_Free(void *ptr) // IN: { if (!FileIOAligned_PoolFree(ptr)) { Aligned_Free(ptr); } } #if defined(__APPLE__) int PosixFileOpener(ConstUnicode pathName, int flags, mode_t mode); #else #define PosixFileOpener(a, b, c) Posix_Open(a, b, c); #endif #endif open-vm-tools-9.4.0-1280544/lib/file/fileLockPrimitive.c0000644765153500003110000015642612220061556020727 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * fileLockPrimitive.c -- * * Portable file locking via Lamport's Bakery algorithm. * * This implementation does rely upon a remove directory operation to fail * if the directory contains any files. */ #define _GNU_SOURCE /* For O_NOFOLLOW */ #include #include #include #include #include #include #include #if defined(_WIN32) #include #include #include #else #include #include #endif #include "vmware.h" #include "hostinfo.h" #include "util.h" #include "err.h" #include "log.h" #include "str.h" #include "fileIO.h" #include "fileLock.h" #include "fileInt.h" #include "random.h" #include "vm_atomic.h" #include "util.h" #include "hostType.h" #include "unicodeOperations.h" #define LOGLEVEL_MODULE main #include "loglevel_user.h" #define LOCK_SHARED "S" #define LOCK_EXCLUSIVE "X" #define FILELOCK_PROGRESS_DEARTH 8000 // Dearth of progress time in msec #define FILELOCK_PROGRESS_SAMPLE 200 // Progress sampling time in msec static char implicitReadToken; #define PARSE_TABLE_UINT 0 #define PARSE_TABLE_STRING 1 typedef struct parse_table { int type; char *name; void *valuePtr; } ParseTable; /* * The lock token. This is returned by the lock operation and must be sent * to the unlock operation. */ #define FILELOCK_TOKEN_SIGNATURE 0x4B434C46 // 'FLCK' in memory struct FileLockToken { uint32 signature; Bool portable; Unicode pathName; union { struct { FileIODescriptor lockFd; } mandatory; struct { Unicode lockFilePath; // &implicitReadToken for implicit read locks } portable; } u; }; /* *----------------------------------------------------------------------------- * * FileLockSleeper -- * * Have the calling thread sleep "for a while". The duration of the * sleep is determined by the count that is passed in. Checks are * also done for exceeding the maximum wait time. * * Results: * 0 slept * EAGAIN maximum sleep time exceeded * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int FileLockSleeper(LockValues *myValues, // IN/OUT: uint32 *loopCount) // IN/OUT: { uint32 msecSleepTime; if ((myValues->msecMaxWaitTime == FILELOCK_TRYLOCK_WAIT) || ((myValues->msecMaxWaitTime != FILELOCK_INFINITE_WAIT) && (myValues->waitTime > myValues->msecMaxWaitTime))) { return EAGAIN; } if (*loopCount <= 20) { /* most locks are "short" */ msecSleepTime = 100; *loopCount += 1; } else if (*loopCount < 40) { /* lock has been around a while, linear back-off */ msecSleepTime = 100 * (*loopCount - 19); *loopCount += 1; } else { /* WOW! long time... Set a maximum */ msecSleepTime = 2000; } myValues->waitTime += msecSleepTime; /* Clamp individual sleeps to avoid Windows issues */ while (msecSleepTime) { uint32 sleepTime = (msecSleepTime > 900) ? 900 : msecSleepTime; msecSleepTime -= FileSleeper(sleepTime, sleepTime); } return 0; } /* *----------------------------------------------------------------------------- * * FileLockRemoveLockingFile -- * * Remove the specified file. * * Results: * 0 success * > 0 failure (errno) * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int FileLockRemoveLockingFile(ConstUnicode lockDir, // IN: ConstUnicode fileName) // IN: { int err; Unicode path; ASSERT(lockDir); ASSERT(fileName); path = Unicode_Join(lockDir, DIRSEPS, fileName, NULL); err = FileDeletionRobust(path, FALSE); if (err != 0) { if (err == ENOENT) { /* Not there anymore; locker unlocked or timed out */ err = 0; } else { Warning(LGPFX" %s of '%s' failed: %s\n", __FUNCTION__, UTF8(path), strerror(err)); } } Unicode_Free(path); return err; } /* *----------------------------------------------------------------------------- * * FileLockParseArgs -- * * Parse the property list arguments of a lock file. The ParseTable * contains names of properies that are interesting to the caller; * only those values associated with the interesting names will be * extracted, the others will be ignored. * * Results: * TRUE An error was detected * FALSE All is well * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool FileLockParseArgs(char *argv[], // IN: uint32 argCount, // IN: ParseTable *table, // IN: uint32 tableSize) // IN: { uint32 argPos = 5; // The property list always starts with this argument while (argCount) { uint32 i; char *p = strchr(argv[argPos], '='); /* Validate the "name=value" form */ if ((p == NULL) || (p == argv[argPos]) || (p[1] == '\0')) { return TRUE; } *p = '\0'; /* Unknown names are ignored without error */ for (i = 0; i < tableSize; i++) { if (strcmp(argv[argPos], table[i].name) == 0) { switch (table[i].type) { case PARSE_TABLE_UINT: if (sscanf(&p[1], "%u", (uint32 *) table[i].valuePtr) != 1) { return TRUE; } break; case PARSE_TABLE_STRING: *((char **) table[i].valuePtr) = &p[1]; break; } } } *p = '='; argPos++; argCount--; } return FALSE; } /* *----------------------------------------------------------------------------- * * FileLockMemberValues -- * * Returns the values associated with lock directory file. * * Results: * 0 Valid lock file; values have been returned * > 0 Lock file problem (errno); values have not been returned * * Side effects: * The lock file may be deleted if it is invalid * *----------------------------------------------------------------------------- */ #define FL_MAX_ARGS 16 int FileLockMemberValues(ConstUnicode lockDir, // IN: ConstUnicode fileName, // IN: char *buffer, // OUT: size_t requiredSize, // IN: LockValues *memberValues) // OUT: { size_t len; int access; Unicode path; FileData fileData; FileIOResult result; FileIODescriptor desc; char *argv[FL_MAX_ARGS]; int err = 0; uint32 argc = 0; char *saveptr = NULL; ParseTable table[] = { { PARSE_TABLE_STRING, "lc", (void *) &memberValues->locationChecksum } }; ASSERT(lockDir); ASSERT(fileName); path = Unicode_Join(lockDir, DIRSEPS, fileName, NULL); FileIO_Invalidate(&desc); access = FILEIO_OPEN_ACCESS_READ; #if defined(_WIN32) access |= FILEIO_OPEN_SHARE_DELETE; #endif result = FileIOCreateRetry(&desc, path, access, FILEIO_OPEN, 0444, FILE_MAX_WAIT_TIME_MS); if (!FileIO_IsSuccess(result)) { err = FileMapErrorToErrno(__FUNCTION__, Err_Errno()); /* * A member file may "disappear" if is deleted (unlinked on POSIXen) * due to an unlock immediately after a directory scan but before the * scan is processed. Since this is a "normal" thing, ENOENT will be * suppressed. */ if (err != ENOENT) { Warning(LGPFX" %s open failure on '%s': %s\n", __FUNCTION__, UTF8(path), strerror(err)); } goto bail; } /* Attempt to obtain the lock file attributes now that it is opened */ err = FileAttributesRobust(path, &fileData); if (err != 0) { /* * A member file may "disappear" if is deleted (unlinked on POSIXen) * due to an unlock immediately after a directory scan but before the * scan is processed. Since this is a "normal" thing, ENOENT will be * suppressed. */ if (err != ENOENT) { Warning(LGPFX" %s file size failure on '%s': %s\n", __FUNCTION__, UTF8(path), strerror(err)); } FileIO_Close(&desc); goto bail; } /* Complain if the lock file is not the proper size */ if (fileData.fileSize != requiredSize) { Warning(LGPFX" %s file '%s': size %"FMT64"u, required size %"FMTSZ"d\n", __FUNCTION__, UTF8(path), fileData.fileSize, requiredSize); FileIO_Close(&desc); goto corrupt; } /* Attempt to read the lock file data and validate how much was read. */ result = FileIO_Read(&desc, buffer, requiredSize, &len); FileIO_Close(&desc); if (!FileIO_IsSuccess(result)) { err = FileMapErrorToErrno(__FUNCTION__, Err_Errno()); Warning(LGPFX" %s read failure on '%s': %s\n", __FUNCTION__, UTF8(path), strerror(err)); goto bail; } if (len != requiredSize) { Warning(LGPFX" %s read length issue on '%s': %"FMTSZ"d and %"FMTSZ"d\n", __FUNCTION__, UTF8(path), len, requiredSize); err = EIO; goto bail; } fixedUp: /* Extract and validate the lock file data. */ for (argc = 0; argc < FL_MAX_ARGS; argc++) { argv[argc] = strtok_r((argc == 0) ? buffer : NULL, " ", &saveptr); if (argv[argc] == NULL) { break; } } /* * Lock file arguments are space separated. There is a minimum of 5 * arguments - machineID, executionID, Lamport number, lock type * and process creation time. The maximum number of arguments is * FL_MAX_ARGS. * * Additional arguments, if present, form a property list - one or more * "name=value" pairs. * * Here is picture of valid forms: * * 0 1 2 3 4 5 6 Comment *------------------------- * A B C D E No property list * A B C D E x One property * A B C D E x y Two properties */ memberValues->locationChecksum = NULL; if ((argc < 5) || ((argc == FL_MAX_ARGS) && (strtok_r(NULL, " ", &saveptr) != NULL))) { goto corrupt; } if ((argc > 5) && FileLockParseArgs(argv, argc - 5, table, ARRAYSIZE(table))) { goto corrupt; } /* * Check for an old style lock file; if found, upgrade it (internally). * * The new style lock always has an executionID that is minimally * processID-processCreationTime (the '-' is the critical difference). */ if ((strchr(argv[1], '-') == NULL) && (strchr(argv[1], '(') == NULL) && (strchr(argv[1], ')') == NULL) && (argc == 6) && !FileLockParseArgs(argv, argc - 5, table, ARRAYSIZE(table))) { char *newBuffer; newBuffer = Str_SafeAsprintf(NULL, "%s %s-%s %s %s %s %s", argv[0], argv[1], argv[4], argv[2], argv[3], argv[4], argv[5]); Str_Strcpy(buffer, newBuffer, requiredSize); free(newBuffer); goto fixedUp; } if (sscanf(argv[2], "%u", &memberValues->lamportNumber) != 1) { goto corrupt; } if ((strcmp(argv[3], LOCK_SHARED) != 0) && (strcmp(argv[3], LOCK_EXCLUSIVE) != 0)) { goto corrupt; } memberValues->machineID = argv[0]; memberValues->executionID = argv[1]; memberValues->lockType = argv[3]; memberValues->memberName = Unicode_Duplicate(fileName); Unicode_Free(path); return 0; corrupt: Warning(LGPFX" %s removing problematic lock file '%s'\n", __FUNCTION__, UTF8(path)); if (argc) { uint32 i; Log(LGPFX" %s '%s' contents are:\n", __FUNCTION__, UTF8(fileName)); for (i = 0; i < argc; i++) { Log(LGPFX" %s %s argv[%u]: '%s'\n", __FUNCTION__, UTF8(fileName), i, argv[i]); } } /* Remove the lock file and behave like it has disappeared */ err = FileDeletionRobust(path, FALSE); if (err == 0) { err = ENOENT; } bail: Unicode_Free(path); return err; } /* *----------------------------------------------------------------------------- * * FileLockValidName -- * * Validate the format of the file name. * * Results: * TRUE Yes * FALSE No * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool FileLockValidName(ConstUnicode fileName) // IN: { uint32 i; ASSERT(fileName); /* The fileName must start with the ASCII character, 'M', 'D' or 'E' */ if (Unicode_FindSubstrInRange("MDE", 0, -1, fileName, 0, 1) == UNICODE_INDEX_NOT_FOUND) { return FALSE; } /* The fileName must contain 5 ASCII digits after the initial character */ for (i = 0; i < 5; i++) { if (Unicode_FindSubstrInRange("0123456789", 0, -1, fileName, i + 1, 1) == UNICODE_INDEX_NOT_FOUND) { return FALSE; } } /* The fileName must terminate with the appropriate suffix string */ return Unicode_EndsWith(fileName, FILELOCK_SUFFIX); } /* *----------------------------------------------------------------------------- * * FileLockActivateList * * Insure a lock list entry exists for the lock directory. * * Results: * 0 success * > 0 error (errno) * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int FileLockActivateList(ConstUnicode dirName, // IN: LockValues *myValues) // IN: { ActiveLock *ptr; ASSERT(dirName); ASSERT(Unicode_StartsWith(dirName, "D")); /* Search the list for a matching entry */ for (ptr = myValues->lockList; ptr != NULL; ptr = ptr->next) { if (Unicode_Compare(ptr->dirName, dirName) == 0) { break; } } /* No entry? Attempt to add one. */ if (ptr == NULL) { ptr = Util_SafeMalloc(sizeof *ptr); ptr->next = myValues->lockList; myValues->lockList = ptr; ptr->age = 0; ptr->dirName = Unicode_Duplicate(dirName); } /* Mark the entry (exists) */ ptr->marked = TRUE; return 0; } /* *----------------------------------------------------------------------------- * * FileLockLocationChecksum -- * * Compute the location checksum of the argument path. * * Results: * The location checksum as dynamically allocated string. * * Side effects: * None * *----------------------------------------------------------------------------- */ static char * FileLockLocationChecksum(ConstUnicode path) // IN: { int c; uint32 hash = 5381; #if defined(_WIN32) char *p; Unicode value = Unicode_Duplicate(path); /* Don't get fooled by mixed case; "normalize" */ Str_ToLower(value); p = value; #else char *p = (char *) path; #endif /* DBJ2 hash... good enough? */ while ((c = *p++)) { hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ } #if defined(_WIN32) Unicode_Free(value); #endif return Str_SafeAsprintf(NULL, "%u", hash); } /* *----------------------------------------------------------------------------- * * FileLockScanDirectory -- * * Call the specified function for each member file found in the * specified directory. * * Results: * 0 success * > 0 failure * * Side effects: * Anything that this not a valid locking file is deleted. * *----------------------------------------------------------------------------- */ static int FileLockScanDirectory(ConstUnicode lockDir, // IN: int (*func)( // IN: ConstUnicode lockDir, ConstUnicode fileName, LockValues *memberValues, LockValues *myValues ), LockValues *myValues, // IN: Bool cleanUp) // IN: { uint32 i; int err; int numEntries; Unicode *fileList = NULL; char *myExecutionID = NULL; char *locationChecksum = NULL; ASSERT(lockDir); numEntries = FileListDirectoryRobust(lockDir, &fileList); if (numEntries == -1) { Log(LGPFX" %s: Could not read the directory '%s': %d\n", __FUNCTION__, UTF8(lockDir), Err_Errno()); return EDOM; // out of my domain } /* Pass 1: Validate entries and handle any 'D' entries */ for (i = 0, err = 0; i < numEntries; i++) { /* Remove any non-locking files */ if (!FileLockValidName(fileList[i])) { Log(LGPFX" %s discarding %s from %s'; invalid file name.\n", __FUNCTION__, UTF8(fileList[i]), UTF8(lockDir)); err = FileLockRemoveLockingFile(lockDir, fileList[i]); if (err != 0) { goto bail; } Unicode_Free(fileList[i]); fileList[i] = NULL; continue; } /* * Any lockers appear to be entering? * * This should be rather rare. If a locker dies while entering * this will cleaned-up. */ if (Unicode_StartsWith(fileList[i], "D")) { if (cleanUp) { err = FileLockActivateList(fileList[i], myValues); if (err != 0) { goto bail; } } Unicode_Free(fileList[i]); fileList[i] = NULL; } } if (myValues->lockList != NULL) { goto bail; } myExecutionID = FileLockGetExecutionID(); locationChecksum = FileLockLocationChecksum(lockDir); /* Pass 2: Handle the 'M' entries */ for (i = 0, err = 0; i < numEntries; i++) { LockValues *ptr; Bool myLockFile; LockValues memberValues; char buffer[FILELOCK_DATA_SIZE]; if ((fileList[i] == NULL) || (Unicode_StartsWith(fileList[i], "E"))) { continue; } myLockFile = (Unicode_Compare(fileList[i], myValues->memberName) == 0) ? TRUE : FALSE; if (myLockFile) { /* It's me! No need to read or validate anything. */ ptr = myValues; } else { /* It's not me! Attempt to extract the member values. */ err = FileLockMemberValues(lockDir, fileList[i], buffer, FILELOCK_DATA_SIZE, &memberValues); if (err != 0) { if (err == ENOENT) { err = 0; /* Not there anymore; locker unlocked or timed out */ continue; } break; } /* Remove any stale locking files */ if (FileLockMachineIDMatch(myValues->machineID, memberValues.machineID)) { Unicode dispose = NULL; if (FileLockValidExecutionID(memberValues.executionID)) { /* If it's mine it better still be where I put it! */ if ((strcmp(myExecutionID, memberValues.executionID) == 0) && ((memberValues.locationChecksum != NULL) && (strcmp(memberValues.locationChecksum, locationChecksum) != 0))) { dispose = Unicode_Duplicate("lock file has been moved."); } } else { dispose = Str_SafeAsprintf(NULL, "invalid executionID %s.", memberValues.executionID); } if (dispose) { Log(LGPFX" %s discarding %s from %s': %s\n", __FUNCTION__, UTF8(fileList[i]), UTF8(lockDir), dispose); Unicode_Free(dispose); Unicode_Free(memberValues.memberName); err = FileLockRemoveLockingFile(lockDir, fileList[i]); if (err != 0) { break; } continue; } } ptr = &memberValues; } /* Locking file looks good; see what happens */ err = (*func)(lockDir, fileList[i], ptr, myValues); if (ptr == &memberValues) { Unicode_Free(memberValues.memberName); } if (err != 0) { break; } } bail: for (i = 0; i < numEntries; i++) { Unicode_Free(fileList[i]); } free(fileList); free(locationChecksum); free(myExecutionID); return err; } /* *----------------------------------------------------------------------------- * * FileLockScanner -- * * Call the specified function for each member file found in the * specified directory. If a rescan is necessary check the list * of outstanding locks and handle removing stale locks. * * Results: * 0 success * > 0 failure * * Side effects: * None * *----------------------------------------------------------------------------- */ static int FileLockScanner(ConstUnicode lockDir, // IN: int (*func)( // IN: ConstUnicode lockDir, ConstUnicode fileName, LockValues *memberValues, LockValues *myValues ), LockValues *myValues, // IN: Bool cleanUp) // IN: { int err; ActiveLock *ptr; ASSERT(lockDir); myValues->lockList = NULL; while (TRUE) { ActiveLock *prev; err = FileLockScanDirectory(lockDir, func, myValues, cleanUp); if ((err > 0) || ((err == 0) && (myValues->lockList == NULL))) { break; } prev = NULL; ptr = myValues->lockList; /* * Some 'D' entries have persisted. Age them and remove those that * have not progressed. Remove those that have disappeared. */ while (ptr != NULL) { Bool remove; if (ptr->marked) { if (ptr->age > FILELOCK_PROGRESS_DEARTH) { Unicode temp; Unicode path; UnicodeIndex index; ASSERT(Unicode_StartsWith(ptr->dirName, "D")); Log(LGPFX" %s discarding %s data from '%s'.\n", __FUNCTION__, UTF8(ptr->dirName), UTF8(lockDir)); path = Unicode_Join(lockDir, DIRSEPS, ptr->dirName, NULL); index = Unicode_FindLast(path, "D"); ASSERT(index != UNICODE_INDEX_NOT_FOUND); temp = Unicode_Replace(path, index, 1, "M"); FileDeletionRobust(temp, FALSE); Unicode_Free(temp); temp = Unicode_Replace(path, index, 1, "E"); FileDeletionRobust(temp, FALSE); Unicode_Free(temp); FileRemoveDirectoryRobust(path); Unicode_Free(path); remove = TRUE; } else { ptr->marked = FALSE; ptr->age += FILELOCK_PROGRESS_SAMPLE; remove = FALSE; } } else { remove = TRUE; } if (remove) { if (prev == NULL) { myValues->lockList = ptr->next; } else { prev->next = ptr->next; } } prev = ptr; ptr = ptr->next; } FileSleeper(FILELOCK_PROGRESS_SAMPLE, FILELOCK_PROGRESS_SAMPLE); // relax } /* Clean up anything still on the list; they are no longer important */ while (myValues->lockList != NULL) { ptr = myValues->lockList; myValues->lockList = ptr->next; Unicode_Free(ptr->dirName); free(ptr); } return err; } /* *----------------------------------------------------------------------------- * * FileUnlockIntrinsic -- * * Release a lock on a file. * * Results: * 0 unlocked * > 0 errno * * Side effects: * None. * *----------------------------------------------------------------------------- */ int FileUnlockIntrinsic(FileLockToken *tokenPtr) // IN: { int err = 0; ASSERT(tokenPtr && (tokenPtr->signature == FILELOCK_TOKEN_SIGNATURE)); LOG(1, ("Requesting unlock on %s\n", UTF8(tokenPtr->pathName))); if (tokenPtr->portable) { /* * If the lockFilePath (a pointer) is the fixed-address token representing * an implicit read lock, there is no lock file and the token can simply * be discarded. */ if (tokenPtr->u.portable.lockFilePath != &implicitReadToken) { Unicode lockDir; /* The lock directory path */ lockDir = Unicode_Append(tokenPtr->pathName, FILELOCK_SUFFIX); /* * TODO: under vmx86_debug validate the contents of the lock file as * matching the machineID and executionID. */ err = FileDeletionRobust(tokenPtr->u.portable.lockFilePath, FALSE); FileRemoveDirectoryRobust(lockDir); // just in case we can clean up if (err && vmx86_debug) { Log(LGPFX" %s failed for '%s': %s\n", __FUNCTION__, UTF8(tokenPtr->u.portable.lockFilePath), strerror(err)); } Unicode_Free(lockDir); Unicode_Free(tokenPtr->u.portable.lockFilePath); } tokenPtr->u.portable.lockFilePath = NULL; // Just in case... } else { ASSERT(FileIO_IsValid(&tokenPtr->u.mandatory.lockFd)); if (FileIO_CloseAndUnlink(&tokenPtr->u.mandatory.lockFd)) { /* * Should succeed, but there is an unavoidable race: * close() must preceed unlink(), but another thread could touch * the file between close() and unlink(). We only worry about other * FileLock-like manipulations; the advisory lock file should not * experience any name collisions. Treat races as success. * Specific errors: * EBUSY: other locked file * ENOENT: other locked + unlocked (w/ implicit unlink) file */ if (Err_Errno() == EBUSY || Err_Errno() == ENOENT) { LOG(0, ("Tolerating %s on unlink of advisory lock at %s\n", Err_Errno() == EBUSY ? "EBUSY" : "ENOENT", UTF8(tokenPtr->pathName))); } else { err = Err_Errno(); if (vmx86_debug) { Log(LGPFX" %s failed for advisory lock '%s': %s\n", __FUNCTION__, UTF8(tokenPtr->pathName), strerror(err)); } } } } Unicode_Free(tokenPtr->pathName); tokenPtr->signature = 0; // Just in case... tokenPtr->pathName = NULL; // Just in case... free(tokenPtr); return err; } /* *----------------------------------------------------------------------------- * * FileLockWaitForPossession -- * * Wait until the caller has a higher priority towards taking * possession of a lock than the specified file. * * Results: * 0 success * > 0 error (errno) * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int FileLockWaitForPossession(ConstUnicode lockDir, // IN: ConstUnicode fileName, // IN: LockValues *memberValues, // IN: LockValues *myValues) // IN: { int err = 0; ASSERT(lockDir); ASSERT(fileName); /* "Win" or wait? */ if (((memberValues->lamportNumber < myValues->lamportNumber) || ((memberValues->lamportNumber == myValues->lamportNumber) && (Unicode_Compare(memberValues->memberName, myValues->memberName) < 0))) && ((strcmp(memberValues->lockType, LOCK_EXCLUSIVE) == 0) || (strcmp(myValues->lockType, LOCK_EXCLUSIVE) == 0))) { Unicode path; uint32 loopCount; Bool thisMachine; thisMachine = FileLockMachineIDMatch(myValues->machineID, memberValues->machineID); loopCount = 0; path = Unicode_Join(lockDir, DIRSEPS, fileName, NULL); while ((err = FileLockSleeper(myValues, &loopCount)) == 0) { /* still there? */ err = FileAttributesRobust(path, NULL); if (err != 0) { if (err == ENOENT) { /* Not there anymore; locker unlocked or timed out */ err = 0; } break; } /* still valid? */ if (thisMachine && !FileLockValidExecutionID(memberValues->executionID)) { /* Invalid Execution ID; remove the member file */ Warning(LGPFX" %s discarding file '%s'; invalid executionID.\n", __FUNCTION__, UTF8(path)); err = FileLockRemoveLockingFile(lockDir, fileName); break; } } /* * Log the disposition of each timeout for all non "try lock" locking * attempts. This can assist in debugging locking problems. */ if ((myValues->msecMaxWaitTime != FILELOCK_TRYLOCK_WAIT) && (err == EAGAIN)) { if (thisMachine) { Log(LGPFX" %s timeout on '%s' due to a local process '%s'\n", __FUNCTION__, UTF8(path), memberValues->executionID); } else { Log(LGPFX" %s timeout on '%s' due to another machine '%s'\n", __FUNCTION__, UTF8(path), memberValues->machineID); } } Unicode_Free(path); } return err; } /* *----------------------------------------------------------------------------- * * FileLockNumberScan -- * * Determine the maxmimum number value within the current locking set. * * Results: * 0 success * > 0 failure (errno) * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int FileLockNumberScan(ConstUnicode lockDir, // IN: ConstUnicode fileName, // IN: LockValues *memberValues, // IN: LockValues *myValues) // IN/OUT: { ASSERT(lockDir); ASSERT(fileName); if (memberValues->lamportNumber > myValues->lamportNumber) { myValues->lamportNumber = memberValues->lamportNumber; } return 0; } /* *----------------------------------------------------------------------------- * * FileLockMakeDirectory -- * * Create a directory. * * Results: * 0 success * > 0 failure (errno) * * Side Effects: * File system may be modified. * *----------------------------------------------------------------------------- */ static int FileLockMakeDirectory(ConstUnicode pathName) // IN: { int err; #if !defined(_WIN32) mode_t save; save = umask(0); #endif ASSERT(pathName); err = FileCreateDirectoryRobust(pathName, 0777); #if !defined(_WIN32) umask(save); #endif return err; } /* *----------------------------------------------------------------------------- * * FileLockCreateEntryDirectory -- * * Create an entry directory in the specified locking directory. * * Due to FileLock_Unlock() attempting to remove the locking * directory on an unlock operation (to "clean up" and remove the * locking directory when it is no longer needed), this routine * must carefully handle a number of race conditions to insure the * the locking directory exists and the entry directory is created * within. * * Results: * 0 success * > 0 failure (errno) * * Side Effects: * On success returns the number identifying the entry directory and * the entry directory path name. * *----------------------------------------------------------------------------- */ static int FileLockCreateEntryDirectory(ConstUnicode lockDir, // IN: Unicode *entryDirectory, // OUT: Unicode *entryFilePath, // OUT: Unicode *memberFilePath, // OUT: Unicode *memberName) // OUT: { int err = 0; uint32 randomNumber = 0; ASSERT(lockDir); *entryDirectory = NULL; *entryFilePath = NULL; *memberFilePath = NULL; *memberName = NULL; /* Fun at the races */ while (TRUE) { Unicode temp; FileData fileData; err = FileAttributesRobust(lockDir, &fileData); if (err == 0) { /* The name exists. Deal with it... */ if (fileData.fileType == FILE_TYPE_REGULAR) { /* * It's a file. Assume this is an (active?) old style lock and * err on the safe side - don't remove it (and automatically * upgrade to a new style lock). */ Log(LGPFX" %s: '%s' exists; an old style lock file?\n", __FUNCTION__, UTF8(lockDir)); err = EBUSY; break; } if (fileData.fileType != FILE_TYPE_DIRECTORY) { /* Not a directory; attempt to remove the debris */ if (FileDeletionRobust(lockDir, FALSE) != 0) { Warning(LGPFX" %s: '%s' exists and is not a directory.\n", __FUNCTION__, UTF8(lockDir)); err = ENOTDIR; break; } continue; } } else { if (err == ENOENT) { /* Not there anymore; locker unlocked or timed out */ err = FileLockMakeDirectory(lockDir); if ((err != 0) && (err != EEXIST)) { Warning(LGPFX" %s creation failure on '%s': %s\n", __FUNCTION__, UTF8(lockDir), strerror(err)); break; } } else { Warning(LGPFX" %s stat failure on '%s': %s\n", __FUNCTION__, UTF8(lockDir), strerror(err)); break; } } /* There is a small chance of collision/failure; grab stings now */ randomNumber = (FileSimpleRandom() >> 8) & 0xFFFF; *memberName = Unicode_Format("M%05u%s", randomNumber, FILELOCK_SUFFIX); temp = Unicode_Format("D%05u%s", randomNumber, FILELOCK_SUFFIX); *entryDirectory = Unicode_Join(lockDir, DIRSEPS, temp, NULL); Unicode_Free(temp); temp = Unicode_Format("E%05u%s", randomNumber, FILELOCK_SUFFIX); *entryFilePath = Unicode_Join(lockDir, DIRSEPS, temp, NULL); Unicode_Free(temp); *memberFilePath = Unicode_Join(lockDir, DIRSEPS, *memberName, NULL); err = FileLockMakeDirectory(*entryDirectory); if (err == 0) { /* * The entry directory was safely created. See if a member file * is in use (the entry directory is removed once the member file * is created). If a member file is in use, choose another number, * otherwise the use of the this number is OK. * * Err on the side of caution... don't want to trash perfectly * good member files. */ err = FileAttributesRobust(*memberFilePath, NULL); if (err != 0) { if (err == ENOENT) { err = 0; break; } if (vmx86_debug) { Log(LGPFX" %s stat failure on '%s': %s\n", __FUNCTION__, UTF8(*memberFilePath), strerror(err)); } } FileRemoveDirectoryRobust(*entryDirectory); } else { if ((err != EEXIST) && // Another process/thread created it... (err != ENOENT)) { // lockDir is gone... Warning(LGPFX" %s creation failure on '%s': %s\n", __FUNCTION__, UTF8(*entryDirectory), strerror(err)); break; } } Unicode_Free(*entryDirectory); Unicode_Free(*entryFilePath); Unicode_Free(*memberFilePath); Unicode_Free(*memberName); *entryDirectory = NULL; *entryFilePath = NULL; *memberFilePath = NULL; *memberName = NULL; } if (err != 0) { Unicode_Free(*entryDirectory); Unicode_Free(*entryFilePath); Unicode_Free(*memberFilePath); Unicode_Free(*memberName); *entryDirectory = NULL; *entryFilePath = NULL; *memberFilePath = NULL; *memberName = NULL; } return err; } /* *----------------------------------------------------------------------------- * * FileLockCreateMemberFile -- * * Create the member file. * * Results: * 0 success * > 0 failure (errno) * * Side Effects: * None * *----------------------------------------------------------------------------- */ static int FileLockCreateMemberFile(FileIODescriptor *desc, // IN: const LockValues *myValues, // IN: ConstUnicode entryFilePath, // IN: ConstUnicode memberFilePath) // IN: { int cnt; int pid; size_t len; FileIOResult result; uint64 processCreationTime; int err = 0; char buffer[FILELOCK_DATA_SIZE] = { 0 }; ASSERT(entryFilePath); ASSERT(memberFilePath); /* * Populate the buffer with appropriate data * * Lock file arguments are space separated. There is a minimum of 5 * arguments - machineID, executionID, Lamport number, lock type * and process creation time. The maximum number of arguments is * FL_MAX_ARGS. * * Additional arguments, if present, form a property list - one or more * "name=value" pairs. * * Yes, the process creation time is redundently encoded. This is necessary * to maintain backwards compatibility. Should an older code pick up a * newer lock file and there is lock contention, the older code will log * the name of the process causing the contention - it's also encoded * into the executionID. */ cnt = sscanf(myValues->executionID, "%d-%"FMT64"u", &pid, &processCreationTime); ASSERT(cnt == 2); // ensure new format executionID Str_Sprintf(buffer, sizeof buffer, "%s %s %u %s %"FMT64"u lc=%s", myValues->machineID, myValues->executionID, myValues->lamportNumber, myValues->lockType, processCreationTime, myValues->locationChecksum); /* Attempt to write the data */ result = FileIO_Write(desc, buffer, sizeof buffer, &len); if (!FileIO_IsSuccess(result)) { err = FileMapErrorToErrno(__FUNCTION__, Err_Errno()); Warning(LGPFX" %s write of '%s' failed: %s\n", __FUNCTION__, UTF8(entryFilePath), strerror(err)); FileIO_Close(desc); return err; } if (FileIO_Close(desc)) { err = FileMapErrorToErrno(__FUNCTION__, Err_Errno()); Warning(LGPFX" %s close of '%s' failed: %s\n", __FUNCTION__, UTF8(entryFilePath), strerror(err)); return err; } if (len != sizeof buffer) { Warning(LGPFX" %s write length issue on '%s': %"FMTSZ"d and %"FMTSZ"d\n", __FUNCTION__, UTF8(entryFilePath), len, sizeof buffer); return EIO; } err = File_Rename(entryFilePath, memberFilePath); if (err != 0) { Warning(LGPFX" %s FileRename of '%s' to '%s' failed: %s\n", __FUNCTION__, UTF8(entryFilePath), UTF8(memberFilePath), strerror(err)); if (vmx86_debug) { Log(LGPFX" %s FileLockFileType() of '%s': %s\n", __FUNCTION__, UTF8(entryFilePath), strerror(FileAttributesRobust(entryFilePath, NULL))); Log(LGPFX" %s FileLockFileType() of '%s': %s\n", __FUNCTION__, UTF8(memberFilePath), strerror(FileAttributesRobust(memberFilePath, NULL))); } return err; } return 0; } /* *----------------------------------------------------------------------------- * * FileLockIntrinsicMandatory -- * * Obtain a lock on a file; shared or exclusive access. * * This implementation uses the FILEIO_OPEN_LOCK_MANDATORY flag, * which requires kernel support for mandatory locking. Such locks * are automatically broken if the host holding the lock fails. * * msecMaxWaitTime specifies the maximum amount of time, in * milliseconds, to wait for the lock before returning the "not * acquired" status. A value of FILELOCK_TRYLOCK_WAIT is the * equivalent of a "try lock" - the lock will be acquired only if * there is no contention. A value of FILELOCK_INFINITE_WAIT * specifies "waiting forever" to acquire the lock. * * Results: * NULL Lock not acquired. Check err. * err 0 Lock Timed Out * err > 0 errno * !NULL Lock Acquired. This is the "lockToken" for an unlock. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static FileLockToken * FileLockIntrinsicMandatory(ConstUnicode pathName, // IN: ConstUnicode lockFile, // IN: LockValues *myValues, // IN/OUT: int *err) // OUT: { int access; int loopCount = 0; FileIOResult result; FileLockToken *tokenPtr = Util_SafeMalloc(sizeof(FileLockToken)); tokenPtr->signature = FILELOCK_TOKEN_SIGNATURE; tokenPtr->portable = FALSE; tokenPtr->pathName = Unicode_Duplicate(pathName); FileIO_Invalidate(&tokenPtr->u.mandatory.lockFd); access = myValues->exclusivity ? FILEIO_OPEN_ACCESS_WRITE : FILEIO_OPEN_ACCESS_READ; access |= FILEIO_OPEN_EXCLUSIVE_LOCK; do { result = FileIOCreateRetry(&tokenPtr->u.mandatory.lockFd, lockFile, access, FILEIO_OPEN_CREATE, 0600, 0); if (result != FILEIO_LOCK_FAILED) { break; } } while (FileLockSleeper(myValues, &loopCount) == 0); if (FileIO_IsSuccess(result)) { ASSERT(FileIO_IsValid(&tokenPtr->u.mandatory.lockFd)); *err = 0; return tokenPtr; } else { *err = FileMapErrorToErrno(__FUNCTION__, Err_Errno()); Unicode_Free(tokenPtr->pathName); ASSERT(!FileIO_IsValid(&tokenPtr->u.mandatory.lockFd)); free(tokenPtr); return NULL; } } /* *----------------------------------------------------------------------------- * * FileLockIntrinsicPortable -- * * Obtain a lock on a file; shared or exclusive access. * * This implementation uses a HIGHLY portable directory-namespace + * Lamport bakery scheme that works on all filesystems that provide atomicity * of the directory namespace. (That is, all known filesystems.) * The various files involved are hidden within a "pathName.lck/" * subdirectory. * * The lock can be broken by removing the subdirectory. The lock * is self-cleaning on the same host (e.g. will detect a dead process * and will break the lock), but NOT self-cleaning across hosts. The * lock does not require any sort of time-based leases or heartbeats. * * Results: * NULL Lock not acquired. Check err. * err 0 Lock Timed Out * err > 0 errno * !NULL Lock Acquired. This is the "lockToken" for an unlock. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static FileLockToken * FileLockIntrinsicPortable(ConstUnicode pathName, // IN: ConstUnicode lockDir, // IN: LockValues *myValues, // IN/OUT: int *err) // OUT: { int access; FileIOResult result; FileIODescriptor desc; FileLockToken *tokenPtr; Unicode entryFilePath = NULL; Unicode memberFilePath = NULL; Unicode entryDirectory = NULL; ASSERT(pathName); ASSERT(err); /* * Attempt to create the locking and entry directories; obtain the * entry and member path names. */ *err = FileLockCreateEntryDirectory(lockDir, &entryDirectory, &entryFilePath, &memberFilePath, &myValues->memberName); switch (*err) { case 0: break; case EROFS: /* FALL THROUGH */ case EACCES: if (!myValues->exclusivity) { /* * Lock is for read/shared access however the lock directory could * not be created. Grant an implicit read lock whenever possible. * The address of a private variable will be used for the lock token. */ Warning(LGPFX" %s implicit %s lock succeeded on '%s'.\n", __FUNCTION__, LOCK_SHARED, UTF8(pathName)); *err = 0; memberFilePath = &implicitReadToken; } /* FALL THROUGH */ default: goto bail; } ASSERT(Unicode_LengthInCodeUnits(memberFilePath) - Unicode_LengthInCodeUnits(pathName) <= FILELOCK_OVERHEAD); /* Attempt to create the entry file */ access = FILEIO_OPEN_ACCESS_WRITE; #if defined(_WIN32) access |= FILEIO_OPEN_SHARE_DELETE; #else access |= FILEIO_OPEN_ACCESS_NOFOLLOW; #endif FileIO_Invalidate(&desc); result = FileIOCreateRetry(&desc, entryFilePath, access, FILEIO_OPEN_CREATE_SAFE, 0644, FILE_MAX_WAIT_TIME_MS); if (!FileIO_IsSuccess(result)) { *err = FileMapErrorToErrno(__FUNCTION__, Err_Errno()); /* clean up */ FileRemoveDirectoryRobust(entryDirectory); FileRemoveDirectoryRobust(lockDir); goto bail; } /* what is max(Number[1]... Number[all lockers])? */ *err = FileLockScanner(lockDir, FileLockNumberScan, myValues, FALSE); if (*err != 0) { /* clean up */ FileIO_Close(&desc); FileDeletionRobust(entryFilePath, FALSE); FileRemoveDirectoryRobust(entryDirectory); FileRemoveDirectoryRobust(lockDir); goto bail; } /* Number[i] = 1 + max([Number[1]... Number[all lockers]) */ myValues->lamportNumber++; /* Attempt to create the member file */ *err = FileLockCreateMemberFile(&desc, myValues, entryFilePath, memberFilePath); /* Remove entry directory; it has done its job */ FileRemoveDirectoryRobust(entryDirectory); if (*err != 0) { /* clean up */ FileDeletionRobust(entryFilePath, FALSE); FileDeletionRobust(memberFilePath, FALSE); FileRemoveDirectoryRobust(lockDir); goto bail; } /* Attempt to acquire the lock */ *err = FileLockScanner(lockDir, FileLockWaitForPossession, myValues, TRUE); switch (*err) { case 0: break; case EAGAIN: /* clean up */ FileDeletionRobust(memberFilePath, FALSE); FileRemoveDirectoryRobust(lockDir); /* FALL THROUGH */ default: break; } bail: Unicode_Free(entryDirectory); Unicode_Free(entryFilePath); if (*err == 0) { tokenPtr = Util_SafeMalloc(sizeof(FileLockToken)); tokenPtr->signature = FILELOCK_TOKEN_SIGNATURE; tokenPtr->portable = TRUE; tokenPtr->pathName = Unicode_Duplicate(pathName); tokenPtr->u.portable.lockFilePath = memberFilePath; } else { Unicode_Free(memberFilePath); tokenPtr = NULL; if (*err == EAGAIN) { *err = 0; // lock not acquired } } return tokenPtr; } /* *----------------------------------------------------------------------------- * * FileLockIntrinsic -- * * Obtain a lock on a file; shared or exclusive access. * * All FileLock_-based locks are advisory locks (i.e. the * lock is maintained separately from the file so only FileLock_ * callers experience locking). Advisory locks have an inherent problem * that they are difficult to break in the event one of the cooperating * entities fails, particularly across distributed filesystems. * * This wrapper function will adaptively switch between a scheme * implemented via mandatory locks and a more portable scheme depending * on host OS support. * * msecMaxWaitTime specifies the maximum amount of time, in * milliseconds, to wait for the lock before returning the "not * acquired" status. A value of FILELOCK_TRYLOCK_WAIT is the * equivalent of a "try lock" - the lock will be acquired only if * there is no contention. A value of FILELOCK_INFINITE_WAIT * specifies "waiting forever" to acquire the lock. * * Results: * NULL Lock not acquired. Check err. * err 0 Lock Timed Out * err > 0 errno * !NULL Lock Acquired. This is the "lockToken" for an unlock. * * Side effects: * None. * *----------------------------------------------------------------------------- */ FileLockToken * FileLockIntrinsic(ConstUnicode pathName, // IN: Bool exclusivity, // IN: uint32 msecMaxWaitTime, // IN: int *err) // OUT: { Unicode lockBase; LockValues myValues = { 0 }; FileLockToken *tokenPtr; /* Construct the locking directory path */ lockBase = Unicode_Append(pathName, FILELOCK_SUFFIX); myValues.lockType = exclusivity ? LOCK_EXCLUSIVE : LOCK_SHARED; myValues.exclusivity = exclusivity; myValues.waitTime = 0; myValues.msecMaxWaitTime = msecMaxWaitTime; if (File_SupportsMandatoryLock(pathName)) { LOG(1, ("Requesting %s lock on %s (mandatory, %u).\n", myValues.lockType, UTF8(pathName), myValues.msecMaxWaitTime)); tokenPtr = FileLockIntrinsicMandatory(pathName, lockBase, &myValues, err); } else { myValues.machineID = (char *) FileLockGetMachineID(); // don't free this! myValues.executionID = FileLockGetExecutionID(); // free this! myValues.lamportNumber = 0; myValues.locationChecksum = FileLockLocationChecksum(lockBase); // free this! myValues.memberName = NULL; LOG(1, ("Requesting %s lock on %s (%s, %s, %u).\n", myValues.lockType, UTF8(pathName), myValues.machineID, myValues.executionID, myValues.msecMaxWaitTime)); tokenPtr = FileLockIntrinsicPortable(pathName, lockBase, &myValues, err); Unicode_Free(myValues.memberName); free(myValues.locationChecksum); free(myValues.executionID); } Unicode_Free(lockBase); return tokenPtr; } /* *----------------------------------------------------------------------------- * * FileLockIsLockedMandatory -- * * Is a file currently locked (at the time of the call)? * * The only way to check for a mandatory lock is to try opening * the file (and quickly closing it again). If the lock is held, * attempting to open the file will return FILEIO_LOCK_FAILED. * * Results: * TRUE YES * FALSE NO; if err is not NULL may check *err for an error * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool FileLockIsLockedMandatory(ConstUnicode lockFile, // IN: int *err) // OUT/OPT: { int access; FileIOResult result; FileIODescriptor desc; FileIO_Invalidate(&desc); /* * Check for lock by actually locking file, and dropping * lock quickly if open was successful. */ access = FILEIO_OPEN_ACCESS_READ | FILEIO_OPEN_ACCESS_WRITE | FILEIO_OPEN_EXCLUSIVE_LOCK; result = FileIOCreateRetry(&desc, lockFile, access, FILEIO_OPEN, 0644, 0); if (FileIO_IsSuccess(result)) { Bool ret; ret = FileIO_Close(&desc); ASSERT(!ret); return FALSE; } else if (result == FILEIO_LOCK_FAILED) { return TRUE; // locked } else if (result == FILEIO_FILE_NOT_FOUND) { return FALSE; // no lock file means unlocked } else { if (err != NULL) { *err = FileMapErrorToErrno(__FUNCTION__, Err_Errno()); } return FALSE; } } /* *----------------------------------------------------------------------------- * * FileLockIsLockedPortable -- * * Is a file currently locked (at the time of the call)? * * The "portable" lock is held if the lock directory exists and * there are any "M" entries (representing held locks). * * FileLocks implemented via mandatory locking are reported * as held locks (errno == ENOTDIR). * * Results: * TRUE YES * FALSE NO; if err is not NULL may check *err for an error * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool FileLockIsLockedPortable(ConstUnicode lockDir, // IN: int *err) // OUT/OPT: { uint32 i; int numEntries; Bool isLocked = FALSE; Unicode *fileList = NULL; numEntries = FileListDirectoryRobust(lockDir, &fileList); if (numEntries == -1) { /* * If the lock directory doesn't exist, we should not count this * as an error. This is expected if the file isn't locked. */ if (err != NULL) { *err = (errno == ENOENT) ? 0 : errno; } return FALSE; } for (i = 0; i < numEntries; i++) { if (Unicode_StartsWith(fileList[i], "M")) { isLocked = TRUE; break; } } for (i = 0; i < numEntries; i++) { Unicode_Free(fileList[i]); } free(fileList); return isLocked; } /* *----------------------------------------------------------------------------- * * FileLockIsLocked -- * * Is a file currently locked (at the time of the call)? * * Results: * TRUE YES * FALSE NO; if err is not NULL may check *err for an error * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool FileLockIsLocked(ConstUnicode pathName, // IN: int *err) // OUT/OPT: { Bool isLocked; Unicode lockBase; ASSERT(pathName); lockBase = Unicode_Append(pathName, FILELOCK_SUFFIX); if (File_SupportsMandatoryLock(pathName)) { isLocked = FileLockIsLockedMandatory(lockBase, err); } else { isLocked = FileLockIsLockedPortable(lockBase, err); } Unicode_Free(lockBase); return isLocked; } /* *---------------------------------------------------------------------- * * FileLock_TokenPathName -- * * Return the path name associated with a lock (token). The path name * is returned as a dynamically allocated string the caller is * responsible for. * * Results: * As above * * Side effects: * None. * *---------------------------------------------------------------------- */ Unicode FileLock_TokenPathName(const FileLockToken *lockToken) // IN: { ASSERT(lockToken && (lockToken->signature == FILELOCK_TOKEN_SIGNATURE)); return Unicode_Duplicate(lockToken->pathName); } open-vm-tools-9.4.0-1280544/lib/file/fileStandAlone.c0000644765153500003110000005045312220061556020167 0ustar dtormts/********************************************************* * Copyright (C) 1998-2011 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * fileStandAlone.c -- * * This file contains lib/file routines which are unentangled - they do * not depend on other libraries besides lib/misc and its dependencies. */ #if defined(_WIN32) #include #endif #include #include #include #include #include "safetime.h" #if !defined(_WIN32) #include #endif #include #include #include #include "vmware.h" #include "util.h" #include "str.h" #include "posix.h" #include "file.h" #include "unicodeOperations.h" /* *---------------------------------------------------------------------- * * File_GetModTime -- * * Get the last modification time of a file and return it. The time * unit is seconds since the POSIX/UNIX/Linux epoch. * * Results: * Last modification time of file or -1 if error. * * Side effects: * None. * *---------------------------------------------------------------------- */ int64 File_GetModTime(ConstUnicode pathName) // IN: { int64 theTime; struct stat statbuf; if (Posix_Stat(pathName, &statbuf) == 0) { theTime = statbuf.st_mtime; } else { theTime = -1; } return theTime; } /* *---------------------------------------------------------------------- * * FileFirstSlashIndex -- * * Finds the first pathname slash index in a path (both slashes count * for Win32, only forward slash for Unix). * * Results: * As described. * * Side effects: * None. * *---------------------------------------------------------------------- */ UnicodeIndex FileFirstSlashIndex(ConstUnicode pathName, // IN: UnicodeIndex startIndex) // IN: { UnicodeIndex firstFS; #if defined(_WIN32) UnicodeIndex firstBS; #endif ASSERT(pathName); firstFS = Unicode_FindSubstrInRange(pathName, startIndex, -1, "/", 0, 1); #if defined(_WIN32) firstBS = Unicode_FindSubstrInRange(pathName, startIndex, -1, "\\", 0, 1); if ((firstFS != UNICODE_INDEX_NOT_FOUND) && (firstBS != UNICODE_INDEX_NOT_FOUND)) { return MIN(firstFS, firstBS); } else { return (firstFS == UNICODE_INDEX_NOT_FOUND) ? firstBS : firstFS; } #else return firstFS; #endif } /* *---------------------------------------------------------------------- * * FileLastSlashIndex -- * * Finds the last pathname slash index in a path (both slashes count * for Win32, only forward slash for Unix). * * Results: * As described. * * Side effects: * None. * *---------------------------------------------------------------------- */ static UnicodeIndex FileLastSlashIndex(ConstUnicode pathName, // IN: UnicodeIndex startIndex) // IN: { UnicodeIndex lastFS; #if defined(_WIN32) UnicodeIndex lastBS; #endif ASSERT(pathName); lastFS = Unicode_FindLastSubstrInRange(pathName, startIndex, -1, "/", 0, 1); #if defined(_WIN32) lastBS = Unicode_FindLastSubstrInRange(pathName, startIndex, -1, "\\", 0, 1); if ((lastFS != UNICODE_INDEX_NOT_FOUND) && (lastBS != UNICODE_INDEX_NOT_FOUND)) { return MAX(lastFS, lastBS); } else { return (lastFS == UNICODE_INDEX_NOT_FOUND) ? lastBS : lastFS; } #else return lastFS; #endif } /* *---------------------------------------------------------------------- * * File_SplitName -- * * Split a file name into three components: VOLUME, DIRECTORY, * BASE. The return values must be freed. * * VOLUME is empty for an empty string or a UNIX-style path, the * drive letter and colon for a Win32 drive-letter path, or the * construction "\\server\share" for a Win32 UNC path. * * BASE is the longest string at the end that begins after the * volume string and after the last directory separator. * * DIRECTORY is everything in-between VOLUME and BASE. * * The concatenation of VOLUME, DIRECTORY, and BASE produces the * original string, so any of those strings may be empty. * * A NULL pointer may be passed for one or more OUT parameters, in * which case that parameter is not returned. * * Able to handle both UNC and drive-letter paths on Windows. * * Results: * As described. * * Side effects: * None. * *---------------------------------------------------------------------- */ void File_SplitName(ConstUnicode pathName, // IN: Unicode *volume, // OUT (OPT): Unicode *directory, // OUT (OPT): Unicode *base) // OUT (OPT): { Unicode vol; Unicode dir; Unicode bas; UnicodeIndex volEnd; UnicodeIndex length; UnicodeIndex baseBegin; WIN32_ONLY(UnicodeIndex pathLen); ASSERT(pathName); /* * Get volume. */ volEnd = 0; #if defined(_WIN32) pathLen = Unicode_LengthInCodePoints(pathName); if ((pathLen > 2) && (Unicode_StartsWith(pathName, "\\\\") || Unicode_StartsWith(pathName, "//"))) { /* UNC path */ volEnd = FileFirstSlashIndex(pathName, 2); if (volEnd == UNICODE_INDEX_NOT_FOUND) { /* we have \\foo, which is just bogus */ volEnd = 0; } else { volEnd = FileFirstSlashIndex(pathName, volEnd + 1); if (volEnd == UNICODE_INDEX_NOT_FOUND) { /* we have \\foo\bar, which is legal */ volEnd = pathLen; } } } else if ((pathLen >= 2) && (Unicode_FindSubstrInRange(pathName, 1, 1, ":", 0, 1) != UNICODE_INDEX_NOT_FOUND)) { /* drive-letter path */ volEnd = 2; } if (volEnd > 0) { vol = Unicode_Substr(pathName, 0, volEnd); } else { vol = Unicode_Duplicate(""); } #else vol = Unicode_Duplicate(""); #endif /* _WIN32 */ /* * Get base. */ baseBegin = FileLastSlashIndex(pathName, 0); baseBegin = (baseBegin == UNICODE_INDEX_NOT_FOUND) ? 0 : baseBegin + 1; if (baseBegin >= volEnd) { bas = Unicode_Substr(pathName, baseBegin, -1); } else { bas = Unicode_Duplicate(""); } /* * Get dir. */ length = baseBegin - volEnd; if (length > 0) { dir = Unicode_Substr(pathName, volEnd, length); } else { dir = Unicode_Duplicate(""); } /* * Return what needs to be returned. */ if (volume) { *volume = vol; } else { Unicode_Free(vol); } if (directory) { *directory = dir; } else { Unicode_Free(dir); } if (base) { *base = bas; } else { Unicode_Free(bas); } } /* *--------------------------------------------------------------------------- * * File_PathJoin -- * * Join the dirName and baseName together to create a (full) path. * * This code concatenates two strings together and omits a redundant * directory separator between the two. * * On Windows, the 'baseName' argument may not be a fully qualified path. * That is, it may not be an absolute path containing a drive letter nor * may it be a UNC path. * * Examples: * File_PathJoin("", "b") -> "/b" * File_PathJoin("/", "b") -> "/b" * File_PathJoin("a", "b") -> "a/b" * File_PathJoin("a/", "b") -> "a/b" * File_PathJoin("a/////", "b") -> "a/b" * File_PathJoin("a", "") -> "a/" * File_PathJoin("a", "/") -> "a/" * File_PathJoin("a", "/b") -> "a/b" * File_PathJoin("a", "/////b") -> "a/b" (only posix) * File_PathJoin("a/", "/b") -> "a/b" * File_PathJoin("a/////", "/////b") -> "a/b" (only posix) * * Results: * The constructed path which must be freed by the caller. * * Side effects: * None * *--------------------------------------------------------------------------- */ Unicode File_PathJoin(ConstUnicode dirName, // IN: ConstUnicode baseName) // IN: See above. { Unicode result; Unicode newDir = NULL; ASSERT(dirName); ASSERT(baseName); /* * Remove ALL directory separators from baseName begin. */ #if defined(_WIN32) { ConstUnicode oldBaseName = baseName; /* * Reject drive letters in baseName. */ ASSERT(Unicode_LengthInCodePoints(baseName) < 2 || Unicode_FindSubstrInRange(baseName, 1, 1, ":", 0, 1) == UNICODE_INDEX_NOT_FOUND); while (*baseName == '/' || *baseName == '\\') { baseName++; } /* * Reject UNC paths for baseName. */ ASSERT(baseName - oldBaseName < 2); } #else while (*baseName == '/') { baseName++; } #endif /* * Remove ALL directory separators from dirName end. */ newDir = File_StripSlashes(dirName); result = Unicode_Join(newDir, DIRSEPS, baseName, NULL); Unicode_Free(newDir); return result; } /* *--------------------------------------------------------------------------- * * File_GetPathName -- * * Behaves like File_SplitName by splitting the fullpath into * pathname & filename components. * * The trailing directory separator [\|/] is stripped off the * pathname component. This in turn means that on Linux the root * directory will be returned as the empty string "". On Windows * it will be returned as X: where X is the drive letter. It is * important that callers of this functions are aware that the "" * on Linux means root "/". * * A NULL pointer may be passed for one or more OUT parameters, * in which case that parameter is not returned. * * Results: * As described. * * Side effects: * The return values must be freed. * *--------------------------------------------------------------------------- */ void File_GetPathName(ConstUnicode fullPath, // IN: Unicode *pathName, // OUT (OPT): Unicode *baseName) // OUT (OPT): { Unicode volume; UnicodeIndex len; UnicodeIndex curLen; File_SplitName(fullPath, &volume, pathName, baseName); if (pathName == NULL) { Unicode_Free(volume); return; } /* * The volume component may be empty. */ if (!Unicode_IsEmpty(volume)) { Unicode temp = Unicode_Append(volume, *pathName); Unicode_Free(*pathName); *pathName = temp; } Unicode_Free(volume); /* * Remove any trailing directory separator characters. */ len = Unicode_LengthInCodePoints(*pathName); curLen = len; while ((curLen > 0) && (FileFirstSlashIndex(*pathName, curLen - 1) == curLen - 1)) { curLen--; } if (curLen < len) { Unicode temp = Unicode_Substr(*pathName, 0, curLen); Unicode_Free(*pathName); *pathName = temp; } } /* *---------------------------------------------------------------------- * * File_StripSlashes -- * * Strip trailing slashes from the end of a path. * * Results: * The stripped filename. * * Side effects: * None. * *---------------------------------------------------------------------- */ Unicode File_StripSlashes(ConstUnicode path) // IN: { Unicode result, volume, dir, base; /* * SplitName handles all drive letter/UNC/whatever cases, all we * have to do is make sure the dir part is stripped of slashes if * there isn't a base part. */ File_SplitName(path, &volume, &dir, &base); if (!Unicode_IsEmpty(dir) && Unicode_IsEmpty(base)) { char *dir2 = Unicode_GetAllocBytes(dir, STRING_ENCODING_UTF8); size_t i = strlen(dir2); /* * Don't strip first slash on Windows, since we want at least * one slash to trail a drive letter/colon or UNC specifier. */ #if defined(_WIN32) while ((i > 1) && (('/' == dir2[i - 1]) || ('\\' == dir2[i - 1]))) { #else while ((i > 0) && ('/' == dir2[i - 1])) { #endif i--; } Unicode_Free(dir); dir = Unicode_AllocWithLength(dir2, i, STRING_ENCODING_UTF8); free(dir2); } result = Unicode_Join(volume, dir, base, NULL); Unicode_Free(volume); Unicode_Free(dir); Unicode_Free(base); return result; } /* *----------------------------------------------------------------------------- * * File_MapPathPrefix -- * * Given a path and a newPrefix -> oldPrefix mapping, transform * oldPath according to the mapping. * * Results: * The new path, or NULL if there is no mapping. * * Side effects: * The returned string is allocated, free it. * *----------------------------------------------------------------------------- */ char * File_MapPathPrefix(const char *oldPath, // IN: const char **oldPrefixes, // IN: const char **newPrefixes, // IN: size_t numPrefixes) // IN: { int i; size_t oldPathLen = strlen(oldPath); for (i = 0; i < numPrefixes; i++) { char *newPath; char *oldPrefix; char *newPrefix; size_t oldPrefixLen; oldPrefix = File_StripSlashes(oldPrefixes[i]); newPrefix = File_StripSlashes(newPrefixes[i]); oldPrefixLen = strlen(oldPrefix); /* * If the prefix matches on a DIRSEPS boundary, or the prefix is the * whole string, replace it. * * If we don't insist on matching a whole directory name, we could * mess things of if one directory is a substring of another. * * Perform a case-insensitive compare on Windows. (There are * case-insensitive filesystems on MacOS also, but the problem * is more acute with Windows because of frequent drive-letter * case mismatches. So in lieu of actually asking the * filesystem, let's just go with a simple ifdef for now.) */ if ((oldPathLen >= oldPrefixLen) && #ifdef _WIN32 (Str_Strncasecmp(oldPath, oldPrefix, oldPrefixLen) == 0) && #else (Str_Strncmp(oldPath, oldPrefix, oldPrefixLen) == 0) && #endif (strchr(VALID_DIRSEPS, oldPath[oldPrefixLen]) || (oldPath[oldPrefixLen] == '\0'))) { size_t newPrefixLen = strlen(newPrefix); size_t newPathLen = (oldPathLen - oldPrefixLen) + newPrefixLen; ASSERT(newPathLen > 0); ASSERT(oldPathLen >= oldPrefixLen); newPath = Util_SafeMalloc((newPathLen + 1) * sizeof(char)); memcpy(newPath, newPrefix, newPrefixLen); memcpy(newPath + newPrefixLen, oldPath + oldPrefixLen, oldPathLen - oldPrefixLen + 1); /* * It should only match once. Weird self-referencing mappings * aren't allowed. */ free(oldPrefix); free(newPrefix); return newPath; } free(oldPrefix); free(newPrefix); } return NULL; } /* *----------------------------------------------------------------------------- * * File_PrependToPath -- * * This function checks if the elem is already present in the * searchPath, if it is then it is moved forward in the search path. * Otherwise it is prepended to the searchPath. * * Results: * Return file search path with elem in front. * * Side effects: * Caller must free returned string. * *----------------------------------------------------------------------------- */ char * File_PrependToPath(const char *searchPath, // IN: const char *elem) // IN: { const char sep = FILE_SEARCHPATHTOKEN[0]; char *newPath; char *path; size_t n; ASSERT(searchPath); ASSERT(elem); newPath = Str_SafeAsprintf(NULL, "%s%s%s", elem, FILE_SEARCHPATHTOKEN, searchPath); n = strlen(elem); path = newPath + n + 1; for (;;) { char *next = Str_Strchr(path, sep); size_t len = next ? next - path : strlen(path); if ((len == n) && (Str_Strncmp(path, elem, len) == 0)) { if (next) { memmove(path, next + 1, strlen(next + 1) + 1); } else { *--path = '\0'; } break; } if (!next) { break; } path = next + 1; } return newPath; } /* *----------------------------------------------------------------------------- * * File_ReplaceExtension -- * * Replaces the extension in input with newExtension. * * If the old extension exists in the list of extensions specified in ..., * truncate it before appending the new extension. * * If the extension is not found in the list, the newExtension is * just appended. * * If there isn't a list of extensions specified (numExtensions == 0), * truncate the old extension unconditionally. * * NB: newExtension and the extension list must have .'s. * * Results: * The name with newExtension added to it. The caller is responsible to * free it when they are done with it. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Unicode File_ReplaceExtension(ConstUnicode pathName, // IN: ConstUnicode newExtension, // IN: uint32 numExtensions, // IN: ...) // IN: { Unicode path; Unicode base; Unicode result; va_list arguments; UnicodeIndex index; ASSERT(pathName); ASSERT(newExtension); ASSERT(Unicode_StartsWith(newExtension, ".")); File_GetPathName(pathName, &path, &base); index = Unicode_FindLast(base, "."); if (index != UNICODE_INDEX_NOT_FOUND) { Unicode oldBase = base; if (numExtensions) { uint32 i; /* * Only truncate the old extension from the base if it exists in * in the valid extensions list. */ va_start(arguments, numExtensions); for (i = 0; i < numExtensions ; i++) { Unicode oldExtension = va_arg(arguments, Unicode); ASSERT(Unicode_StartsWith(oldExtension, ".")); if (Unicode_CompareRange(base, index, -1, oldExtension, 0, -1, FALSE) == 0) { base = Unicode_Truncate(oldBase, index); // remove '.' break; } } va_end(arguments); } else { /* Always truncate the old extension if extension list is empty . */ base = Unicode_Truncate(oldBase, index); // remove '.' } if (oldBase != base) { Unicode_Free(oldBase); } } if (Unicode_IsEmpty(path)) { result = Unicode_Append(base, newExtension); } else { result = Unicode_Join(path, DIRSEPS, base, newExtension, NULL); } Unicode_Free(path); Unicode_Free(base); return result; } /* *----------------------------------------------------------------------------- * * File_RemoveExtension -- * * Return a copy of the given path name with the extension * removed. We ASSERT that the given path does have an extension. * * Results: * A newly allocated buffer with the modified string. The caller * is responsible to free it when they are done with it. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Unicode File_RemoveExtension(ConstUnicode pathName) // IN: { UnicodeIndex index; ASSERT(pathName); index = Unicode_FindLast(pathName, "."); ASSERT(index != UNICODE_INDEX_NOT_FOUND); return Unicode_Truncate(pathName, index); } open-vm-tools-9.4.0-1280544/lib/file/fileIOPosix.c0000644765153500003110000023152312220061556017470 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * fileIOPosix.c -- * * Implementation of the file library host specific functions for linux. */ #if !defined(VMX86_TOOLS) && !defined(__APPLE__) && !defined(sun) #define FILEIO_SUPPORT_ODIRECT #define _GNU_SOURCE #endif #include #include #include #include #if defined __ANDROID__ #include // for __NR_SYSCALL_BASE #endif #include #include #include #include #if defined(linux) /* * These headers are needed to get __USE_LARGEFILE, __USE_LARGEFILE64, * and SYS__llseek. */ # ifdef ANDROID_X86 # undef _GNU_SOURCE # endif # include # ifndef _GNU_SOURCE # define _GNU_SOURCE # endif # include #ifdef __ANDROID__ # include #else # include #endif #endif #if defined __ANDROID__ # include #endif #include #include "su.h" #if defined(__APPLE__) #include "sysSocket.h" // Don't move this: it fixes a system header. #include #include #include #include #include #include #include #include #include #include #include #else #if defined(__FreeBSD__) #include #include #else #include #if !defined(sun) #include #include #endif #endif #endif /* Check for non-matching prototypes */ #include "vmware.h" #include "str.h" #include "err.h" #include "posix.h" #include "file.h" #include "fileIO.h" #include "fileInt.h" #include "config.h" #include "util.h" #include "iovector.h" #include "hostType.h" #include "unicodeOperations.h" #include "memaligned.h" #include "userlock.h" #include "hostinfo.h" #if defined(__APPLE__) #include /* * F_NODIRECT was added in Mac OS 10.7.0 "Lion". We test at runtime for the * right version before using it, but we also need to get the definition. */ #include #ifndef F_NODIRECT #define F_NODIRECT 62 #endif #endif /* * fallocate() is only supported since the glibc-2.8 and * linux kernel-2.6.23. Presently the glibc in our toolchain is 2.3. */ #if defined(__linux__) #if !defined(SYS_fallocate) #if defined(__i386__) #define SYS_fallocate 324 #elif __x86_64__ #define SYS_fallocate 285 #elif __arm__ #define SYS_fallocate (__NR_SYSCALL_BASE+352) // newer glibc value #endif #endif #if !defined(FALLOC_FL_KEEP_SIZE) #define FALLOC_FL_KEEP_SIZE 1 #endif #endif static const unsigned int FileIO_SeekOrigins[] = { SEEK_SET, SEEK_CUR, SEEK_END, }; static const int FileIO_OpenActions[] = { 0, O_TRUNC, O_CREAT, O_CREAT | O_EXCL, O_CREAT | O_TRUNC, }; /* * Options for FileCoalescing performance optimization */ typedef struct FilePosixOptions { Bool initialized; Bool aligned; Bool enabled; int countThreshold; int sizeThreshold; int aioNumThreads; } FilePosixOptions; static FilePosixOptions filePosixOptions; /* * Data structures for FileIOAligned_* functions; only used on * hosted (see fileInt.h for rationale). */ #if !defined(VMX86_TOOLS) && !defined(VMX86_SERVER) #define ALIGNEDPOOL_FREELIST_SIZE 30 #define ALIGNEDPOOL_BUFSZ (1024 * 1024) #define ALIGNEDPOOL_OLD_AGE ((VmTimeType)1000 * 1000 * 1000) /* nanoseconds */ typedef struct AlignedPool { MXUserExclLock *lock; /* * list: Array of allocated buffers. * 0 .. numBusy-1 : busy buffers (in use by a caller). * numBusy .. numAlloc-1 : allocated but not busy. * numAlloc .. SIZE-1 : unused. */ void *list[ALIGNEDPOOL_FREELIST_SIZE]; /* * timestamp: Array of release timestamps. * 0 .. numBusy-1 : unused. * numBusy .. numAlloc-1 : last time we had N buffers outstanding. * numAlloc .. SIZE-1 : unused. */ VmTimeType timestamp[ALIGNEDPOOL_FREELIST_SIZE]; /* invariant: 0 <= numBusy <= numAlloc <= ALIGNEDPOOL_FREELIST_SIZE */ unsigned numAlloc; unsigned numBusy; } AlignedPool; static Atomic_Ptr alignedPoolLockStorage; static AlignedPool alignedPool; #endif /* * Although, support for preadv()/pwrite() first appeared in Linux 2.6.30, * library support was added in glibc 2.10. Hence these functions * are not available in any header file. */ #if defined(__linux__) #if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64) extern ssize_t preadv64(int fd, const struct iovec *iov, int iovcnt, off64_t offset) __attribute__ ((weak)); extern ssize_t pwritev64(int fd, const struct iovec *iov, int iovcnt, off64_t offset) __attribute__ ((weak)); #else #error "Large file support unavailable. Aborting." #endif #endif /* defined(__linux__) */ /* *----------------------------------------------------------------------------- * * FileIOErrno2Result -- * * Convert a POSIX errno to a FileIOResult code. * * Results: * The FileIOResult corresponding to the errno, FILEIO_ERROR by default. * * Side effects: * None * *----------------------------------------------------------------------------- */ static FileIOResult FileIOErrno2Result(int error) // IN: errno to convert { switch (error) { case EEXIST: return FILEIO_OPEN_ERROR_EXIST; case ENOENT: return FILEIO_FILE_NOT_FOUND; case EACCES: return FILEIO_NO_PERMISSION; case ENAMETOOLONG: return FILEIO_FILE_NAME_TOO_LONG; case ENOSPC: return FILEIO_WRITE_ERROR_NOSPC; case EFBIG: return FILEIO_WRITE_ERROR_FBIG; #if defined(VMX86_SERVER) case EBUSY: return FILEIO_LOCK_FAILED; #endif #if defined(EDQUOT) case EDQUOT: return FILEIO_WRITE_ERROR_DQUOT; #endif default: Log("%s: Unexpected errno=%d, %s\n", __FUNCTION__, error, Err_Errno2String(error)); return FILEIO_ERROR; } } /* *---------------------------------------------------------------------- * * FileIO_OptionalSafeInitialize -- * * Initialize global state. If this module is called from a * thread other than the VMX or VCPU threads, like an aioGeneric worker * thread, then we cannot do things like call config. Do that sort * of initialization here, which is called from a safe thread. * * This routine is OPTIONAL if you do not call this module from a * worker thread. The same initialization can be done lazily when * a read/write routine is called. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ INLINE void FileIO_OptionalSafeInitialize(void) { if (!filePosixOptions.initialized) { filePosixOptions.enabled = Config_GetBool(TRUE, "filePosix.coalesce.enable"); /* * Aligned malloc starts failing to allocate memory during heavy I/O on * Linux. We're not sure why -- maybe we are running out of mmaps? * Turn it off by default for now. */ filePosixOptions.aligned = Config_GetBool(FALSE, "filePosix.coalesce.aligned"); filePosixOptions.countThreshold = Config_GetLong(5, "filePosix.coalesce.count"); filePosixOptions.sizeThreshold = Config_GetLong(16*1024, "filePosix.coalesce.size"); filePosixOptions.aioNumThreads = Config_GetLong(0, "aiomgr.numThreads"); filePosixOptions.initialized = TRUE; FileIOAligned_PoolInit(); } } /* *---------------------------------------------------------------------- * * FileIO_Invalidate -- * * Initialize a FileIODescriptor with an invalid value * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ void FileIO_Invalidate(FileIODescriptor *fd) // OUT: { ASSERT(fd); (memset)(fd, 0, sizeof *fd); fd->posix = -1; } /* *---------------------------------------------------------------------- * * FileIO_IsValid -- * * Check whether a FileIODescriptor is valid. * * Results: * True if valid. * * Side effects: * None * *---------------------------------------------------------------------- */ Bool FileIO_IsValid(const FileIODescriptor *fd) // IN: { ASSERT(fd); return fd->posix != -1; } /* *---------------------------------------------------------------------- * * FileIO_CreateFDPosix -- * * This function is for specific needs: for example, when you need * to create a FileIODescriptor from an already open fd. Use only * FileIO_* library functions on the FileIODescriptor from that point on. * * Because FileIODescriptor struct is different on two platforms, * this function is the only one in the file library that's * platform-specific. * * Results: * FileIODescriptor * * Side effects: * None * *---------------------------------------------------------------------- */ FileIODescriptor FileIO_CreateFDPosix(int posix, // IN: UNIX file descriptor int flags) // IN: UNIX access flags { FileIODescriptor fd; FileIO_Invalidate(&fd); switch (flags & O_ACCMODE) { case O_RDWR: fd.flags |= (FILEIO_OPEN_ACCESS_READ | FILEIO_OPEN_ACCESS_WRITE); break; case O_WRONLY: fd.flags |= FILEIO_OPEN_ACCESS_WRITE; break; default: ASSERT(FALSE); /* FALLTHRU */ case O_RDONLY: fd.flags |= FILEIO_OPEN_ACCESS_READ; break; } #if defined(O_SYNC) // Not available in FreeBSD tools build if (flags & O_SYNC) { fd.flags |= FILEIO_OPEN_SYNC; } #endif if (flags & O_APPEND) { fd.flags |= FILEIO_OPEN_APPEND; } fd.posix = posix; return fd; } /* *---------------------------------------------------------------------- * * FileIO_GetVolumeSectorSize -- * * Get sector size of underlying volume. * * Results: * Always 512, there does not seem to be a way to query sectorSize * from filename. But O_DIRECT boundary alignment constraint is * always 512, so use that. * * Side effects: * None * *---------------------------------------------------------------------- */ Bool FileIO_GetVolumeSectorSize(ConstUnicode pathName, // IN: uint32 *sectorSize) // OUT: { ASSERT(sectorSize); *sectorSize = 512; return TRUE; } #if defined(__APPLE__) /* *---------------------------------------------------------------------- * * ProxySendResults -- * * Send the results of a open from the proxy. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void ProxySendResults(int sock_fd, // IN: int send_fd, // IN: int send_errno) // IN: { struct iovec iov; struct msghdr msg; char cmsgBuf[CMSG_SPACE(sizeof send_fd)]; iov.iov_base = &send_errno; iov.iov_len = sizeof send_errno; if (send_fd == -1) { msg.msg_control = NULL; msg.msg_controllen = 0; } else { struct cmsghdr *cmsg; msg.msg_control = cmsgBuf; msg.msg_controllen = sizeof cmsgBuf; cmsg = CMSG_FIRSTHDR(&msg); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_len = CMSG_LEN(sizeof send_fd); cmsg->cmsg_type = SCM_RIGHTS; (*(int *) CMSG_DATA(cmsg)) = send_fd; msg.msg_controllen = cmsg->cmsg_len; } msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_flags = 0; sendmsg(sock_fd, &msg, 0); } /* *---------------------------------------------------------------------- * * ProxyReceiveResults -- * * Receive the results of an open from the proxy. * * Results: * None * * Side effects: * None * *---------------------------------------------------------------------- */ static void ProxyReceiveResults(int sock_fd, // IN: int *recv_fd, // OUT: int *recv_errno) // OUT: { int err; struct iovec iov; struct msghdr msg; struct cmsghdr *cmsg; uint8_t cmsgBuf[CMSG_SPACE(sizeof(int))]; iov.iov_base = recv_errno; iov.iov_len = sizeof *recv_errno; msg.msg_control = cmsgBuf; msg.msg_controllen = sizeof cmsgBuf; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = &iov; msg.msg_iovlen = 1; err = recvmsg(sock_fd, &msg, 0); if (err <= 0) { *recv_fd = -1; *recv_errno = (err == 0) ? EIO : errno; return; } if (msg.msg_controllen == 0) { *recv_fd = -1; } else { cmsg = CMSG_FIRSTHDR(&msg); if ((cmsg->cmsg_level == SOL_SOCKET) && (cmsg->cmsg_type == SCM_RIGHTS)) { *recv_fd = *((int *) CMSG_DATA(cmsg)); } else { *recv_fd = -1; *recv_errno = EIO; } } } /* *---------------------------------------------------------------------- * * ProxyOpen -- * * Open a file via a proxy. * * Results: * -1 on error * >= 0 on success * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ static int ProxyOpen(ConstUnicode pathName, // IN: int flags, // IN: int mode) // IN: { int err; pid_t pid; int fds[2]; int proxyFD; int saveErrno = 0; if (pathName == NULL) { errno = EFAULT; return -1; } err = socketpair(AF_UNIX, SOCK_DGRAM, 0, fds); if (err == -1) { errno = ENOMEM; // Out of resources... return err; } pid = fork(); if (pid == -1) { proxyFD = -1; saveErrno = ENOMEM; // Out of resources... goto bail; } if (pid == 0) { /* child: use fd[0] */ proxyFD = Posix_Open(pathName, flags, mode); ProxySendResults(fds[0], proxyFD, errno); _exit(0); } else { /* parent: use fd[1] */ ProxyReceiveResults(fds[1], &proxyFD, &saveErrno); waitpid(pid, &err, 0); } bail: close(fds[0]); close(fds[1]); errno = saveErrno; return proxyFD; } /* *---------------------------------------------------------------------- * * ProxyUse -- * * Determine is the open proxy is to be used. * * Results: * 0 Success, useProxy is set * > 0 Failure (errno value); useProxy is undefined * * Side effects: * None * *---------------------------------------------------------------------- */ static int ProxyUse(ConstUnicode pathName, // IN: Bool *useProxy) // IN: { Unicode path; UnicodeIndex index; struct statfs sfbuf; struct stat statbuf; if (pathName == NULL) { errno = EFAULT; return -1; } if ((Posix_Lstat(pathName, &statbuf) == 0) && S_ISLNK(statbuf.st_mode)) { *useProxy = TRUE; return 0; } /* * Construct the path to the directory that contains the filePath. */ index = Unicode_FindLast(pathName, "/"); if (index == UNICODE_INDEX_NOT_FOUND) { path = Unicode_Duplicate("."); } else { Unicode temp; temp = Unicode_Substr(pathName, 0, index + 1); path = Unicode_Append(temp, "."); Unicode_Free(temp); } /* * Attempt to obtain information about the testPath (directory * containing filePath). */ if (Posix_Statfs(path, &sfbuf) == 0) { /* * The testPath exists; determine proxy usage explicitely. */ *useProxy = strcmp(sfbuf.f_fstypename, "nfs") == 0 ? TRUE : FALSE; } else { /* * A statfs error of some sort; Err on the side of caution. */ *useProxy = TRUE; } Unicode_Free(path); return 0; } /* *---------------------------------------------------------------------- * * PosixFileOpener -- * * Open a file. Use a proxy when creating a file or on NFS. * * Why a proxy? The Mac OS X 10.4.* NFS client interacts with our * use of settid() and doesn't send the proper credentials on opens. * This leads to files being written without error but containing no * data. The proxy avoids all of this unhappiness. * * Results: * -1 on error * >= 0 on success * * Side effects: * errno is set * *---------------------------------------------------------------------- */ int PosixFileOpener(ConstUnicode pathName, // IN: int flags, // IN: mode_t mode) // IN: { Bool useProxy; if ((flags & O_ACCMODE) || (flags & O_CREAT)) { int err; /* * Open for write and/or O_CREAT. Determine proxy usage. */ err = ProxyUse(pathName, &useProxy); if (err != 0) { errno = err; return -1; } } else { /* * No write access, no need for a proxy. */ useProxy = FALSE; } return useProxy ? ProxyOpen(pathName, flags, mode) : Posix_Open(pathName, flags, mode); } #endif /* *---------------------------------------------------------------------- * * FileIOCreateRetry -- * * Open/create a file; specify creation mode * May perform retries to deal with certain OS conditions * * Results: * FILEIO_SUCCESS on success: 'file' is set * FILEIO_OPEN_ERROR_EXIST if the file already exists * FILEIO_FILE_NOT_FOUND if the file is not present * FILEIO_ERROR for other errors * * Side effects: * None * *---------------------------------------------------------------------- */ FileIOResult FileIOCreateRetry(FileIODescriptor *file, // OUT: ConstUnicode pathName, // IN: int access, // IN: FileIOOpenAction action, // IN: int mode, // IN: mode_t for creation uint32 msecMaxWaitTime) // IN: Ignored { uid_t uid = -1; int fd = -1; int flags = 0; int error; FileIOResult ret; ASSERT(file); if (pathName == NULL) { errno = EFAULT; return FILEIO_ERROR; } ASSERT(!FileIO_IsValid(file)); ASSERT(file->lockToken == NULL); ASSERT_ON_COMPILE(FILEIO_ERROR_LAST < 16); /* See comment in fileIO.h */ FileIOResolveLockBits(&access); ASSERT((access & FILEIO_OPEN_LOCKED) == 0 && (access & FILEIO_OPEN_EXCLUSIVE_LOCK) == 0); /* Only ESX implements mandatory locking */ ASSERT((access & FILEIO_OPEN_LOCK_MANDATORY) == 0 || File_SupportsMandatoryLock(pathName)); #if defined(__APPLE__) if (access & FILEIO_OPEN_EXCLUSIVE_LOCK_MACOS) { flags |= O_EXLOCK; } #elif defined(__linux__) if (((access & (FILEIO_OPEN_LOCK_MANDATORY | FILEIO_OPEN_MULTIWRITER_LOCK)) != 0) && HostType_OSIsVMK()) { /* These flags are only supported on vmkernel */ if ((access & FILEIO_OPEN_MULTIWRITER_LOCK) != 0) { flags |= O_MULTIWRITER_LOCK; } else if ((access & FILEIO_OPEN_LOCK_MANDATORY) != 0) { flags |= O_EXCLUSIVE_LOCK; } } #endif /* * Locking implementation note: this can be recursive. On ESX: * FileIOCreateRetry("foo", ...ADVISORY...) * -> FileIO_Lock("foo", ...ADVISORY...) * -> FileLock_Lock("foo", ...ADVISORY...) * -> FileIOCreateRetry("foo.lck", ...MANDATORY...) * -> open("foo.lck", ...O_EXCLUSIVE_LOCK...) */ FileIO_Init(file, pathName); /* Mandatory file locks are only available at open() itself */ if ((access & FILEIO_OPEN_LOCK_ADVISORY) != 0) { ret = FileIO_Lock(file, access); if (!FileIO_IsSuccess(ret)) { goto error; } } if ((access & (FILEIO_OPEN_ACCESS_READ | FILEIO_OPEN_ACCESS_WRITE)) == (FILEIO_OPEN_ACCESS_READ | FILEIO_OPEN_ACCESS_WRITE)) { flags |= O_RDWR; } else if (access & FILEIO_OPEN_ACCESS_WRITE) { flags |= O_WRONLY; } else if (access & FILEIO_OPEN_ACCESS_READ) { flags |= O_RDONLY; } if (access & FILEIO_OPEN_EXCLUSIVE_READ && access & FILEIO_OPEN_EXCLUSIVE_WRITE) { flags |= O_EXCL; } if (access & FILEIO_OPEN_UNBUFFERED) { #if defined(FILEIO_SUPPORT_ODIRECT) flags |= O_DIRECT; #elif !defined(__APPLE__) // Mac hosts need this access flag after opening. access &= ~FILEIO_OPEN_UNBUFFERED; LOG_ONCE((LGPFX" %s reverting to buffered IO on %s.\n", __FUNCTION__, UTF8(pathName))); #endif } if (access & FILEIO_OPEN_NONBLOCK) { flags |= O_NONBLOCK; } if (access & FILEIO_OPEN_APPEND) { flags |= O_APPEND; } #if defined(O_NOFOLLOW) if (access & FILEIO_OPEN_ACCESS_NOFOLLOW) { flags |= O_NOFOLLOW; } #endif #if defined(linux) if (access & FILEIO_OPEN_SYNC) { flags |= O_SYNC; } #endif #if defined(O_NOFOLLOW) if (access & FILEIO_OPEN_ACCESS_NOFOLLOW) { flags |= O_NOFOLLOW; } #endif flags |= FileIO_OpenActions[action]; file->flags = access; if (access & FILEIO_OPEN_PRIVILEGED) { uid = Id_BeginSuperUser(); } fd = PosixFileOpener(pathName, flags, mode); error = errno; if (access & FILEIO_OPEN_PRIVILEGED) { Id_EndSuperUser(uid); } errno = error; if (fd == -1) { ret = FileIOErrno2Result(errno); goto error; } #if defined(__APPLE__) if (access & (FILEIO_OPEN_UNBUFFERED | FILEIO_OPEN_SYNC)) { error = fcntl(fd, F_NOCACHE, 1); if (error == -1) { ret = FileIOErrno2Result(errno); goto error; } if (!(access & FILEIO_OPEN_SYNC)) { /* * F_NODIRECT was added in Mac OS 10.7.0 "Lion" which has Darwin * kernel 11.0.0. */ if (Hostinfo_OSVersion(0) >= 11) { error = fcntl(fd, F_NODIRECT, 1); if (error == -1) { ret = FileIOErrno2Result(errno); goto error; } } } } #endif if (access & FILEIO_OPEN_DELETE_ASAP) { /* * Remove the name from the name space. The file remains laid out on the * disk and accessible through the file descriptor until it is closed. */ if (Posix_Unlink(pathName) == -1) { ret = FileIOErrno2Result(errno); goto error; } } file->posix = fd; return FILEIO_SUCCESS; error: error = errno; if (fd != -1) { close(fd); } FileIO_Unlock(file); FileIO_Cleanup(file); FileIO_Invalidate(file); errno = error; return ret; } /* *---------------------------------------------------------------------- * * FileIO_Create -- * * Open/create a file; specify creation mode * * Results: * FILEIO_SUCCESS on success: 'file' is set * FILEIO_OPEN_ERROR_EXIST if the file already exists * FILEIO_FILE_NOT_FOUND if the file is not present * FILEIO_ERROR for other errors * * Side effects: * None * *---------------------------------------------------------------------- */ FileIOResult FileIO_Create(FileIODescriptor *file, // OUT: ConstUnicode pathName, // IN: int access, // IN: FileIOOpenAction action, // IN: int mode) // IN: mode_t for creation { return FileIOCreateRetry(file, pathName, access, action, mode, 0); } /* *---------------------------------------------------------------------- * * FileIO_Open -- * * Open/create a file * * Results: * FILEIO_SUCCESS on success: 'file' is set * FILEIO_OPEN_ERROR_EXIST if the file already exists * FILEIO_FILE_NOT_FOUND if the file is not present * FILEIO_ERROR for other errors * * Side effects: * None * *---------------------------------------------------------------------- */ FileIOResult FileIO_Open(FileIODescriptor *file, // OUT: ConstUnicode pathName, // IN: int access, // IN: FileIOOpenAction action) // IN: { return FileIOCreateRetry(file, pathName, access, action, S_IRUSR | S_IWUSR, 0); } /* *---------------------------------------------------------------------- * * FileIO_Seek -- * * Change the current position in a file * * Results: * On success: the new current position in bytes from the beginning of * the file * * On failure: -1 * * Side effects: * None * *---------------------------------------------------------------------- */ #if defined(linux) && defined(SYS__llseek) /* * If the llseek system call exists, use it to provide a version of 64-bit * lseek() functionality, for FileIO_Seek() to use if appropriate. */ #define VM_HAVE__LLSEEK 1 static INLINE int _llseek(unsigned int fd, unsigned long offset_high, unsigned long offset_low, loff_t * result, unsigned int whence) { return syscall(SYS__llseek, fd, offset_high, offset_low, result, whence); } #endif uint64 FileIO_Seek(const FileIODescriptor *file, // IN: int64 distance, // IN: FileIOSeekOrigin origin) // IN: { ASSERT(file); /* * The goal is to use the best lseek-type function with support for 64-bit * file offsets (aka large file support, or LFS). * * __USE_LARGEFILE implies that lseek() has LFS * VM_HAVE__LLSEEK tells us that we have the _llseek() routine available * __USE_LARGEFILE64 implies that lseek64() is available * * All three of these defines only come into play on Linux systems. On any * other OS, they won't be present, and we go straight for lseek() since * that's the only known alternative. */ #if defined(VM_HAVE__LLSEEK) && !defined(__USE_LARGEFILE) && !defined(__USE_LARGEFILE64) /* * This is a Linux system that doesn't have a glibc with any large-file * support (LFS), but does have the llseek system call. On Linux, this is * the least desirable option because the API is a bit grotty (e.g. the * casting of negative offsets into unsigned offset_hi and offset_lo), and * because doing system calls directly from our code is more likely to * break than using libc. */ loff_t res; if (_llseek(file->posix, distance >> 32, distance & 0xFFFFFFFF, &res, FileIO_SeekOrigins[origin]) == -1) { res = -1; } return res; #elif defined(__USE_LARGEFILE64) && !defined(__USE_LARGEFILE) /* * This is a Linux system with glibc that has lseek64 available, but not a * lseek with LFS. * * lseek64 is a bit cleaner than _llseek (because glibc provides it, we * know the API won't break) but still not as portable as plain old lseek. */ return lseek64(file->posix, distance, FileIO_SeekOrigins[origin]); #else /* * We're taking this route because either we know lseek() can support * 64-bit file offsets (__USE_LARGEFILE is set) or because llseek and * lseek64 are both unavailable. * * This means this a Linux/glibc system with transparent LFS support, an * old Linux system without llseek, or another POSIX system. */ return lseek(file->posix, distance, FileIO_SeekOrigins[origin]); #endif } /* *---------------------------------------------------------------------- * * FileIO_Write -- * * Write to a file * * Results: * FILEIO_SUCCESS on success: '*actual_count' = 'requested' bytes have * been written * FILEIO_WRITE_ERROR_FBIG for the attempt to write file that exceeds * maximum file size * FILEIO_WRITE_ERROR_NOSPC when the device containing the file has no * room for the data * FILEIO_WRITE_ERROR_DQUOT for attempts to write file that exceeds * user's disk quota * FILEIO_ERROR for other errors: only '*actual_count' bytes have been * written for sure * * Side effects: * None * *---------------------------------------------------------------------- */ FileIOResult FileIO_Write(FileIODescriptor *fd, // IN: const void *bufIn, // IN: size_t requested, // IN: size_t *actual) // OUT: { const uint8 *buf = (const uint8 *)bufIn; size_t initial_requested; FileIOResult fret = FILEIO_SUCCESS; ASSERT(fd); ASSERT_NOT_IMPLEMENTED(requested < 0x80000000); initial_requested = requested; while (requested > 0) { ssize_t res; res = write(fd->posix, buf, requested); if (res == -1) { int error = errno; if (error == EINTR) { NOT_TESTED(); continue; } fret = FileIOErrno2Result(error); break; } buf += res; requested -= res; } if (actual) { *actual = initial_requested - requested; } return fret; } /* *---------------------------------------------------------------------- * * FileIO_Read -- * * Read from a file * * Results: * FILEIO_SUCCESS on success: '*actual_count' = 'requested' bytes have * been written * FILEIO_READ_ERROR_EOF if the end of the file was reached: only * '*actual_count' bytes have been read for sure * FILEIO_ERROR for other errors: only '*actual_count' bytes have been * read for sure * * Side effects: * None * *---------------------------------------------------------------------- */ FileIOResult FileIO_Read(FileIODescriptor *fd, // IN: void *bufIn, // OUT: size_t requested, // IN: size_t *actual) // OUT: { uint8 *buf = (uint8 *) bufIn; size_t initial_requested; FileIOResult fret = FILEIO_SUCCESS; ASSERT(fd); ASSERT_NOT_IMPLEMENTED(requested < 0x80000000); initial_requested = requested; while (requested > 0) { ssize_t res; res = read(fd->posix, buf, requested); if (res == -1) { if (errno == EINTR) { NOT_TESTED(); continue; } fret = FileIOErrno2Result(errno); if (FILEIO_ERROR == fret) { Log("read failed, errno=%d, %s\n", errno, Err_Errno2String(errno)); } break; } if (res == 0) { fret = FILEIO_READ_ERROR_EOF; break; } buf += res; requested -= res; } if (actual) { *actual = initial_requested - requested; } return fret; } /* *---------------------------------------------------------------------- * * FileIO_Truncate -- * * Truncates file to a given length * * Results: * Bool - TRUE on success, FALSE on failure * * Side effects: * None * *---------------------------------------------------------------------- */ Bool FileIO_Truncate(FileIODescriptor *file, // IN: uint64 newLength) // IN: { ASSERT(file); return ftruncate(file->posix, newLength) == 0; } /* *---------------------------------------------------------------------- * * FileIO_Close -- * * Close a file * * Results: * TRUE: an error occured * FALSE: no error occured * * Side effects: * None * *---------------------------------------------------------------------- */ Bool FileIO_Close(FileIODescriptor *file) // IN: { int err; ASSERT(file); err = (close(file->posix) == -1) ? errno : 0; /* Unlock the file if it was locked */ FileIO_Unlock(file); FileIO_Cleanup(file); FileIO_Invalidate(file); if (err) { errno = err; } return err != 0; } /* *---------------------------------------------------------------------- * * FileIO_Sync -- * * Synchronize the disk state of a file with its memory state * * Results: * On success: 0 * On failure: -1 * * Side effects: * None * *---------------------------------------------------------------------- */ int FileIO_Sync(const FileIODescriptor *file) // IN: { ASSERT(file); return fsync(file->posix); } /* *----------------------------------------------------------------------------- * * FileIOCoalesce -- * * Linux 2.2 does a fairly braindead thing with ioVec's. It simply issues * reads and writes internal to the kernel in serial * (linux/fs/read_write.c:do_readv_writev()). We optimize here for the * case of many small chunks. The cost of the extra copy in this case * is made up for by the decreased number of separate I/Os the kernel * issues internally. Note that linux 2.4 seems to be smarter with respect * to this problem. * * Results: * Bool - Whether or not coalescing was done. If it was done, * FileIODecoalesce *MUST* be called. * * Side effects: * FileIOCoalesce will malloc *outVec if coalescing is performed * *----------------------------------------------------------------------------- */ static Bool FileIOCoalesce(struct iovec *inVec, // IN: Vector to coalesce from int inCount, // IN: count for inVec size_t inTotalSize, // IN: totalSize (bytes) in inVec Bool isWrite, // IN: coalesce for writing (or reading) Bool forceCoalesce, // IN: if TRUE always coalesce int flags, // IN: fileIO open flags struct iovec *outVec) // OUT: Coalesced (1-entry) iovec { uint8 *cBuf; ASSERT(inVec); ASSERT(outVec); FileIO_OptionalSafeInitialize(); /* simple case: no need to coalesce */ if (inCount == 1) { return FALSE; } /* * Only coalesce when the number of entries is above our count threshold * and the average size of an entry is less than our size threshold */ if (!forceCoalesce && (!filePosixOptions.enabled || inCount <= filePosixOptions.countThreshold || inTotalSize / inCount >= filePosixOptions.sizeThreshold)) { return FALSE; } // XXX: Wouldn't it be nice if we could log from here! //LOG(5, ("FILE: Coalescing %s of %d elements and %d size\n", // isWrite ? "write" : "read", inCount, inTotalSize)); if (filePosixOptions.aligned || flags & FILEIO_OPEN_UNBUFFERED) { cBuf = FileIOAligned_Malloc(sizeof(uint8) * inTotalSize); } else { cBuf = Util_SafeMalloc(sizeof(uint8) * inTotalSize); } if (!cBuf) { return FALSE; } if (isWrite) { IOV_WriteIovToBuf(inVec, inCount, cBuf, inTotalSize); } outVec->iov_base = cBuf; outVec->iov_len = inTotalSize; return TRUE; } /* *----------------------------------------------------------------------------- * * FileIODecoalesce -- * * Inverse of the coalesce optimization. For writes, its a NOOP, but * for reads, it copies the data back into the original buffer. * It also frees the memory allocated by FileIOCoalesce. * * Results: * void * * Side effects: * None * *----------------------------------------------------------------------------- */ static void FileIODecoalesce(struct iovec *coVec, // IN: Coalesced (1-entry) vector struct iovec *origVec, // IN: Original vector int origVecCount, // IN: count for origVec size_t actualSize, // IN: # bytes to transfer back to origVec Bool isWrite, // IN: decoalesce for writing (or reading) int flags) // IN: fileIO open flags { ASSERT(coVec); ASSERT(origVec); ASSERT(actualSize <= coVec->iov_len); ASSERT_NOT_TESTED(actualSize == coVec->iov_len); if (!isWrite) { IOV_WriteBufToIov(coVec->iov_base, actualSize, origVec, origVecCount); } if (filePosixOptions.aligned || flags & FILEIO_OPEN_UNBUFFERED) { FileIOAligned_Free(coVec->iov_base); } else { free(coVec->iov_base); } } /* *---------------------------------------------------------------------- * * FileIO_Readv -- * * Wrapper for readv. In linux, we can issue a readv directly. * But the readv is not atomic, i.e, the read can succeed * on the first N vectors, and return a positive value in spite * of the fact that there was an error on the N+1st vector. There * is no way to query the exact error that happened. So, we retry * in a loop (for a max of MAX_RWV_RETRIES). * XXX: If we retried MAX_RWV_RETRIES times and gave up, we will * return FILEIO_ERROR even if errno is undefined. * * Results: * FILEIO_SUCCESS, FILEIO_ERROR, FILEIO_READ_ERROR_EOF * * Side effects: * None * *---------------------------------------------------------------------- */ FileIOResult FileIO_Readv(FileIODescriptor *fd, // IN: struct iovec *v, // IN: int numEntries, // IN: size_t totalSize, // IN: size_t *actual) // OUT: { size_t bytesRead = 0, sum = 0; FileIOResult fret = FILEIO_ERROR; int nRetries = 0, maxRetries = numEntries; struct iovec coV; struct iovec *vPtr; Bool didCoalesce; int numVec; ASSERT(fd); didCoalesce = FileIOCoalesce(v, numEntries, totalSize, FALSE, FALSE, fd->flags, &coV); ASSERT_NOT_IMPLEMENTED(totalSize < 0x80000000); numVec = didCoalesce ? 1 : numEntries; vPtr = didCoalesce ? &coV : v; while (nRetries < maxRetries) { ssize_t retval; ASSERT(numVec > 0); retval = readv(fd->posix, vPtr, numVec); if (retval == -1) { if (errno == EINTR) { NOT_TESTED(); continue; } fret = FileIOErrno2Result(errno); break; } bytesRead += retval; if (bytesRead == totalSize) { fret = FILEIO_SUCCESS; break; } if (retval == 0) { fret = FILEIO_READ_ERROR_EOF; break; } /* * Ambigous case. Stupid Linux. If the bytesRead matches an * exact iovector boundary, we need to retry from the next * iovec. 2) If it does not match, EOF is the only error possible. * NOTE: If Linux Readv implementation changes, this * ambiguity handling may need to change. * --Ganesh, 08/15/2001. */ for (; sum <= bytesRead; vPtr++, numVec--) { sum += vPtr->iov_len; /* * In each syscall, we will process atleast one iovec * or get an error back. We will therefore retry atmost * count times. If multiple iovecs were processed before * an error hit, we will retry a lesser number of times. */ nRetries++; } if (sum > bytesRead) { // A partially filled iovec can ONLY mean EOF fret = FILEIO_READ_ERROR_EOF; break; } } if (didCoalesce) { FileIODecoalesce(&coV, v, numEntries, bytesRead, FALSE, fd->flags); } if (actual) { *actual = bytesRead; } return fret; } /* *---------------------------------------------------------------------- * * FileIO_Writev -- * * Wrapper for writev. In linux, we can issue a writev directly. * But the writev is not atomic, i.e, the write can succeed * on the first N vectors, and return a positive value in spite * of the fact that there was an error on the N+1st vector. There * is no way to query the exact error that happened. So, we retry * in a loop (for a max of MAX_RWV_RETRIES). * XXX: If we retried MAX_RWV_RETRIES times and gave up, we will * return FILEIO_ERROR even if errno is undefined. * * Results: * FILEIO_SUCCESS, FILEIO_ERROR * * Side effects: * None * *---------------------------------------------------------------------- */ FileIOResult FileIO_Writev(FileIODescriptor *fd, // IN: struct iovec *v, // IN: int numEntries, // IN: size_t totalSize, // IN: size_t *actual) // OUT: { size_t bytesWritten = 0, sum = 0; FileIOResult fret = FILEIO_ERROR; int nRetries = 0, maxRetries = numEntries; struct iovec coV; struct iovec *vPtr; Bool didCoalesce; int numVec; ASSERT(fd); didCoalesce = FileIOCoalesce(v, numEntries, totalSize, TRUE, FALSE, fd->flags, &coV); ASSERT_NOT_IMPLEMENTED(totalSize < 0x80000000); numVec = didCoalesce ? 1 : numEntries; vPtr = didCoalesce ? &coV : v; while (nRetries < maxRetries) { ssize_t retval; ASSERT(numVec > 0); retval = writev(fd->posix, vPtr, numVec); if (retval == -1) { if (errno == EINTR) { NOT_TESTED(); continue; } fret = FileIOErrno2Result(errno); break; } bytesWritten += retval; if (bytesWritten == totalSize) { fret = FILEIO_SUCCESS; break; } NOT_TESTED(); for (; sum <= bytesWritten; vPtr++, numVec--) { sum += vPtr->iov_len; nRetries++; } /* * writev only seems to produce a partial iovec when the disk is * out of space. Just call it an error. --probin */ if (sum != bytesWritten) { fret = FILEIO_WRITE_ERROR_NOSPC; break; } } if (didCoalesce) { FileIODecoalesce(&coV, v, numEntries, bytesWritten, TRUE, fd->flags); } if (actual) { *actual = bytesWritten; } return fret; } #if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) ||\ defined(sun) /* *---------------------------------------------------------------------- * * FileIOPreadvCoalesced -- * * This function implements vector pread for platforms that do not * support the preadv system call. The incoming vectors are * coalesced to a single buffer to issue only one pread() * system call which reads from a specified offset. The * vectors are then decoalesced before return. * * Results: * FILEIO_SUCCESS, FILEIO_ERROR * * Side effects: * None * *---------------------------------------------------------------------- */ static FileIOResult FileIOPreadvCoalesced(FileIODescriptor *fd, // IN: File descriptor struct iovec *entries, // IN: Vector to read into int numEntries, // IN: Number of vector entries uint64 offset, // IN: Offset to start reading size_t totalSize, // IN: totalSize(bytes) in entries size_t *actual) // OUT: number of bytes read { struct iovec *vPtr; struct iovec coV; int count; uint64 fileOffset; FileIOResult fret; Bool didCoalesce; size_t sum = 0; didCoalesce = FileIOCoalesce(entries, numEntries, totalSize, FALSE, TRUE /* force coalescing */, fd->flags, &coV); count = didCoalesce ? 1 : numEntries; vPtr = didCoalesce ? &coV : entries; fileOffset = offset; while (count > 0) { size_t leftToRead = vPtr->iov_len; uint8 *buf = (uint8 *) vPtr->iov_base; while (leftToRead > 0) { ssize_t retval = pread(fd->posix, buf, leftToRead, fileOffset); if (retval == -1) { if (errno == EINTR) { LOG_ONCE((LGPFX" %s got EINTR. Retrying\n", __FUNCTION__)); NOT_TESTED_ONCE(); continue; } fret = FileIOErrno2Result(errno); goto exit; } if (retval == 0) { fret = FILEIO_READ_ERROR_EOF; goto exit; } buf += retval; leftToRead -= retval; sum += retval; fileOffset += retval; } count--; vPtr++; } fret = FILEIO_SUCCESS; exit: if (didCoalesce) { FileIODecoalesce(&coV, entries, numEntries, sum, FALSE, fd->flags); } if (actual) { *actual = sum; } return fret; } /* *---------------------------------------------------------------------- * * FileIOPwritevCoalesced -- * * This function implements vector pwrite for platforms that do not * support the pwritev system call. The incoming vectors are * coalesced to a single buffer to issue only one pwrite() * system call which writes from a specified offset. The * vectors are then decoalesced before return. * * Results: * FILEIO_SUCCESS, FILEIO_ERROR * * Side effects: * None * *---------------------------------------------------------------------- */ static FileIOResult FileIOPwritevCoalesced(FileIODescriptor *fd, // IN: File descriptor struct iovec *entries, // IN: Vector to write from int numEntries, // IN: Number of vector entries uint64 offset, // IN: Offset to start writing size_t totalSize, // IN: Total size(bytes) size_t *actual) // OUT: number of bytes written { struct iovec coV; Bool didCoalesce; struct iovec *vPtr; int count; uint64 fileOffset; FileIOResult fret; size_t sum = 0; didCoalesce = FileIOCoalesce(entries, numEntries, totalSize, TRUE, TRUE /* force coalescing */, fd->flags, &coV); count = didCoalesce ? 1 : numEntries; vPtr = didCoalesce ? &coV : entries; fileOffset = offset; while (count > 0) { size_t leftToWrite = vPtr->iov_len; uint8 *buf = (uint8 *)vPtr->iov_base; while (leftToWrite > 0) { ssize_t retval = pwrite(fd->posix, buf, leftToWrite, fileOffset); if (retval == -1) { if (errno == EINTR) { LOG_ONCE((LGPFX" %s got EINTR. Retrying\n", __FUNCTION__)); NOT_TESTED_ONCE(); continue; } fret = FileIOErrno2Result(errno); goto exit; } if (retval == 0) { NOT_TESTED(); fret = FILEIO_WRITE_ERROR_NOSPC; goto exit; } if (retval < leftToWrite) { /* * Using %zd on Android generated a warning about * expecting a "signed size_t" argument; casting retval to * "signed size_t" generated an error, though. We've * already checked for retval == -1 above, so the cast * below should be OK. Refer to bug 817761. */ LOG_ONCE((LGPFX" %s wrote %"FMTSZ"u out of %"FMTSZ"u bytes.\n", __FUNCTION__, (size_t)retval, leftToWrite)); } buf += retval; leftToWrite -= retval; sum += retval; fileOffset += retval; } count--; vPtr++; } fret = FILEIO_SUCCESS; exit: if (didCoalesce) { FileIODecoalesce(&coV, entries, numEntries, sum, TRUE, fd->flags); } if (actual) { *actual = sum; } return fret; } #endif /* defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(sun) */ #if defined(__linux__ ) /* *---------------------------------------------------------------------- * * FileIOPreadvInternal -- * * This function implements vector pread for linux builds. Although, * support for preadv() first appeared in Linux 2.6.30, * library support was added in glibc 2.10. * Hence using weak linkage technique, we try to call the more * optimized preadv system call. If the system does not support * this, we fall back to earlier unoptimized techique. * * Note that in linux, preadv can succeed on the first N vectors, * and return a positive value in spite of the fact that there was * an error on the N+1st vector. There is no way to query the exact * error that happened. So, we retry in a loop (for a max of * MAX_RWV_RETRIES), same as FileIO_Readv(). * * XXX: If we retried MAX_RWV_RETRIES times and gave up, we will * return FILEIO_ERROR even if errno is undefined. * * Results: * FILEIO_SUCCESS, FILEIO_ERROR * * Side effects: * None * *---------------------------------------------------------------------- */ static FileIOResult FileIOPreadvInternal(FileIODescriptor *fd, // IN: File descriptor struct iovec *entries, // IN: Vector to read into int numEntries, // IN: Number of vector entries uint64 offset, // IN: Offset to start reading size_t totalSize, // IN: totalSize(bytes) in entries size_t *actual) // OUT: number of bytes read { struct iovec *vPtr; int numVec; size_t bytesRead = 0; size_t sum = 0; int nRetries = 0; int maxRetries = numEntries; FileIOResult fret = FILEIO_ERROR; numVec = numEntries; vPtr = entries; while (nRetries < maxRetries) { ssize_t retval = 0; ASSERT(numVec > 0); if (preadv64 != NULL) { retval = preadv64(fd->posix, vPtr, numVec, offset); } else { fret = FileIOPreadvCoalesced(fd, entries, numEntries, offset, totalSize, &bytesRead); break; } if (retval == -1) { if (errno == EINTR) { NOT_TESTED(); continue; } if (errno == ENOSYS) { /* * Function not supported by system. Fallback to unoptimized * function. */ ASSERT (nRetries == 0); fret = FileIOPreadvCoalesced(fd, entries, numEntries, offset, totalSize, &bytesRead); break; } fret = FileIOErrno2Result(errno); break; } bytesRead += retval; if (bytesRead == totalSize) { fret = FILEIO_SUCCESS; break; } if (retval == 0) { fret = FILEIO_READ_ERROR_EOF; break; } /* * This is an ambiguous case in linux preadv implementation. * If the bytesRead matches an exact iovector boundary, we need * to retry from the next iovec. However, if it does not match, * EOF is the only error possible. Linux 3.4.4 continues to have * this behaviour. * NOTE: If Linux preadv implementation changes, this * ambiguity handling may need to change. */ for (; sum <= bytesRead; vPtr++, numVec--) { sum += vPtr->iov_len; /* * In each syscall, we will process atleast one iovec * or get an error back. We will therefore retry at most * count times. If multiple iovecs were processed before * an error hit, we will retry a lesser number of times. */ nRetries++; } if (sum > bytesRead) { // A partially filled iovec can ONLY mean EOF fret = FILEIO_READ_ERROR_EOF; break; } } if (actual) { *actual = bytesRead; } return fret; } /* *---------------------------------------------------------------------- * * FileIOPwritevInternal -- * * This function implements vector pwrite for linux builds. Although, * support for pwritev() first appeared in Linux 2.6.30, library * support was added in glibc 2.10. * Hence using weak linkage technique, we try to call the more * optimized pwritev system call. If the system does not support * this, we fall back to earlier unoptimized techique. * * Note that in linux, pwritev can succeed on the first N vectors, * and return a positive value in spite of the fact that there was * an error on the N+1st vector. There is no way to query the exact * error that happened. So, we retry in a loop (for a max of * MAX_RWV_RETRIES), same as FileIO_Writev(). * * XXX: If we retried MAX_RWV_RETRIES times and gave up, we will * return FILEIO_ERROR even if errno is undefined. * * Results: * FILEIO_SUCCESS, FILEIO_ERROR * * Side effects: * None * *---------------------------------------------------------------------- */ static FileIOResult FileIOPwritevInternal(FileIODescriptor *fd, // IN: File descriptor struct iovec *entries, // IN: Vector to write from int numEntries, // IN: Number of vector entries uint64 offset, // IN: Offset to start writing size_t totalSize, // IN: Total size(bytes)in entries size_t *actual) // OUT: number of bytes written { struct iovec *vPtr; int numVec; size_t bytesWritten = 0; size_t sum = 0; int nRetries = 0; int maxRetries = numEntries; FileIOResult fret = FILEIO_ERROR; numVec = numEntries; vPtr = entries; while (nRetries < maxRetries) { ssize_t retval = 0; ASSERT(numVec > 0); if (pwritev64 != NULL) { retval = pwritev64(fd->posix, vPtr, numVec, offset); } else { fret = FileIOPwritevCoalesced(fd, entries, numEntries, offset, totalSize, &bytesWritten); break; } if (retval == -1) { if (errno == EINTR) { NOT_TESTED(); continue; } if (errno == ENOSYS) { /* * Function not supported by system. Fallback to unoptimized * function. */ ASSERT (nRetries == 0); fret = FileIOPwritevCoalesced(fd, entries, numEntries, offset, totalSize, &bytesWritten); break; } fret = FileIOErrno2Result(errno); break; } bytesWritten += retval; if (bytesWritten == totalSize) { fret = FILEIO_SUCCESS; break; } NOT_TESTED(); for (; sum <= bytesWritten; vPtr++, numVec--) { sum += vPtr->iov_len; nRetries++; } /* * pwritev produces a partial iovec when the disk is * out of space. Just call it an error. */ if (sum != bytesWritten) { fret = FILEIO_WRITE_ERROR_NOSPC; break; } } if (actual) { *actual = bytesWritten; } return fret; } #endif /* defined(__linux__ ) */ #if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) ||\ defined(sun) /* *---------------------------------------------------------------------- * * FileIO_Preadv -- * * Implementation of vector pread.The function checks for the support * of system call preadv with the version of glibc and calls the * optimized system call. If the system call is not supported, * we fall back to the earlier technique of coalescing the vectors * and calling a single pread and decoalescing again. * * Results: * FILEIO_SUCCESS, FILEIO_ERROR * * Side effects: * None * *---------------------------------------------------------------------- */ FileIOResult FileIO_Preadv(FileIODescriptor *fd, // IN: File descriptor struct iovec *entries, // IN: Vector to read into int numEntries, // IN: Number of vector entries uint64 offset, // IN: Offset to start reading size_t totalSize, // IN: totalSize (bytes) in entries size_t *actual) // OUT: number of bytes read { FileIOResult fret; ASSERT(fd); ASSERT(entries); ASSERT(!(fd->flags & FILEIO_ASYNCHRONOUS)); ASSERT_NOT_IMPLEMENTED(totalSize < 0x80000000); #if defined(__linux__ ) fret = FileIOPreadvInternal(fd, entries, numEntries, offset, totalSize, actual); #else fret = FileIOPreadvCoalesced(fd, entries, numEntries, offset, totalSize, actual); #endif /* defined(__linux__ ) */ return fret; } /* *---------------------------------------------------------------------- * * FileIO_Pwritev -- * * Implementation of vector pwrite.The function checks for the support * of system call pwritev with the version of glibc and calls the * optimized system call. If the system call is not supported, * we fall back to the earlier technique of coalescing the vectors and * calling a single pread and decoalescing again. * * Results: * FILEIO_SUCCESS, FILEIO_ERROR * * Side effects: * None * *---------------------------------------------------------------------- */ FileIOResult FileIO_Pwritev(FileIODescriptor *fd, // IN: File descriptor struct iovec *entries, // IN: Vector to write from int numEntries, // IN: Number of vector entries uint64 offset, // IN: Offset to start writing size_t totalSize, // IN: Total size (bytes) in entries size_t *actual) // OUT: number of bytes written { FileIOResult fret; ASSERT(fd); ASSERT(entries); ASSERT(!(fd->flags & FILEIO_ASYNCHRONOUS)); ASSERT_NOT_IMPLEMENTED(totalSize < 0x80000000); #if defined(__linux__ ) fret = FileIOPwritevInternal(fd, entries, numEntries, offset, totalSize, actual); #else fret = FileIOPwritevCoalesced(fd, entries, numEntries, offset, totalSize, actual); #endif /* defined(__linux__ ) */ return fret; } #endif /* defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(sun) */ /* *---------------------------------------------------------------------- * * FileIO_GetAllocSize -- * * Get logcial and alloced size of a file. * * Results: * FileIOResult. * * Side effects: * None * *---------------------------------------------------------------------- */ FileIOResult FileIO_GetAllocSize(const FileIODescriptor *fd, // IN: uint64 *logicalBytes, // OUT: uint64 *allocedBytes) // OUT: { struct stat statBuf; ASSERT(fd); if (fstat(fd->posix, &statBuf) == -1) { return FileIOErrno2Result(errno); } if (logicalBytes) { *logicalBytes = statBuf.st_size; } if (allocedBytes) { /* * If you don't like the magic number 512, yell at the people * who wrote sys/stat.h and tell them to add a #define for it. */ *allocedBytes = statBuf.st_blocks * 512; } return FILEIO_SUCCESS; } /* *---------------------------------------------------------------------- * * FileIO_SetAllocSize -- * * Set allocated size of file, allocating new blocks if needed. * It is an error for size to be less than the current size. * * Results: * TRUE on success. Sets errno on failure. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool FileIO_SetAllocSize(const FileIODescriptor *fd, // IN: uint64 size) // IN: { #if defined(__APPLE__) || defined(__linux__) FileIOResult fret; uint64 curSize; uint64 preallocLen; #if defined(__APPLE__) fstore_t prealloc; #endif fret = FileIO_GetAllocSize(fd, NULL, &curSize); if (!FileIO_IsSuccess(fret)) { return FALSE; } if (curSize > size) { errno = EINVAL; return FALSE; } preallocLen = size - curSize; #if defined(__APPLE__) prealloc.fst_flags = 0; prealloc.fst_posmode = F_PEOFPOSMODE; prealloc.fst_offset = 0; prealloc.fst_length = preallocLen; prealloc.fst_bytesalloc = 0; return fcntl(fd->posix, F_PREALLOCATE, &prealloc) != -1; #elif __linux__ return syscall(SYS_fallocate, fd->posix, FALLOC_FL_KEEP_SIZE, curSize, preallocLen) == 0; #endif #else errno = ENOSYS; return FALSE; #endif } /* *---------------------------------------------------------------------- * * FileIO_GetAllocSizeByPath -- * * Get the logcial and alloced size of a file specified by path. * * Results: * FileIOResult. * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ FileIOResult FileIO_GetAllocSizeByPath(ConstUnicode pathName, // IN: uint64 *logicalBytes, // OUT: uint64 *allocedBytes) // OUT: { struct stat statBuf; if (Posix_Stat(pathName, &statBuf) == -1) { return FileIOErrno2Result(errno); } if (logicalBytes) { *logicalBytes = statBuf.st_size; } if (allocedBytes) { #if __linux__ && defined(N_PLAT_NLM) /* Netware doesn't have st_blocks. Just fall back to GetSize. */ *allocedBytes = statBuf.st_size; #else /* * If you don't like the magic number 512, yell at the people * who wrote sys/stat.h and tell them to add a #define for it. */ *allocedBytes = statBuf.st_blocks * 512; #endif } return FILEIO_SUCCESS; } /* *---------------------------------------------------------------------- * * FileIO_Access -- * * Wrapper for access syscall. We return FILEIO_SUCCESS if the file * is accessible with the specified mode. If not, we will return * FILEIO_ERROR. * * Results: * FILEIO_SUCCESS or FILEIO_ERROR. * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ FileIOResult FileIO_Access(ConstUnicode pathName, // IN: Path name. May be NULL. int accessMode) // IN: Access modes to be asserted { int mode = 0; if (pathName == NULL) { errno = EFAULT; return FILEIO_ERROR; } if (accessMode & FILEIO_ACCESS_READ) { mode |= R_OK; } if (accessMode & FILEIO_ACCESS_WRITE) { mode |= W_OK; } if (accessMode & FILEIO_ACCESS_EXEC) { mode |= X_OK; } if (accessMode & FILEIO_ACCESS_EXISTS) { mode |= F_OK; } return (Posix_Access(pathName, mode) == -1) ? FILEIO_ERROR : FILEIO_SUCCESS; } /* *---------------------------------------------------------------------- * * FileIO_GetFlags -- * * Accessor for fd->flags; * * Results: * fd->flags * * Side Effects: * None * *---------------------------------------------------------------------- */ uint32 FileIO_GetFlags(FileIODescriptor *fd) // IN: { ASSERT(fd); ASSERT(FileIO_IsValid(fd)); return fd->flags; } /* *---------------------------------------------------------------------- * * FileIO_SupportsFileSize -- * * Test whether underlying filesystem supports specified file size. * * Results: * Return TRUE if such file size is supported, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool FileIO_SupportsFileSize(const FileIODescriptor *fd, // IN: uint64 requestedSize) // IN: { #if defined(linux) /* * Linux makes test on seek(), so we can do simple non-intrusive test. * Verified to work on 2.2.x, 2.4.x and 2.6.x, with ext2, ext3, smbfs, * cifs, nfs and ncpfs. Always got some reasonable value. */ Bool supported = FALSE; uint64 oldPos; ASSERT(FileIO_IsValid(fd)); oldPos = FileIO_Seek(fd, 0, FILEIO_SEEK_CURRENT); if (oldPos != (uint64)-1) { uint64 newPos; if (FileIO_Seek(fd, requestedSize, FILEIO_SEEK_BEGIN) == requestedSize) { supported = TRUE; } newPos = FileIO_Seek(fd, oldPos, FILEIO_SEEK_BEGIN); ASSERT_NOT_IMPLEMENTED(oldPos == newPos); } return supported; #elif defined(__APPLE__) struct statfs buf; if (fstatfs(fd->posix, &buf) == -1) { Log(LGPFX" %s fstatfs failure: %s\n", __FUNCTION__, Err_Errno2String(errno)); /* Be optimistic despite failure */ return TRUE; } /* Check for FAT and UFS file systems */ if ((Str_Strcasecmp(buf.f_fstypename, "msdos") == 0) || (Str_Strcasecmp(buf.f_fstypename, "ufs") == 0)) { /* 4 GB limit */ return requestedSize > CONST64U(0xFFFFFFFF) ? FALSE : TRUE; } /* Be optimistic... */ return TRUE; #else /* Be optimistic on FreeBSD and Solaris... */ return TRUE; #endif } /* *---------------------------------------------------------------------- * * FileIO_GetModTime -- * * Retrieve last modification time. * * Results: * Return POSIX epoch time or -1 on error. * * Side effects: * None. * *---------------------------------------------------------------------- */ int64 FileIO_GetModTime(const FileIODescriptor *fd) // IN: { struct stat statbuf; if (fstat(fd->posix, &statbuf) == 0) { return statbuf.st_mtime; } else { return -1; } } /* *---------------------------------------------------------------------- * * FileIO_PrivilegedPosixOpen -- * * Opens file with elevated privileges. * * Results: * Opened file descriptor, or -1 on failure (errno contains error code). * * Side effects: * None. * *---------------------------------------------------------------------- */ int FileIO_PrivilegedPosixOpen(ConstUnicode pathName, // IN: int flags) // IN: { int fd; Bool suDone; uid_t uid = -1; if (pathName == NULL) { errno = EFAULT; return -1; } /* * I've said *opens*. I want you really think twice before creating files * with elevated privileges, so for them you have to use Id_BeginSuperUser() * yourself. */ ASSERT((flags & (O_CREAT | O_TRUNC)) == 0); if (Id_IsSuperUser()) { suDone = FALSE; } else { uid = Id_BeginSuperUser(); suDone = TRUE; } fd = Posix_Open(pathName, flags, 0); if (suDone) { int error = errno; Id_EndSuperUser(uid); errno = error; } return fd; } /* *----------------------------------------------------------------------------- * * FileIO_DescriptorToStream * * Return a FILE * stream equivalent to the given FileIODescriptor. * This is the logical equivalent of Posix dup() then fdopen(). * * Caller should fclose the returned descriptor when finished. * * Results: * !NULL A FILE * associated with the file associated with the fd * NULL Failure * * Side effects: * New fd allocated. * *----------------------------------------------------------------------------- */ FILE * FileIO_DescriptorToStream(FileIODescriptor *fdesc, // IN: Bool textMode) // IN: unused { int dupFD; const char *mode; int tmpFlags; FILE *stream; dupFD = dup(fdesc->posix); if (dupFD == -1) { return NULL; } /* The file you pass us should be valid and opened for *something* */ ASSERT(FileIO_IsValid(fdesc)); ASSERT((fdesc->flags & (FILEIO_OPEN_ACCESS_READ | FILEIO_OPEN_ACCESS_WRITE)) != 0); tmpFlags = fdesc->flags & (FILEIO_OPEN_ACCESS_READ | FILEIO_OPEN_ACCESS_WRITE); if (tmpFlags == (FILEIO_OPEN_ACCESS_READ | FILEIO_OPEN_ACCESS_WRITE)) { mode = "r+"; } else if (tmpFlags == FILEIO_OPEN_ACCESS_WRITE) { mode = "w"; } else { /* therefore (tmpFlags == FILEIO_OPEN_ACCESS_READ) */ mode = "r"; } stream = fdopen(dupFD, mode); if (stream == NULL) { close(dupFD); } return stream; } #if defined(__APPLE__) /* *---------------------------------------------------------------------- * * HostSupportsPrealloc -- * * Returns TRUE if the host OS is new enough to support F_PREALLOCATE * without data loss bugs. On OSX, this has been verified fixed * on 10.6 build with kern.osrelease 10.0.0d6. * * Results: * TRUE if the current host OS is new enough. * FALSE if it is not or we can't tell because of an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ static Bool HostSupportsPrealloc(void) { static Atomic_uint32 supported = { 0 }; enum { PREALLOC_UNKNOWN = 0, PREALLOC_YES, PREALLOC_NO } val; char curRel[32]; char type; unsigned static const int req[] = { 10, 0, 0, 6 }; unsigned int cur[4], i; int num; size_t len = sizeof(curRel); Bool ret = FALSE; val = Atomic_Read(&supported); if (val != PREALLOC_UNKNOWN) { return val == PREALLOC_YES; } if (sysctlbyname("kern.osrelease", (void *) &curRel, &len, NULL, 0) == -1) { goto exit; } curRel[31] = '\0'; Log("Current OS Release is %s\n", curRel); /* * Apple's osversion is in the format X.Y.Z which maps to the public * OSX version 10.X-4.Y, and Z is incremented for each publicly * released build. The Z part is of the form AB, where a and * B are version numbers and is either d (devel), a (alpha), * b (beta), rc, or fc. If the B is missing, then its a GA build. * * Since we're checking for 10.0.0d6, we can just say anything without * a type or with a type other than d is higher. For d, we compare * the last number. */ num = sscanf(curRel, "%u.%u.%u%c%u", &cur[0], &cur[1], &cur[2], &type, &cur[3]); if (num < 3) { goto exit; } for (i = 0; i < 3; i++) { if (req[i] > cur[i]) { goto exit; } else if (req[i] < cur[i]) { ret = TRUE; goto exit; } } if (num == 5 && type == 'd') { ret = req[3] <= cur[3]; goto exit; } /* * If we get a type with no letter (num == 4), thats odd. * Consider it mal-formatted and fail. */ ret = num != 4; exit: if (!ret && filePosixOptions.initialized && filePosixOptions.aioNumThreads == 1) { ret = TRUE; } Atomic_Write(&supported, ret ? PREALLOC_YES : PREALLOC_NO); return ret; } #else /* *---------------------------------------------------------------------- * * HostSupportsPrealloc -- * * fallocate() is supported for ext4 and xfs since 2.6.23 kernels * * Results: * TRUE if the current host is linux and kernel is >= 2.6.23. * FALSE if it is not . * * Side effects: * None. * *---------------------------------------------------------------------- */ static Bool HostSupportsPrealloc(void) { #if (defined(__linux__ ) && !defined(VMX86_SERVER)) if (Hostinfo_OSVersion(0) >=2 && Hostinfo_OSVersion(1) >=6 && Hostinfo_OSVersion(2) >=23) { return TRUE; } #endif return FALSE; } #endif /* *---------------------------------------------------------------------------- * * FileIO_SupportsPrealloc -- * * Checks if the HostOS/filesystem supports preallocation. * * Results: * TRUE if supported by the Host OS/filesystem. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool FileIO_SupportsPrealloc(const char *pathName, // IN: Bool fsCheck) // IN: { Bool ret = TRUE; if (!HostSupportsPrealloc()) { return FALSE; } if (!fsCheck) { return ret; } #if (defined( __linux__) && !defined(VMX86_SERVER)) { struct statfs statBuf; Unicode fullPath; ret = FALSE; if (!pathName) { return ret; } fullPath = File_FullPath(pathName); if (!fullPath) { return ret; } if (Posix_Statfs(fullPath, &statBuf) == 0 && statBuf.f_type == EXT4_SUPER_MAGIC) { ret = TRUE; } Unicode_Free(fullPath); } #endif return ret; } /* * The FileIOAligned_* functions are only used on * hosted (see fileInt.h for rationale). */ #if !defined(VMX86_TOOLS) && !defined(VMX86_SERVER) /* *--------------------------------------------------------------------------- * * FileIOAligned_PoolInit -- * * Initialize alignedPool. Must be called before FileIOAligned_PoolMalloc. * * Result: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ void FileIOAligned_PoolInit(void) { alignedPool.lock = MXUser_CreateSingletonExclLock(&alignedPoolLockStorage, "alignedPoolLock", RANK_LEAF); ASSERT_NOT_IMPLEMENTED(alignedPool.lock); } /* *--------------------------------------------------------------------------- * * FileIOAligned_PoolExit -- * * Tear down alignedPool. Afterwards, PoolInit can be called again if * desired. * * Result: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ void FileIOAligned_PoolExit(void) { if (!alignedPool.lock) { LOG_ONCE(("%s called without FileIOAligned_Pool lock\n", __FUNCTION__)); return; } MXUser_AcquireExclLock(alignedPool.lock); if (alignedPool.numBusy > 0) { LOG_ONCE(("%s: %d busy buffers! Proceeding with trepidation.\n", __FUNCTION__, alignedPool.numBusy)); } while (alignedPool.numAlloc > 0) { alignedPool.numAlloc--; Aligned_Free(alignedPool.list[alignedPool.numAlloc]); } MXUser_ReleaseExclLock(alignedPool.lock); MXUser_DestroyExclLock(alignedPool.lock); memset(&alignedPool, 0, sizeof alignedPool); } /* *--------------------------------------------------------------------------- * * FileIOAligned_PoolMalloc -- * * Alloc a chunk of memory aligned on a page boundary using a memory * pool. Result needs to be freed with FileIOAligned_PoolFree. Returns * NULL if the pool is full or the requested size cannot be satisfied from * the pool. * * Result: * A pointer. NULL if requested size is too large, or on out of memory * condition. * * Side effects: * None. * *--------------------------------------------------------------------------- */ void * FileIOAligned_PoolMalloc(size_t size) // IN: { void *buf = NULL; if (!alignedPool.lock) { LOG_ONCE(("%s called without FileIOAligned_Pool lock\n", __FUNCTION__)); return NULL; } if (size > ALIGNEDPOOL_BUFSZ) { return NULL; } MXUser_AcquireExclLock(alignedPool.lock); ASSERT(alignedPool.numBusy <= ARRAYSIZE(alignedPool.list)); ASSERT(alignedPool.numAlloc <= ARRAYSIZE(alignedPool.list)); ASSERT(alignedPool.numBusy <= alignedPool.numAlloc); if (alignedPool.numBusy == ARRAYSIZE(alignedPool.list)) { goto done; } if (alignedPool.numBusy == alignedPool.numAlloc) { buf = Aligned_UnsafeMalloc(ALIGNEDPOOL_BUFSZ); /* If allocation fails, just bail. */ if (buf) { alignedPool.list[alignedPool.numAlloc] = buf; alignedPool.numBusy = ++alignedPool.numAlloc; } goto done; } buf = alignedPool.list[alignedPool.numBusy]; alignedPool.numBusy++; done: MXUser_ReleaseExclLock(alignedPool.lock); return buf; } /* *--------------------------------------------------------------------------- * * FileIOAligned_PoolFree -- * * Test if a pointer was allocated from alignedPool, and if so, free it. * * Result: * TRUE if ptr was allocated from alignedPool. ptr is returned to pool. * FALSE otherwise. * * Side effects: * Might Aligned_Free() some entries from alignedPool if the timestamp[] * entries indicate that we have not needed them for a while. * *--------------------------------------------------------------------------- */ Bool FileIOAligned_PoolFree(void *ptr) // IN: { unsigned i; Bool ret = FALSE; VmTimeType now; if (!alignedPool.lock) { LOG_ONCE(("%s called without FileIOAligned_Pool lock\n", __FUNCTION__)); return FALSE; } MXUser_AcquireExclLock(alignedPool.lock); ASSERT(alignedPool.numBusy <= ARRAYSIZE(alignedPool.list)); ASSERT(alignedPool.numAlloc <= ARRAYSIZE(alignedPool.list)); ASSERT(alignedPool.numBusy <= alignedPool.numAlloc); for (i = 0; i < alignedPool.numBusy; i++) { if (alignedPool.list[i] == ptr) { break; } } if (i == alignedPool.numBusy) { /* The pointer wasn't allocated from our pool. */ goto done; } alignedPool.numBusy--; /* * At this point either i points to the "top" busy item, or i points to an * earlier busy item. If i points to the top, we're done, and the following * "swap" is a noop. If i points somewhere further down the busy list, we * can simply move the newly freed item to the top of the free list by * swapping its place with the not-freed item at list[numBusy]. */ alignedPool.list[i] = alignedPool.list[alignedPool.numBusy]; alignedPool.list[alignedPool.numBusy] = ptr; now = Hostinfo_SystemTimerNS(); alignedPool.timestamp[alignedPool.numBusy] = now; while (alignedPool.numAlloc > alignedPool.numBusy && now - alignedPool.timestamp[alignedPool.numAlloc - 1] > ALIGNEDPOOL_OLD_AGE) { alignedPool.numAlloc--; Aligned_Free(alignedPool.list[alignedPool.numAlloc]); alignedPool.list[alignedPool.numAlloc] = NULL; } ret = TRUE; done: MXUser_ReleaseExclLock(alignedPool.lock); return ret; } #endif open-vm-tools-9.4.0-1280544/lib/file/Makefile.am0000644765153500003110000000235412220061556017164 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libFile.la libFile_la_SOURCES = libFile_la_SOURCES += file.c libFile_la_SOURCES += fileStandAlone.c libFile_la_SOURCES += filePosix.c libFile_la_SOURCES += fileIO.c libFile_la_SOURCES += fileIOPosix.c libFile_la_SOURCES += fileLockPrimitive.c libFile_la_SOURCES += fileLockPosix.c libFile_la_SOURCES += fileTempPosix.c libFile_la_SOURCES += fileTemp.c open-vm-tools-9.4.0-1280544/lib/file/file.c0000644765153500003110000017516712220061556016230 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * file.c -- * * Interface to host file system. See also filePosix.c, * fileWin32.c, etc. * * If a function can be implemented such that it has no dependencies * outside of lib/misc, place the function in fileStandAlone.c, NOT * here. */ #if defined(_WIN32) #include #endif #include #include #include #include #include "safetime.h" #if defined(_WIN32) #include #define S_IXUSR 0100 #define S_IWUSR 0200 #else #include #endif #include #include #include #include "vmware.h" #include "util.h" #include "str.h" #include "msg.h" #include "log.h" #include "random.h" #include "uuid.h" #include "config.h" #include "posix.h" #include "file.h" #include "fileIO.h" #include "fileInt.h" #include "dynbuf.h" #include "base64.h" #include "timeutil.h" #include "hostinfo.h" #include "hostType.h" #include "vm_atomic.h" #include "fileLock.h" #include "userlock.h" #include "unicodeOperations.h" /* *---------------------------------------------------------------------- * * File_Exists -- * * Check if a file is accessible with the process' real user ID * * XXX - This function invokes access(), which uses the real uid, * not the effective uid, so it probably does not do what you * expect. Instead it should use Posix_EuidAccess(), which * uses the effective uid, but it's too risky to fix right now. * See PR 459242. * * Results: * TRUE file is accessible with the process' real uid * FALSE file doesn't exist or an error occured * * Side effects: * None * *---------------------------------------------------------------------- */ Bool File_Exists(ConstUnicode pathName) // IN: May be NULL. { return FileIO_IsSuccess(FileIO_Access(pathName, FILEIO_ACCESS_EXISTS)); } /* *---------------------------------------------------------------------- * * File_UnlinkIfExists -- * * If the given file exists, unlink it. * * Results: * Return 0 if the unlink is successful or if the file did not exist. * Otherwise return -1. * * Side effects: * May unlink the file. * *---------------------------------------------------------------------- */ int File_UnlinkIfExists(ConstUnicode pathName) // IN: { int ret = FileDeletion(pathName, TRUE); if (ret != 0) { ret = (ret == ENOENT) ? 0 : -1; } return ret; } /* *----------------------------------------------------------------------------- * * File_SupportsMandatoryLock -- * * Determines if the underlying filesystem for a particular location * can support mandatory locking. Mandatory locking is used within * FileLock to make the advisory FileLock self-cleaning in the event * of host failure. * * Results: * TRUE if FILEIO_OPEN_EXCLUSIVE_LOCK will work, FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool File_SupportsMandatoryLock(ConstUnicode pathName) // IN: file to be locked { /* * For now, "know" that all ESX filesystems support mandatory locks * and no non-ESX filesystems support mandatory locks. */ return HostType_OSIsVMK(); } /* *---------------------------------------------------------------------- * * File_IsDirectory -- * * Check if specified file is a directory or not. * * Results: * TRUE is a directory * FALSE is not a directory or an error occured * * Side effects: * None * *---------------------------------------------------------------------- */ Bool File_IsDirectory(ConstUnicode pathName) // IN: { FileData fileData; return (FileAttributes(pathName, &fileData) == 0) && (fileData.fileType == FILE_TYPE_DIRECTORY); } /* *----------------------------------------------------------------------------- * * File_GetFilePermissions -- * * Return the read / write / execute permissions of a file. * * Results: * TRUE if success, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool File_GetFilePermissions(ConstUnicode pathName, // IN: int *mode) // OUT: file mode { FileData fileData; ASSERT(mode); if (FileAttributes(pathName, &fileData) != 0) { return FALSE; } *mode = fileData.fileMode; #if defined(_WIN32) /* * On Win32 implementation of FileAttributes does not return execution * bit. */ if (FileIO_Access(pathName, FILEIO_ACCESS_EXEC) == FILEIO_SUCCESS) { *mode |= S_IXUSR; } #endif return TRUE; } /* *---------------------------------------------------------------------- * * File_Unlink -- * * Unlink the file. * * POSIX: If name is a symbolic link, then unlink the the file the link * refers to as well as the link itself. Only one level of links are * followed. * WINDOWS: No symbolic links so no link following. * * Results: * Return 0 if the unlink is successful. Otherwise, returns -1. * * Side effects: * The file is removed. * *---------------------------------------------------------------------- */ int File_Unlink(ConstUnicode pathName) // IN: { return (FileDeletion(pathName, TRUE) == 0) ? 0 : -1; } /* *---------------------------------------------------------------------- * * File_UnlinkNoFollow -- * * Unlink the file (do not follow symbolic links). * On Windows, there are no symbolic links so this is the same as * File_Unlink * * Results: * Return 0 if the unlink is successful. Otherwise, returns -1. * * Side effects: * The file is removed. * *---------------------------------------------------------------------- */ int File_UnlinkNoFollow(ConstUnicode pathName) // IN: { return (FileDeletion(pathName, FALSE) == 0) ? 0 : -1; } /* *---------------------------------------------------------------------- * * File_CreateDirectoryEx -- * * Creates the specified directory with the specified permissions. * * Results: * True if the directory is successfully created, false otherwise. * * Side effects: * Creates the directory on disk. * *---------------------------------------------------------------------- */ Bool File_CreateDirectoryEx(ConstUnicode pathName, // IN: int mask) // IN: { int err = FileCreateDirectory(pathName, mask); return err == 0; } /* *---------------------------------------------------------------------- * * File_CreateDirectory -- * * Creates the specified directory with 0777 permissions. * * Results: * True if the directory is successfully created, false otherwise. * * Side effects: * Creates the directory on disk. * *---------------------------------------------------------------------- */ Bool File_CreateDirectory(ConstUnicode pathName) // IN: { return File_CreateDirectoryEx(pathName, 0777); } /* *---------------------------------------------------------------------- * * File_EnsureDirectory -- * * If the directory doesn't exist, creates it. If the directory * already exists, do nothing and succeed. * * Results: * See above. * * Side effects: * May create a directory on disk. * *---------------------------------------------------------------------- */ Bool File_EnsureDirectory(ConstUnicode pathName) // IN: { int err = FileCreateDirectory(pathName, 0777); return ((err == 0) || (err == EEXIST)); } /* *---------------------------------------------------------------------- * * File_DeleteEmptyDirectory -- * * Deletes the specified directory if it is empty. * * Results: * True if the directory is successfully deleted, false otherwise. * * Side effects: * Deletes the directory from disk. * *---------------------------------------------------------------------- */ Bool File_DeleteEmptyDirectory(ConstUnicode pathName) // IN: { Bool returnValue = TRUE; if (FileRemoveDirectory(pathName) != 0) { #if defined(_WIN32) /* * Directory may have read-only bit set. Unset the * read-only bit and try deleting one more time. */ if (File_SetFilePermissions(pathName, S_IWUSR)) { if (FileRemoveDirectory(pathName) != 0) { returnValue = FALSE; } } else { returnValue = FALSE; } #else returnValue = FALSE; #endif } return returnValue; } /* *---------------------------------------------------------------------- * * GetOldMachineID -- * * Return the old machineID, the one based on Hostinfo_MachineID. * * Results: * The machineID is returned. It should not be freed. * * Side effects: * Memory allocated for the machineID is never freed, however the * memory is cached - there is no memory leak. * *---------------------------------------------------------------------- */ static const char * GetOldMachineID(void) { static Atomic_Ptr atomic; /* Implicitly initialized to NULL. --mbellon */ const char *machineID; machineID = Atomic_ReadPtr(&atomic); if (machineID == NULL) { char *p; uint32 hashValue; uint64 hardwareID; char encodedMachineID[16 + 1]; char rawMachineID[sizeof hashValue + sizeof hardwareID]; Hostinfo_MachineID(&hashValue, &hardwareID); /* Build the raw machineID */ memcpy(rawMachineID, &hashValue, sizeof hashValue); memcpy(&rawMachineID[sizeof hashValue], &hardwareID, sizeof hardwareID); /* Base 64 encode the binary data to obtain printable characters */ Base64_Encode(rawMachineID, sizeof rawMachineID, encodedMachineID, sizeof encodedMachineID, NULL); /* remove '/' from the encoding; no problem using it for a file name */ for (p = encodedMachineID; *p; p++) { if (*p == '/') { *p = '-'; } } p = Util_SafeStrdup(encodedMachineID); if (Atomic_ReadIfEqualWritePtr(&atomic, NULL, p)) { free(p); } machineID = Atomic_ReadPtr(&atomic); ASSERT(machineID); } return machineID; } /* *---------------------------------------------------------------------- * * FileLockGetMachineID -- * * Return the machineID, a "universally unique" identification of * of the system that calls this routine. * * An attempt is first made to use the host machine's UUID. If that * fails drop back to the older machineID method. * * Results: * The machineID is returned. It should not be freed. * * Side effects: * Memory allocated for the machineID is never freed, however the * memory is cached - there is no memory leak. * *---------------------------------------------------------------------- */ const char * FileLockGetMachineID(void) { static Atomic_Ptr atomic; /* Implicitly initialized to NULL. --mbellon */ const char *machineID; machineID = Atomic_ReadPtr(&atomic); if (machineID == NULL) { char *p; char *q; /* * UUID_GetHostRealUUID is fine on Windows. * * UUID_GetHostUUID is fine on Macs because the UUID can't be found * in /dev/mem even if it can be accessed. Macs always use the MAC * address from en0 to provide a UUID. * * UUID_GetHostUUID is problematic on Linux so it is not acceptable for * locking purposes - it accesses /dev/mem to obtain the SMBIOS UUID * and that can fail when the calling process is not priviledged. * */ #if defined(_WIN32) q = UUID_GetRealHostUUID(); #elif defined(__APPLE__) || defined(VMX86_SERVER) q = UUID_GetHostUUID(); #else q = NULL; #endif if (q == NULL) { p = Util_SafeStrdup(GetOldMachineID()); } else { p = Str_SafeAsprintf(NULL, "uuid=%s", q); free(q); /* Surpress any whitespace. */ for (q = p; *q; q++) { if (isspace((int) *q)) { *q = '-'; } } } if (Atomic_ReadIfEqualWritePtr(&atomic, NULL, p)) { free(p); } machineID = Atomic_ReadPtr(&atomic); ASSERT(machineID); } return machineID; } /* *----------------------------------------------------------------------------- * * OldMachineIDMatch -- * * Do the old-style MachineIDs match? * * Results: * TRUE Yes * FALSE No * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool OldMachineIDMatch(const char *first, // IN: const char *second) // IN: { #if defined(__APPLE__) || defined(linux) /* Ignore the host name hash */ char *p; char *q; size_t len; Bool result; uint8 rawMachineID_1[12]; uint8 rawMachineID_2[12]; for (p = Util_SafeStrdup(first), q = p; *p; p++) { if (*p == '-') { *p = '/'; } } result = Base64_Decode(q, rawMachineID_1, sizeof rawMachineID_1, &len); free(q); if ((result == FALSE) || (len != 12)) { Warning("%s: unexpected decode problem #1 (%s)\n", __FUNCTION__, first); return FALSE; } for (p = Util_SafeStrdup(second), q = p; *p; p++) { if (*p == '-') { *p = '/'; } } result = Base64_Decode(q, rawMachineID_2, sizeof rawMachineID_2, &len); free(q); if ((result == FALSE) || (len != 12)) { Warning("%s: unexpected decode problem #2 (%s)\n", __FUNCTION__, second); return FALSE; } return memcmp(&rawMachineID_1[4], &rawMachineID_2[4], 8) == 0 ? TRUE : FALSE; #else return strcmp(first, second) == 0 ? TRUE : FALSE; #endif } /* *----------------------------------------------------------------------------- * * FileLockMachineIDMatch -- * * Do the MachineIDs match? * * Results: * TRUE Yes * FALSE No * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool FileLockMachineIDMatch(char *hostMachineID, // IN: char *otherMachineID) // IN: { if (strncmp(hostMachineID, "uuid=", 5) == 0) { if (strncmp(otherMachineID, "uuid=", 5) == 0) { return strcmp(hostMachineID + 5, otherMachineID + 5) == 0 ? TRUE : FALSE; } else { return OldMachineIDMatch(GetOldMachineID(), otherMachineID); } } else { if (strncmp(otherMachineID, "uuid=", 5) == 0) { return FALSE; } else { return strcmp(hostMachineID, otherMachineID) == 0 ? TRUE : FALSE; } } } /* *---------------------------------------------------------------------------- * * File_IsEmptyDirectory -- * * Check if specified file is a directory and contains no files. * * Results: * Bool - TRUE -> is an empty directory, FALSE -> not an empty directory * * Side effects: * None * *---------------------------------------------------------------------------- */ Bool File_IsEmptyDirectory(ConstUnicode pathName) // IN: { int numFiles; if (!File_IsDirectory(pathName)) { return FALSE; } numFiles = File_ListDirectory(pathName, NULL); if (numFiles < 0) { return FALSE; } return numFiles == 0; } /* *---------------------------------------------------------------------- * * File_IsFile -- * * Check if specified file is a regular file. * * Results: * TRUE is a regular file * FALSE is not a regular file or an error occured. * * Side effects: * None * *---------------------------------------------------------------------- */ Bool File_IsFile(ConstUnicode pathName) // IN: { FileData fileData; return (FileAttributes(pathName, &fileData) == 0) && (fileData.fileType == FILE_TYPE_REGULAR); } /* *---------------------------------------------------------------------- * * File_CopyFromFdToFd -- * * Write all data between the current position in the 'src' file and the * end of the 'src' file to the current position in the 'dst' file * * Results: * TRUE success * FALSE failure * * Side effects: * The current position in the 'src' file and the 'dst' file are modified * *---------------------------------------------------------------------- */ Bool File_CopyFromFdToFd(FileIODescriptor src, // IN: FileIODescriptor dst) // IN: { Err_Number err; FileIOResult fretR; do { unsigned char buf[8 * 1024]; size_t actual; FileIOResult fretW; fretR = FileIO_Read(&src, buf, sizeof(buf), &actual); if (!FileIO_IsSuccess(fretR) && (fretR != FILEIO_READ_ERROR_EOF)) { err = Err_Errno(); Msg_Append(MSGID(File.CopyFromFdToFd.read.failure) "Read error: %s.\n\n", FileIO_MsgError(fretR)); Err_SetErrno(err); return FALSE; } fretW = FileIO_Write(&dst, buf, actual, NULL); if (!FileIO_IsSuccess(fretW)) { err = Err_Errno(); Msg_Append(MSGID(File.CopyFromFdToFd.write.failure) "Write error: %s.\n\n", FileIO_MsgError(fretW)); Err_SetErrno(err); return FALSE; } } while (fretR != FILEIO_READ_ERROR_EOF); return TRUE; } /* *---------------------------------------------------------------------- * * File_CopyFromFdToName -- * * Copy the 'src' file to 'dstName'. * If the 'dstName' file already exists, * If 'dstDispose' is -1, the user is prompted for proper action. * If 'dstDispose' is 0, retry until success (dangerous). * If 'dstDispose' is 1, overwrite the file. * If 'dstDispose' is 2, return the error. * * Results: * TRUE on success * FALSE on failure: if the user cancelled the operation, no message is * appended. Otherwise messages are appended * * Side effects: * None * *---------------------------------------------------------------------- */ Bool File_CopyFromFdToName(FileIODescriptor src, // IN: ConstUnicode dstName, // IN: int dstDispose) // IN: { Bool success; Err_Number err; FileIOResult fret; FileIODescriptor dst; ASSERT(dstName); FileIO_Invalidate(&dst); fret = File_CreatePrompt(&dst, dstName, 0, dstDispose); if (!FileIO_IsSuccess(fret)) { err = Err_Errno(); if (fret != FILEIO_CANCELLED) { Msg_Append(MSGID(File.CopyFromFdToName.create.failure) "Unable to create a new '%s' file: %s.\n\n", UTF8(dstName), FileIO_MsgError(fret)); } Err_SetErrno(err); return FALSE; } success = File_CopyFromFdToFd(src, dst); err = Err_Errno(); if (FileIO_Close(&dst) != 0) { if (success) { // Report close failure when there isn't another error err = Err_Errno(); } Msg_Append(MSGID(File.CopyFromFdToName.close.failure) "Unable to close the '%s' file: %s.\n\n", UTF8(dstName), Msg_ErrString()); success = FALSE; } if (!success) { /* The copy failed: ensure the destination file is removed */ File_Unlink(dstName); } Err_SetErrno(err); return success; } /* *---------------------------------------------------------------------- * * File_CreatePrompt -- * * Create the 'name' file for write access or 'access' access. * If the 'name' file already exists, * If 'prompt' is not -1, it is the automatic answer to the question that * would be asked to the user if it was -1. * * Results: * FILEIO_CANCELLED if the operation was cancelled by the user, otherwise * as FileIO_Open() * * Side effects: * None * *---------------------------------------------------------------------- */ FileIOResult File_CreatePrompt(FileIODescriptor *file, // OUT: ConstUnicode pathName, // IN: int access, // IN: int prompt) // IN: { FileIOResult fret; FileIOOpenAction action; ASSERT(file); ASSERT(pathName); action = FILEIO_OPEN_CREATE_SAFE; while ((fret = FileIO_Open(file, pathName, FILEIO_OPEN_ACCESS_WRITE | access, action)) == FILEIO_OPEN_ERROR_EXIST) { static Msg_String const buttons[] = { {BUTTONID(file.create.retry) "Retry"}, {BUTTONID(file.create.overwrite) "Overwrite"}, {BUTTONID(cancel) "Cancel"}, {NULL} }; int answer; Err_Number err = Err_Errno(); answer = (prompt != -1) ? prompt : Msg_Question(buttons, 2, MSGID(File.CreatePrompt.question) "The file '%s' already exists.\n" "To overwrite the content of the file, select Overwrite.\n" "To retry the operation after you have moved the file " "to another location, select Retry.\n" "To cancel the operation, select Cancel.\n", UTF8(pathName)); Err_SetErrno(err); if (answer == 2) { fret = FILEIO_CANCELLED; break; } if (answer == 1) { action = FILEIO_OPEN_CREATE_EMPTY; } } return fret; } /* *---------------------------------------------------------------------- * * File_CopyFromNameToName -- * * Copy the 'srcName' file to 'dstName'. * If 'srcName' doesn't exist, an error is reported * If the 'dstName' file already exists, * If 'dstDispose' is -1, the user is prompted for proper action. * If 'dstDispose' is 0, retry until success (dangerous). * If 'dstDispose' is 1, overwrite the file. * If 'dstDispose' is 2, return the error. * * Results: * TRUE on success * FALSE on failure: if the user cancelled the operation, no message is * appended. Otherwise messages are appended * * Side effects: * None * *---------------------------------------------------------------------- */ Bool File_CopyFromNameToName(ConstUnicode srcName, // IN: ConstUnicode dstName, // IN: int dstDispose) // IN: { Bool success; Err_Number err; FileIOResult fret; FileIODescriptor src; ASSERT(srcName); ASSERT(dstName); FileIO_Invalidate(&src); fret = FileIO_Open(&src, srcName, FILEIO_OPEN_ACCESS_READ, FILEIO_OPEN); if (!FileIO_IsSuccess(fret)) { err = Err_Errno(); Msg_Append(MSGID(File.CopyFromNameToName.open.failure) "Unable to open the '%s' file for read access: %s.\n\n", UTF8(srcName), FileIO_MsgError(fret)); Err_SetErrno(err); return FALSE; } success = File_CopyFromFdToName(src, dstName, dstDispose); err = Err_Errno(); if (FileIO_Close(&src) != 0) { if (success) { // Report close failure when there isn't another error err = Err_Errno(); } Msg_Append(MSGID(File.CopyFromNameToName.close.failure) "Unable to close the '%s' file: %s.\n\n", UTF8(srcName), Msg_ErrString()); success = FALSE; } Err_SetErrno(err); return success; } /* *----------------------------------------------------------------------------- * * FileCopyTree -- * * Recursively copies all files from a source path to a destination, * optionally overwriting any files. This does the actual work * for File_CopyTree. * * Results: * TRUE on success * FALSE on failure: Error messages are appended. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool FileCopyTree(ConstUnicode srcName, // IN: ConstUnicode dstName, // IN: Bool overwriteExisting, // IN: Bool followSymlinks) // IN: { int err; Bool success = TRUE; int numFiles; int i; Unicode *fileList = NULL; numFiles = File_ListDirectory(srcName, &fileList); if (numFiles == -1) { err = Err_Errno(); Msg_Append(MSGID(File.CopyTree.walk.failure) "Unable to access '%s' when copying files.\n\n", UTF8(srcName)); Err_SetErrno(err); return FALSE; } File_EnsureDirectory(dstName); for (i = 0; i < numFiles && success; i++) { struct stat sb; Unicode name; Unicode srcFilename; name = Unicode_Alloc(fileList[i], STRING_ENCODING_DEFAULT); srcFilename = File_PathJoin(srcName, name); if (followSymlinks) { success = (Posix_Stat(srcFilename, &sb) == 0); } else { success = (Posix_Lstat(srcFilename, &sb) == 0); } if (success) { Unicode dstFilename = File_PathJoin(dstName, name); switch (sb.st_mode & S_IFMT) { case S_IFDIR: success = FileCopyTree(srcFilename, dstFilename, overwriteExisting, followSymlinks); break; #if !defined(_WIN32) case S_IFLNK: if (Posix_Symlink(Posix_ReadLink(srcFilename), dstFilename) != 0) { err = Err_Errno(); Msg_Append(MSGID(File.CopyTree.symlink.failure) "Unable to symlink '%s' to '%s': %s\n\n", UTF8(Posix_ReadLink(srcFilename)), UTF8(dstFilename), Err_Errno2String(err)); Err_SetErrno(err); success = FALSE; } break; #endif default: if (!File_Copy(srcFilename, dstFilename, overwriteExisting)) { err = Err_Errno(); Msg_Append(MSGID(File.CopyTree.copy.failure) "Unable to copy '%s' to '%s': %s\n\n", UTF8(srcFilename), UTF8(dstFilename), Err_Errno2String(err)); Err_SetErrno(err); success = FALSE; } break; } Unicode_Free(dstFilename); } else { err = Err_Errno(); Msg_Append(MSGID(File.CopyTree.stat.failure) "Unable to get information on '%s' when copying files.\n\n", UTF8(srcFilename)); Err_SetErrno(err); } Unicode_Free(srcFilename); Unicode_Free(name); } for (i = 0; i < numFiles; i++) { Unicode_Free(fileList[i]); } free(fileList); return success; } /* *----------------------------------------------------------------------------- * * File_CopyTree -- * * Recursively copies all files from a source path to a destination, * optionally overwriting any files. * * Results: * TRUE on success * FALSE on failure: Error messages are appended. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool File_CopyTree(ConstUnicode srcName, // IN: ConstUnicode dstName, // IN: Bool overwriteExisting, // IN: Bool followSymlinks) // IN: { int err; ASSERT(srcName); ASSERT(dstName); if (!File_IsDirectory(srcName)) { err = Err_Errno(); Msg_Append(MSGID(File.CopyTree.source.notDirectory) "Source path '%s' is not a directory.", UTF8(srcName)); Err_SetErrno(err); return FALSE; } if (!File_IsDirectory(dstName)) { err = Err_Errno(); Msg_Append(MSGID(File.CopyTree.dest.notDirectory) "Destination path '%s' is not a directory.", UTF8(dstName)); Err_SetErrno(err); return FALSE; } return FileCopyTree(srcName, dstName, overwriteExisting, followSymlinks); } /* *---------------------------------------------------------------------- * * File_CopyFromFd -- * * Copy the 'src' file to 'dstName'. * If the 'dstName' file already exists, 'overwriteExisting' * decides whether to overwrite the existing file or not. * * Results: * TRUE on success * FALSE on failure: Messages are appended * * Side effects: * None * *---------------------------------------------------------------------- */ Bool File_CopyFromFd(FileIODescriptor src, // IN: ConstUnicode dstName, // IN: Bool overwriteExisting) // IN: { Bool success; Err_Number err; FileIOResult fret; FileIODescriptor dst; FileIOOpenAction action; ASSERT(dstName); FileIO_Invalidate(&dst); action = overwriteExisting ? FILEIO_OPEN_CREATE_EMPTY : FILEIO_OPEN_CREATE_SAFE; fret = FileIO_Open(&dst, dstName, FILEIO_OPEN_ACCESS_WRITE, action); if (!FileIO_IsSuccess(fret)) { err = Err_Errno(); Msg_Append(MSGID(File.CopyFromFdToName.create.failure) "Unable to create a new '%s' file: %s.\n\n", UTF8(dstName), FileIO_MsgError(fret)); Err_SetErrno(err); return FALSE; } success = File_CopyFromFdToFd(src, dst); err = Err_Errno(); if (FileIO_Close(&dst) != 0) { if (success) { // Report close failure when there isn't another error err = Err_Errno(); } Msg_Append(MSGID(File.CopyFromFdToName.close.failure) "Unable to close the '%s' file: %s.\n\n", UTF8(dstName), Msg_ErrString()); success = FALSE; } if (!success) { /* The copy failed: ensure the destination file is removed */ File_Unlink(dstName); } Err_SetErrno(err); return success; } /* *---------------------------------------------------------------------- * * File_Copy -- * * Copy the 'srcName' file to 'dstName'. * If 'srcName' doesn't exist, an error is reported * If the 'dstName' file already exists, 'overwriteExisting' * decides whether to overwrite the existing file or not. * * Results: * TRUE on success * FALSE on failure: Messages are appended * * Side effects: * None * *---------------------------------------------------------------------- */ Bool File_Copy(ConstUnicode srcName, // IN: ConstUnicode dstName, // IN: Bool overwriteExisting) // IN: { Bool success; Err_Number err; FileIOResult fret; FileIODescriptor src; ASSERT(srcName); ASSERT(dstName); FileIO_Invalidate(&src); fret = FileIO_Open(&src, srcName, FILEIO_OPEN_ACCESS_READ, FILEIO_OPEN); if (!FileIO_IsSuccess(fret)) { err = Err_Errno(); Msg_Append(MSGID(File.Copy.open.failure) "Unable to open the '%s' file for read access: %s.\n\n", UTF8(srcName), FileIO_MsgError(fret)); Err_SetErrno(err); return FALSE; } success = File_CopyFromFd(src, dstName, overwriteExisting); err = Err_Errno(); if (FileIO_Close(&src) != 0) { if (success) { // Report close failure when there isn't another error err = Err_Errno(); } Msg_Append(MSGID(File.Copy.close.failure) "Unable to close the '%s' file: %s.\n\n", UTF8(srcName), Msg_ErrString()); success = FALSE; } Err_SetErrno(err); return success; } /* *---------------------------------------------------------------------- * * File_Move -- * * Moves a file from one place to the other as efficiently as possible. * This can be used to rename a file but, since file copying may be * necessary, there is no assurance of atomicity. For efficiency * purposes copying only results if the native rename ability fails. * * Results: * TRUE succeeded * FALSE otherwise * * Side effects: * src file is no more, but dst file exists * *---------------------------------------------------------------------- */ Bool File_Move(ConstUnicode oldFile, // IN: ConstUnicode newFile, // IN: Bool *asRename) // OUT: result occurred due to rename/copy { Bool ret; Bool duringRename; if (File_Rename(oldFile, newFile) == 0) { duringRename = TRUE; ret = TRUE; Err_SetErrno(0); } else { duringRename = FALSE; if (File_Copy(oldFile, newFile, TRUE)) { // Allow overwrite File_Unlink(oldFile); // Explicitly ignore errors ret = TRUE; Err_SetErrno(0); } else { ret = FALSE; } } if (asRename) { *asRename = duringRename; } return ret; } /* *----------------------------------------------------------------------------- * * File_MoveTree -- * * Moves a directory from one place to the other. * - If dstName indicates a path that does not exist a directory will be * created with that path filled with the contents from srcName. * - If dstName is an existing directory then the contents will be moved * into that directory. * - If dstName indicates a file then File_MoveTree fails. * * First we'll attempt to rename the directory, failing that we copy the * contents from src->destination and unlink the src. If the copy is * succesful then we will report success even if the unlink fails for some * reason. In that event we will append error messages. * * Results: * TRUE - on success * FALSE - on failure with error messages appended * * Side effects: * - Deletes the originating directory * - In the event of a failed copy we'll leave the new directory in a state * *----------------------------------------------------------------------------- */ Bool File_MoveTree(ConstUnicode srcName, // IN: ConstUnicode dstName, // IN: Bool overwriteExisting) // IN: { Bool ret = FALSE; Bool createdDir = FALSE; ASSERT(srcName); ASSERT(dstName); if (!File_IsDirectory(srcName)) { Msg_Append(MSGID(File.MoveTree.source.notDirectory) "Source path '%s' is not a directory.", UTF8(srcName)); return FALSE; } if (File_Rename(srcName, dstName) == 0) { ret = TRUE; } else { struct stat statbuf; if (-1 == Posix_Stat(dstName, &statbuf)) { int err = Err_Errno(); if (ENOENT == err) { if (!File_CreateDirectoryHierarchy(dstName, NULL)) { Msg_Append(MSGID(File.MoveTree.dst.couldntCreate) "Could not create '%s'.\n\n", UTF8(dstName)); return FALSE; } createdDir = TRUE; } else { Msg_Append(MSGID(File.MoveTree.statFailed) "%d:Failed to stat destination '%s'.\n\n", err, UTF8(dstName)); return FALSE; } } else { if (!File_IsDirectory(dstName)) { Msg_Append(MSGID(File.MoveTree.dest.notDirectory) "The destination path '%s' is not a directory.\n\n", UTF8(dstName)); return FALSE; } } #if !defined(__FreeBSD__) && !defined(sun) /* * File_GetFreeSpace is not defined for FreeBSD */ if (createdDir) { /* * Check for free space on destination filesystem. * We only check for free space if the destination directory * did not exist. In this case, we will not be overwriting any existing * paths, so we need as much space as srcName. */ int64 srcSize; int64 freeSpace; srcSize = File_GetSizeEx(srcName); freeSpace = File_GetFreeSpace(dstName, TRUE); if (freeSpace < srcSize) { Unicode spaceStr = Msg_FormatSizeInBytes(srcSize); Msg_Append(MSGID(File.MoveTree.dst.insufficientSpace) "There is not enough space in the file system to " "move the directory tree. Free %s and try again.", spaceStr); free(spaceStr); return FALSE; } } #endif if (File_CopyTree(srcName, dstName, overwriteExisting, FALSE)) { ret = TRUE; if (!File_DeleteDirectoryTree(srcName)) { Msg_Append(MSGID(File.MoveTree.cleanupFailed) "Forced to copy '%s' into '%s' but unable to remove " "source directory.\n\n", UTF8(srcName), UTF8(dstName)); } } else { ret = FALSE; Msg_Append(MSGID(File.MoveTree.copyFailed) "Could not rename and failed to copy source directory " "'%s'.\n\n", UTF8(srcName)); if (createdDir) { /* * Only clean up if we created the directory. Not attempting to * clean up partial failures. */ File_DeleteDirectoryTree(dstName); } } } return ret; } /* *---------------------------------------------------------------------- * * File_GetModTimeString -- * * Returns a human-readable string denoting the last modification * time of a file. * ctime() returns string terminated with newline, which we replace * with a '\0'. * * Results: * Last modification time string on success, NULL on error. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * File_GetModTimeString(ConstUnicode pathName) // IN: { int64 modTime; modTime = File_GetModTime(pathName); return (modTime == -1) ? NULL : TimeUtil_GetTimeFormat(modTime, TRUE, TRUE); } /* *---------------------------------------------------------------------------- * * File_GetSize -- * * Get size of file. Try File_GetSizeEx to get size of directory/symlink. * * Results: * Size of file or -1. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int64 File_GetSize(ConstUnicode pathName) // IN: { int64 ret; if (pathName == NULL) { ret = -1; } else { FileIODescriptor fd; FileIOResult res; FileIO_Invalidate(&fd); res = FileIO_Open(&fd, pathName, FILEIO_OPEN_ACCESS_READ, FILEIO_OPEN); if (FileIO_IsSuccess(res)) { ret = FileIO_GetSize(&fd); FileIO_Close(&fd); } else { ret = -1; } } return ret; } /* *---------------------------------------------------------------------- * * File_SupportsLargeFiles -- * * Check if the given file is on an FS that supports 4GB files. * Require 4GB support so we rule out FAT filesystems, which * support 4GB-1 on both Linux and Windows. * * Results: * TRUE if FS supports files over 4GB. * * Side effects: * None * *---------------------------------------------------------------------- */ Bool File_SupportsLargeFiles(ConstUnicode pathName) // IN: { return File_SupportsFileSize(pathName, CONST64U(0x100000000)); } /* *---------------------------------------------------------------------------- * * File_GetSizeEx -- * * Get size of file or directory or symlink. File_GetSize can only get * size of file. * * Results: * Size of file/directory/symlink or -1. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int64 File_GetSizeEx(ConstUnicode pathName) // IN { int numFiles; int i; Unicode *fileList = NULL; struct stat sb; int64 totalSize = 0; if (pathName == NULL) { return -1; } if (-1 == Posix_Lstat(pathName, &sb)) { return -1; } if (S_IFDIR != (sb.st_mode & S_IFMT)) { return sb.st_size; } numFiles = File_ListDirectory(pathName, &fileList); if (-1 == numFiles) { return -1; } for (i = 0; i < numFiles; i++) { Unicode name; Unicode fileName; int64 fileSize; name = Unicode_Alloc(fileList[i], STRING_ENCODING_DEFAULT); fileName = File_PathJoin(pathName, name); fileSize = File_GetSizeEx(fileName); Unicode_Free(fileName); Unicode_Free(name); if (-1 == fileSize) { totalSize = -1; break; } else { totalSize += fileSize; } } if (numFiles >= 0) { Unicode_FreeList(fileList, numFiles); } return totalSize; } /* *---------------------------------------------------------------------------- * * File_GetSizeByPath -- * * Get size of a file without opening it. * * Results: * Size of file or -1. * * Side effects: * None. * *---------------------------------------------------------------------------- */ int64 File_GetSizeByPath(ConstUnicode pathName) // IN: { return (pathName == NULL) ? -1 : FileIO_GetSizeByPath(pathName); } /* *----------------------------------------------------------------------------- * * File_CreateDirectoryHierarchyEx -- * * Create a directory including any parents that don't already exist. * All the created directories are tagged with the specified permission. * Returns the topmost directory which was created, to allow calling code * to remove it after in case later operations fail. * * Results: * TRUE on success, FALSE on failure. * * If topmostCreated is not NULL, it returns the result of the hierarchy * creation. If no directory was created, *topmostCreated is set to NULL. * Otherwise *topmostCreated is set to the topmost directory which was * created. *topmostCreated is set even in case of failure. * * The caller most Unicode_Free the resulting string. * * Side effects: * Only the obvious. * *----------------------------------------------------------------------------- */ Bool File_CreateDirectoryHierarchyEx(ConstUnicode pathName, // IN: int mask, // IN Unicode *topmostCreated) // OUT: { Unicode volume; UnicodeIndex index; UnicodeIndex length; if (topmostCreated != NULL) { *topmostCreated = NULL; } if (pathName == NULL) { return TRUE; } length = Unicode_LengthInCodePoints(pathName); if (length == 0) { return TRUE; } /* * Skip past any volume/share. */ File_SplitName(pathName, &volume, NULL, NULL); index = Unicode_LengthInCodePoints(volume); Unicode_Free(volume); if (index >= length) { return File_IsDirectory(pathName); } /* * Iterate parent directories, splitting on appropriate dir separators. */ while (TRUE) { Bool failed; Unicode temp; index = FileFirstSlashIndex(pathName, index + 1); temp = Unicode_Substr(pathName, 0, (index == UNICODE_INDEX_NOT_FOUND) ? -1 : index); if (File_IsDirectory(temp)) { failed = FALSE; } else { failed = !File_CreateDirectoryEx(temp, mask); if (!failed && topmostCreated != NULL && *topmostCreated == NULL) { *topmostCreated = temp; temp = NULL; } } Unicode_Free(temp); if (failed) { return FALSE; } if (index == UNICODE_INDEX_NOT_FOUND) { break; } } return TRUE; } /* *----------------------------------------------------------------------------- * * File_CreateDirectoryHierarchy -- * * Create a directory including any parents that don't already exist. * All the created directories are tagged with 0777 permissions. * Returns the topmost directory which was created, to allow calling code * to remove it after in case later operations fail. * * Results: * TRUE on success, FALSE on failure. * * If topmostCreated is not NULL, it returns the result of the hierarchy * creation. If no directory was created, *topmostCreated is set to NULL. * Otherwise *topmostCreated is set to the topmost directory which was * created. *topmostCreated is set even in case of failure. * * The caller most Unicode_Free the resulting string. * * Side effects: * Only the obvious. * *----------------------------------------------------------------------------- */ Bool File_CreateDirectoryHierarchy(ConstUnicode pathName, // IN: Unicode *topmostCreated) // OUT: { return File_CreateDirectoryHierarchyEx(pathName, 0777, topmostCreated); } /* *---------------------------------------------------------------------- * * File_DeleteDirectoryTree -- * * Deletes the specified directory tree. If filesystem errors are * encountered along the way, the function will continue to delete what * it can but will return FALSE. * * Results: * TRUE the entire tree was deleted or didn't exist * FALSE otherwise. * * Side effects: * Deletes the directory tree from disk. * *---------------------------------------------------------------------- */ Bool File_DeleteDirectoryTree(ConstUnicode pathName) // IN: directory to delete { int i; int numFiles; int err = 0; Unicode base; Unicode *fileList = NULL; Bool sawFileError = FALSE; if (Posix_EuidAccess(pathName, F_OK) != 0) { /* * If Posix_EuidAccess failed with errno == ENOSYS, then fall back * to FileAttributes. */ if (errno == ENOSYS) { /* FileAttributes returns the error code instead of setting errno. */ err = FileAttributes(pathName, NULL); } else { /* Use the error value that was set by Posix_EuidAccess. */ err = errno; } } switch (err) { case ENOENT: case ENOTDIR: /* path does not exist or is inaccessible */ return TRUE; default: break; } /* get list of files in current directory */ numFiles = File_ListDirectory(pathName, &fileList); if (numFiles == -1) { return FALSE; } /* delete everything in the directory */ base = Unicode_Append(pathName, DIRSEPS); for (i = 0; i < numFiles; i++) { Unicode curPath; struct stat statbuf; curPath = Unicode_Append(base, fileList[i]); if (Posix_Lstat(curPath, &statbuf) == 0) { switch (statbuf.st_mode & S_IFMT) { case S_IFDIR: /* Directory, recurse */ if (!File_DeleteDirectoryTree(curPath)) { sawFileError = TRUE; } break; #if !defined(_WIN32) case S_IFLNK: /* Delete symlink, not what it points to */ if (FileDeletion(curPath, FALSE) != 0) { sawFileError = TRUE; } break; #endif default: if (FileDeletion(curPath, FALSE) != 0) { #if defined(_WIN32) if (File_SetFilePermissions(curPath, S_IWUSR)) { if (FileDeletion(curPath, FALSE) != 0) { sawFileError = TRUE; } } else { sawFileError = TRUE; } #else sawFileError = TRUE; #endif } break; } } else { sawFileError = TRUE; } Unicode_Free(curPath); } Unicode_Free(base); /* * Call File_DeleteEmptyDirectory() only if there is no prior error * while deleting the children. */ if (!sawFileError && !File_DeleteEmptyDirectory(pathName)) { sawFileError = TRUE; } for (i = 0; i < numFiles; i++) { Unicode_Free(fileList[i]); } free(fileList); return !sawFileError; } /* *----------------------------------------------------------------------------- * * File_FindFileInSearchPath -- * * Search all the directories in searchPath for a filename. * If searchPath has a relative path take it with respect to cwd. * searchPath must be ';' delimited. * * Results: * TRUE if a file is found. FALSE otherwise. * * Side effects: * If result is non Null allocate a string for the filename found. * *----------------------------------------------------------------------------- */ Bool File_FindFileInSearchPath(const char *fileIn, // IN: const char *searchPath, // IN: const char *cwd, // IN: char **result) // OUT: { char *cur; char *tok; Bool found; Bool full; char *saveptr = NULL; char *sp = NULL; Unicode dir = NULL; Unicode file = NULL; ASSERT(fileIn); ASSERT(cwd); ASSERT(searchPath); /* * First check the usual places - the fullpath or the cwd. */ full = File_IsFullPath(fileIn); if (full) { cur = Util_SafeStrdup(fileIn); } else { cur = Str_SafeAsprintf(NULL, "%s%s%s", cwd, DIRSEPS, fileIn); } if (Posix_EuidAccess(cur, F_OK) == 0) { goto done; } if (errno == ENOSYS && FileAttributes(cur, NULL) == 0) { goto done; } free(cur); cur = NULL; if (full) { goto done; } File_GetPathName(fileIn, &dir, &file); /* * Search path applies only if filename is simple basename. */ if (Unicode_LengthInCodePoints(dir) != 0) { goto done; } /* * Didn't find it in the usual places so strip it to its bare minimum and * start searching. */ sp = Util_SafeStrdup(searchPath); tok = strtok_r(sp, FILE_SEARCHPATHTOKEN, &saveptr); while (tok) { if (File_IsFullPath(tok)) { /* Fully Qualified Path. Use it. */ cur = Str_SafeAsprintf(NULL, "%s%s%s", tok, DIRSEPS, file); } else { /* Relative Path. Prepend the cwd. */ if (Str_Strcasecmp(tok, ".") == 0) { /* Don't append "." */ cur = Str_SafeAsprintf(NULL, "%s%s%s", cwd, DIRSEPS, file); } else { cur = Str_SafeAsprintf(NULL, "%s%s%s%s%s", cwd, DIRSEPS, tok, DIRSEPS, file); } } if (Posix_EuidAccess(cur, F_OK) == 0) { break; } if ((errno == ENOSYS) && (FileAttributes(cur, NULL) == 0)) { break; } free(cur); cur = NULL; tok = strtok_r(NULL, FILE_SEARCHPATHTOKEN, &saveptr); } done: if (cur) { found = TRUE; if (result) { *result = File_FullPath(cur); if (*result == NULL) { found = FALSE; } } free(cur); } else { found = FALSE; } free(sp); Unicode_Free(dir); Unicode_Free(file); return found; } /* *---------------------------------------------------------------------- * * File_ExpandAndCheckDir -- * * Expand any environment variables in the given path and check that * the named directory is writeable. * * Results: * NULL if error, the expanded path otherwise. * * Side effects: * The result is allocated. * *---------------------------------------------------------------------- */ char * File_ExpandAndCheckDir(const char *dirName) // IN: { if (dirName != NULL) { char *edirName = Util_ExpandString(dirName); if ((edirName != NULL) && FileIsWritableDir(edirName)) { size_t len = strlen(edirName) - 1; if (edirName[len] == DIRSEPC) { edirName[len] = '\0'; } return edirName; } } return NULL; } /* *----------------------------------------------------------------------------- * * FileSimpleRandom -- * * Return a random number in the range of 0 and 2^32-1. * * Results: * Random number is returned. * * Side Effects: * None. * *----------------------------------------------------------------------------- */ uint32 FileSimpleRandom(void) { static Atomic_Ptr lckStorage; static rqContext *context = NULL; uint32 result; MXUserExclLock *lck = MXUser_CreateSingletonExclLock(&lckStorage, "fileSimpleRandomLock", RANK_LEAF); ASSERT_NOT_IMPLEMENTED(lck != NULL); MXUser_AcquireExclLock(lck); if (UNLIKELY(context == NULL)) { uint32 value; #if defined(_WIN32) value = GetCurrentProcessId(); #else value = getpid(); #endif context = Random_QuickSeed(value); ASSERT(context); } result = Random_Quick(context); MXUser_ReleaseExclLock(lck); return result; } /* *---------------------------------------------------------------------- * * FileSleeper * * Sleep for a random amount of time, no less than the specified minimum * and no more than the specified maximum sleep time values. This often * proves useful to "jitter" retries such that multiple threads don't * easily get into resonance performing necessary actions. * * Results: * Somnambulistic behavior; the amount of time slept is returned. * * Side effects: * None * *---------------------------------------------------------------------- */ uint32 FileSleeper(uint32 msecMinSleepTime, // IN: uint32 msecMaxSleepTime) // IN: { uint32 variance; uint32 msecActualSleepTime; ASSERT(msecMinSleepTime <= msecMaxSleepTime); variance = msecMaxSleepTime - msecMinSleepTime; if (variance == 0) { msecActualSleepTime = msecMinSleepTime; } else { float fpRand = ((float) FileSimpleRandom()) / ((float) ~((uint32) 0)); msecActualSleepTime = msecMinSleepTime + (uint32) (fpRand * variance); } usleep(1000 * msecActualSleepTime); return msecActualSleepTime; } /* *---------------------------------------------------------------------- * * FileRotateByRename -- * * The oldest indexed file should be removed so that the consequent * rename succeeds. * * The last dst is 'fileName' and should not be deleted. * * Results: * If newFileName is non-NULL: the new path is returned to *newFileName * if the rotation succeeded, otherwise NULL is returned in *newFileName. * The caller is responsible for freeing the string returned in * *newFileName. * * Side effects: * Rename backup old files kept so far. * *---------------------------------------------------------------------- */ static void FileRotateByRename(const char *fileName, // IN: full path to file const char *baseName, // IN: filename w/o extension. const char *ext, // IN: extension int n, // IN: number of old files to keep char **newFileName) // OUT/OPT: new path to file { char *src = NULL; char *dst = NULL; int i; int result; if (newFileName != NULL) { *newFileName = NULL; } for (i = n; i >= 0; i--) { src = (i == 0) ? (char *) fileName : Str_SafeAsprintf(NULL, "%s-%d%s", baseName, i - 1, ext); if (dst == NULL) { result = File_UnlinkIfExists(src); if (result == -1) { Log(LGPFX" %s: failed to remove %s: %s\n", __FUNCTION__, src, Msg_ErrString()); } } else { result = Posix_Rename(src, dst); if (result == -1) { int error = Err_Errno(); if (error != ENOENT) { Log(LGPFX" %s: failed to rename %s -> %s: %s\n", src, dst, __FUNCTION__, Err_Errno2String(error)); } } } if ((src == fileName) && (newFileName != NULL) && (result == 0)) { *newFileName = Util_SafeStrdup(dst); } ASSERT(dst != fileName); free(dst); dst = src; } } /* *---------------------------------------------------------------------- * * FileNumberCompare -- * * Helper function for comparing the contents of two * uint32 pointers a and b, suitable for use by qsort * to order an array of file numbers. * * Results: * The contents of 'a' minus the contents of 'b'. * * Side effects: * None. */ static int FileNumberCompare(const void *a, // IN: const void *b) // IN: { return *(uint32 *) a - *(uint32 *) b; } /* *---------------------------------------------------------------------- * * FileRotateByRenumber -- * * File rotation scheme optimized for vmfs: * 1) find highest numbered file (maxNr) * 2) rename . to -. * 3) delete (nFound - numToKeep) lowest numbered files. * * Wrap around is handled incorrectly. * * Results: * If newFilePath is non-NULL: the new path is returned to *newFilePath * if the rotation succeeded, otherwise NULL is returned in *newFilePath. * The caller is responsible for freeing the string returned in * *newFilePath. * * Side effects: * Files renamed / deleted. * *---------------------------------------------------------------------- */ static void FileRotateByRenumber(const char *filePath, // IN: full path to file const char *filePathNoExt, // IN: filename w/o extension. const char *ext, // IN: extension int n, // IN: number old files to keep char **newFilePath) // OUT/OPT: new path to file { char *baseDir = NULL, *fmtString = NULL, *baseName = NULL, *tmp; char *fullPathNoExt = NULL; uint32 maxNr = 0; int i, nrFiles, nFound = 0; char **fileList = NULL; uint32 *fileNumbers = NULL; int result; if (newFilePath != NULL) { *newFilePath = NULL; } fullPathNoExt = File_FullPath(filePathNoExt); if (fullPathNoExt == NULL) { Log(LGPFX" %s: failed to get full path for '%s'.\n", __FUNCTION__, filePathNoExt); goto cleanup; } File_GetPathName(fullPathNoExt, &baseDir, &baseName); if ((baseDir[0] == '\0') || (baseName[0] == '\0')) { Log(LGPFX" %s: failed to get base dir for path '%s'.\n", __FUNCTION__, filePathNoExt); goto cleanup; } fmtString = Str_SafeAsprintf(NULL, "%s-%%d%s%%n", baseName, ext); nrFiles = File_ListDirectory(baseDir, &fileList); if (nrFiles == -1) { Log(LGPFX" %s: failed to read the directory '%s'.\n", __FUNCTION__, baseDir); goto cleanup; } fileNumbers = Util_SafeCalloc(nrFiles, sizeof(uint32)); for (i = 0; i < nrFiles; i++) { uint32 curNr; int bytesProcessed = 0; /* * Make sure the whole file name matched what we expect for the file. */ if ((sscanf(fileList[i], fmtString, &curNr, &bytesProcessed) >= 1) && (bytesProcessed == strlen(fileList[i]))) { fileNumbers[nFound++] = curNr; } free(fileList[i]); } if (nFound > 0) { qsort(fileNumbers, nFound, sizeof(uint32), FileNumberCompare); maxNr = fileNumbers[nFound - 1]; } /* rename the existing file to the next number */ tmp = Str_SafeAsprintf(NULL, "%s/%s-%d%s", baseDir, baseName, maxNr + 1, ext); result = Posix_Rename(filePath, tmp); if (result == -1) { int error = Err_Errno(); if (error != ENOENT) { Log(LGPFX" %s: failed to rename %s -> %s failed: %s\n", __FUNCTION__, filePath, tmp, Err_Errno2String(error)); } } if (newFilePath != NULL) { if (result == -1) { free(tmp); } else { *newFilePath = tmp; } } if (nFound >= n) { /* Delete the extra files. */ for (i = 0; i <= nFound - n; i++) { tmp = Str_SafeAsprintf(NULL, "%s/%s-%d%s", baseDir, baseName, fileNumbers[i], ext); if (Posix_Unlink(tmp) == -1) { Log(LGPFX" %s: failed to remove %s: %s\n", __FUNCTION__, tmp, Msg_ErrString()); } free(tmp); } } cleanup: free(fileNumbers); free(fileList); free(fmtString); free(baseDir); free(baseName); free(fullPathNoExt); } /* *---------------------------------------------------------------------- * * File_Rotate -- * * Rotate old files. The 'noRename' option is useful for filesystems * where rename is hideously expensive (*cough* vmfs). * * Results: * If newFileName is non-NULL: the new path is returned to * *newFileName if the rotation succeeded, otherwise NULL * is returned in *newFileName. The caller is responsible * for freeing the string returned in *newFileName. * * Side effects: * Files are renamed / deleted. * *---------------------------------------------------------------------- */ void File_Rotate(const char *fileName, // IN: original file int n, // IN: number of backup files Bool noRename, // IN: don't rename all files char **newFileName) // OUT/OPT: new path to file { const char *ext; size_t baseLen; char *baseName; if ((ext = Str_Strrchr(fileName, '.')) == NULL) { ext = fileName + strlen(fileName); } baseLen = ext - fileName; /* * Backup base of file name. * * Since the Str_Asprintf(...) doesn't like format of %.*s and crashes * in Windows 2000. (Daniel Liu) */ baseName = Util_SafeStrdup(fileName); baseName[baseLen] = '\0'; if (noRename) { FileRotateByRenumber(fileName, baseName, ext, n, newFileName); } else { FileRotateByRename(fileName, baseName, ext, n, newFileName); } free(baseName); } /* *----------------------------------------------------------------------------- * * File_GetFSMountInfo -- * * Platform-independent wrapper around File_GetVMFSMountInfo * * Results: * On failure return -1. Otherwise, return fsType, version, * remoteIP, remoteMountPoint, and localMountPoint. * * Side effects: * None * *----------------------------------------------------------------------------- */ int File_GetFSMountInfo(ConstUnicode pathName, char **fsType, uint32 *version, char **remoteIP, char **remoteMountPoint, char **localMountPoint) { #if defined VMX86_SERVER return File_GetVMFSMountInfo(pathName, fsType, version, remoteIP, remoteMountPoint, localMountPoint); #else return -1; #endif } open-vm-tools-9.4.0-1280544/lib/file/fileTempPosix.c0000644765153500003110000003402512220061556020064 0ustar dtormts/********************************************************* * Copyright (C) 2004-2011 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if !defined(__FreeBSD__) && !defined(sun) # include #endif #if defined(sun) # include #endif #include "vmware.h" #include "file.h" #include "fileInt.h" #include "util.h" #include "su.h" #include "vm_atomic.h" #include "str.h" #include "vm_version.h" #include "random.h" #include "userlock.h" #include "unicodeOperations.h" #include "err.h" #include "posix.h" #include "mutexRankLib.h" #include "hostType.h" #include "localconfig.h" #define LOGLEVEL_MODULE util #include "loglevel_user.h" /* *---------------------------------------------------------------------- * * FileTryDir -- * * Check to see if the given directory is actually a directory * and is writable by us. * * Results: * The expanded directory name on success, NULL on failure. * * Side effects: * The result is allocated. * *---------------------------------------------------------------------- */ static char * FileTryDir(const char *dirName) // IN: Is this a writable directory? { char *edirName; if (dirName != NULL) { edirName = Util_ExpandString(dirName); if ((edirName != NULL) && FileIsWritableDir(edirName)) { return edirName; } free(edirName); } return NULL; } /* *---------------------------------------------------------------------- * * FileGetTmpDir -- * * Determine the best temporary directory. Unsafe since the * returned directory is generally going to be 0777, thus all sorts * of denial of service or symlink attacks are possible. * * Results: * NULL if error (reported to the user). * * Side effects: * The result is allocated. * *---------------------------------------------------------------------- */ static char * FileGetTmpDir(Bool useConf) // IN: Use the config file? { char *dirName; char *edirName; /* Make several attempts to find a good temporary directory candidate */ if (useConf) { dirName = (char *)LocalConfig_GetString(NULL, "tmpDirectory"); edirName = FileTryDir(dirName); free(dirName); if (edirName != NULL) { return edirName; } } /* Posix_Getenv string must _not_ be freed */ edirName = FileTryDir(Posix_Getenv("TMPDIR")); if (edirName != NULL) { return edirName; } /* P_tmpdir is usually defined in */ edirName = FileTryDir(P_tmpdir); if (edirName != NULL) { return edirName; } edirName = FileTryDir("/tmp"); if (edirName != NULL) { return edirName; } edirName = FileTryDir("~"); if (edirName != NULL) { return edirName; } dirName = File_Cwd(NULL); if (dirName != NULL) { edirName = FileTryDir(dirName); free(dirName); if (edirName != NULL) { return edirName; } } edirName = FileTryDir("/"); if (edirName != NULL) { return edirName; } Warning("%s: Couldn't get a temporary directory\n", __FUNCTION__); return NULL; } #undef HOSTINFO_TRYDIR #if !defined(__FreeBSD__) && !defined(sun) /* *----------------------------------------------------------------------------- * * FileGetUserName -- * * Retrieve the name associated with a user ID. Thread-safe * version. --hpreg * * Results: * The allocated name on success * NULL on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ static char * FileGetUserName(uid_t uid) // IN: { char *memPool; char *userName; struct passwd pw; struct passwd *pw_p; long memPoolSize; #if defined(__APPLE__) memPoolSize = _PASSWORD_LEN; #else memPoolSize = sysconf(_SC_GETPW_R_SIZE_MAX); if (memPoolSize <= 0) { Warning("%s: sysconf(_SC_GETPW_R_SIZE_MAX) failed.\n", __FUNCTION__); return NULL; } #endif memPool = malloc(memPoolSize); if (memPool == NULL) { Warning("%s: Not enough memory.\n", __FUNCTION__); return NULL; } if ((Posix_Getpwuid_r(uid, &pw, memPool, memPoolSize, &pw_p) != 0) || pw_p == NULL) { free(memPool); Warning("%s: Unable to retrieve the username associated with " "user ID %u.\n", __FUNCTION__, uid); return NULL; } userName = strdup(pw_p->pw_name); free(memPool); if (userName == NULL) { Warning("%s: Not enough memory.\n", __FUNCTION__); return NULL; } return userName; } /* *----------------------------------------------------------------------------- * * FileAcceptableSafeTmpDir -- * * Determines if the specified path is acceptable as the safe * temp directory. The directory must either be creatable * with the appropriate permissions and userId or it must * already exist with those settings. * * Results: * TRUE if path is acceptible, FALSE otherwise * * Side effects: * Directory may be created * *----------------------------------------------------------------------------- */ static Bool FileAcceptableSafeTmpDir(const char *dirname, // IN: int userId) // IN: { Bool result; static const mode_t mode = 0700; result = (Posix_Mkdir(dirname, mode) == 0); if (!result) { int error = errno; if (EEXIST == error) { struct stat st; /* * The name already exists. Check that it is what we want: a * directory owned by the current effective user with permissions * 'mode'. It is crucial to use lstat() instead of stat() here, * because we do not want the name to be a symlink (created by * another user) pointing to a directory owned by the current * effective user with permissions 'mode'. */ if (0 == Posix_Lstat(dirname, &st)) { /* * Our directory inherited S_ISGID if its parent had it. So it * is important to ignore that bit, and it is safe to do so * because that bit does not affect the owner's permissions. */ if (S_ISDIR(st.st_mode) && (st.st_uid == userId) && ((st.st_mode & 05777) == mode)) { result = TRUE; } } } } return result; } /* *----------------------------------------------------------------------------- * * FileFindExistingSafeTmpDir -- * * Searches the directory baseTmpDir to see if any subdirectories * are suitable to use as the safe temp directory. The safe temp * directory must have the correct permissions and userId. * * Results: * Path to discovered safe temp directory (must be freed). * NULL returned if no suitable directory is found. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Unicode FileFindExistingSafeTmpDir(uid_t userId, // IN: const char *userName, // IN: const char *baseTmpDir) // IN: { int i; int numFiles; Unicode pattern; Unicode tmpDir = NULL; Unicode *fileList = NULL; /* * We always use the pattern PRODUCT-USER-xxxx when creating * alternative safe temp directories, so check for ones with * those names and the appropriate permissions. */ pattern = Unicode_Format("%s-%s-", PRODUCT_GENERIC_NAME_LOWER, userName); if (pattern == NULL) { return NULL; } numFiles = File_ListDirectory(baseTmpDir, &fileList); if (numFiles == -1) { Unicode_Free(pattern); return NULL; } for (i = 0; i < numFiles; i++) { if (Unicode_StartsWith(fileList[i], pattern)) { Unicode path = Unicode_Join(baseTmpDir, DIRSEPS, fileList[i], NULL); if (File_IsDirectory(path) && FileAcceptableSafeTmpDir(path, userId)) { tmpDir = path; break; } Unicode_Free(path); } } Unicode_FreeList(fileList, numFiles); Unicode_Free(pattern); return tmpDir; } /* *----------------------------------------------------------------------------- * * FileCreateSafeTmpDir -- * * Creates a new directory within baseTmpDir with the correct permissions * and userId to ensure it is safe from symlink attacks. * * Results: * Path to created safe temp directory (must be freed). * NULL returned if no suitable directory could be created. * * Side effects: * Directory may be created. * *----------------------------------------------------------------------------- */ static char * FileCreateSafeTmpDir(uid_t userId, // IN: const char *userName, // IN: const char *baseTmpDir) // IN: { static const int MAX_DIR_ITERS = 250; int curDirIter = 0; char *tmpDir = NULL; while (TRUE) { /* * We use a random number that makes it more likely that we will create * an unused name than if we had simply tried suffixes in numeric order. */ tmpDir = Str_Asprintf(NULL, "%s%s%s-%s-%u", baseTmpDir, DIRSEPS, PRODUCT_GENERIC_NAME_LOWER, userName, FileSimpleRandom()); if (!tmpDir) { Warning("%s: Out of memory error.\n", __FUNCTION__); break; } if (FileAcceptableSafeTmpDir(tmpDir, userId)) { break; } if (++curDirIter > MAX_DIR_ITERS) { Warning("%s: Failed to create a safe temporary directory, path " "\"%s\". The maximum number of attempts was exceeded.\n", __FUNCTION__, tmpDir); free(tmpDir); tmpDir = NULL; break; } free(tmpDir); tmpDir = NULL; } return tmpDir; } #endif // __linux__ /* *----------------------------------------------------------------------------- * * File_GetSafeTmpDir -- * * Return a safe temporary directory (i.e. a temporary directory which * is not prone to symlink attacks, because it is only writable by the * current effective user). * * Guaranteed to return the same directory every time it is * called during the lifetime of the current process, for the * current effective user ID. (Barring the user manually deleting * or renaming the directory.) * * Results: * The allocated directory path on success. * NULL on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ char * File_GetSafeTmpDir(Bool useConf) // IN: { char *tmpDir; #if defined(__FreeBSD__) || defined(sun) tmpDir = FileGetTmpDir(useConf); #else static Atomic_Ptr lckStorage; static char *safeDir; char *baseTmpDir = NULL; char *userName = NULL; uid_t userId; MXUserExclLock *lck; userId = geteuid(); /* Get and take lock for our safe dir. */ lck = MXUser_CreateSingletonExclLock(&lckStorage, "getSafeTmpDirLock", RANK_getSafeTmpDirLock); ASSERT_NOT_IMPLEMENTED(lck != NULL); MXUser_AcquireExclLock(lck); /* * Check if we've created a temporary dir already and if it is still usable. */ tmpDir = NULL; if (safeDir && FileAcceptableSafeTmpDir(safeDir, userId)) { tmpDir = Util_SafeStrdup(safeDir); goto exit; } /* We don't have a useable temporary dir, create one. */ baseTmpDir = FileGetTmpDir(useConf); if (!baseTmpDir) { Warning("%s: FileGetTmpDir failed.\n", __FUNCTION__); goto exit; } userName = FileGetUserName(userId); if (!userName) { Warning("%s: FileGetUserName failed, using numeric ID " "as username instead.\n", __FUNCTION__); /* Fallback on just using the userId as the username. */ userName = Str_Asprintf(NULL, "uid-%d", userId); if (!userName) { Warning("%s: Str_Asprintf error.\n", __FUNCTION__); goto exit; } } tmpDir = Str_Asprintf(NULL, "%s%s%s-%s", baseTmpDir, DIRSEPS, PRODUCT_GENERIC_NAME_LOWER, userName); if (!tmpDir) { Warning("%s: Out of memory error.\n", __FUNCTION__); goto exit; } if (!FileAcceptableSafeTmpDir(tmpDir, userId)) { /* * We didn't get our first choice for the safe temp directory. * Search through the unsafe tmp directory to see if there is * an acceptable one to use. */ free(tmpDir); tmpDir = FileFindExistingSafeTmpDir(userId, userName, baseTmpDir); if (!tmpDir) { /* * We didn't find any usable directories, so try to create one now. */ tmpDir = FileCreateSafeTmpDir(userId, userName, baseTmpDir); } } if (tmpDir) { /* * We have successfully created a temporary directory, remember it for * future calls. */ free(safeDir); safeDir = Util_SafeStrdup(tmpDir); } exit: MXUser_ReleaseExclLock(lck); free(baseTmpDir); free(userName); #endif return tmpDir; } open-vm-tools-9.4.0-1280544/lib/file/fileTemp.c0000644765153500003110000002312112220061556017034 0ustar dtormts/********************************************************* * Copyright (C) 2011 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #if defined(_WIN32) #include #endif #include #include #include #include #include #include #include #include #include "vmware.h" #include "log.h" #include "file.h" #include "fileInt.h" #include "util.h" #include "unicodeOperations.h" #include "posix.h" #if !defined(O_BINARY) #define O_BINARY 0 #endif /* *---------------------------------------------------------------------- * * FileTempNum -- * * Compute a number to be used as an attachment to a base name. * In order to avoid race conditions, files and directories are * kept separate via enforced odd (file) and even (directory) * numberings. * * Regardless of the input value of *var, the output value will * be even or odd as determined by createTempFile. * * Results: * An odd number if createTempFile is TRUE. * An even number if createTempFile is FALSE. * * Side effects: * None * *---------------------------------------------------------------------- */ static void FileTempNum(Bool createTempFile, // IN: uint32 *var) // IN/OUT: { ASSERT(var); *var += (FileSimpleRandom() >> 8) & 0xFF; *var = (*var & ~0x1) | (createTempFile ? 1 : 0); } /* *---------------------------------------------------------------------- * * File_MakeTempEx2 -- * * Create a temporary file or a directory. * If a temporary file is created successfully, then return an open file * descriptor to that file. * * 'dir' specifies the directory in which to create the file. It * must not end in a slash. * * 'createTempFile', if TRUE, then a temporary file will be created. If * FALSE, then a temporary directory will be created. * * 'createNameFunc' specifies the user-specified callback function that * will be called to construct the fileName. 'createNameFuncData' will be * passed everytime 'createNameFunc' is called. 'createNameFunc' * should return the proper fileName. * * Check the documentation for File_MakeTempHelperFunc. * * Results: * if a temporary file is created, then Open file descriptor or -1; * if a temporary directory is created, then 0 or -1; * If successful then presult points to a dynamically allocated * string with the pathname of the temp file. * * Side effects: * Creates the requested object when successful. Errno is set on error * * Files and directories are effectively in separate name spaces; * the numerical value attached via createNameFunc is odd for files * and even for directories. * *---------------------------------------------------------------------- */ int File_MakeTempEx2(ConstUnicode dir, // IN: Bool createTempFile, // IN: File_MakeTempCreateNameFunc *createNameFunc, // IN: void *createNameFuncData, // IN: Unicode *presult) // OUT: { uint32 i; int fd = -1; uint32 var = 0; Unicode path = NULL; if ((dir == NULL) || (createNameFunc == NULL)) { errno = EFAULT; return -1; } ASSERT(presult); *presult = NULL; for (i = 0; i < (MAX_INT32 / 2); i++) { Unicode fileName; /* construct suffixed pathname to use */ Unicode_Free(path); path = NULL; /* * Files and directories are kept separate (odd and even respectfully). * This way the available exclusion mechanisms work properly - O_EXCL * on files, mkdir on directories - and races are avoided. * * Not attempting an open on a directory is a good thing... */ FileTempNum(createTempFile, &var); fileName = (*createNameFunc)(var, createNameFuncData); ASSERT(fileName); /* construct base full pathname to use */ path = Unicode_Join(dir, DIRSEPS, fileName, NULL); Unicode_Free(fileName); if (createTempFile) { fd = Posix_Open(path, O_CREAT | O_EXCL | O_BINARY | O_RDWR, 0600); } else { fd = Posix_Mkdir(path, 0700); } if (fd != -1) { *presult = path; path = NULL; break; } if (errno != EEXIST) { Log(LGPFX" Failed to create temporary %s \"%s\": %s.\n", createTempFile ? "file" : "directory", UTF8(path), strerror(errno)); goto exit; } } if (fd == -1) { Warning(LGPFX" Failed to create temporary %s \"%s\": " "The name space is full.\n", createTempFile ? "file" : "directory", UTF8(path)); errno = EAGAIN; } exit: Unicode_Free(path); return fd; } /* *---------------------------------------------------------------------------- * * FileMakeTempExCreateNameFunc -- * * This is a helper function designed for File_MakeTempEx function. * Everytime this function is called, this creates a fileName with the * format and returns back to the caller. * * 'num' specifies the nth time this function is called. * * 'data' specifies the payload that is specified when File_MakeTempEx2() * function is called. This points to a Unicode string. * * Results: * if successful, a dynamically allocated string with the basename of * the temp file. NULL otherwise. * * Side effects: * None * *---------------------------------------------------------------------------- */ static Unicode FileMakeTempExCreateNameFunc(uint32 num, // IN: void *data) // IN: { if (data == NULL) { return NULL; } return Unicode_Format("%s%u", (Unicode) data, num); } /* *---------------------------------------------------------------------- * * File_MakeTempEx -- * * Create a temporary file and, if successful, return an open file * descriptor to that file. * * 'dir' specifies the directory in which to create the file. It * must not end in a slash. * * 'fileName' specifies the base filename of the created file. * * Results: * Open file descriptor or -1; if successful then presult points * to a dynamically allocated string with the pathname of the temp * file. * * Side effects: * Creates a file if successful. Errno is set on error * *---------------------------------------------------------------------- */ int File_MakeTempEx(ConstUnicode dir, // IN: ConstUnicode fileName, // IN: Unicode *presult) // OUT: { return File_MakeTempEx2(dir, TRUE, FileMakeTempExCreateNameFunc, (void *) fileName, presult); } /* *---------------------------------------------------------------------- * * File_MakeSafeTemp -- * * Exactly the same as File_MakeTemp except uses a safe directory * as the default temporary directory. * * Results: * Open file descriptor or -1 * * Side effects: * Creates a file if successful. *---------------------------------------------------------------------- */ int File_MakeSafeTemp(ConstUnicode tag, // IN (OPT): Unicode *presult) // OUT: { int fd; Unicode dir = NULL; Unicode fileName = NULL; ASSERT(presult); *presult = NULL; if (tag && File_IsFullPath(tag)) { File_GetPathName(tag, &dir, &fileName); } else { dir = File_GetSafeTmpDir(TRUE); fileName = Unicode_Duplicate(tag ? tag : "vmware"); } fd = File_MakeTempEx(dir, fileName, presult); Unicode_Free(dir); Unicode_Free(fileName); return fd; } /* *----------------------------------------------------------------------------- * * File_DoesVolumeSupportAcls -- * * Determines if the volume that the pathname resides on supports * ACLs. * * Results: * TRUE it does * FALSE it doesn't * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool File_DoesVolumeSupportAcls(ConstUnicode path) // IN: { Bool succeeded = FALSE; #if defined(_WIN32) Bool res; Unicode vol, vol2; const utf16_t *vol2W; DWORD fsFlags; ASSERT(path); File_SplitName(path, &vol, NULL, NULL); vol2 = Unicode_Append(vol, DIRSEPS); vol2W = UNICODE_GET_UTF16(vol2); res = GetVolumeInformationW(vol2W, NULL, 0, NULL, NULL, &fsFlags, NULL, 0); UNICODE_RELEASE_UTF16(vol2W); if (res) { if ((fsFlags & FS_PERSISTENT_ACLS) == 0) { goto exit; } } else { Log(LGPFX" %s: GetVolumeInformation failed: %d\n", __FUNCTION__, GetLastError()); goto exit; } succeeded = TRUE; exit: Unicode_Free(vol); Unicode_Free(vol2); #endif return succeeded; } open-vm-tools-9.4.0-1280544/lib/file/filePosix.c0000644765153500003110000023417612220061556017247 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * filePosix.c -- * * Interface to Posix-specific file functions. */ #include /* Needed before sys/vfs.h with glibc 2.0 --hpreg */ #if defined(__FreeBSD__) # include # include #else # if !defined(__APPLE__) # include # endif # include # include /* Needed before sys/mnttab.h in Solaris */ # if defined(sun) # include # elif __APPLE__ # include # else # include # endif #include #endif #include #include #include #include #include #include #include #if defined(__linux__) # include #endif #include "vmware.h" #include "posix.h" #include "file.h" #include "fileInt.h" #include "msg.h" #include "util.h" #include "str.h" #include "util.h" #include "timeutil.h" #include "dynbuf.h" #include "localconfig.h" #include "hostType.h" #include "vmfs.h" #define LOGLEVEL_MODULE main #include "loglevel_user.h" #include "unicodeOperations.h" #if !defined(__FreeBSD__) && !defined(sun) #if !defined(__APPLE__) static char *FilePosixLookupMountPoint(char const *canPath, Bool *bind); #endif static char *FilePosixNearestExistingAncestor(char const *path); #if defined(VMX86_SERVER) #define VMFS3CONST 256 #include "hostType.h" /* Needed for VMFS implementation of File_GetFreeSpace() */ # include # endif #endif #if defined(VMX86_SERVER) #include "fs_user.h" #endif /* * XXX * FTS is not available on all posix platforms that we care about. * We depend on FTS for a simple pre-order file traversal. For the Windows * implementation we need to write our own traversal code anyway. When that * happens the prosix version should be updated to use the generic code. */ #if defined(__USE_FILE_OFFSET64) || defined(sun) || defined(__ANDROID__) # define CAN_USE_FTS 0 #else # define CAN_USE_FTS 1 #endif #if CAN_USE_FTS # include struct WalkDirContextImpl { FTS *fts; }; #endif /* A string for NFS on ESX file system type */ #define FS_NFS_ON_ESX "NFS" /* A string for VMFS on ESX file system type */ #define FS_VMFS_ON_ESX "VMFS" #define FS_VSAN_URI_PREFIX "vsan:" #if defined __ANDROID__ /* * Android doesn't support setmntent(), endmntent() or MOUNTED. */ #define NO_SETMNTENT #define NO_ENDMNTENT #endif /* Long path chunk growth size */ #define FILE_PATH_GROW_SIZE 1024 /* *----------------------------------------------------------------------------- * * FileRemoveDirectory -- * * Delete a directory. * * Results: * 0 success * > 0 failure (errno) * * Side effects: * May change the host file system. * *----------------------------------------------------------------------------- */ int FileRemoveDirectory(ConstUnicode pathName) // IN: { return (Posix_Rmdir(pathName) == -1) ? errno : 0; } /* *----------------------------------------------------------------------------- * * File_Rename -- * * Rename a file. * * Results: * 0 success * > 0 failure (errno) * * Side effects: * May change the host file system. * *----------------------------------------------------------------------------- */ int File_Rename(ConstUnicode oldName, // IN: ConstUnicode newName) // IN: { return (Posix_Rename(oldName, newName) == -1) ? errno : 0; } int File_RenameRetry(ConstUnicode oldFile, // IN: ConstUnicode newFile, // IN: uint32 msecMaxWaitTime) // IN: Unused. { return File_Rename(oldFile, newFile); } /* *---------------------------------------------------------------------- * * FileDeletion -- * Delete the specified file. A NULL pathName will result in an error * and errno will be set to EFAULT. * * Results: * 0 success * > 0 failure (errno) * * Side effects: * May change the host file system. errno may be set. * *---------------------------------------------------------------------- */ int FileDeletion(ConstUnicode pathName, // IN: const Bool handleLink) // IN: { int err; if (pathName == NULL) { errno = EFAULT; return errno; } if (handleLink) { Unicode linkPath = Posix_ReadLink(pathName); if (linkPath == NULL) { /* If there is no link involved, continue */ err = errno; if (err != EINVAL) { goto bail; } } else { err = (Posix_Unlink(linkPath) == -1) ? errno : 0; Unicode_Free(linkPath); /* Ignore a file that has already disappeared */ if (err != ENOENT) { goto bail; } } } err = (Posix_Unlink(pathName) == -1) ? errno : 0; bail: return err; } /* *----------------------------------------------------------------------------- * * File_UnlinkDelayed -- * * Same as File_Unlink for POSIX systems since we can unlink anytime. * * Results: * Return 0 if the unlink is successful. Otherwise, returns -1. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int File_UnlinkDelayed(ConstUnicode pathName) // IN: { return (FileDeletion(pathName, TRUE) == 0) ? 0 : -1; } /* *----------------------------------------------------------------------------- * * FileAttributes -- * * Return the attributes of a file. Time units are in OS native time. * * Results: * 0 success * > 0 failure (errno) * * Side effects: * None * *----------------------------------------------------------------------------- */ int FileAttributes(ConstUnicode pathName, // IN: FileData *fileData) // OUT: { int err; struct stat statbuf; if (Posix_Stat(pathName, &statbuf) == -1) { err = errno; } else { if (fileData != NULL) { fileData->fileCreationTime = statbuf.st_ctime; fileData->fileModificationTime = statbuf.st_mtime; fileData->fileAccessTime = statbuf.st_atime; fileData->fileSize = statbuf.st_size; switch (statbuf.st_mode & S_IFMT) { case S_IFREG: fileData->fileType = FILE_TYPE_REGULAR; break; case S_IFDIR: fileData->fileType = FILE_TYPE_DIRECTORY; break; case S_IFBLK: fileData->fileType = FILE_TYPE_BLOCKDEVICE; break; case S_IFCHR: fileData->fileType = FILE_TYPE_CHARDEVICE; break; case S_IFLNK: fileData->fileType = FILE_TYPE_SYMLINK; break; default: fileData->fileType = FILE_TYPE_UNCERTAIN; break; } fileData->fileMode = statbuf.st_mode; fileData->fileOwner = statbuf.st_uid; fileData->fileGroup = statbuf.st_gid; } err = 0; } return err; } /* *---------------------------------------------------------------------- * * File_IsRemote -- * * Determine whether a file is on a remote filesystem. * * On ESX all files are treated as local files, as all * callers of this function wants to do is to post message * that performance will be degraded on remote filesystems. * On ESX (a) performance should be acceptable with remote * files, and (b) even if it is not, we should not ask users * whether they are aware that it is poor. ESX has * performance monitoring which can notify user if something * is wrong. * * On hosted platform we report remote files as faithfully * as we can because having mainmem file on NFS is known * to badly affect VM consistency when NFS filesystem gets * reconnected. Due to that we are conservative, and report * filesystem as remote if there was some problem with * determining file remoteness. * * Results: * The answer. * * Side effects: * None * *---------------------------------------------------------------------- */ #if !defined(__FreeBSD__) && !defined(sun) Bool File_IsRemote(ConstUnicode pathName) // IN: Path name { if (HostType_OSIsVMK()) { /* * All files and file systems are treated as "directly attached" * on ESX. See bug 158284. */ return FALSE; } else { struct statfs sfbuf; if (Posix_Statfs(pathName, &sfbuf) == -1) { Log(LGPFX" %s: statfs(%s) failed: %s\n", __func__, UTF8(pathName), Err_Errno2String(errno)); return TRUE; } #if defined(__APPLE__) return sfbuf.f_flags & MNT_LOCAL ? FALSE : TRUE; #else if (NFS_SUPER_MAGIC == sfbuf.f_type) { return TRUE; } if (SMB_SUPER_MAGIC == sfbuf.f_type) { return TRUE; } if (CIFS_SUPER_MAGIC == sfbuf.f_type) { return TRUE; } return FALSE; #endif } } #endif /* !FreeBSD && !sun */ /* *---------------------------------------------------------------------- * * File_IsSymLink -- * * Check if the specified file is a symbolic link or not * * Results: * Bool - TRUE -> is a symlink, FALSE -> not a symlink or error * * Side effects: * None * *---------------------------------------------------------------------- */ Bool File_IsSymLink(ConstUnicode pathName) // IN: { struct stat statbuf; return (Posix_Lstat(pathName, &statbuf) == 0) && S_ISLNK(statbuf.st_mode); } /* *---------------------------------------------------------------------- * * File_Cwd -- * * Find the current directory on drive DRIVE. DRIVE is either NULL * (current drive) or a string starting with [A-Za-z]. * * Results: * NULL if error. * * Side effects: * The result is allocated * *---------------------------------------------------------------------- */ Unicode File_Cwd(ConstUnicode drive) // IN: { size_t size; char *buffer; Unicode path; if ((drive != NULL) && !Unicode_IsEmpty(drive)) { Warning(LGPFX" %s: Drive letter %s on Linux?\n", __FUNCTION__, UTF8(drive)); } size = FILE_PATH_GROW_SIZE; buffer = Util_SafeMalloc(size); while (TRUE) { if (getcwd(buffer, size) != NULL) { break; } free(buffer); buffer = NULL; if (errno != ERANGE) { break; } size += FILE_PATH_GROW_SIZE; buffer = Util_SafeMalloc(size); } if (buffer == NULL) { Msg_Append(MSGID(filePosix.getcwd) "Unable to retrieve the current working directory: %s. " "Check if the directory has been deleted or unmounted.\n", Msg_ErrString()); Warning(LGPFX" %s: getcwd() failed: %s\n", __FUNCTION__, Msg_ErrString()); return NULL; } path = Unicode_Alloc(buffer, STRING_ENCODING_DEFAULT); free(buffer); return path; } /* *---------------------------------------------------------------------- * * FileStripFwdSlashes -- * * Returns a new string with the extraneous forward slashes ("/") removed. * * Results: * As documented. * * Side effects: * None * *---------------------------------------------------------------------- */ static Unicode FileStripFwdSlashes(ConstUnicode pathName) // IN: { char *ptr; char *path; char *cptr; char *prev; Unicode result; ASSERT(pathName); path = Unicode_GetAllocBytes(pathName, STRING_ENCODING_UTF8); ASSERT(path != NULL); ptr = path; cptr = path; prev = NULL; /* * Copy over if not DIRSEPC. If yes, copy over only if previous * character was not DIRSEPC. */ while (*ptr != '\0') { if (*ptr == DIRSEPC) { if (prev != ptr - 1) { *cptr++ = *ptr; } prev = ptr; } else { *cptr++ = *ptr; } ptr++; } *cptr = '\0'; result = Unicode_AllocWithUTF8(path); free(path); return result; } /* *---------------------------------------------------------------------- * * File_FullPath -- * * Compute the full path of a file. If the file if NULL or "", the * current directory is returned * * Results: * NULL if error (reported to the user) * * Side effects: * The result is allocated * *---------------------------------------------------------------------- */ Unicode File_FullPath(ConstUnicode pathName) // IN: { Unicode cwd; Unicode ret; if ((pathName != NULL) && File_IsFullPath(pathName)) { cwd = NULL; } else { cwd = File_Cwd(NULL); if (cwd == NULL) { return NULL; } } if ((pathName == NULL) || Unicode_IsEmpty(pathName)) { ret = Unicode_Duplicate(cwd); } else if (File_IsFullPath(pathName)) { ret = Posix_RealPath(pathName); if (ret == NULL) { ret = FileStripFwdSlashes(pathName); } } else { Unicode path = Unicode_Join(cwd, DIRSEPS, pathName, NULL); ret = Posix_RealPath(path); if (ret == NULL) { ret = FileStripFwdSlashes(path); } Unicode_Free(path); } Unicode_Free(cwd); return ret; } /* *---------------------------------------------------------------------- * * File_IsFullPath -- * * Is this a full path? * * Results: * TRUE if full path. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool File_IsFullPath(ConstUnicode pathName) // IN: { /* start with a slash? */ return (pathName == NULL) ? FALSE : Unicode_StartsWith(pathName, DIRSEPS); } /* *---------------------------------------------------------------------- * * File_GetTimes -- * * Get the date and time that a file was created, last accessed, * last modified and last attribute changed. * * Results: * TRUE if succeed or FALSE if error. * * Side effects: * If a particular time is not available, -1 will be returned for * that time. * *---------------------------------------------------------------------- */ Bool File_GetTimes(ConstUnicode pathName, // IN: VmTimeType *createTime, // OUT: Windows NT time format VmTimeType *accessTime, // OUT: Windows NT time format VmTimeType *writeTime, // OUT: Windows NT time format VmTimeType *attrChangeTime) // OUT: Windows NT time format { struct stat statBuf; ASSERT(createTime && accessTime && writeTime && attrChangeTime); *createTime = -1; *accessTime = -1; *writeTime = -1; *attrChangeTime = -1; if (Posix_Lstat(pathName, &statBuf) == -1) { Log(LGPFX" %s: error stating file \"%s\": %s\n", __FUNCTION__, UTF8(pathName), Err_Errno2String(errno)); return FALSE; } /* * XXX We should probably use the MIN of all Unix times for the creation * time, so that at least times are never inconsistent in the * cross-platform format. Maybe atime is always that MIN. We should * check and change the code if it is not. * * XXX atime is almost always MAX. */ #if defined(__FreeBSD__) /* * FreeBSD: All supported versions have timestamps with nanosecond * resolution. FreeBSD 5+ has also file creation time. */ # if defined(__FreeBSD_version) && __FreeBSD_version >= 500043 *createTime = TimeUtil_UnixTimeToNtTime(statBuf.st_birthtimespec); # endif *accessTime = TimeUtil_UnixTimeToNtTime(statBuf.st_atimespec); *writeTime = TimeUtil_UnixTimeToNtTime(statBuf.st_mtimespec); *attrChangeTime = TimeUtil_UnixTimeToNtTime(statBuf.st_ctimespec); #elif defined(linux) /* * Linux: Glibc 2.3+ has st_Xtim. Glibc 2.1/2.2 has st_Xtime/__unusedX on * same place (see below). We do not support Glibc 2.0 or older. */ # if (__GLIBC__ == 2) && (__GLIBC_MINOR__ < 3) && !defined(__UCLIBC__) { /* * stat structure is same between glibc 2.3 and older glibcs, just * these __unused fields are always zero. If we'll use __unused* * instead of zeroes, we get automatically nanosecond timestamps * when running on host which provides them. */ struct timespec timeBuf; timeBuf.tv_sec = statBuf.st_atime; timeBuf.tv_nsec = statBuf.__unused1; *accessTime = TimeUtil_UnixTimeToNtTime(timeBuf); timeBuf.tv_sec = statBuf.st_mtime; timeBuf.tv_nsec = statBuf.__unused2; *writeTime = TimeUtil_UnixTimeToNtTime(timeBuf); timeBuf.tv_sec = statBuf.st_ctime; timeBuf.tv_nsec = statBuf.__unused3; *attrChangeTime = TimeUtil_UnixTimeToNtTime(timeBuf); } # elif defined(__ANDROID__) { struct timespec timeBuf; timeBuf.tv_sec = statBuf.st_atime; timeBuf.tv_nsec = statBuf.st_atime_nsec; *accessTime = TimeUtil_UnixTimeToNtTime(timeBuf); timeBuf.tv_sec = statBuf.st_mtime; timeBuf.tv_nsec = statBuf.st_mtime_nsec; *writeTime = TimeUtil_UnixTimeToNtTime(timeBuf); timeBuf.tv_sec = statBuf.st_ctime; timeBuf.tv_nsec = statBuf.st_ctime_nsec; *attrChangeTime = TimeUtil_UnixTimeToNtTime(timeBuf); } # else *accessTime = TimeUtil_UnixTimeToNtTime(statBuf.st_atim); *writeTime = TimeUtil_UnixTimeToNtTime(statBuf.st_mtim); *attrChangeTime = TimeUtil_UnixTimeToNtTime(statBuf.st_ctim); # endif #elif defined(__APPLE__) /* Mac: No file create timestamp. */ *accessTime = TimeUtil_UnixTimeToNtTime(statBuf.st_atimespec); *writeTime = TimeUtil_UnixTimeToNtTime(statBuf.st_mtimespec); *attrChangeTime = TimeUtil_UnixTimeToNtTime(statBuf.st_ctimespec); #else { /* Solaris: No nanosecond timestamps, no file create timestamp. */ struct timespec timeBuf; timeBuf.tv_nsec = 0; timeBuf.tv_sec = statBuf.st_atime; *accessTime = TimeUtil_UnixTimeToNtTime(timeBuf); timeBuf.tv_sec = statBuf.st_mtime; *writeTime = TimeUtil_UnixTimeToNtTime(timeBuf); timeBuf.tv_sec = statBuf.st_ctime; *attrChangeTime = TimeUtil_UnixTimeToNtTime(timeBuf); } #endif return TRUE; } /* *---------------------------------------------------------------------- * * File_SetTimes -- * * Set the date and time that a file was created, last accessed, or * last modified. * * Results: * TRUE if succeed or FALSE if error. * * Side effects: * If fileName is a symlink, target's timestamps will be updated. * Symlink itself's timestamps will not be changed. * *---------------------------------------------------------------------- */ Bool File_SetTimes(ConstUnicode pathName, // IN: VmTimeType createTime, // IN: ignored VmTimeType accessTime, // IN: Windows NT time format VmTimeType writeTime, // IN: Windows NT time format VmTimeType attrChangeTime) // IN: ignored { struct timeval times[2]; struct timeval *aTime, *wTime; struct stat statBuf; char *path; int err; if (pathName == NULL) { return FALSE; } path = Unicode_GetAllocBytes(pathName, STRING_ENCODING_DEFAULT); if (path == NULL) { Log(LGPFX" %s: failed to convert \"%s\" to current encoding\n", __FUNCTION__, UTF8(pathName)); return FALSE; } err = (lstat(path, &statBuf) == -1) ? errno : 0; if (err != 0) { Log(LGPFX" %s: error stating file \"%s\": %s\n", __FUNCTION__, UTF8(pathName), Err_Errno2String(err)); free(path); return FALSE; } aTime = ×[0]; wTime = ×[1]; /* * Preserve old times if new time <= 0. * XXX Need a better implementation to preserve tv_usec. */ aTime->tv_sec = statBuf.st_atime; aTime->tv_usec = 0; wTime->tv_sec = statBuf.st_mtime; wTime->tv_usec = 0; if (accessTime > 0) { struct timespec ts; TimeUtil_NtTimeToUnixTime(&ts, accessTime); aTime->tv_sec = ts.tv_sec; aTime->tv_usec = ts.tv_nsec / 1000; } if (writeTime > 0) { struct timespec ts; TimeUtil_NtTimeToUnixTime(&ts, writeTime); wTime->tv_sec = ts.tv_sec; wTime->tv_usec = ts.tv_nsec / 1000; } err = (utimes(path, times) == -1) ? errno : 0; free(path); if (err != 0) { Log(LGPFX" %s: utimes error on file \"%s\": %s\n", __FUNCTION__, UTF8(pathName), Err_Errno2String(err)); return FALSE; } return TRUE; } /* *---------------------------------------------------------------------- * * File_SetFilePermissions -- * * Set file permissions. * * Results: * TRUE if succeed or FALSE if error. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool File_SetFilePermissions(ConstUnicode pathName, // IN: int perms) // IN: permissions { ASSERT(pathName); if (Posix_Chmod(pathName, perms) == -1) { /* The error is not critical, just log it. */ Log(LGPFX" %s: failed to change permissions on file \"%s\": %s\n", __FUNCTION__, UTF8(pathName), Err_Errno2String(errno)); return FALSE; } return TRUE; } #if !defined(__FreeBSD__) && !defined(sun) /* *----------------------------------------------------------------------------- * * FilePosixGetParent -- * * The input buffer is a canonical file path. Change it in place to the * canonical file path of its parent directory. * * Although this code is quite simple, we encapsulate it in a function * because it is easy to get it wrong. * * Results: * TRUE if the input buffer was (and remains) the root directory. * FALSE if the input buffer was not the root directory and was changed in * place to its parent directory. * * Example: "/foo/bar" -> "/foo" FALSE * "/foo" -> "/" FALSE * "/" -> "/" TRUE * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool FilePosixGetParent(Unicode *canPath) // IN/OUT: Canonical file path { Unicode pathName; Unicode baseName; ASSERT(File_IsFullPath(*canPath)); if (Unicode_Compare(*canPath, DIRSEPS) == 0) { return TRUE; } File_GetPathName(*canPath, &pathName, &baseName); Unicode_Free(baseName); Unicode_Free(*canPath); if (Unicode_IsEmpty(pathName)) { /* empty string which denotes "/" */ Unicode_Free(pathName); *canPath = Unicode_Duplicate("/"); } else { *canPath = pathName; } return FALSE; } /* *---------------------------------------------------------------------- * * FileGetStats -- * * Calls statfs on a full path (eg. something returned from File_FullPath). * If doNotAscend is FALSE, climb up the directory chain and call statfs * on each level until it succeeds. * * Results: * TRUE statfs succeeded * FALSE unable to statfs anything along the path * * Side effects: * None * *---------------------------------------------------------------------- */ static Bool FileGetStats(ConstUnicode pathName, // IN: Bool doNotAscend, // IN: struct statfs *pstatfsbuf) // OUT: { Bool retval = TRUE; Unicode dupPath = NULL; while (Posix_Statfs(dupPath ? dupPath : pathName, pstatfsbuf) == -1) { if (errno != ENOENT || doNotAscend) { retval = FALSE; break; } if (dupPath == NULL) { /* Dup fullPath, so as not to modify input parameters */ dupPath = Unicode_Duplicate(pathName); } FilePosixGetParent(&dupPath); } Unicode_Free(dupPath); return retval; } /* *---------------------------------------------------------------------- * * File_GetFreeSpace -- * * Return the free space (in bytes) available to the user on a disk where * a file is or would be. If doNotAscend is FALSE, the helper function * ascends the directory chain on system call errors in order to obtain * the file system information. * * Results: * -1 if error (reported to the user) * * Side effects: * None * *---------------------------------------------------------------------- */ uint64 File_GetFreeSpace(ConstUnicode pathName, // IN: File name Bool doNotAscend) // IN: Do not ascend dir chain { uint64 ret; Unicode fullPath; struct statfs statfsbuf; fullPath = File_FullPath(pathName); if (fullPath == NULL) { return -1; } if (FileGetStats(fullPath, doNotAscend, &statfsbuf)) { ret = (uint64) statfsbuf.f_bavail * statfsbuf.f_bsize; } else { Warning("%s: Couldn't statfs %s\n", __func__, fullPath); ret = -1; } Unicode_Free(fullPath); return ret; } #if defined(VMX86_SERVER) /* *---------------------------------------------------------------------- * * File_GetVMFSAttributes -- * * Acquire the attributes for a given file or directory on a VMFS volume. * * Results: * Integer return value and populated FS_PartitionListResult * * Side effects: * Will fail if file is not on VMFS or not enough memory for partition * query results * *---------------------------------------------------------------------- */ int File_GetVMFSAttributes(ConstUnicode pathName, // IN: File/dir to test FS_PartitionListResult **fsAttrs) // IN/OUT: VMFS Info { int fd; int ret; Unicode fullPath; Unicode directory = NULL; fullPath = File_FullPath(pathName); if (fullPath == NULL) { ret = -1; goto bail; } if (File_IsDirectory(fullPath)) { directory = Unicode_Duplicate(fullPath); } else { File_SplitName(fullPath, NULL, &directory, NULL); } if (!HostType_OSIsVMK()) { Log(LGPFX" %s: File %s not on VMFS volume\n", __func__, UTF8(pathName)); ret = -1; goto bail; } *fsAttrs = Util_SafeMalloc(FS_PARTITION_ARR_SIZE(FS_PLIST_DEF_MAX_PARTITIONS)); memset(*fsAttrs, 0, FS_PARTITION_ARR_SIZE(FS_PLIST_DEF_MAX_PARTITIONS)); (*fsAttrs)->ioctlAttr.maxPartitions = FS_PLIST_DEF_MAX_PARTITIONS; (*fsAttrs)->ioctlAttr.getAttrSpec = FS_ATTR_SPEC_BASIC; fd = Posix_Open(directory, O_RDONLY, 0); if (fd == -1) { Log(LGPFX" %s: could not open %s: %s\n", __func__, UTF8(pathName), Err_Errno2String(errno)); ret = -1; free(*fsAttrs); *fsAttrs = NULL; goto bail; } ret = ioctl(fd, IOCTLCMD_VMFS_FS_GET_ATTR, (char *) *fsAttrs); close(fd); if (ret == -1) { Log(LGPFX" %s: Could not get volume attributes (ret = %d): %s\n", __func__, ret, Err_Errno2String(errno)); free(*fsAttrs); *fsAttrs = NULL; } bail: Unicode_Free(fullPath); Unicode_Free(directory); return ret; } /* *---------------------------------------------------------------------- * * File_GetVMFSVersion -- * * Get the version number of the VMFS file system on which the * given file resides. * * Results: * Integer return value and version number. * * Side effects: * Will fail if file is not on VMFS or not enough memory for partition * query results. * *---------------------------------------------------------------------- */ int File_GetVMFSVersion(ConstUnicode pathName, // IN: File name to test uint32 *versionNum) // OUT: Version number { int ret = -1; FS_PartitionListResult *fsAttrs = NULL; if (!versionNum) { errno = EINVAL; goto exit; } ret = File_GetVMFSAttributes(pathName, &fsAttrs); if (ret < 0) { Log(LGPFX" %s: File_GetVMFSAttributes failed\n", __func__); } else { *versionNum = fsAttrs->versionNumber; } if (fsAttrs) { free(fsAttrs); } exit: return ret; } /* *---------------------------------------------------------------------- * * File_GetVMFSBlockSize -- * * Acquire the blocksize for a given file on a VMFS file system. * * Results: * Integer return value and block size * * Side effects: * Will fail if file is not on VMFS or not enough memory for partition * query results * *---------------------------------------------------------------------- */ int File_GetVMFSBlockSize(ConstUnicode pathName, // IN: File name to test uint32 *blockSize) // IN/OUT: VMFS block size { int ret = -1; FS_PartitionListResult *fsAttrs = NULL; if (!blockSize) { errno = EINVAL; goto exit; } ret = File_GetVMFSAttributes(pathName, &fsAttrs); if (ret < 0) { Log(LGPFX" %s: File_GetVMFSAttributes failed\n", __func__); } else { *blockSize = fsAttrs->fileBlockSize; } if (fsAttrs) { free(fsAttrs); } exit: return ret; } /* *---------------------------------------------------------------------- * * File_GetVMFSMountInfo -- * * Acquire the FS mount point info such as fsType, major version, * local mount point (/vmfs/volumes/xyz), and for NFS, * remote IP and remote mount point for a given file. * * Results: * Integer return value and allocated data * * Side effects: * Only implemented on ESX. Will fail on other platforms. * remoteIP and remoteMountPoint are only populated for files on NFS. * *---------------------------------------------------------------------- */ int File_GetVMFSMountInfo(ConstUnicode pathName, // IN: char **fsType, // OUT: uint32 *version, // OUT: char **remoteIP, // OUT: char **remoteMountPoint, // OUT: char **localMountPoint) // OUT: { int ret; FS_PartitionListResult *fsAttrs = NULL; *localMountPoint = File_GetUniqueFileSystemID(pathName); if (*localMountPoint == NULL) { return -1; } // Get file IP and mount point ret = File_GetVMFSAttributes(pathName, &fsAttrs); if (ret >= 0 && fsAttrs) { *version = fsAttrs->versionNumber; *fsType = Util_SafeStrdup(fsAttrs->fsType); if (memcmp(fsAttrs->fsType, FS_NFS_ON_ESX, sizeof(FS_NFS_ON_ESX)) == 0) { /* * logicalDevice from NFS3 client contains remote IP and remote * mount point, separated by space. Split them out. If there is * no space then this is probably NFS41 client, and we cannot * obtain its remote mount point details at this time. */ char *sep = strchr(fsAttrs->logicalDevice, ' '); if (sep) { *sep++ = 0; *remoteIP = Util_SafeStrdup(fsAttrs->logicalDevice); *remoteMountPoint = Util_SafeStrdup(sep); } else { *remoteIP = NULL; *remoteMountPoint = NULL; } } else { *remoteIP = NULL; *remoteMountPoint = NULL; } free(fsAttrs); } return ret; } #endif /* *---------------------------------------------------------------------- * * FileIsVMFS -- * * Is the given file on a filesystem that supports vmfs-specific * features like zeroed-thick and multiwriter files? * * Results: * TRUE if we're on VMFS. * * Side effects: * None * *---------------------------------------------------------------------- */ static Bool FileIsVMFS(ConstUnicode pathName) // IN: { Bool result = FALSE; #if defined(VMX86_SERVER) /* Right now only VMFS supports zeroedThick and multiWriter. */ FS_PartitionListResult *fsAttrs = NULL; if (File_GetVMFSAttributes(pathName, &fsAttrs) >= 0) { /* We want to match anything that starts with VMFS */ result = strncmp(fsAttrs->fsType, FS_VMFS_ON_ESX, strlen(FS_VMFS_ON_ESX)) == 0; } else { Log(LGPFX" %s: File_GetVMFSAttributes failed\n", __func__); } if (fsAttrs) { free(fsAttrs); } #endif return result; } /* *---------------------------------------------------------------------- * * File_SupportsZeroedThick -- * * Check if the given file is on an FS supports creation of * the zeroed-thick files. * Currently only VMFS on ESX does support zeroed-thick files, but * this may change in the future. * * Results: * TRUE if FS supports creation of the zeroed-thick files. * * Side effects: * None * *---------------------------------------------------------------------- */ Bool File_SupportsZeroedThick(ConstUnicode pathName) // IN: { return FileIsVMFS(pathName); } /* *---------------------------------------------------------------------- * * File_SupportsMultiWriter -- * * Check if the given file is on an FS supports opening files * in multi-writer mode. * Currently only VMFS on ESX supports multi-writer mode, but * this may change in the future. * * Results: * TRUE if FS supports opening files in multi-writer mode. * * Side effects: * None * *---------------------------------------------------------------------- */ Bool File_SupportsMultiWriter(ConstUnicode pathName) // IN: { return FileIsVMFS(pathName); } /* *---------------------------------------------------------------------- * * File_GetCapacity -- * * Return the total capacity (in bytes) available to the user on a disk * where a file is or would be * * Results: * -1 if error (reported to the user) * * Side effects: * None * *---------------------------------------------------------------------- */ uint64 File_GetCapacity(ConstUnicode pathName) // IN: Path name { uint64 ret; Unicode fullPath; struct statfs statfsbuf; fullPath = File_FullPath(pathName); if (fullPath == NULL) { return -1; } if (FileGetStats(fullPath, FALSE, &statfsbuf)) { ret = (uint64) statfsbuf.f_blocks * statfsbuf.f_bsize; } else { Warning(LGPFX" %s: Couldn't statfs\n", __func__); ret = -1; } Unicode_Free(fullPath); return ret; } /* *----------------------------------------------------------------------------- * * File_GetUniqueFileSystemID -- * * Returns a string which uniquely identifies the underlying filesystem * for a given path. * * 'path' can be relative (including empty) or absolute, and any number * of non-existing components at the end of 'path' are simply ignored. * * XXX: On Posix systems, we choose the underlying device's name as the * unique ID. I make no claim that this is 100% unique so if you * need this functionality to be 100% perfect, I suggest you think * about it more deeply than I did. -meccleston * * Results: * On success: Allocated and NUL-terminated filesystem ID. * On failure: NULL. * * Side effects: * None * *----------------------------------------------------------------------------- */ char * File_GetUniqueFileSystemID(char const *path) // IN: File path { #ifdef VMX86_SERVER char vmfsVolumeName[FILE_MAXPATH]; char *existPath; char *canPath; existPath = FilePosixNearestExistingAncestor(path); canPath = Posix_RealPath(existPath); free(existPath); if (canPath == NULL) { return NULL; } /* * VCFS doesn't have real mount points, so the mount point lookup below * returns "/vmfs", instead of the VCFS mount point. * * See bug 61646 for why we care. */ if (strncmp(canPath, VCFS_MOUNT_POINT, strlen(VCFS_MOUNT_POINT)) != 0 || sscanf(canPath, VCFS_MOUNT_PATH "%[^/]%*s", vmfsVolumeName) != 1) { free(canPath); goto exit; } /* * If the path points to a file or directory that is on a vsan datastore, * we have to determine which namespace object is involved. */ if (strncmp(vmfsVolumeName, FS_VSAN_URI_PREFIX, strlen(FS_VSAN_URI_PREFIX)) == 0) { FS_PartitionListResult *fsAttrs = NULL; int res; res = File_GetVMFSAttributes(canPath, &fsAttrs); if (res >= 0 && fsAttrs != NULL && strncmp(fsAttrs->fsType, FS_VMFS_ON_ESX, strlen(FS_VMFS_ON_ESX)) == 0) { char *unique; unique = Str_SafeAsprintf(NULL, "%s/%s/%s", VCFS_MOUNT_POINT, vmfsVolumeName, fsAttrs->name); free(fsAttrs); free(canPath); return unique; } free(fsAttrs); } free(canPath); return Str_SafeAsprintf(NULL, "%s/%s", VCFS_MOUNT_POINT, vmfsVolumeName); exit: #endif return FilePosixGetBlockDevice(path); } #if !defined(__APPLE__) /* *----------------------------------------------------------------------------- * * FilePosixLookupMountPoint -- * * Looks up passed in canonical file path in list of mount points. * If there is a match, it returns the underlying device name of the * mount point along with a flag indicating whether the mount point is * mounted with the "--[r]bind" option. * * Results: * On success: The allocated, NUL-terminated mounted "device". * On failure: NULL. * * Side effects: * None * *----------------------------------------------------------------------------- */ static char * FilePosixLookupMountPoint(char const *canPath, // IN: Canonical file path Bool *bind) // OUT: Mounted with --[r]bind? { #if defined NO_SETMNTENT || defined NO_ENDMNTENT NOT_IMPLEMENTED(); errno = ENOSYS; return NULL; #else FILE *f; struct mntent mnt; char *buf; size_t size; size_t used; char *ret = NULL; ASSERT(canPath); ASSERT(bind); size = 4 * FILE_MAXPATH; // Should suffice for most locales retry: f = setmntent(MOUNTED, "r"); if (f == NULL) { return NULL; } buf = Util_SafeMalloc(size); while (Posix_Getmntent_r(f, &mnt, buf, size) != NULL) { /* * Our Posix_Getmntent_r graciously sets errno when the buffer * is too small, but on UTF-8 based platforms Posix_Getmntent_r * is #defined to the system's getmntent_r, which can simply * truncate the strings with no other indication. See how much * space it used and increase the buffer size if needed. Note * that if some of the strings are empty, they may share a * common nul in the buffer, and the resulting size calculation * will be a little over-zealous. */ used = 0; if (mnt.mnt_fsname) { used += strlen(mnt.mnt_fsname) + 1; } if (mnt.mnt_dir) { used += strlen(mnt.mnt_dir) + 1; } if (mnt.mnt_type) { used += strlen(mnt.mnt_type) + 1; } if (mnt.mnt_opts) { used += strlen(mnt.mnt_opts) + 1; } if (used >= size || !mnt.mnt_fsname || !mnt.mnt_dir || !mnt.mnt_type || !mnt.mnt_opts) { size += 4 * FILE_MAXPATH; ASSERT(size <= 32 * FILE_MAXPATH); free(buf); endmntent(f); goto retry; } /* * NB: A call to realpath is not needed as getmntent() already * returns it in canonical form. Additionally, it is bad * to call realpath() as often a mount point is down, and * realpath calls stat which can block trying to stat * a filesystem that the caller of the function is not at * all expecting. */ if (strcmp(mnt.mnt_dir, canPath) == 0) { /* * The --bind and --rbind options behave differently. See * FilePosixGetBlockDevice() for details. * * Sadly (I blame a bug in 'mount'), there is no way to tell them * apart in /etc/mtab: the option recorded there is, in both cases, * always "bind". */ *bind = strstr(mnt.mnt_opts, "bind") != NULL; ret = Util_SafeStrdup(mnt.mnt_fsname); break; } } // 'canPath' is not a mount point. endmntent(f); free(buf); return ret; #endif } #endif /* *----------------------------------------------------------------------------- * * FilePosixGetBlockDevice -- * * Retrieve the block device that backs file path 'path'. * * 'path' can be relative (including empty) or absolute, and any number of * non-existing components at the end of 'path' are simply ignored. * * Results: * On success: The allocated, NUL-terminated block device absolute path. * On failure: NULL. * * Side effects: * None * *----------------------------------------------------------------------------- */ char * FilePosixGetBlockDevice(char const *path) // IN: File path { char *existPath; Bool failed; #if defined(__APPLE__) struct statfs buf; #else char canPath[FILE_MAXPATH]; char canPath2[FILE_MAXPATH]; unsigned int retries = 0; char *realPath; #endif existPath = FilePosixNearestExistingAncestor(path); #if defined(__APPLE__) failed = statfs(existPath, &buf) == -1; free(existPath); if (failed) { return NULL; } return Util_SafeStrdup(buf.f_mntfromname); #else realPath = Posix_RealPath(existPath); free(existPath); if (realPath == NULL) { return NULL; } Str_Strcpy(canPath, realPath, sizeof canPath); free(realPath); retry: Str_Strcpy(canPath2, canPath, sizeof canPath2); /* Find the nearest ancestor of 'canPath' that is a mount point. */ for (;;) { char *x; Bool bind; char *ptr; ptr = FilePosixLookupMountPoint(canPath, &bind); if (ptr) { if (bind) { /* * 'canPath' is a mount point mounted with --[r]bind. This is the * mount equivalent of a hard link. Follow the rabbit... * * --bind and --rbind behave differently. Consider this mount * table: * * /dev/sda1 / ext3 * exit14:/vol/vol0/home /exit14/home nfs * / /bind (mounted with --bind) * / /rbind (mounted with --rbind) * * then what we _should_ return for these paths is: * * /bind/exit14/home -> /dev/sda1 * /rbind/exit14/home -> exit14:/vol/vol0/home * * XXX but currently because we cannot easily tell the difference, * we always assume --rbind and we return: * * /bind/exit14/home -> exit14:/vol/vol0/home * /rbind/exit14/home -> exit14:/vol/vol0/home */ Bool rbind = TRUE; if (rbind) { /* * Compute 'canPath = ptr + (canPath2 - canPath)' using and * preserving the structural properties of all canonical * paths involved in the expression. */ size_t canPathLen = strlen(canPath); char const *diff = canPath2 + (canPathLen > 1 ? canPathLen : 0); if (*diff != '\0') { Str_Sprintf(canPath, sizeof canPath, "%s%s", strlen(ptr) > 1 ? ptr : "", diff); } else { Str_Strcpy(canPath, ptr, sizeof canPath); } } else { Str_Strcpy(canPath, ptr, sizeof canPath); } free(ptr); /* * There could be a series of these chained together. It is * possible for the mounts to get into a loop, so limit the total * number of retries to something reasonable like 10. */ retries++; if (retries > 10) { Warning(LGPFX" %s: The --[r]bind mount count exceeds %u. Giving " "up.\n", __func__, 10); return NULL; } goto retry; } return ptr; } /* XXX temporary work-around until this function is Unicoded. */ x = Util_SafeStrdup(canPath); failed = FilePosixGetParent(&x); Str_Strcpy(canPath, x, sizeof canPath); free(x); /* * Prevent an infinite loop in case FilePosixLookupMountPoint() even * fails on "/". */ if (failed) { return NULL; } } #endif } /* *----------------------------------------------------------------------------- * * FilePosixNearestExistingAncestor -- * * Find the nearest existing ancestor of 'path'. * * 'path' can be relative (including empty) or absolute, and 'path' can * have any number of non-existing components at its end. * * Results: * The allocated, NUL-terminated, non-empty path of the * nearest existing ancestor. * * Side effects: * None * *----------------------------------------------------------------------------- */ static char * FilePosixNearestExistingAncestor(char const *path) // IN: File path { size_t resultSize; char *result; struct stat statbuf; resultSize = MAX(strlen(path), 1) + 1; result = Util_SafeMalloc(resultSize); Str_Strcpy(result, path, resultSize); for (;;) { char *ptr; if (*result == '\0') { Str_Strcpy(result, *path == DIRSEPC ? "/" : ".", resultSize); break; } if (Posix_Stat(result, &statbuf) == 0) { break; } ptr = strrchr(result, DIRSEPC); if (!ptr) { ptr = result; } *ptr = '\0'; } return result; } #endif /* !FreeBSD && !sun */ /* *---------------------------------------------------------------------------- * * File_IsSameFile -- * * Determine whether both paths point to the same file. * * Caveats - While local files are matched based on inode and device * ID, some older versions of NFS return buggy device IDs, so the * determination cannot be done with 100% confidence across NFS. * Paths that traverse NFS mounts are matched based on device, inode * and all of the fields of the stat structure except for times. * This introduces a race condition in that if the target files are not * locked, they can change out from underneath this function yielding * false negative results. Cloned files sytems mounted across an old * version of NFS may yield a false positive. * * Results: * TRUE if both paths point to the same file, FALSE otherwise. * * Side effects: * Changes errno, maybe. * *---------------------------------------------------------------------------- */ Bool File_IsSameFile(ConstUnicode path1, // IN: ConstUnicode path2) // IN: { struct stat st1; struct stat st2; #if !defined(sun) // Solaris does not have statfs struct statfs stfs1; struct statfs stfs2; #endif ASSERT(path1); ASSERT(path2); /* * First take care of the easy checks. If the paths are identical, or if * the inode numbers or resident devices don't match, we're done. */ if (Unicode_Compare(path1, path2) == 0) { return TRUE; } if (Posix_Stat(path1, &st1) == -1) { return FALSE; } if (Posix_Stat(path2, &st2) == -1) { return FALSE; } if (st1.st_ino != st2.st_ino) { return FALSE; } if (st1.st_dev != st2.st_dev) { return FALSE; } if (HostType_OSIsPureVMK()) { /* * On ESX, post change 1074635 the st_dev field of the stat structure * is valid and differentiates between resident devices or NFS file * systems - no need to use statfs to obtain file system information. */ return TRUE; } #if !defined(sun) // Solaris does not have statfs if (Posix_Statfs(path1, &stfs1) != 0) { return FALSE; } if (Posix_Statfs(path2, &stfs2) != 0) { return FALSE; } #if defined(__APPLE__) || defined(__FreeBSD__) if ((stfs1.f_flags & MNT_LOCAL) && (stfs2.f_flags & MNT_LOCAL)) { return TRUE; } #else if ((stfs1.f_type != NFS_SUPER_MAGIC) && (stfs2.f_type != NFS_SUPER_MAGIC)) { return TRUE; } #endif #endif /* * At least one of the paths traverses NFS and some older NFS * implementations can set st_dev incorrectly. Do some extra checks of the * stat structure to increase our confidence. Since the st_ino numbers had * to match to get this far, the overwhelming odds are the two files are * the same. * * If another process was actively writing or otherwise modifying the file * while we stat'd it, then the following test could fail and we could * return a false negative. On the other hand, if NFS lies about st_dev * and the paths point to a cloned file system, then the we will return a * false positive. */ if ((st1.st_mode == st2.st_mode) && (st1.st_nlink == st2.st_nlink) && (st1.st_uid == st2.st_uid) && (st1.st_gid == st2.st_gid) && (st1.st_rdev == st2.st_rdev) && (st1.st_size == st2.st_size) && (st1.st_blksize == st2.st_blksize) && (st1.st_blocks == st2.st_blocks)) { return TRUE; } return FALSE; } /* *----------------------------------------------------------------------------- * * File_Replace -- * * Replace old file with new file, and attempt to reproduce * file permissions. A NULL value for either the oldName or * newName will result in failure and errno will be set to EFAULT. * * Results: * TRUE on success. * * Side effects: * errno may be set. * *----------------------------------------------------------------------------- */ Bool File_Replace(ConstUnicode oldName, // IN: old file ConstUnicode newName) // IN: new file { int status = 0; Bool result = FALSE; char *newPath = NULL; char *oldPath = NULL; struct stat st; if (newName == NULL) { status = EFAULT; goto bail; } else if ((newPath = Unicode_GetAllocBytes(newName, STRING_ENCODING_DEFAULT)) == NULL) { status = UNICODE_CONVERSION_ERRNO; Msg_Append(MSGID(filePosix.replaceConversionFailed) "Failed to convert file path \"%s\" to current encoding\n", newName); goto bail; } if (oldName == NULL) { status = EFAULT; goto bail; } else if ((oldPath = Unicode_GetAllocBytes(oldName, STRING_ENCODING_DEFAULT)) == NULL) { status = UNICODE_CONVERSION_ERRNO; Msg_Append(MSGID(filePosix.replaceConversionFailed) "Failed to convert file path \"%s\" to current encoding\n", oldName); goto bail; } if ((stat(oldPath, &st) == 0) && (chmod(newPath, st.st_mode) == -1)) { status = errno; Msg_Append(MSGID(filePosix.replaceChmodFailed) "Failed to duplicate file permissions from " "\"%s\" to \"%s\": %s\n", oldName, newName, Msg_ErrString()); goto bail; } if (rename(newPath, oldPath) < 0) { status = errno; Msg_Append(MSGID(filePosix.replaceRenameFailed) "Failed to rename \"%s\" to \"%s\": %s\n", newName, oldName, Msg_ErrString()); goto bail; } result = TRUE; bail: free(newPath); free(oldPath); errno = status; return result; } #ifdef VMX86_SERVER /* *----------------------------------------------------------------------------- * * File_Is2TiBEnabled -- * * Look up for the config option "disk.enable2TiB" in config file * (/etc/vmware/config). If config option is not present then return * TRUE. * * Results: * TRUE if 2tbplus vdisk support is enabled (default value). * FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool File_Is2TiBEnabled(void) { static Bool enable2TiB = FALSE; static Bool enable2TiBInited = FALSE; if (!enable2TiBInited) { enable2TiB = LocalConfig_GetBool(TRUE, "disk.enable2TiB"); enable2TiBInited = TRUE; } return enable2TiB; } #endif /* *---------------------------------------------------------------------- * * FilePosixGetMaxOrSupportsFileSize -- * * Given a file descriptor to a file on a volume, either find out the * max file size for the volume on which the file is located or check * if the volume supports the given file size. * If getMaxFileSize is set then find out the max file size and store it * in *maxFileSize on success, otherwise figure out if *fileSize is * supported. * * Results: * If getMaxFileSize was set: * TRUE with max file size stored in *fileSize. * Otherwise: * TRUE fileSize is supported. * FALSE fileSize not supported or could not figure out the answer. * * Side effects: * None. * *---------------------------------------------------------------------- */ static Bool FilePosixGetMaxOrSupportsFileSize(FileIODescriptor *fd, // IN: uint64 *fileSize, // IN/OUT: Bool getMaxFileSize) // IN: { uint64 value = 0; uint64 mask; ASSERT(fd); ASSERT(fileSize); if (!getMaxFileSize) { return FileIO_SupportsFileSize(fd, *fileSize); } /* * Try to do a binary search and figure out the max supported file size. */ for (mask = (1ULL << 62); mask != 0; mask >>= 1) { if (FileIO_SupportsFileSize(fd, value | mask)) { value |= mask; } } *fileSize = value; return TRUE; } /* *---------------------------------------------------------------------- * * FilePosixCreateTestGetMaxOrSupportsFileSize -- * * Given a path to a dir on a volume, either find out the max file size * for the volume on which the dir is located or check if the volume * supports the given file size. * If getMaxFileSize is set then find out the max file size and store it * in *maxFileSize on success, otherwise figure out if *fileSize is * supported. * * Results: * If getMaxFileSize was set: * TRUE if figured out the max file size. * FALSE failed to figure out the max file size. * Otherwise: * TRUE fileSize is supported. * FALSE fileSize not supported or could not figure out the answer. * * Side effects: * None. * *---------------------------------------------------------------------- */ static Bool FilePosixCreateTestGetMaxOrSupportsFileSize(ConstUnicode dirName,// IN: test dir uint64 *fileSize, // IN/OUT: Bool getMaxFileSize) // IN: { Bool retVal; int posixFD; Unicode temp; Unicode path; FileIODescriptor fd; ASSERT(fileSize); temp = Unicode_Append(dirName, "/.vmBigFileTest"); posixFD = File_MakeSafeTemp(temp, &path); Unicode_Free(temp); if (posixFD == -1) { Log(LGPFX" %s: Failed to create temporary file in dir: %s\n", __func__, UTF8(dirName)); return FALSE; } fd = FileIO_CreateFDPosix(posixFD, O_RDWR); retVal = FilePosixGetMaxOrSupportsFileSize(&fd, fileSize, getMaxFileSize); /* Eventually perform destructive tests here... */ FileIO_Close(&fd); File_Unlink(path); Unicode_Free(path); return retVal; } #ifdef VMX86_SERVER /* *---------------------------------------------------------------------- * * FileVMKGetMaxFileSize -- * * Given a path to a file on a volume, find out the max file size for * the volume on which the file is located. * Max file size gets stored in *maxFileSize on success. * * Results: * TRUE if figured out the max file size. * FALSE failed to figure out the max file size. * * Side effects: * None * *---------------------------------------------------------------------- */ static Bool FileVMKGetMaxFileSize(ConstUnicode pathName, // IN: uint64 *maxFileSize) // OUT: { int fd; Bool retval = TRUE; Unicode fullPath; Unicode dirPath = NULL; ASSERT(maxFileSize); fullPath = File_FullPath(pathName); if (fullPath == NULL) { Log(LGPFX" %s: Failed to get the full path for %s\n", __func__, UTF8(pathName)); retval = FALSE; goto bail; } if (File_IsDirectory(fullPath)) { dirPath = Unicode_Duplicate(fullPath); } else { dirPath = NULL; File_SplitName(fullPath, NULL, &dirPath, NULL); } /* * We always try to open the dir in order to avoid any contention on VMDK * descriptor file with those threads which already have descriptor file * opened for writing. */ fd = Posix_Open(dirPath, O_RDONLY, 0); if (fd == -1) { Log(LGPFX" %s: could not open %s: %s\n", __func__, UTF8(dirPath), Err_Errno2String(errno)); retval = FALSE; goto bail; } if(ioctl(fd, IOCTLCMD_VMFS_GET_MAX_FILE_SIZE, maxFileSize) == -1) { Log(LGPFX" %s: Could not get max file size for path: %s, error: %s\n", __func__, UTF8(pathName), Err_Errno2String(errno)); retval = FALSE; } close(fd); bail: Unicode_Free(fullPath); Unicode_Free(dirPath); return retval; } #endif /* *---------------------------------------------------------------------- * * FileVMKGetMaxOrSupportsFileSize -- * * Given a path to a file on a volume, either find out the max file size * for the volume on which the file is located or check if the volume * supports the given file size. * If getMaxFileSize is set then find out the max file size and store it * in *maxFileSize on success, otherwise figure out if *fileSize is * supported. * * Results: * If getMaxFileSize was set: * TRUE if figured out the max file size. * FALSE failed to figure out the max file size. * Otherwise: * TRUE fileSize is supported. * FALSE fileSize not supported or could not figure out the answer. * * Side effects: * None * *---------------------------------------------------------------------- */ static Bool FileVMKGetMaxOrSupportsFileSize(ConstUnicode pathName, // IN: uint64 *fileSize, // IN/OUT: Bool getMaxFileSize) // IN: { #if defined(VMX86_SERVER) FS_PartitionListResult *fsAttrs = NULL; uint64 maxFileSize; /* * Let's first try IOCTL to figure out max file size. */ if (FileVMKGetMaxFileSize(pathName, &maxFileSize)) { if (getMaxFileSize) { *fileSize = maxFileSize; return TRUE; } return (*fileSize <= maxFileSize); } /* * Try the old way if IOCTL failed. */ LOG(0, (LGPFX" %s: Failed to figure out max file size via " "IOCTLCMD_VMFS_GET_MAX_FILE_SIZE. Falling back to old method.\n", __func__)); maxFileSize = -1; if (File_GetVMFSAttributes(pathName, &fsAttrs) < 0) { Log(LGPFX" %s: File_GetVMFSAttributes Failed\n", __func__); return FALSE; } if (strcmp(fsAttrs->fsType, FS_VMFS_ON_ESX) == 0) { if (fsAttrs->versionNumber == 3) { maxFileSize = (VMFS3CONST * (uint64) fsAttrs->fileBlockSize * 1024); } else if (fsAttrs->versionNumber >= 5) { /* Get ready for 64 TB on VMFS5 and perform sanity check on version */ maxFileSize = (uint64) 0x400000000000ULL; } else { Log(LGPFX" %s: Unsupported filesystem version, %u\n", __func__, fsAttrs->versionNumber); free(fsAttrs); return FALSE; } free(fsAttrs); if (maxFileSize == -1) { Log(LGPFX" %s: Failed to figure out the max file size for %s\n", __func__, pathName); return FALSE; } if (getMaxFileSize) { *fileSize = maxFileSize; return TRUE; } else { return *fileSize <= maxFileSize; } } else { Unicode fullPath; Unicode parentPath; Bool supported; Log(LGPFX" %s: Trying create file and seek approach.\n", __func__); fullPath = File_FullPath(pathName); if (fullPath == NULL) { Log(LGPFX" %s: Error acquiring full path\n", __func__); free(fsAttrs); return FALSE; } File_GetPathName(fullPath, &parentPath, NULL); supported = FilePosixCreateTestGetMaxOrSupportsFileSize(parentPath, fileSize, getMaxFileSize); free(fsAttrs); Unicode_Free(fullPath); Unicode_Free(parentPath); return supported; } #endif Log(LGPFX" %s: did not execute properly\n", __func__); return FALSE; /* happy compiler */ } /* *---------------------------------------------------------------------- * * FileGetMaxOrSupportsFileSize -- * * Given a path to a file on a volume, either find out the max file size * for the volume on which the file is located or check if the volume * supports the given file size. * If getMaxFileSize is set then find out the max file size and store it * in *maxFileSize on success, otherwise figure out if *fileSize is * supported. * * Results: * If getMaxFileSize was set: * TRUE if figured out the max file size. * FALSE failed to figure out the max file size. * Otherwise: * TRUE fileSize is supported. * FALSE fileSize not supported or could not figure out the answer. * * Side effects: * None * *---------------------------------------------------------------------- */ Bool FileGetMaxOrSupportsFileSize(ConstUnicode pathName, // IN: uint64 *fileSize, // IN/OUT: Bool getMaxFileSize) // IN: { Unicode fullPath; Unicode folderPath; Bool retval = FALSE; ASSERT(fileSize); #ifdef VMX86_SERVER if (!File_Is2TiBEnabled()) { if (getMaxFileSize) { /* * Return 2tb-512b since hostd uses this value directly to report max * VMDK's sizes to the UI. */ *fileSize = CONST64U(0x20000000000) - CONST64U(512); return TRUE; } return *fileSize <= (CONST64U(0x20000000000) - CONST64U(512)); } #endif /* * We acquire the full path name for testing in * FilePosixCreateTestGetMaxOrSupportsFileSize(). This is also done in the * event that a user tries to create a virtual disk in the directory that * they want a vmdk created in (setting filePath only to the disk name, * not the entire path.). */ fullPath = File_FullPath(pathName); if (fullPath == NULL) { Log(LGPFX" %s: Error acquiring full path for path: %s.\n", __func__, pathName); goto out; } if (HostType_OSIsVMK()) { retval = FileVMKGetMaxOrSupportsFileSize(fullPath, fileSize, getMaxFileSize); goto out; } if (File_IsFile(fullPath)) { FileIOResult res; FileIODescriptor fd; FileIO_Invalidate(&fd); res = FileIO_Open(&fd, fullPath, FILEIO_OPEN_ACCESS_READ, FILEIO_OPEN); if (FileIO_IsSuccess(res)) { retval = FilePosixGetMaxOrSupportsFileSize(&fd, fileSize, getMaxFileSize); FileIO_Close(&fd); goto out; } } /* * On unknown filesystems create a temporary file in the argument file's * parent directory and use it as a test. */ if (File_IsDirectory(pathName)) { folderPath = Unicode_Duplicate(fullPath); } else { folderPath = NULL; File_SplitName(fullPath, NULL, &folderPath, NULL); } retval = FilePosixCreateTestGetMaxOrSupportsFileSize(folderPath, fileSize, getMaxFileSize); Unicode_Free(folderPath); out: Unicode_Free(fullPath); return retval; } /* *---------------------------------------------------------------------- * * File_GetMaxFileSize -- * * Given a path to a file on a volume, return the max file size for that * volume. The max file size is stored on *maxFileSize on success. * The function caps the max file size to be MAX_SUPPORTED_FILE_SIZE on * any type of FS. * * Results: * TRUE on success. * FALSE failed to figure out max file size due to some reasons. * * Side effects: * None * *---------------------------------------------------------------------- */ Bool File_GetMaxFileSize(ConstUnicode pathName, // IN: uint64 *maxFileSize) // OUT: { Bool result; if (!maxFileSize) { Log(LGPFX" %s: maxFileSize passed as NULL.\n", __func__); return FALSE; } result = FileGetMaxOrSupportsFileSize(pathName, maxFileSize, TRUE); if (result) { /* * Cap the max supported file size at MAX_SUPPORTED_FILE_SIZE. */ if (*maxFileSize > MAX_SUPPORTED_FILE_SIZE) { *maxFileSize = MAX_SUPPORTED_FILE_SIZE; } } return result; } /* *---------------------------------------------------------------------- * * File_SupportsFileSize -- * * Check if the given file is on an FS that supports such file size. * The function caps the max supported file size to be * MAX_SUPPORTED_FILE_SIZE on any type of FS. * * Results: * TRUE if FS supports such file size. * FALSE otherwise (file size not supported, invalid path, read-only, ...) * * Side effects: * None * *---------------------------------------------------------------------- */ Bool File_SupportsFileSize(ConstUnicode pathName, // IN: uint64 fileSize) // IN: { /* * All supported filesystems can hold at least 2GB-1 bytes files. */ if (fileSize <= 0x7FFFFFFF) { return TRUE; } /* * Cap the max supported file size at MAX_SUPPORTED_FILE_SIZE. */ if (fileSize > MAX_SUPPORTED_FILE_SIZE) { return FALSE; } return FileGetMaxOrSupportsFileSize(pathName, &fileSize, FALSE); } /* *----------------------------------------------------------------------------- * * FileCreateDirectory -- * * Create a directory. The umask is honored. * * Results: * 0 success * > 0 failure (errno) * * Side effects: * May change the host file system. * *----------------------------------------------------------------------------- */ int FileCreateDirectory(ConstUnicode pathName, // IN: int mask) // IN: { int err; if (pathName == NULL) { err = errno = EFAULT; } else { err = (Posix_Mkdir(pathName, mask) == -1) ? errno : 0; } return err; } /* *---------------------------------------------------------------------- * * File_ListDirectory -- * * Gets the list of files (and directories) in a directory. * * Results: * Returns the number of files returned or -1 on failure. * * Side effects: * If ids is provided and the function succeeds, memory is * allocated for both the unicode strings and the array itself * and must be freed. (See Unicode_FreeList.) * The memory allocated for the array may be larger than necessary. * The caller may trim it with realloc() if it cares. * * A file name that cannot be represented in the default encoding * will appear as a string of three UTF8 sustitution characters. * *---------------------------------------------------------------------- */ int File_ListDirectory(ConstUnicode pathName, // IN: Unicode **ids) // OUT: relative paths { int err; DIR *dir; DynBuf b; int count; ASSERT(pathName != NULL); dir = Posix_OpenDir(pathName); if (dir == (DIR *) NULL) { // errno is preserved return -1; } DynBuf_Init(&b); count = 0; while (TRUE) { struct dirent *entry; errno = 0; entry = readdir(dir); if (entry == (struct dirent *) NULL) { err = errno; break; } /* Strip out undesirable paths. No one ever cares about these. */ if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) { continue; } /* Don't create the file list if we aren't providing it to the caller. */ if (ids) { Unicode id; if (Unicode_IsBufferValid(entry->d_name, -1, STRING_ENCODING_DEFAULT)) { id = Unicode_Alloc(entry->d_name, STRING_ENCODING_DEFAULT); } else { id = Unicode_EscapeBuffer(entry->d_name, -1, STRING_ENCODING_DEFAULT); Warning("%s: file '%s' in directory '%s' cannot be converted to " "UTF8\n", __FUNCTION__, pathName, id); Unicode_Free(id); id = Unicode_Duplicate(UNICODE_SUBSTITUTION_CHAR UNICODE_SUBSTITUTION_CHAR UNICODE_SUBSTITUTION_CHAR); } DynBuf_Append(&b, &id, sizeof id); } count++; } closedir(dir); if (ids && (err == 0)) { *ids = DynBuf_Detach(&b); } DynBuf_Destroy(&b); return (errno = err) == 0 ? count : -1; } #if CAN_USE_FTS /* *----------------------------------------------------------------------------- * * File_WalkDirectoryStart -- * * Start a directory tree walk at 'parentPath'. * * To read each entry, repeatedly pass the returned context to * File_WalkDirectoryNext() until that function returns FALSE. * * When done, pass the returned context to File_WalkDirectoryEnd(). * * A pre-order, logical traversal will be completed; hard links and * symbolic links that do not cause a cycle are followed in the directory * traversal. * * We assume no thread will change the working directory between the calls * to File_WalkDirectoryStart and File_WalkDirectoryEnd. * * Results: * A context used in subsequent calls to File_WalkDirectoryNext() or NULL * if an error is encountered. * * Side effects: * None * *----------------------------------------------------------------------------- */ WalkDirContext File_WalkDirectoryStart(ConstUnicode parentPath) // IN: { WalkDirContextImpl *context; char * const traversalRoots[] = { Unicode_GetAllocBytes(parentPath, STRING_ENCODING_DEFAULT), NULL }; context = malloc(sizeof *context); if (!context) { return NULL; } context->fts = fts_open(traversalRoots, FTS_LOGICAL|FTS_NOSTAT|FTS_NOCHDIR, NULL); if (!context->fts) { free(context); context = NULL; } free(traversalRoots[0]); return context; } /* *----------------------------------------------------------------------------- * * File_WalkDirectoryNext -- * * Get the next entry in a directory traversal started with * File_WalkDirectoryStart. * * Results: * TRUE iff the traversal hasn't completed. * * If TRUE, *path holds an allocated string prefixed by parentPath that * the caller must free (see Unicode_Free). * * If FALSE, errno is 0 iff the walk completed sucessfully. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool File_WalkDirectoryNext(WalkDirContext context, // IN: Unicode *path) // OUT: { FTSENT *nextEntry; ASSERT(context); ASSERT(context->fts); ASSERT(path); do { nextEntry = fts_read(context->fts); /* * We'll skip any entries that cannot be read, are errors, or * are the second traversal (post-order) of a directory. */ if (nextEntry && nextEntry->fts_info != FTS_DNR && nextEntry->fts_info != FTS_ERR && nextEntry->fts_info != FTS_DP) { *path = Unicode_AllocWithLength(nextEntry->fts_path, nextEntry->fts_pathlen, STRING_ENCODING_DEFAULT); return TRUE; } } while (nextEntry); return FALSE; } /* *----------------------------------------------------------------------------- * * File_WalkDirectoryEnd -- * * End the directory traversal. * * Results: * None * * Side effects: * The context is now invalid. * *----------------------------------------------------------------------------- */ void File_WalkDirectoryEnd(WalkDirContext context) // IN: { ASSERT(context); ASSERT(context->fts); if (fts_close(context->fts) == -1) { Log(LGPFX" %s: failed to close fts: %p\n", __FUNCTION__, context->fts); } free((WalkDirContextImpl *)context); } #else /* *----------------------------------------------------------------------------- * * File_WalkDirectoryStart -- * File_WalkDirectoryNext -- * File_WalkDirectoryEnd -- * * XXX FTS is not supported on this posix variant. See above. * * Results: * None * * Side effects: * ASSERTs. * *----------------------------------------------------------------------------- */ WalkDirContext File_WalkDirectoryStart(ConstUnicode parentPath) // IN: { NOT_IMPLEMENTED(); } Bool File_WalkDirectoryNext(WalkDirContext context, // IN: Unicode *path) // OUT: { NOT_IMPLEMENTED(); } void File_WalkDirectoryEnd(WalkDirContext context) // IN: { NOT_IMPLEMENTED(); } #endif // CAN_USE_FTS /* *---------------------------------------------------------------------- * * FileIsGroupsMember -- * * Determine if a gid is in the gid list of the current process * * Results: * FALSE if error (reported to the user) * * Side effects: * None * *---------------------------------------------------------------------- */ static Bool FileIsGroupsMember(gid_t gid) // IN: { int nr_members; gid_t *members; int res; int ret; members = NULL; nr_members = 0; for (;;) { gid_t *new; res = getgroups(nr_members, members); if (res == -1) { Warning(LGPFX" %s: Couldn't getgroups\n", __FUNCTION__); ret = FALSE; goto end; } if (res == nr_members) { break; } /* Was bug 17760 --hpreg */ new = realloc(members, res * sizeof *members); if (new == NULL) { Warning(LGPFX" %s: Couldn't realloc\n", __FUNCTION__); ret = FALSE; goto end; } members = new; nr_members = res; } for (res = 0; res < nr_members; res++) { if (members[res] == gid) { ret = TRUE; goto end; } } ret = FALSE; end: free(members); return ret; } /* *---------------------------------------------------------------------- * * FileIsWritableDir -- * * Determine in a non-intrusive way if the user can create a file in a * directory * * Results: * FALSE if error (reported to the user) * * Side effects: * None * * Bug: * It would be cleaner to use the POSIX access(2), which deals well * with read-only filesystems. Unfortunately, access(2) doesn't deal with * the effective [u|g]ids. * *---------------------------------------------------------------------- */ Bool FileIsWritableDir(ConstUnicode dirName) // IN: { int err; uid_t euid; FileData fileData; err = FileAttributes(dirName, &fileData); if ((err != 0) || (fileData.fileType != FILE_TYPE_DIRECTORY)) { return FALSE; } euid = geteuid(); if (euid == 0) { /* Root can read or write any file. Well... This is not completely true because of read-only filesystems and NFS root squashing... What a nightmare --hpreg */ return TRUE; } if (fileData.fileOwner == euid) { fileData.fileMode >>= 6; } else if (FileIsGroupsMember(fileData.fileGroup)) { fileData.fileMode >>= 3; } /* Check for Read and Execute permissions */ return (fileData.fileMode & 3) == 3; } /* *---------------------------------------------------------------------- * * File_MakeCfgFileExecutable -- * * Make a .vmx file executable. This is sometimes necessary * to enable MKS access to the VM. * * Owner always gets rwx. Group/other get x where r is set. * * Results: * FALSE if error * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ Bool File_MakeCfgFileExecutable(ConstUnicode pathName) // IN: { struct stat s; if (Posix_Stat(pathName, &s) == 0) { mode_t newMode = s.st_mode; newMode |= S_IRUSR | S_IWUSR | S_IXUSR; ASSERT_ON_COMPILE(S_IRGRP >> 2 == S_IXGRP && S_IROTH >> 2 == S_IXOTH); newMode |= ((newMode & (S_IRGRP | S_IROTH)) >> 2); return newMode == s.st_mode || Posix_Chmod(pathName, newMode); } return FALSE; } /* *---------------------------------------------------------------------------- * * File_GetSizeAlternate -- * * An alternate way to determine the filesize. Useful for finding * problems with files on remote fileservers, such as described in bug * 19036. However, in Linux we do not have an alternate way, yet, to * determine the problem, so we call back into the regular getSize * function. * * Results: * Size of file or -1. * * Side effects: * None * *---------------------------------------------------------------------------- */ int64 File_GetSizeAlternate(ConstUnicode pathName) // IN: { return File_GetSize(pathName); } /* *---------------------------------------------------------------------------- * * File_IsCharDevice -- * * This function checks whether the given file is a char device * and return TRUE in such case. This is often useful on Windows * where files like COM?, LPT? must be differentiated from "normal" * disk files. * * Results: * TRUE is a character device * FALSE is not a character device or error * * Side effects: * None * *---------------------------------------------------------------------------- */ Bool File_IsCharDevice(ConstUnicode pathName) // IN: { FileData fileData; return (FileAttributes(pathName, &fileData) == 0) && (fileData.fileType == FILE_TYPE_CHARDEVICE); } open-vm-tools-9.4.0-1280544/lib/file/fileLockPosix.c0000644765153500003110000007245112220061556020054 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * fileLockPosix.c -- * * Interface to host-specific locking function for Posix hosts. */ #include #include #include #include /* Needed before sys/vfs.h with glibc 2.0 --hpreg */ #if !defined(__FreeBSD__) #if defined(__APPLE__) #include #include #include #include #else #include #endif #endif #include #include #include #include #include #include #include "vmware.h" #include "posix.h" #include "file.h" #include "fileIO.h" #include "fileLock.h" #include "fileInt.h" #include "util.h" #include "str.h" #include "err.h" #include "vm_version.h" #include "localconfig.h" #include "hostinfo.h" #include "su.h" #include "hostType.h" #include "unicodeOperations.h" #define LOGLEVEL_MODULE main #include "loglevel_user.h" #define DEVICE_LOCK_DIR "/var/lock" #define LOG_MAX_PROC_NAME 64 /* * XXX * Most of these warnings must be turned back into Msg_Appends, or the * equivalent. They were changed from Msg_Appends to Warnings to facilitate * integration in the disklib library, but many of the warnings are very * important, and should be presented directly to the user, not go silently * into the log file. */ #if !defined(__FreeBSD__) && !defined(sun) /* *---------------------------------------------------------------------- * * IsLinkingAvailable -- * * Check if linking is supported in the filesystem where we create * the lock file. * * Results: * TRUE is we're sure it's supported. FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ static Bool IsLinkingAvailable(const char *fileName) // IN: { struct statfs buf; int status; ASSERT(fileName); /* * Don't use linking on ESX/VMFS... the overheads are expensive and this * path really isn't used. */ if (HostType_OSIsVMK()) { return FALSE; } status = statfs(fileName, &buf); if (status == -1) { Log(LGPFX" Bad statfs using %s (%s).\n", fileName, Err_Errno2String(errno)); return FALSE; } #if defined(__APPLE__) if ((Str_Strcasecmp(buf.f_fstypename, "hfs") == 0) || (Str_Strcasecmp(buf.f_fstypename, "nfs") == 0) || (Str_Strcasecmp(buf.f_fstypename, "ufs") == 0)) { return TRUE; } if ((Str_Strcasecmp(buf.f_fstypename, "smbfs") != 0) && (Str_Strcasecmp(buf.f_fstypename, "afpfs") != 0)) { Log(LGPFX" Unknown filesystem '%s'. Using non-linking file locking.\n", buf.f_fstypename); } #else /* consult "table" of known filesystem types */ switch (buf.f_type) { case AFFS_SUPER_MAGIC: case EXT_SUPER_MAGIC: case EXT2_OLD_SUPER_MAGIC: case EXT2_SUPER_MAGIC: // EXT3_SUPER_MAGIC is EXT2_SUPER_MAGIC case HFSPLUS_SUPER_MAGIC: case NFS_SUPER_MAGIC: case XENIX_SUPER_MAGIC: case SYSV4_SUPER_MAGIC: case SYSV2_SUPER_MAGIC: case COH_SUPER_MAGIC: case UFS_SUPER_MAGIC: case REISERFS_SUPER_MAGIC: case XFS_SUPER_MAGIC: case TMPFS_SUPER_MAGIC: case JFS_SUPER_MAGIC: return TRUE; // these are known to work case SMB_SUPER_MAGIC: case MSDOS_SUPER_MAGIC: return FALSE; } /* * Nothing is known about this filesystem. Play it safe and use * non-link based locking. */ Warning(LGPFX" Unknown filesystem 0x%x. Using non-linking locking.\n", (unsigned int) buf.f_type); #endif return FALSE; } /* *---------------------------------------------------------------------- * * RemoveStaleLockFile -- * * Remove a stale lock file. * * Results: * TRUE on success. * * Side effects: * Unlink file. * *---------------------------------------------------------------------- */ static Bool RemoveStaleLockFile(const char *lockFileName) // IN: { uid_t uid; int ret; int saveErrno; ASSERT(lockFileName); /* stale lock */ Log(LGPFX" Found a previous instance of lock file '%s'. " "It will be removed automatically.\n", lockFileName); uid = Id_BeginSuperUser(); ret = unlink(lockFileName); saveErrno = errno; Id_EndSuperUser(uid); if (ret < 0) { Warning(LGPFX" Failed to remove stale lock file %s (%s).\n", lockFileName, Err_Errno2String(saveErrno)); return FALSE; } return TRUE; } /* *---------------------------------------------------------------------- * * GetLockFileValues -- * * Get host name and PID of locking process. * * Results: * 1 on success, 0 if file doesn't exist, -1 for all other errors. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int GetLockFileValues(const char *lockFileName, // IN: int *pid, // OUT: char *hostID) // OUT: { char *p; int saveErrno; FILE *lockFile; char line[1000]; Bool deleteLockFile; uid_t uid; int status; ASSERT(lockFileName); ASSERT(pid); ASSERT(hostID); uid = Id_BeginSuperUser(); lockFile = Posix_Fopen(lockFileName, "r"); saveErrno = errno; Id_EndSuperUser(uid); if (lockFile == NULL) { Warning(LGPFX" Failed to open existing lock file %s (%s).\n", lockFileName, Err_Errno2String(saveErrno)); return (saveErrno == ENOENT) ? 0 : -1; } p = fgets(line, sizeof line, lockFile); saveErrno = errno; fclose(lockFile); if (p == NULL) { Warning(LGPFX" Failed to read line from lock file %s (%s).\n", lockFileName, Err_Errno2String(saveErrno)); deleteLockFile = TRUE; } else { switch (sscanf(line, "%d %999s", pid, hostID)) { case 2: // Everything is OK deleteLockFile = FALSE; break; case 1: default: Warning(LGPFX" Badly formatted lock file %s.\n", lockFileName); deleteLockFile = TRUE; } } status = 1; if (deleteLockFile) { status = 0; // we're going to delete the file if (!RemoveStaleLockFile(lockFileName)) { status = -1; } } return status; } /* *---------------------------------------------------------------------- * * FileLockIsValidProcess -- * * Determine if the process, via its pid, is valid (alive). * * Results: * TRUE Yes * FALSE No * * Side effects: * None. * *---------------------------------------------------------------------- */ static Bool FileLockIsValidProcess(int pid) // IN: { HostinfoProcessQuery value = Hostinfo_QueryProcessExistence(pid); if (value == HOSTINFO_PROCESS_QUERY_UNKNOWN) { return TRUE; // Err on the side of caution } return (value == HOSTINFO_PROCESS_QUERY_ALIVE) ? TRUE : FALSE; } /* *---------------------------------------------------------------------- * * FileLockCreateLockFile -- * * Create a new lock file, either via a O_EXCL creat() call or * through the linking method. * * Results: * 1 if we created our lock file successfully. * 0 if we should retry the creation. * -1 if the process failed. * * Side effects: * Change the host file system. * *---------------------------------------------------------------------- */ static int FileLockCreateLockFile(const char *lockFileName, // IN: const char *lockFileLink, // IN: const char *uniqueID) // IN: { int err; int lockFD; int status = 1; int saveErrno; Bool useLinking = IsLinkingAvailable(lockFileName); uid_t uid; if (useLinking) { uid = Id_BeginSuperUser(); lockFD = creat(lockFileLink, 0444); saveErrno = errno; Id_EndSuperUser(uid); if (lockFD == -1) { Log(LGPFX" Failed to create new lock file %s (%s).\n", lockFileLink, Err_Errno2String(saveErrno)); return (saveErrno == EEXIST) ? 0 : -1; } } else { /* * XXX * Note that this option is racy, at least for SMB and FAT32 file * systems. It appears, however, that by using a temporary lock * file before getting the real, persistent lock file, the race * can be eliminated. -- johnh */ uid = Id_BeginSuperUser(); lockFD = Posix_Open(lockFileName, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); saveErrno = errno; Id_EndSuperUser(uid); if (lockFD == -1) { Log(LGPFX" Failed to create new lock file %s (%s).\n", lockFileName, Err_Errno2String(saveErrno)); return (saveErrno == EEXIST) ? 0 : -1; } } err = write(lockFD, uniqueID, strlen(uniqueID)); saveErrno = errno; close(lockFD); if (err != strlen(uniqueID)) { Warning(LGPFX" Failed to write to new lock file %s (%s).\n", lockFileName, Err_Errno2String(saveErrno)); status = -1; goto exit; } uid = Id_BeginSuperUser(); if (useLinking && (link(lockFileLink, lockFileName) < 0)) { status = (errno == EEXIST) ? 0 : -1; } Id_EndSuperUser(uid); exit: if (useLinking) { uid = Id_BeginSuperUser(); err = unlink(lockFileLink); Id_EndSuperUser(uid); if (err < 0) { Warning(LGPFX" Failed to remove temporary lock file %s (%s).\n", lockFileLink, Err_Errno2String(errno)); } } return status; } /* *---------------------------------------------------------------------- * * FileLock_LockDevice -- * * Lock with a file. Detect and remove stale locks * when possible. * * Results: * 1 if got the lock, 0 if not, -1 for errors. * * Side effects: * Change the host file system. * * Note: * This locking method remains due to "minicom" and similar * programs that use this locking method for access serialization * of serial ports. * *---------------------------------------------------------------------- */ int FileLock_LockDevice(const char *deviceName) // IN: { const char *hostID; char uniqueID[1000]; char *lockFileName; char *lockFileLink; int status = -1; ASSERT(deviceName); lockFileName = Str_SafeAsprintf(NULL, "%s/LCK..%s", DEVICE_LOCK_DIR, deviceName); lockFileLink = Str_SafeAsprintf(NULL, "%s/LTMP..%s.t%05d", DEVICE_LOCK_DIR, deviceName, getpid()); LOG(1, ("Requesting lock %s (temp = %s).\n", lockFileName, lockFileLink)); hostID = FileLockGetMachineID(); Str_Sprintf(uniqueID, sizeof uniqueID, "%d %s\n", getpid(), hostID); while ((status = FileLockCreateLockFile(lockFileName, lockFileLink, uniqueID)) == 0) { int pid; char fileID[1000]; /* * The lock file already exists. See if it is a stale lock. * * We retry the link if the file is gone now (0 return). */ switch (GetLockFileValues(lockFileName, &pid, fileID)) { case 1: break; case 0: continue; case -1: status = -1; goto exit; default: NOT_REACHED(); } if (strcmp(hostID, fileID) != 0) { /* Lock was acquired by a different host. */ status = 0; goto exit; } if (FileLockIsValidProcess(pid)) { status = 0; goto exit; } /* stale lock */ if (!RemoveStaleLockFile(lockFileName)) { status = -1; goto exit; } /* TRY AGAIN */ } exit: free(lockFileName); free(lockFileLink); return status; } /* *---------------------------------------------------------------------- * * FileLock_UnlockDevice -- * * Unlock a lock obtained by FileLock_LockDevice. * * Results: * True if successful, FALSE otherwise. * * Side effects: * Change the host file system. * *---------------------------------------------------------------------- */ Bool FileLock_UnlockDevice(const char *deviceName) // IN: { uid_t uid; int ret; int saveErrno; char *path; ASSERT(deviceName); path = Str_SafeAsprintf(NULL, "%s/LCK..%s", DEVICE_LOCK_DIR, deviceName); LOG(1, ("Releasing lock %s.\n", path)); uid = Id_BeginSuperUser(); ret = unlink(path); saveErrno = errno; Id_EndSuperUser(uid); if (ret < 0) { Log(LGPFX" Cannot remove lock file %s (%s).\n", path, Err_Errno2String(saveErrno)); free(path); return FALSE; } free(path); return TRUE; } /* *---------------------------------------------------------------------- * * FileLockAppendMessage -- * * Append a detailed error message to the MsgList. * * Results: * As above * * Side effects: * Memory is allocated * *---------------------------------------------------------------------- */ void FileLockAppendMessage(MsgList **msgs, // IN/OPT: int err) // IN: errno { MsgList_Append(msgs, MSGID(fileLock.posix) "A file locking error (%d) has occurred: %s.", err, Err_Errno2String(err)); } #if defined(linux) /* *---------------------------------------------------------------------- * * FileReadSlashProc -- * * Read the data in a /proc file * * Results: * 0 Data is available * !0 Error (errno) * * Side effects: * None. * *---------------------------------------------------------------------- */ static int FileReadSlashProc(const char *procPath, // IN: char *buffer, // OUT: size_t bufferSize) // IN: { int fd; int err; char *p; size_t len; ASSERT(procPath); ASSERT(buffer); ASSERT(bufferSize > 0); fd = Posix_Open(procPath, O_RDONLY, 0); if (fd == -1) { return errno; } len = read(fd, buffer, bufferSize - 1); err = errno; close(fd); if (len == -1) { return err; } buffer[len] = '\0'; p = strchr(buffer, '\n'); if (p != NULL) { *p = '\0'; } return 0; } /* *--------------------------------------------------------------------------- * * FileLockProcessDescriptor -- * * Returns the process descriptor of the specified process. * * The format of a process descriptor is as follows: * * processID-processCreationTime(processName) * * where the processName and processCreationTime information * may be independently optional. * * Results: * NULL The process does not exist. * !NULL The process descriptor is returned. It is the callers * responsibility to free the dynamically allocated memory. * * Side Effects: * None * *--------------------------------------------------------------------------- */ static char * FileLockProcessDescriptor(pid_t pid) // IN: { char path[64]; char buffer[1024]; char *descriptor = NULL; if (!FileLockIsValidProcess(pid)) { return NULL; } Str_Sprintf(path, sizeof path, "/proc/%d/stat", pid); if (FileReadSlashProc(path, buffer, sizeof buffer) == 0) { char *p; char *q; char *rest; uint32 argc; char *argv[22]; char *savePtr = NULL; /* * You are in a maze of twisty little fields, (virtually) all alike... * * The process creation time, in 64-bit jiffies is "out there". * * A "man 5 proc" will provide illumination concerning all of the * fields found on this line of text. We code for the worst case * and ensure that file names containing spaces or parens are * properly handled. */ p = strchr(buffer, '('); if ((p == NULL) || (p == buffer) || (*(p - 1) != ' ')) { goto bail; } *(p - 1) = '\0'; q = strrchr(p + 1, ')'); if (q == NULL) { goto bail; } rest = q + 1; if (*rest != ' ') { goto bail; } *rest++ = '\0'; argv[0] = strtok_r(buffer, " ", &savePtr); // ensure no trailing spaces argv[1] = p; /* Map spaces in the process name to something benign */ q = p; while ((q = strchr(q, ' ')) != NULL) { *q = '_'; } if (strlen(p) > LOG_MAX_PROC_NAME) { p[LOG_MAX_PROC_NAME - 1] = ')'; p[LOG_MAX_PROC_NAME] = '\0'; } for (argc = 2; argc < 22; argc++) { argv[argc] = strtok_r((argc == 2) ? rest : NULL, " ", &savePtr); if (argv[argc] == NULL) { break; } } if (argc == 22) { descriptor = Str_SafeAsprintf(NULL, "%s-%s%s", argv[0], argv[21], argv[1]); } } bail: if (descriptor == NULL) { /* * Accessing /proc failed in some way. Emit a valid string that also * provides a clue that there is/was a problem. */ descriptor = Str_SafeAsprintf(NULL, "%d-0", pid); } return descriptor; } #elif defined(__APPLE__) /* *--------------------------------------------------------------------------- * * FileLockProcessCreationTime -- * * Returns the process creation time of the specified process. * * Results: * TRUE Done! * FALSE Process doesn't exist * * Side effects: * None * *--------------------------------------------------------------------------- */ static Bool FileLockProcessCreationTime(pid_t pid, // IN: uint64 *procCreationTime) // OUT: { int err; size_t size; struct kinfo_proc info; int mib[4]; ASSERT(procCreationTime); /* Request information about the specified process */ mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PID; mib[3] = pid; memset(&info, 0, sizeof info); size = sizeof info; err = sysctl(mib, ARRAYSIZE(mib), &info, &size, NULL, 0); if (err == -1) { return FALSE; } *procCreationTime = (info.kp_proc.p_starttime.tv_sec * CONST64U(1000000)) + info.kp_proc.p_starttime.tv_usec; return TRUE; } /* *--------------------------------------------------------------------------- * * FileLockProcessDescriptor -- * * Returns the process descriptor of the specified process. * * The format of a process descriptor is as follows: * * processID-processCreationTime(processName) * * where the processName and processCreationTime information * may be independently optional. * * Results: * NULL The process does not exist. * !NULL The process descriptor is returned. It is the callers * responsibility to free the dynamically allocated memory. * * Side effects: * None * *--------------------------------------------------------------------------- */ static char * FileLockProcessDescriptor(pid_t pid) // IN: { uint64 procCreationTime; if (!FileLockIsValidProcess(pid)) { return NULL; } if (!FileLockProcessCreationTime(pid, &procCreationTime)) { return NULL; } return Str_SafeAsprintf(NULL, "%d-%"FMT64"u", pid, procCreationTime); } #else /* *--------------------------------------------------------------------------- * * FileLockProcessDescriptor -- * * Returns the process descriptor of the specified process. * * The format of a process descriptor is as follows: * * processID-processCreationTime(processName) * * where the processName and processCreationTime information * may be independently optional. * * Results: * NULL The process does not exist. * !NULL The process descriptor is returned. It is the callers * responsibility to free the dynamically allocated memory. * * Side effects: * None * *--------------------------------------------------------------------------- */ static char * FileLockProcessDescriptor(pid_t pid) // IN: { return FileLockIsValidProcess(pid) ? Str_SafeAsprintf(NULL, "%d-0", pid) : NULL; } #endif /* *--------------------------------------------------------------------------- * * FileLockGetExecutionID -- * * Returns the executionID of the caller. * * Results: * The executionID of the caller. This is a dynamically allocated string; * the caller is responsible for its disposal. * * Side effects: * The executionID of the caller is not thread safe. Locking is currently * done at the process level - all threads of a process are treated * identically. * *--------------------------------------------------------------------------- */ char * FileLockGetExecutionID(void) { char *descriptor = FileLockProcessDescriptor(getpid()); ASSERT(descriptor); // Must be able to describe ourselves! return descriptor; } /* *--------------------------------------------------------------------------- * * FileLockParseProcessDescriptor -- * * Attempt to parse the specified process descriptor. Return the * pieces requested. * * Results: * TRUE Process descriptor is valid. * FALSE Process descriptor is invalid. * * Side effects: * None * *--------------------------------------------------------------------------- */ static Bool FileLockParseProcessDescriptor(const char *procDescriptor, // IN: pid_t *pid, // OUT: uint64 *procCreationTime) // OUT: { ASSERT(procDescriptor); ASSERT(pid); ASSERT(procCreationTime); if (sscanf(procDescriptor, "%d-%"FMT64"u", pid, procCreationTime) != 2) { if (sscanf(procDescriptor, "%d", pid) == 1) { *procCreationTime = 0ULL; } else { return FALSE; } } return *pid >= 0; } /* *---------------------------------------------------------------------- * * FileLockValidExecutionID -- * * Validate the execution ID. * * Results: * TRUE Yes * FALSE No * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool FileLockValidExecutionID(const char *executionID) // IN: { pid_t filePID; pid_t procPID; Bool gotFileData; Bool gotProcData; char *procDescriptor; uint64 fileCreationTime; uint64 procCreationTime; gotFileData = FileLockParseProcessDescriptor(executionID, &filePID, &fileCreationTime); if (!gotFileData) { Warning(LGPFX" %s parse error on '%s'. Assuming valid.\n", __FUNCTION__, executionID); return TRUE; // Assume TRUE - preserve a lock - on parse error } procDescriptor = FileLockProcessDescriptor(filePID); if (procDescriptor == NULL) { return FALSE; // process doesn't exist } gotProcData = FileLockParseProcessDescriptor(procDescriptor, &procPID, &procCreationTime); ASSERT(gotProcData); // We built it; it had better be good ASSERT(procPID == filePID); // This better match what we started with... free(procDescriptor); if ((fileCreationTime != 0) && (procCreationTime != 0) && (fileCreationTime != procCreationTime)) { return FALSE; // The process no longer exists } else { return TRUE; // Looks valid... } } /* *--------------------------------------------------------------------------- * * FileLockNormalizePath * * Normalize the path of the file being locked. Locking a symbolic * link should place the lock next to the link, not where the link * points to. * * Results: * The normalized path or NULL on error * * Side effects: * None * *--------------------------------------------------------------------------- */ static Unicode FileLockNormalizePath(ConstUnicode filePath) // IN: { Unicode result; Unicode fullPath; Unicode dirName = NULL; Unicode fileName = NULL; /* * If the file to be locked is a symbolic link the lock file belongs next * to the symbolic link, not "off" where the symbolic link points to. * Translation: Don't "full path" the entire path of the file to be locked; * "full path" the dirName of the path, leaving the fileName alone. */ File_GetPathName(filePath, &dirName, &fileName); fullPath = File_FullPath(dirName); result = (fullPath == NULL) ? NULL : Unicode_Join(fullPath, DIRSEPS, fileName, NULL); Unicode_Free(fullPath); Unicode_Free(dirName); Unicode_Free(fileName); return result; } /* *---------------------------------------------------------------------- * * FileLock_Lock -- * * Obtain a lock on a file; shared or exclusive access. Also specify * how long to wait on lock acquisition - msecMaxWaitTime * * msecMaxWaitTime specifies the maximum amount of time, in * milliseconds, to wait for the lock before returning the "not * acquired" status. A value of FILELOCK_TRYLOCK_WAIT is the * equivalent of a "try lock" - the lock will be acquired only if * there is no contention. A value of FILELOCK_INFINITE_WAIT * specifies "waiting forever" to acquire the lock. * * Results: * NULL Lock not acquired * errno to *err, msg to **msgs - when appropriate * !NULL Lock Acquired. This is the "lockToken" for an unlock. * * Side effects: * Changes the host file system. * *---------------------------------------------------------------------- */ FileLockToken * FileLock_Lock(ConstUnicode filePath, // IN: const Bool readOnly, // IN: const uint32 msecMaxWaitTime, // IN: int *err, // OUT/OPT: returns errno MsgList **msgs) // OUT/OPT: add error message { int res = 0; Unicode normalizedPath; FileLockToken *tokenPtr; ASSERT(filePath); ASSERT(err); normalizedPath = FileLockNormalizePath(filePath); if (normalizedPath == NULL) { res = EINVAL; tokenPtr = NULL; } else { tokenPtr = FileLockIntrinsic(normalizedPath, !readOnly, msecMaxWaitTime, &res); Unicode_Free(normalizedPath); } if (err != NULL) { *err = res; } if (tokenPtr == NULL) { int errnoValue; if (res == 0) { errnoValue = EAGAIN; // Thank you for playing; try again /* Failed to acquire the lock; another has possession of it */ } else { errnoValue = res; } FileLockAppendMessage(msgs, errnoValue); } return tokenPtr; } /* *---------------------------------------------------------------------- * * FileLock_IsLocked -- * * Is a file currently locked (at the time of the call)? * * Results: * TRUE YES * FALSE Failure (errno to *err, msg to **msgs - when appropriate) * *---------------------------------------------------------------------- */ Bool FileLock_IsLocked(ConstUnicode filePath, // IN: int *err, // OUT/OPT: returns errno MsgList **msgs) // OUT/OPT: add error message { int res = 0; Bool isLocked; Unicode normalizedPath; ASSERT(filePath); normalizedPath = FileLockNormalizePath(filePath); if (normalizedPath == NULL) { res = EINVAL; isLocked = FALSE; } else { isLocked = FileLockIsLocked(normalizedPath, &res); Unicode_Free(normalizedPath); } if (err != NULL) { *err = res; } if (res != 0) { FileLockAppendMessage(msgs, res); } return isLocked; } /* *---------------------------------------------------------------------- * * FileLock_Unlock -- * * Release the lock held on the specified file. * * Results: * TRUE Success * FALSE Failure (errno to *err, msg to **msgs - when appropriate) * * Side effects: * Changes the host file system. * *---------------------------------------------------------------------- */ Bool FileLock_Unlock(const FileLockToken *lockToken, // IN: int *err, // OUT/OPT: returns errno MsgList **msgs) // OUT/OPT: add error message { int res; ASSERT(lockToken); res = FileUnlockIntrinsic((FileLockToken *) lockToken); if (err != NULL) { *err = res; } if (res != 0) { FileLockAppendMessage(msgs, res); } return (res == 0); } #else char * FileLockGetExecutionID(void) { NOT_IMPLEMENTED(); } Bool FileLockValidExecutionID(const char *executionID) // IN: { NOT_IMPLEMENTED(); } #endif /* !__FreeBSD__ && !sun */ open-vm-tools-9.4.0-1280544/lib/file/Makefile.in0000644765153500003110000004522112220061621017166 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/file DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libFile_la_LIBADD = am_libFile_la_OBJECTS = file.lo fileStandAlone.lo filePosix.lo \ fileIO.lo fileIOPosix.lo fileLockPrimitive.lo fileLockPosix.lo \ fileTempPosix.lo fileTemp.lo libFile_la_OBJECTS = $(am_libFile_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libFile_la_SOURCES) DIST_SOURCES = $(libFile_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libFile.la libFile_la_SOURCES = file.c fileStandAlone.c filePosix.c fileIO.c \ fileIOPosix.c fileLockPrimitive.c fileLockPosix.c \ fileTempPosix.c fileTemp.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/file/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/file/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libFile.la: $(libFile_la_OBJECTS) $(libFile_la_DEPENDENCIES) $(EXTRA_libFile_la_DEPENDENCIES) $(LINK) $(libFile_la_OBJECTS) $(libFile_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileIO.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileIOPosix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileLockPosix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileLockPrimitive.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filePosix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileStandAlone.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileTemp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileTempPosix.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/file/fileIO.c0000644765153500003110000006456612220061556016460 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * fileIO.c -- * * Basic (non internationalized) implementation of error messages for the * Files library. * * File locking/unlocking routines. * */ #include #include #include #include "vmware.h" #include "util.h" #include "fileIO.h" #include "fileLock.h" #include "fileInt.h" #include "msg.h" #include "unicodeOperations.h" #include "hostType.h" #if defined(_WIN32) #include #else #include #include #include #include #include #endif #if defined(VMX86_SERVER) #include "fs_public.h" #endif /* *---------------------------------------------------------------------- * * FileIO_ErrorEnglish -- * * Return the message associated with a status code * * Results: * The message * * Side effects: * None * *---------------------------------------------------------------------- */ const char * FileIO_ErrorEnglish(FileIOResult status) // IN { return Msg_StripMSGID(FileIO_MsgError(status)); } /* *---------------------------------------------------------------------- * * FileIO_MsgError -- * * Return the message associated with a status code * * Results: * The message. * * Side effects: * None. * *---------------------------------------------------------------------- */ const char * FileIO_MsgError(FileIOResult status) // IN { const char *result = NULL; switch (status) { case FILEIO_SUCCESS: /* * Most of the time, you don't call this function with this value * because there is no error */ result = MSGID(fileio.success) "Success"; break; case FILEIO_CANCELLED: /* * Most of the time, you don't call this function with this value * because you don't want to display error messages after a user has * cancelled an operation. */ result = MSGID(fileio.cancel) "The operation was canceled by the user"; break; case FILEIO_ERROR: /* * Most of the time, you don't call this function with this value * because you can call your native function to retrieve a more * accurate message. */ result = MSGID(fileio.generic) "Error"; break; case FILEIO_OPEN_ERROR_EXIST: result = MSGID(fileio.exists) "The file already exists"; break; case FILEIO_LOCK_FAILED: result = MSGID(fileio.lock) "Failed to lock the file"; break; case FILEIO_READ_ERROR_EOF: result = MSGID(fileio.eof) "Tried to read beyond the end of the file"; break; case FILEIO_FILE_NOT_FOUND: result = MSGID(fileio.notfound) "Could not find the file"; break; case FILEIO_NO_PERMISSION: result = MSGID(fileio.noPerm) "Insufficient permission to access the file"; break; case FILEIO_FILE_NAME_TOO_LONG: result = MSGID(fileio.namelong) "The file name is too long"; break; case FILEIO_WRITE_ERROR_FBIG: result = MSGID(fileio.fBig) "The file is too large"; break; case FILEIO_WRITE_ERROR_NOSPC: result = MSGID(fileio.noSpc) "There is no space left on the device"; break; case FILEIO_WRITE_ERROR_DQUOT: result = MSGID(fileio.dQuot) "There is no space left on the device"; break; case FILEIO_ERROR_LAST: NOT_IMPLEMENTED(); break; /* * We do not provide a default case on purpose, so that the compiler can * detect changes in the error set and reminds us to implement the * associated messages --hpreg */ } if (!result) { Warning("%s: bad code %d\n", __FUNCTION__, status); ASSERT(0); result = MSGID(fileio.unknown) "Unknown error"; } return result; } /* *---------------------------------------------------------------------- * * FileIO_Init -- * * Initialize invalid FileIODescriptor. Expects that caller * prepared structure with FileIO_Invalidate. * * Results: * None. * * Side effects: * None * *---------------------------------------------------------------------- */ void FileIO_Init(FileIODescriptor *fd, // IN/OUT: ConstUnicode pathName) // IN: { ASSERT(fd); ASSERT(pathName); fd->fileName = Unicode_Duplicate(pathName); } /* *---------------------------------------------------------------------- * * FileIO_Cleanup -- * * Undo resource allocation done by FileIO_Init. You do not want to * call this function directly, you most probably want FileIO_Close. * * Results: * None. * * Side effects: * None * *---------------------------------------------------------------------- */ void FileIO_Cleanup(FileIODescriptor *fd) // IN/OUT: { ASSERT(fd); if (fd->fileName) { Unicode_Free(fd->fileName); fd->fileName = NULL; } } /* *---------------------------------------------------------------------- * * FileIOResolveLockBits -- * * Resolve the multitude of lock bits from historical public names * to newer internal names. * * Input flags: FILEIO_OPEN_LOCKED a.k.a. FILEIO_OPEN_LOCK_BEST, * FILEIO_OPEN_EXCLUSIVE_LOCK * Output flags: FILEIO_OPEN_LOCK_MANDATORY, FILEIO_OPEN_LOCK_ADVISORY * * Results: * None * * Side effects: * Only output flags are set in *access. * *---------------------------------------------------------------------- */ void FileIOResolveLockBits(int *access) // IN/OUT: FILEIO_OPEN_* bits { /* * Lock types: * none: no locking at all * advisory: open() ignores lock, FileIO_ respects lock. * mandatory: open() and FileIO_ respect lock. * "best": downgrades to advisory or mandatory based on OS support */ if ((*access & FILEIO_OPEN_EXCLUSIVE_LOCK) != 0) { *access &= ~FILEIO_OPEN_EXCLUSIVE_LOCK; *access |= FILEIO_OPEN_LOCK_MANDATORY; } if ((*access & FILEIO_OPEN_LOCK_BEST) != 0) { /* "Best effort" bit: mandatory if OS supports, advisory otherwise */ *access &= ~FILEIO_OPEN_LOCK_BEST; if (HostType_OSIsVMK()) { *access |= FILEIO_OPEN_LOCK_MANDATORY; } else { *access |= FILEIO_OPEN_LOCK_ADVISORY; } } /* Only one lock type (or none at all) allowed */ ASSERT(((*access & FILEIO_OPEN_LOCK_ADVISORY) == 0) || ((*access & FILEIO_OPEN_LOCK_MANDATORY) == 0)); } /* *---------------------------------------------------------------------- * * FileIO_Lock -- * * Call the FileLock module to lock the given file. * * Results: * FILEIO_ERROR A serious error occured. * FILEIO_SUCCESS All is well * FILEIO_LOCK_FAILED Requested lock on file was not acquired * FILEIO_FILE_NOT_FOUND Unable to find the specified file * FILEIO_NO_PERMISSION Permissions issues * FILEIO_FILE_NAME_TOO_LONG The path name is too long * * Side effects: * None * *---------------------------------------------------------------------- */ FileIOResult FileIO_Lock(FileIODescriptor *file, // IN/OUT: int access) // IN: { FileIOResult ret = FILEIO_SUCCESS; /* * Lock the file if necessary. */ ASSERT(file); ASSERT(file->lockToken == NULL); FileIOResolveLockBits(&access); ASSERT((access & FILEIO_OPEN_LOCKED) == 0); #if !defined(__FreeBSD__) && !defined(sun) if ((access & FILEIO_OPEN_LOCK_MANDATORY) != 0) { /* Mandatory file locks are available only when opening a file */ ret = FILEIO_LOCK_FAILED; } else if ((access & FILEIO_OPEN_LOCK_ADVISORY) != 0) { int err = 0; file->lockToken = FileLock_Lock(file->fileName, (access & FILEIO_OPEN_ACCESS_WRITE) == 0, FILELOCK_DEFAULT_WAIT, &err, NULL); if (file->lockToken == NULL) { /* Describe the lock not acquired situation in detail */ Warning(LGPFX" %s on '%s' failed: %s\n", __FUNCTION__, UTF8(file->fileName), (err == 0) ? "Lock timed out" : strerror(err)); /* Return a serious failure status if the locking code did */ switch (err) { case 0: // File is currently locked case EROFS: // Attempt to lock for write on RO FS ret = FILEIO_LOCK_FAILED; break; case ENAMETOOLONG: // Path is too long ret = FILEIO_FILE_NAME_TOO_LONG; break; case ENOENT: // No such file or directory ret = FILEIO_FILE_NOT_FOUND; break; case EACCES: // Permissions issues ret = FILEIO_NO_PERMISSION; break; default: // Some sort of locking error ret = FILEIO_ERROR; } } } #endif // !__FreeBSD__ && !sun return ret; } /* *---------------------------------------------------------------------- * * FileIO_UnLock -- * * Call the FileLock module to unlock the given file. * * Results: * FILEIO_SUCCESS All is well * FILEIO_ERROR A serious error occured. * * Side effects: * None * *---------------------------------------------------------------------- */ FileIOResult FileIO_Unlock(FileIODescriptor *file) // IN/OUT: { FileIOResult ret = FILEIO_SUCCESS; ASSERT(file); #if !defined(__FreeBSD__) && !defined(sun) if (file->lockToken != NULL) { int err = 0; if (!FileLock_Unlock(file->lockToken, &err, NULL)) { Warning(LGPFX" %s on '%s' failed: %s\n", __FUNCTION__, UTF8(file->fileName), strerror(err)); ret = FILEIO_ERROR; } file->lockToken = NULL; } #else ASSERT(file->lockToken == NULL); #endif // !__FreeBSD__ && !sun return ret; } /* *---------------------------------------------------------------------- * * FileIO_GetSize -- * * Get size of file. * * Results: * Size of file or -1. * * Side effects: * errno is set on error. * *---------------------------------------------------------------------- */ int64 FileIO_GetSize(const FileIODescriptor *fd) // IN: { int64 logicalBytes; return (FileIO_GetAllocSize(fd, &logicalBytes, NULL) != FILEIO_SUCCESS) ? -1 : logicalBytes; } /* *---------------------------------------------------------------------- * * FileIO_GetSizeByPath -- * * Get size of a file specified by path. * * Results: * Size of file or -1. * * Side effects: * errno is set on error * *---------------------------------------------------------------------- */ int64 FileIO_GetSizeByPath(ConstUnicode pathName) // IN: { int64 logicalBytes; return (FileIO_GetAllocSizeByPath(pathName, &logicalBytes, NULL) != FILEIO_SUCCESS) ? -1 : logicalBytes; } /* *---------------------------------------------------------------------- * * FileIO_Filename -- * * Returns the filename that was used to open a FileIODescriptor * * Results: * Filename. You DON'T own the memory - use Unicode_Duplicate if * you want to keep it for yourself. In particular, if the file * gets closed the string will almost certainly become invalid. * * Side effects: * None. * *---------------------------------------------------------------------- */ ConstUnicode FileIO_Filename(FileIODescriptor *fd) // IN: { ASSERT(fd); return fd->fileName; } /* *---------------------------------------------------------------------- * * FileIO_CloseAndUnlink * * Closes and unlinks the file associated with a FileIODescriptor. * * Results: * TRUE: An error occurred. * FALSE: The file was closed and unlinked. * * Side effects: * File is probably closed and unlinked. * *---------------------------------------------------------------------- */ Bool FileIO_CloseAndUnlink(FileIODescriptor *fd) // IN: { Unicode path; Bool ret; ASSERT(fd); ASSERT(FileIO_IsValid(fd)); path = Unicode_Duplicate(fd->fileName); ret = FileIO_Close(fd) || File_Unlink(path); Unicode_Free(path); return ret; } #if defined(_WIN32) || defined(__linux__) || defined(__APPLE__) || \ defined(__FreeBSD__) || defined(sun) /* *---------------------------------------------------------------------- * * FileIO_Pread -- * * Reads from a file starting at a specified offset. * * Note: This function may update the file pointer so you will need to * call FileIO_Seek before calling FileIO_Read/Write afterwards. * * Results: * FILEIO_SUCCESS, FILEIO_ERROR * * Side effects: * None * *---------------------------------------------------------------------- */ FileIOResult FileIO_Pread(FileIODescriptor *fd, // IN: File descriptor void *buf, // IN: Buffer to read into size_t len, // IN: Length of the buffer uint64 offset) // IN: Offset to start reading { struct iovec iov; ASSERT(fd); iov.iov_base = buf; iov.iov_len = len; return FileIO_Preadv(fd, &iov, 1, offset, len, NULL); } /* *---------------------------------------------------------------------- * * FileIO_Pwrite -- * * Writes to a file starting at a specified offset. * * Note: This function may update the file pointer so you will need to * call FileIO_Seek before calling FileIO_Read/Write afterwards. * * Results: * FILEIO_SUCCESS, FILEIO_ERROR * * Side effects: * None * *---------------------------------------------------------------------- */ FileIOResult FileIO_Pwrite(FileIODescriptor *fd, // IN: File descriptor void const *buf, // IN: Buffer to write from size_t len, // IN: Length of the buffer uint64 offset) // IN: Offset to start writing { struct iovec iov; ASSERT(fd); /* The cast is safe because FileIO_Pwritev() will not write to '*buf'. */ iov.iov_base = (void *)buf; iov.iov_len = len; return FileIO_Pwritev(fd, &iov, 1, offset, len, NULL); } #endif #if defined(sun) && __GNUC__ < 3 /* *----------------------------------------------------------------------------- * * FileIO_IsSuccess -- * * XXX: See comment in fileIO.h. For reasonable compilers, this * function is implemented as "static inline" in fileIO.h; for * unreasonable compilers, it can't be static so we implement it here. * * Results: * TRUE if the input indicates success. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool FileIO_IsSuccess(FileIOResult res) // IN: { return res == FILEIO_SUCCESS; } #endif /* *----------------------------------------------------------------------------- * * FileIO_AtomicTempPath * * Return a temp path name in the same directory as the argument path. * The path is the full path of the source file with a '~' appended. * The caller must free the path when done. * * Results: * Unicode path if successful, NULL on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Unicode FileIO_AtomicTempPath(ConstUnicode path) // IN: { Unicode srcPath; Unicode retPath; srcPath = File_FullPath(path); if (!srcPath) { Log("%s: File_FullPath of '%s' failed.\n", __FUNCTION__, path); return NULL; } retPath = Unicode_Join(srcPath, "~", NULL); Unicode_Free(srcPath); return retPath; } /* *----------------------------------------------------------------------------- * * FileIO_AtomicTempFile * * Create a temp file in the same directory as the argument file. * On non-Windows attempts to create the temp file with the same * permissions and owner/group as the argument file. * * Results: * FileIOResult of call that failed or FILEIO_SUCCESS * * Side effects: * Creates a new file. * *----------------------------------------------------------------------------- */ FileIOResult FileIO_AtomicTempFile(FileIODescriptor *fileFD, // IN: FileIODescriptor *tempFD) // OUT: { Unicode tempPath = NULL; int permissions; FileIOResult status; #if !defined(_WIN32) int ret; struct stat stbuf; #endif ASSERT(FileIO_IsValid(fileFD)); ASSERT(tempFD && !FileIO_IsValid(tempFD)); tempPath = FileIO_AtomicTempPath(FileIO_Filename(fileFD)); if (!tempPath) { status = FILEIO_ERROR; goto bail; } #if defined(_WIN32) permissions = 0; File_UnlinkIfExists(tempPath); #else if (fstat(fileFD->posix, &stbuf)) { Log("%s: Failed to fstat '%s', errno: %d.\n", __FUNCTION__, FileIO_Filename(fileFD), errno); status = FILEIO_ERROR; goto bail; } permissions = stbuf.st_mode; /* Clean up a previously created temp file; if one exists. */ ret = Posix_Unlink(tempPath); if (ret != 0 && errno != ENOENT) { Log("%s: Failed to unlink temporary file, errno: %d\n", __FUNCTION__, errno); /* Fall through; FileIO_Create will report the actual error. */ } #endif status = FileIO_Create(tempFD, tempPath, FILEIO_ACCESS_READ | FILEIO_ACCESS_WRITE, FILEIO_OPEN_CREATE_SAFE, permissions); if (!FileIO_IsSuccess(status)) { Log("%s: Failed to create temporary file, %s (%d). errno: %d\n", __FUNCTION__, FileIO_ErrorEnglish(status), status, Err_Errno()); goto bail; } #if !defined(_WIN32) /* * On ESX we always use the vmkernel atomic file swap primitive, so * there's no need to set the permissions and owner of the temp file. * * XXX this comment is not true for NFS on ESX -- we use rename rather * than "vmkernel atomic file swap primitive" -- but we do not care * because files are always owned by root. Sigh. Bug 839283. */ if (!HostType_OSIsVMK()) { if (fchmod(tempFD->posix, stbuf.st_mode)) { Log("%s: Failed to chmod temporary file, errno: %d\n", __FUNCTION__, errno); status = FILEIO_ERROR; goto bail; } if (fchown(tempFD->posix, stbuf.st_uid, stbuf.st_gid)) { Log("%s: Failed to chown temporary file, errno: %d\n", __FUNCTION__, errno); status = FILEIO_ERROR; goto bail; } } #endif Unicode_Free(tempPath); return FILEIO_SUCCESS; bail: ASSERT(!FileIO_IsSuccess(status)); if (FileIO_IsValid(tempFD)) { FileIO_Close(tempFD); #if defined(_WIN32) File_UnlinkIfExists(tempPath); #else ret = Posix_Unlink(tempPath); if (ret != 0) { Log("%s: Failed to clean up temporary file, errno: %d\n", __FUNCTION__, errno); } ASSERT(ret == 0); #endif } Unicode_Free(tempPath); return status; } /* *----------------------------------------------------------------------------- * * FileIO_AtomicUpdate -- * * On ESX when the target files reside on vmfs, exchanges the contents * of two files using code modeled from VmkfsLib_SwapFiles. Both "curr" * and "new" are left open. * * On hosted products, uses rename to swap files, so "new" becomes "curr", * and path to "new" no longer exists on success. * * On ESX on NFS: * * If renameOnNFS is TRUE, use rename, like on hosted. * * If renameOnNFS is FALSE, returns -1 rather than trying to use rename, * to avoid various bugs in the vmkernel NFSv3 client. Bug 839283, * bug 862647, bug 841185, bug 856752. * * On success the caller must call FileIO_IsValid on newFD to verify it * is still open before using it again. * * Results: * 1 if successful, 0 on failure, -1 if not supported on this filesystem. * errno is preserved. * * Side effects: * Disk I/O. * *----------------------------------------------------------------------------- */ int FileIO_AtomicUpdate(FileIODescriptor *newFD, // IN/OUT: file IO descriptor FileIODescriptor *currFD, // IN/OUT: file IO descriptor Bool renameOnNFS) // IN: fall back to rename on NFS { char *currPath; char *newPath; uint32 currAccess; uint32 newAccess; int ret = 0; FileIOResult status; FileIODescriptor tmpFD; int savedErrno = 0; ASSERT(FileIO_IsValid(newFD)); ASSERT(FileIO_IsValid(currFD)); if (HostType_OSIsVMK()) { #if defined(VMX86_SERVER) FS_SwapFilesArgs *args = NULL; char *dirName = NULL; char *fileName = NULL; char *dstDirName = NULL; char *dstFileName = NULL; int fd; currPath = File_FullPath(FileIO_Filename(currFD)); newPath = File_FullPath(FileIO_Filename(newFD)); ASSERT(currPath); ASSERT(newPath); File_GetPathName(newPath, &dirName, &fileName); File_GetPathName(currPath, &dstDirName, &dstFileName); ASSERT(dirName && *dirName); ASSERT(fileName && *fileName); ASSERT(dstDirName && *dstDirName); ASSERT(dstFileName && *dstFileName); ASSERT(!strcmp(dirName, dstDirName)); args = (FS_SwapFilesArgs *) Util_SafeCalloc(1, sizeof(*args)); if (Str_Snprintf(args->srcFile, sizeof(args->srcFile), "%s", fileName) < 0) { Log("%s: Path too long \"%s\".\n", __FUNCTION__, fileName); savedErrno = ENAMETOOLONG; goto swapdone; } if (Str_Snprintf(args->dstFilePath, sizeof(args->dstFilePath), "%s/%s", dstDirName, dstFileName) < 0) { Log("%s: Path too long \"%s\".\n", __FUNCTION__, dstFileName); savedErrno = ENAMETOOLONG; goto swapdone; } /* * Issue the ioctl on the directory rather than on the file, * because the file could be open. */ fd = Posix_Open(dirName, O_RDONLY); if (fd < 0) { Log("%s: Open failed \"%s\" %d.\n", __FUNCTION__, dirName, errno); ASSERT_BUG_DEBUGONLY(615124, errno != EBUSY); savedErrno = errno; goto swapdone; } if (ioctl(fd, IOCTLCMD_VMFS_SWAP_FILES, args) != 0) { savedErrno = errno; if (errno != ENOSYS && errno != ENOTTY) { Log("%s: ioctl failed %d.\n", __FUNCTION__, errno); ASSERT_BUG_DEBUGONLY(615124, errno != EBUSY); } } else { ret = 1; } close(fd); /* * Did we fail because we are on a file system that does not * support the IOCTLCMD_VMFS_SWAP_FILES ioctl? If so fallback to * using rename. * * Check for both ENOSYS and ENOTTY. PR 957695 */ if (savedErrno == ENOSYS || savedErrno == ENOTTY) { if (renameOnNFS) { /* * NFS allows renames of locked files, even if both files * are locked. The file lock follows the file handle, not * the name, so after the rename we can swap the underlying * file descriptors instead of closing and reopening the * target file. * * This is different than the hosted path below because * ESX uses native file locks and hosted does not. * * We assume that all ESX file systems that support rename * have the same file lock semantics as NFS. */ if (File_Rename(newPath, currPath)) { Log("%s: rename of '%s' to '%s' failed %d.\n", __FUNCTION__, newPath, currPath, errno); savedErrno = errno; goto swapdone; } ret = 1; fd = newFD->posix; newFD->posix = currFD->posix; currFD->posix = fd; FileIO_Close(newFD); } else { ret = -1; } } swapdone: free(args); free(dirName); free(fileName); free(dstDirName); free(dstFileName); free(currPath); free(newPath); errno = savedErrno; return ret; #else NOT_REACHED(); #endif } currPath = Unicode_Duplicate(FileIO_Filename(currFD)); newPath = Unicode_Duplicate(FileIO_Filename(newFD)); newAccess = newFD->flags; currAccess = currFD->flags; FileIO_Close(newFD); /* * The current file needs to be closed and reopened, * but we don't want to drop the file lock by calling * FileIO_Close() on it. Instead, use native close primitives. * We'll reopen it later with FileIO_Open. Set the * descriptor/handle to an invalid value while we're in the * middle of transferring ownership. */ #if defined(_WIN32) CloseHandle(currFD->win32); currFD->win32 = INVALID_HANDLE_VALUE; #else close(currFD->posix); currFD->posix = -1; #endif if (File_RenameRetry(newPath, currPath, 10) == 0) { ret = TRUE; } else { savedErrno = errno; ASSERT(!ret); } FileIO_Invalidate(&tmpFD); /* * Clear the locking bits from the requested access so that reopening * the file ignores the advisory lock. */ ASSERT((currAccess & FILEIO_OPEN_LOCK_MANDATORY) == 0); currAccess &= ~(FILEIO_OPEN_LOCK_MANDATORY | FILEIO_OPEN_LOCK_ADVISORY | FILEIO_OPEN_LOCK_BEST | FILEIO_OPEN_LOCKED); status = FileIO_Open(&tmpFD, currPath, currAccess, FILEIO_OPEN); if (!FileIO_IsSuccess(status)) { Panic("Failed to reopen dictionary after renaming " "\"%s\" to \"%s\": %s (%d)\n", newPath, currPath, FileIO_ErrorEnglish(status), status); } ASSERT(tmpFD.lockToken == NULL); #if defined(_WIN32) currFD->win32 = tmpFD.win32; #else currFD->posix = tmpFD.posix; #endif FileIO_Cleanup(&tmpFD); Unicode_Free(currPath); Unicode_Free(newPath); errno = savedErrno; return ret; } open-vm-tools-9.4.0-1280544/lib/hgfsServer/0000755765153500003110000000000012220061622016315 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/hgfsServer/hgfsServerPacketUtil.c0000644765153500003110000004332412220061556022601 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * hgfsServerPacketUtil.c -- * * Utility functions for manipulating packet used by hgfs server code */ #include #include #include #include "vmware.h" #include "hgfsServer.h" #include "hgfsServerInt.h" #include "util.h" #define LOGLEVEL_MODULE hgfs #include "loglevel_user.h" /* *----------------------------------------------------------------------------- * * HSPU_GetReplyPacket -- * * Get a reply packet given an hgfs packet. * Guest mappings may be established. * * Results: * Pointer to reply packet. * * Side effects: * Buffer may be allocated. *----------------------------------------------------------------------------- */ void * HSPU_GetReplyPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet size_t *replyPacketSize, // IN/OUT: Size of reply Packet HgfsTransportSessionInfo *transportSession) // IN: Session Info { ASSERT(transportSession); if (packet->replyPacket) { /* * When we are transferring packets over backdoor, reply packet * is a static buffer. Backdoor should always return from here. */ LOG(4, ("Existing reply packet %s %"FMTSZ"u %"FMTSZ"u\n", __FUNCTION__, *replyPacketSize, packet->replyPacketSize)); ASSERT_DEVEL(*replyPacketSize <= packet->replyPacketSize); } else if (transportSession->channelCbTable && transportSession->channelCbTable->getWriteVa) { /* Can we write directly into guest memory ? */ ASSERT_DEVEL(packet->metaPacket); if (packet->metaPacket) { LOG(10, ("%s Using meta packet for reply packet\n", __FUNCTION__)); ASSERT_DEVEL(*replyPacketSize <= packet->metaPacketSize); packet->replyPacket = packet->metaPacket; packet->replyPacketSize = packet->metaPacketSize; LOG(10, ("%s Mapping meta packet for reply packet\n", __FUNCTION__)); packet->replyPacket = HSPU_GetBuf(packet, 0, &packet->metaPacket, packet->metaPacketSize, &packet->metaPacketIsAllocated, BUF_WRITEABLE, transportSession); /* * Really this can never happen, we would have caught bad physical address * during getMetaPacket. */ ASSERT(packet->replyPacket); packet->replyPacketSize = packet->metaPacketSize; } } else { /* For sockets channel we always need to allocate buffer */ LOG(10, ("%s Allocating reply packet\n", __FUNCTION__)); packet->replyPacket = Util_SafeMalloc(*replyPacketSize); packet->replyPacketIsAllocated = TRUE; packet->replyPacketSize = *replyPacketSize; } *replyPacketSize = packet->replyPacketSize; return packet->replyPacket; } /* *----------------------------------------------------------------------------- * * HSPU_PutReplyPacket -- * * Free buffer if reply packet was allocated. * * Results: * None. * * Side effects: * None. *----------------------------------------------------------------------------- */ void HSPU_PutReplyPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet HgfsTransportSessionInfo *transportSession) // IN: Session Info { if (packet->replyPacketIsAllocated) { LOG(10, ("%s Freeing reply packet", __FUNCTION__)); free(packet->replyPacket); packet->replyPacketIsAllocated = FALSE; packet->replyPacket = NULL; packet->replyPacketSize = 0; } } /* *----------------------------------------------------------------------------- * * HSPU_GetMetaPacket -- * * Get a meta packet given an hgfs packet. * Guest mappings will be established. * * Results: * Pointer to meta packet. * * Side effects: * Buffer may be allocated. *----------------------------------------------------------------------------- */ void * HSPU_GetMetaPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet size_t *metaPacketSize, // OUT: Size of metaPacket HgfsTransportSessionInfo *transportSession) // IN: Session Info { *metaPacketSize = packet->metaPacketSize; return HSPU_GetBuf(packet, 0, &packet->metaPacket, packet->metaPacketSize, &packet->metaPacketIsAllocated, BUF_READWRITEABLE, transportSession); } /* *----------------------------------------------------------------------------- * * HSPU_GetDataPacketIov -- * * Get a data packet in an iov form given an hgfs packet. * Guest mappings will be established. * * Results: * Pointer to data packet iov. * * Side effects: * Buffer may be allocated. *----------------------------------------------------------------------------- */ void * HSPU_GetDataPacketIov(HgfsPacket *packet, // IN/OUT: Hgfs Packet HgfsTransportSessionInfo *transportSession, // IN: Session Info HgfsVaIov iov) // OUT: I/O vector { NOT_IMPLEMENTED(); return NULL; } /* *----------------------------------------------------------------------------- * * HSPU_GetDataPacketBuf -- * * Get a data packet given an hgfs packet. * Guest mappings will be established. * * Results: * Pointer to data packet. * * Side effects: * Buffer may be allocated. *----------------------------------------------------------------------------- */ void * HSPU_GetDataPacketBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet MappingType mappingType, // IN: Writeable/Readable HgfsTransportSessionInfo *transportSession) // IN: Session Info { packet->dataMappingType = mappingType; return HSPU_GetBuf(packet, packet->dataPacketIovIndex, &packet->dataPacket, packet->dataPacketSize, &packet->dataPacketIsAllocated, mappingType, transportSession); } /* *----------------------------------------------------------------------------- * * HSPU_GetBuf -- * * Get a {meta, data} packet given an hgfs packet. * Guest mappings will be established. * * Results: * Pointer to buffer. * * Side effects: * Buffer may be allocated. *----------------------------------------------------------------------------- */ void * HSPU_GetBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet uint32 startIndex, // IN: start index of iov void **buf, // OUT: Contigous buffer size_t bufSize, // IN: Size of buffer Bool *isAllocated, // OUT: Was buffer allocated ? MappingType mappingType, // IN: Readable/Writeable ? HgfsTransportSessionInfo *transportSession) // IN: Session Info { uint32 iovCount; uint32 iovMapped = 0; int32 size = bufSize; int i; void* (*func)(uint64, uint32, char **); ASSERT(buf); if (*buf) { return *buf; } else if (bufSize == 0) { return NULL; } if (!transportSession->channelCbTable) { return NULL; } if (mappingType == BUF_WRITEABLE || mappingType == BUF_READWRITEABLE) { func = transportSession->channelCbTable->getWriteVa; } else { ASSERT(mappingType == BUF_READABLE); func = transportSession->channelCbTable->getReadVa; } /* Looks like we are in the middle of poweroff. */ if (func == NULL) { return NULL; } /* Establish guest memory mappings */ for (iovCount = startIndex; iovCount < packet->iovCount && size > 0; iovCount++) { packet->iov[iovCount].token = NULL; /* Debugging check: Iov in VMCI should never cross page boundary */ ASSERT_DEVEL(packet->iov[iovCount].len <= (PAGE_SIZE - PAGE_OFFSET(packet->iov[iovCount].pa))); packet->iov[iovCount].va = func(packet->iov[iovCount].pa, packet->iov[iovCount].len, &packet->iov[iovCount].token); ASSERT_DEVEL(packet->iov[iovCount].va); if (packet->iov[iovCount].va == NULL) { /* Guest probably passed us bad physical address */ *buf = NULL; goto freeMem; } iovMapped++; size -= packet->iov[iovCount].len; } if (iovMapped > 1) { uint32 copiedAmount = 0; uint32 copyAmount; int32 remainingSize; int i; /* Seems like more than one page was requested. */ ASSERT_DEVEL(packet->iov[startIndex].len < bufSize); *buf = Util_SafeMalloc(bufSize); *isAllocated = TRUE; LOG(10, ("%s: Hgfs Allocating buffer \n", __FUNCTION__)); if (mappingType == BUF_READABLE || mappingType == BUF_READWRITEABLE) { /* * Since we are allocating seperate buffer, it does not make sense * to continue to hold on to mappings. Let's release it, we will * reacquire mappings when we need in HSPU_CopyBufToIovec. */ remainingSize = bufSize; for (i = startIndex; i < packet->iovCount && remainingSize > 0; i++) { copyAmount = remainingSize < packet->iov[i].len ? remainingSize : packet->iov[i].len; memcpy((char *)*buf + copiedAmount, packet->iov[i].va, copyAmount); copiedAmount += copyAmount; remainingSize -= copyAmount; } ASSERT_DEVEL(copiedAmount == bufSize); } } else { /* We will continue to hold on to guest mappings */ *buf = packet->iov[startIndex].va; return *buf; } freeMem: for (i = startIndex; i < iovCount; i++) { transportSession->channelCbTable->putVa(&packet->iov[i].token); packet->iov[i].va = NULL; } return *buf; } /* *----------------------------------------------------------------------------- * * HSPU_PutMetaPacket -- * * Free meta packet buffer if allocated. * Guest mappings will be released. * * Results: * void. * * Side effects: * *----------------------------------------------------------------------------- */ void HSPU_PutMetaPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet HgfsTransportSessionInfo *transportSession) // IN: Session Info { LOG(4, ("%s Hgfs Putting Meta packet\n", __FUNCTION__)); HSPU_PutBuf(packet, 0, &packet->metaPacket, &packet->metaPacketSize, &packet->metaPacketIsAllocated, BUF_WRITEABLE, transportSession); } /* *----------------------------------------------------------------------------- * * HSPU_PutDataPacketIov -- * * Free data packet Iov if allocated. * * Results: * void. * * Side effects: * Guest mappings will be released. *----------------------------------------------------------------------------- */ void HSPU_PutDataPacketIov() { NOT_IMPLEMENTED(); } /* *----------------------------------------------------------------------------- * * HSPU_PutDataPacketBuf -- * * Free data packet buffer if allocated. * Guest mappings will be released. * * Results: * void. * * Side effects: * None. *----------------------------------------------------------------------------- */ void HSPU_PutDataPacketBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet HgfsTransportSessionInfo *transportSession) // IN: Session Info { LOG(4, ("%s Hgfs Putting Data packet\n", __FUNCTION__)); HSPU_PutBuf(packet, packet->dataPacketIovIndex, &packet->dataPacket, &packet->dataPacketSize, &packet->dataPacketIsAllocated, packet->dataMappingType, transportSession); } /* *----------------------------------------------------------------------------- * * HSPU_PutBuf -- * * Free buffer if allocated and release guest mappings. * * Results: * None. * * Side effects: * None. *----------------------------------------------------------------------------- */ void HSPU_PutBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet uint32 startIndex, // IN: Start of iov void **buf, // IN/OUT: Buffer to be freed size_t *bufSize, // IN: Size of the buffer Bool *isAllocated, // IN: Was buffer allocated ? MappingType mappingType, // IN: Readable / Writeable ? HgfsTransportSessionInfo *transportSession) // IN: Session info { uint32 iovCount = 0; int size = *bufSize; ASSERT(buf); if (!transportSession->channelCbTable) { return; } if (!transportSession->channelCbTable->putVa || *buf == NULL) { return; } if (*isAllocated) { if (mappingType == BUF_WRITEABLE) { HSPU_CopyBufToIovec(packet, startIndex, *buf, *bufSize, transportSession); } LOG(10, ("%s: Hgfs Freeing buffer \n", __FUNCTION__)); free(*buf); *isAllocated = FALSE; } else { for (iovCount = startIndex; iovCount < packet->iovCount && size > 0; iovCount++) { ASSERT_DEVEL(packet->iov[iovCount].token); transportSession->channelCbTable->putVa(&packet->iov[iovCount].token); size -= packet->iov[iovCount].len; } LOG(10, ("%s: Hgfs bufSize = %d \n", __FUNCTION__, size)); ASSERT(size <= 0); } *buf = NULL; } /* *----------------------------------------------------------------------------- * * HSPU_CopyBufToMetaIovec -- * * Write out buffer to data Iovec. * * Results: * void * * Side effects: * @iov is populated with contents of @buf *----------------------------------------------------------------------------- */ void HSPU_CopyBufToMetaIovec(HgfsPacket *packet, // IN/OUT: Hgfs packet void *buf, // IN: Buffer to copy from size_t bufSize, // IN: Size of buffer HgfsTransportSessionInfo *transportSession)// IN: Session Info { HSPU_CopyBufToIovec(packet, 0, buf, bufSize, transportSession); } /* *----------------------------------------------------------------------------- * * HSPU_CopyBufToDataIovec -- * * Write out buffer to data Iovec. * * Results: * void * * Side effects: * @iov is populated with contents of @buf *----------------------------------------------------------------------------- */ void HSPU_CopyBufToDataIovec(HgfsPacket *packet, // IN: Hgfs packet void *buf, // IN: Buffer to copy from uint32 bufSize, // IN: Size of buffer HgfsTransportSessionInfo *transportSession) { HSPU_CopyBufToIovec(packet, packet->dataPacketIovIndex, buf, bufSize, transportSession); } /* *----------------------------------------------------------------------------- * * HSPU_CopyBufToDataIovec -- * * Write out buffer to data Iovec. * * Results: * void * * Side effects: * @iov is populated with contents of @buf *----------------------------------------------------------------------------- */ void HSPU_CopyBufToIovec(HgfsPacket *packet, // IN/OUT: Hgfs Packet uint32 startIndex, // IN: start index into iov void *buf, // IN: Contigous Buffer size_t bufSize, // IN: Size of buffer HgfsTransportSessionInfo *transportSession) // IN: Session Info { uint32 iovCount; size_t remainingSize = bufSize; size_t copyAmount; size_t copiedAmount = 0; ASSERT(packet); ASSERT(buf); if (!transportSession->channelCbTable) { return; } ASSERT_DEVEL(transportSession->channelCbTable->getWriteVa); if (!transportSession->channelCbTable->getWriteVa) { return; } for (iovCount = startIndex; iovCount < packet->iovCount && remainingSize > 0; iovCount++) { copyAmount = remainingSize < packet->iov[iovCount].len ? remainingSize: packet->iov[iovCount].len; packet->iov[iovCount].token = NULL; /* Debugging check: Iov in VMCI should never cross page boundary */ ASSERT_DEVEL(packet->iov[iovCount].len <= (PAGE_SIZE - PAGE_OFFSET(packet->iov[iovCount].pa))); packet->iov[iovCount].va = transportSession->channelCbTable->getWriteVa(packet->iov[iovCount].pa, packet->iov[iovCount].len, &packet->iov[iovCount].token); ASSERT_DEVEL(packet->iov[iovCount].va); if (packet->iov[iovCount].va != NULL) { memcpy(packet->iov[iovCount].va, (char *)buf + copiedAmount, copyAmount); transportSession->channelCbTable->putVa(&packet->iov[iovCount].token); remainingSize -= copyAmount; copiedAmount += copyAmount; } else { break; } } ASSERT_DEVEL(remainingSize == 0); } open-vm-tools-9.4.0-1280544/lib/hgfsServer/hgfsServer.c0000644765153500003110000103714212220061556020615 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #if defined(__APPLE__) /* * DirectoryEntry type that is used in common code is * defined as dirent for Mac OS. * _DARWIN_USE_64_BIT_INODE definition is needed to make dirent * structure definitions in this file and in HgfsServerLinux.c * consistent. */ #define _DARWIN_USE_64_BIT_INODE #endif #include #include #include "vmware.h" #include "str.h" #include "cpName.h" #include "cpNameLite.h" #include "hgfsServerInt.h" #include "hgfsServerPolicy.h" #include "hgfsUtil.h" #include "hgfsVirtualDir.h" #include "hgfsEscape.h" #include "codeset.h" #include "config.h" #include "dbllnklst.h" #include "file.h" #include "util.h" #include "wiper.h" #include "hgfsServer.h" #include "hgfsDirNotify.h" #include "hgfsTransport.h" #include "userlock.h" #include "poll.h" #include "mutexRankLib.h" #include "vm_basic_asm.h" #include "unicodeOperations.h" #if defined(_WIN32) #include #define HGFS_PARENT_DIR "..\\" #else #include #define stricmp strcasecmp #define HGFS_PARENT_DIR "../" #endif // _WIN32 #define HGFS_PARENT_DIR_LEN 3 #define LOGLEVEL_MODULE hgfs #include "loglevel_user.h" /* * Define this to enable an ASSERT on HGFS_STATUS_PROTOCOL_ERROR. * This is useful if client is to be guaranteed to work with the server * without falling back to older protocol versions and to ensure that * clients don't send op value greater than HGFS_OP_MAX. * * NOTE: This flag is only meant to be used while testing. This should * _always_ be undefined when checking code in. */ #if 0 #define HGFS_ASSERT_CLIENT(op) \ do { \ LOG(4, ("%s: op: %u.\n", __FUNCTION__, op)); \ ASSERT(status != HGFS_STATUS_PROTOCOL_ERROR); \ } while(0) #else #define HGFS_ASSERT_CLIENT(op) #endif #define HGFS_ASSERT_INPUT(input) ASSERT(input && input->packet && input->metaPacket && \ ((!input->v4header && input->session) || \ (input->v4header && \ (input->op == HGFS_OP_CREATE_SESSION_V4 || input->session))) && \ (!input->payloadSize || input->payload)) /* * Define this to enable an ASSERT if server gets an op lower than * this value. This is useful if client is to be guaranteed to work with * the server without falling back to older protocol versions. * * NOTE: This flag is only meant to be used while testing. This should * _always_ be undefined when checking code in. */ #if 0 #define HGFS_ASSERT_MINIMUM_OP(op) \ do { \ LOG(4, ("%s: op received - %u.\n", __FUNCTION__, op)); \ ASSERT(op >= HGFS_OP_OPEN_V3); \ } while(0) #else #define HGFS_ASSERT_MINIMUM_OP(op) #endif #ifdef VMX86_TOOLS #define Config_GetBool(defaultValue,fmt) (defaultValue) #endif /* * This ensures that the hgfs name conversion code never fails on long * filenames by using a buffer that is too small. If anything, we will * fail first elsewhere because the name is too big to fit in one hgfs * packet. [bac] */ #define HGFS_PATH_MAX HGFS_PACKET_MAX /* * Array of FileNodes for opening files. */ #define NUM_FILE_NODES 100 #define NUM_SEARCHES 100 /* Default maximum number of open nodes. */ #define MAX_CACHED_FILENODES 30 /* Default maximun number of open nodes that have server locks. */ #define MAX_LOCKED_FILENODES 10 /* Maximum number of cached open nodes. */ static unsigned int maxCachedOpenNodes; /* Value of config option to require using host timestamps */ Bool alwaysUseHostTime = FALSE; /* * Monotonically increasing handle counter used to dish out HgfsHandles. * This value is checkpointed. */ static Atomic_uint32 hgfsHandleCounter = {0}; /* * Number of outstanding asynchronous operations. */ static Atomic_uint32 gHgfsAsyncCounter = {0}; static MXUserExclLock *gHgfsAsyncLock; static MXUserCondVar *gHgfsAsyncVar; static HgfsServerStateLogger *hgfsMgrData = NULL; /* * Session usage and locking. * * The channel will serialize callbacks to connect, disconnect, close * and invalidate objects for sessions. * The receives will also be serialized with the above when received through * the backdoor channel. * However, when requests are received from a socket, they will be from a * worker thread. It is the responsibility of the socket channel to keep * the session alive when processing the receive request which it does by * an additional reference for the session. This means even if a disconnect * occurs and the socket is closed, the channel will not call the session * close until the hgfs server returns from the receive processing. Thus * the hgfs server session data will remain valid. * When the hgfs server processes requests asynchronously, or returns from * receive request prior to sending the reply to be done at a later time, * a reference on the session is taken out while processing the message, * and not removed until the reply is processed. This reference will ensure * the session is not torndown until the final reference is removed, even * if the close session is called from the channel. */ /* Session related callbacks. */ static void HgfsServerSessionReceive(HgfsPacket *packet, void *clientData); static Bool HgfsServerSessionConnect(void *transportData, HgfsServerChannelCallbacks *channelCbTable, uint32 channelCapabililies, void **clientData); static void HgfsServerSessionDisconnect(void *clientData); static void HgfsServerSessionClose(void *clientData); static void HgfsServerSessionInvalidateObjects(void *clientData, DblLnkLst_Links *shares); static uint32 HgfsServerSessionInvalidateInactiveSessions(void *clientData); static void HgfsServerSessionSendComplete(HgfsPacket *packet, void *clientData); /* * Callback table passed to transport and any channels. */ HgfsServerSessionCallbacks hgfsServerSessionCBTable = { HgfsServerSessionConnect, HgfsServerSessionDisconnect, HgfsServerSessionClose, HgfsServerSessionReceive, HgfsServerSessionInvalidateObjects, HgfsServerSessionInvalidateInactiveSessions, HgfsServerSessionSendComplete, }; /* Lock that protects shared folders list. */ static MXUserExclLock *gHgfsSharedFoldersLock = NULL; /* List of shared folders nodes. */ static DblLnkLst_Links gHgfsSharedFoldersList; static Bool gHgfsInitialized = FALSE; /* * Number of active sessions that support change directory notification. HGFS server * needs to maintain up-to-date shared folders list when there is * at least one such session. */ static Bool gHgfsDirNotifyActive = FALSE; typedef struct HgfsSharedFolderProperties { DblLnkLst_Links links; char *name; /* Name of the share. */ HgfsSharedFolderHandle notificationHandle; /* Directory notification handle. */ Bool markedForDeletion; } HgfsSharedFolderProperties; static void HgfsServerTransportRemoveSessionFromList(HgfsTransportSessionInfo *transportSession, HgfsSessionInfo *sessionInfo); /* * Limit payload to 16M + header. * This limit ensures that list of shared pages fits into VMCI datagram. * Client may impose a lower limit in create session request. */ #define MAX_SERVER_PACKET_SIZE_V4 (0x1000000 + sizeof(HgfsHeader)) /* Local functions. */ static void HgfsInvalidateSessionObjects(DblLnkLst_Links *shares, HgfsSessionInfo *session); static Bool HgfsAddToCacheInternal(HgfsHandle handle, HgfsSessionInfo *session); static Bool HgfsIsCachedInternal(HgfsHandle handle, HgfsSessionInfo *session); static Bool HgfsRemoveLruNode(HgfsSessionInfo *session); static Bool HgfsRemoveFromCacheInternal(HgfsHandle handle, HgfsSessionInfo *session); static void HgfsRemoveSearchInternal(HgfsSearch *search, HgfsSessionInfo *session); static HgfsSearch *HgfsSearchHandle2Search(HgfsHandle handle, HgfsSessionInfo *session); static HgfsHandle HgfsSearch2SearchHandle(HgfsSearch const *search); static HgfsSearch *HgfsAddNewSearch(char const *utf8Dir, DirectorySearchType type, char const *utf8ShareName, char const *rootDir, HgfsSessionInfo *session); static void HgfsDumpAllSearches(HgfsSessionInfo *session); static void HgfsDumpAllNodes(HgfsSessionInfo *session); static void HgfsFreeFileNode(HgfsHandle handle, HgfsSessionInfo *session); static void HgfsFreeFileNodeInternal(HgfsHandle handle, HgfsSessionInfo *session); static HgfsFileNode *HgfsAddNewFileNode(HgfsFileOpenInfo *openInfo, HgfsLocalId const *localId, fileDesc fileDesc, Bool append, size_t shareNameLen, char const *shareName, Bool sharedFolderOpen, HgfsSessionInfo *session); static void HgfsRemoveFileNode(HgfsFileNode *node, HgfsSessionInfo *session); static HgfsFileNode *HgfsGetNewNode(HgfsSessionInfo *session); static HgfsHandle HgfsFileNode2Handle(HgfsFileNode const *fileNode); static HgfsFileNode *HgfsHandle2FileNode(HgfsHandle handle, HgfsSessionInfo *session); static void HgfsServerExitSessionInternal(HgfsSessionInfo *session); static Bool HgfsIsShareRoot(char const *cpName, size_t cpNameSize); static void HgfsServerCompleteRequest(HgfsInternalStatus status, size_t replyPayloadSize, HgfsInputParam *input); static Bool HgfsHandle2NotifyInfo(HgfsHandle handle, HgfsSessionInfo *session, char **fileName, size_t *fileNameSize, HgfsSharedFolderHandle *folderHandle); static void HgfsServerDirWatchEvent(HgfsSharedFolderHandle sharedFolder, HgfsSubscriberHandle subscriber, char* fileName, uint32 mask, struct HgfsSessionInfo *session); static void HgfsFreeSearchDirents(HgfsSearch *search); /* * Opcode handlers */ static void HgfsServerOpen(HgfsInputParam *input); static void HgfsServerRead(HgfsInputParam *input); static void HgfsServerWrite(HgfsInputParam *input); static void HgfsServerSearchOpen(HgfsInputParam *input); static void HgfsServerSearchRead(HgfsInputParam *input); static void HgfsServerGetattr(HgfsInputParam *input); static void HgfsServerSetattr(HgfsInputParam *input); static void HgfsServerCreateDir(HgfsInputParam *input); static void HgfsServerDeleteFile(HgfsInputParam *input); static void HgfsServerDeleteDir(HgfsInputParam *input); static void HgfsServerRename(HgfsInputParam *input); static void HgfsServerQueryVolume(HgfsInputParam *input); static void HgfsServerSymlinkCreate(HgfsInputParam *input); static void HgfsServerServerLockChange(HgfsInputParam *input); static void HgfsServerWriteWin32Stream(HgfsInputParam *input); static void HgfsServerCreateSession(HgfsInputParam *input); static void HgfsServerDestroySession(HgfsInputParam *input); static void HgfsServerClose(HgfsInputParam *input); static void HgfsServerSearchClose(HgfsInputParam *input); static void HgfsServerSetDirNotifyWatch(HgfsInputParam *input); static void HgfsServerRemoveDirNotifyWatch(HgfsInputParam *input); /* *---------------------------------------------------------------------------- * * HgfsServerSessionGet -- * * Increment session reference count. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsServerSessionGet(HgfsSessionInfo *session) // IN: session context { ASSERT(session); Atomic_Inc(&session->refCount); } /* *---------------------------------------------------------------------------- * * HgfsServerSessionPut -- * * Decrement session reference count. * * Free session info data if no reference. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void HgfsServerSessionPut(HgfsSessionInfo *session) // IN: session context { ASSERT(session); if (Atomic_FetchAndDec(&session->refCount) == 1) { HgfsServerExitSessionInternal(session); } } /* *---------------------------------------------------------------------------- * * HgfsServerTransportSessionGet -- * * Increment transport session reference count. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsServerTransportSessionGet(HgfsTransportSessionInfo *transportSession) // IN: session context { ASSERT(transportSession); Atomic_Inc(&transportSession->refCount); } /* *---------------------------------------------------------------------------- * * HgfsServerTransportSessionPut -- * * Decrement transport session reference count. * * Free session info data if no reference. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void HgfsServerTransportSessionPut(HgfsTransportSessionInfo *transportSession) // IN: transport session context { ASSERT(transportSession); if (Atomic_FetchAndDec(&transportSession->refCount) == 1) { DblLnkLst_Links *curr, *next; MXUser_AcquireExclLock(transportSession->sessionArrayLock); DblLnkLst_ForEachSafe(curr, next, &transportSession->sessionArray) { HgfsSessionInfo *session = DblLnkLst_Container(curr, HgfsSessionInfo, links); HgfsServerTransportRemoveSessionFromList(transportSession, session); HgfsServerSessionPut(session); } MXUser_ReleaseExclLock(transportSession->sessionArrayLock); } } /* *----------------------------------------------------------------------------- * * HgfsServerInitHandleCounter -- * * Initialize the file handle counter to the new value passed. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void HgfsServerInitHandleCounter(uint32 newHandleCounter) { Atomic_Write(&hgfsHandleCounter, newHandleCounter); } /* *----------------------------------------------------------------------------- * * HgfsServerGetHandleCounter -- * * Return file handle counter. This is used by the checkpointing code to * checkpoint this value so we avoid the risk of handle collision. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static uint32 HgfsServerGetHandleCounter(void) { return Atomic_Read(&hgfsHandleCounter); } /* *----------------------------------------------------------------------------- * * HgfsServerGetNextHandleCounter -- * * Return file handle counter. This is used by the checkpointing code to * checkpoint this value so we avoid the risk of handle collision. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static uint32 HgfsServerGetNextHandleCounter(void) { uint32 count = Atomic_FetchAndInc(&hgfsHandleCounter); /* * Call server manager for logging state updates. * XXX - This will have to be reworked when the server is * more concurrent than with the current access. */ if (hgfsMgrData != NULL && hgfsMgrData->logger != NULL) { hgfsMgrData->logger(hgfsMgrData->loggerData, count + 1); } return count; } /* *----------------------------------------------------------------------------- * * HgfsHandle2FileNode -- * * Retrieve the file node a handle refers to. * * The session's nodeArrayLock should be acquired prior to calling this * function. * * Results: * The file node if the handle is valid (i.e. it refers to an existing file * node that is currently in use). * NULL if the handle is invalid. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static HgfsFileNode * HgfsHandle2FileNode(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session) // IN: Session info { unsigned int i; HgfsFileNode *fileNode = NULL; ASSERT(session); ASSERT(session->nodeArray); /* XXX: This O(n) lookup can and should be optimized. */ for (i = 0; i < session->numNodes; i++) { if (session->nodeArray[i].state != FILENODE_STATE_UNUSED && session->nodeArray[i].handle == handle) { fileNode = &session->nodeArray[i]; break; } } return fileNode; } /* *----------------------------------------------------------------------------- * * HgfsFileNode2Handle -- * * Retrieve the handle that represents a file node outside of the server. * * The session's nodeArrayLock should be acquired prior to calling this * function. * * Results: * The handle * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsHandle HgfsFileNode2Handle(HgfsFileNode const *fileNode) // IN { ASSERT(fileNode); return fileNode->handle; } /* *----------------------------------------------------------------------------- * * HgfsDumpAllNodes -- * * Debugging routine; print all nodes in the nodeArray. * * The session's nodeArrayLock should be acquired prior to calling this * function. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsDumpAllNodes(HgfsSessionInfo *session) // IN: session info { unsigned int i; ASSERT(session); ASSERT(session->nodeArray); Log("Dumping all nodes\n"); for (i = 0; i < session->numNodes; i++) { Log("handle %u, name \"%s\", localdev %"FMT64"u, localInum %"FMT64"u %u\n", session->nodeArray[i].handle, session->nodeArray[i].utf8Name ? session->nodeArray[i].utf8Name : "NULL", session->nodeArray[i].localId.volumeId, session->nodeArray[i].localId.fileId, session->nodeArray[i].fileDesc); } Log("Done\n"); } /* *----------------------------------------------------------------------------- * * HgfsHandle2FileDesc -- * * Retrieve the file descriptor (host OS file handle) based on the hgfs * handle. * * Results: * TRUE if the handle is valid and the file desc was retrieved successfully. * FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsHandle2FileDesc(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: Session info fileDesc *fd, // OUT: OS handle (file descriptor) void **fileCtx) // OUT: OS file context { Bool found = FALSE; HgfsFileNode *fileNode = NULL; MXUser_AcquireExclLock(session->nodeArrayLock); fileNode = HgfsHandle2FileNode(handle, session); if (fileNode == NULL) { goto exit; } *fd = fileNode->fileDesc; if (fileCtx) { *fileCtx = fileNode->fileCtx; } found = TRUE; exit: MXUser_ReleaseExclLock(session->nodeArrayLock); return found; } /* *----------------------------------------------------------------------------- * * HgfsHandle2AppendFlag -- * * Retrieve the append flag for the file node that corresponds to * the specified hgfs handle. * * Results: * TRUE if the handle is valid and append flag was retrieved successfully. * FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsHandle2AppendFlag(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: Session info Bool *appendFlag) // OUT: append flag { Bool found = FALSE; HgfsFileNode *fileNode = NULL; MXUser_AcquireExclLock(session->nodeArrayLock); fileNode = HgfsHandle2FileNode(handle, session); if (fileNode == NULL) { goto exit; } *appendFlag = fileNode->flags & HGFS_FILE_NODE_APPEND_FL; found = TRUE; exit: MXUser_ReleaseExclLock(session->nodeArrayLock); return found; } /* *----------------------------------------------------------------------------- * * HgfsHandle2LocalId -- * * Retrieve the local id for the file node that corresponds to * the specified hgfs handle. * * Results: * TRUE if the hgfs handle is valid and local id was retrieved successfully. * FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsHandle2LocalId(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: Session info HgfsLocalId *localId) // OUT: local id info { Bool found = FALSE; HgfsFileNode *fileNode = NULL; ASSERT(localId); MXUser_AcquireExclLock(session->nodeArrayLock); fileNode = HgfsHandle2FileNode(handle, session); if (fileNode == NULL) { goto exit; } localId->volumeId = fileNode->localId.volumeId; localId->fileId = fileNode->localId.fileId; found = TRUE; exit: MXUser_ReleaseExclLock(session->nodeArrayLock); return found; } /* *----------------------------------------------------------------------------- * * HgfsHandle2ServerLock -- * * Retrieve the serverlock information for the file node that corresponds to * the specified hgfs handle. If the server is not compiled with oplock * support, we always return TRUE and HGFS_LOCK_NONE. * * Results: * TRUE if the hgfs handle is valid and the lock was retrieved successfully. * FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsHandle2ServerLock(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: Session info HgfsServerLock *lock) // OUT: Server lock { #ifdef HGFS_OPLOCKS Bool found = FALSE; HgfsFileNode *fileNode = NULL; ASSERT(lock); MXUser_AcquireExclLock(session->nodeArrayLock); fileNode = HgfsHandle2FileNode(handle, session); if (fileNode == NULL) { goto exit; } *lock = fileNode->serverLock; found = TRUE; exit: MXUser_ReleaseExclLock(session->nodeArrayLock); return found; #else *lock = HGFS_LOCK_NONE; return TRUE; #endif } /* *----------------------------------------------------------------------------- * * HgfsFileDesc2Handle -- * * Given an OS handle/fd, return file's hgfs handle. * * Results: * TRUE if the node was found. * FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsFileDesc2Handle(fileDesc fd, // IN: OS handle (file descriptor) HgfsSessionInfo *session, // IN: Session info HgfsHandle *handle) // OUT: Hgfs file handle { unsigned int i; Bool found = FALSE; HgfsFileNode *existingFileNode = NULL; ASSERT(session); ASSERT(session->nodeArray); MXUser_AcquireExclLock(session->nodeArrayLock); for (i = 0; i < session->numNodes; i++) { existingFileNode = &session->nodeArray[i]; if ((existingFileNode->state == FILENODE_STATE_IN_USE_CACHED) && (existingFileNode->fileDesc == fd)) { *handle = HgfsFileNode2Handle(existingFileNode); found = TRUE; break; } } MXUser_ReleaseExclLock(session->nodeArrayLock); return found; } /* *----------------------------------------------------------------------------- * * HgfsHandle2ShareMode -- * * Given an OS handle/fd, return the share access mode. * * Results: * TRUE if the node was found. * FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsHandle2ShareMode(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: Session info HgfsOpenMode *shareMode) // OUT:share access mode { Bool found = FALSE; HgfsFileNode *existingFileNode = NULL; HgfsNameStatus nameStatus; if (shareMode == NULL) { return found; } MXUser_AcquireExclLock(session->nodeArrayLock); existingFileNode = HgfsHandle2FileNode(handle, session); if (existingFileNode == NULL) { goto exit_unlock; } nameStatus = HgfsServerPolicy_GetShareMode(existingFileNode->shareName, existingFileNode->shareNameLen, shareMode); found = (nameStatus == HGFS_NAME_STATUS_COMPLETE); exit_unlock: MXUser_ReleaseExclLock(session->nodeArrayLock); return found; } /* *----------------------------------------------------------------------------- * * HgfsHandle2FileName -- * * Given an OS handle/fd, return file's hgfs name. * * Results: * TRUE if the node was found. * FALSE otherwise. * * Side effects: * Allocates memory and makes a copy of the file name. * *----------------------------------------------------------------------------- */ Bool HgfsHandle2FileName(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session,// IN: Session info char **fileName, // OUT: UTF8 file name size_t *fileNameSize) // OUT: UTF8 file name size { Bool unused1, unused2; return HgfsHandle2FileNameMode(handle, session, &unused1, &unused2, fileName, fileNameSize); } /* *----------------------------------------------------------------------------- * * HgfsHandle2FileNameMode -- * * Given an OS handle/fd, return file's hgfs name and permissions * associated with the corresponding shared folder. * * Results: * TRUE if the node was found. * FALSE otherwise. * * Side effects: * Allocates memory and makes a copy of the file name. * *----------------------------------------------------------------------------- */ Bool HgfsHandle2FileNameMode(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session,// IN: Session info Bool *readPermissions, // OUT: shared folder permissions Bool *writePermissions, // OUT: shared folder permissions char **fileName, // OUT: UTF8 file name size_t *fileNameSize) // OUT: UTF8 file name size { Bool found = FALSE; HgfsFileNode *existingFileNode = NULL; char *name = NULL; size_t nameSize = 0; if ((fileName == NULL) || (fileNameSize == NULL)) { return found; } MXUser_AcquireExclLock(session->nodeArrayLock); existingFileNode = HgfsHandle2FileNode(handle, session); if (existingFileNode == NULL) { goto exit_unlock; } name = malloc(existingFileNode->utf8NameLen + 1); if (name == NULL) { goto exit_unlock; } *readPermissions = existingFileNode->shareInfo.readPermissions; *writePermissions = existingFileNode->shareInfo.writePermissions; nameSize = existingFileNode->utf8NameLen; memcpy(name, existingFileNode->utf8Name, nameSize); name[nameSize] = '\0'; found = TRUE; exit_unlock: MXUser_ReleaseExclLock(session->nodeArrayLock); *fileName = name; *fileNameSize = nameSize; return found; } /* *----------------------------------------------------------------------------- * * HgfsHandle2FileNameMode -- * * Given an OS handle/fd, return information needed for directory * notification package: relative to the root share file name and * shared folder notification handle. * * Results: * TRUE if the node was found. * FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsHandle2NotifyInfo(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: Session info char **fileName, // OUT: UTF8 file name size_t *fileNameSize, // OUT: UTF8 file name size HgfsSharedFolderHandle *folderHandle) // OUT: shared folder handle { Bool found = FALSE; HgfsFileNode *existingFileNode; char *name; size_t nameSize; ASSERT(fileName != NULL && fileNameSize != NULL); MXUser_AcquireExclLock(session->nodeArrayLock); existingFileNode = HgfsHandle2FileNode(handle, session); if (NULL != existingFileNode) { nameSize = existingFileNode->utf8NameLen - existingFileNode->shareInfo.rootDirLen; name = Util_SafeMalloc(nameSize + 1); *folderHandle = existingFileNode->shareInfo.handle; memcpy(name, existingFileNode->utf8Name, nameSize); name[nameSize] = '\0'; *fileName = name; *fileNameSize = nameSize; found = TRUE; } MXUser_ReleaseExclLock(session->nodeArrayLock); return found; } /* *----------------------------------------------------------------------------- * * HgfsFileHasServerLock -- * * Check if the file with the given name is already opened with a server * lock on it. If the server is compiled without oplock support, we always * return FALSE. * * Results: * TRUE if the node was found and has an oplock. * FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsFileHasServerLock(const char *utf8Name, // IN: Name in UTF8 HgfsSessionInfo *session, // IN: Session info HgfsServerLock *serverLock, // OUT: Existing oplock fileDesc *fileDesc) // OUT: Existing fd { #ifdef HGFS_OPLOCKS unsigned int i; Bool found = FALSE; ASSERT(utf8Name); ASSERT(session); ASSERT(session->nodeArray); MXUser_AcquireExclLock(session->nodeArrayLock); for (i = 0; i < session->numNodes; i++) { HgfsFileNode *existingFileNode = &session->nodeArray[i]; if ((existingFileNode->state == FILENODE_STATE_IN_USE_CACHED) && (existingFileNode->serverLock != HGFS_LOCK_NONE) && (!stricmp(existingFileNode->utf8Name, utf8Name))) { LOG(4, ("Found file with a lock: %s\n", utf8Name)); *serverLock = existingFileNode->serverLock; *fileDesc = existingFileNode->fileDesc; found = TRUE; break; } } MXUser_ReleaseExclLock(session->nodeArrayLock); return found; #else return FALSE; #endif } /* *----------------------------------------------------------------------------- * * HgfsGetNodeCopy -- * * Make a copy of the node. The node should not be kept around for long, as * the data might become stale. This is mostly a convenience function to get * node fields more efficiently. * * Results: * TRUE if the hgfs handle is valid and the copy was successful. * FALSE otherwise. * * Side effects: * Allocates memory for node.utf8Name if copyName was set to TRUE. * *----------------------------------------------------------------------------- */ Bool HgfsGetNodeCopy(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: Session info Bool copyName, // IN: Should we copy the name? HgfsFileNode *copy) // IN/OUT: Copy of the node { HgfsFileNode *original = NULL; Bool found = FALSE; ASSERT(copy); MXUser_AcquireExclLock(session->nodeArrayLock); original = HgfsHandle2FileNode(handle, session); if (original == NULL) { goto exit; } if (copyName) { copy->utf8Name = malloc(original->utf8NameLen + 1); if (copy->utf8Name == NULL) { goto exit; } copy->utf8NameLen = original->utf8NameLen; memcpy(copy->utf8Name, original->utf8Name, copy->utf8NameLen); copy->utf8Name[copy->utf8NameLen] = '\0'; } else { copy->utf8Name = NULL; copy->utf8NameLen = 0; } copy->localId = original->localId; copy->fileDesc = original->fileDesc; copy->mode = original->mode; copy->shareAccess = original->shareAccess; copy->flags = original->flags; copy->state = original->state; copy->handle = original->handle; copy->fileCtx = original->fileCtx; found = TRUE; exit: MXUser_ReleaseExclLock(session->nodeArrayLock); return found; } /* *---------------------------------------------------------------------------- * * HgfsHandleIsSequentialOpen -- * * Get the Hgfs open mode this handle was originally opened with. * * Results: * TRUE on success, FALSE on failure. sequentialOpen is filled in on * success. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool HgfsHandleIsSequentialOpen(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: Session info Bool *sequentialOpen) // OUT: If open was sequential { HgfsFileNode *node; Bool success = FALSE; ASSERT(sequentialOpen); MXUser_AcquireExclLock(session->nodeArrayLock); node = HgfsHandle2FileNode(handle, session); if (node == NULL) { goto exit; } *sequentialOpen = node->flags & HGFS_FILE_NODE_SEQUENTIAL_FL; success = TRUE; exit: MXUser_ReleaseExclLock(session->nodeArrayLock); return success; } /* *---------------------------------------------------------------------------- * * HgfsHandleIsSharedFolderOpen -- * * Find if this is a shared folder open. * * Results: * TRUE on success, FALSE on failure. sharedFolderOpen is filled in on * success. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool HgfsHandleIsSharedFolderOpen(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: Session info Bool *sharedFolderOpen) // OUT: If shared folder { HgfsFileNode *node; Bool success = FALSE; ASSERT(sharedFolderOpen); MXUser_AcquireExclLock(session->nodeArrayLock); node = HgfsHandle2FileNode(handle, session); if (node == NULL) { goto exit; } *sharedFolderOpen = node->flags & HGFS_FILE_NODE_SHARED_FOLDER_OPEN_FL; success = TRUE; exit: MXUser_ReleaseExclLock(session->nodeArrayLock); return success; } /* *----------------------------------------------------------------------------- * * HgfsUpdateNodeFileDesc -- * * Given a hgfs file handle, update the node with the new file desc (OS * handle) information. * * Results: * TRUE if the update is successful. * FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsUpdateNodeFileDesc(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: Session info fileDesc fd, // IN: OS handle (file desc) void *fileCtx) // IN: OS file context { HgfsFileNode *node; Bool updated = FALSE; MXUser_AcquireExclLock(session->nodeArrayLock); node = HgfsHandle2FileNode(handle, session); if (node == NULL) { goto exit; } node->fileDesc = fd; node->fileCtx = fileCtx; updated = TRUE; exit: MXUser_ReleaseExclLock(session->nodeArrayLock); return updated; } /* *----------------------------------------------------------------------------- * * HgfsUpdateNodeServerLock -- * * Given a file desc (OS handle), update the node with the new oplock * information. * * Results: * TRUE if the update is successful. * FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsUpdateNodeServerLock(fileDesc fd, // IN: OS handle HgfsSessionInfo *session, // IN: Session info HgfsServerLock serverLock) // IN: new oplock { unsigned int i; HgfsFileNode *existingFileNode = NULL; Bool updated = FALSE; ASSERT(session); ASSERT(session->nodeArray); MXUser_AcquireExclLock(session->nodeArrayLock); for (i = 0; i < session->numNodes; i++) { existingFileNode = &session->nodeArray[i]; if (existingFileNode->state != FILENODE_STATE_UNUSED) { if (existingFileNode->fileDesc == fd) { existingFileNode->serverLock = serverLock; updated = TRUE; break; } } } MXUser_ReleaseExclLock(session->nodeArrayLock); return updated; } /* *----------------------------------------------------------------------------- * * HgfsUpdateNodeAppendFlag -- * * Given a hgfs file handle, update the node with the append flag info. * * Results: * TRUE if the update is successful. * FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsUpdateNodeAppendFlag(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: Session info Bool appendFlag) // OUT: Append flag { HgfsFileNode *node; Bool updated = FALSE; MXUser_AcquireExclLock(session->nodeArrayLock); node = HgfsHandle2FileNode(handle, session); if (node == NULL) { goto exit; } if (appendFlag) { node->flags |= HGFS_FILE_NODE_APPEND_FL; } updated = TRUE; exit: MXUser_ReleaseExclLock(session->nodeArrayLock); return updated; } /* *----------------------------------------------------------------------------- * * HgfsServerCheckOpenFlagsForShare -- * * Given an open mode check this is compatible with the mode for * the share upon which the open file resides. * * If the share is read only and mode is HGFS_OPEN_CREATE we remap * it to HGFS_OPEN which is allowed if the file exists. * * Results: * TRUE if the mode is compatible. * FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsServerCheckOpenFlagsForShare(HgfsFileOpenInfo *openInfo,// IN: Hgfs file handle HgfsOpenFlags *flags) // IN/OUT: open mode { Bool status = TRUE; HgfsNameStatus nameStatus; HgfsOpenMode shareMode; char const *inEnd; char const *next; int len; ASSERT(openInfo); ASSERT(flags); inEnd = openInfo->cpName + openInfo->cpNameSize; /* The share name is the first component of the cross-platform name. */ len = CPName_GetComponent(openInfo->cpName, inEnd, &next); if (len < 0) { LOG(4, ("%s: get first component failed\n", __FUNCTION__)); status = FALSE; goto exit; } nameStatus = HgfsServerPolicy_GetShareMode(openInfo->cpName, len, &shareMode); if (nameStatus != HGFS_NAME_STATUS_COMPLETE) { status = FALSE; goto exit; } if (shareMode == HGFS_OPEN_MODE_READ_ONLY) { /* Read only share we may have work to do. */ if (*flags != HGFS_OPEN && *flags != HGFS_OPEN_CREATE) { status = FALSE; goto exit; } if (*flags == HGFS_OPEN_CREATE) { /* * Map open or create, to just open, which will fail if * if the file does not exist, which it is okay, as creating * a new file is not allowed and should be failed. */ *flags = HGFS_OPEN; } } exit: return status; } /* *----------------------------------------------------------------------------- * * HgfsDumpAllSearches -- * * Debugging routine; print all searches in the searchArray. * * Caller should hold the session's searchArrayLock. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsDumpAllSearches(HgfsSessionInfo *session) // IN: session info { unsigned int i; ASSERT(session); ASSERT(session->searchArray); Log("Dumping all searches\n"); for (i = 0; i < session->numSearches; i++) { Log("handle %u, baseDir \"%s\"\n", session->searchArray[i].handle, session->searchArray[i].utf8Dir ? session->searchArray[i].utf8Dir : "(NULL)"); } Log("Done\n"); } /* *----------------------------------------------------------------------------- * * HgfsGetNewNode -- * * Remove a node from the free list and return it. Nodes on * the free list should already be initialized. * * If the free list is empty, reallocates more memory, * initializes it appropriately, adds the new entries to the * free list, and then returns one off the free list. * * The session's nodeArrayLock should be acquired prior to calling this * function. * * Results: * An unused file node on success * NULL on failure * * Side effects: * Memory allocation (potentially). * *----------------------------------------------------------------------------- */ static HgfsFileNode * HgfsGetNewNode(HgfsSessionInfo *session) // IN: session info { HgfsFileNode *node; HgfsFileNode *newMem; unsigned int newNumNodes; unsigned int i; ASSERT(session); ASSERT(session->nodeArray); LOG(4, ("%s: entered\n", __FUNCTION__)); if (!DblLnkLst_IsLinked(&session->nodeFreeList)) { /* * This has to be unsigned and with maximum bit length. This is * required to take care of "negative" differences as well. */ uintptr_t ptrDiff; if (DOLOG(4)) { Log("Dumping nodes before realloc\n"); HgfsDumpAllNodes(session); } /* Try to get twice as much memory as we had */ newNumNodes = 2 * session->numNodes; newMem = (HgfsFileNode *)realloc(session->nodeArray, newNumNodes * sizeof *(session->nodeArray)); if (!newMem) { LOG(4, ("%s: can't realloc more nodes\n", __FUNCTION__)); return NULL; } ptrDiff = (char *)newMem - (char *)session->nodeArray; if (ptrDiff) { size_t const oldSize = session->numNodes * sizeof *(session->nodeArray); /* * The portion of memory that contains all our file nodes moved. * All pointers that pointed inside the previous portion of memory * must be updated to point to the new portion of memory. * * We'll need to lock this if we multithread. */ LOG(4, ("Rebasing pointers, diff is %"FMTSZ"u, sizeof node is " "%"FMTSZ"u\n", ptrDiff, sizeof(HgfsFileNode))); LOG(4, ("old: %p new: %p\n", session->nodeArray, newMem)); ASSERT(newMem == (HgfsFileNode *)((char*)session->nodeArray + ptrDiff)); #define HgfsServerRebase(_ptr, _type) \ if ((size_t)((char *)_ptr - (char *)session->nodeArray) < oldSize) { \ _ptr = (_type *)((char *)_ptr + ptrDiff); \ } /* * Rebase the links of all file nodes */ for (i = 0; i < session->numNodes; i++) { HgfsServerRebase(newMem[i].links.prev, DblLnkLst_Links) HgfsServerRebase(newMem[i].links.next, DblLnkLst_Links) } /* * There is no need to rebase the anchor of the file node free list * because if we are here, it is empty. */ /* Rebase the anchor of the cached file nodes list. */ HgfsServerRebase(session->nodeCachedList.prev, DblLnkLst_Links) HgfsServerRebase(session->nodeCachedList.next, DblLnkLst_Links) #undef HgfsServerRebase } /* Initialize the new nodes */ LOG(4, ("numNodes was %u, now is %u\n", session->numNodes, newNumNodes)); for (i = session->numNodes; i < newNumNodes; i++) { DblLnkLst_Init(&newMem[i].links); newMem[i].state = FILENODE_STATE_UNUSED; newMem[i].utf8Name = NULL; newMem[i].utf8NameLen = 0; newMem[i].fileCtx = NULL; /* Append at the end of the list */ DblLnkLst_LinkLast(&session->nodeFreeList, &newMem[i].links); } session->nodeArray = newMem; session->numNodes = newNumNodes; if (DOLOG(4)) { Log("Dumping nodes after pointer changes\n"); HgfsDumpAllNodes(session); } } /* Remove the first item from the list */ node = DblLnkLst_Container(session->nodeFreeList.next, HgfsFileNode, links); DblLnkLst_Unlink1(&node->links); return node; } /* *----------------------------------------------------------------------------- * * HgfsRemoveFileNode -- * * Free its localname, clear its fields, return it to the free list. * * The session's nodeArrayLock should be acquired prior to calling this * function. * * Results: * None * * Side effects: * node->utf8Name is freed. * node->state is set to FILENODE_STATE_UNUSED. * *----------------------------------------------------------------------------- */ static void HgfsRemoveFileNode(HgfsFileNode *node, // IN: file node HgfsSessionInfo *session) // IN: session info { ASSERT(node); LOG(4, ("%s: handle %u, name %s, fileId %"FMT64"u\n", __FUNCTION__, HgfsFileNode2Handle(node), node->utf8Name, node->localId.fileId)); if (node->shareName) { free(node->shareName); } node->shareName = NULL; if (node->utf8Name) { free(node->utf8Name); } node->utf8Name = NULL; node->state = FILENODE_STATE_UNUSED; ASSERT(node->fileCtx == NULL); node->fileCtx = NULL; /* Prepend at the beginning of the list */ DblLnkLst_LinkFirst(&session->nodeFreeList, &node->links); } /* *----------------------------------------------------------------------------- * * HgfsFreeFileNodeInternal -- * * Free its localname, clear its fields, return it to the free list. * * The session's nodeArrayLock should be acquired prior to calling this * function. * * Results: * None * * Side effects: * node->utf8Name is freed. * node->state is set to FILENODE_STATE_UNUSED. * *----------------------------------------------------------------------------- */ static void HgfsFreeFileNodeInternal(HgfsHandle handle, // IN: Handle to free HgfsSessionInfo *session) // IN: Session info { HgfsFileNode *node = HgfsHandle2FileNode(handle, session); ASSERT(node); HgfsRemoveFileNode(node, session); } /* *----------------------------------------------------------------------------- * * HgfsFreeFileNode -- * * Free its localname, clear its fields, return it to the free list. * * Results: * None * * Side effects: * node->utf8Name is freed. * node->state is set to FILENODE_STATE_UNUSED. * *----------------------------------------------------------------------------- */ static void HgfsFreeFileNode(HgfsHandle handle, // IN: Handle to free HgfsSessionInfo *session) // IN: Session info { MXUser_AcquireExclLock(session->nodeArrayLock); HgfsFreeFileNodeInternal(handle, session); MXUser_ReleaseExclLock(session->nodeArrayLock); } /* *----------------------------------------------------------------------------- * * HgfsAddNewFileNode -- * * Gets a free node off the free list, sets its name, localId info, * file descriptor and permissions. * * The session's nodeArrayLock should be acquired prior to calling this * function. * * Results: * A pointer to the newly added node on success * NULL on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsFileNode * HgfsAddNewFileNode(HgfsFileOpenInfo *openInfo, // IN: open info struct HgfsLocalId const *localId, // IN: Local unique file ID fileDesc fileDesc, // IN: File Handle Bool append, // IN: open with append flag size_t shareNameLen, // IN: share name byte length char const *shareName, // IN: share name Bool sharedFolderOpen, // IN: shared folder only open HgfsSessionInfo *session) // IN: session info { HgfsFileNode *newNode; char* rootDir; ASSERT(openInfo); ASSERT(localId); ASSERT(session); /* This was already verified in HgfsUnpackOpenRequest... */ ASSERT(openInfo->mask & HGFS_OPEN_VALID_FILE_NAME); /* Get an unused node */ newNode = HgfsGetNewNode(session); if (!newNode) { LOG(4, ("%s: out of memory\n", __FUNCTION__)); return NULL; } /* Set new node's fields */ if (!HgfsServerGetOpenMode(openInfo, &newNode->mode)) { HgfsRemoveFileNode(newNode, session); return NULL; } /* * Save a copy of the share name so we can look up its * access mode at various times over the node's lifecycle. */ newNode->shareName = malloc(shareNameLen + 1); if (newNode->shareName == NULL) { LOG(4, ("%s: out of memory\n", __FUNCTION__)); HgfsRemoveFileNode(newNode, session); return NULL; } memcpy(newNode->shareName, shareName, shareNameLen); newNode->shareName[shareNameLen] = '\0'; newNode->shareNameLen = shareNameLen; newNode->utf8NameLen = strlen(openInfo->utf8Name); newNode->utf8Name = malloc(newNode->utf8NameLen + 1); if (newNode->utf8Name == NULL) { LOG(4, ("%s: out of memory\n", __FUNCTION__)); HgfsRemoveFileNode(newNode, session); return NULL; } memcpy(newNode->utf8Name, openInfo->utf8Name, newNode->utf8NameLen); newNode->utf8Name[newNode->utf8NameLen] = '\0'; newNode->shareInfo.rootDirLen = strlen(openInfo->shareInfo.rootDir); rootDir = malloc(newNode->shareInfo.rootDirLen + 1); if (rootDir == NULL) { LOG(4, ("HgfsAddNewFileNode: out of memory\n")); HgfsRemoveFileNode(newNode, session); return NULL; } memcpy(rootDir, openInfo->shareInfo.rootDir, newNode->shareInfo.rootDirLen); rootDir[newNode->shareInfo.rootDirLen] = '\0'; newNode->shareInfo.rootDir = rootDir; newNode->handle = HgfsServerGetNextHandleCounter(); newNode->localId = *localId; newNode->fileDesc = fileDesc; newNode->shareAccess = (openInfo->mask & HGFS_OPEN_VALID_SHARE_ACCESS) ? openInfo->shareAccess : HGFS_DEFAULT_SHARE_ACCESS; newNode->flags = 0; if (append) { newNode->flags |= HGFS_FILE_NODE_APPEND_FL; } if (sharedFolderOpen) { newNode->flags |= HGFS_FILE_NODE_SHARED_FOLDER_OPEN_FL; } if (HGFS_OPEN_MODE_FLAGS(openInfo->mode) & HGFS_OPEN_SEQUENTIAL) { newNode->flags |= HGFS_FILE_NODE_SEQUENTIAL_FL; } newNode->serverLock = openInfo->acquiredLock; newNode->state = FILENODE_STATE_IN_USE_NOT_CACHED; newNode->shareInfo.readPermissions = openInfo->shareInfo.readPermissions; newNode->shareInfo.writePermissions = openInfo->shareInfo.writePermissions; newNode->shareInfo.handle = openInfo->shareInfo.handle; LOG(4, ("%s: got new node, handle %u\n", __FUNCTION__, HgfsFileNode2Handle(newNode))); return newNode; } /* *----------------------------------------------------------------------------- * * HgfsAddToCacheInternal -- * * Adds the node to cache. If the number of nodes in the cache exceed * the maximum number of entries then the first node is removed. The * first node should be the least recently used. * * The session's nodeArrayLock should be acquired prior to calling this * function. * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsAddToCacheInternal(HgfsHandle handle, // IN: HGFS file handle HgfsSessionInfo *session) // IN: Session info { HgfsFileNode *node; /* Check if the node is already cached. */ if (HgfsIsCachedInternal(handle, session)) { ASSERT((node = HgfsHandle2FileNode(handle, session)) && node->state == FILENODE_STATE_IN_USE_CACHED); return TRUE; } /* Remove the LRU node if the list is full. */ if (session->numCachedOpenNodes == maxCachedOpenNodes) { if (!HgfsRemoveLruNode(session)) { LOG(4, ("%s: Unable to remove LRU node from cache.\n", __FUNCTION__)); return FALSE; } } ASSERT_BUG(36244, session->numCachedOpenNodes < maxCachedOpenNodes); node = HgfsHandle2FileNode(handle, session); ASSERT(node); /* Append at the end of the list. */ DblLnkLst_LinkLast(&session->nodeCachedList, &node->links); node->state = FILENODE_STATE_IN_USE_CACHED; session->numCachedOpenNodes++; /* * Keep track of how many open nodes we have with * server locks on them. The locked file should * always be present in the node cache. So we keep * the number of the files that have locks on them * limited, and smaller than the number of maximum * nodes in the cache. */ if (node->serverLock != HGFS_LOCK_NONE) { session->numCachedLockedNodes++; } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsRemoveFromCacheInternal -- * * Remove the specified node from the cache and close the associated * file descriptor. If the node was not already in the cache then nothing * is done. * * The session's nodeArrayLock should be acquired prior to calling this * function. * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsRemoveFromCacheInternal(HgfsHandle handle, // IN: Hgfs handle to the node HgfsSessionInfo *session) // IN: Session info { HgfsFileNode *node; ASSERT(session); node = HgfsHandle2FileNode(handle, session); if (node == NULL) { LOG(4, ("%s: invalid handle.\n", __FUNCTION__)); return FALSE; } if (node->state == FILENODE_STATE_IN_USE_CACHED) { /* Unlink the node from the list of cached fileNodes. */ DblLnkLst_Unlink1(&node->links); node->state = FILENODE_STATE_IN_USE_NOT_CACHED; session->numCachedOpenNodes--; LOG(4, ("%s: cache entries %u remove node %s id %"FMT64"u fd %u .\n", __FUNCTION__, session->numCachedOpenNodes, node->utf8Name, node->localId.fileId, node->fileDesc)); /* * XXX: From this point and up in the call chain (i.e. this function and * all callers), Bool is returned instead of the HgfsInternalStatus. * HgfsCloseFile returns HgfsInternalStatus, which is far more granular, * but modifying this stack to use HgfsInternalStatus instead of Bool is * not worth it, as we'd have to #define per-platform error codes for * things like "ran out of memory", "bad file handle", etc. * * Instead, we'll just await the lobotomization of the node cache to * really fix this. */ if (HgfsCloseFile(node->fileDesc, node->fileCtx)) { LOG(4, ("%s: Could not close fd %u\n", __FUNCTION__, node->fileDesc)); return FALSE; } node->fileCtx = NULL; /* * If we have just removed the node then the number of used nodes better * be less than the max. If we didn't remove a node, it means the * node we tried to remove was not in the cache to begin with, and * we have a problem (see bug 36244). */ ASSERT(session->numCachedOpenNodes < maxCachedOpenNodes); } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsIsCachedInternal -- * * Check if the node exists in the cache. If the node is found in * the cache then move it to the end of the list. Most recently * used nodes move towards the end of the list. * * The session nodeArrayLock should be acquired prior to calling this * function. * * Results: * TRUE if the node is found in the cache. * FALSE if the node is not in the cache. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsIsCachedInternal(HgfsHandle handle, // IN: Structure representing file node HgfsSessionInfo *session) // IN: Session info { HgfsFileNode *node; ASSERT(session); node = HgfsHandle2FileNode(handle, session); if (node == NULL) { LOG(4, ("%s: invalid handle.\n", __FUNCTION__)); return FALSE; } if (node->state == FILENODE_STATE_IN_USE_CACHED) { /* * Move this node to the end of the list. */ DblLnkLst_Unlink1(&node->links); DblLnkLst_LinkLast(&session->nodeCachedList, &node->links); return TRUE; } return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsIsServerLockAllowed -- * * Check if there's room for another file node with the server lock. * If there's no room in the cache for the file with the server lock, * then the file will be opened without the lock even if the client * asked for the lock. * * * Results: * TRUE if the node is found in the cache. * FALSE if the node is not in the cache. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsIsServerLockAllowed(HgfsSessionInfo *session) // IN: session info { Bool allowed; MXUser_AcquireExclLock(session->nodeArrayLock); allowed = session->numCachedLockedNodes < MAX_LOCKED_FILENODES; MXUser_ReleaseExclLock(session->nodeArrayLock); return allowed; } /* *----------------------------------------------------------------------------- * * HgfsGetNewSearch -- * * Remove a search from the free list and return it. Searches on * the free list should already be initialized. * * If the free list is empty, reallocates more memory, * initializes it appropriately, adds the new entries to the * free list, and then returns one off the free list. * * Caller should hold the session's searchArrayLock. * * Results: * An unused search on success * NULL on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsSearch * HgfsGetNewSearch(HgfsSessionInfo *session) // IN: session info { HgfsSearch *search; HgfsSearch *newMem; unsigned int newNumSearches; unsigned int i; ASSERT(session); ASSERT(session->searchArray); LOG(4, ("%s: entered\n", __FUNCTION__)); if (!DblLnkLst_IsLinked(&session->searchFreeList)) { /* * This has to be unsigned and with maximum bit length. This is * required to take care of "negative" differences as well. */ uintptr_t ptrDiff; if (DOLOG(4)) { Log("Dumping searches before realloc\n"); HgfsDumpAllSearches(session); } /* Try to get twice as much memory as we had */ newNumSearches = 2 * session->numSearches; newMem = (HgfsSearch *)realloc(session->searchArray, newNumSearches * sizeof *(session->searchArray)); if (!newMem) { LOG(4, ("%s: can't realloc more searches\n", __FUNCTION__)); return NULL; } ptrDiff = (char *)newMem - (char *)session->searchArray; if (ptrDiff) { size_t const oldSize = session->numSearches * sizeof *(session->searchArray); /* * The portion of memory that contains all our searches moved. * All pointers that pointed inside the previous portion of memory * must be updated to point to the new portion of memory. */ LOG(4, ("Rebasing pointers, diff is %"FMTSZ"u, sizeof search is " "%"FMTSZ"u\n", ptrDiff, sizeof(HgfsSearch))); LOG(4, ("old: %p new: %p\n", session->searchArray, newMem)); ASSERT(newMem == (HgfsSearch*)((char*)session->searchArray + ptrDiff)); #define HgfsServerRebase(_ptr, _type) \ if ((size_t)((char *)_ptr - (char *)session->searchArray) < oldSize) { \ _ptr = (_type *)((char *)_ptr + ptrDiff); \ } /* * Rebase the links of all searches */ for (i = 0; i < session->numSearches; i++) { HgfsServerRebase(newMem[i].links.prev, DblLnkLst_Links) HgfsServerRebase(newMem[i].links.next, DblLnkLst_Links) } /* * There is no need to rebase the links of the search free list * because if we are here, it is empty */ #undef HgfsServerRebase } /* Initialize the new searches */ LOG(4, ("numSearches was %u, now is %u\n", session->numSearches, newNumSearches)); for (i = session->numSearches; i < newNumSearches; i++) { DblLnkLst_Init(&newMem[i].links); newMem[i].utf8Dir = NULL; newMem[i].utf8DirLen = 0; newMem[i].utf8ShareName = NULL; newMem[i].utf8ShareNameLen = 0; newMem[i].shareInfo.rootDir = NULL; newMem[i].shareInfo.rootDirLen = 0; newMem[i].dents = NULL; newMem[i].numDents = 0; /* Append at the end of the list */ DblLnkLst_LinkLast(&session->searchFreeList, &newMem[i].links); } session->searchArray = newMem; session->numSearches = newNumSearches; if (DOLOG(4)) { Log("Dumping searches after pointer changes\n"); HgfsDumpAllSearches(session); } } /* Remove the first item from the list */ search = DblLnkLst_Container(session->searchFreeList.next, HgfsSearch, links); DblLnkLst_Unlink1(&search->links); return search; } /* *----------------------------------------------------------------------------- * * HgfsSearch2SearchHandle -- * * Retrieve the handle that represents a search outside of the server. * * Caller should hold the session's searchArrayLock. * * Results: * The handle * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsHandle HgfsSearch2SearchHandle(HgfsSearch const *search) // IN { ASSERT(search); return search->handle; } /* *----------------------------------------------------------------------------- * * HgfsSearchIsBaseNameSpace -- * * Check if the search is the base of our name space, i.e. the dirents are * the shares themselves. * * Results: * TRUE if the search is the base of the name space, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool HgfsSearchIsBaseNameSpace(HgfsSearch const *search) // IN { ASSERT(search); return search->type == DIRECTORY_SEARCH_TYPE_BASE; } /* *----------------------------------------------------------------------------- * * HgfsGetSearchCopy -- * * Make a copy of the search. It should not be kept around for long, as the * data might become stale. This is mostly a convenience function to get * search fields more efficiently. * * Note that unlike HgfsGetNodeCopy, we always copy the name, and we never * copy the dents. * * Results: * TRUE if the hgfs handle is valid and the copy was successful. * FALSE otherwise. * * Side effects: * Allocates memory for search.utf8Dir * *----------------------------------------------------------------------------- */ Bool HgfsGetSearchCopy(HgfsHandle handle, // IN: Hgfs search handle HgfsSessionInfo *session, // IN: Session info HgfsSearch *copy) // IN/OUT: Copy of the search { HgfsSearch *original = NULL; Bool found = FALSE; ASSERT(copy); MXUser_AcquireExclLock(session->searchArrayLock); original = HgfsSearchHandle2Search(handle, session); if (original == NULL) { goto exit; } copy->utf8Dir = malloc(original->utf8DirLen + 1); if (copy->utf8Dir == NULL) { goto exit; } copy->utf8DirLen = original->utf8DirLen; memcpy(copy->utf8Dir, original->utf8Dir, copy->utf8DirLen); copy->utf8Dir[copy->utf8DirLen] = '\0'; copy->utf8ShareName = malloc(original->utf8ShareNameLen + 1); if (copy->utf8ShareName == NULL) { goto exit; } copy->utf8ShareNameLen = original->utf8ShareNameLen; memcpy(copy->utf8ShareName, original->utf8ShareName, copy->utf8ShareNameLen); copy->utf8ShareName[copy->utf8ShareNameLen] = '\0'; /* No dents for the copy, they consume too much memory and aren't needed. */ copy->dents = NULL; copy->numDents = 0; copy->handle = original->handle; copy->type = original->type; found = TRUE; exit: MXUser_ReleaseExclLock(session->searchArrayLock); return found; } /* *----------------------------------------------------------------------------- * * HgfsAddNewSearch -- * * Gets a free search off the free list, sets its base directory, dents, * and type. * * Caller should hold the session's searchArrayLock. * * Results: * A pointer to the newly added search on success * NULL on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsSearch * HgfsAddNewSearch(char const *utf8Dir, // IN: UTF8 name of dir to search in DirectorySearchType type, // IN: What kind of search is this? char const *utf8ShareName, // IN: Share name containing the directory char const *rootDir, // IN: Root directory for the share HgfsSessionInfo *session) // IN: Session info { HgfsSearch *newSearch; ASSERT(utf8Dir); /* Get an unused search */ newSearch = HgfsGetNewSearch(session); if (!newSearch) { LOG(4, ("%s: out of memory\n", __FUNCTION__)); return NULL; } newSearch->dents = NULL; newSearch->numDents = 0; newSearch->type = type; newSearch->handle = HgfsServerGetNextHandleCounter(); newSearch->utf8DirLen = strlen(utf8Dir); newSearch->utf8Dir = Util_SafeStrdup(utf8Dir); newSearch->utf8ShareNameLen = strlen(utf8ShareName); newSearch->utf8ShareName = Util_SafeStrdup(utf8ShareName); newSearch->shareInfo.rootDirLen = strlen(rootDir); newSearch->shareInfo.rootDir = Util_SafeStrdup(rootDir); LOG(4, ("%s: got new search, handle %u\n", __FUNCTION__, HgfsSearch2SearchHandle(newSearch))); return newSearch; } /* *----------------------------------------------------------------------------- * * HgfsFreeSearchDirents -- * * Frees all dirents and dirents pointer array. * * Caller should hold the session's searchArrayLock. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsFreeSearchDirents(HgfsSearch *search) // IN/OUT: search { unsigned int i; if (search->dents) { for (i = 0; i < search->numDents; i++) { free(search->dents[i]); } free(search->dents); } } /* *----------------------------------------------------------------------------- * * HgfsRemoveSearchInternal -- * * Destroy a search object and recycle it to the free list * * Caller should hold the session's searchArrayLock. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsRemoveSearchInternal(HgfsSearch *search, // IN: search HgfsSessionInfo *session) // IN: session info { ASSERT(search); ASSERT(session); LOG(4, ("%s: handle %u, dir %s\n", __FUNCTION__, HgfsSearch2SearchHandle(search), search->utf8Dir)); HgfsFreeSearchDirents(search); free(search->utf8Dir); free(search->utf8ShareName); free((char*)search->shareInfo.rootDir); /* Prepend at the beginning of the list */ DblLnkLst_LinkFirst(&session->searchFreeList, &search->links); } /* *----------------------------------------------------------------------------- * * HgfsRemoveSearch -- * * Wrapper around HgfsRemoveSearchInternal that first takes the lock and * converts the handle to the search itself. * * Results: * TRUE if the search was freed successfully. * FALSE if the search could not be found. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsRemoveSearch(HgfsHandle handle, // IN: search HgfsSessionInfo *session) // IN: session info { HgfsSearch *search; Bool success = FALSE; MXUser_AcquireExclLock(session->searchArrayLock); search = HgfsSearchHandle2Search(handle, session); if (search != NULL) { HgfsRemoveSearchInternal(search, session); success = TRUE; } MXUser_ReleaseExclLock(session->searchArrayLock); return success; } /* *----------------------------------------------------------------------------- * * HgfsGetSearchResult -- * * Returns a copy of the search result at the given offset. If remove is set * to TRUE, the existing result is also pruned and the remaining results * are shifted up in the result array. * * Results: * NULL if there was an error or no search results were left. * Non-NULL if result was found. Caller must free it. * * Side effects: * None * *----------------------------------------------------------------------------- */ DirectoryEntry * HgfsGetSearchResult(HgfsHandle handle, // IN: Handle to search HgfsSessionInfo *session, // IN: Session info uint32 offset, // IN: Offset to retrieve at Bool remove) // IN: If true, removes the result { HgfsSearch *search; DirectoryEntry *dent = NULL; MXUser_AcquireExclLock(session->searchArrayLock); search = HgfsSearchHandle2Search(handle, session); if (search == NULL || search->dents == NULL) { goto out; } if (offset >= search->numDents) { goto out; } /* If we're not removing the result, we need to make a copy of it. */ if (remove) { /* * We're going to shift the dents array, overwriting the dent pointer at * offset, so first we need to save said pointer so that we can return it * later to the caller. */ dent = search->dents[offset]; /* Shift up the remaining results */ memmove(&search->dents[offset], &search->dents[offset + 1], (search->numDents - (offset + 1)) * sizeof search->dents[0]); /* Decrement the number of results */ search->numDents--; } else { DirectoryEntry *originalDent; size_t nameLen; originalDent = search->dents[offset]; ASSERT(originalDent); nameLen = strlen(originalDent->d_name); /* * Make sure the name will not overrun the d_name buffer, the end of * which is also the end of the DirectoryEntry. */ ASSERT(offsetof(DirectoryEntry, d_name) + nameLen < originalDent->d_reclen); dent = malloc(originalDent->d_reclen); if (dent == NULL) { goto out; } /* * Yes, there are more members than this in a dirent. But if you look * at the top of hgfsServerInt.h, you'll see that on Windows we only * define d_reclen and d_name, as those are the only fields we need. */ dent->d_reclen = originalDent->d_reclen; memcpy(dent->d_name, originalDent->d_name, nameLen); dent->d_name[nameLen] = 0; } out: MXUser_ReleaseExclLock(session->searchArrayLock); return dent; } /* *----------------------------------------------------------------------------- * * HgfsSearchHandle2Search -- * * Retrieve the search a handle refers to. * * Results: * The search if the handle is valid (i.e. it refers to an existing search * that is currently in use) * NULL if the handle is invalid * * Caller should hold the session's searchArrayLock. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsSearch * HgfsSearchHandle2Search(HgfsHandle handle, // IN: handle HgfsSessionInfo *session) // IN: session info { unsigned int i; HgfsSearch *search = NULL; ASSERT(session); ASSERT(session->searchArray); /* XXX: This O(n) lookup can and should be optimized. */ for (i = 0; i < session->numSearches; i++) { if (!DblLnkLst_IsLinked(&session->searchArray[i].links) && session->searchArray[i].handle == handle) { search = &session->searchArray[i]; break; } } return search; } /* *----------------------------------------------------------------------------- * * HgfsUpdateNodeNames -- * * Walk the node array and update all nodes that have the old file name to * store the new file name. * * Results: * None * * Side effects: * If there isnt enough memory to accomodate the new names, those file nodes * that couldnt be updated are deleted. * *----------------------------------------------------------------------------- */ void HgfsUpdateNodeNames(const char *oldLocalName, // IN: Name of file to look for const char *newLocalName, // IN: Name to replace with HgfsSessionInfo *session) // IN: Session info { HgfsFileNode *fileNode; unsigned int i; char *newBuffer; size_t newBufferLen; ASSERT(oldLocalName); ASSERT(newLocalName); ASSERT(session); ASSERT(session->nodeArray); newBufferLen = strlen(newLocalName); MXUser_AcquireExclLock(session->nodeArrayLock); for (i = 0; i < session->numNodes; i++) { fileNode = &session->nodeArray[i]; /* If the node is on the free list, skip it. */ if (fileNode->state == FILENODE_STATE_UNUSED) { continue; } if (strcmp(fileNode->utf8Name, oldLocalName) == 0) { newBuffer = malloc(newBufferLen + 1); if (!newBuffer) { LOG(4, ("%s: Failed to update a node name.\n", __FUNCTION__)); continue; } memcpy(newBuffer, newLocalName, newBufferLen); newBuffer[newBufferLen] = '\0'; /* Update this name to the new name. */ free(fileNode->utf8Name); fileNode->utf8Name = newBuffer; fileNode->utf8NameLen = newBufferLen; } } MXUser_ReleaseExclLock(session->nodeArrayLock); } /* *----------------------------------------------------------------------------- * * HgfsServerClose -- * * Handle a Close request. * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerClose(HgfsInputParam *input) // IN: Input params { HgfsHandle file; HgfsInternalStatus status = HGFS_ERROR_SUCCESS; size_t replyPayloadSize = 0; HGFS_ASSERT_INPUT(input); if (HgfsUnpackCloseRequest(input->payload, input->payloadSize, input->op, &file)) { LOG(4, ("%s: close fh %u\n", __FUNCTION__, file)); if (!HgfsRemoveFromCache(file, input->session)) { LOG(4, ("%s: Could not remove the node from cache.\n", __FUNCTION__)); status = HGFS_ERROR_INTERNAL; } else { HgfsFreeFileNode(file, input->session); if (!HgfsPackCloseReply(input->packet, input->metaPacket, input->op, &replyPayloadSize, input->session)) { status = HGFS_ERROR_INTERNAL; } } } else { status = HGFS_ERROR_INTERNAL; } HgfsServerCompleteRequest(status, replyPayloadSize, input); } /* *----------------------------------------------------------------------------- * * HgfsServerSearchClose -- * * Handle a "Search Close" request. * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerSearchClose(HgfsInputParam *input) // IN: Input params { HgfsHandle search; HgfsInternalStatus status; size_t replyPayloadSize = 0; HGFS_ASSERT_INPUT(input); if (HgfsUnpackSearchCloseRequest(input->payload, input->payloadSize, input->op, &search)) { LOG(4, ("%s: close search #%u\n", __FUNCTION__, search)); if (HgfsRemoveSearch(search, input->session)) { if (HgfsPackSearchCloseReply(input->packet, input->metaPacket, input->op, &replyPayloadSize, input->session)) { status = HGFS_ERROR_SUCCESS; } else { status = HGFS_ERROR_INTERNAL; } } else { /* Invalid handle */ LOG(4, ("%s: invalid handle %u\n", __FUNCTION__, search)); status = HGFS_ERROR_INTERNAL; } } else { status = HGFS_ERROR_INTERNAL; } HgfsServerCompleteRequest(status, replyPayloadSize, input); } #define HGFS_SIZEOF_OP(type) (sizeof (type) + sizeof (HgfsRequest)) /* Opcode handlers, indexed by opcode */ static struct { void (*handler)(HgfsInputParam *input); /* Minimal size of the request packet */ unsigned int minReqSize; /* How do you process the request {sync, async} ? */ RequestHint reqType; } const handlers[] = { { HgfsServerOpen, sizeof (HgfsRequestOpen), REQ_SYNC }, { HgfsServerRead, sizeof (HgfsRequestRead), REQ_SYNC }, { HgfsServerWrite, sizeof (HgfsRequestWrite), REQ_SYNC }, { HgfsServerClose, sizeof (HgfsRequestClose), REQ_SYNC }, { HgfsServerSearchOpen, sizeof (HgfsRequestSearchOpen), REQ_SYNC }, { HgfsServerSearchRead, sizeof (HgfsRequestSearchRead), REQ_SYNC }, { HgfsServerSearchClose, sizeof (HgfsRequestSearchClose), REQ_SYNC }, { HgfsServerGetattr, sizeof (HgfsRequestGetattr), REQ_SYNC }, { HgfsServerSetattr, sizeof (HgfsRequestSetattr), REQ_SYNC }, { HgfsServerCreateDir, sizeof (HgfsRequestCreateDir), REQ_SYNC }, { HgfsServerDeleteFile, sizeof (HgfsRequestDelete), REQ_SYNC }, { HgfsServerDeleteDir, sizeof (HgfsRequestDelete), REQ_SYNC }, { HgfsServerRename, sizeof (HgfsRequestRename), REQ_SYNC }, { HgfsServerQueryVolume, sizeof (HgfsRequestQueryVolume), REQ_SYNC }, { HgfsServerOpen, sizeof (HgfsRequestOpenV2), REQ_SYNC }, { HgfsServerGetattr, sizeof (HgfsRequestGetattrV2), REQ_SYNC }, { HgfsServerSetattr, sizeof (HgfsRequestSetattrV2), REQ_SYNC }, { HgfsServerSearchRead, sizeof (HgfsRequestSearchReadV2), REQ_SYNC }, { HgfsServerSymlinkCreate, sizeof (HgfsRequestSymlinkCreate), REQ_SYNC }, { HgfsServerServerLockChange, sizeof (HgfsRequestServerLockChange), REQ_SYNC }, { HgfsServerCreateDir, sizeof (HgfsRequestCreateDirV2), REQ_SYNC }, { HgfsServerDeleteFile, sizeof (HgfsRequestDeleteV2), REQ_SYNC }, { HgfsServerDeleteDir, sizeof (HgfsRequestDeleteV2), REQ_SYNC }, { HgfsServerRename, sizeof (HgfsRequestRenameV2), REQ_SYNC }, { HgfsServerOpen, HGFS_SIZEOF_OP(HgfsRequestOpenV3), REQ_SYNC }, { HgfsServerRead, HGFS_SIZEOF_OP(HgfsRequestReadV3), REQ_SYNC }, { HgfsServerWrite, HGFS_SIZEOF_OP(HgfsRequestWriteV3), REQ_SYNC }, { HgfsServerClose, HGFS_SIZEOF_OP(HgfsRequestCloseV3), REQ_SYNC }, { HgfsServerSearchOpen, HGFS_SIZEOF_OP(HgfsRequestSearchOpenV3), REQ_SYNC }, { HgfsServerSearchRead, HGFS_SIZEOF_OP(HgfsRequestSearchReadV3), REQ_SYNC }, { HgfsServerSearchClose, HGFS_SIZEOF_OP(HgfsRequestSearchCloseV3), REQ_SYNC }, { HgfsServerGetattr, HGFS_SIZEOF_OP(HgfsRequestGetattrV3), REQ_SYNC }, { HgfsServerSetattr, HGFS_SIZEOF_OP(HgfsRequestSetattrV3), REQ_SYNC }, { HgfsServerCreateDir, HGFS_SIZEOF_OP(HgfsRequestCreateDirV3), REQ_SYNC }, { HgfsServerDeleteFile, HGFS_SIZEOF_OP(HgfsRequestDeleteV3), REQ_SYNC }, { HgfsServerDeleteDir, HGFS_SIZEOF_OP(HgfsRequestDeleteV3), REQ_SYNC }, { HgfsServerRename, HGFS_SIZEOF_OP(HgfsRequestRenameV3), REQ_SYNC }, { HgfsServerQueryVolume, HGFS_SIZEOF_OP(HgfsRequestQueryVolumeV3), REQ_SYNC }, { HgfsServerSymlinkCreate, HGFS_SIZEOF_OP(HgfsRequestSymlinkCreateV3), REQ_SYNC }, { HgfsServerServerLockChange, sizeof (HgfsRequestServerLockChange), REQ_SYNC }, { HgfsServerWriteWin32Stream, HGFS_SIZEOF_OP(HgfsRequestWriteWin32StreamV3), REQ_SYNC }, /* * Starting from HGFS_OP_CREATE_SESSION_V4 (all V4 commands and above) the * second field is the minimum size for actual HGFS operational request * and not the minimum size of operational request with a header. */ { HgfsServerCreateSession, offsetof(HgfsRequestCreateSessionV4, reserved), REQ_SYNC}, { HgfsServerDestroySession, offsetof(HgfsRequestDestroySessionV4, reserved), REQ_SYNC}, { HgfsServerRead, sizeof (HgfsRequestReadV3), REQ_SYNC}, { HgfsServerWrite, sizeof (HgfsRequestWriteV3), REQ_SYNC}, { HgfsServerSetDirNotifyWatch, sizeof (HgfsRequestSetWatchV4), REQ_SYNC}, { HgfsServerRemoveDirNotifyWatch, sizeof (HgfsRequestRemoveWatchV4), REQ_SYNC}, { NULL, 0, REQ_SYNC}, // No Op notify { HgfsServerSearchRead, sizeof (HgfsRequestSearchReadV4), REQ_SYNC}, }; /* *----------------------------------------------------------------------------- * * HgfsServerCompleteRequest -- * * Performs all necessary action which needed for completing HGFS request: * 1. Sends reply to the guest. * 2. Release allocated objects, mapped guest memory. * 3. Dereference objects that were referenced. * * Results: * None. * * Side effects: * Reference to Session is dropped. * *----------------------------------------------------------------------------- */ static void HgfsServerCompleteRequest(HgfsInternalStatus status, // IN: Status of the request size_t replyPayloadSize, // IN: sizeof the reply payload HgfsInputParam *input) // INOUT: request context { char *packetOut; size_t replyPacketSize; size_t replySize; if (HGFS_ERROR_SUCCESS == status) { HGFS_ASSERT_INPUT(input); } else { ASSERT(input); } if (input->v4header) { HgfsHeader *header; replySize = sizeof *header + replyPayloadSize; replyPacketSize = replySize; header = HSPU_GetReplyPacket(input->packet, &replyPacketSize, input->transportSession); packetOut = (char *)header; ASSERT_DEVEL(header && (replySize <= replyPacketSize)); if (header && (sizeof *header <= replyPacketSize)) { uint64 replySessionId = HGFS_INVALID_SESSION_ID; if (NULL != input->session) { replySessionId = input->session->sessionId; } HgfsPackReplyHeaderV4(status, replyPayloadSize, input->op, replySessionId, input->id, header); } } else { HgfsReply *reply; /* * Starting from HGFS V3 header is not included in the payload size. */ if (input->op < HGFS_OP_OPEN_V3) { replySize = MAX(replyPayloadSize, sizeof *reply); } else { replySize = sizeof *reply + replyPayloadSize; } replyPacketSize = replySize; reply = HSPU_GetReplyPacket(input->packet, &replyPacketSize, input->transportSession); packetOut = (char *)reply; ASSERT_DEVEL(reply && (replySize <= replyPacketSize)); if (reply && (sizeof *reply <= replyPacketSize)) { HgfsPackLegacyReplyHeader(status, input->id, reply); } } if (!HgfsPacketSend(input->packet, packetOut, replySize, input->transportSession, 0)) { /* Send failed. Drop the reply. */ LOG(4, ("Error sending reply\n")); } if (NULL != input->session) { HgfsServerSessionPut(input->session); } HgfsServerTransportSessionPut(input->transportSession); free(input); } /* *----------------------------------------------------------------------------- * * HgfsServerProcessRequest -- * * Dispatch an incoming packet (in packetIn) to a handler function. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerProcessRequest(void *context) { HgfsInputParam *input = (HgfsInputParam *)context; if (!input->metaPacket) { input->metaPacket = HSPU_GetMetaPacket(input->packet, &input->metaPacketSize, input->transportSession); } input->payload = (char *)input->metaPacket + input->payloadOffset; (*handlers[input->op].handler)(input); } /* *----------------------------------------------------------------------------- * * HgfsServerSessionReceive -- * * Dispatch an incoming packet (in packetIn) to a handler function. * * This function cannot fail; if something goes wrong, it returns * a packet containing only a reply header with error code. * * The handler function can send the reply packet either using * HgfsPacketSend helper functions. This function would return error * as a reply if the op handler do not return HGFS_ERROR_SUCCESS. * * NOTE: If any op handler needs to keep packetIn around for sending replies * at a later point (possibly in a different thread context), it should * make a copy of it. The validity of packetIn for the HGFS server is only * within the scope of this function. * * Definitions of Meta Packet, Data packet can be looked up in * hgfsChannelVmci.c * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerSessionReceive(HgfsPacket *packet, // IN: Hgfs Packet void *clientData) // IN: session info { HgfsTransportSessionInfo *transportSession = (HgfsTransportSessionInfo *)clientData; HgfsInternalStatus status; HgfsInputParam *input = NULL; ASSERT(transportSession); if (transportSession->state == HGFS_SESSION_STATE_CLOSED) { LOG(4, ("%s: %d: Received packet after disconnected.\n", __FUNCTION__, __LINE__)); return; } HgfsServerTransportSessionGet(transportSession); if (!HgfsParseRequest(packet, transportSession, &input, &status)) { LOG(4, ("%s: %d: Can't generate any response for the guest, just exit.\n ", __FUNCTION__, __LINE__)); HgfsServerTransportSessionPut(transportSession); return; } packet->id = input->id; HGFS_ASSERT_MINIMUM_OP(input->op); if (HGFS_ERROR_SUCCESS == status) { HGFS_ASSERT_INPUT(input); if (HgfsValidatePacket(input->metaPacket, input->metaPacketSize, input->v4header) && (input->op < ARRAYSIZE(handlers)) && (handlers[input->op].handler != NULL) && (input->metaPacketSize >= handlers[input->op].minReqSize)) { /* Initial validation passed, process the client request now. */ packet->processedAsync = packet->supportsAsync && (handlers[input->op].reqType == REQ_ASYNC); if (packet->processedAsync) { LOG(4, ("%s: %d: @@Async\n", __FUNCTION__, __LINE__)); #ifndef VMX86_TOOLS /* * Asynchronous processing is supported by the transport. * We can release mappings here and reacquire when needed. */ HSPU_PutMetaPacket(packet, transportSession); input->metaPacket = NULL; Atomic_Inc(&gHgfsAsyncCounter); /* Remove pending requests during poweroff. */ Poll_Callback(POLL_CS_MAIN, POLL_FLAG_REMOVE_AT_POWEROFF, HgfsServerProcessRequest, input, POLL_REALTIME, 1000, NULL); #else /* Tools code should never process request async. */ ASSERT(0); #endif } else { LOG(4, ("%s: %d: ##Sync\n", __FUNCTION__, __LINE__)); HgfsServerProcessRequest(input); } } else { /* * The input packet is smaller than the minimal size needed for the * operation. */ status = HGFS_ERROR_PROTOCOL; LOG(4, ("%s: %d: Possible BUG! Malformed packet.\n", __FUNCTION__, __LINE__)); } } HGFS_ASSERT_CLIENT(input->op); /* Send error if we fail to process the op. */ if (HGFS_ERROR_SUCCESS != status) { LOG(4, ("Error %d occured parsing the packet\n", (uint32)status)); HgfsServerCompleteRequest(status, 0, input); } } /* *----------------------------------------------------------------------------- * * HgfsServerTransportGetSessionInfo -- * * Scans the list of sessions and return the session with the specified * session id. * * Results: * A valid pointer to HgfsSessionInfo if there is a session with the * specified session id. NULL, otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsSessionInfo * HgfsServerTransportGetSessionInfo(HgfsTransportSessionInfo *transportSession, // IN: transport session info uint64 sessionId) // IN: session id { DblLnkLst_Links *curr; HgfsSessionInfo *session = NULL; ASSERT(transportSession); if (HGFS_INVALID_SESSION_ID == sessionId) { return NULL; } MXUser_AcquireExclLock(transportSession->sessionArrayLock); DblLnkLst_ForEach(curr, &transportSession->sessionArray) { session = DblLnkLst_Container(curr, HgfsSessionInfo, links); if (session->sessionId == sessionId) { HgfsServerSessionGet(session); break; } session = NULL; } MXUser_ReleaseExclLock(transportSession->sessionArrayLock); return session; } /* *----------------------------------------------------------------------------- * * HgfsServerTransportRemoveSessionFromList -- * * Unlinks the specified session info from the list. * * Note: The caller must acquire the sessionArrayLock in transportSession * before calling this function. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsServerTransportRemoveSessionFromList(HgfsTransportSessionInfo *transportSession, // IN: transport session info HgfsSessionInfo *session) // IN: session info { ASSERT(transportSession); ASSERT(session); DblLnkLst_Unlink1(&session->links); transportSession->numSessions--; HgfsServerSessionPut(session); } /* *----------------------------------------------------------------------------- * * HgfsServerTransportAddSessionToList -- * * Links the specified session info to the list. * * Results: * HGFS_ERROR_SUCCESS if the session is successfully added to the list, * HGFS_ERROR_TOO_MANY_SESSIONS if maximum number of sessions were already * added to the list. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsServerTransportAddSessionToList(HgfsTransportSessionInfo *transportSession, // IN: transport session info HgfsSessionInfo *session) // IN: session info { HgfsInternalStatus status = HGFS_ERROR_TOO_MANY_SESSIONS; ASSERT(transportSession); ASSERT(session); MXUser_AcquireExclLock(transportSession->sessionArrayLock); if (transportSession->numSessions == MAX_SESSION_COUNT) { goto abort; } DblLnkLst_LinkLast(&transportSession->sessionArray, &session->links); transportSession->numSessions++; HgfsServerSessionGet(session); status = HGFS_ERROR_SUCCESS; abort: MXUser_ReleaseExclLock(transportSession->sessionArrayLock); return status; } /* *----------------------------------------------------------------------------- * * HgfsServerCleanupDeletedFolders -- * * This function iterates through all shared folders and removes all * deleted shared folders, removes them from notification package and * from the folders list. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void HgfsServerCleanupDeletedFolders(void) { DblLnkLst_Links *link, *nextElem; MXUser_AcquireExclLock(gHgfsSharedFoldersLock); DblLnkLst_ForEachSafe(link, nextElem, &gHgfsSharedFoldersList) { HgfsSharedFolderProperties *folder = DblLnkLst_Container(link, HgfsSharedFolderProperties, links); if (folder->markedForDeletion) { LOG(8, ("%s: removing shared folder handle %#x\n", __FUNCTION__, folder->notificationHandle)); if (!HgfsNotify_RemoveSharedFolder(folder->notificationHandle)) { LOG(4, ("Problem removing %d shared folder handle\n", folder->notificationHandle)); } DblLnkLst_Unlink1(link); free(folder); } } MXUser_ReleaseExclLock(gHgfsSharedFoldersLock); } /* *----------------------------------------------------------------------------- * * HgfsServer_RegisterSharedFolder -- * * This is a callback function which is invoked by hgfsServerManagement * for every shared folder when something changed in shared folders * configuration. The function iterates through the list of existing * shared folders trying to locate an entry with the shareName. If the * entry is found the function returns corresponding handle. Otherwise * it creates a new entry and assigns a new handle to it. * * Currently there is no notification that a shared folder has been * deleted. The only way to find out that a shred folder is deleted * is to notice that it is not enumerated any more. Thus an explicit * "end of list" notification is needed. "sharedFolder == NULL" notifies * that enumeration is completed which allows to delete all shared * folders that were not mentioned during current enumeration. * * Results: * HgfsSharedFolderHandle for the entry. * * Side effects: * May add an entry to known shared folders list. * *----------------------------------------------------------------------------- */ HgfsSharedFolderHandle HgfsServer_RegisterSharedFolder(const char *shareName, // IN: shared folder name const char *sharePath, // IN: shared folder path Bool addFolder) // IN: add or remove folder { DblLnkLst_Links *link, *nextElem; HgfsSharedFolderHandle result = HGFS_INVALID_FOLDER_HANDLE; LOG(8, ("%s: %s, %s, %s\n", __FUNCTION__, (shareName ? shareName : "NULL"), (sharePath ? sharePath : "NULL"), (addFolder ? "add" : "remove"))); if (!gHgfsDirNotifyActive) { LOG(8, ("%s: notification disabled\n", __FUNCTION__)); goto exit; } LOG(8, ("%s: %s, %s, %s - active notification\n", __FUNCTION__, (shareName ? shareName : "NULL"), (sharePath ? sharePath : "NULL"), (addFolder ? "add" : "remove"))); if (NULL == shareName) { /* * The function is invoked with shareName NULL when all shares has been * enumerated. * Need to delete all shared folders that were marked for deletion. */ HgfsServerCleanupDeletedFolders(); goto exit; } MXUser_AcquireExclLock(gHgfsSharedFoldersLock); DblLnkLst_ForEachSafe(link, nextElem, &gHgfsSharedFoldersList) { HgfsSharedFolderProperties *folder = DblLnkLst_Container(link, HgfsSharedFolderProperties, links); if (strcmp(folder->name, shareName) == 0) { result = folder->notificationHandle; folder->markedForDeletion = !addFolder; break; } } if (addFolder && HGFS_INVALID_FOLDER_HANDLE == result) { result = HgfsNotify_AddSharedFolder(sharePath, shareName); if (HGFS_INVALID_FOLDER_HANDLE != result) { HgfsSharedFolderProperties *folder = (HgfsSharedFolderProperties *)Util_SafeMalloc(sizeof *folder); folder->notificationHandle = result; folder->name = Util_SafeStrdup(shareName); folder->markedForDeletion = FALSE; DblLnkLst_Init(&folder->links); DblLnkLst_LinkLast(&gHgfsSharedFoldersList, &folder->links); } } MXUser_ReleaseExclLock(gHgfsSharedFoldersLock); exit: LOG(8, ("%s: %s, %s, %s exit %#x\n",__FUNCTION__, (shareName ? shareName : "NULL"), (sharePath ? sharePath : "NULL"), (addFolder ? "add" : "remove"), result)); return result; } /* *----------------------------------------------------------------------------- * * HgfsServerGetShareHandle -- * * The function returns shared folder notification handle for the specified * shared folder. * * Results: * HgfsSharedFolderHandle that corresponds to the shared folder. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static HgfsSharedFolderHandle HgfsServerGetShareHandle(const char *shareName) // IN: name of the shared folder { DblLnkLst_Links *link; HgfsSharedFolderHandle result = HGFS_INVALID_FOLDER_HANDLE; if (!gHgfsDirNotifyActive) { return HGFS_INVALID_FOLDER_HANDLE; } MXUser_AcquireExclLock(gHgfsSharedFoldersLock); DblLnkLst_ForEach(link, &gHgfsSharedFoldersList) { HgfsSharedFolderProperties *folder = DblLnkLst_Container(link, HgfsSharedFolderProperties, links); if (strcmp(folder->name, shareName) == 0) { result = folder->notificationHandle; break; } } MXUser_ReleaseExclLock(gHgfsSharedFoldersLock); return result; } /* *----------------------------------------------------------------------------- * * HgfsServerGetShareName -- * * Get the share name for a shared folder handle by looking at the * requested handle, finding the matching share (if any), and returning * the share's name. * * Results: * An Bool value indicating if the result is returned. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool HgfsServerGetShareName(HgfsSharedFolderHandle sharedFolder, // IN: Notify handle size_t *shareNameLen, // OUT: Name length char **shareName) // OUT: Share name { Bool result = FALSE; DblLnkLst_Links *link; if (!gHgfsDirNotifyActive) { return FALSE; } MXUser_AcquireExclLock(gHgfsSharedFoldersLock); DblLnkLst_ForEach(link, &gHgfsSharedFoldersList) { HgfsSharedFolderProperties *folder = DblLnkLst_Container(link, HgfsSharedFolderProperties, links); if (folder->notificationHandle == sharedFolder) { *shareName = Util_SafeStrdup(folder->name); result = TRUE; *shareNameLen = strlen(*shareName); break; } } MXUser_ReleaseExclLock(gHgfsSharedFoldersLock); return result; } /* *----------------------------------------------------------------------------- * * HgfsServer_InitState -- * * Initialize the global server state * * Results: * TRUE if succeeded, FALSE if failed. * * Side effects: * Memory allocation. * *----------------------------------------------------------------------------- */ Bool HgfsServer_InitState(HgfsServerSessionCallbacks **callbackTable, // IN/OUT: our callbacks HgfsServerStateLogger *serverMgrData) // IN: mgr callback { Bool result = TRUE; ASSERT(callbackTable); /* Save any server manager data for logging state updates.*/ hgfsMgrData = serverMgrData; maxCachedOpenNodes = Config_GetLong(MAX_CACHED_FILENODES, "hgfs.fdCache.maxNodes"); alwaysUseHostTime = Config_GetBool(FALSE, "hgfs.alwaysUseHostTime"); /* * Initialize the globals for handling the active shared folders. */ gHgfsAsyncLock = NULL; gHgfsAsyncVar = NULL; Atomic_Write(&gHgfsAsyncCounter, 0); DblLnkLst_Init(&gHgfsSharedFoldersList); gHgfsSharedFoldersLock = MXUser_CreateExclLock("sharedFoldersLock", RANK_hgfsSharedFolders); if (NULL != gHgfsSharedFoldersLock) { gHgfsAsyncLock = MXUser_CreateExclLock("asyncLock", RANK_hgfsSharedFolders); if (NULL != gHgfsAsyncLock) { gHgfsAsyncVar = MXUser_CreateCondVarExclLock(gHgfsAsyncLock); if (NULL != gHgfsAsyncVar) { if (!HgfsServerPlatformInit()) { LOG(4, ("Could not initialize server platform specific \n")); result = FALSE; } } else { LOG(4, ("%s: Could not create async counter cond var.\n", __FUNCTION__)); result = FALSE; } } else { LOG(4, ("%s: Could not create async counter mutex.\n", __FUNCTION__)); result = FALSE; } } else { LOG(4, ("%s: Could not create shared folders mutex.\n", __FUNCTION__)); result = FALSE; } if (result) { *callbackTable = &hgfsServerSessionCBTable; if (Config_GetBool(TRUE, "isolation.tools.hgfs.notify.enable")) { gHgfsDirNotifyActive = HgfsNotify_Init() == HGFS_STATUS_SUCCESS; Log("%s: initialized notification %s.\n", __FUNCTION__, (gHgfsDirNotifyActive ? "active" : "inactive")); } gHgfsInitialized = TRUE; } else { HgfsServer_ExitState(); // Cleanup partially initialized state } return result; } /* *----------------------------------------------------------------------------- * * HgfsServer_ExitState -- * * Cleanup the global server state. * * This function should be called when all other HGFS threads stopped * running. Otherwise we'll be in trouble because this is where we delete * the node array lock. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsServer_ExitState(void) { gHgfsInitialized = FALSE; if (gHgfsDirNotifyActive) { HgfsNotify_Exit(); gHgfsDirNotifyActive = FALSE; Log("%s: exit notification - inactive.\n", __FUNCTION__); } if (NULL != gHgfsSharedFoldersLock) { MXUser_DestroyExclLock(gHgfsSharedFoldersLock); gHgfsSharedFoldersLock = NULL; } if (NULL != gHgfsAsyncLock) { MXUser_DestroyExclLock(gHgfsAsyncLock); gHgfsAsyncLock = NULL; } if (NULL != gHgfsAsyncVar) { MXUser_DestroyCondVar(gHgfsAsyncVar); gHgfsAsyncVar = NULL; } HgfsServerPlatformDestroy(); } /* *----------------------------------------------------------------------------- * * HgfsGenerateSessionId -- * * Generates unique session id. * * Results: * Unique 64-bit value. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static uint64 HgfsGenerateSessionId(void) { return RDTSC(); } /* *----------------------------------------------------------------------------- * * HgfsServerSetSessionCapability -- * * Sets session capability for a specific operation code. * * Results: * TRUE is the capability for the operation has been changed. * FALSE if the operation is not represented in the capabilities array. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsServerSetSessionCapability(HgfsOp op, // IN: operation code uint32 flags, // IN: flags that describe level of support HgfsSessionInfo *session) // INOUT: session to update { int i; Bool result = FALSE; for ( i = 0; i < ARRAYSIZE(session->hgfsSessionCapabilities); i++) { if (session->hgfsSessionCapabilities[i].op == op) { session->hgfsSessionCapabilities[i].flags = flags; result = TRUE; } } LOG(4, ("%s: Setting capabilitiy flags %x for op code %d %s\n", __FUNCTION__, flags, op, result ? "succeeded" : "failed")); return result; } /* *----------------------------------------------------------------------------- * * HgfsServerEnumerateSharedFolders -- * * Enumerates all exisitng shared folders and registers shared folders with * directory notification package. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool HgfsServerEnumerateSharedFolders(void) { void *state; Bool success = FALSE; LOG(8, ("%s: entered\n", __FUNCTION__)); state = HgfsServerPolicy_GetSharesInit(); if (NULL != state) { Bool done; do { char const *shareName; size_t len; success = HgfsServerPolicy_GetShares(state, &shareName, &len, &done); if (success && !done) { HgfsSharedFolderHandle handle; char const *sharePath; size_t sharePathLen; HgfsNameStatus nameStatus; nameStatus = HgfsServerPolicy_GetSharePath(shareName, len, HGFS_OPEN_MODE_READ_ONLY, &sharePathLen, &sharePath); if (HGFS_NAME_STATUS_COMPLETE == nameStatus) { LOG(8, ("%s: registering share %s path %s\n", __FUNCTION__, shareName, sharePath)); handle = HgfsServer_RegisterSharedFolder(shareName, sharePath, TRUE); success = handle != HGFS_INVALID_FOLDER_HANDLE; LOG(8, ("%s: registering share %s hnd %#x\n", __FUNCTION__, shareName, handle)); } } } while (!done && success); HgfsServerPolicy_GetSharesCleanup(state); } LOG(8, ("%s: exit %d\n", __FUNCTION__, success)); return success; } /* *----------------------------------------------------------------------------- * * HgfsServerSessionConnect -- * * Initialize a new client session. * * Allocate HgfsTransportSessionInfo and initialize it. * * Results: * TRUE on success, FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool HgfsServerSessionConnect(void *transportData, // IN: transport session context HgfsServerChannelCallbacks *channelCbTable, // IN: Channel callbacks uint32 channelCapabilities, // IN: channel capabilities void **transportSessionData) // OUT: server session context { HgfsTransportSessionInfo *transportSession; ASSERT(transportSessionData); LOG(4, ("%s: initting.\n", __FUNCTION__)); transportSession = Util_SafeCalloc(1, sizeof *transportSession); transportSession->transportData = transportData; transportSession->channelCbTable = channelCbTable; transportSession->maxPacketSize = MAX_SERVER_PACKET_SIZE_V4; transportSession->type = HGFS_SESSION_TYPE_REGULAR; transportSession->state = HGFS_SESSION_STATE_OPEN; transportSession->channelCapabilities = channelCapabilities; transportSession->numSessions = 0; transportSession->sessionArrayLock = MXUser_CreateExclLock("HgfsSessionArrayLock", RANK_hgfsSessionArrayLock); if (transportSession->sessionArrayLock == NULL) { LOG(4, ("%s: Could not create session sync mutex.\n", __FUNCTION__)); free(transportSession); return FALSE; } DblLnkLst_Init(&transportSession->sessionArray); transportSession->defaultSessionId = HGFS_INVALID_SESSION_ID; Atomic_Write(&transportSession->refCount, 0); /* Give our session a reference to hold while we are open. */ HgfsServerTransportSessionGet(transportSession); *transportSessionData = transportSession; return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsServerAllocateSession -- * * Initialize a new Hgfs session. * * Allocate HgfsSessionInfo and initialize it. Create the nodeArray and * searchArray for the session. * * Results: * TRUE on success, FALSE otherwise. * * Side effects: * Allocates and initializes new session info. * *----------------------------------------------------------------------------- */ Bool HgfsServerAllocateSession(HgfsTransportSessionInfo *transportSession, // IN: uint32 channelCapabilities, // IN: HgfsSessionInfo **sessionData) // OUT: { int i; HgfsSessionInfo *session; LOG(8, ("%s: entered\n", __FUNCTION__)); ASSERT(transportSession); session = Util_SafeCalloc(1, sizeof *session); /* * Initialize all our locks first as these can fail. */ session->fileIOLock = MXUser_CreateExclLock("HgfsFileIOLock", RANK_hgfsFileIOLock); if (session->fileIOLock == NULL) { LOG(4, ("%s: Could not create node array sync mutex.\n", __FUNCTION__)); free(session); return FALSE; } session->nodeArrayLock = MXUser_CreateExclLock("HgfsNodeArrayLock", RANK_hgfsNodeArrayLock); if (session->nodeArrayLock == NULL) { MXUser_DestroyExclLock(session->fileIOLock); LOG(4, ("%s: Could not create node array sync mutex.\n", __FUNCTION__)); free(session); return FALSE; } session->searchArrayLock = MXUser_CreateExclLock("HgfsSearchArrayLock", RANK_hgfsSearchArrayLock); if (session->searchArrayLock == NULL) { MXUser_DestroyExclLock(session->fileIOLock); MXUser_DestroyExclLock(session->nodeArrayLock); LOG(4, ("%s: Could not create search array sync mutex.\n", __FUNCTION__)); free(session); return FALSE; } session->sessionId = HgfsGenerateSessionId(); session->state = HGFS_SESSION_STATE_OPEN; DblLnkLst_Init(&session->links); session->maxPacketSize = MAX_SERVER_PACKET_SIZE_V4; session->activeNotification = FALSE; session->isInactive = TRUE; session->transportSession = transportSession; session->numInvalidationAttempts = 0; /* * Initialize the node handling components. */ DblLnkLst_Init(&session->nodeFreeList); DblLnkLst_Init(&session->nodeCachedList); /* Allocate array of FileNodes and add them to free list. */ session->numNodes = NUM_FILE_NODES; session->nodeArray = Util_SafeCalloc(session->numNodes, sizeof (HgfsFileNode)); session->numCachedOpenNodes = 0; session->numCachedLockedNodes = 0; for (i = 0; i < session->numNodes; i++) { DblLnkLst_Init(&session->nodeArray[i].links); /* Append at the end of the list. */ DblLnkLst_LinkLast(&session->nodeFreeList, &session->nodeArray[i].links); } /* * Initialize the search handling components. */ /* Initialize search freelist. */ DblLnkLst_Init(&session->searchFreeList); Atomic_Write(&session->refCount, 0); /* Give our session a reference to hold while we are open. */ HgfsServerSessionGet(session); /* Allocate array of searches and add them to free list. */ session->numSearches = NUM_SEARCHES; session->searchArray = Util_SafeCalloc(session->numSearches, sizeof (HgfsSearch)); for (i = 0; i < session->numSearches; i++) { DblLnkLst_Init(&session->searchArray[i].links); /* Append at the end of the list. */ DblLnkLst_LinkLast(&session->searchFreeList, &session->searchArray[i].links); } /* Get common to all sessions capabiities. */ HgfsServerGetDefaultCapabilities(session->hgfsSessionCapabilities, &session->numberOfCapabilities); if (channelCapabilities & HGFS_CHANNEL_SHARED_MEM) { HgfsServerSetSessionCapability(HGFS_OP_READ_FAST_V4, HGFS_REQUEST_SUPPORTED, session); HgfsServerSetSessionCapability(HGFS_OP_WRITE_FAST_V4, HGFS_REQUEST_SUPPORTED, session); if (gHgfsDirNotifyActive) { LOG(8, ("%s: notify is enabled\n", __FUNCTION__)); if (HgfsServerEnumerateSharedFolders()) { HgfsServerSetSessionCapability(HGFS_OP_SET_WATCH_V4, HGFS_REQUEST_SUPPORTED, session); HgfsServerSetSessionCapability(HGFS_OP_REMOVE_WATCH_V4, HGFS_REQUEST_SUPPORTED, session); session->activeNotification = TRUE; } else { HgfsServerSetSessionCapability(HGFS_OP_SET_WATCH_V4, HGFS_REQUEST_NOT_SUPPORTED, session); HgfsServerSetSessionCapability(HGFS_OP_REMOVE_WATCH_V4, HGFS_REQUEST_NOT_SUPPORTED, session); } LOG(8, ("%s: session notify capability is %s\n", __FUNCTION__, (session->activeNotification ? "enabled" : "disabled"))); } HgfsServerSetSessionCapability(HGFS_OP_SEARCH_READ_V4, HGFS_REQUEST_SUPPORTED, session); } *sessionData = session; LOG(8, ("%s: exit TRUE\n", __FUNCTION__)); return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsDisconnectSessionInt -- * * Disconnect a client session. * * Mark the session as closed as we are in the process of teardown * of the session. No more new requests should be processed. We would * start draining any outstanding pending operations at this point. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void HgfsDisconnectSessionInt(HgfsSessionInfo *session) // IN: session context { LOG(8, ("%s: entered\n", __FUNCTION__)); ASSERT(session); ASSERT(session->nodeArray); ASSERT(session->searchArray); if (session->activeNotification) { LOG(8, ("%s: calling notify component to disconnect\n", __FUNCTION__)); HgfsNotify_RemoveSessionSubscribers(session); } LOG(8, ("%s: exit\n", __FUNCTION__)); } /* *----------------------------------------------------------------------------- * * HgfsServerSessionDisconnect -- * * Disconnect a client session. * * Mark the session as closed as we are in the process of teardown * of the session. No more new requests should be processed. We would * start draining any outstanding pending operations at this point. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void HgfsServerSessionDisconnect(void *clientData) // IN: session context { HgfsTransportSessionInfo *transportSession = (HgfsTransportSessionInfo *)clientData; DblLnkLst_Links *curr, *next; LOG(8, ("%s: entered\n", __FUNCTION__)); ASSERT(transportSession); MXUser_AcquireExclLock(transportSession->sessionArrayLock); DblLnkLst_ForEachSafe(curr, next, &transportSession->sessionArray) { HgfsSessionInfo *session = DblLnkLst_Container(curr, HgfsSessionInfo, links); HgfsDisconnectSessionInt(session); } MXUser_ReleaseExclLock(transportSession->sessionArrayLock); transportSession->state = HGFS_SESSION_STATE_CLOSED; LOG(8, ("%s: exit\n", __FUNCTION__)); } /* *----------------------------------------------------------------------------- * * HgfsServerSessionClose -- * * Closes a client session. * * Remvoing the final reference will free the session's nodeArray * and seachArrary, and finally free the session object. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void HgfsServerSessionClose(void *clientData) // IN: session context { HgfsTransportSessionInfo *transportSession = (HgfsTransportSessionInfo *)clientData; ASSERT(transportSession); ASSERT(transportSession->state == HGFS_SESSION_STATE_CLOSED); /* Remove, typically, the last reference, will teardown everything. */ HgfsServerTransportSessionPut(transportSession); } /* *----------------------------------------------------------------------------- * * HgfsServerExitSessionInternal -- * * Destroys a session. * * Free the session's nodeArray and seachArrary. Free the session. * * The caller must have previously acquired the global sessions lock. * * Results: * TRUE on success, FALSE otherwise. * * Side effects: * Allocates new session info. * *----------------------------------------------------------------------------- */ static void HgfsServerExitSessionInternal(HgfsSessionInfo *session) // IN: session context { int i; ASSERT(session); ASSERT(session->nodeArray); ASSERT(session->searchArray); MXUser_AcquireExclLock(session->nodeArrayLock); LOG(4, ("%s: exiting.\n", __FUNCTION__)); /* Recycle all nodes that are still in use, then destroy the node pool. */ for (i = 0; i < session->numNodes; i++) { HgfsHandle handle; if (session->nodeArray[i].state == FILENODE_STATE_UNUSED) { continue; } handle = HgfsFileNode2Handle(&session->nodeArray[i]); HgfsRemoveFromCacheInternal(handle, session); HgfsFreeFileNodeInternal(handle, session); } free(session->nodeArray); session->nodeArray = NULL; MXUser_ReleaseExclLock(session->nodeArrayLock); /* * Recycle all searches that are still in use, then destroy the * search pool. */ MXUser_AcquireExclLock(session->searchArrayLock); for (i = 0; i < session->numSearches; i++) { if (DblLnkLst_IsLinked(&session->searchArray[i].links)) { continue; } HgfsRemoveSearchInternal(&session->searchArray[i], session); } free(session->searchArray); session->searchArray = NULL; MXUser_ReleaseExclLock(session->searchArrayLock); /* Teardown the locks for the sessions and destroy itself. */ MXUser_DestroyExclLock(session->nodeArrayLock); MXUser_DestroyExclLock(session->searchArrayLock); MXUser_DestroyExclLock(session->fileIOLock); free(session); } /* *----------------------------------------------------------------------------- * * HgfsServer_GetHandleCounter -- * * Return file handle counter. This is used by the checkpointing code to * checkpoint this value so we avoid the risk of handle collision. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ uint32 HgfsServer_GetHandleCounter(void) { return HgfsServerGetHandleCounter(); } /* *----------------------------------------------------------------------------- * * HgfsServer_SetHandleCounter -- * * Set the file handle counter. This is used by the checkpointing code to * restore this value so we avoid the risk of handle collision. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsServer_SetHandleCounter(uint32 newHandleCounter) { HgfsServerInitHandleCounter(newHandleCounter); } /* *---------------------------------------------------------------------------- * * HgfsServerSessionSendComplete -- * * This is called by the Transport when it is done sending the packet. * Free the buffer. If we allocate buffers per session we have the session * that the buffer belongs too. * * Results: * None. * * Side effects: * Frees the packet buffer. * *--------------------------------------------------------------------------- */ void HgfsServerSessionSendComplete(HgfsPacket *packet, // IN/OUT: Hgfs packet void *clientData) // IN: session info { HgfsTransportSessionInfo *transportSession = (HgfsTransportSessionInfo *)clientData; if (packet->guestInitiated) { HSPU_PutMetaPacket(packet, transportSession); HSPU_PutReplyPacket(packet, transportSession); HSPU_PutDataPacketBuf(packet, transportSession); } else { free(packet->metaPacket); free(packet); } } /* *---------------------------------------------------------------------------- * * HgfsServer_Quiesce -- * * The function is called when VM is about to take a snapshot and * when creation of the snapshot completed. When the freeze is TRUE the * function quiesces all asynchronous and background activity to prevent * interactions with snapshots and waits until there is no such activity. * When freeze is FALSE the function restarts background activity that * has been suspended previously. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsServer_Quiesce(Bool freeze) // IN: { if (!gHgfsInitialized) { return; } if (freeze) { /* Suspend background activity. */ if (gHgfsDirNotifyActive) { HgfsNotify_Deactivate(HGFS_NOTIFY_REASON_SERVER_SYNC); } /* Wait for outstanding asynchronous requests to complete. */ MXUser_AcquireExclLock(gHgfsAsyncLock); while (Atomic_Read(&gHgfsAsyncCounter)) { MXUser_WaitCondVarExclLock(gHgfsAsyncLock, gHgfsAsyncVar); } MXUser_ReleaseExclLock(gHgfsAsyncLock); } else { /* Resume background activity. */ if (gHgfsDirNotifyActive) { HgfsNotify_Activate(HGFS_NOTIFY_REASON_SERVER_SYNC); } } } /* *---------------------------------------------------------------------------- * * HgfsNotifyPacketSent -- * * Decrements counter of outstanding asynchronous packets * and signal conditional variable when the counter * becomes 0. * * Results: * TRUE on success, FALSE on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void HgfsNotifyPacketSent(void) { if (Atomic_FetchAndDec(&gHgfsAsyncCounter) == 1) { MXUser_AcquireExclLock(gHgfsAsyncLock); MXUser_BroadcastCondVar(gHgfsAsyncVar); MXUser_ReleaseExclLock(gHgfsAsyncLock); } } /* *---------------------------------------------------------------------------- * * HgfsPacketSend -- * * Send the packet. * * Results: * TRUE on success, FALSE on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool HgfsPacketSend(HgfsPacket *packet, // IN/OUT: Hgfs Packet char *packetOut, // IN: output buffer size_t packetOutLen, // IN: packet size HgfsTransportSessionInfo *transportSession, // IN: session info HgfsSendFlags flags) // IN: flags for how to process { Bool result = FALSE; Bool notificationNeeded = packet->guestInitiated && packet->processedAsync; ASSERT(packet); ASSERT(transportSession); if (transportSession->state == HGFS_SESSION_STATE_OPEN) { packet->replyPacketSize = packetOutLen; ASSERT(transportSession->type == HGFS_SESSION_TYPE_REGULAR); result = transportSession->channelCbTable->send(transportSession->transportData, packet, packetOut, packetOutLen, flags); } if (notificationNeeded) { HgfsNotifyPacketSent(); } return result; } /* *----------------------------------------------------------------------------- * * HgfsInvalidateSessionObjects -- * * Iterates over all nodes and searches, invalidating and removing those * that are no longer within a share. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsInvalidateSessionObjects(DblLnkLst_Links *shares, // IN: List of new shares HgfsSessionInfo *session) // IN: Session info { unsigned int i; ASSERT(shares); ASSERT(session); ASSERT(session->nodeArray); ASSERT(session->searchArray); LOG(4, ("%s: Beginning\n", __FUNCTION__)); MXUser_AcquireExclLock(session->nodeArrayLock); /* * Iterate over each node, skipping those that are unused. For each node, * if its filename is no longer within a share, remove it. */ for (i = 0; i < session->numNodes; i++) { HgfsHandle handle; DblLnkLst_Links *l; if (session->nodeArray[i].state == FILENODE_STATE_UNUSED) { continue; } handle = HgfsFileNode2Handle(&session->nodeArray[i]); LOG(4, ("%s: Examining node with fd %d (%s)\n", __FUNCTION__, handle, session->nodeArray[i].utf8Name)); /* For each share, is the node within the share? */ for (l = shares->next; l != shares; l = l->next) { HgfsSharedFolder *share; share = DblLnkLst_Container(l, HgfsSharedFolder, links); ASSERT(share); if (strcmp(session->nodeArray[i].shareInfo.rootDir, share->path) == 0) { LOG(4, ("%s: Node is still valid\n", __FUNCTION__)); break; } } /* If the node wasn't found in any share, remove it. */ if (l == shares) { LOG(4, ("%s: Node is invalid, removing\n", __FUNCTION__)); if (!HgfsRemoveFromCacheInternal(handle, session)) { LOG(4, ("%s: Could not remove node with " "fh %d from the cache.\n", __FUNCTION__, handle)); } else { HgfsFreeFileNodeInternal(handle, session); } } } MXUser_ReleaseExclLock(session->nodeArrayLock); MXUser_AcquireExclLock(session->searchArrayLock); /* * Iterate over each search, skipping those that are on the free list. For * each search, if its base name is no longer within a share, remove it. */ for (i = 0; i < session->numSearches; i++) { DblLnkLst_Links *l; if (DblLnkLst_IsLinked(&session->searchArray[i].links)) { continue; } if (HgfsSearchIsBaseNameSpace(&session->searchArray[i])) { /* Skip search of the base name space. Maybe stale but it is okay. */ continue; } LOG(4, ("%s: Examining search (%s)\n", __FUNCTION__, session->searchArray[i].utf8Dir)); /* For each share, is the search within the share? */ for (l = shares->next; l != shares; l = l->next) { HgfsSharedFolder *share; share = DblLnkLst_Container(l, HgfsSharedFolder, links); ASSERT(share); if (strcmp(session->searchArray[i].shareInfo.rootDir, share->path) == 0) { LOG(4, ("%s: Search is still valid\n", __FUNCTION__)); break; } } /* If the node wasn't found in any share, remove it. */ if (l == shares) { LOG(4, ("%s: Search is invalid, removing\n", __FUNCTION__)); HgfsRemoveSearchInternal(&session->searchArray[i], session); } } MXUser_ReleaseExclLock(session->searchArrayLock); LOG(4, ("%s: Ending\n", __FUNCTION__)); } /* *----------------------------------------------------------------------------- * * HgfsServerSessionInvalidateObjects -- * * Iterates over all sessions and invalidate session objects for the shares * removed. * * Caller guarantees that the sessions won't go away under us, so no locks * needed. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsServerSessionInvalidateObjects(void *clientData, // IN: DblLnkLst_Links *shares) // IN: List of new shares { HgfsTransportSessionInfo *transportSession = (HgfsTransportSessionInfo *)clientData; DblLnkLst_Links *curr; ASSERT(transportSession); MXUser_AcquireExclLock(transportSession->sessionArrayLock); DblLnkLst_ForEach(curr, &transportSession->sessionArray) { HgfsSessionInfo *session = DblLnkLst_Container(curr, HgfsSessionInfo, links); HgfsServerSessionGet(session); HgfsInvalidateSessionObjects(shares, session); HgfsServerSessionPut(session); } MXUser_ReleaseExclLock(transportSession->sessionArrayLock); } /* *----------------------------------------------------------------------------- * * HgfsServerSessionInvalidateInactiveSessions -- * * Iterates over all sessions and invalidate all inactive session objects. * * Following clock algorithm is used to determine whether the session object * is inactive or not. * * When this function is called, the HGFS server manager will iterate * over all the sessions belonging to this manager. Each session is marked * as inactive. Whenever a message is processed for a session, that * session is marked as active. When this function is called the next time, * any sessions that are still inactive will be invalidated. * * Caller guarantees that the sessions won't go away under us, so no locks * needed. * * Results: * Number of active sessions remaining inside the HGFS server. * * Side effects: * None * *----------------------------------------------------------------------------- */ uint32 HgfsServerSessionInvalidateInactiveSessions(void *clientData) // IN: { HgfsTransportSessionInfo *transportSession = (HgfsTransportSessionInfo *)clientData; uint32 numActiveSessionsLeft = 0; DblLnkLst_Links shares, *curr, *next; ASSERT(transportSession); MXUser_AcquireExclLock(transportSession->sessionArrayLock); DblLnkLst_Init(&shares); DblLnkLst_ForEachSafe(curr, next, &transportSession->sessionArray) { HgfsSessionInfo *session = DblLnkLst_Container(curr, HgfsSessionInfo, links); HgfsServerSessionGet(session); session->numInvalidationAttempts++; numActiveSessionsLeft++; /* * Check if the session is inactive. If the session is inactive, then * invalidate the session objects. */ if (session->isInactive) { if (session->numInvalidationAttempts == MAX_SESSION_INVALIDATION_ATTEMPTS) { HgfsServerTransportRemoveSessionFromList(transportSession, session); /* * We need to reduce the refcount by 1 since we want to * destroy the session. */ numActiveSessionsLeft--; HgfsServerSessionPut(session); } else { HgfsInvalidateSessionObjects(&shares, session); } } else { session->isInactive = TRUE; session->numInvalidationAttempts = 0; } HgfsServerSessionPut(session); } MXUser_ReleaseExclLock(transportSession->sessionArrayLock); return numActiveSessionsLeft; } /* *----------------------------------------------------------------------------- * * HgfsServerStatFs -- * * Calls on the wiper library to return the number of free bytes and * total bytes on the filesystem underlying the given pathname. * * Results: * TRUE if successful: freeBytes and totalBytes have been written to. * FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsServerStatFs(const char *pathName, // IN: Path we're interested in size_t pathLength, // IN: Length of path uint64 *freeBytes, // OUT: Free bytes on volume uint64 *totalBytes) // OUT: Total bytes on volume { WiperPartition p; unsigned char *wiperError; ASSERT(pathName); ASSERT(freeBytes); ASSERT(totalBytes); Wiper_Init(NULL); /* * Sanity checks. If length is good, assume well-formed drive path * (i.e. "C:\..." or "\\abc..."). Note that we throw out shares that * exactly equal p.mountPoint's size because we won't have room for a null * delimiter on copy. Allow 0 length drives so that hidden feature "" can * work. */ if (pathLength >= sizeof p.mountPoint) { LOG(4, ("%s: could not get the volume name\n", __FUNCTION__)); return FALSE; } /* Now call the wiper lib to get space information. */ Str_Strcpy(p.mountPoint, pathName, sizeof p.mountPoint); wiperError = WiperSinglePartition_GetSpace(&p, freeBytes, totalBytes); if (strlen(wiperError) > 0) { LOG(4, ("%s: error using wiper lib: %s\n", __FUNCTION__, wiperError)); return FALSE; } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsServerGetShareInfo -- * * Construct local name based on the crossplatform CPName for the file. * The name returned is allocated and must be freed by the caller. * * outLen can be NULL, in which case the length is not returned. * * Results: * A status code indicating either success (correspondent share exists) or * a failure status. * * Side effects: * Memory allocation in the success case * *----------------------------------------------------------------------------- */ HgfsNameStatus HgfsServerGetShareInfo(char *cpName, // IN: Cross-platform filename to check size_t cpNameSize, // IN: Size of name cpName uint32 caseFlags, // IN: Case-sensitivity flags HgfsShareInfo *shareInfo,// OUT: properties of the shared folder char **bufOut, // OUT: File name in local fs size_t *outLen) // OUT: Length of name out { HgfsNameStatus nameStatus; char const *inEnd; char *next; char *myBufOut; char *convertedMyBufOut; char *out; size_t outSize; size_t myBufOutLen; size_t convertedMyBufOutLen; int len; uint32 pathNameLen; char tempBuf[HGFS_PATH_MAX]; size_t tempSize; char *tempPtr; uint32 startIndex = 0; HgfsShareOptions shareOptions; ASSERT(cpName); ASSERT(bufOut); inEnd = cpName + cpNameSize; if (!Unicode_IsBufferValid(cpName, cpNameSize, STRING_ENCODING_UTF8)) { LOG(4, ("%s: invalid UTF8 string @ %p\n", __FUNCTION__, cpName)); return HGFS_NAME_STATUS_FAILURE; } /* * Get first component. */ len = CPName_GetComponent(cpName, inEnd, (char const **) &next); if (len < 0) { LOG(4, ("%s: get first component failed\n", __FUNCTION__)); return HGFS_NAME_STATUS_FAILURE; } /* See if we are dealing with the base of the namespace */ if (!len) { return HGFS_NAME_STATUS_INCOMPLETE_BASE; } /* Check permission on the share and get the share path */ nameStatus = HgfsServerPolicy_ProcessCPName(cpName, len, &shareInfo->readPermissions, &shareInfo->writePermissions, &shareInfo->handle, &shareInfo->rootDir); if (nameStatus != HGFS_NAME_STATUS_COMPLETE) { LOG(4, ("%s: No such share (%s)\n", __FUNCTION__, cpName)); return nameStatus; } shareInfo->rootDirLen = strlen(shareInfo->rootDir); /* Get the config options. */ nameStatus = HgfsServerPolicy_GetShareOptions(cpName, len, &shareOptions); if (nameStatus != HGFS_NAME_STATUS_COMPLETE) { LOG(4, ("%s: no matching share: %s.\n", __FUNCTION__, cpName)); return nameStatus; } /* Point to the next component, if any */ cpNameSize -= next - cpName; cpName = next; /* * Allocate space for the string. We trim the unused space later. */ outSize = HGFS_PATH_MAX; myBufOut = (char *) malloc(outSize * sizeof *myBufOut); if (!myBufOut) { LOG(4, ("%s: out of memory allocating string\n", __FUNCTION__)); return HGFS_NAME_STATUS_OUT_OF_MEMORY; } out = myBufOut; /* * See if we are dealing with a "root" share or regular share */ if (shareInfo->rootDirLen == 0) { size_t prefixLen; /* * This is a "root" share. Interpret the input appropriately as * either a drive letter or UNC name and append it to the output * buffer (for Win32) or simply get the prefix for root (for * linux). */ tempSize = sizeof tempBuf; tempPtr = tempBuf; nameStatus = CPName_ConvertFromRoot((char const **) &cpName, &cpNameSize, &tempSize, &tempPtr); if (nameStatus != HGFS_NAME_STATUS_COMPLETE) { LOG(4, ("%s: ConvertFromRoot not complete\n", __FUNCTION__)); goto error; } prefixLen = tempPtr - tempBuf; /* Copy the UTF8 prefix to the output buffer. */ if (prefixLen >= HGFS_PATH_MAX) { Log("%s: error: prefix too long\n", __FUNCTION__); nameStatus = HGFS_NAME_STATUS_TOO_LONG; goto error; } memcpy(out, tempBuf, prefixLen); out += prefixLen; *out = 0; outSize -= prefixLen; } else { /* * This is a regular share. Append the path to the out buffer. */ if (outSize < shareInfo->rootDirLen + 1) { LOG(4, ("%s: share path too big\n", __FUNCTION__)); nameStatus = HGFS_NAME_STATUS_TOO_LONG; goto error; } memcpy(out, shareInfo->rootDir, shareInfo->rootDirLen + 1); out += shareInfo->rootDirLen; outSize -= shareInfo->rootDirLen; } /* Convert the rest of the input name (if any) to a local name */ tempSize = sizeof tempBuf; tempPtr = tempBuf; if (CPName_ConvertFrom((char const **) &cpName, &cpNameSize, &tempSize, &tempPtr) < 0) { LOG(4, ("%s: CP name conversion failed\n", __FUNCTION__)); nameStatus = HGFS_NAME_STATUS_FAILURE; goto error; } /* * For volume root directory shares the prefix will have a trailing * separator and since our remaining paths start with a separator, we * will skip over the second separator for this case. Bug 166755. */ if ((out != myBufOut) && (*(out - 1) == DIRSEPC) && (tempBuf[0] == DIRSEPC)) { startIndex++; } pathNameLen = tempPtr - &tempBuf[startIndex]; /* Copy UTF8 to the output buffer. */ if (pathNameLen >= outSize) { LOG(4, ("%s: pathname too long\n", __FUNCTION__)); nameStatus = HGFS_NAME_STATUS_TOO_LONG; goto error; } memcpy(out, &tempBuf[startIndex], pathNameLen); outSize -= pathNameLen; out += pathNameLen; *out = 0; myBufOutLen = out - myBufOut; #if defined(__APPLE__) { size_t nameLen; /* * For Mac hosts the unicode format is decomposed (form D) * so there is a need to convert the incoming name from HGFS clients * which is assumed to be in the normalized form C (precomposed). */ if (!CodeSet_Utf8FormCToUtf8FormD(myBufOut, myBufOutLen, &tempPtr, &nameLen)) { LOG(4, ("%s: unicode conversion to form D failed.\n", __FUNCTION__)); nameStatus = HGFS_NAME_STATUS_FAILURE; goto error; } free(myBufOut); LOG(4, ("%s: name is \"%s\"\n", __FUNCTION__, tempPtr)); /* Save returned pointers, update buffer length. */ myBufOut = tempPtr; out = tempPtr + nameLen; myBufOutLen = nameLen; } #endif /* defined(__APPLE__) */ /* * Convert file name to proper case if host default config option is not set * and case conversion is required for this platform. */ if (!HgfsServerPolicy_IsShareOptionSet(shareOptions, HGFS_SHARE_HOST_DEFAULT_CASE) && HgfsServerCaseConversionRequired()) { nameStatus = HgfsServerConvertCase(shareInfo->rootDir, shareInfo->rootDirLen, myBufOut, myBufOutLen, caseFlags, &convertedMyBufOut, &convertedMyBufOutLen); /* * On success, use the converted file names for further operations. */ if (nameStatus != HGFS_NAME_STATUS_COMPLETE) { LOG(4, ("%s: HgfsServerConvertCase failed.\n", __FUNCTION__)); goto error; } free(myBufOut); myBufOut = convertedMyBufOut; myBufOutLen = convertedMyBufOutLen; ASSERT(myBufOut); } /* Check for symlinks if the followSymlinks option is not set. */ if (!HgfsServerPolicy_IsShareOptionSet(shareOptions, HGFS_SHARE_FOLLOW_SYMLINKS)) { /* * Verify that either the path is same as share path or the path until the * parent directory is within the share. * * XXX: Symlink check could become susceptible to TOCTOU (time-of-check, * time-of-use) attack when we move to asynchrounous HGFS operations. * We should use the resolved file path for further file system * operations, instead of using the one passed from the client. */ nameStatus = HgfsServerHasSymlink(myBufOut, myBufOutLen, shareInfo->rootDir, shareInfo->rootDirLen); if (nameStatus != HGFS_NAME_STATUS_COMPLETE) { LOG(4, ("%s: parent path failed to be resolved: %d\n", __FUNCTION__, nameStatus)); goto error; } } { char *p; /* Trim unused memory */ /* Enough space for resulting string + NUL termination */ p = realloc(myBufOut, (myBufOutLen + 1) * sizeof *p); if (!p) { LOG(4, ("%s: failed to trim memory\n", __FUNCTION__)); } else { myBufOut = p; } if (outLen) { *outLen = myBufOutLen; } } LOG(4, ("%s: name is \"%s\"\n", __FUNCTION__, myBufOut)); *bufOut = myBufOut; return HGFS_NAME_STATUS_COMPLETE; error: free(myBufOut); return nameStatus; } /* *----------------------------------------------------------------------------- * * HgfsServerIsSharedFolderOnly -- * * Test a name if it is a shared folder only or not * * This function assumes that CPName_GetComponent() will always succeed * with a size greater than 0, so it must ONLY be called after a call to * HgfsServerGetShareInfo() that returns HGFS_NAME_STATUS_COMPLETE. * * Results: * True if it is a shared folder only, otherwise false * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsServerIsSharedFolderOnly(char const *cpName,// IN: Cross-platform filename to check size_t cpNameSize) // IN: Size of name cpName { char const *inEnd; char const *next; int len; ASSERT(cpName); inEnd = cpName + cpNameSize; len = CPName_GetComponent(cpName, inEnd, &next); ASSERT(len > 0); (void) len; /* Shuts up gcc's -Werror=unused-but-set-variable. */ return (next == inEnd); } /* *----------------------------------------------------------------------------- * * HgfsServerDumpDents -- * * Dump a set of directory entries (debugging code) * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsServerDumpDents(HgfsHandle searchHandle, // IN: Handle to dump dents from HgfsSessionInfo *session) // IN: Session info { #ifdef VMX86_LOG unsigned int i; HgfsSearch *search; MXUser_AcquireExclLock(session->searchArrayLock); search = HgfsSearchHandle2Search(searchHandle, session); if (search != NULL) { Log("%s: %u dents in \"%s\"\n", __FUNCTION__, search->numDents, search->utf8Dir); Log("Dumping dents:\n"); for (i = 0; i < search->numDents; i++) { Log("\"%s\"\n", search->dents[i]->d_name); } } MXUser_ReleaseExclLock(session->searchArrayLock); #endif } /* *----------------------------------------------------------------------------- * * HgfsServerGetDents -- * * Get directory entry names from the given callback function, and * build an array of DirectoryEntrys of all the names. Somewhat similar to * scandir(3) on linux, but more general. * * Results: * On success, the number of directory entries found. * On failure, negative error. * * Side effects: * Memory allocation. * *----------------------------------------------------------------------------- */ static int HgfsServerGetDents(HgfsGetNameFunc getName, // IN: Function to get name HgfsInitFunc initName, // IN: Setup function HgfsCleanupFunc cleanupName, // IN: Cleanup function DirectoryEntry ***dents) // OUT: Array of DirectoryEntrys { uint32 totalDents = 0; // Number of allocated dents uint32 numDents = 0; // Current actual number of dents DirectoryEntry **myDents = NULL; // So realloc is happy w/ zero numDents void *state; state = initName(); if (!state) { LOG(4, ("%s: Couldn't init state\n", __FUNCTION__)); goto error_free; } for (;;) { DirectoryEntry *pDirEntry; char const *name; size_t len; Bool done = FALSE; size_t newDirEntryLen; size_t maxLen; /* Add '.' and ".." as the first dents. */ if (numDents == 0) { name = "."; len = 1; } else if (numDents == 1) { name = ".."; len = 2; } else { if (!getName(state, &name, &len, &done)) { LOG(4, ("%s: Couldn't get next name\n", __FUNCTION__)); goto error; } } if (done) { LOG(4, ("%s: No more names\n", __FUNCTION__)); break; } #if defined(sun) /* * Solaris lacks a single definition of NAME_MAX and using pathconf(), to * determine NAME_MAX for the current directory, is too cumbersome for * our purposes, so we use PATH_MAX as a reasonable upper bound on the * length of the name. */ maxLen = PATH_MAX; #else maxLen = sizeof pDirEntry->d_name; #endif if (len >= maxLen) { Log("%s: Error: Name \"%s\" is too long.\n", __FUNCTION__, name); continue; } /* See if we need to allocate more memory */ if (numDents == totalDents) { void *p; if (totalDents != 0) { totalDents *= 2; } else { totalDents = 100; } p = realloc(myDents, totalDents * sizeof *myDents); if (!p) { LOG(4, ("%s: Couldn't reallocate array memory\n", __FUNCTION__)); goto error; } myDents = (DirectoryEntry **)p; } /* This file/directory can be added to the list. */ LOG(4, ("%s: Nextfilename = \"%s\"\n", __FUNCTION__, name)); /* * Start with the size of the DirectoryEntry struct, subtract the static * length of the d_name buffer (256 in Linux, 1 in Solaris, etc) and add * back just enough space for the UTF-8 name and nul terminator. */ newDirEntryLen = sizeof *pDirEntry - sizeof pDirEntry->d_name + len + 1; pDirEntry = (DirectoryEntry *)malloc(newDirEntryLen); if (!pDirEntry) { LOG(4, ("%s: Couldn't allocate dentry memory\n", __FUNCTION__)); goto error; } pDirEntry->d_reclen = (unsigned short)newDirEntryLen; memcpy(pDirEntry->d_name, name, len); pDirEntry->d_name[len] = 0; myDents[numDents] = pDirEntry; numDents++; } /* We are done; cleanup the state */ if (!cleanupName(state)) { LOG(4, ("%s: Non-error cleanup failed\n", __FUNCTION__)); goto error_free; } /* Trim extra memory off of dents */ { void *p; p = realloc(myDents, numDents * sizeof *myDents); if (!p) { LOG(4, ("%s: Couldn't realloc less array memory\n", __FUNCTION__)); *dents = myDents; } else { *dents = (DirectoryEntry **)p; } } return numDents; error: /* Cleanup the callback state */ if (!cleanupName(state)) { LOG(4, ("%s: Error cleanup failed\n", __FUNCTION__)); } error_free: /* Free whatever has been allocated so far */ { unsigned int i; for (i = 0; i < numDents; i++) { free(myDents[i]); } free(myDents); } return -1; } /* *----------------------------------------------------------------------------- * * HgfsServerSearchRealDir -- * * Handle a search on a real directory. Takes a pointer to an enumerator * for the directory's contents and returns a handle to a search that is * correctly set up with the real directory's entries. * * The casual reader will notice that the "type" of this search is obviously * always DIRECTORY_SEARCH_TYPE_DIR, but the caller is nonetheless required * to pass it in, for completeness' sake with respect to * HgfsServerSearchVirtualDir. * * Results: * Zero on success, returns a handle to the created search. * Non-zero on failure. * * Side effects: * Memory allocation on success * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsServerSearchRealDir(char const *baseDir, // IN: Directory to search size_t baseDirLen, // IN: Length of directory char const *shareName, // IN: Share name containing the directory char const *rootDir, // IN: Shared folder root directory HgfsSessionInfo *session, // IN: Session info HgfsHandle *handle) // OUT: Search handle { HgfsSearch *search = NULL; HgfsInternalStatus status = 0; HgfsNameStatus nameStatus; int numDents; Bool followSymlinks; HgfsShareOptions configOptions; ASSERT(baseDir); ASSERT(handle); ASSERT(shareName); MXUser_AcquireExclLock(session->searchArrayLock); search = HgfsAddNewSearch(baseDir, DIRECTORY_SEARCH_TYPE_DIR, shareName, rootDir, session); if (!search) { LOG(4, ("%s: failed to get new search\n", __FUNCTION__)); status = HGFS_ERROR_INTERNAL; goto out; } /* Get the config options. */ nameStatus = HgfsServerPolicy_GetShareOptions(shareName, strlen(shareName), &configOptions); if (nameStatus != HGFS_NAME_STATUS_COMPLETE) { LOG(4, ("%s: no matching share: %s.\n", __FUNCTION__, shareName)); status = HGFS_ERROR_INTERNAL; HgfsRemoveSearchInternal(search, session); goto out; } followSymlinks = HgfsServerPolicy_IsShareOptionSet(configOptions, HGFS_SHARE_FOLLOW_SYMLINKS); status = HgfsServerScandir(baseDir, baseDirLen, followSymlinks, &search->dents, &numDents); if (status != 0) { LOG(4, ("%s: couldn't scandir\n", __FUNCTION__)); HgfsRemoveSearchInternal(search, session); goto out; } search->numDents = numDents; *handle = HgfsSearch2SearchHandle(search); out: MXUser_ReleaseExclLock(session->searchArrayLock); return status; } /* *----------------------------------------------------------------------------- * * HgfsServerSearchVirtualDir -- * * Handle a search on a virtual directory (i.e. one that does not * really exist on the server). Takes a pointer to an enumerator * for the directory's contents and returns a handle to a search that is * correctly set up with the virtual directory's entries. * * Results: * Zero on success, returns a handle to the created search. * Non-zero on failure. * * Side effects: * Memory allocation on success * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsServerSearchVirtualDir(HgfsGetNameFunc *getName, // IN: Name enumerator HgfsInitFunc *initName, // IN: Init function HgfsCleanupFunc *cleanupName, // IN: Cleanup function DirectorySearchType type, // IN: Kind of search HgfsSessionInfo *session, // IN: Session info HgfsHandle *handle) // OUT: Search handle { HgfsInternalStatus status = 0; HgfsSearch *search = NULL; int result = 0; ASSERT(getName); ASSERT(initName); ASSERT(cleanupName); ASSERT(handle); MXUser_AcquireExclLock(session->searchArrayLock); search = HgfsAddNewSearch("", type, "", "", session); if (!search) { LOG(4, ("%s: failed to get new search\n", __FUNCTION__)); status = HGFS_ERROR_INTERNAL; goto out; } result = HgfsServerGetDents(getName, initName, cleanupName, &search->dents); if (result < 0) { LOG(4, ("%s: couldn't get dents\n", __FUNCTION__)); HgfsRemoveSearchInternal(search, session); status = HGFS_ERROR_INTERNAL; goto out; } search->numDents = result; *handle = HgfsSearch2SearchHandle(search); out: MXUser_ReleaseExclLock(session->searchArrayLock); return status; } /* *----------------------------------------------------------------------------- * * HgfsRemoveFromCache -- * * Grab a node cache lock and call HgfsRemoveFromCacheInternal. * * If the node was not already in the cache then nothing is done. * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsRemoveFromCache(HgfsHandle handle, // IN: Hgfs handle to the node HgfsSessionInfo *session) // IN: Session info { Bool removed = FALSE; MXUser_AcquireExclLock(session->nodeArrayLock); removed = HgfsRemoveFromCacheInternal(handle, session); MXUser_ReleaseExclLock(session->nodeArrayLock); return removed; } /* *----------------------------------------------------------------------------- * * HgfsIsCached -- * * Grab a lock and call HgfsIsCachedInternal. * * Results: * TRUE if the node is found in the cache. * FALSE if the node is not in the cache. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsIsCached(HgfsHandle handle, // IN: Structure representing file node HgfsSessionInfo *session) // IN: Session info { Bool cached = FALSE; MXUser_AcquireExclLock(session->nodeArrayLock); cached = HgfsIsCachedInternal(handle, session); MXUser_ReleaseExclLock(session->nodeArrayLock); return cached; } /* *----------------------------------------------------------------------------- * * HgfsRemoveLruNode-- * * Removes the least recently used node in the cache. The first node is * removed since most recently used nodes are moved to the end of the * list. * * XXX: Right now we do not remove nodes that have server locks on them * This is not correct and should be fixed before the release. * Instead we should cancel the server lock (by calling IoCancel) * notify client of the lock break, and close the file. * * Assumes that there is at least one node in the cache. * * The session's nodeArrayLock should be acquired prior to calling this * function. * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsRemoveLruNode(HgfsSessionInfo *session) // IN: session info { HgfsFileNode *lruNode = NULL; HgfsHandle handle; Bool found = FALSE; uint32 numOpenNodes = session->numCachedOpenNodes; ASSERT(session); ASSERT(session->numCachedOpenNodes > 0); /* * Remove the first item from the list that does not have a server lock, * file context or is open in sequential mode. */ while (!found && (numOpenNodes-- > 0)) { lruNode = DblLnkLst_Container(session->nodeCachedList.next, HgfsFileNode, links); ASSERT(lruNode->state == FILENODE_STATE_IN_USE_CACHED); if (lruNode->serverLock != HGFS_LOCK_NONE || lruNode->fileCtx != NULL || (lruNode->flags & HGFS_FILE_NODE_SEQUENTIAL_FL) != 0) { /* * Move this node with the server lock to the beginning of the list. * Also, prevent files opened in HGFS_FILE_NODE_SEQUENTIAL_FL mode * from being closed. -- On some platforms, this mode does not * allow files to be closed/re-opened (eg: When restoring a file * into a Windows guest you cannot use BackupWrite, then close and * re-open the file and continue to use BackupWrite. */ DblLnkLst_Unlink1(&lruNode->links); DblLnkLst_LinkLast(&session->nodeCachedList, &lruNode->links); } else { found = TRUE; } } if (found) { handle = HgfsFileNode2Handle(lruNode); if (!HgfsRemoveFromCacheInternal(handle, session)) { LOG(4, ("%s: Could not remove the node from cache.\n", __FUNCTION__)); return FALSE; } } else { LOG(4, ("%s: Could not find a node to remove from cache.\n", __FUNCTION__)); return FALSE; } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsAddToCache -- * * Grabs the cache lock and calls HgfsAddToCacheInternal. * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsAddToCache(HgfsHandle handle, // IN: HGFS file handle HgfsSessionInfo *session) // IN: Session info { Bool added = FALSE; MXUser_AcquireExclLock(session->nodeArrayLock); added = HgfsAddToCacheInternal(handle, session); MXUser_ReleaseExclLock(session->nodeArrayLock); return added; } /* *----------------------------------------------------------------------------- * * HgfsCreateAndCacheFileNode -- * * Get a node from the free node list and cache it. * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsCreateAndCacheFileNode(HgfsFileOpenInfo *openInfo, // IN: Open info struct HgfsLocalId const *localId, // IN: Local unique file ID fileDesc fileDesc, // IN: Handle to the fileopenInfo, Bool append, // IN: flag to append HgfsSessionInfo *session) // IN: session info { HgfsHandle handle; HgfsFileNode *node = NULL; char const *inEnd; char const *next; int len; Bool sharedFolderOpen = FALSE; ASSERT(openInfo); ASSERT(localId); ASSERT(session); inEnd = openInfo->cpName + openInfo->cpNameSize; /* * Get first component. */ len = CPName_GetComponent(openInfo->cpName, inEnd, &next); if (len < 0) { LOG(4, ("%s: get first component failed\n", __FUNCTION__)); HgfsCloseFile(fileDesc, NULL); return FALSE; } /* See if we are dealing with the base of the namespace */ if (!len) { HgfsCloseFile(fileDesc, NULL); return FALSE; } if (!next) { sharedFolderOpen = TRUE; } MXUser_AcquireExclLock(session->nodeArrayLock); node = HgfsAddNewFileNode(openInfo, localId, fileDesc, append, len, openInfo->cpName, sharedFolderOpen, session); if (node == NULL) { LOG(4, ("%s: Failed to add new node.\n", __FUNCTION__)); MXUser_ReleaseExclLock(session->nodeArrayLock); HgfsCloseFile(fileDesc, NULL); return FALSE; } handle = HgfsFileNode2Handle(node); if (!HgfsAddToCacheInternal(handle, session)) { HgfsFreeFileNodeInternal(handle, session); HgfsCloseFile(fileDesc, NULL); LOG(4, ("%s: Failed to add node to the cache.\n", __FUNCTION__)); MXUser_ReleaseExclLock(session->nodeArrayLock); return FALSE; } MXUser_ReleaseExclLock(session->nodeArrayLock); /* Only after everything is successful, save the handle in the open info. */ openInfo->file = handle; return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsAllocInitReply -- * * Allocates hgfs reply packet and calculates pointer to HGFS payload. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsAllocInitReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header size_t payloadSize, // IN: payload size void **payload, // OUT: pointer to the reply payload HgfsSessionInfo *session) // IN: Session Info { HgfsRequest *request = (HgfsRequest *)packetHeader; size_t replyPacketSize; size_t headerSize = 0; /* Replies prior to V3 do not have a header. */ Bool result = FALSE; char *reply; if (HGFS_V4_LEGACY_OPCODE == request->op) { headerSize = sizeof(HgfsHeader); } else if (request->op < HGFS_OP_CREATE_SESSION_V4 && request->op > HGFS_OP_RENAME_V2) { headerSize = sizeof(HgfsReply); } replyPacketSize = headerSize + payloadSize; reply = HSPU_GetReplyPacket(packet, &replyPacketSize, session->transportSession); if (reply && (replyPacketSize >= headerSize + payloadSize)) { memset(reply, 0, headerSize + payloadSize); result = TRUE; if (payloadSize > 0) { *payload = reply + headerSize; } else { *payload = NULL; } } return result; } /* *----------------------------------------------------------------------------- * * HgfsServerRead -- * * Handle a Read request. * * Results: * HGFS_ERROR_SUCCESS on success. * HGFS error code on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerRead(HgfsInputParam *input) // IN: Input params { HgfsInternalStatus status; HgfsHandle file; uint64 offset; uint32 requiredSize; size_t replyPayloadSize = 0; HGFS_ASSERT_INPUT(input); if (!HgfsUnpackReadRequest(input->payload, input->payloadSize, input->op, &file, &offset, &requiredSize)) { LOG(4, ("%s: Failed to unpack a valid packet -> PROTOCOL_ERROR.\n", __FUNCTION__)); status = HGFS_ERROR_PROTOCOL; } else { switch(input->op) { case HGFS_OP_READ_FAST_V4: case HGFS_OP_READ_V3: { HgfsReplyReadV3 *reply; void *payload; uint32 inlineDataSize = (HGFS_OP_READ_FAST_V4 == input->op) ? 0 : requiredSize; if (!HgfsAllocInitReply(input->packet, input->metaPacket, sizeof *reply + inlineDataSize, (void **)&reply, input->session)) { status = HGFS_ERROR_PROTOCOL; LOG(4, ("%s: V3/V4 Failed to alloc reply -> PROTOCOL_ERROR.\n", __FUNCTION__)); } else { if (HGFS_OP_READ_V3 == input->op) { payload = &reply->payload[0]; } else { payload = HSPU_GetDataPacketBuf(input->packet, BUF_WRITEABLE, input->transportSession); } if (payload) { status = HgfsPlatformReadFile(file, input->session, offset, requiredSize, payload, &reply->actualSize); if (HGFS_ERROR_SUCCESS == status) { reply->reserved = 0; replyPayloadSize = sizeof *reply + ((inlineDataSize > 0) ? reply->actualSize : 0); } } else { status = HGFS_ERROR_PROTOCOL; LOG(4, ("%s: V3/V4 Failed to get payload -> PROTOCOL_ERROR.\n", __FUNCTION__)); } } break; } case HGFS_OP_READ: { HgfsReplyRead *reply; if (HgfsAllocInitReply(input->packet, input->metaPacket, sizeof *reply + requiredSize, (void **)&reply, input->session)) { status = HgfsPlatformReadFile(file, input->session, offset, requiredSize, reply->payload, &reply->actualSize); if (HGFS_ERROR_SUCCESS == status) { replyPayloadSize = sizeof *reply + reply->actualSize; } else { LOG(4, ("%s: V1 Failed to read-> %d.\n", __FUNCTION__, status)); } } else { status = HGFS_ERROR_PROTOCOL; LOG(4, ("%s: V1 Failed to alloc reply -> PROTOCOL_ERROR.\n", __FUNCTION__)); } break; } default: NOT_IMPLEMENTED(); status = HGFS_ERROR_PROTOCOL; LOG(4, ("%s: Unsupported protocol version passed %d -> PROTOCOL_ERROR.\n", __FUNCTION__, input->op)); } } HgfsServerCompleteRequest(status, replyPayloadSize, input); } /* *----------------------------------------------------------------------------- * * HgfsServerWrite -- * * Handle a Write request. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerWrite(HgfsInputParam *input) // IN: Input params { uint32 numberBytesToWrite; HgfsInternalStatus status; HgfsWriteFlags flags; uint64 offset; char *dataToWrite; uint32 replyActualSize; size_t replyPayloadSize = 0; HgfsHandle file; HGFS_ASSERT_INPUT(input); if (HgfsUnpackWriteRequest(input, &file, &offset, &numberBytesToWrite, &flags, &dataToWrite)) { status = HgfsPlatformWriteFile(file, input->session, offset, numberBytesToWrite, flags, dataToWrite, &replyActualSize); if (HGFS_ERROR_SUCCESS == status) { if (!HgfsPackWriteReply(input->packet, input->metaPacket, input->op, replyActualSize, &replyPayloadSize, input->session)) { status = HGFS_ERROR_INTERNAL; } } } else { status = HGFS_ERROR_PROTOCOL; } HgfsServerCompleteRequest(status, replyPayloadSize, input); } /* *----------------------------------------------------------------------------- * * HgfsQueryVolume -- * * Performs actual work to get free space and capacity for a volume or * a group of volumes. * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsQueryVolume(HgfsSessionInfo *session, // IN: session info char *fileName, // IN: cpName for the volume size_t fileNameLength, // IN: cpName length uint32 caseFlags, // IN: case sensitive/insensitive name uint64 *freeBytes, // OUT: free space in bytes uint64 *totalBytes) // OUT: capacity in bytes { HgfsInternalStatus status = HGFS_ERROR_SUCCESS; uint64 outFreeBytes = 0; uint64 outTotalBytes = 0; char *utf8Name = NULL; size_t utf8NameLen; HgfsNameStatus nameStatus; Bool firstShare = TRUE; HgfsShareInfo shareInfo; HgfsHandle handle; VolumeInfoType infoType; DirectoryEntry *dent; size_t failed = 0; size_t shares = 0; int offset = 0; HgfsInternalStatus firstErr = HGFS_ERROR_SUCCESS; Bool success; /* It is now safe to read the file name field. */ nameStatus = HgfsServerGetShareInfo(fileName, fileNameLength, caseFlags, &shareInfo, &utf8Name, &utf8NameLen); switch (nameStatus) { case HGFS_NAME_STATUS_INCOMPLETE_BASE: /* * This is the base of our namespace. Clients can request a * QueryVolumeInfo on it, on individual shares, or on just about * any pathname. */ LOG(4,("%s: opened search on base\n", __FUNCTION__)); status = HgfsServerSearchVirtualDir(HgfsServerPolicy_GetShares, HgfsServerPolicy_GetSharesInit, HgfsServerPolicy_GetSharesCleanup, DIRECTORY_SEARCH_TYPE_BASE, session, &handle); if (status != 0) { return status; } /* * If we're outside the Tools, find out if we're to compute the minimum * values across all shares, or the maximum values. */ infoType = VOLUME_INFO_TYPE_MIN; #ifndef VMX86_TOOLS { char *volumeInfoType = Config_GetString("min", "tools.hgfs.volumeInfoType"); if (!Str_Strcasecmp(volumeInfoType, "max")) { infoType = VOLUME_INFO_TYPE_MAX; } free(volumeInfoType); } #endif /* * Now go through all shares and get share paths on the server. * Then retrieve space info for each share's volume. */ offset = 0; while ((dent = HgfsGetSearchResult(handle, session, offset, TRUE)) != NULL) { char const *sharePath; size_t sharePathLen; uint64 currentFreeBytes = 0; uint64 currentTotalBytes = 0; size_t length; length = strlen(dent->d_name); /* * Now that the server is passing '.' and ".." around as dents, we * need to make sure to handle them properly. In particular, they * should be ignored within QueryVolume, as they're not real shares. */ if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) { LOG(4, ("%s: Skipping fake share %s\n", __FUNCTION__, dent->d_name)); free(dent); continue; } /* * The above check ignores '.' and '..' so we do not include them in * the share count here. */ shares++; /* * Check permission on the share and get the share path. It is not * fatal if these do not succeed. Instead we ignore the failures * (apart from logging them) until we have processed all shares. Only * then do we check if there were any failures; if all shares failed * to process then we bail out with an error code. */ nameStatus = HgfsServerPolicy_GetSharePath(dent->d_name, length, HGFS_OPEN_MODE_READ_ONLY, &sharePathLen, &sharePath); free(dent); if (nameStatus != HGFS_NAME_STATUS_COMPLETE) { LOG(4, ("%s: No such share or access denied\n", __FUNCTION__)); if (0 == firstErr) { firstErr = HgfsPlatformConvertFromNameStatus(nameStatus); } failed++; continue; } /* * Pick the drive with amount of space available and return that * according to different volume info type. */ if (!HgfsServerStatFs(sharePath, sharePathLen, ¤tFreeBytes, ¤tTotalBytes)) { LOG(4, ("%s: error getting volume information\n", __FUNCTION__)); if (0 == firstErr) { firstErr = HGFS_ERROR_IO; } failed++; continue; } /* * Pick the drive with amount of space available and return that * according to different volume info type. */ switch (infoType) { case VOLUME_INFO_TYPE_MIN: if ((outFreeBytes > currentFreeBytes) || firstShare) { firstShare = FALSE; outFreeBytes = currentFreeBytes; outTotalBytes = currentTotalBytes; } break; case VOLUME_INFO_TYPE_MAX: if ((outFreeBytes < currentFreeBytes)) { outFreeBytes = currentFreeBytes; outTotalBytes = currentTotalBytes; } break; default: NOT_IMPLEMENTED(); } } if (!HgfsRemoveSearch(handle, session)) { LOG(4, ("%s: could not close search on base\n", __FUNCTION__)); } if (shares == failed) { if (firstErr != 0) { /* * We failed to query any of the shares. We return the error] * from the first share failure. */ status = firstErr; } /* No shares but no error, return zero for sizes and success. */ } break; case HGFS_NAME_STATUS_COMPLETE: ASSERT(utf8Name); LOG(4,("%s: querying path %s\n", __FUNCTION__, utf8Name)); success = HgfsServerStatFs(utf8Name, utf8NameLen, &outFreeBytes, &outTotalBytes); free(utf8Name); if (!success) { LOG(4, ("%s: error getting volume information\n", __FUNCTION__)); status = HGFS_ERROR_IO; } break; default: LOG(4,("%s: file access check failed\n", __FUNCTION__)); status = HgfsPlatformConvertFromNameStatus(nameStatus); } *freeBytes = outFreeBytes; *totalBytes = outTotalBytes; LOG(4, ("%s: return %"FMT64"u bytes Free %"FMT64"u bytes\n", __FUNCTION__, outTotalBytes, outFreeBytes)); return status; } /* *----------------------------------------------------------------------------- * * HgfsServerQueryVolume -- * * Handle a Query Volume request. * * Right now we only handle the volume space request. Call Wiper library * to get the volume information. * It is possible that shared folders can belong to different volumes on * the server. If this is the case, default to return the space information * of the volume that has the least amount of the available space, but it's * configurable with a config option (tools.hgfs.volumeInfoType). 2 possible * options, min and max. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerQueryVolume(HgfsInputParam *input) // IN: Input params { HgfsInternalStatus status; size_t replyPayloadSize = 0; HgfsHandle file; char *fileName; size_t fileNameLength; uint32 caseFlags; Bool useHandle; uint64 freeBytes; uint64 totalBytes; HGFS_ASSERT_INPUT(input); if (HgfsUnpackQueryVolumeRequest(input->payload, input->payloadSize, input->op, &useHandle, &fileName, &fileNameLength, &caseFlags, &file)) { /* * We don't yet support file handle for this operation. * Clients should retry using the file name. */ if (useHandle) { LOG(4, ("%s: Doesn't support file handle.\n", __FUNCTION__)); status = HGFS_ERROR_INVALID_PARAMETER; } else { status = HgfsQueryVolume(input->session, fileName, fileNameLength, caseFlags, &freeBytes, &totalBytes); if (HGFS_ERROR_SUCCESS == status) { if (!HgfsPackQueryVolumeReply(input->packet, input->metaPacket, input->op, freeBytes, totalBytes, &replyPayloadSize, input->session)) { status = HGFS_ERROR_INTERNAL; } } } } else { status = HGFS_ERROR_PROTOCOL; } HgfsServerCompleteRequest(status, replyPayloadSize, input); } /* *----------------------------------------------------------------------------- * * HgfsSymlinkCreate -- * * Platform independent function that verifies whether symbolic link creation * is allowed for the specific shared folder and then calls platform specific * HgfsPlatformSymlinkCreate to do the actual job. * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsSymlinkCreate(HgfsSessionInfo *session, // IN: session info, char *srcFileName, // IN: symbolic link file name uint32 srcFileNameLength, // IN: symbolic link name length uint32 srcCaseFlags, // IN: symlink case flags char *trgFileName, // IN: symbolic link target name uint32 trgFileNameLength, // IN: target name length uint32 trgCaseFlags) // IN: target case flags { HgfsShareInfo shareInfo; HgfsInternalStatus status = 0; HgfsNameStatus nameStatus; HgfsShareOptions configOptions; char *localSymlinkName = NULL; size_t localSymlinkNameLen; char localTargetName[HGFS_PACKET_MAX]; /* * It is now safe to read the symlink file name and the * "targetName" field */ nameStatus = HgfsServerGetShareInfo(srcFileName, srcFileNameLength, srcCaseFlags, &shareInfo, &localSymlinkName, &localSymlinkNameLen); if (nameStatus == HGFS_NAME_STATUS_COMPLETE) { if (shareInfo.writePermissions ) { /* Get the config options. */ nameStatus = HgfsServerPolicy_GetShareOptions(srcFileName, srcFileNameLength, &configOptions); if (nameStatus == HGFS_NAME_STATUS_COMPLETE) { /* Prohibit symlink ceation if symlink following is enabled. */ if (HgfsServerPolicy_IsShareOptionSet(configOptions, HGFS_SHARE_FOLLOW_SYMLINKS)) { status = HGFS_ERROR_ACCESS_DENIED; } } else { LOG(4, ("%s: no matching share: %s.\n", __FUNCTION__, srcFileName)); status = HgfsPlatformConvertFromNameStatus(nameStatus); } } else { status = HgfsPlatformFileExists(localSymlinkName); if (status != 0) { if (status == HGFS_ERROR_FILE_NOT_FOUND) { status = HGFS_ERROR_ACCESS_DENIED; } } else { status = HGFS_ERROR_FILE_EXIST; } LOG(4, ("%s: failed access check, error %d\n", __FUNCTION__, status)); } } else { LOG(4, ("%s: symlink name access check failed\n", __FUNCTION__)); status = HgfsPlatformConvertFromNameStatus(nameStatus); } if (HGFS_ERROR_SUCCESS == status) { /* Convert from CPName-lite to normal and NUL-terminate. */ memcpy(localTargetName, trgFileName, trgFileNameLength); CPNameLite_ConvertFrom(localTargetName, trgFileNameLength, DIRSEPC); localTargetName[trgFileNameLength] = '\0'; status = HgfsPlatformSymlinkCreate(localSymlinkName, localTargetName); } free(localSymlinkName); return status; } /* *----------------------------------------------------------------------------- * * HgfsServerSymlinkCreate -- * * Handle a SymlinkCreate request. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerSymlinkCreate(HgfsInputParam *input) // IN: Input params { HgfsInternalStatus status; HgfsHandle srcFile; char *srcFileName; size_t srcFileNameLength; uint32 srcCaseFlags; Bool srcUseHandle; HgfsHandle trgFile; char *trgFileName; size_t trgFileNameLength; uint32 trgCaseFlags; Bool trgUseHandle; size_t replyPayloadSize = 0; HGFS_ASSERT_INPUT(input); if (HgfsUnpackSymlinkCreateRequest(input->payload, input->payloadSize, input->op, &srcUseHandle, &srcFileName, &srcFileNameLength, &srcCaseFlags, &srcFile, &trgUseHandle, &trgFileName, &trgFileNameLength, &trgCaseFlags, &trgFile)) { /* * We don't yet support file handle for this operation. * Clients should retry using the file name. */ if (srcUseHandle || trgUseHandle) { LOG(4, ("%s: Doesn't support file handle.\n", __FUNCTION__)); status = HGFS_ERROR_INVALID_PARAMETER; } else { status = HgfsSymlinkCreate(input->session, srcFileName, srcFileNameLength, srcCaseFlags, trgFileName, trgFileNameLength, trgCaseFlags); if (HGFS_ERROR_SUCCESS == status) { if (!HgfsPackSymlinkCreateReply(input->packet, input->metaPacket, input->op, &replyPayloadSize, input->session)) { status = HGFS_ERROR_INTERNAL; } } } } else { status = HGFS_ERROR_PROTOCOL; } HgfsServerCompleteRequest(status, replyPayloadSize, input); } /* *----------------------------------------------------------------------------- * * HgfsServerSearchOpen -- * * Handle a search open request. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerSearchOpen(HgfsInputParam *input) // IN: Input params { HgfsInternalStatus status; size_t replyPayloadSize = 0; char *dirName; uint32 dirNameLength; uint32 caseFlags = HGFS_FILE_NAME_DEFAULT_CASE; HgfsHandle search; HgfsNameStatus nameStatus; HgfsShareInfo shareInfo; char *baseDir = NULL; size_t baseDirLen; HGFS_ASSERT_INPUT(input); if (HgfsUnpackSearchOpenRequest(input->payload, input->payloadSize, input->op, &dirName, &dirNameLength, &caseFlags)) { nameStatus = HgfsServerGetShareInfo(dirName, dirNameLength, caseFlags, &shareInfo, &baseDir, &baseDirLen); status = HgfsPlatformSearchDir(nameStatus, dirName, dirNameLength, caseFlags, &shareInfo, baseDir, baseDirLen, input->session, &search); if (HGFS_ERROR_SUCCESS == status) { if (!HgfsPackSearchOpenReply(input->packet, input->metaPacket, input->op, search, &replyPayloadSize, input->session)) { status = HGFS_ERROR_INTERNAL; } } } else { status = HGFS_ERROR_PROTOCOL; } HgfsServerCompleteRequest(status, replyPayloadSize, input); } /* *----------------------------------------------------------------------------- * * HgfsValidateRenameFile -- * * Validates if the file can can participate in rename process either as * as a source or as a target. * * Results: * HGFS_ERROR_SUCCESS if rename operation is allowed. * Appropriate error code otherwise. * * Side effects: * Allcates locaFileName which must be freed by the caller. * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsValidateRenameFile(Bool useHandle, // IN: HgfsHandle fileHandle, // IN: char *cpName, // IN: size_t cpNameLength, // IN: uint32 caseFlags, // IN: HgfsSessionInfo *session, // IN: Session info fileDesc* descr, // OUT: HgfsShareInfo *shareInfo, // OUT: char **localFileName, // OUT: size_t *localNameLength) // OUT: { HgfsInternalStatus status; Bool sharedFolderOpen = FALSE; HgfsServerLock serverLock = HGFS_LOCK_NONE; HgfsNameStatus nameStatus; if (useHandle) { status = HgfsPlatformGetFd(fileHandle, session, FALSE, descr); if (HGFS_ERROR_SUCCESS != status) { LOG(4, ("%s: could not map cached handle %d, error %u\n", __FUNCTION__, fileHandle, status)); } else if (!HgfsHandle2FileNameMode(fileHandle, session, &shareInfo->writePermissions, &shareInfo->readPermissions, localFileName, localNameLength)) { /* * HgfsPlatformRename requires valid source file name even when file handle * is specified. * Also the name will be required to update the nodes on a successful * rename operation. */ LOG(4, ("%s: could not get file name for fd %d\n", __FUNCTION__, *descr)); status = HGFS_ERROR_INVALID_HANDLE; } else if (HgfsHandleIsSharedFolderOpen(fileHandle, session, &sharedFolderOpen) && sharedFolderOpen) { LOG(4, ("%s: Cannot rename shared folder\n", __FUNCTION__)); status = HGFS_ERROR_ACCESS_DENIED; } } else { nameStatus = HgfsServerGetShareInfo(cpName, cpNameLength, caseFlags, shareInfo, localFileName, localNameLength); if (HGFS_NAME_STATUS_COMPLETE != nameStatus) { LOG(4, ("%s: access check failed\n", __FUNCTION__)); status = HgfsPlatformConvertFromNameStatus(nameStatus); } else if (HgfsServerIsSharedFolderOnly(cpName, cpNameLength)) { /* Guest OS is not allowed to rename shared folder. */ LOG(4, ("%s: Cannot rename shared folder\n", __FUNCTION__)); status = HGFS_ERROR_ACCESS_DENIED; } else { status = HGFS_ERROR_SUCCESS; } } ASSERT(*localFileName != NULL || HGFS_ERROR_SUCCESS != status); if (HGFS_ERROR_SUCCESS == status) { if (HgfsFileHasServerLock(*localFileName, session, &serverLock, descr)) { /* * XXX: Before renaming the file, check to see if we are holding * an oplock on both the old and new files. If one of them is oplocked, and * we commence with the rename, we'll trigger an oplock break that'll * deadlock us. The client should be smart enough to break necessary oplocks * on the source and target files before calling rename, so we'll return * an error. */ LOG (4, ("%s: File has an outstanding oplock. Client " "should remove this oplock and try again.\n", __FUNCTION__)); status = HGFS_ERROR_PATH_BUSY; } } return status; } /* *----------------------------------------------------------------------------- * * HgfsServerRename -- * * Handle a Rename request. * * Simply converts the new and old names to local filenames, calls * platform specific function to rename/move the file, and returns an * appropriate response to the driver. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerRename(HgfsInputParam *input) // IN: Input params { char *utf8OldName = NULL; size_t utf8OldNameLen; char *utf8NewName = NULL; size_t utf8NewNameLen; char *cpOldName; size_t cpOldNameLen; char *cpNewName; size_t cpNewNameLen; HgfsInternalStatus status; fileDesc srcFileDesc; fileDesc targetFileDesc; HgfsHandle srcFile; HgfsHandle targetFile; HgfsRenameHint hints; uint32 oldCaseFlags; uint32 newCaseFlags; HgfsShareInfo shareInfo; size_t replyPayloadSize = 0; HGFS_ASSERT_INPUT(input); if (HgfsUnpackRenameRequest(input->payload, input->payloadSize, input->op, &cpOldName, &cpOldNameLen, &cpNewName, &cpNewNameLen, &hints, &srcFile, &targetFile, &oldCaseFlags, &newCaseFlags)) { status = HgfsValidateRenameFile((hints & HGFS_RENAME_HINT_USE_SRCFILE_DESC) != 0, srcFile, cpOldName, cpOldNameLen, oldCaseFlags, input->session, &srcFileDesc, &shareInfo, &utf8OldName, &utf8OldNameLen); if (HGFS_ERROR_SUCCESS == status) { /* * Renaming a file requires both read and write permssions for the * original file. * However the error code must be different depending on the existence * of the file with the same name. */ if (!shareInfo.writePermissions || !shareInfo.readPermissions) { status = HgfsPlatformFileExists(utf8OldName); if (HGFS_ERROR_SUCCESS == status) { status = HGFS_ERROR_ACCESS_DENIED; } LOG(4, ("HgfsServerRename: failed access check, error %d\n", status)); } else { status = HgfsValidateRenameFile((hints & HGFS_RENAME_HINT_USE_TARGETFILE_DESC) != 0, targetFile, cpNewName, cpNewNameLen, newCaseFlags, input->session, &targetFileDesc, &shareInfo, &utf8NewName, &utf8NewNameLen); if (HGFS_ERROR_SUCCESS == status) { /* * Renaming a file requires both read and write permssions for * the target directory. * However the error code must be different depending on the existence * of the target directory - if the destination directory exists then * ERROR_ACCESS_DENIED should be returned regardless if the destination * file exists. */ if (!shareInfo.writePermissions || !shareInfo.readPermissions) { status = HgfsPlatformFileExists(utf8NewName); if (HGFS_ERROR_SUCCESS == status || HGFS_ERROR_FILE_NOT_FOUND == status) { status = HGFS_ERROR_ACCESS_DENIED; } LOG(4, ("HgfsServerRename: failed access check, error %d\n", status)); } } } } } else { status = HGFS_ERROR_PROTOCOL; } /* If all pre-conditions are met go ahead with actual rename. */ if (HGFS_ERROR_SUCCESS == status) { status = HgfsPlatformRename(utf8OldName, srcFileDesc, utf8NewName, targetFileDesc, hints); if (HGFS_ERROR_SUCCESS == status) { /* Update all file nodes that refer to this file to contain the new name. */ HgfsUpdateNodeNames(utf8OldName, utf8NewName, input->session); if (!HgfsPackRenameReply(input->packet, input->metaPacket, input->op, &replyPayloadSize, input->session)) { status = HGFS_ERROR_INTERNAL; } } } free(utf8OldName); free(utf8NewName); HgfsServerCompleteRequest(status, replyPayloadSize, input); } /* *----------------------------------------------------------------------------- * * HgfsServerCreateDir -- * * Handle a CreateDir request. * * Simply converts to the local filename, calls platform specific * code to create a directory, and returns an appropriate response to the driver. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerCreateDir(HgfsInputParam *input) // IN: Input params { HgfsInternalStatus status; HgfsNameStatus nameStatus; HgfsCreateDirInfo info; char *utf8Name; size_t utf8NameLen; size_t replyPayloadSize = 0; HgfsShareInfo shareInfo; HGFS_ASSERT_INPUT(input); if (HgfsUnpackCreateDirRequest(input->payload, input->payloadSize, input->op, &info)) { nameStatus = HgfsServerGetShareInfo(info.cpName, info.cpNameSize, info.caseFlags, &shareInfo, &utf8Name, &utf8NameLen); if (HGFS_NAME_STATUS_COMPLETE == nameStatus) { ASSERT(utf8Name); LOG(4, ("%s: making dir \"%s\"", __FUNCTION__, utf8Name)); /* * For read-only shares we must never attempt to create a directory. * However the error code must be different depending on the existence * of the file with the same name. */ if (shareInfo.writePermissions) { status = HgfsPlatformCreateDir(&info, utf8Name); if (HGFS_ERROR_SUCCESS == status) { if (!HgfsPackCreateDirReply(input->packet, input->metaPacket, info.requestType, &replyPayloadSize, input->session)) { status = HGFS_ERROR_PROTOCOL; } } } else { status = HgfsPlatformFileExists(utf8Name); if (HGFS_ERROR_SUCCESS == status) { status = HGFS_ERROR_FILE_EXIST; } else if (HGFS_ERROR_FILE_NOT_FOUND == status) { status = HGFS_ERROR_ACCESS_DENIED; } } } else { /* * Check if the name does not exist - the share was not found. * Then it could one of two things: the share was removed/disabled; * or we could be in the root share itself and have a new name. * To return the correct error, if we are in the root share, * we must check the open mode too - creation of new files/folders * should fail access denied, for anything else "not found" is acceptable. */ if (nameStatus == HGFS_NAME_STATUS_DOES_NOT_EXIST) { if (HgfsServerIsSharedFolderOnly(info.cpName, info.cpNameSize)) { nameStatus = HGFS_NAME_STATUS_ACCESS_DENIED; LOG(4, ("%s: New file creation in share root not allowed\n", __FUNCTION__)); } else { LOG(4, ("%s: Shared folder not found\n", __FUNCTION__)); } } else { LOG(4, ("%s: Shared folder access error %u\n", __FUNCTION__, nameStatus)); } status = HgfsPlatformConvertFromNameStatus(nameStatus); } } else { status = HGFS_ERROR_PROTOCOL; } HgfsServerCompleteRequest(status, replyPayloadSize, input); } /* *----------------------------------------------------------------------------- * * HgfsServerDeleteFile -- * * Handle a Delete File request. * * Simply converts to the local filename, calls DeleteFile on the * file or calls the Windows native API Delete, and returns an * appropriate response to the driver. * * Enforcing read-only shares restrictions * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerDeleteFile(HgfsInputParam *input) // IN: Input params { char *cpName; size_t cpNameSize; HgfsServerLock serverLock = HGFS_LOCK_NONE; fileDesc fileDesc; HgfsHandle file; HgfsDeleteHint hints = 0; HgfsInternalStatus status; HgfsNameStatus nameStatus; uint32 caseFlags; size_t replyPayloadSize = 0; HgfsShareInfo shareInfo; HGFS_ASSERT_INPUT(input); if (HgfsUnpackDeleteRequest(input->payload, input->payloadSize, input->op, &cpName, &cpNameSize, &hints, &file, &caseFlags)) { if (hints & HGFS_DELETE_HINT_USE_FILE_DESC) { status = HgfsPlatformDeleteFileByHandle(file, input->session); } else { char *utf8Name = NULL; size_t utf8NameLen; nameStatus = HgfsServerGetShareInfo(cpName, cpNameSize, caseFlags, &shareInfo, &utf8Name, &utf8NameLen); if (nameStatus == HGFS_NAME_STATUS_COMPLETE) { /* * Deleting a file needs both read and write permssions. * However the error code must be different depending on the existence * of the file with the same name. */ if (!shareInfo.writePermissions || !shareInfo.readPermissions) { status = HgfsPlatformFileExists(utf8Name); if (HGFS_ERROR_SUCCESS == status) { status = HGFS_ERROR_ACCESS_DENIED; } LOG(4, ("HgfsServerDeleteFile: failed access check, error %d\n", status)); } else if (HgfsFileHasServerLock(utf8Name, input->session, &serverLock, &fileDesc)) { /* * XXX: If the file has an oplock, the client should have broken it on * its own by now. Sorry! */ LOG (4, ("%s: File has an outstanding oplock. Client should " "remove this oplock and try again.\n", __FUNCTION__)); status = HGFS_ERROR_PATH_BUSY; } else { LOG(4, ("%s: deleting \"%s\"\n", __FUNCTION__, utf8Name)); status = HgfsPlatformDeleteFileByName(utf8Name); } free(utf8Name); } else { LOG(4, ("%s: Shared folder does not exist.\n", __FUNCTION__)); status = HgfsPlatformConvertFromNameStatus(nameStatus); } } if (HGFS_ERROR_SUCCESS == status) { if (!HgfsPackDeleteReply(input->packet, input->metaPacket, input->op, &replyPayloadSize, input->session)) { status = HGFS_ERROR_INTERNAL; } } } else { status = HGFS_ERROR_PROTOCOL; } HgfsServerCompleteRequest(status, replyPayloadSize, input); } /* *----------------------------------------------------------------------------- * * HgfsServerDeleteDir -- * * Handle a Delete Dir request. * * Simply converts to the local filename, calls RemoveDirectory on the * directory or Windows native API delete if we have a valid handle, * and returns an appropriate response to the driver. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerDeleteDir(HgfsInputParam *input) // IN: Input params { char *cpName; size_t cpNameSize; HgfsInternalStatus status; HgfsNameStatus nameStatus; HgfsHandle file; HgfsDeleteHint hints = 0; fileDesc fileDesc; Bool sharedFolderOpen = FALSE; uint32 caseFlags; size_t replyPayloadSize = 0; HgfsShareInfo shareInfo; HGFS_ASSERT_INPUT(input); if (HgfsUnpackDeleteRequest(input->payload, input->payloadSize, input->op, &cpName, &cpNameSize, &hints, &file, &caseFlags)) { if (hints & HGFS_DELETE_HINT_USE_FILE_DESC) { status = HgfsPlatformGetFd(file, input->session, FALSE, &fileDesc); if (HGFS_ERROR_SUCCESS == status) { if (HgfsHandleIsSharedFolderOpen(file, input->session, &sharedFolderOpen) && sharedFolderOpen) { LOG(4, ("%s: Cannot delete shared folder\n", __FUNCTION__)); status = HGFS_ERROR_ACCESS_DENIED; } else { status = HgfsPlatformDeleteDirByHandle(file, input->session); if (HGFS_ERROR_SUCCESS != status) { LOG(4, ("%s: error deleting directory %d: %d\n", __FUNCTION__, file, status)); } } } else { LOG(4, ("%s: could not map cached handle %u, error %u\n", __FUNCTION__, file, status)); } } else { char *utf8Name = NULL; size_t utf8NameLen; nameStatus = HgfsServerGetShareInfo(cpName, cpNameSize, caseFlags, &shareInfo, &utf8Name, &utf8NameLen); if (HGFS_NAME_STATUS_COMPLETE == nameStatus) { ASSERT(utf8Name); /* Guest OS is not allowed to delete shared folder. */ if (HgfsServerIsSharedFolderOnly(cpName, cpNameSize)){ LOG(4, ("%s: Cannot delete shared folder\n", __FUNCTION__)); status = HGFS_ERROR_ACCESS_DENIED; } else if (!shareInfo.writePermissions || !shareInfo.readPermissions) { /* * Deleting a directory requires both read and write permissions. * However the error code must be different depending on the existence * of the file with the same name. */ status = HgfsPlatformFileExists(utf8Name); if (HGFS_ERROR_SUCCESS == status) { status = HGFS_ERROR_ACCESS_DENIED; } LOG(4, ("HgfsServerDeleteDir: failed access check, error %d\n", status)); } else { LOG(4, ("%s: removing \"%s\"\n", __FUNCTION__, utf8Name)); status = HgfsPlatformDeleteDirByName(utf8Name); } free(utf8Name); } else { LOG(4, ("%s: access check failed\n", __FUNCTION__)); status = HgfsPlatformConvertFromNameStatus(nameStatus); } } if (HGFS_ERROR_SUCCESS == status) { if (!HgfsPackDeleteReply(input->packet, input->metaPacket, input->op, &replyPayloadSize, input->session)) { status = HGFS_ERROR_INTERNAL; } } } else { status = HGFS_ERROR_PROTOCOL; } HgfsServerCompleteRequest(status, replyPayloadSize, input); } /* *----------------------------------------------------------------------------- * * HgfsServerServerLockChange -- * * Called by the client when it wants to either acquire an oplock on a file * that was previously opened, or when it wants to release/downgrade an * oplock on a file that was previously oplocked. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerServerLockChange(HgfsInputParam *input) // IN: Input params { HGFS_ASSERT_INPUT(input); HgfsServerCompleteRequest(HGFS_ERROR_NOT_SUPPORTED, 0, input); } /* *----------------------------------------------------------------------------- * * HgfsServerWriteWin32Stream -- * * Handle a write request in the WIN32_STREAM_ID format. * * Results: * ERROR_SUCCESS or an appropriate Win32 error code. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerWriteWin32Stream(HgfsInputParam *input) // IN: Input params { uint32 actualSize; HgfsInternalStatus status; HgfsHandle file; char *dataToWrite; Bool doSecurity; size_t replyPayloadSize = 0; size_t requiredSize; HGFS_ASSERT_INPUT(input); if (HgfsUnpackWriteWin32StreamRequest(input->payload, input->payloadSize, input->op, &file, &dataToWrite, &requiredSize, &doSecurity)) { status = HgfsPlatformWriteWin32Stream(file, dataToWrite, (uint32)requiredSize, doSecurity, &actualSize, input->session); if (HGFS_ERROR_SUCCESS == status) { if (!HgfsPackWriteWin32StreamReply(input->packet, input->metaPacket, input->op, actualSize, &replyPayloadSize, input->session)) { status = HGFS_ERROR_INTERNAL; } } } else { status = HGFS_ERROR_PROTOCOL; } HgfsServerCompleteRequest(status, replyPayloadSize, input); } /* *----------------------------------------------------------------------------- * * HgfsServerSetDirWatchByHandle -- * * Sets directory notification watch request using directory handle. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsInternalStatus HgfsServerSetDirWatchByHandle(HgfsInputParam *input, // IN: Input params HgfsHandle dir, // IN: directory handle uint32 events, // IN: event types to report Bool watchTree, // IN: recursive watch HgfsSubscriberHandle *watchId) // OUT: watch id { HgfsInternalStatus status; char *fileName = NULL; size_t fileNameSize; HgfsSharedFolderHandle sharedFolder = HGFS_INVALID_FOLDER_HANDLE; LOG(8, ("%s: entered\n", __FUNCTION__)); ASSERT(watchId != NULL); if (HgfsHandle2NotifyInfo(dir, input->session, &fileName, &fileNameSize, &sharedFolder)) { LOG(4, ("%s: adding a subscriber on shared folder handle %#x\n", __FUNCTION__, sharedFolder)); *watchId = HgfsNotify_AddSubscriber(sharedFolder, fileName, events, watchTree, HgfsServerDirWatchEvent, input->session); status = (HGFS_INVALID_SUBSCRIBER_HANDLE == *watchId) ? HGFS_ERROR_INTERNAL : HGFS_ERROR_SUCCESS; LOG(4, ("%s: result of add subscriber id %"FMT64"x status %u\n", __FUNCTION__, *watchId, status)); } else { status = HGFS_ERROR_INTERNAL; } free(fileName); LOG(8, ("%s: exit %u\n", __FUNCTION__, status)); return status; } /* *----------------------------------------------------------------------------- * * HgfsServerSetDirWatchByName -- * * Sets directory notification watch request using directory name. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsInternalStatus HgfsServerSetDirWatchByName(HgfsInputParam *input, // IN: Input params char *cpName, // IN: directory name uint32 cpNameSize, // IN: directory name length uint32 caseFlags, // IN: case flags uint32 events, // IN: event types to report Bool watchTree, // IN: recursive watch HgfsSubscriberHandle *watchId) // OUT: watch id { HgfsInternalStatus status; HgfsNameStatus nameStatus; char *utf8Name = NULL; size_t utf8NameLen; HgfsShareInfo shareInfo; HgfsSharedFolderHandle sharedFolder = HGFS_INVALID_FOLDER_HANDLE; ASSERT(cpName != NULL); ASSERT(watchId != NULL); LOG(8, ("%s: entered\n",__FUNCTION__)); nameStatus = HgfsServerGetShareInfo(cpName, cpNameSize, caseFlags, &shareInfo, &utf8Name, &utf8NameLen); if (HGFS_NAME_STATUS_COMPLETE == nameStatus) { char const *inEnd = cpName + cpNameSize; char const *next; int len; ASSERT(utf8Name); /* * Get first component. */ len = CPName_GetComponent(cpName, inEnd, (char const **) &next); if (len < 0) { LOG(4, ("%s: get first component failed\n", __FUNCTION__)); nameStatus = HGFS_NAME_STATUS_FAILURE; } else if (0 == len) { /* See if we are dealing with the base of the namespace */ nameStatus = HGFS_NAME_STATUS_INCOMPLETE_BASE; } else { sharedFolder = HgfsServerGetShareHandle(cpName); } if (HGFS_NAME_STATUS_COMPLETE == nameStatus && HGFS_INVALID_FOLDER_HANDLE != sharedFolder) { if (cpNameSize > len + 1) { size_t nameSize = cpNameSize - len - 1; char tempBuf[HGFS_PATH_MAX]; char *tempPtr = tempBuf; size_t tempSize = sizeof tempBuf; nameStatus = CPName_ConvertFrom((char const **) &next, &nameSize, &tempSize, &tempPtr); if (HGFS_NAME_STATUS_COMPLETE == nameStatus) { LOG(8, ("%s: adding subscriber on share hnd %#x\n", __FUNCTION__, sharedFolder)); *watchId = HgfsNotify_AddSubscriber(sharedFolder, tempBuf, events, watchTree, HgfsServerDirWatchEvent, input->session); status = (HGFS_INVALID_SUBSCRIBER_HANDLE == *watchId) ? HGFS_ERROR_INTERNAL : HGFS_ERROR_SUCCESS; LOG(8, ("%s: adding subscriber on share hnd %#x result %u\n", __FUNCTION__, sharedFolder, status)); } else { LOG(4, ("%s: Conversion to platform specific name failed\n", __FUNCTION__)); status = HgfsPlatformConvertFromNameStatus(nameStatus); } } else { LOG(8, ("%s: adding subscriber on share hnd %#x\n", __FUNCTION__, sharedFolder)); *watchId = HgfsNotify_AddSubscriber(sharedFolder, "", events, watchTree, HgfsServerDirWatchEvent, input->session); status = (HGFS_INVALID_SUBSCRIBER_HANDLE == *watchId) ? HGFS_ERROR_INTERNAL : HGFS_ERROR_SUCCESS; LOG(8, ("%s: adding subscriber on share hnd %#x result %u\n", __FUNCTION__, sharedFolder, status)); } } else if (HGFS_NAME_STATUS_INCOMPLETE_BASE == nameStatus) { LOG(4, ("%s: Notification for root share is not supported yet\n", __FUNCTION__)); status = HGFS_ERROR_INVALID_PARAMETER; } else { LOG(4, ("%s: file not found.\n", __FUNCTION__)); status = HgfsPlatformConvertFromNameStatus(nameStatus); } } else { LOG(4, ("%s: file not found.\n", __FUNCTION__)); status = HgfsPlatformConvertFromNameStatus(nameStatus); } free(utf8Name); LOG(8, ("%s: exit %u\n",__FUNCTION__, status)); return status; } /* *----------------------------------------------------------------------------- * * HgfsServerSetDirNotifyWatch -- * * Handle a set directory notification watch request. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerSetDirNotifyWatch(HgfsInputParam *input) // IN: Input params { char *cpName; size_t cpNameSize; HgfsInternalStatus status; HgfsHandle dir; uint32 caseFlags; size_t replyPayloadSize = 0; uint32 flags; uint32 events; HgfsSubscriberHandle watchId = HGFS_INVALID_SUBSCRIBER_HANDLE; Bool useHandle; HGFS_ASSERT_INPUT(input); LOG(8, ("%s: entered\n", __FUNCTION__)); /* * If the active session does not support directory change notification - bail out * with an error immediately. Otherwise setting watch may succeed but no notification * will be delivered when a change occurs. */ if (!input->session->activeNotification) { HgfsServerCompleteRequest(HGFS_ERROR_PROTOCOL, 0, input); return; } if (HgfsUnpackSetWatchRequest(input->payload, input->payloadSize, input->op, &useHandle, &cpName, &cpNameSize, &flags, &events, &dir, &caseFlags)) { Bool watchTree = 0 != (flags & HGFS_NOTIFY_FLAG_WATCH_TREE); if (useHandle) { status = HgfsServerSetDirWatchByHandle(input, dir, events, watchTree, &watchId); } else { status = HgfsServerSetDirWatchByName(input, cpName, cpNameSize, caseFlags, events, watchTree, &watchId); } if (HGFS_ERROR_SUCCESS == status) { if (!HgfsPackSetWatchReply(input->packet, input->metaPacket, input->op, watchId, &replyPayloadSize, input->session)) { status = HGFS_ERROR_INTERNAL; } } } else { status = HGFS_ERROR_PROTOCOL; } HgfsServerCompleteRequest(status, replyPayloadSize, input); LOG(8, ("%s: exit %u\n", __FUNCTION__, status)); } /* *----------------------------------------------------------------------------- * * HgfsServerRemoveDirNotifyWatch -- * * Handle a remove directory notification watch request. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerRemoveDirNotifyWatch(HgfsInputParam *input) // IN: Input params { HgfsSubscriberHandle watchId; HgfsInternalStatus status; size_t replyPayloadSize = 0; LOG(8, ("%s: entered\n", __FUNCTION__)); HGFS_ASSERT_INPUT(input); if (HgfsUnpackRemoveWatchRequest(input->payload, input->payloadSize, input->op, &watchId)) { LOG(8, ("%s: remove subscriber on subscr id %"FMT64"x\n", __FUNCTION__, watchId)); if (HgfsNotify_RemoveSubscriber(watchId)) { status = HGFS_ERROR_SUCCESS; } else { status = HGFS_ERROR_INTERNAL; } LOG(8, ("%s: remove subscriber on subscr id %"FMT64"x result %u\n", __FUNCTION__, watchId, status)); } else { status = HGFS_ERROR_PROTOCOL; } if (HGFS_ERROR_SUCCESS == status) { if (!HgfsPackRemoveWatchReply(input->packet, input->metaPacket, input->op, &replyPayloadSize, input->session)) { status = HGFS_ERROR_INTERNAL; } } HgfsServerCompleteRequest(status, replyPayloadSize, input); LOG(8, ("%s: exit result %u\n", __FUNCTION__, status)); } /* *----------------------------------------------------------------------------- * * HgfsServerGetattr -- * * Handle a Getattr request. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerGetattr(HgfsInputParam *input) // IN: Input params { char *localName; HgfsAttrHint hints = 0; HgfsFileAttrInfo attr; HgfsInternalStatus status = 0; HgfsNameStatus nameStatus; char *cpName; size_t cpNameSize; char *targetName = NULL; uint32 targetNameLen = 0; HgfsHandle file; /* file handle from driver */ uint32 caseFlags = 0; HgfsShareOptions configOptions; size_t localNameLen; HgfsShareInfo shareInfo; size_t replyPayloadSize = 0; HGFS_ASSERT_INPUT(input); if (HgfsUnpackGetattrRequest(input->payload, input->payloadSize, input->op, &attr, &hints, &cpName, &cpNameSize, &file, &caseFlags)) { /* Client wants us to reuse an existing handle. */ if (hints & HGFS_ATTR_HINT_USE_FILE_DESC) { fileDesc fd; targetNameLen = 0; status = HgfsPlatformGetFd(file, input->session, FALSE, &fd); if (HGFS_ERROR_SUCCESS == status) { status = HgfsPlatformGetattrFromFd(fd, input->session, &attr); } else { LOG(4, ("%s: Could not get file descriptor\n", __FUNCTION__)); } } else { /* * Depending on whether this file/dir is real or virtual, either * forge its attributes or look them up in the actual filesystem. */ nameStatus = HgfsServerGetShareInfo(cpName, cpNameSize, caseFlags, &shareInfo, &localName, &localNameLen); switch (nameStatus) { case HGFS_NAME_STATUS_INCOMPLETE_BASE: /* * This is the base of our namespace; make up fake status for * this directory. */ LOG(4, ("%s: getting attrs for base dir\n", __FUNCTION__)); HgfsPlatformGetDefaultDirAttrs(&attr); break; case HGFS_NAME_STATUS_COMPLETE: /* This is a regular lookup; proceed as usual */ ASSERT(localName); /* Get the config options. */ nameStatus = HgfsServerPolicy_GetShareOptions(cpName, cpNameSize, &configOptions); if (HGFS_NAME_STATUS_COMPLETE == nameStatus) { status = HgfsPlatformGetattrFromName(localName, configOptions, cpName, &attr, &targetName); } else { LOG(4, ("%s: no matching share: %s.\n", __FUNCTION__, cpName)); status = HGFS_ERROR_FILE_NOT_FOUND; } free(localName); if (HGFS_ERROR_SUCCESS == status && !HgfsServerPolicy_CheckMode(HGFS_OPEN_MODE_READ_ONLY, shareInfo.writePermissions, shareInfo.readPermissions)) { status = HGFS_ERROR_ACCESS_DENIED; } else if (status != HGFS_ERROR_SUCCESS) { /* * If it is a dangling share server should not return * HGFS_ERROR_FILE_NOT_FOUND * to the client because it causes confusion: a name that is returned * by directory enumeration should not produce "name not found" * error. * Replace it with a more appropriate error code: no such device. */ if (status == HGFS_ERROR_FILE_NOT_FOUND && HgfsIsShareRoot(cpName, cpNameSize)) { status = HGFS_ERROR_IO; } } break; default: status = HgfsPlatformHandleIncompleteName(nameStatus, &attr); } targetNameLen = targetName ? strlen(targetName) : 0; } if (HGFS_ERROR_SUCCESS == status) { if (!HgfsPackGetattrReply(input->packet, input->metaPacket, &attr, targetName, targetNameLen, &replyPayloadSize, input->session)) { status = HGFS_ERROR_INTERNAL; } } } else { status = HGFS_ERROR_PROTOCOL; } free(targetName); HgfsServerCompleteRequest(status, replyPayloadSize, input); } /* *----------------------------------------------------------------------------- * * HgfsServerSetattr -- * * Handle a Setattr request. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerSetattr(HgfsInputParam *input) // IN: Input params { HgfsInternalStatus status = HGFS_ERROR_SUCCESS; HgfsNameStatus nameStatus; HgfsFileAttrInfo attr; char *cpName; size_t cpNameSize = 0; HgfsAttrHint hints = 0; HgfsOpenMode shareMode; uint32 caseFlags = 0; HgfsShareInfo shareInfo; HgfsHandle file; size_t replyPayloadSize = 0; HGFS_ASSERT_INPUT(input); if (HgfsUnpackSetattrRequest(input->payload, input->payloadSize, input->op, &attr, &hints, &cpName, &cpNameSize, &file, &caseFlags)) { /* Client wants us to reuse an existing handle. */ if (hints & HGFS_ATTR_HINT_USE_FILE_DESC) { if (HgfsHandle2ShareMode(file, input->session, &shareMode)) { if (HGFS_OPEN_MODE_READ_ONLY != shareMode) { status = HgfsPlatformSetattrFromFd(file, input->session, &attr, hints); } else { status = HGFS_ERROR_ACCESS_DENIED; } } else { LOG(4, ("%s: could not get share mode fd %d\n", __FUNCTION__, file)); status = HGFS_ERROR_INVALID_HANDLE; } } else { /* Client wants us to open a new handle for this operation. */ char *utf8Name = NULL; size_t utf8NameLen; nameStatus = HgfsServerGetShareInfo(cpName, cpNameSize, caseFlags, &shareInfo, &utf8Name, &utf8NameLen); if (HGFS_NAME_STATUS_COMPLETE == nameStatus) { fileDesc hFile; HgfsServerLock serverLock = HGFS_LOCK_NONE; HgfsShareOptions configOptions; /* * XXX: If the client has an oplock on this file, it must reuse the * handle for the oplocked node (or break the oplock) prior to making * a setattr request. Fail this request. */ if (!HgfsServerPolicy_CheckMode(HGFS_OPEN_MODE_WRITE_ONLY, shareInfo.writePermissions, shareInfo.readPermissions)) { status = HGFS_ERROR_ACCESS_DENIED; } else if (HGFS_NAME_STATUS_COMPLETE != HgfsServerPolicy_GetShareOptions(cpName, cpNameSize, &configOptions)) { LOG(4, ("%s: no matching share: %s.\n", __FUNCTION__, cpName)); status = HGFS_ERROR_FILE_NOT_FOUND; } else if (HgfsFileHasServerLock(utf8Name, input->session, &serverLock, &hFile)) { LOG(4, ("%s: An open, oplocked handle exists for " "this file. The client should retry with that handle\n", __FUNCTION__)); status = HGFS_ERROR_PATH_BUSY; } else { status = HgfsPlatformSetattrFromName(utf8Name, &attr, configOptions, hints); } free(utf8Name); } else { LOG(4, ("%s: file not found.\n", __FUNCTION__)); status = HgfsPlatformConvertFromNameStatus(nameStatus); } } if (HGFS_ERROR_SUCCESS == status) { if (!HgfsPackSetattrReply(input->packet, input->metaPacket, attr.requestType, &replyPayloadSize, input->session)) { status = HGFS_ERROR_INTERNAL; } } } else { status = HGFS_ERROR_PROTOCOL; } HgfsServerCompleteRequest(status, replyPayloadSize, input); } /* *----------------------------------------------------------------------------- * * HgfsServerValidateOpenParameters -- * * Performs sanity check of the input parameters. * * Results: * HGFS_ERROR_SUCCESS if the parameters are valid. * Appropriate error code otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsInternalStatus HgfsServerValidateOpenParameters(HgfsFileOpenInfo *openInfo, // IN/OUT: openfile info Bool *denyCreatingFile, // OUT: No new files int *followSymlinks) // OUT: Host resolves link { size_t utf8NameLen; HgfsInternalStatus status; *followSymlinks = 0; *denyCreatingFile = FALSE; if ((openInfo->mask & HGFS_OPEN_VALID_MODE)) { HgfsNameStatus nameStatus; /* It is now safe to read the file name. */ nameStatus = HgfsServerGetShareInfo(openInfo->cpName, openInfo->cpNameSize, openInfo->caseFlags, &openInfo->shareInfo, &openInfo->utf8Name, &utf8NameLen); if (HGFS_NAME_STATUS_COMPLETE == nameStatus) { if (openInfo->mask & HGFS_OPEN_VALID_FLAGS) { HgfsOpenFlags savedOpenFlags = openInfo->flags; if (HgfsServerCheckOpenFlagsForShare(openInfo, &openInfo->flags)) { HgfsShareOptions configOptions; /* Get the config options. */ nameStatus = HgfsServerPolicy_GetShareOptions(openInfo->cpName, openInfo->cpNameSize, &configOptions); if (nameStatus == HGFS_NAME_STATUS_COMPLETE) { *followSymlinks = HgfsServerPolicy_IsShareOptionSet(configOptions, HGFS_SHARE_FOLLOW_SYMLINKS); *denyCreatingFile = savedOpenFlags != openInfo->flags; status = HGFS_ERROR_SUCCESS; } else { LOG(4, ("%s: no matching share: %s.\n", __FUNCTION__, openInfo->cpName)); *denyCreatingFile = TRUE; status = HGFS_ERROR_FILE_NOT_FOUND; } } else { /* Incompatible open mode with share mode. */ status = HGFS_STATUS_ACCESS_DENIED; } } else { status = HGFS_ERROR_PROTOCOL; } } else { /* * Check if the name does not exist - the share was not found. * Then it could one of two things: the share was removed/disabled; * or we could be in the root share itself and have a new name. * To return the correct error, if we are in the root share, * we must check the open mode too - creation of new files/folders * should fail access denied, for anything else "not found" is acceptable. */ if (nameStatus == HGFS_NAME_STATUS_DOES_NOT_EXIST) { if ((openInfo->mask & HGFS_OPEN_VALID_FLAGS && (openInfo->flags == HGFS_OPEN_CREATE || openInfo->flags == HGFS_OPEN_CREATE_SAFE || openInfo->flags == HGFS_OPEN_CREATE_EMPTY)) && HgfsServerIsSharedFolderOnly(openInfo->cpName, openInfo->cpNameSize)) { nameStatus = HGFS_NAME_STATUS_ACCESS_DENIED; LOG(4, ("%s: New file creation in share root not allowed\n", __FUNCTION__)); } else { LOG(4, ("%s: Shared folder not found\n", __FUNCTION__)); } } else { LOG(4, ("%s: Shared folder access error %u\n", __FUNCTION__, nameStatus)); } status = HgfsPlatformConvertFromNameStatus(nameStatus); } } else { LOG(4, ("%s: filename or mode not provided\n", __FUNCTION__)); status = HGFS_ERROR_PROTOCOL; } return status; } /* *----------------------------------------------------------------------------- * * HgfsServerOpen -- * * Handle an Open request. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerOpen(HgfsInputParam *input) // IN: Input params { HgfsInternalStatus status; fileDesc newHandle; HgfsLocalId localId; HgfsFileOpenInfo openInfo; fileDesc fileDesc; HgfsServerLock serverLock = HGFS_LOCK_NONE; size_t replyPayloadSize = 0; HGFS_ASSERT_INPUT(input); if (HgfsUnpackOpenRequest(input->payload, input->payloadSize, input->op, &openInfo)) { int followSymlinks; Bool denyCreatingFile; status = HgfsServerValidateOpenParameters(&openInfo, &denyCreatingFile, &followSymlinks); if (HGFS_ERROR_SUCCESS == status) { ASSERT(openInfo.utf8Name); LOG(4, ("%s: opening \"%s\", mode %u, flags %u, perms %u%u%u%u attr %u\n", __FUNCTION__, openInfo.utf8Name, openInfo.mode, openInfo.mask & HGFS_OPEN_VALID_FLAGS ? openInfo.flags : 0, (openInfo.mask & HGFS_OPEN_VALID_SPECIAL_PERMS) ? openInfo.specialPerms : 0, (openInfo.mask & HGFS_OPEN_VALID_OWNER_PERMS) ? openInfo.ownerPerms : 0, (openInfo.mask & HGFS_OPEN_VALID_GROUP_PERMS) ? openInfo.groupPerms : 0, (openInfo.mask & HGFS_OPEN_VALID_OTHER_PERMS) ? openInfo.otherPerms : 0, openInfo.mask & HGFS_OPEN_VALID_FILE_ATTR ? (uint32)openInfo.attr : 0)); /* * XXX: Before opening the file, see if we already have this file opened on * the server with an oplock on it. If we do, we must fail the new open * request, otherwise we will trigger an oplock break that the guest cannot * handle at this time (since the HGFS server is running in the context of * the vcpu thread), and we'll deadlock. * * Until we overcome this limitation via Crosstalk, we will be extra smart * in the client drivers so as to prevent open requests on handles that * already have an oplock. And the server will protect itself like so. * * XXX: With some extra effort, we could allow a second open for read here, * since that won't break a shared oplock, but the clients should already * realize that the second open can be avoided via sharing handles, too. */ if (!HgfsFileHasServerLock(openInfo.utf8Name, input->session, &serverLock, &fileDesc)) { /* See if the name is valid, and if so add it and return the handle. */ status = HgfsPlatformValidateOpen(&openInfo, followSymlinks, input->session, &localId, &newHandle); if (status == HGFS_ERROR_SUCCESS) { ASSERT(newHandle >= 0); /* * Open succeeded, so make new node and return its handle. If we fail, * it's almost certainly an internal server error. */ if (HgfsCreateAndCacheFileNode(&openInfo, &localId, newHandle, FALSE, input->session)) { if (!HgfsPackOpenReply(input->packet, input->metaPacket, &openInfo, &replyPayloadSize, input->session)) { status = HGFS_ERROR_INTERNAL; } } } else if (denyCreatingFile && HGFS_ERROR_FILE_NOT_FOUND == status) { status = HGFS_ERROR_ACCESS_DENIED; } } else { status = HGFS_ERROR_PATH_BUSY; } free(openInfo.utf8Name); } } else { status = HGFS_ERROR_PROTOCOL; } HgfsServerCompleteRequest(status, replyPayloadSize, input); } /* *----------------------------------------------------------------------------- * * HgfsServerSearchReadAttrToMask -- * * Sets a search read information mask from the retrieved attribute * information. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void HgfsServerSearchReadAttrToMask(HgfsFileAttrInfo *attr, // IN/OUT: attributes for entry HgfsSearchReadMask *mask) // IN/OUT: what info is required/returned { if (0 != (attr->mask & HGFS_ATTR_VALID_TYPE)) { *mask |= (HGFS_SEARCH_READ_FILE_NODE_TYPE); } if (0 != (attr->mask & HGFS_ATTR_VALID_SIZE)) { *mask |= (HGFS_SEARCH_READ_FILE_SIZE); } if (0 != (attr->mask & HGFS_ATTR_VALID_ALLOCATION_SIZE)) { *mask |= (HGFS_SEARCH_READ_ALLOCATION_SIZE); } if (0 != (attr->mask & (HGFS_ATTR_VALID_CREATE_TIME | HGFS_ATTR_VALID_ACCESS_TIME | HGFS_ATTR_VALID_WRITE_TIME | HGFS_ATTR_VALID_CHANGE_TIME))) { *mask |= (HGFS_SEARCH_READ_TIME_STAMP); } if (0 != (attr->mask & (HGFS_ATTR_VALID_FLAGS | HGFS_ATTR_VALID_OWNER_PERMS | HGFS_ATTR_VALID_GROUP_PERMS | HGFS_ATTR_VALID_OTHER_PERMS))) { Bool isReadOnly = TRUE; *mask |= (HGFS_SEARCH_READ_FILE_ATTRIBUTES); /* * For V4 we don't return the permissions as they are really not * used. Only used to see if the entry is read only. So set the * attribute flag if the entry is read only. */ if (attr->mask & HGFS_ATTR_VALID_OWNER_PERMS && attr->ownerPerms & HGFS_PERM_WRITE) { isReadOnly = FALSE; } if (attr->mask & HGFS_ATTR_VALID_GROUP_PERMS && attr->groupPerms & HGFS_PERM_WRITE) { isReadOnly = FALSE; } if (attr->mask & HGFS_ATTR_VALID_OTHER_PERMS && attr->otherPerms & HGFS_PERM_WRITE) { isReadOnly = FALSE; } if (isReadOnly) { attr->flags |= HGFS_ATTR_READONLY; attr->mask |= HGFS_ATTR_VALID_FLAGS; } } if (0 != (attr->mask & (HGFS_ATTR_VALID_FILEID | HGFS_ATTR_VALID_NON_STATIC_FILEID))) { *mask |= (HGFS_SEARCH_READ_FILE_ID); } } /* *----------------------------------------------------------------------------- * * HgfsGetDirEntry -- * * Gets a directory entry at specified offset. * * Results: * A platform specific error or success. * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsInternalStatus HgfsGetDirEntry(HgfsHandle hgfsSearchHandle, // IN: ID for search data HgfsSearch *search, // IN: search data HgfsShareOptions configOptions, // IN: share configuration settings HgfsSessionInfo *session, // IN: session we are called in HgfsSearchReadInfo *info, // IN/OUT: request details HgfsSearchReadEntry *entry, // OUT: directory entry Bool *moreEntries) // OUT: any more entries { HgfsInternalStatus status = HGFS_ERROR_SUCCESS; DirectoryEntry *dent; HgfsSearchReadMask infoRetrieved; HgfsSearchReadMask infoRequested; HgfsFileAttrInfo *attr; char **entryName; uint32 *nameLength; Bool getAttrs; Bool unescapeName = TRUE; uint32 requestedIndex; infoRequested = info->requestedMask; attr = &entry->attr; entryName = &entry->name; nameLength = &entry->nameLength; requestedIndex = info->currentIndex; getAttrs = (0 != (infoRequested & (HGFS_SEARCH_READ_FILE_SIZE | HGFS_SEARCH_READ_ALLOCATION_SIZE | HGFS_SEARCH_READ_TIME_STAMP | HGFS_SEARCH_READ_FILE_ATTRIBUTES | HGFS_SEARCH_READ_FILE_ID | HGFS_SEARCH_READ_FILE_NODE_TYPE))); /* Clear out what we will return. */ infoRetrieved = 0; memset(attr, 0, sizeof *attr); dent = HgfsGetSearchResult(hgfsSearchHandle, session, requestedIndex, FALSE); if (dent) { unsigned int length; char *fullName; char *sharePath; size_t sharePathLen; size_t fullNameLen; HgfsServerLock serverLock = HGFS_LOCK_NONE; fileDesc fileDesc; length = strlen(dent->d_name); /* Each type of search gets a dent's attributes in a different way. */ switch (search->type) { case DIRECTORY_SEARCH_TYPE_DIR: /* * Construct the UTF8 version of the full path to the file, and call * HgfsGetattrFromName to get the attributes of the file. */ fullNameLen = search->utf8DirLen + 1 + length; fullName = (char *)malloc(fullNameLen + 1); if (fullName) { memcpy(fullName, search->utf8Dir, search->utf8DirLen); fullName[search->utf8DirLen] = DIRSEPC; memcpy(&fullName[search->utf8DirLen + 1], dent->d_name, length + 1); LOG(4, ("%s: about to stat \"%s\"\n", __FUNCTION__, fullName)); /* Do we need to query the attributes information? */ if (getAttrs) { /* * XXX: It is unreasonable to make the caller either 1) pass existing * handles for directory objects as part of the SearchRead, or 2) * prior to calling SearchRead on a directory, break all oplocks on * that directory's objects. * * To compensate for that, if we detect that this directory object * has an oplock, we'll quietly reuse the handle. Note that this * requires clients who take out an exclusive oplock to open a * handle with read as well as write access, otherwise we'll fail * further down in HgfsStat. * * XXX: We could open a new handle safely if its a shared oplock. * But isn't this handle sharing always desirable? */ if (HgfsFileHasServerLock(fullName, session, &serverLock, &fileDesc)) { LOG(4, ("%s: Reusing existing oplocked handle " "to avoid oplock break deadlock\n", __FUNCTION__)); status = HgfsPlatformGetattrFromFd(fileDesc, session, attr); } else { status = HgfsPlatformGetattrFromName(fullName, configOptions, search->utf8ShareName, attr, NULL); } if (HGFS_ERROR_SUCCESS != status) { HgfsOp savedOp = attr->requestType; LOG(4, ("%s: stat FAILED %s (%d)\n", __FUNCTION__, fullName, status)); memset(attr, 0, sizeof *attr); attr->requestType = savedOp; attr->type = HGFS_FILE_TYPE_REGULAR; attr->mask = HGFS_ATTR_VALID_TYPE; status = HGFS_ERROR_SUCCESS; } } /* * Update the search read mask for the attributes information. */ HgfsServerSearchReadAttrToMask(attr, &infoRetrieved); free(fullName); } else { LOG(4, ("%s: could not allocate space for \"%s\\%s\"\n", __FUNCTION__, search->utf8Dir, dent->d_name)); status = HGFS_ERROR_NOT_ENOUGH_MEMORY; } break; case DIRECTORY_SEARCH_TYPE_BASE: /* * We only want to unescape names that we could have escaped. * This cannot apply to our shares since they are created by the user. * The client will take care of escaping anything it requires. */ unescapeName = FALSE; if (getAttrs) { /* * For a search enumerating all shares, give the default attributes * for '.' and ".." (which aren't really shares anyway). Each real * share gets resolved into its full path, and gets its attributes * via HgfsGetattrFromName. */ if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) { LOG(4, ("%s: assigning %s default attributes\n", __FUNCTION__, dent->d_name)); HgfsPlatformGetDefaultDirAttrs(attr); } else { HgfsNameStatus nameStatus; /* Check permission on the share and get the share path */ nameStatus = HgfsServerPolicy_GetSharePath(dent->d_name, length, HGFS_OPEN_MODE_READ_ONLY, &sharePathLen, (char const **)&sharePath); if (nameStatus == HGFS_NAME_STATUS_COMPLETE) { /* * Server needs to produce list of shares that is consistent with * the list defined in UI. If a share can't be accessed because of * problems on the host, the server still enumerates it and * returns to the client. */ /* * XXX: We will open a new handle for this, but it should be safe * from oplock-induced deadlock because these are all directories, * and thus cannot have oplocks placed on them. */ status = HgfsPlatformGetattrFromName(sharePath, configOptions, dent->d_name, attr, NULL); /* * For some reason, Windows marks drives as hidden and system. So * if one of the top level shared folders is mapped to a drive * letter (like C:\), then GetFileAttributesEx() will return hidden * and system attributes for that drive. We don't want that * since we want the users to see all top level shared folders. * Even in the case when the top level shared folder is mapped * to a non-drive hidden/system directory, we still want to display * it to the user. So make sure that system and hidden attributes * are not set. * Note, that for network shares this doesn't apply, since each * top level network share is a separate mount point that doesn't * have such attributes. So when we finally have per share * mounting, this hack will go away. * * See bug 125065. */ attr->flags &= ~(HGFS_ATTR_HIDDEN | HGFS_ATTR_SYSTEM); if (HGFS_ERROR_SUCCESS != status) { /* * The dent no longer exists. Log the event. */ LOG(4, ("%s: stat FAILED\n", __FUNCTION__)); status = HGFS_ERROR_SUCCESS; } } else { LOG(4, ("%s: No such share or access denied\n", __FUNCTION__)); status = HgfsPlatformConvertFromNameStatus(nameStatus); } } if (HGFS_ERROR_SUCCESS == status) { /* * Update the search read mask for the attributes information. */ HgfsServerSearchReadAttrToMask(attr, &infoRetrieved); } } break; case DIRECTORY_SEARCH_TYPE_OTHER: /* * The POSIX implementation of HgfsSearchOpen could not have created * this kind of search. */ #if !defined(_WIN32) NOT_IMPLEMENTED(); #endif /* * We only want to unescape names that we could have escaped. * This cannot apply to these entries. */ unescapeName = FALSE; if (getAttrs) { /* * All "other" searches get the default attributes. This includes * an enumeration of drive, and the root enumeration (which contains * a "drive" dent and a "unc" dent). */ HgfsPlatformGetDefaultDirAttrs(attr); /* * Update the search read mask for the attributes information. */ HgfsServerSearchReadAttrToMask(attr, &infoRetrieved); } break; default: NOT_IMPLEMENTED(); break; } /* * We need to unescape the name before sending it back to the client */ if (HGFS_ERROR_SUCCESS == status) { *entryName = Util_SafeStrdup(dent->d_name); if (unescapeName) { *nameLength = HgfsEscape_Undo(*entryName, length + 1); } else { *nameLength = length; } infoRetrieved |= HGFS_SEARCH_READ_NAME; LOG(4, ("%s: dent name is \"%s\" len = %u\n", __FUNCTION__, *entryName, *nameLength)); } else { *entryName = NULL; *nameLength = 0; LOG(4, ("%s: error %d getting dent\n", __FUNCTION__, status)); } if (HGFS_ERROR_SUCCESS == status) { /* Update the entry fields for valid data and index for the dent. */ entry->fileIndex = requestedIndex; entry->mask = infoRetrieved; /* Retrieve any platform specific information from the dent. */ } free(dent); *moreEntries = TRUE; } else { /* End of directory entries marker. */ *entryName = NULL; *nameLength = 0; *moreEntries = FALSE; info->replyFlags |= HGFS_SEARCH_READ_REPLY_FINAL_ENTRY; } return status; } /* *----------------------------------------------------------------------------- * * HgfsDoSearchRead -- * * Gets all the directory entries that remain or as many that will * fit into the reply buffer from the specified index. Fill in the * reply with the records and complete the reply details. * * Results: * A platform specific error or success. * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsInternalStatus HgfsDoSearchRead(HgfsHandle hgfsSearchHandle, // IN: ID for search data HgfsSearch *search, // IN: search data HgfsShareOptions configOptions, // IN: share configuration settings HgfsSessionInfo *session, // IN: session we are called in HgfsSearchReadInfo *info, // IN/OUT: request details size_t *replyHeaderSize, // OUT: reply info written size size_t *replyDirentSize) // OUT: reply dirent written size { HgfsSearchReadEntry entry; size_t bytesWritten = 0; size_t bytesRemaining = 0; char *currentSearchReadRecord = NULL; char *lastSearchReadRecord = NULL; Bool moreEntries = TRUE; HgfsInternalStatus status = HGFS_ERROR_SUCCESS; info->currentIndex = info->startIndex; *replyHeaderSize = 0; *replyDirentSize = 0; while (moreEntries) { size_t offsetInBuffer = ROUNDUP(*replyDirentSize, sizeof (uint64)); if (info->payloadSize <= offsetInBuffer) { break; } memset(&entry, 0, sizeof entry); currentSearchReadRecord = (char*)info->replyPayload + offsetInBuffer; bytesRemaining = info->payloadSize - offsetInBuffer; bytesWritten = 0; status = HgfsGetDirEntry(hgfsSearchHandle, search, configOptions, session, info, &entry, &moreEntries); if (HGFS_ERROR_SUCCESS != status) { /* Failed to retrieve an entry record, bail. */ break; } if (!HgfsPackSearchReadReplyRecord(info->requestType, &entry, bytesRemaining, lastSearchReadRecord, currentSearchReadRecord, &bytesWritten)) { /* * The current entry is too large to be contained in the reply. * If this is the first entry returned then we have an error. * Otherwise, we return success for what is already in the reply. */ if (0 == info->numberRecordsWritten) { status = HGFS_ERROR_INTERNAL; } moreEntries = FALSE; } if (NULL != entry.name) { free(entry.name); } if (HGFS_ERROR_SUCCESS != status) { /* Failed to pack any entry records, bail. */ break; } /* * Only count records actually written to the reply. * (The final, empty record is not written for all protocol versions.) */ if (0 < bytesWritten) { if (0 != (info->flags & HGFS_SEARCH_READ_SINGLE_ENTRY)) { moreEntries = FALSE; } *replyDirentSize = ROUNDUP(*replyDirentSize, sizeof (uint64)) + bytesWritten; lastSearchReadRecord = currentSearchReadRecord; info->currentIndex++; info->numberRecordsWritten++; } } /* Now pack the search read reply common reply part. */ if (HgfsPackSearchReadReplyHeader(info, &bytesWritten)) { /* The search read reply common reply part size was already done so should be 0. */ *replyHeaderSize = bytesWritten; } else { status = HGFS_ERROR_PROTOCOL; } return status; } /* *----------------------------------------------------------------------------- * * HgfsServerSearchRead -- * * Handle a "Search Read" request. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerSearchRead(HgfsInputParam *input) // IN: Input params { HgfsInternalStatus status = HGFS_ERROR_SUCCESS; HgfsNameStatus nameStatus; HgfsHandle hgfsSearchHandle; HgfsSearch search; HgfsShareOptions configOptions = 0; size_t replyInfoSize = 0; size_t replyDirentSize = 0; size_t replyPayloadSize = 0; size_t inlineDataSize = 0; size_t baseReplySize; HgfsSearchReadInfo info; HGFS_ASSERT_INPUT(input); memset(&info, 0, sizeof info); /* * For search read V4 we use the whole packet buffer available to pack * as many replies as can fit into that size. For all previous versions * only one record is going to be returned, so we allow the old packet * max for the reply. */ if (HgfsUnpackSearchReadRequest(input->payload, input->payloadSize, input->op, &info, &baseReplySize, &inlineDataSize, &hgfsSearchHandle)) { LOG(4, ("%s: read search #%u, offset %u\n", __FUNCTION__, hgfsSearchHandle, info.startIndex)); if (!HgfsAllocInitReply(input->packet, input->metaPacket, baseReplySize + inlineDataSize, &info.reply, input->session)) { status = HGFS_ERROR_PROTOCOL; } else { if (inlineDataSize == 0) { info.replyPayload = HSPU_GetDataPacketBuf(input->packet, BUF_WRITEABLE, input->transportSession); } else { info.replyPayload = (char *)info.reply + baseReplySize; } if (info.replyPayload == NULL) { LOG(4, ("%s: Op %d reply buffer failure\n", __FUNCTION__, input->op)); status = HGFS_ERROR_PROTOCOL; } else { if (HgfsGetSearchCopy(hgfsSearchHandle, input->session, &search)) { /* Get the config options. */ if (search.utf8ShareNameLen != 0) { nameStatus = HgfsServerPolicy_GetShareOptions(search.utf8ShareName, search.utf8ShareNameLen, &configOptions); if (nameStatus != HGFS_NAME_STATUS_COMPLETE) { LOG(4, ("%s: no matching share: %s.\n", __FUNCTION__, search.utf8ShareName)); status = HGFS_ERROR_FILE_NOT_FOUND; } } else if (0 == info.startIndex) { HgfsSearch *rootSearch; MXUser_AcquireExclLock(input->session->searchArrayLock); rootSearch = HgfsSearchHandle2Search(hgfsSearchHandle, input->session); ASSERT(NULL != rootSearch); HgfsFreeSearchDirents(rootSearch); rootSearch->numDents = HgfsServerGetDents(HgfsServerPolicy_GetShares, HgfsServerPolicy_GetSharesInit, HgfsServerPolicy_GetSharesCleanup, &rootSearch->dents); if (((int) (rootSearch->numDents)) < 0) { ASSERT_DEVEL(0); LOG(4, ("%s: couldn't get root dents\n", __FUNCTION__)); rootSearch->numDents = 0; status = HGFS_ERROR_INTERNAL; } MXUser_ReleaseExclLock(input->session->searchArrayLock); } if (HGFS_ERROR_SUCCESS == status) { status = HgfsDoSearchRead(hgfsSearchHandle, &search, configOptions, input->session, &info, &replyInfoSize, &replyDirentSize); } if (HGFS_ERROR_SUCCESS == status) { replyPayloadSize = replyInfoSize + ((inlineDataSize == 0) ? 0 : replyDirentSize); } free(search.utf8Dir); free(search.utf8ShareName); } else { LOG(4, ("%s: handle %u is invalid\n", __FUNCTION__, hgfsSearchHandle)); status = HGFS_ERROR_INVALID_HANDLE; } } } } else { status = HGFS_ERROR_PROTOCOL; } HgfsServerCompleteRequest(status, replyPayloadSize, input); } /* *----------------------------------------------------------------------------- * * HgfsServerCreateSession -- * * Handle a "Create session" request. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerCreateSession(HgfsInputParam *input) // IN: Input params { size_t replyPayloadSize = 0; HgfsCreateSessionInfo info; HgfsInternalStatus status; HGFS_ASSERT_INPUT(input); if (HgfsUnpackCreateSessionRequest(input->payload, input->payloadSize, input->op, &info)) { HgfsSessionInfo *session; LOG(4, ("%s: create session\n", __FUNCTION__)); if (!HgfsServerAllocateSession(input->transportSession, input->transportSession->channelCapabilities, &session)) { status = HGFS_ERROR_NOT_ENOUGH_MEMORY; goto abort; } else { status = HgfsServerTransportAddSessionToList(input->transportSession, session); if (HGFS_ERROR_SUCCESS != status) { LOG(4, ("%s: Could not add session to the list.\n", __FUNCTION__)); HgfsServerSessionPut(session); goto abort; } } if (info.maxPacketSize < session->maxPacketSize) { session->maxPacketSize = info.maxPacketSize; } if (HgfsPackCreateSessionReply(input->packet, input->metaPacket, &replyPayloadSize, session)) { status = HGFS_ERROR_SUCCESS; } else { status = HGFS_ERROR_INTERNAL; } } else { status = HGFS_ERROR_PROTOCOL; } abort: HgfsServerCompleteRequest(status, replyPayloadSize, input); } /* *----------------------------------------------------------------------------- * * HgfsServerDestroySession -- * * Handle a "Destroy session" request. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerDestroySession(HgfsInputParam *input) // IN: Input params { HgfsTransportSessionInfo *transportSession; HgfsSessionInfo *session; size_t replyPayloadSize = 0; HgfsInternalStatus status; HGFS_ASSERT_INPUT(input); transportSession = input->transportSession; session = input->session; session->state = HGFS_SESSION_STATE_CLOSED; if (session->sessionId == transportSession->defaultSessionId) { transportSession->defaultSessionId = HGFS_INVALID_SESSION_ID; } /* * Remove the session from the list. By doing that, the refcount of * the session will be decremented. Later, we will be invoking * HgfsServerCompleteRequest which will decrement the session's * refcount and cleanup the session */ MXUser_AcquireExclLock(transportSession->sessionArrayLock); HgfsServerTransportRemoveSessionFromList(transportSession, session); MXUser_ReleaseExclLock(transportSession->sessionArrayLock); if (HgfsPackDestroySessionReply(input->packet, input->metaPacket, &replyPayloadSize, session)) { status = HGFS_ERROR_SUCCESS; } else { status = HGFS_ERROR_INTERNAL; } HgfsServerCompleteRequest(status, replyPayloadSize, input); HgfsServerSessionPut(session); } /* *----------------------------------------------------------------------------- * * HgfsBuildRelativePath -- * * Generates relative file path which need to be used a symbolic link * target which would generate target name defined in "target" if the path * to symbolic link file defined in the "source". * Both source and target parameters represent absolute paths. * * Results: * Allocated path that caller must free. * NULL if there is a low memory condition. * * Side effects: * None * *----------------------------------------------------------------------------- */ char* HgfsBuildRelativePath(const char* source, // IN: source file name const char* target) // IN: target file name { const char *relativeSource = source; const char *relativeTarget = target; const char* sourceSep; const char* targetSep; int level = 0; size_t targetSize; char *result; char *currentPosition; /* * First remove the part of the path which is common between source and * target */ while (*relativeSource != '\0' && *relativeTarget != '\0') { sourceSep = strchr(relativeSource, DIRSEPC); targetSep = strchr(relativeTarget, DIRSEPC); if (sourceSep == NULL || targetSep == NULL) { break; } if ((sourceSep - relativeSource) != (targetSep - relativeTarget)) { break; } if (strncmp(relativeSource, relativeTarget, (targetSep - relativeTarget)) != 0) { break; } relativeSource = sourceSep + 1; relativeTarget = targetSep + 1; }; /* * Find out how many directories deep the source file is from the common * part of the path. */ while(*relativeSource != '\0') { sourceSep = strchr(relativeSource, DIRSEPC); if (sourceSep != NULL) { /* Several consecutive separators mean only one level. */ while (*sourceSep == DIRSEPC) { sourceSep++; } if (*sourceSep != '\0') { level++; relativeSource = sourceSep; } else { break; } } else { break; } } /* * Consruct relative path by adding level number of "../" * to the relative target path. */ targetSize = level * HGFS_PARENT_DIR_LEN + strlen(relativeTarget) + sizeof '\0'; result = malloc(targetSize); currentPosition = result; if (result != NULL) { while (level != 0) { memcpy(currentPosition, HGFS_PARENT_DIR, HGFS_PARENT_DIR_LEN); level--; currentPosition += HGFS_PARENT_DIR_LEN; } memcpy(currentPosition, relativeTarget, strlen(relativeTarget) + sizeof '\0'); } return result; } /* *----------------------------------------------------------------------------- * * HgfsServerDirWatchEvent -- * * The callback is invoked by the file system change notification component * in response to a change event when the client has set at least one watch * on a directory. * * The function builds directory notification packet and queues it to be sent * to the client. It processes one notification at a time. Any consolidation of * packets is expected to occur at the transport layer. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerDirWatchEvent(HgfsSharedFolderHandle sharedFolder, // IN: shared folder HgfsSubscriberHandle subscriber, // IN: subsciber char* fileName, // IN: name of the file uint32 mask, // IN: event type struct HgfsSessionInfo *session) // IN: session info { HgfsPacket *packet = NULL; HgfsHeader *packetHeader = NULL; char *shareName = NULL; size_t shareNameLen; size_t sizeNeeded; uint32 flags; LOG(4, ("%s:Entered shr hnd %u hnd %"FMT64"x file %s mask %u\n", __FUNCTION__, sharedFolder, subscriber, fileName, mask)); if (!HgfsServerGetShareName(sharedFolder, &shareNameLen, &shareName)) { LOG(4, ("%s: failed to find shared folder for a handle %x\n", __FUNCTION__, sharedFolder)); goto exit; } sizeNeeded = HgfsPackCalculateNotificationSize(shareName, fileName); packetHeader = Util_SafeCalloc(1, sizeNeeded); packet = Util_SafeCalloc(1, sizeof *packet); packet->guestInitiated = FALSE; packet->metaPacketSize = sizeNeeded; packet->metaPacket = packetHeader; packet->dataPacketIsAllocated = TRUE; flags = 0; if (mask & HGFS_NOTIFY_EVENTS_DROPPED) { flags |= HGFS_NOTIFY_FLAG_OVERFLOW; } if (!HgfsPackChangeNotificationRequest(packetHeader, subscriber, shareName, fileName, mask, flags, session, &sizeNeeded)) { LOG(4, ("%s: failed to pack notification request\n", __FUNCTION__)); goto exit; } if (!HgfsPacketSend(packet, (char *)packetHeader, sizeNeeded, session->transportSession, 0)) { LOG(4, ("%s: failed to send notification to the host\n", __FUNCTION__)); goto exit; } /* The transport will call the server send complete callback to release the packets. */ packet = NULL; packetHeader = NULL; LOG(4, ("%s: Sent notify for: %u index: %"FMT64"u file name %s mask %x\n", __FUNCTION__, sharedFolder, subscriber, fileName, mask)); exit: if (shareName) { free(shareName); } if (packet) { free(packet); } if (packetHeader) { free(packetHeader); } } /* *----------------------------------------------------------------------------- * * HgfsIsShareRoot -- * * Checks if the cpName represents the root directory for a share. * Components in CPName format are separated by NUL characters. * CPName for the root of a share contains only one component thus * it does not have any embedded '\0' characters in the name. * * Results: * TRUE if it is the root directory, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool HgfsIsShareRoot(char const *cpName, // IN: name to test size_t cpNameSize) // IN: length of the name { size_t i; for (i = 0; i < cpNameSize; i++) { if (cpName[i] == '\0') { return FALSE; } } return TRUE; } #ifdef HGFS_OPLOCKS /* *----------------------------------------------------------------------------- * * HgfsServerOplockBreakReply -- * * The client was sent an oplock break request, and responded with this * reply. It contains the oplock status that the client is now in. Since * the break could have actually been a degrade, it is well within the * client's rights to transition to a non-broken state. We need to make * sure that such a transition was legal, acknowledge the brea * appropriately, and update our own state. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void HgfsServerOplockBreakReply(const unsigned char *packetIn, // IN: Reply packet unsigned int packetSize, // IN: Size of packet void *clientData) // IN: From request { HgfsReplyServerLockChange *reply; ServerLockData *lockData; ASSERT(packetIn); ASSERT(clientData); if (packetSize < sizeof *reply) { return; } reply = (HgfsReplyServerLockChange *)packetIn; lockData = (ServerLockData *)clientData; /* * XXX: It should be safe to ignore the status and id from the actual * HgfsReply. The only information we need to properly acknowledge the break * is the original fd and the new lease, which, in the case of a degrade, * is double checked in HgfsAckOplockBreak, so we'd be safe from a garbage * value. */ HgfsAckOplockBreak(lockData, reply->serverLock); } /* *----------------------------------------------------------------------------- * * HgfsServerOplockBreak -- * * When the host FS needs to break the oplock so that another client * can open the file, it signals the event in the overlapped structure * that we used to request an oplock. * This sets off the following chains of events: * 1. Send the oplock break request to the guest. * 2. Once the guest acknowledges the oplock break, the completion * routine GuestRpcServerRequestCallback will fire, causing * HgfsServerOplockBreakReply to also fire, which will break the oplock * on the host FS. * * Results: * None. * * Side effects: * If successful, allocates memory for the rpc request. * *----------------------------------------------------------------------------- */ void HgfsServerOplockBreak(ServerLockData *lockData) { HgfsHandle hgfsHandle; char *requestBuffer = NULL; HgfsRequestServerLockChange *request; HgfsServerLock lock; LOG(4, ("%s: entered\n", __FUNCTION__)); /* * XXX: Just because the file in not in the cache on the server, * does not mean it was closed on the client. It is possible that * we closed the file on the server because we ran out of space * in cache. That's why for now as long as a file has a lock, * we don't remove it from the node cache. This should be fixed. * * In any case, none of these cache-related failures should cause us to ack * the oplock break locally. That is because if the file wasn't in the * cache, or it had no lock, chances are someone else (maybe the VCPU * thread) broke the oplock and/or closed the file. */ if (!HgfsFileDesc2Handle(lockData->fileDesc, &hgfsHandle)) { LOG(4, ("%s: file is not in the cache\n", __FUNCTION__)); goto free_and_exit; } if (!HgfsHandle2ServerLock(hgfsHandle, &lock)) { LOG(4, ("%s: could not retrieve node's lock info.\n", __FUNCTION__)); goto free_and_exit; } if (lock == HGFS_LOCK_NONE) { LOG(4, ("%s: the file does not have a server lock.\n", __FUNCTION__)); goto free_and_exit; } /* * We need to setup the entire request here. The command prefix will be * added later, so save some space for it. * * XXX: This should probably go into a common allocation function that * other out-of-band requests can use. */ requestBuffer = malloc(sizeof *request + HGFS_CLIENT_CMD_LEN); if (requestBuffer == NULL) { LOG(4, ("%s: could not allocate memory.\n", __FUNCTION__)); goto ack_and_exit; } /* Save space for the command prefix. */ request = (HgfsRequestServerLockChange *) (requestBuffer + HGFS_CLIENT_CMD_LEN); request->header.op = HGFS_OP_SERVER_LOCK_CHANGE; request->header.id = 0; /* XXX */ request->file = hgfsHandle; request->newServerLock = lockData->serverLock; /* * Just send the request size for our actual request; our callee will * write in the command prefix and modify the request size appropriately. * * If for some reason we fail, we'll acknowledge the oplock break * immediately. */ if (HgfsServerManager_SendRequest(requestBuffer, sizeof *request, HgfsServerOplockBreakReply, lockData)) { return; } free(requestBuffer); ack_and_exit: HgfsAckOplockBreak(lockData, HGFS_LOCK_NONE); return; free_and_exit: free(lockData); } #endif /* * more testing */ #if 0 void TestNodeFreeList(void) { HgfsHandle array[10 * NUM_FILE_NODES]; HgfsFileNode *node; unsigned int i; printf("%s: begin >>>>>>>>>>>>>>>>>>>>>>>>>>>\n", __FUNCTION__); for (i = 0; i < sizeof array / sizeof array[0]; i++) { char tempName[20]; HgfsLocalId localId; Str_Sprintf(tempName, sizeof tempName, "name%u", i); printf("\nadding node with name: %s\n", tempName); localId.volumeId = 0; localId.fileId = i + 1000; node = HgfsAddNewFileNode(Util_SafeStrdup(tempName), &localId); array[i] = HgfsFileNode2Handle(node); } HgfsDumpAllNodes(); printf("done getting nodes, now freeing\n"); for (i = 0; i < sizeof array / sizeof array[0]; i++) { printf("removing node #%u\n", i); HgfsRemoveFileNode(&nodeArray[array[i]]); } HgfsDumpAllNodes(); printf("%s: end <<<<<<<<<<<<<<<<<<<<<<<<<< \n", __FUNCTION__); } void TestSearchFreeList(void) { HgfsHandle array[10 * NUM_SEARCHES]; HgfsSearch *search; unsigned int i; printf("%s: begin >>>>>>>>>>>>>>>>>>>>>>>>>>>\n", __FUNCTION__); for (i = 0; i < sizeof array / sizeof array[0]; i++) { char tempName[20]; Str_Sprintf(tempName, sizeof tempName, "baseDir%u", i); printf("\nadding search with baseDir: \"%s\"\n", tempName); search = HgfsAddNewSearch(Util_SafeStrdup(tempName)); array[i] = HgfsSearch2SearchHandle(search); } HgfsDumpAllSearches(); printf("done getting searches, now freeing\n"); for (i = 0; i < sizeof array / sizeof array[0]; i++) { printf("removing search #%u\n", i); HgfsRemoveSearch(&searchArray[array[i]]); } HgfsDumpAllSearches(); printf("%s: end <<<<<<<<<<<<<<<<<<<<<<<<<< \n", __FUNCTION__); } #endif open-vm-tools-9.4.0-1280544/lib/hgfsServer/hgfsServerLinux.c0000644765153500003110000043110412220061556021630 0ustar dtormts/********************************************************* * Copyright (C) 1998-2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * hgfsServerLinux.c -- * * This file contains the linux implementation of the server half * of the Host/Guest File System (hgfs), a.k.a. "Shared Folder". * * The hgfs server carries out filesystem requests that it receives * over the backdoor from a driver in the other world. */ #define _GNU_SOURCE // for O_NOFOLLOW #if defined(__APPLE__) #define _DARWIN_USE_64_BIT_INODE #endif #include #include #include #include #include #include #include // for utimes(2) #include #include #include #include #if defined(__FreeBSD__) # include #else # include # include #endif #include "vmware.h" #include "hgfsServerPolicy.h" // for security policy #include "hgfsServerInt.h" #include "hgfsEscape.h" #include "str.h" #include "cpNameLite.h" #include "hgfsUtil.h" // for cross-platform time conversion #include "posix.h" #include "file.h" #include "util.h" #include "su.h" #include "codeset.h" #include "unicodeOperations.h" #include "userlock.h" #if defined(linux) && !defined(SYS_getdents64) /* For DT_UNKNOWN */ # include #endif #ifndef VMX86_TOOLS # include "config.h" #endif #define LOGLEVEL_MODULE hgfs #include "loglevel_user.h" #if defined(__APPLE__) #include // for the alias manager #include // for CFString and CFURL #include // for getattrlist #include // for VERG / VDIR #endif /* * ALLPERMS (mode 07777) and ACCESSPERMS (mode 0777) are not defined in the * Solaris version of . */ #ifdef sun # define ACCESSPERMS (S_IRWXU|S_IRWXG|S_IRWXO) # define ALLPERMS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO) #endif #ifdef HGFS_OPLOCKS # include # include "sig.h" #endif /* * On Linux, we must wrap getdents64, as glibc does not wrap it for us. We use getdents64 * (rather than getdents) because with the latter, we'll get 64-bit offsets and inode * numbers. Note that getdents64 isn't supported everywhere, in particular, kernels older * than 2.4.1 do not implement it. On those older guests, we try using getdents(), and * translating the results to our DirectoryEntry structure... * * On FreeBSD and Mac platforms, getdents is implemented as getdirentries, and takes an * additional parameter which returns the position of the block read, which we don't care * about. */ #if defined(linux) static INLINE int getdents_linux(unsigned int fd, DirectoryEntry *dirp, unsigned int count) { # if defined(SYS_getdents64) return syscall(SYS_getdents64, fd, dirp, count); # else /* * Fall back to regular getdents on older Linux systems that don't have * getdents64. Because glibc does translation between the kernel's "struct dirent" and * the libc "struct dirent", this structure matches the one in linux/dirent.h, rather * than us using the libc 'struct dirent' directly */ struct linux_dirent { long d_ino; long d_off; /* __kernel_off_t expands to long on RHL 6.2 */ unsigned short d_reclen; char d_name[NAME_MAX]; } *dirp_temp; int retval; dirp_temp = alloca((sizeof *dirp_temp) * count); retval = syscall(SYS_getdents, fd, dirp_temp, count); if (retval > 0) { int i; /* * Translate from the Linux 'struct dirent' to the hgfs DirectoryEntry, since * they're not always the same layout. */ for (i = 0; i < count; i++) { dirp[i].d_ino = dirp_temp[i].d_ino; dirp[i].d_off = dirp_temp[i].d_off; dirp[i].d_reclen = dirp_temp[i].d_reclen; dirp[i].d_type = DT_UNKNOWN; memset(dirp[i].d_name, 0, sizeof dirp->d_name); memcpy(dirp[i].d_name, dirp_temp[i].d_name, ((sizeof dirp->d_name) < (sizeof dirp_temp->d_name)) ? (sizeof dirp->d_name) : (sizeof dirp_temp->d_name)); } } return retval; # endif } # define getdents getdents_linux #elif defined(__FreeBSD__) #define getdents(fd, dirp, count) \ ({ \ long basep; \ getdirentries(fd, dirp, count, &basep); \ }) #elif defined(__APPLE__) static INLINE int getdents_apple(DIR *fd, // IN DirectoryEntry *dirp, // OUT unsigned int count) // IN: ignored { int res = 0; struct dirent *dirEntry; dirEntry = readdir(fd); if (NULL != dirEntry) { memcpy(dirp, dirEntry, dirEntry->d_reclen); res = dirEntry->d_reclen; } return res; } # define getdents getdents_apple #endif /* * O_DIRECTORY is only relevant on Linux. For other platforms, we'll hope that * the kernel is smart enough to deny getdents(2) (or getdirentries(2)) on * files which aren't directories. * * Likewise, O_NOFOLLOW doesn't exist on Solaris 9. Oh well. */ #ifndef O_DIRECTORY #define O_DIRECTORY 0 #endif #ifndef O_NOFOLLOW #define O_NOFOLLOW 0 #endif #if defined(sun) || defined(linux) || \ (defined(__FreeBSD_version) && __FreeBSD_version < 490000) /* * Implements futimes(), which was introduced in glibc 2.3.3. FreeBSD 3.2 * doesn't have it, but 4.9 does. Unfortunately, these early FreeBSD versions * don't have /proc/self, so futimes() will simply fail. For now the only * caller to futimes() is HgfsServerSetattr which doesn't get invoked at all * in the HGFS server which runs in the Tools, so it's OK. */ #define PROC_SELF_FD "/proc/self/fd/" #define STRLEN_OF_MAXINT_AS_STRING 10 int futimes(int fd, const struct timeval times[2]) { #ifndef sun /* * Hack to allow the timevals in futimes() to be const even when utimes() * expects non-const timevals. This is the case on glibc up to 2.3 or * thereabouts. */ struct timeval mytimes[2]; /* Maximum size of "/proc/self/fd/" as a string. Accounts for nul. */ char nameBuffer[sizeof PROC_SELF_FD + STRLEN_OF_MAXINT_AS_STRING]; mytimes[0] = times[0]; mytimes[1] = times[1]; if (snprintf(nameBuffer, sizeof nameBuffer, PROC_SELF_FD "%d", fd) < 0) { return -1; } return Posix_Utimes(nameBuffer, mytimes); #else /* !sun */ return futimesat(fd, NULL, times); #endif /* !sun */ } #undef PROC_SELF_FD #undef STRLEN_OF_MAXINT_AS_STRING #endif #if defined(__APPLE__) struct FInfoAttrBuf { uint32 length; fsobj_type_t objType; char finderInfo[32]; }; #endif /* * Taken from WinNT.h. * For verifying the Windows client which can ask for delete access as well as the * standard read, write, execute permissions. * XXX - should probably be moved into a header file and may need to be expanded if * Posix looks at the access mode more thoroughly or we expand the set of cross-platform * access mode flags. */ #define DELETE (0x00010000L) /* * Server open flags, indexed by HgfsOpenFlags. Stolen from * lib/fileIOPosix.c * * Using O_NOFOLLOW will allow us to forgo a (racy) symlink check just * before opening the file. * * Using O_NONBLOCK will prevent us from blocking the HGFS server if * we open a FIFO. */ static const int HgfsServerOpenFlags[] = { O_NONBLOCK | O_NOFOLLOW, O_NONBLOCK | O_NOFOLLOW | O_TRUNC, O_NONBLOCK | O_NOFOLLOW | O_CREAT, O_NONBLOCK | O_NOFOLLOW | O_CREAT | O_EXCL, O_NONBLOCK | O_NOFOLLOW | O_CREAT | O_TRUNC, }; /* * Server open mode, indexed by HgfsOpenMode. */ static const int HgfsServerOpenMode[] = { O_RDONLY, O_WRONLY, O_RDWR, }; /* Local functions. */ static HgfsInternalStatus HgfsGetattrResolveAlias(char const *fileName, char **targetName); static void HgfsStatToFileAttr(struct stat *stats, uint64 *creationTime, HgfsFileAttrInfo *attr); static int HgfsStat(const char* fileName, Bool followLink, struct stat *stats, uint64 *creationTime); static int HgfsFStat(int fd, struct stat *stats, uint64 *creationTime); static void HgfsGetSequentialOnlyFlagFromName(const char *fileName, HgfsFileAttrInfo *attr); static void HgfsGetSequentialOnlyFlagFromFd(int fd, HgfsFileAttrInfo *attr); static int HgfsConvertComponentCase(char *currentComponent, const char *dirPath, const char **convertedComponent, size_t *convertedComponentSize); static int HgfsConstructConvertedPath(char **path, size_t *pathSize, char *convertedPath, size_t convertedPathSize); static int HgfsCaseInsensitiveLookup(const char *sharePath, size_t sharePathLength, char *fileName, size_t fileNameLength, char **convertedFileName, size_t *convertedFileNameLength); static Bool HgfsSetattrMode(struct stat *statBuf, HgfsFileAttrInfo *attr, mode_t *newPermissions); static Bool HgfsSetattrOwnership(HgfsFileAttrInfo *attr, uid_t *newUid, gid_t *newGid); static HgfsInternalStatus HgfsSetattrTimes(struct stat *statBuf, HgfsFileAttrInfo *attr, HgfsAttrHint hints, struct timeval *accessTime, struct timeval *modTime, Bool *timesChanged); static HgfsInternalStatus HgfsGetHiddenXAttr(char const *fileName, Bool *attribute); static HgfsInternalStatus HgfsSetHiddenXAttr(char const *fileName, Bool value, mode_t permissions); static HgfsInternalStatus HgfsEffectivePermissions(char *fileName, Bool readOnlyShare, uint32 *permissions); static uint64 HgfsGetCreationTime(const struct stat *stats); #ifdef HGFS_OPLOCKS /* *----------------------------------------------------------------------------- * * HgfsServerSigOplockBreak -- * * Handle a pending oplock break. Called from the VMX poll loop context. * All we really do is set up the state for an oplock break and call * HgfsServerOplockBreak which will do the rest of the work. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void HgfsServerSigOplockBreak(int sigNum, // IN: Signal number siginfo_t *info, // IN: Additional info about signal ucontext_t *u, // IN: Interrupted context (regs etc) void *clientData) // IN: Ignored { ServerLockData *lockData; int newLease, fd; HgfsServerLock newServerLock; ASSERT(sigNum == SIGIO); ASSERT(info); ASSERT(clientData == NULL); fd = info->si_fd; LOG(4, ("%s: Received SIGIO for fd %d\n", __FUNCTION__, fd)); /* * We've got all we need from the signal handler, let it continue handling * signals of this type. */ Sig_Continue(sigNum); /* * According to locks.c in kernel source, doing F_GETLEASE when a lease * break is pending will return the new lease we should use. It'll be * F_RDLCK if we can downgrade, or F_UNLCK if we should break altogether. */ newLease = fcntl(fd, F_GETLEASE); if (newLease == F_RDLCK) { newServerLock = HGFS_LOCK_SHARED; } else if (newLease == F_UNLCK) { newServerLock = HGFS_LOCK_NONE; } else if (newLease == -1) { int error = errno; Log("%s: Could not get old lease for fd %d: %s\n", __FUNCTION__, fd, strerror(error)); goto error; } else { Log("%s: Unexpected reply to get lease for fd %d: %d\n", __FUNCTION__, fd, newLease); goto error; } /* * Setup a ServerLockData struct so that we can make use of * HgfsServerOplockBreak which does the heavy lifting of discovering which * HGFS handle we're interested in breaking, sending the break, receiving * the acknowledgement, and firing the platform-specific acknowledgement * function (where we'll downgrade the lease). */ lockData = malloc(sizeof *lockData); if (lockData) { lockData->fileDesc = fd; lockData->serverLock = newServerLock; lockData->event = 0; // not needed /* * Relinquish control of this data. It'll get freed later, when the RPC * command completes. */ HgfsServerOplockBreak(lockData); return; } else { Log("%s: Could not allocate memory for lease break on behalf of fd %d\n", __FUNCTION__, fd); } error: /* Clean up as best we can. */ fcntl(fd, F_SETLEASE, F_UNLCK); HgfsUpdateNodeServerLock(fd, HGFS_LOCK_NONE); } #endif /* HGFS_OPLOCKS */ /* *----------------------------------------------------------------------------- * * HgfsPlatformConvertFromNameStatus -- * * This function converts between a status code used in processing a cross * platform filename, and a platform-specific status code. * * Because the two status codes never go down the wire, there is no danger * of backwards compatibility here, and we should ASSERT if we encounter * an status code that we're not familiar with. * * Results: * Converted status code. * * Side effects: * None. * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsPlatformConvertFromNameStatus(HgfsNameStatus status) // IN { switch(status) { case HGFS_NAME_STATUS_COMPLETE: return 0; case HGFS_NAME_STATUS_FAILURE: case HGFS_NAME_STATUS_INCOMPLETE_BASE: case HGFS_NAME_STATUS_INCOMPLETE_ROOT: case HGFS_NAME_STATUS_INCOMPLETE_DRIVE: case HGFS_NAME_STATUS_INCOMPLETE_UNC: case HGFS_NAME_STATUS_INCOMPLETE_UNC_MACH: return EINVAL; case HGFS_NAME_STATUS_DOES_NOT_EXIST: return ENOENT; case HGFS_NAME_STATUS_ACCESS_DENIED: return EACCES; case HGFS_NAME_STATUS_SYMBOLIC_LINK: return ELOOP; case HGFS_NAME_STATUS_OUT_OF_MEMORY: return ENOMEM; case HGFS_NAME_STATUS_TOO_LONG: return ENAMETOOLONG; case HGFS_NAME_STATUS_NOT_A_DIRECTORY: return ENOTDIR; default: NOT_IMPLEMENTED(); } } /* *----------------------------------------------------------------------------- * * HgfsPlatformGetDefaultDirAttrs -- * * Get default directory attributes. Permissions are Read and * Execute permission only. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsPlatformGetDefaultDirAttrs(HgfsFileAttrInfo *attr) // OUT { struct timeval tv; uint64 hgfsTime; ASSERT(attr); attr->type = HGFS_FILE_TYPE_DIRECTORY; attr->size = 4192; /* * Linux and friends are OK with receiving timestamps of 0, but just * for consistency with the Windows server, we'll pass back the * host's time in a virtual directory's timestamps. */ if (gettimeofday(&tv, NULL) != 0) { hgfsTime = 0; } else { hgfsTime = HgfsConvertToNtTime(tv.tv_sec, tv.tv_usec * 1000); } attr->creationTime = hgfsTime; attr->accessTime = hgfsTime; attr->writeTime = hgfsTime; attr->attrChangeTime = hgfsTime; attr->specialPerms = 0; attr->ownerPerms = HGFS_PERM_READ | HGFS_PERM_EXEC; attr->groupPerms = HGFS_PERM_READ | HGFS_PERM_EXEC; attr->otherPerms = HGFS_PERM_READ | HGFS_PERM_EXEC; attr->mask = HGFS_ATTR_VALID_TYPE | HGFS_ATTR_VALID_SIZE | HGFS_ATTR_VALID_CREATE_TIME | HGFS_ATTR_VALID_ACCESS_TIME | HGFS_ATTR_VALID_WRITE_TIME | HGFS_ATTR_VALID_CHANGE_TIME | HGFS_ATTR_VALID_SPECIAL_PERMS | HGFS_ATTR_VALID_OWNER_PERMS | HGFS_ATTR_VALID_GROUP_PERMS | HGFS_ATTR_VALID_OTHER_PERMS; } /* *----------------------------------------------------------------------------- * * HgfsServerGetOpenFlags -- * * Retrieve system open flags from HgfsOpenFlags. * * Does the correct bounds checking on the HgfsOpenFlags before * indexing into the array of flags to use. See bug 54429. * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool HgfsServerGetOpenFlags(HgfsOpenFlags flagsIn, // IN int *flagsOut) // OUT { unsigned int arraySize; ASSERT(flagsOut); arraySize = ARRAYSIZE(HgfsServerOpenFlags); if ((unsigned int)flagsIn >= arraySize) { Log("%s: Invalid HgfsOpenFlags %d\n", __FUNCTION__, flagsIn); return FALSE; } *flagsOut = HgfsServerOpenFlags[flagsIn]; return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsServerPlatformInit -- * * Set up any state needed to start Linux HGFS server. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsServerPlatformInit(void) { #ifdef HGFS_OPLOCKS /* Register a signal handler to catch oplock break signals. */ Sig_Callback(SIGIO, SIG_SAFE, HgfsServerSigOplockBreak, NULL); #endif return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsServerPlatformDestroy -- * * Tear down any state used for Linux HGFS server. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void HgfsServerPlatformDestroy(void) { #ifdef HGFS_OPLOCKS /* Tear down oplock state, so we no longer catch signals. */ Sig_Callback(SIGIO, SIG_NOHANDLER, NULL, NULL); #endif } /* *----------------------------------------------------------------------------- * * HgfsServerGetOpenMode -- * * Retrieve system open mode from HgfsOpenMode. * * Does the correct bounds checking on the HgfsOpenMode before * indexing into the array of modes to use. See bug 54429. * * This is just the POSIX implementation; the Windows implementation is * more complicated, hence the need for the HgfsFileOpenInfo as an * argument. * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsServerGetOpenMode(HgfsFileOpenInfo *openInfo, // IN: Open info to examine uint32 *modeOut) // OUT: Local mode { ASSERT(modeOut); /* * If we didn't get the mode in the open request, we'll return a mode of 0. * This has the effect of failing the call to open(2) later, which is * exactly what we want. */ if ((openInfo->mask & HGFS_OPEN_VALID_MODE) == 0) { *modeOut = 0; return TRUE; } if (!HGFS_OPEN_MODE_IS_VALID_MODE(openInfo->mode)) { Log("%s: Invalid HgfsOpenMode %d\n", __FUNCTION__, openInfo->mode); return FALSE; } *modeOut = HgfsServerOpenMode[HGFS_OPEN_MODE_ACCMODE(openInfo->mode)]; return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsCloseFile -- * * Closes the file descriptor and release the file context. * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsCloseFile(fileDesc fileDesc, // IN: File descriptor void *fileCtx) // IN: File context { if (close(fileDesc) != 0) { int error = errno; LOG(4, ("%s: Could not close fd %d: %s\n", __FUNCTION__, fileDesc, strerror(error))); return error; } return 0; } /* *----------------------------------------------------------------------------- * * HgfsCheckFileNode -- * * Check if a file node is still valid (i.e. if the file name stored in the * file node still refers to the same file) * * Results: * Zero if the file node is valid * Non-zero if the file node is stale * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsInternalStatus HgfsCheckFileNode(char const *localName, // IN HgfsLocalId const *localId) // IN { struct stat nodeStat; ASSERT(localName); ASSERT(localId); /* * A file is uniquely identified by a (device; inode) pair. Check that the * file name still refers to the same pair */ #if defined(__APPLE__) /* * Can't use Posix_Stat because of inconsistent definition * of _DARWIN_USE_64_BIT_INODE in this file and in other libraries. */ if (stat(localName, &nodeStat) < 0) { #else if (Posix_Stat(localName, &nodeStat) < 0) { #endif int error = errno; LOG(4, ("%s: couldn't stat local file \"%s\": %s\n", __FUNCTION__, localName, strerror(error))); return error; } if (nodeStat.st_dev != localId->volumeId || nodeStat.st_ino != localId->fileId) { LOG(4, ("%s: local Id mismatch\n", __FUNCTION__)); return ENOENT; } return 0; } /* *----------------------------------------------------------------------------- * * HgfsPlatformGetFd -- * * Returns the file descriptor associated with the node. If the node is * cached then it just returns the cached file descriptor (checking for * correct write flags). Otherwise, it opens a new file, caches the node * and returns the file desriptor. * * Results: * Zero on success. fd contains the opened file descriptor. * Non-zero on error. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsPlatformGetFd(HgfsHandle hgfsHandle, // IN: HGFS file handle HgfsSessionInfo *session, // IN: Session info Bool append, // IN: Open with append flag fileDesc *fd) // OUT: Opened file descriptor { int newFd = -1, openFlags = 0; HgfsFileNode node; HgfsInternalStatus status = 0; ASSERT(fd); ASSERT(session); /* * Use node copy convenience function to get the node information. * Note that we shouldn't keep this node around for too long because * the information can become stale. However, it's ok to get all the * fields in one step, instead of getting them all separate. * * XXX: It would be better if we didn't do this node copy on the fast * path. Unfortuntely, even the fast path may need to look at the node's * append flag. */ node.utf8Name = NULL; if (!HgfsGetNodeCopy(hgfsHandle, session, TRUE, &node)) { /* XXX: Technically, this can also fail if we're out of memory. */ LOG(4, ("%s: Invalid hgfs handle.\n", __FUNCTION__)); status = EBADF; goto exit; } /* If the node is found in the cache */ if (HgfsIsCached(hgfsHandle, session)) { /* * If the append flag is set check to see if the file was opened * in append mode. If not, close the file and reopen it in append * mode. */ if (append && !(node.flags & HGFS_FILE_NODE_APPEND_FL)) { status = HgfsCloseFile(node.fileDesc, node.fileCtx); if (status != 0) { LOG(4, ("%s: Couldn't close file \"%s\" for reopening\n", __FUNCTION__, node.utf8Name)); goto exit; } /* * Update the node in the cache with the new value of the append * flag. */ if (!HgfsUpdateNodeAppendFlag(hgfsHandle, session, TRUE)) { LOG(4, ("%s: Could not update the node in the cache\n", __FUNCTION__)); status = EBADF; goto exit; } } else { newFd = node.fileDesc; goto exit; } } /* * If we got here then the file was either not in the cache or needs * reopening. This means we need to open a file. But first, verify * that the file we intend to open isn't stale. */ status = HgfsCheckFileNode(node.utf8Name, &node.localId); if (status != 0) { goto exit; } /* * We're not interested in creating a new file. So let's just get the * flags for a simple open request. This really should always work. */ HgfsServerGetOpenFlags(0, &openFlags); /* * We don't need to specify open permissions here because we're only * reopening an existing file, not creating a new one. * * XXX: We should use O_LARGEFILE, see lib/file/fileIOPosix.c --hpreg */ newFd = Posix_Open(node.utf8Name, node.mode | openFlags | (append ? O_APPEND : 0)); if (newFd < 0) { int error = errno; LOG(4, ("%s: Couldn't open file \"%s\": %s\n", __FUNCTION__, node.utf8Name, strerror(errno))); status = error; goto exit; } /* * Update the original node with the new value of the file desc. * This call might fail if the node is not used anymore. */ if (!HgfsUpdateNodeFileDesc(hgfsHandle, session, newFd, NULL)) { LOG(4, ("%s: Could not update the node -- node is not used.\n", __FUNCTION__)); status = EBADF; goto exit; } /* Add the node to the cache. */ if (!HgfsAddToCache(hgfsHandle, session)) { LOG(4, ("%s: Could not add node to the cache\n", __FUNCTION__)); status = EBADF; goto exit; } exit: if (status == 0) { *fd = newFd; } free(node.utf8Name); return status; } /* *----------------------------------------------------------------------------- * * HgfsValidateOpen -- * * Verify that the file with the given local name exists in the * local filesystem by trying to open the file with the requested * mode and permissions. If the open succeeds we stat the file * and fill in the volumeId and fileId with the file's local * filesystem device and inode number, respectively. * * Results: * Zero on success * Non-zero on failure. * * Side effects: * File with name "localName" may be created or truncated. * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsPlatformValidateOpen(HgfsFileOpenInfo *openInfo, // IN: Open info struct Bool followSymlinks, // IN: followSymlinks config option HgfsSessionInfo *session, // IN: session info HgfsLocalId *localId, // OUT: Local unique file ID fileDesc *fileDesc) // OUT: Handle to the file { struct stat fileStat; int fd; int error; int openMode = 0, openFlags = 0; mode_t openPerms; HgfsServerLock serverLock; HgfsInternalStatus status = 0; Bool needToSetAttribute = FALSE; ASSERT(openInfo); ASSERT(localId); ASSERT(fileDesc); ASSERT(session); /* * Get correct system flags and mode from the HgfsOpenFlags and * HgfsOpenMode. This is related to bug 54429. */ if (!HgfsServerGetOpenFlags(openInfo->mask & HGFS_OPEN_VALID_FLAGS ? openInfo->flags : 0, &openFlags) || !HgfsServerGetOpenMode(openInfo, &openMode)) { status = EPROTO; goto exit; } /* * Create mode_t for use in open(). If owner permissions are missing, use * read/write for the owner permissions. If group or other permissions * are missing, use the owner permissions. * * This sort of makes sense. If the Windows driver wants to make a file * read-only, it probably intended for the file to be 555. Since creating * a file requires a valid mode, it's highly unlikely that we'll ever * be creating a file without owner permissions. */ openPerms = ~ALLPERMS; openPerms |= openInfo->mask & HGFS_OPEN_VALID_SPECIAL_PERMS ? openInfo->specialPerms << 9 : 0; openPerms |= openInfo->mask & HGFS_OPEN_VALID_OWNER_PERMS ? openInfo->ownerPerms << 6 : S_IWUSR | S_IRUSR; openPerms |= openInfo->mask & HGFS_OPEN_VALID_GROUP_PERMS ? openInfo->groupPerms << 3 : (openPerms & S_IRWXU) >> 3; openPerms |= openInfo->mask & HGFS_OPEN_VALID_OTHER_PERMS ? openInfo->otherPerms : (openPerms & S_IRWXU) >> 6; /* * By default we don't follow symlinks, O_NOFOLLOW is always set. * Unset it if followSymlinks config option is specified. */ if (followSymlinks) { openFlags &= ~O_NOFOLLOW; } /* * Need to validate that open does not change the file for read * only shared folders. */ status = 0; if (!openInfo->shareInfo.writePermissions) { Bool deleteAccess = FALSE; /* * If a valid desiredAccess field specified by the Windows client, we use that * as the desiredAccess field has more data such as delete than is contained * in the mode. */ if ((0 != (openInfo->mask & HGFS_OPEN_VALID_DESIRED_ACCESS)) && (0 != (openInfo->desiredAccess & DELETE))) { deleteAccess = TRUE; } if ((openFlags & (O_APPEND | O_CREAT | O_TRUNC)) || (openMode & (O_WRONLY | O_RDWR)) || deleteAccess) { status = Posix_Access(openInfo->utf8Name, F_OK); if (status < 0) { status = errno; if (status == ENOENT && (openFlags & O_CREAT) != 0) { status = EACCES; } } else { /* * Handle the case when the file already exists: * If there is an attempt to createa new file, fail with "EEXIST" * error, otherwise set error to "EACCES". */ if ((openFlags & O_CREAT) && (openFlags & O_EXCL)) { status = EEXIST; } else { status = EACCES; } } } if (status != 0) { goto exit; } } if (!openInfo->shareInfo.readPermissions) { /* * "Drop Box" / "FTP incoming" type of shared folders. * Allow creating a new file. Deny opening exisitng file. */ status = Posix_Access(openInfo->utf8Name, F_OK); if (status < 0) { status = errno; if (status != ENOENT || (openFlags & O_CREAT) == 0) { status = EACCES; } } else { status = EACCES; } if (status != 0) { goto exit; } } /* * Determine if hidden attribute needs to be updated. * It needs to be updated if a new file is created or an existing file is truncated. * Since Posix_Open does not tell us if a new file has been created when O_CREAT is * specified we need to find out if the file exists before an open that may create * it. */ if (openInfo->mask & HGFS_OPEN_VALID_FILE_ATTR) { if ((openFlags & O_TRUNC) || ((openFlags & O_CREAT) && (openFlags & O_EXCL))) { needToSetAttribute = TRUE; } else if (openFlags & O_CREAT) { int err = Posix_Access(openInfo->utf8Name, F_OK); needToSetAttribute = (err != 0) && (errno == ENOENT); } } /* * Try to open the file with the requested mode, flags and permissions. */ fd = Posix_Open(openInfo->utf8Name, openMode | openFlags, openPerms); if (fd < 0) { error = errno; LOG(4, ("%s: couldn't open file \"%s\": %s\n", __FUNCTION__, openInfo->utf8Name, strerror(error))); status = error; goto exit; } /* Stat file to get its volume and file info */ if (fstat(fd, &fileStat) < 0) { error = errno; LOG(4, ("%s: couldn't stat local file \"%s\": %s\n", __FUNCTION__, openInfo->utf8Name, strerror(error))); close(fd); status = error; goto exit; } /* Set the rest of the Windows specific attributes if necessary. */ if (needToSetAttribute) { HgfsSetHiddenXAttr(openInfo->utf8Name, (openInfo->attr & HGFS_ATTR_HIDDEN) != 0, fileStat.st_mode); } /* Try to acquire an oplock. */ if (openInfo->mask & HGFS_OPEN_VALID_SERVER_LOCK) { serverLock = openInfo->desiredLock; if (!HgfsAcquireServerLock(fd, session, &serverLock)) { openInfo->acquiredLock = HGFS_LOCK_NONE; } else { openInfo->acquiredLock = serverLock; } } else { openInfo->acquiredLock = HGFS_LOCK_NONE; } *fileDesc = fd; /* Set volume and file ids from stat results */ localId->volumeId = fileStat.st_dev; localId->fileId = fileStat.st_ino; exit: return status; } /* *----------------------------------------------------------------------------- * * HgfsAcquireServerLock -- * * Acquire a lease for the open file. Typically we try and get the exact * lease desired, but if the client asked for HGFS_LOCK_OPPORTUNISTIC, we'll * take the "best" lease we can get. * * Results: * TRUE on success. serverLock contains the type of the lock acquired. * FALSE on failure. serverLock is HGFS_LOCK_NONE. * * XXX: This function has the potential to return per-platform error codes, * but since it is opportunistic by nature, it isn't necessary to do so. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsAcquireServerLock(fileDesc fileDesc, // IN: OS handle HgfsSessionInfo *session, // IN: session info HgfsServerLock *serverLock) // IN/OUT: Oplock asked for/granted { #ifdef HGFS_OPLOCKS HgfsServerLock desiredLock; int leaseType, error; ASSERT(serverLock); ASSERT(session); desiredLock = *serverLock; if (desiredLock == HGFS_LOCK_NONE) { return TRUE; } if (!HgfsIsServerLockAllowed(session)) { return FALSE; } /* * First tell the kernel which signal to send us. SIGIO is already the * default, but if we skip this step, we won't get the siginfo_t when * a lease break occurs. * * XXX: Do I need to do fcntl(fileDesc, F_SETOWN, getpid())? */ if (fcntl(fileDesc, F_SETSIG, SIGIO)) { error = errno; Log("%s: Could not set SIGIO as the desired lease break signal for " "fd %d: %s\n", __FUNCTION__, fileDesc, strerror(error)); return FALSE; } /* * If the client just wanted the best lock possible, start off with a write * lease and move down to a read lease if that was unavailable. */ if ((desiredLock == HGFS_LOCK_OPPORTUNISTIC) || (desiredLock == HGFS_LOCK_EXCLUSIVE)) { leaseType = F_WRLCK; } else if (desiredLock == HGFS_LOCK_SHARED) { leaseType = F_RDLCK; } else { LOG(4, ("%s: Unknown server lock\n", __FUNCTION__)); return FALSE; } if (fcntl(fileDesc, F_SETLEASE, leaseType)) { /* * If our client was opportunistic and we failed to get his lease because * someone else is already writing or reading to the file, try again with * a read lease. */ if (desiredLock == HGFS_LOCK_OPPORTUNISTIC && (errno == EAGAIN || errno == EACCES)) { leaseType = F_RDLCK; if (fcntl(fileDesc, F_SETLEASE, leaseType)) { error = errno; LOG(4, ("%s: Could not get any opportunistic lease for fd %d: %s\n", __FUNCTION__, fileDesc, strerror(error))); return FALSE; } } else { error = errno; LOG(4, ("%s: Could not get %s lease for fd %d: %s\n", __FUNCTION__, leaseType == F_WRLCK ? "write" : "read", fileDesc, strerror(errno))); return FALSE; } } /* Got a lease of some kind. */ LOG(4, ("%s: Got %s lease for fd %d\n", __FUNCTION__, leaseType == F_WRLCK ? "write" : "read", fileDesc)); *serverLock = leaseType == F_WRLCK ? HGFS_LOCK_EXCLUSIVE : HGFS_LOCK_SHARED; return TRUE; #else return FALSE; #endif } /* *----------------------------------------------------------------------------- * * HgfsGetattrResolveAlias -- * * Mac OS defines a special file type known as an alias which behaves like a * symlink when viewed through the Finder, but is actually a regular file * otherwise. Unlike symlinks, aliases cannot be broken; if the target file * is deleted, so is the alias. * * If the given filename is (or contains) an alias, this function will * resolve it completely and set targetName to something non-NULL. * * Results: * Zero on success. targetName is allocated if the file was an alias, and * NULL otherwise. * Non-zero on failure. targetName is unmodified. * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsInternalStatus HgfsGetattrResolveAlias(char const *fileName, // IN: Input filename char **targetName) // OUT: Target filename { #ifndef __APPLE__ *targetName = NULL; return 0; #else char *myTargetName = NULL; HgfsInternalStatus status = HGFS_INTERNAL_STATUS_ERROR; CFURLRef resolvedRef = NULL; CFStringRef resolvedString; FSRef fileRef; Boolean targetIsFolder; Boolean wasAliased; OSStatus osStatus; ASSERT_ON_COMPILE(sizeof osStatus == sizeof (int32)); /* * Create and resolve an FSRef of the desired path. We pass FALSE to * resolveAliasChains because aliases to aliases should behave as * symlinks to symlinks. If the file is an alias, wasAliased will be set to * TRUE and fileRef will reference the target file. */ osStatus = FSPathMakeRef(fileName, &fileRef, NULL); if (osStatus != noErr) { LOG(4, ("%s: could not create file reference: error %d\n", __FUNCTION__, (int32)osStatus)); goto exit; } /* * If alias points to an unmounted volume, the volume needs to be explicitly * mounted on the host. Mount flag kResolveAliasFileNoUI serves the purpose. * * XXX: This function returns fnfErr (file not found) if it encounters a * broken alias. Perhaps we should make that look like a dangling symlink * instead of returning an error? * * XXX: It also returns errors if it encounters a file with a .alias suffix * that isn't a real alias. That's OK for now because our caller * (HgfsGetattrFromName) will assume that an error means the file is a * regular file. */ osStatus = FSResolveAliasFileWithMountFlags(&fileRef, FALSE, &targetIsFolder, &wasAliased, kResolveAliasFileNoUI); if (osStatus != noErr) { LOG(4, ("%s: could not resolve reference: error %d\n", __FUNCTION__, (int32)osStatus)); goto exit; } if (wasAliased) { CFIndex maxPath; /* * This is somewhat convoluted. We create a CFURL from the FSRef because * we want to call CFURLGetFileSystemRepresentation() to get a UTF-8 * string representing the target of the alias. But to call * CFStringGetMaximumSizeOfFileSystemRepresentation(), we need a * CFString, so we make one from the CFURL. Once we've got the max number * of bytes for a filename on the filesystem, we allocate some memory * and convert the CFURL to a basic UTF-8 string using a call to * CFURLGetFileSystemRepresentation(). */ resolvedRef = CFURLCreateFromFSRef(NULL, &fileRef); if (resolvedRef == NULL) { LOG(4, ("%s: could not create resolved URL reference from " "resolved filesystem reference\n", __FUNCTION__)); goto exit; } resolvedString = CFURLGetString(resolvedRef); if (resolvedString == NULL) { LOG(4, ("%s: could not create resolved string reference from " "resolved URL reference\n", __FUNCTION__)); goto exit; } maxPath = CFStringGetMaximumSizeOfFileSystemRepresentation(resolvedString); myTargetName = malloc(maxPath); if (myTargetName == NULL) { LOG(4, ("%s: could not allocate %"FMTSZ"d bytes of memory for " "target name storage\n", __FUNCTION__, maxPath)); goto exit; } if (!CFURLGetFileSystemRepresentation(resolvedRef, FALSE, myTargetName, maxPath)) { LOG(4, ("%s: could not convert and copy resolved URL reference " "into allocated buffer\n", __FUNCTION__)); goto exit; } *targetName = myTargetName; LOG(4, ("%s: file was an alias\n", __FUNCTION__)); } else { *targetName = NULL; LOG(4, ("%s: file was not an alias\n", __FUNCTION__)); } status = 0; exit: if (status != 0) { free(myTargetName); } if (resolvedRef != NULL) { CFRelease(resolvedRef); } return status; #endif } /* *----------------------------------------------------------------------------- * * HgfsGetHiddenAttr -- * * For Mac hosts and Linux hosts, if a guest is Windows we force the "dot", * files to be treated as hidden too in the Windows client by always setting * the hidden attribute flag. * Currently, this flag cannot be removed by Windows clients. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsGetHiddenAttr(char const *fileName, // IN: Input filename HgfsFileAttrInfo *attr) // OUT: Struct to copy into { char *baseName; ASSERT(fileName); ASSERT(attr); baseName = strrchr(fileName, DIRSEPC); if ((baseName != NULL) && (baseName[1] == '.') && (strcmp(&baseName[1], ".") != 0) && (strcmp(&baseName[1], "..") != 0)) { attr->mask |= HGFS_ATTR_VALID_FLAGS; attr->flags |= HGFS_ATTR_HIDDEN; /* * The request sets the forced flag so the client knows it is simulated * and is not a real attribute, which can only happen on a Windows server. * This allows the client to enforce some checks correctly if the flag * is real or not. * This replicates SMB behavior see bug 292189. */ attr->flags |= HGFS_ATTR_HIDDEN_FORCED; } else { Bool isHidden = FALSE; /* * Do not propagate any error returned from HgfsGetHiddenXAttr. * Consider that the file is not hidden if can't get hidden attribute for * whatever reason; most likely it fails because hidden attribute is not supported * by the OS or file system. */ HgfsGetHiddenXAttr(fileName, &isHidden); if (isHidden) { attr->mask |= HGFS_ATTR_VALID_FLAGS; attr->flags |= HGFS_ATTR_HIDDEN; } } } /* *----------------------------------------------------------------------------- * * HgfsConvertComponentCase -- * * Do a case insensitive search of a directory for the specified entry. If * a matching entry is found, return it in the convertedComponent argument. * * Results: * On Success: * Returns 0 and the converted component name in the argument convertedComponent. * The length for the convertedComponent is returned in convertedComponentSize. * * On Failure: * Non-zero errno return, with convertedComponent and convertedComponentSize * set to NULL and 0 respectively. * * Side effects: * On success, allocated memory is returned in convertedComponent and needs * to be freed. * *----------------------------------------------------------------------------- */ static int HgfsConvertComponentCase(char *currentComponent, // IN const char *dirPath, // IN const char **convertedComponent, // OUT size_t *convertedComponentSize) // OUT { struct dirent *dirent; DIR *dir = NULL; char *dentryName; size_t dentryNameLen; char *myConvertedComponent = NULL; size_t myConvertedComponentSize; int ret; ASSERT(currentComponent); ASSERT(dirPath); ASSERT(convertedComponent); ASSERT(convertedComponentSize); /* Open the specified directory. */ dir = Posix_OpenDir(dirPath); if (!dir) { ret = errno; goto exit; } /* * Unicode_CompareIgnoreCase crashes with invalid unicode strings, * validate it before passing it to Unicode_* functions. */ if (!Unicode_IsBufferValid(currentComponent, -1, STRING_ENCODING_UTF8)) { /* Invalid unicode string, return failure. */ ret = EINVAL; goto exit; } /* * Read all of the directory entries. For each one, convert the name * to lower case and then compare it to the lower case component. */ while ((dirent = readdir(dir))) { Unicode dentryNameU; int cmpResult; dentryName = dirent->d_name; dentryNameLen = strlen(dentryName); /* * Unicode_CompareIgnoreCase crashes with invalid unicode strings, * validate and convert it appropriately before passing it to Unicode_* * functions. */ if (!Unicode_IsBufferValid(dentryName, dentryNameLen, STRING_ENCODING_DEFAULT)) { /* Invalid unicode string, skip the entry. */ continue; } dentryNameU = Unicode_Alloc(dentryName, STRING_ENCODING_DEFAULT); cmpResult = Unicode_CompareIgnoreCase(currentComponent, dentryNameU); Unicode_Free(dentryNameU); if (cmpResult == 0) { /* * The current directory entry is a case insensitive match to * the specified component. Malloc and copy the current directory entry. */ myConvertedComponentSize = dentryNameLen + 1; myConvertedComponent = malloc(myConvertedComponentSize); if (myConvertedComponent == NULL) { ret = errno; LOG(4, ("%s: failed to malloc myConvertedComponent.\n", __FUNCTION__)); goto exit; } Str_Strcpy(myConvertedComponent, dentryName, myConvertedComponentSize); /* Success. Cleanup and exit. */ ret = 0; *convertedComponentSize = myConvertedComponentSize; *convertedComponent = myConvertedComponent; goto exit; } } /* We didn't find a match. Failure. */ ret = ENOENT; exit: if (dir) { closedir(dir); } if (ret) { *convertedComponent = NULL; *convertedComponentSize = 0; } return ret; } /* *----------------------------------------------------------------------------- * * HgfsConstructConvertedPath -- * * Expand the passed string and append the converted path. * * Results: * Returns 0 if successful, errno on failure. Note that this * function cannot return ENOENT. * * Side effects: * Reallocs the path. * *----------------------------------------------------------------------------- */ static int HgfsConstructConvertedPath(char **path, // IN/OUT size_t *pathSize, // IN/OUT char *convertedPath, // IN size_t convertedPathSize) // IN { char *p; size_t convertedPathLen = convertedPathSize - 1; ASSERT(path); ASSERT(*path); ASSERT(convertedPath); ASSERT(pathSize); p = realloc(*path, *pathSize + convertedPathLen + sizeof (DIRSEPC)); if (!p) { int error = errno; LOG(4, ("%s: failed to realloc.\n", __FUNCTION__)); return error; } *path = p; *pathSize += convertedPathLen + sizeof (DIRSEPC); /* Copy out the converted component to curDir, and free it. */ Str_Strncat(p, *pathSize, DIRSEPS, sizeof (DIRSEPS)); Str_Strncat(p, *pathSize, convertedPath, convertedPathLen); return 0; } /* *----------------------------------------------------------------------------- * * HgfsCaseInsensitiveLookup -- * * Do a case insensitive lookup for fileName. Each component past sharePath is * looked-up case-insensitively. Expensive! * * NOTE: * shareName is always expected to be a prefix of fileName. * * Results: * Returns 0 if successful and resolved path for fileName is returned in * convertedFileName with its length in convertedFileNameLength. * Otherwise returns non-zero errno with convertedFileName and * convertedFileNameLength set to NULL and 0 respectively. * * Side effects: * On success, allocated memory is returned in convertedFileName and needs * to be freed. * *----------------------------------------------------------------------------- */ static int HgfsCaseInsensitiveLookup(const char *sharePath, // IN size_t sharePathLength, // IN char *fileName, // IN size_t fileNameLength, // IN char **convertedFileName, // OUT size_t *convertedFileNameLength) // OUT { char *currentComponent; char *curDir; char *nextComponent; int error = ENOENT; size_t curDirSize; char *convertedComponent = NULL; size_t convertedComponentSize = 0; ASSERT(sharePath); ASSERT(fileName); ASSERT(convertedFileName); ASSERT(fileNameLength >= sharePathLength); currentComponent = fileName + sharePathLength; /* Check there is something beyond the share name. */ if (*currentComponent == '\0') { /* * The fileName is the same as sharePath. Nothing else to do. * Dup the string and return. */ *convertedFileName = strdup(fileName); if (!*convertedFileName) { error = errno; *convertedFileName = NULL; *convertedFileNameLength = 0; LOG(4, ("%s: strdup on fileName failed.\n", __FUNCTION__)); } else { *convertedFileNameLength = strlen(fileName); } return 0; } /* Skip a component separator if not in the share path. */ if (*currentComponent == DIRSEPC) { currentComponent += 1; } curDirSize = sharePathLength + 1; curDir = malloc(curDirSize); if (!curDir) { error = errno; LOG(4, ("%s: failed to allocate for curDir\n", __FUNCTION__)); goto exit; } Str_Strcpy(curDir, sharePath, curDirSize); while (TRUE) { /* Get the next component. */ nextComponent = strchr(currentComponent, DIRSEPC); if (nextComponent != NULL) { *nextComponent = '\0'; } /* * Try to match the current component against the one in curDir. * HgfsConvertComponentCase may return ENOENT. In that case return * the path case-converted uptil now (curDir) and append to it the * rest of the unconverted path. */ error = HgfsConvertComponentCase(currentComponent, curDir, (const char **)&convertedComponent, &convertedComponentSize); /* Restore the path separator if we removed it earlier. */ if (nextComponent != NULL) { *nextComponent = DIRSEPC; } if (error) { if (error == ENOENT) { int ret; /* * Copy out the components starting from currentComponent. We do this * after replacing DIRSEPC, so all the components following * currentComponent gets copied. */ ret = HgfsConstructConvertedPath(&curDir, &curDirSize, currentComponent, strlen(currentComponent) + 1); if (ret) { error = ret; } } if (error != ENOENT) { free(curDir); } break; } /* Expand curDir and copy out the converted component. */ error = HgfsConstructConvertedPath(&curDir, &curDirSize, convertedComponent, convertedComponentSize); if (error) { free(curDir); free(convertedComponent); break; } /* Free the converted component. */ free(convertedComponent); /* If there is no component after the current one then we are done. */ if (nextComponent == NULL) { /* Set success. */ error = 0; break; } /* * Set the current component pointer to point at the start of the next * component. */ currentComponent = nextComponent + 1; } /* If the conversion was successful, return the result. */ if (error == 0 || error == ENOENT) { *convertedFileName = curDir; *convertedFileNameLength = curDirSize; } exit: if (error && error != ENOENT) { *convertedFileName = NULL; *convertedFileNameLength = 0; } return error; } /* *----------------------------------------------------------------------------- * * HgfsServerConvertCase -- * * Converts the fileName to appropriate case depending upon flags. * * Results: * Returns HGFS_NAME_STATUS_COMPLETE if successful and converted * path for fileName is returned in convertedFileName and it length in * convertedFileNameLength. * * Otherwise returns non-zero integer without affecting fileName with * convertedFileName and convertedFileNameLength set to NULL and 0 * respectively. * * Side effects: * On success, allocated memory is returned in convertedFileName and needs * to be freed. * *----------------------------------------------------------------------------- */ HgfsNameStatus HgfsServerConvertCase(const char *sharePath, // IN size_t sharePathLength, // IN char *fileName, // IN size_t fileNameLength, // IN uint32 caseFlags, // IN char **convertedFileName, // OUT size_t *convertedFileNameLength) // OUT { int error = 0; HgfsNameStatus nameStatus = HGFS_NAME_STATUS_COMPLETE; ASSERT(sharePath); ASSERT(fileName); ASSERT(convertedFileName); ASSERT(convertedFileNameLength); *convertedFileName = NULL; *convertedFileNameLength = 0; /* * Case-insensitive lookup is expensive, do it only if the flag is set * and file is inaccessible using the case passed to us. We use access(2) * call to check if the passed case of the file name is correct. */ if (caseFlags == HGFS_FILE_NAME_CASE_INSENSITIVE && Posix_Access(fileName, F_OK) == -1) { LOG(4, ("%s: Case insensitive lookup, fileName: %s, flags: %u.\n", __FUNCTION__, fileName, caseFlags)); error = HgfsCaseInsensitiveLookup(sharePath, sharePathLength, fileName, fileNameLength, convertedFileName, convertedFileNameLength); /* * Success or non-ENOENT error code. HgfsCaseInsensitiveLookup can * return ENOENT, and its ok to continue if it is ENOENT. */ switch (error) { /* * Both ENOENT and 0 mean that HgfsCaseInsensitiveLookup * successfully built the converted name thus we return * HGFS_NAME_STATUS_COMPLETE in these two cases. */ case 0: case ENOENT: nameStatus = HGFS_NAME_STATUS_COMPLETE; break; case ENOTDIR: nameStatus = HGFS_NAME_STATUS_NOT_A_DIRECTORY; break; default: nameStatus = HGFS_NAME_STATUS_FAILURE; break; } return nameStatus; } *convertedFileName = strdup(fileName); if (!*convertedFileName) { nameStatus = HGFS_NAME_STATUS_OUT_OF_MEMORY; LOG(4, ("%s: strdup on fileName failed.\n", __FUNCTION__)); } else { *convertedFileNameLength = fileNameLength; } return nameStatus; } /* *----------------------------------------------------------------------------- * * HgfsServerCaseConversionRequired -- * * Determines if the case conversion is required for this platform. * * Results: * TRUE on Linux / Apple. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsServerCaseConversionRequired() { return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsEffectivePermissions -- * * Get permissions that are in efffect for the current user. * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsInternalStatus HgfsEffectivePermissions(char *fileName, // IN: Input filename Bool readOnlyShare, // IN: Share name uint32 *permissions) // OUT: Effective permissions { *permissions = 0; if (Posix_Access(fileName, R_OK) == 0) { *permissions |= HGFS_PERM_READ; } if (Posix_Access(fileName, X_OK) == 0) { *permissions |= HGFS_PERM_EXEC; } if (!readOnlyShare && (Posix_Access(fileName, W_OK) == 0)) { *permissions |= HGFS_PERM_WRITE; } return 0; } /* *----------------------------------------------------------------------------- * * HgfsGetCreationTime -- * * Calculates actual or emulated file creation time from stat structure. * Definition of stat structure are different on diferent platforms. * This function hides away all these differences and produces 64 bit value * which should be reported to the client. * * Results: * Value that should be used as a file creation time stamp. * The resulting timestamp is in platform independent HGFS format. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static uint64 HgfsGetCreationTime(const struct stat *stats) { uint64 creationTime; /* * Linux and FreeBSD before v5 doesn't know about creation time; we just use the time * of last data modification for the creation time. * FreeBSD 5+ supprots file creation time. * * Using mtime when creation time is unavailable to be consistent with SAMBA. */ #ifdef __FreeBSD__ /* * FreeBSD: All supported versions have timestamps with nanosecond resolution. * FreeBSD 5+ has also file creation time. */ # if __IS_FREEBSD_VER__(500043) creationTime = HgfsConvertTimeSpecToNtTime(&stats->st_birthtimespec); # else creationTime = HgfsConvertTimeSpecToNtTime(&stats->st_mtimespec); # endif #elif defined(linux) /* * Linux: Glibc 2.3+ has st_Xtim. Glibc 2.1/2.2 has st_Xtime/__unusedX on * same place (see below). We do not support Glibc 2.0 or older. */ # if (__GLIBC__ == 2) && (__GLIBC_MINOR__ < 3) && !defined(__UCLIBC__) /* * stat structure is same between glibc 2.3 and older glibcs, just * these __unused fields are always zero. If we'll use __unused* * instead of zeroes, we get automatically nanosecond timestamps * when running on host which provides them. */ creationTime = HgfsConvertToNtTime(stats->st_mtime, stats->__unused2); # else creationTime = HgfsConvertTimeSpecToNtTime(&stats->st_mtim); # endif #elif defined(__APPLE__) creationTime = HgfsConvertTimeSpecToNtTime(&stats->st_birthtimespec); #else /* * Solaris: No nanosecond timestamps, no file create timestamp. */ creationTime = HgfsConvertToNtTime(stats->st_mtime, 0); #endif return creationTime; } /* *----------------------------------------------------------------------------- * * HgfsStat -- * * Wrapper function that invokes stat on Mac OS and on Linux. * * Returns filled stat structure and a file creation time. File creation time is * the birthday time for Mac OS and last write time for Linux (which does not support * file creation time). * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ static int HgfsStat(const char* fileName, // IN: file name Bool followLink, // IN: If true then follow symlink struct stat *stats, // OUT: file attributes uint64 *creationTime) // OUT: file creation time { int error; #if defined(__APPLE__) if (followLink) { error = stat(fileName, stats); } else { error = lstat(fileName, stats); } #else if (followLink) { error = Posix_Stat(fileName, stats); } else { error = Posix_Lstat(fileName, stats); } #endif *creationTime = HgfsGetCreationTime(stats); return error; } /* *----------------------------------------------------------------------------- * * HgfsFStat -- * * Wrapper function that invokes fstat. * * Returns filled stat structure and a file creation time. File creation time is * the birthday time for Mac OS and last write time for Linux (which does not support * file creation time). * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ static int HgfsFStat(int fd, // IN: file descriptor struct stat *stats, // OUT: file attributes uint64 *creationTime) // OUT: file creation time { int error = 0; if (fstat(fd, stats) < 0) { error = errno; } *creationTime = HgfsGetCreationTime(stats); return error; } /* *---------------------------------------------------------------------------- * * HgfsGetSequentialOnlyFlagFromName -- * * Certain files like 'kallsyms' residing in /proc/ filesystem can be * copied only if they are opened in sequential mode. Check for such files * and set the 'sequential only' flag. This is done by trying to read the file * content using 'pread'. If 'pread' fails with ESPIPE then they are * tagged as 'sequential only' files. * * Results: * None. * * Side effects: * None * *---------------------------------------------------------------------------- */ static void HgfsGetSequentialOnlyFlagFromName(const char *fileName, // IN HgfsFileAttrInfo *attr) // IN/OUT { #if defined(__linux) || defined(__APPLE__) int fd; if ((NULL == fileName) || (NULL == attr)) { return; } fd = Posix_Open(fileName, O_RDONLY); if (fd < 0) { LOG(4, ("%s: Couldn't open the file \"%s\"\n", __FUNCTION__, fileName)); return; } HgfsGetSequentialOnlyFlagFromFd(fd, attr); close(fd); return; #endif } /* *---------------------------------------------------------------------------- * * HgfsGetSequentialOnlyFlagFromFd -- * * Certain files like 'kallsyms' residing in /proc/ filesystem can be * copied only if they are opened in sequential mode. Check for such files * and set the 'sequential only' flag. This is done by trying to read the file * content using 'pread'. If 'pread' fails with ESPIPE then they are * tagged as 'sequential only' files. * * Results: * None. * * Side effects: * None * *---------------------------------------------------------------------------- */ static void HgfsGetSequentialOnlyFlagFromFd(int fd, // IN HgfsFileAttrInfo *attr) // IN/OUT { #if defined(__linux) || defined(__APPLE__) int error; char buffer[2]; struct stat stats; if (NULL == attr) { return; } if (fstat(fd, &stats) < 0) { return; } if (S_ISDIR(stats.st_mode) || S_ISLNK(stats.st_mode)) { return; } /* * At this point in the code, we are not reading any amount of data from the * file. We just want to check the behavior of pread. Since we are not * reading any data, we can call pread with size specified as 0. */ error = pread(fd, buffer, 0, 0); LOG(4, ("%s: pread returned %d, errno %d\n", __FUNCTION__, error, errno)); if ((-1 == error) && (ESPIPE == errno)) { LOG(4, ("%s: Marking the file as 'Sequential only' file\n", __FUNCTION__)); attr->flags |= HGFS_ATTR_SEQUENTIAL_ONLY; } return; #endif } /* *----------------------------------------------------------------------------- * * HgfsPlatformGetattrFromName -- * * Performs a stat operation on the given filename, and, if it is a symlink, * allocates the target filename on behalf of the caller and performs a * readlink to get it. If not a symlink, the targetName argument is * untouched. Does necessary translation between Unix file stats and the * HgfsFileAttrInfo formats. * NOTE: The function is different from HgfsGetAttrFromId: this function returns * effectve permissions while HgfsGetAttrFromId does not. * The reason for this asymmetry is that effective permissions are needed * to get a new handle. If the file is already opened then * getting effective permissions does not have any value. However getting * effective permissions would hurt perfomance and should be avoided. * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsPlatformGetattrFromName(char *fileName, // IN/OUT: Input filename HgfsShareOptions configOptions, // IN: Share config options char *shareName, // IN: Share name HgfsFileAttrInfo *attr, // OUT: Struct to copy into char **targetName) // OUT: Symlink target { HgfsInternalStatus status = 0; struct stat stats; int error; char *myTargetName = NULL; uint64 creationTime; ASSERT(fileName); ASSERT(attr); LOG(4, ("%s: getting attrs for \"%s\"\n", __FUNCTION__, fileName)); error = HgfsStat(fileName, HgfsServerPolicy_IsShareOptionSet(configOptions, HGFS_SHARE_FOLLOW_SYMLINKS), &stats, &creationTime); if (error) { status = errno; LOG(4, ("%s: error stating file: %s\n", __FUNCTION__, strerror(status))); goto exit; } /* * Deal with the file type returned from lstat(2). We currently support * regular files, directories, and symlinks. On Mac OS, we'll additionally * treat finder aliases as symlinks. */ if (S_ISDIR(stats.st_mode)) { attr->type = HGFS_FILE_TYPE_DIRECTORY; LOG(4, ("%s: is a directory\n", __FUNCTION__)); } else if (S_ISLNK(stats.st_mode)) { attr->type = HGFS_FILE_TYPE_SYMLINK; LOG(4, ("%s: is a symlink\n", __FUNCTION__)); /* * In the case of a symlink, we should populate targetName if the * caller asked. Use st_size and readlink() to do so. */ if (targetName != NULL) { myTargetName = Posix_ReadLink(fileName); if (myTargetName == NULL) { error = errno; LOG(4, ("%s: readlink returned wrong size\n", __FUNCTION__)); /* * Because of an unavoidable race between the lstat(2) and the * readlink(2), the symlink target may have lengthened and we may * not have read the entire link. If that happens, just return * "out of memory". */ status = error ? error : ENOMEM; goto exit; } } } else { /* * Now is a good time to check if the file was an alias. If so, we'll * treat it as a symlink. * * XXX: If HgfsGetattrResolveAlias fails, we'll treat the file as a * regular file. This isn't completely correct (the function may have * failed because we're out of memory), but it's better than having to * call LScopyItemInfoForRef for each file, which may negatively affect * performance. See: * * http://lists.apple.com/archives/carbon-development/2001/Nov/msg00007.html */ LOG(4, ("%s: NOT a directory or symlink\n", __FUNCTION__)); if (HgfsGetattrResolveAlias(fileName, &myTargetName)) { LOG(4, ("%s: could not resolve file aliases\n", __FUNCTION__)); } attr->type = HGFS_FILE_TYPE_REGULAR; if (myTargetName != NULL) { /* * At this point the alias target has been successfully resolved. If * the alias target is inside the same shared folder then convert it * to relative path. Converting to a relative path produces a symlink * that points to the target file in the guest OS. If the target lies * outside the shared folder then treat it the same way as if alias * has not been resolved. */ HgfsNameStatus nameStatus; size_t sharePathLen; const char* sharePath; nameStatus = HgfsServerPolicy_GetSharePath(shareName, strlen(shareName), HGFS_OPEN_MODE_READ_ONLY, &sharePathLen, &sharePath); if (nameStatus == HGFS_NAME_STATUS_COMPLETE && sharePathLen < strlen(myTargetName) && Str_Strncmp(sharePath, myTargetName, sharePathLen) == 0) { char *relativeName; relativeName = HgfsBuildRelativePath(fileName, myTargetName); free(myTargetName); myTargetName = relativeName; if (myTargetName != NULL) { /* * Let's mangle the permissions and size of the file so that * it more closely resembles a symlink. The size should be * the length of the target name (not including the * nul-terminator), and the permissions should be 777. */ stats.st_size = strlen(myTargetName); stats.st_mode |= ACCESSPERMS; attr->type = HGFS_FILE_TYPE_SYMLINK; } else { LOG(4, ("%s: out of memory\n", __FUNCTION__)); } } else { LOG(4, ("%s: alias target is outside shared folder\n", __FUNCTION__)); } } } if (myTargetName != NULL && targetName != NULL) { #if defined(__APPLE__) /* * HGFS clients will expect filenames in unicode normal form C * (precomposed) so Mac hosts must convert from normal form D * (decomposed). */ if (!CodeSet_Utf8FormDToUtf8FormC(myTargetName, strlen(myTargetName), targetName, NULL)) { LOG(4, ("%s: Unable to normalize form C \"%s\"\n", __FUNCTION__, myTargetName)); status = HgfsPlatformConvertFromNameStatus(HGFS_NAME_STATUS_FAILURE); goto exit; } #else *targetName = myTargetName; myTargetName = NULL; #endif } HgfsStatToFileAttr(&stats, &creationTime, attr); /* * In the case we have a Windows client, force the hidden flag. * This will be ignored by Linux, Solaris clients. */ HgfsGetHiddenAttr(fileName, attr); HgfsGetSequentialOnlyFlagFromName(fileName, attr); /* Get effective permissions if we can */ if (!(S_ISLNK(stats.st_mode))) { HgfsOpenMode shareMode; uint32 permissions; HgfsNameStatus nameStatus; nameStatus = HgfsServerPolicy_GetShareMode(shareName, strlen(shareName), &shareMode); if (nameStatus == HGFS_NAME_STATUS_COMPLETE && HgfsEffectivePermissions(fileName, shareMode == HGFS_OPEN_MODE_READ_ONLY, &permissions) == 0) { attr->mask |= HGFS_ATTR_VALID_EFFECTIVE_PERMS; attr->effectivePerms = permissions; } } exit: free(myTargetName); return status; } /* *----------------------------------------------------------------------------- * * HgfsPlatformGetattrFromFd -- * * Performs a stat operation on the given file desc. * Does necessary translation between Unix file stats and the * HgfsFileAttrInfo formats. * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsPlatformGetattrFromFd(fileDesc fileDesc, // IN: file descriptor HgfsSessionInfo *session, // IN: session info HgfsFileAttrInfo *attr) // OUT: FileAttrInfo to copy into { HgfsInternalStatus status = 0; struct stat stats; int error; HgfsOpenMode shareMode; HgfsHandle handle = HGFS_INVALID_HANDLE; char *fileName = NULL; size_t fileNameLen; uint64 creationTime; ASSERT(attr); ASSERT(session); LOG(4, ("%s: getting attrs for %u\n", __FUNCTION__, fileDesc)); error = HgfsFStat(fileDesc, &stats, &creationTime); if (error) { LOG(4, ("%s: error stating file: %s\n", __FUNCTION__, strerror(error))); status = error; goto exit; } /* * For now, everything that isn't a directory or symlink is a regular * file. */ if (S_ISDIR(stats.st_mode)) { attr->type = HGFS_FILE_TYPE_DIRECTORY; LOG(4, ("%s: is a directory\n", __FUNCTION__)); } else if (S_ISLNK(stats.st_mode)) { attr->type = HGFS_FILE_TYPE_SYMLINK; LOG(4, ("%s: is a symlink\n", __FUNCTION__)); } else { attr->type = HGFS_FILE_TYPE_REGULAR; LOG(4, ("%s: NOT a directory or symlink\n", __FUNCTION__)); } HgfsStatToFileAttr(&stats, &creationTime, attr); /* * XXX - Correct share mode checking should be fully implemented. * * For now, we must ensure that the client only sees read only * attributes when the share is read only. This allows the client * to make decisions to fail write/delete operations. * It is required by clients who use file handles that * are cached, for setting attributes, renaming and deletion. */ if (!HgfsFileDesc2Handle(fileDesc, session, &handle)) { LOG(4, ("%s: could not get HGFS handle for fd %u\n", __FUNCTION__, fileDesc)); status = EBADF; goto exit; } if (!HgfsHandle2ShareMode(handle, session, &shareMode)) { LOG(4, ("%s: could not get share mode fd %u\n", __FUNCTION__, fileDesc)); status = EBADF; goto exit; } if (!HgfsHandle2FileName(handle, session, &fileName, &fileNameLen)) { LOG(4, ("%s: could not map cached target file handle %u\n", __FUNCTION__, handle)); status = EBADF; goto exit; } /* * In the case we have a Windows client, force the hidden flag. * This will be ignored by Linux, Solaris clients. */ HgfsGetHiddenAttr(fileName, attr); HgfsGetSequentialOnlyFlagFromFd(fileDesc, attr); if (shareMode == HGFS_OPEN_MODE_READ_ONLY) { /* * Share does not allow write, so tell the client * everything is read only. */ if (attr->mask & HGFS_ATTR_VALID_OWNER_PERMS) { attr->ownerPerms &= ~HGFS_PERM_WRITE; } if (attr->mask & HGFS_ATTR_VALID_GROUP_PERMS) { attr->groupPerms &= ~HGFS_PERM_WRITE; } if (attr->mask & HGFS_ATTR_VALID_OTHER_PERMS) { attr->otherPerms &= ~HGFS_PERM_WRITE; } } exit: free(fileName); return status; } /* *----------------------------------------------------------------------------- * * HgfsStatToFileAttr -- * * Does necessary translation between Unix file stats and the * HgfsFileAttrInfo formats. * It expects creationTime to be in platform-independent HGFS format and * stats in a platform-specific stat format. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsStatToFileAttr(struct stat *stats, // IN: stat information uint64 *creationTime, // IN: file creation time HgfsFileAttrInfo *attr) // OUT: FileAttrInfo to copy into { attr->size = stats->st_size; attr->creationTime = *creationTime; #ifdef __FreeBSD__ /* * FreeBSD: All supported versions have timestamps with nanosecond resolution. * FreeBSD 5+ has also file creation time. */ attr->accessTime = HgfsConvertTimeSpecToNtTime(&stats->st_atimespec); attr->writeTime = HgfsConvertTimeSpecToNtTime(&stats->st_mtimespec); attr->attrChangeTime = HgfsConvertTimeSpecToNtTime(&stats->st_ctimespec); #elif defined(linux) /* * Linux: Glibc 2.3+ has st_Xtim. Glibc 2.1/2.2 has st_Xtime/__unusedX on * same place (see below). We do not support Glibc 2.0 or older. */ # if (__GLIBC__ == 2) && (__GLIBC_MINOR__ < 3) && !defined(__UCLIBC__) /* * stat structure is same between glibc 2.3 and older glibcs, just * these __unused fields are always zero. If we'll use __unused* * instead of zeroes, we get automatically nanosecond timestamps * when running on host which provides them. */ attr->accessTime = HgfsConvertToNtTime(stats->st_atime, stats->__unused1); attr->writeTime = HgfsConvertToNtTime(stats->st_mtime, stats->__unused2); attr->attrChangeTime = HgfsConvertToNtTime(stats->st_ctime, stats->__unused3); # else attr->accessTime = HgfsConvertTimeSpecToNtTime(&stats->st_atim); attr->writeTime = HgfsConvertTimeSpecToNtTime(&stats->st_mtim); attr->attrChangeTime = HgfsConvertTimeSpecToNtTime(&stats->st_ctim); # endif #else /* * Solaris, Mac OS: No nanosecond timestamps. */ attr->accessTime = HgfsConvertToNtTime(stats->st_atime, 0); attr->writeTime = HgfsConvertToNtTime(stats->st_mtime, 0); attr->attrChangeTime = HgfsConvertToNtTime(stats->st_ctime, 0); #endif attr->specialPerms = (stats->st_mode & (S_ISUID | S_ISGID | S_ISVTX)) >> 9; attr->ownerPerms = (stats->st_mode & S_IRWXU) >> 6; attr->groupPerms = (stats->st_mode & S_IRWXG) >> 3; attr->otherPerms = stats->st_mode & S_IRWXO; LOG(4, ("%s: done, permissions %o%o%o%o, size %"FMT64"u\n", __FUNCTION__, attr->specialPerms, attr->ownerPerms, attr->groupPerms, attr->otherPerms, attr->size)); #ifdef __FreeBSD__ # if !defined(VM_X86_64) && __FreeBSD_version >= 500043 # define FMTTIMET "" # else # define FMTTIMET "l" # endif #else # define FMTTIMET "l" #endif LOG(4, ("access: %"FMTTIMET"d/%"FMT64"u \nwrite: %"FMTTIMET"d/%"FMT64"u \n" "attr: %"FMTTIMET"d/%"FMT64"u\n", stats->st_atime, attr->accessTime, stats->st_mtime, attr->writeTime, stats->st_ctime, attr->attrChangeTime)); #undef FMTTIMET attr->userId = stats->st_uid; attr->groupId = stats->st_gid; attr->hostFileId = stats->st_ino; attr->volumeId = stats->st_dev; attr->mask = HGFS_ATTR_VALID_TYPE | HGFS_ATTR_VALID_SIZE | HGFS_ATTR_VALID_CREATE_TIME | HGFS_ATTR_VALID_ACCESS_TIME | HGFS_ATTR_VALID_WRITE_TIME | HGFS_ATTR_VALID_CHANGE_TIME | HGFS_ATTR_VALID_SPECIAL_PERMS | HGFS_ATTR_VALID_OWNER_PERMS | HGFS_ATTR_VALID_GROUP_PERMS | HGFS_ATTR_VALID_OTHER_PERMS | HGFS_ATTR_VALID_USERID | HGFS_ATTR_VALID_GROUPID | HGFS_ATTR_VALID_FILEID | HGFS_ATTR_VALID_VOLID; } /* *----------------------------------------------------------------------------- * * HgfsSetattrMode -- * * Set the permissions based on stat and attributes. * * Results: * TRUE if permissions have changed. * FALSE otherwise. * * Note that newPermissions is always set. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool HgfsSetattrMode(struct stat *statBuf, // IN: stat info HgfsFileAttrInfo *attr, // IN: attrs to set mode_t *newPermissions) // OUT: new perms { Bool permsChanged = FALSE; ASSERT(statBuf); ASSERT(attr); ASSERT(newPermissions); *newPermissions = ~ALLPERMS; if (attr->mask & HGFS_ATTR_VALID_SPECIAL_PERMS) { *newPermissions |= attr->specialPerms << 9; permsChanged = TRUE; } else { *newPermissions |= statBuf->st_mode & (S_ISUID | S_ISGID | S_ISVTX); } if (attr->mask & HGFS_ATTR_VALID_OWNER_PERMS) { *newPermissions |= attr->ownerPerms << 6; permsChanged = TRUE; } else { *newPermissions |= statBuf->st_mode & S_IRWXU; } if (attr->mask & HGFS_ATTR_VALID_GROUP_PERMS) { *newPermissions |= attr->groupPerms << 3; permsChanged = TRUE; } else { *newPermissions |= statBuf->st_mode & S_IRWXG; } if (attr->mask & HGFS_ATTR_VALID_OTHER_PERMS) { *newPermissions |= attr->otherPerms; permsChanged = TRUE; } else { *newPermissions |= statBuf->st_mode & S_IRWXO; } return permsChanged; } /* *----------------------------------------------------------------------------- * * HgfsSetattrOwnership -- * * Set the user and group ID based the attributes. * * Results: * TRUE if ownership has changed. * FALSE otherwise. * * Note that newUid/newGid are always set. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool HgfsSetattrOwnership(HgfsFileAttrInfo *attr, // IN: attrs to set uid_t *newUid, // OUT: new user ID gid_t *newGid) // OUT: new group ID { Bool idChanged = FALSE; ASSERT(attr); ASSERT(newUid); ASSERT(newGid); *newUid = *newGid = -1; if (attr->mask & HGFS_ATTR_VALID_USERID) { *newUid = attr->userId; idChanged = TRUE; } if (attr->mask & HGFS_ATTR_VALID_GROUPID) { *newGid = attr->groupId; idChanged = TRUE; } return idChanged; } /* *----------------------------------------------------------------------------- * * HgfsSetattrTimes -- * * Set the time stamps based on stat and attributes. * * Results: * Zero on success. accessTime/modTime contain new times. * Non-zero on failure. * * Note that timesChanged is always set. * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsInternalStatus HgfsSetattrTimes(struct stat *statBuf, // IN: stat info HgfsFileAttrInfo *attr, // IN: attrs to set HgfsAttrHint hints, // IN: attr hints struct timeval *accessTime, // OUT: access time struct timeval *modTime, // OUT: modification time Bool *timesChanged) // OUT: times changed { HgfsInternalStatus status = 0; int error; ASSERT(statBuf); ASSERT(attr); ASSERT(accessTime); ASSERT(modTime); ASSERT(timesChanged); *timesChanged = FALSE; if (attr->mask & (HGFS_ATTR_VALID_ACCESS_TIME | HGFS_ATTR_VALID_WRITE_TIME)) { /* * utime(2) only lets you update both atime and mtime at once, so * if either one needs updating, first we get the current times * and call utime with some combination of the current and new * times. This is a bit racy because someone else could update * one of them in between, but this seems to be how "touch" does * things, so we'll go with it. [bac] */ if ((attr->mask & (HGFS_ATTR_VALID_ACCESS_TIME | HGFS_ATTR_VALID_WRITE_TIME)) != (HGFS_ATTR_VALID_ACCESS_TIME | HGFS_ATTR_VALID_WRITE_TIME)) { /* * XXX Set also usec from nsec stat fields. */ accessTime->tv_sec = statBuf->st_atime; accessTime->tv_usec = 0; modTime->tv_sec = statBuf->st_mtime; modTime->tv_usec = 0; } /* * If times need updating, we either use the guest-provided time or the * host time. HGFS_ATTR_HINT_SET_x_TIME_ will be set if we should use * the guest time, and alwaysUseHostTime will be TRUE if the config * option to always use host time is set. */ if (attr->mask & HGFS_ATTR_VALID_ACCESS_TIME) { if (!alwaysUseHostTime && (hints & HGFS_ATTR_HINT_SET_ACCESS_TIME)) { /* Use the guest-provided time */ struct timespec ts; HgfsConvertFromNtTimeNsec(&ts, attr->accessTime); accessTime->tv_sec = ts.tv_sec; accessTime->tv_usec = ts.tv_nsec / 1000; } else { /* Use the host's time */ struct timeval tv; if (gettimeofday(&tv, NULL) != 0) { error = errno; LOG(4, ("%s: gettimeofday error: %s\n", __FUNCTION__, strerror(error))); status = error; goto exit; } accessTime->tv_sec = tv.tv_sec; accessTime->tv_usec = tv.tv_usec; } } if (attr->mask & HGFS_ATTR_VALID_WRITE_TIME) { if (!alwaysUseHostTime && (hints & HGFS_ATTR_HINT_SET_WRITE_TIME)) { struct timespec ts; HgfsConvertFromNtTimeNsec(&ts, attr->writeTime); modTime->tv_sec = ts.tv_sec; modTime->tv_usec = ts.tv_nsec / 1000; } else { struct timeval tv; if (gettimeofday(&tv, NULL) != 0) { error = errno; LOG(4, ("%s: gettimeofday error: %s\n", __FUNCTION__, strerror(error))); status = error; goto exit; } modTime->tv_sec = tv.tv_sec; modTime->tv_usec = tv.tv_usec; } } *timesChanged = TRUE; } exit: return status; } /* *----------------------------------------------------------------------------- * * HgfsPlatformSetattrFromFd -- * * Handle a Setattr request by file descriptor. * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsPlatformSetattrFromFd(HgfsHandle file, // IN: file descriptor HgfsSessionInfo *session, // IN: session info HgfsFileAttrInfo *attr, // OUT: attrs to set HgfsAttrHint hints) // IN: attr hints { HgfsInternalStatus status = 0, timesStatus; int error; struct stat statBuf; struct timeval times[2]; mode_t newPermissions; uid_t newUid = -1; gid_t newGid = -1; Bool permsChanged = FALSE; Bool timesChanged = FALSE; Bool idChanged = FALSE; int fd; HgfsServerLock serverLock; ASSERT(session); ASSERT(file != HGFS_INVALID_HANDLE); status = HgfsPlatformGetFd(file, session, FALSE, &fd); if (status != 0) { LOG(4, ("%s: Could not get file descriptor\n", __FUNCTION__)); goto exit; } /* We need the old stats so that we can preserve times. */ if (fstat(fd, &statBuf) == -1) { error = errno; LOG(4, ("%s: error stating file %u: %s\n", __FUNCTION__, fd, strerror(error))); status = error; goto exit; } /* * Try to make each requested attribute change. In the event that * one operation fails, we still attempt to perform any other * operations that the driver requested. We return success only * if all operations succeeded. */ /* * Set permissions based on what we got in the packet. If we didn't get * a particular bit, use the existing permissions. In that case we don't * toggle permsChanged since it should not influence our decision of * whether to actually call chmod or not. */ permsChanged = HgfsSetattrMode(&statBuf, attr, &newPermissions); if (permsChanged) { LOG(4, ("%s: set mode %o\n", __FUNCTION__, (unsigned)newPermissions)); if (fchmod(fd, newPermissions) < 0) { error = errno; LOG(4, ("%s: error chmoding file %u: %s\n", __FUNCTION__, fd, strerror(error))); status = error; } } idChanged = HgfsSetattrOwnership(attr, &newUid, &newGid); if (idChanged) { LOG(4, ("%s: set uid %"FMTUID" and gid %"FMTUID"\n", __FUNCTION__, newUid, newGid)); if (fchown(fd, newUid, newGid) < 0) { error = errno; LOG(4, ("%s: error chowning file %u: %s\n", __FUNCTION__, fd, strerror(error))); status = error; } } if (attr->mask & HGFS_ATTR_VALID_SIZE) { /* * XXX: Truncating the file will trigger an oplock break. The client * should have predicted this and removed the oplock prior to sending * the truncate request. At this point, the server must safeguard itself * against deadlock. */ if (!HgfsHandle2ServerLock(file, session, &serverLock)) { LOG(4, ("%s: File handle is no longer valid.\n", __FUNCTION__)); status = EBADF; } else if (serverLock != HGFS_LOCK_NONE) { LOG(4, ("%s: Client attempted to truncate an oplocked file\n", __FUNCTION__)); status = EBUSY; } else if (ftruncate(fd, attr->size) < 0) { error = errno; LOG(4, ("%s: error truncating file %u: %s\n", __FUNCTION__, fd, strerror(error))); status = error; } else { LOG(4, ("%s: set size %"FMT64"u\n", __FUNCTION__, attr->size)); } } /* Setting hidden attribute for symlink itself is not supported. */ if ((attr->mask & HGFS_ATTR_VALID_FLAGS) && !S_ISLNK(statBuf.st_mode)) { char *localName; size_t localNameSize; if (HgfsHandle2FileName(file, session, &localName, &localNameSize)) { status = HgfsSetHiddenXAttr(localName, (attr->flags & HGFS_ATTR_HIDDEN) != 0, newPermissions); free(localName); } } timesStatus = HgfsSetattrTimes(&statBuf, attr, hints, ×[0], ×[1], ×Changed); if (timesStatus == 0 && timesChanged) { uid_t uid = (uid_t)-1; Bool switchToSuperUser = FALSE; LOG(4, ("%s: setting new times\n", __FUNCTION__)); /* * If the VMX is neither the file owner nor running as root, return an error. * Otherwise if we are not the file owner switch to superuser briefly * to set the files times using futimes. */ if (geteuid() != statBuf.st_uid) { /* We are not the file owner. Check if we are running as root. */ if (!Id_IsSuperUser()) { LOG(4, ("%s: only owner of file %u or root can call futimes\n", __FUNCTION__, fd)); /* XXX: Linux kernel says both EPERM and EACCES are valid here. */ status = EPERM; goto exit; } uid = Id_BeginSuperUser(); switchToSuperUser = TRUE; } /* * XXX Newer glibc provide also lutimes() and futimes() * when we politely ask with -D_GNU_SOURCE -D_BSD_SOURCE */ if (futimes(fd, times) < 0) { if (!switchToSuperUser) { /* * Check bug 718252. If futimes() fails, switch to * superuser briefly and try futimes() one more time. */ uid = Id_BeginSuperUser(); switchToSuperUser = TRUE; if (futimes(fd, times) < 0) { error = errno; LOG(4, ("%s: Executing futimes as owner on file: %u " "failed with error: %s\n", __FUNCTION__, fd, strerror(error))); status = error; } } else { error = errno; LOG(4, ("%s: Executing futimes as superuser on file: %u " "failed with error: %s\n", __FUNCTION__, fd, strerror(error))); status = error; } } if (switchToSuperUser) { Id_EndSuperUser(uid); } } else if (timesStatus != 0) { status = timesStatus; } exit: return status; } /* *----------------------------------------------------------------------------- * * HgfsPlatformSetattrFromName -- * * Handle a Setattr request by name. * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsPlatformSetattrFromName(char *localName, // IN: Name HgfsFileAttrInfo *attr, // IN: attrs to set HgfsShareOptions configOptions, // IN: share options HgfsAttrHint hints) // IN: attr hints { HgfsInternalStatus status = 0, timesStatus; struct stat statBuf; struct timeval times[2]; mode_t newPermissions; uid_t newUid = -1; gid_t newGid = -1; Bool permsChanged = FALSE; Bool timesChanged = FALSE; Bool idChanged = FALSE; int error; ASSERT(localName); if (!HgfsServerPolicy_IsShareOptionSet(configOptions, HGFS_SHARE_FOLLOW_SYMLINKS)) { /* * If followSymlink option is not set, verify that the pathname isn't a * symlink. Some of the following syscalls (chmod, for example) will * follow a link. So we need to verify the final component too. The * parent has already been verified in HgfsServerGetAccess. * * XXX: This is racy. But clients interested in preventing a race should * have sent us a Setattr packet with a valid HGFS handle. */ if (File_IsSymLink(localName)) { LOG(4, ("%s: pathname contains a symlink\n", __FUNCTION__)); status = EINVAL; goto exit; } } LOG(4, ("%s: setting attrs for \"%s\"\n", __FUNCTION__, localName)); /* We need the old stats so that we can preserve times. */ if (Posix_Lstat(localName, &statBuf) == -1) { error = errno; LOG(4, ("%s: error stating file \"%s\": %s\n", __FUNCTION__, localName, strerror(error))); status = error; goto exit; } /* * Try to make each requested attribute change. In the event that * one operation fails, we still attempt to perform any other * operations that the driver requested. We return success only * if all operations succeeded. */ /* * Set permissions based on what we got in the packet. If we didn't get * a particular bit, use the existing permissions. In that case we don't * toggle permsChanged since it should not influence our decision of * whether to actually call chmod or not. */ permsChanged = HgfsSetattrMode(&statBuf, attr, &newPermissions); if (permsChanged) { LOG(4, ("%s: set mode %o\n", __FUNCTION__, (unsigned)newPermissions)); if (Posix_Chmod(localName, newPermissions) < 0) { error = errno; LOG(4, ("%s: error chmoding file \"%s\": %s\n", __FUNCTION__, localName, strerror(error))); status = error; } } idChanged = HgfsSetattrOwnership(attr, &newUid, &newGid); /* * Chown changes the uid and gid together. If one of them should * not be changed, we pass in -1. */ if (idChanged) { if (Posix_Lchown(localName, newUid, newGid) < 0) { error = errno; LOG(4, ("%s: error chowning file \"%s\": %s\n", __FUNCTION__, localName, strerror(error))); status = error; } } if (attr->mask & HGFS_ATTR_VALID_SIZE) { if (Posix_Truncate(localName, attr->size) < 0) { error = errno; LOG(4, ("%s: error truncating file \"%s\": %s\n", __FUNCTION__, localName, strerror(error))); status = error; } else { LOG(4, ("%s: set size %"FMT64"u\n", __FUNCTION__, attr->size)); } } if (attr->mask & HGFS_ATTR_VALID_FLAGS) { status = HgfsSetHiddenXAttr(localName, (attr->flags & HGFS_ATTR_HIDDEN) != 0, newPermissions); } timesStatus = HgfsSetattrTimes(&statBuf, attr, hints, ×[0], ×[1], ×Changed); if (timesStatus == 0 && timesChanged) { /* * XXX Newer glibc provide also lutimes() and futimes() * when we politely ask with -D_GNU_SOURCE -D_BSD_SOURCE */ if (Posix_Utimes(localName, times) < 0) { error = errno; LOG(4, ("%s: utimes error on file \"%s\": %s\n", __FUNCTION__, localName, strerror(error))); status = error; } } else if (timesStatus != 0) { status = timesStatus; } exit: return status; } HgfsInternalStatus HgfsPlatformWriteWin32Stream(HgfsHandle file, // IN: packet header char *dataToWrite, // IN: request type size_t requiredSize, Bool doSecurity, uint32 *actualSize, HgfsSessionInfo *session) { return EPROTO; } /* *----------------------------------------------------------------------------- * * HgfsConvertToUtf8FormC -- * * Converts file name coming from OS to Utf8 form C. * The function NOOP on Linux where the name is already in correct * encoding. * On Mac OS the default encoding is Utf8 form D thus a convertion to * Utf8 for C is required. * * Results: * TRUE on success. Buffer has name in Utf8 form C encoding. * FALSE on error. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsConvertToUtf8FormC(char *buffer, // IN/OUT: name to normalize size_t bufferSize) // IN: size of the name buffer { #if defined(__APPLE__) size_t entryNameLen; char *entryName = NULL; Bool result; /* * HGFS clients receive names in unicode normal form C, * (precomposed) so Mac hosts must convert from normal form D * (decomposed). */ if (CodeSet_Utf8FormDToUtf8FormC(buffer, bufferSize, &entryName, &entryNameLen)) { result = entryNameLen < bufferSize; if (result) { memcpy(buffer, entryName, entryNameLen + 1); } free(entryName); } else { LOG(4, ("%s: Unable to normalize form C \"%s\"\n", __FUNCTION__, buffer)); result = FALSE; } return result; #else size_t size; /* * Buffer may contain invalid data after the null terminating character. * We need to check the validity of the buffer only till the null * terminating character (if any). Calculate the real size of the * string before calling Unicode_IsBufferValid(). */ for (size = 0; size < bufferSize ; size++) { if ('\0' == buffer[size]) { break; } } return Unicode_IsBufferValid(buffer, size, STRING_ENCODING_UTF8); #endif /* defined(__APPLE__) */ } /* *----------------------------------------------------------------------------- * * HgfsServerScandir -- * * The cross-platform HGFS server code will call into this function * in order to populate a list of dents. In the Linux case, we want to avoid * using scandir(3) because it makes no provisions for not following * symlinks. Instead, we'll open(2) the directory with O_DIRECTORY and * O_NOFOLLOW, call getdents(2) directly, then close(2) the directory. * * On Mac OS getdirentries became deprecated starting from 10.6 and * there is no similar API available. Thus on Mac OS readdir is used that * returns one directory entry at a time. * * Results: * Zero on success. numDents contains the number of directory entries found. * Non-zero on error. * * Side effects: * Memory allocation. * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsServerScandir(char const *baseDir, // IN: Directory to search in size_t baseDirLen, // IN: Ignored Bool followSymlinks, // IN: followSymlinks config option DirectoryEntry ***dents, // OUT: Array of DirectoryEntrys int *numDents) // OUT: Number of DirectoryEntrys { #if defined(__APPLE__) DIR *fd = NULL; #else int fd = -1; int openFlags = O_NONBLOCK | O_RDONLY | O_DIRECTORY | O_NOFOLLOW; #endif int result; DirectoryEntry **myDents = NULL; int myNumDents = 0; HgfsInternalStatus status = 0; /* * XXX: glibc uses 8192 (BUFSIZ) when it can't get st_blksize from a stat. * Should we follow its lead and use stat to get st_blksize? */ char buffer[8192]; #if defined(__APPLE__) /* * Since opendir does not support O_NOFOLLOW flag need to explicitly verify * that we are not dealing with symlink if follow symlinks is * not allowed. */ if (!followSymlinks) { struct stat st; if (lstat(baseDir, &st) == -1) { status = errno; LOG(4, ("%s: error in lstat: %d (%s)\n", __FUNCTION__, status, strerror(status))); goto exit; } if (S_ISLNK(st.st_mode)) { status = EACCES; LOG(4, ("%s: do not follow symlink\n", __FUNCTION__)); goto exit; } } fd = Posix_OpenDir(baseDir); if (NULL == fd) { status = errno; LOG(4, ("%s: error in opendir: %d (%s)\n", __FUNCTION__, status, strerror(status))); goto exit; } #else /* Follow symlinks if config option is set. */ if (followSymlinks) { openFlags &= ~O_NOFOLLOW; } /* We want a directory. No FIFOs. Symlinks only if config option is set. */ result = Posix_Open(baseDir, openFlags); if (result < 0) { status = errno; LOG(4, ("%s: error in open: %d (%s)\n", __FUNCTION__, status, strerror(status))); goto exit; } fd = result; #endif /* * Rather than read a single dent at a time, batch up multiple dents * in each call by using a buffer substantially larger than one dent. */ while ((result = getdents(fd, (void *)buffer, sizeof buffer)) > 0) { size_t offset = 0; while (offset < result) { DirectoryEntry *newDent, **newDents; newDent = (DirectoryEntry *)(buffer + offset); /* This dent had better fit in the actual space we've got left. */ ASSERT(newDent->d_reclen <= result - offset); /* Add another dent pointer to the dents array. */ newDents = realloc(myDents, sizeof *myDents * (myNumDents + 1)); if (newDents == NULL) { status = ENOMEM; goto exit; } myDents = newDents; /* * Allocate the new dent and set it up. We do a straight memcpy of * the entire record to avoid dealing with platform-specific fields. */ myDents[myNumDents] = malloc(newDent->d_reclen); if (myDents[myNumDents] == NULL) { status = ENOMEM; goto exit; } if (HgfsConvertToUtf8FormC(newDent->d_name, sizeof newDent->d_name)) { memcpy(myDents[myNumDents], newDent, newDent->d_reclen); /* * Dent is done. Bump the offset to the batched buffer to process the * next dent within it. */ myNumDents++; } else { /* * XXX: * HGFS discards all file names that can't be converted to utf8. * It is not desirable since it causes many problems like * failure to delete directories which contain such files. * Need to change this to a more reasonable behavior, similar * to name escaping which is used to deal with illegal file names. */ free(myDents[myNumDents]); } offset += newDent->d_reclen; } } if (result == -1) { status = errno; LOG(4, ("%s: error in getdents: %d (%s)\n", __FUNCTION__, status, strerror(status))); goto exit; } exit: #if defined(__APPLE__) if (NULL != fd && closedir(fd) < 0) { #else if (fd != -1 && close(fd) < 0) { #endif status = errno; LOG(4, ("%s: error in close: %d (%s)\n", __FUNCTION__, status, strerror(status))); } /* * On error, free all allocated dents. On success, set the dents pointer * given to us by the client. */ if (status != 0) { size_t i; for (i = 0; i < myNumDents; i++) { free(myDents[i]); } free(myDents); } else { *dents = myDents; *numDents = myNumDents; } return status; } /* *---------------------------------------------------------------------- * * Request Handler Functions * ------------------------- * * The functions that follow are all of the same type: they take a * request packet which came from the driver, process it, and fill out * a reply packet which is then sent back to the driver. They are * called by DispatchPacket, which dispatches an incoming packet to * the correct handler function based on the packet's opcode. * * These functions all take the following as input: * * - A pointer to a buffer containing the incoming request packet, * - A pointer to a buffer big enough to hold the outgoing reply packet, * - A pointer to the size of the incoming packet, packetSize. * * After processing the request, the handler functions write the reply * packet into the output buffer and set the packetSize to be the size * of the OUTGOING reply packet. The ServerLoop function uses the size * to send the reply back to the driver. * * Note that it is potentially okay for the caller to use the same * buffer for both input and output; handler functions should make * sure they are safe w.r.t. this possibility by storing any state * from the input buffer before they clobber it by potentially writing * output into the same buffer. * * Handler functions should return zero if they successfully processed * the request, or a negative error if an unrecoverable error * occurred. Normal errors (e.g. a poorly formed request packet) * should be handled by sending an error packet back to the driver, * NOT by returning an error code to the caller, because errors * returned by handler functions cause the server to terminate. * * [bac] * *---------------------------------------------------------------------- */ /* *----------------------------------------------------------------------------- * * HgfsPlatformReadFile -- * * Reads data from a file. * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsPlatformReadFile(HgfsHandle file, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: session info uint64 offset, // IN: file offset to read from uint32 requiredSize, // IN: length of data to read void* payload, // OUT: buffer for the read data uint32 *actualSize) // OUT: actual length read { int fd; int error; HgfsInternalStatus status; Bool sequentialOpen; ASSERT(session); LOG(4, ("%s: read fh %u, offset %"FMT64"u, count %u\n", __FUNCTION__, file, offset, requiredSize)); /* Get the file descriptor from the cache */ status = HgfsPlatformGetFd(file, session, FALSE, &fd); if (status != 0) { LOG(4, ("%s: Could not get file descriptor\n", __FUNCTION__)); return status; } if (!HgfsHandleIsSequentialOpen(file, session, &sequentialOpen)) { LOG(4, ("%s: Could not get sequenial open status\n", __FUNCTION__)); return EBADF; } #if defined(__linux__) || defined(__APPLE__) /* Read from the file. */ if (sequentialOpen) { error = read(fd, payload, requiredSize); } else { error = pread(fd, payload, requiredSize, offset); } #else /* * Seek to the offset and read from the file. Grab the IO lock to make * this and the subsequent read atomic. */ MXUser_AcquireExclLock(session->fileIOLock); if (sequentialOpen) { error = 0; // No error from seek } else { # ifdef linux { uint64 res; # if !defined(VM_X86_64) error = _llseek(fd, offset >> 32, offset & 0xFFFFFFFF, &res, 0); # else error = llseek(fd, offset >> 32, offset & 0xFFFFFFFF, &res, 0); # endif } # else error = lseek(fd, offset, 0); # endif } if (error >= 0) { error = read(fd, payload, requiredSize); } else { LOG(4, ("%s: could not seek to %"FMT64"u: %s\n", __FUNCTION__, offset, strerror(status))); } MXUser_ReleaseExclLock(session->fileIOLock); #endif if (error < 0) { status = errno; LOG(4, ("%s: error reading from file: %s\n", __FUNCTION__, strerror(status))); } else { LOG(4, ("%s: read %d bytes\n", __FUNCTION__, error)); *actualSize = error; } return status; } /* *----------------------------------------------------------------------------- * * HgfsPlatformWriteFile -- * * Performs actual writing data to a file. * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsPlatformWriteFile(HgfsHandle file, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: session info uint64 offset, // IN: file offset to write to uint32 requiredSize, // IN: length of data to write HgfsWriteFlags flags, // IN: write flags void* payload, // IN: data to be written uint32 *actualSize) // OUT: actual length written { HgfsInternalStatus status; int fd; int error = 0; Bool sequentialOpen; LOG(4, ("%s: write fh %u, offset %"FMT64"u, count %u\n", __FUNCTION__, file, offset, requiredSize)); /* Get the file desriptor from the cache */ status = HgfsPlatformGetFd(file, session, ((flags & HGFS_WRITE_APPEND) ? TRUE : FALSE), &fd); if (status != 0) { LOG(4, ("%s: Could not get file descriptor\n", __FUNCTION__)); return status; } if (!HgfsHandleIsSequentialOpen(file, session, &sequentialOpen)) { LOG(4, ("%s: Could not get sequential open status\n", __FUNCTION__)); return EBADF; } #if defined(__linux__) /* Write to the file. */ if (sequentialOpen) { error = write(fd, payload, requiredSize); } else { error = pwrite(fd, payload, requiredSize, offset); } #elif defined(__APPLE__) { Bool appendMode; if (!HgfsHandle2AppendFlag(file, session, &appendMode)) { LOG(4, ("%s: Could not get append mode\n", __FUNCTION__)); return EBADF; } /* Write to the file. */ if (sequentialOpen || appendMode) { error = write(fd, payload, requiredSize); } else { error = pwrite(fd, payload, requiredSize, offset); } } #else /* * Seek to the offset and write from the file. Grab the IO lock to make * this and the subsequent write atomic. */ MXUser_AcquireExclLock(session->fileIOLock); if (!sequentialOpen) { # ifdef linux { uint64 res; # if !defined(VM_X86_64) error = _llseek(fd, offset >> 32, offset & 0xFFFFFFFF, &res, 0); # else error = llseek(fd, offset >> 32, offset & 0xFFFFFFFF, &res, 0); # endif } # else error = lseek(fd, offset, 0); # endif } if (error < 0) { LOG(4, ("%s: could not seek to %"FMT64"u: %s\n", __FUNCTION__, offset, strerror(errno))); } else { error = write(fd, payload, requiredSize); } { int savedErr = errno; MXUser_ReleaseExclLock(session->fileIOLock); errno = savedErr; } #endif if (error < 0) { status = errno; LOG(4, ("%s: error writing to file: %s\n", __FUNCTION__, strerror(status))); } else { LOG(4, ("%s: wrote %d bytes\n", __FUNCTION__, error)); *actualSize = error; } return status; } /* *----------------------------------------------------------------------------- * * HgfsPlatformSearchDir -- * * Handle platform specific logic needed to perform search open request. * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsPlatformSearchDir(HgfsNameStatus nameStatus, // IN: name status char *dirName, // IN: relative directory name uint32 dirNameLength, // IN: length of dirName uint32 caseFlags, // IN: case flags HgfsShareInfo *shareInfo, // IN: sharfed folder information char *baseDir, // IN: name of the shared directory uint32 baseDirLen, // IN: length of the baseDir HgfsSessionInfo *session, // IN: session info HgfsHandle *handle) // OUT: search handle { HgfsInternalStatus status = 0; switch (nameStatus) { case HGFS_NAME_STATUS_COMPLETE: { char *inEnd; char *next; int len; ASSERT(baseDir); LOG(4, ("%s: searching in \"%s\", %s.\n", __FUNCTION__, baseDir, dirName)); inEnd = dirName + dirNameLength; /* Get the first component. */ len = CPName_GetComponent(dirName, inEnd, (char const **) &next); if (len >= 0) { if (*inEnd != '\0') { /* * NT4 clients can send the name without a nul-terminator. * The space for the nul is included and tested for in the size * calculations above. Size of structure (includes a single * character of the name) and the full dirname length. */ *inEnd = '\0'; } LOG(4, ("%s: dirName: %s.\n", __FUNCTION__, dirName)); status = HgfsServerSearchRealDir(baseDir, baseDirLen, dirName, shareInfo->rootDir, session, handle); } else { LOG(4, ("%s: get first component failed\n", __FUNCTION__)); status = ENOENT; } /* * If the directory exists but shared folder is write only * then return access denied, otherwise preserve the original * error code. */ if (!shareInfo->readPermissions && HGFS_NAME_STATUS_COMPLETE == status) { status = HGFS_NAME_STATUS_ACCESS_DENIED; } if (status != 0) { LOG(4, ("%s: couldn't scandir\n", __FUNCTION__)); } break; } case HGFS_NAME_STATUS_INCOMPLETE_BASE: /* * This is the base of our namespace, so enumerate all * shares. [bac] */ LOG(4, ("%s: opened search on base\n", __FUNCTION__)); status = HgfsServerSearchVirtualDir(HgfsServerPolicy_GetShares, HgfsServerPolicy_GetSharesInit, HgfsServerPolicy_GetSharesCleanup, DIRECTORY_SEARCH_TYPE_BASE, session, handle); if (status != 0) { LOG(4, ("%s: couldn't enumerate shares\n", __FUNCTION__)); } break; default: LOG(4, ("%s: access check failed\n", __FUNCTION__)); status = HgfsPlatformConvertFromNameStatus(nameStatus); } if (DOLOG(4)) { HgfsServerDumpDents(*handle, session); } return status; } /* *----------------------------------------------------------------------------- * * HgfsPlatformHandleIncompleteName -- * * Returns platform error that matches HgfsNameStatus. * * Results: * Non-zero error code. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsPlatformHandleIncompleteName(HgfsNameStatus nameStatus, // IN: name status HgfsFileAttrInfo *attr) // OUT: unused { return HgfsPlatformConvertFromNameStatus(nameStatus); } /* *----------------------------------------------------------------------------- * * HgfsPlatformDeleteFileByName -- * * POSIX specific implementation of a delete file request which accepts * utf8 file path as a parameter. * * Simply calls Posix_Unlink. * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsPlatformDeleteFileByName(char const *utf8Name) // IN: full file path in uf8 encoding { HgfsInternalStatus status; LOG(4, ("%s: unlinking \"%s\"\n", __FUNCTION__, utf8Name)); status = Posix_Unlink(utf8Name); if (status) { status = errno; LOG(4, ("%s: error: %s\n", __FUNCTION__, strerror(status))); } return status; } /* *----------------------------------------------------------------------------- * * HgfsPlatformDeleteFileByHandle -- * * POSIX specific implementation of a delete file request which accepts * HgfsHandle as a parameter. * * File handle must have appropriate access mode to allow file deletion. * Shared folder restrictions are enforced here as well. * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsPlatformDeleteFileByHandle(HgfsHandle file, // IN: File being deleted HgfsSessionInfo *session) // IN: session info { HgfsInternalStatus status; Bool readPermissions; Bool writePermissions; char *localName; size_t localNameSize; if (HgfsHandle2FileNameMode(file, session, &writePermissions, &readPermissions, &localName, &localNameSize)) { if (writePermissions && readPermissions) { status = HgfsPlatformDeleteFileByName(localName); } else { status = EPERM; } free(localName); } else { LOG(4, ("%s: could not map cached file handle %u\n", __FUNCTION__, file)); status = EBADF; } return status; } /* *----------------------------------------------------------------------------- * * HgfsPlatformDeleteDirByName -- * * POSIX specific implementation of a delete directory request which accepts * utf8 file path as a parameter. * * Simply calls Posix_Rmdir. * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsPlatformDeleteDirByName(char const *utf8Name) // IN: full file path in uf8 encoding { HgfsInternalStatus status; LOG(4, ("%s: removing \"%s\"\n", __FUNCTION__, utf8Name)); status = Posix_Rmdir(utf8Name); if (status) { status = errno; LOG(4, ("%s: error: %s\n", __FUNCTION__, strerror(status))); } return status; } /* *----------------------------------------------------------------------------- * * HgfsPlatformDeleteDirByHandle -- * * POSIX specific implementation of a Delete directory request which accepts * HgfsHandle as a parameter. * * File handle must have appropriate access mode to allow file deletion. * Shared folder restrictions are enforced here as well. * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsPlatformDeleteDirByHandle(HgfsHandle file, // IN: File being deleted HgfsSessionInfo *session) // IN: session info { HgfsInternalStatus status; Bool readPermissions; Bool writePermissions; char *localName; size_t localNameSize; if (HgfsHandle2FileNameMode(file, session, &writePermissions, &readPermissions, &localName, &localNameSize)) { if (writePermissions && readPermissions) { status = HgfsPlatformDeleteDirByName(localName); } else { status = EPERM; } free(localName); } else { LOG(4, ("%s: could not map cached file handle %u\n", __FUNCTION__, file)); status = EBADF; } return status; } /* *----------------------------------------------------------------------------- * * HgfsPlatformFileExists -- * * Platform specific function that that verifies if a file or directory exists. * * Results: * 0 if user has permissions to traverse the parent directory and * the file exists, POSIX error code otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsPlatformFileExists(char *localTargetName) // IN: Full file path utf8 encoding { int err; err = Posix_Access(localTargetName, F_OK); if (-1 == err) { err = errno; } return err; } /* *----------------------------------------------------------------------------- * * HgfsPlatformRename -- * * POSIX version of the function that renames a file or directory. * * Results: * 0 on success, POSIX error code otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsPlatformRename(char *localSrcName, // IN: local path to source file fileDesc srcFile, // IN: source file handle char *localTargetName, // IN: local path to target file fileDesc targetFile, // IN: target file handle HgfsRenameHint hints) // IN: rename hints { HgfsInternalStatus status = 0; if (hints & HGFS_RENAME_HINT_NO_REPLACE_EXISTING) { if (0 == HgfsPlatformFileExists(localTargetName)) { status = EEXIST; goto exit; } } LOG(4, ("%s: renaming \"%s\" to \"%s\"\n", __FUNCTION__, localSrcName, localTargetName)); status = Posix_Rename(localSrcName, localTargetName); if (status) { status = errno; LOG(4, ("%s: error: %s\n", __FUNCTION__, strerror(status))); } exit: return status; } /* *----------------------------------------------------------------------------- * * HgfsPlatformCreateDir -- * * POSIX specific code that implements create directory request. * * It invokes POSIX to create the directory and then assigns * file attributes to the new directory if attributes are specified * by the guest. * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsPlatformCreateDir(HgfsCreateDirInfo *info, // IN: direcotry properties char *utf8Name) // IN: full path for the new directory { mode_t permissions; HgfsInternalStatus status; /* * Create mode_t for use in mkdir(). If owner permissions are missing, use * read/write/execute for the owner permissions. If group or other * permissions are missing, use the owner permissions. * * This sort of makes sense. If the Windows driver wants to make a dir * read-only, it probably intended for the dir to be 666. Since creating * a directory requires a valid mode, it's highly unlikely that we'll ever * be creating a directory without owner permissions. */ permissions = ~ALLPERMS; permissions |= info->mask & HGFS_CREATE_DIR_VALID_SPECIAL_PERMS ? info->specialPerms << 9 : 0; permissions |= info->mask & HGFS_CREATE_DIR_VALID_OWNER_PERMS ? info->ownerPerms << 6 : S_IRWXU; permissions |= info->mask & HGFS_CREATE_DIR_VALID_GROUP_PERMS ? info->groupPerms << 3 : (permissions & S_IRWXU) >> 3; permissions |= info->mask & HGFS_CREATE_DIR_VALID_OTHER_PERMS ? info->otherPerms : (permissions & S_IRWXU) >> 6; LOG(4, ("%s: making dir \"%s\", mode %"FMTMODE"\n", __FUNCTION__, utf8Name, permissions)); status = Posix_Mkdir(utf8Name, permissions); if ((info->mask & HGFS_CREATE_DIR_VALID_FILE_ATTR) && (info->fileAttr & HGFS_ATTR_HIDDEN) && 0 == status) { /* * Set hidden attribute when requested. * Do not fail directory creation if setting hidden attribute fails. */ HgfsSetHiddenXAttr(utf8Name, TRUE, permissions); } if (status) { status = errno; LOG(4, ("%s: error: %s\n", __FUNCTION__, strerror(status))); } return status; } /* *----------------------------------------------------------------------------- * * HgfsPlatformSymlinkCreate -- * * Platform specific function that actually creates the symbolic link. * * Results: * Zero on success. * Non-zero on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsPlatformSymlinkCreate(char *localSymlinkName, // IN: symbolic link file name char *localTargetName) // IN: symlink target name { HgfsInternalStatus status = 0; int error; /* XXX: Should make use of targetNameP->flags? */ error = Posix_Symlink(localTargetName, localSymlinkName); if (error) { status = errno; LOG(4, ("%s: error: %s\n", __FUNCTION__, strerror(errno))); } return status; } /* *---------------------------------------------------------------------- * * HgfsServerHasSymlink -- * * This function determines if any of the intermediate components of the * fileName makes references outside the actual shared path. We do not * check for the last component as none of the server operations follow * symlinks. Also some ops that call us expect to operate on a symlink * final component. * * We use following algorithm. It takes 2 parameters, sharePath and * fileName, and returns non-zero errno if fileName makes an invalid * reference. The idea is to resolve both the sharePath and parent * directory of the fileName. The sharePath is already resolved * beforehand in HgfsServerPolicyRead. During resolution, we eliminate * all the ".", "..", and symlinks handled by the realpath(3) libc call. * * We use parent because last component could be a symlink or a component * that doesn't exist. After resolving, we determine if sharePath is a * prefix of fileName. * * Note that realpath(3) behaves differently on GNU and BSD systems. * Following table lists the difference: * * GNU realpath BSD realpath * ----------------------- ----------------------- * * "/tmp/existingFile" "/tmp/existingFile" (0) "/tmp/existingFile" (0) * "/tmp/missingFile" NULL (ENOENT) "/tmp/missingFile" (0) * "/missingDir/foo" NULL (ENOENT) NULL (ENOENT) * In /tmp, "" NULL (ENOENT) "/tmp" (0) * In /tmp, "." "/tmp" (0) "/tmp" (0) * * Results: * HGFS_NAME_STATUS_COMPLETE if the given path has a symlink, an appropriate name status error otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ HgfsNameStatus HgfsServerHasSymlink(const char *fileName, // IN size_t fileNameLength, // IN const char *sharePath, // IN size_t sharePathLength) // IN { char *resolvedFileDirPath = NULL; char *fileDirName = NULL; HgfsInternalStatus status; HgfsNameStatus nameStatus = HGFS_NAME_STATUS_COMPLETE; ASSERT(fileName); ASSERT(sharePath); ASSERT(sharePathLength <= fileNameLength); LOG(4, ("%s: fileName: %s, sharePath: %s#\n", __FUNCTION__, fileName, sharePath)); /* * Return success if: * - empty fileName or * - sharePath is empty (this is for special root share that allows * access to entire host) or * - fileName and sharePath are same. */ if (fileNameLength == 0 || sharePathLength == 0 || Str_Strcmp(sharePath, fileName) == 0) { goto exit; } /* Separate out parent directory of the fileName. */ File_GetPathName(fileName, &fileDirName, NULL); /* * File_GetPathName may return an empty string to signify the root of * the filesystem. To simplify subsequent processing, let's convert such * empty strings to "/" when found. See File_GetPathName header comment * for details. */ if (strlen(fileDirName) == 0) { char *p; p = realloc(fileDirName, sizeof (DIRSEPS)); if (p == NULL) { nameStatus = HGFS_NAME_STATUS_OUT_OF_MEMORY; LOG(4, ("%s: failed to realloc fileDirName.\n", __FUNCTION__)); goto exit; } else { fileDirName = p; Str_Strcpy(fileDirName, DIRSEPS, sizeof (DIRSEPS)); } } /* * Resolve parent directory of fileName. * Use realpath(2) to resolve the parent. */ resolvedFileDirPath = Posix_RealPath(fileDirName); if (resolvedFileDirPath == NULL) { /* Let's return some meaningful errors if possible. */ status = errno; switch (status) { case ENOENT: nameStatus = HGFS_NAME_STATUS_DOES_NOT_EXIST; break; case ENOTDIR: nameStatus = HGFS_NAME_STATUS_NOT_A_DIRECTORY; break; default: nameStatus = HGFS_NAME_STATUS_FAILURE; break; } LOG(4, ("%s: realpath failed: fileDirName: %s: %s\n", __FUNCTION__, fileDirName, strerror(errno))); goto exit; } /* Resolved parent should match with the shareName. */ if (Str_Strncmp(sharePath, resolvedFileDirPath, sharePathLength) != 0) { nameStatus = HGFS_NAME_STATUS_ACCESS_DENIED; LOG(4, ("%s: resolved parent do not match, parent: %s, resolved: %s#\n", __FUNCTION__, fileDirName, resolvedFileDirPath)); goto exit; } exit: free(resolvedFileDirPath); free(fileDirName); return nameStatus; } /* *----------------------------------------------------------------------------- * * HgfsServerWriteWin32Stream -- * * Handle a write request in the WIN32_STREAM_ID format. * * Results: * EOPNOTSUPP, because this is unimplemented. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsServerWriteWin32Stream(char const *packetIn, // IN: incoming packet HgfsOp op, // IN: request type const void *payload, // IN: HGFS operational packet (without header) size_t payloadSize, // IN: size of HGFS operational packet HgfsSessionInfo *session) // IN: session info { return EOPNOTSUPP; } #ifdef HGFS_OPLOCKS /* *----------------------------------------------------------------------------- * * HgfsAckOplockBreak -- * * Platform-dependent implementation of oplock break acknowledgement. * This function gets called when the oplock break rpc command is completed. * The rpc oplock break command (HgfsServerOplockBreak) is in hgfsServer.c * * On Linux, we use fcntl() to downgrade the lease. Then we update the node * cache, free the clientData, and call it a day. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsAckOplockBreak(ServerLockData *lockData, // IN: server lock info HgfsServerLock replyLock) // IN: client has this lock { int fileDesc, newLock; HgfsServerLock actualLock; ASSERT(lockData); fileDesc = lockData->fileDesc; LOG(4, ("%s: Acknowledging break on fd %d\n", __FUNCTION__, fileDesc)); /* * The Linux server supports lock downgrading. We only downgrade to a shared * lock if our previous call to fcntl() said we could, and if the client * wants to downgrade to a shared lock. Otherwise, we break altogether. */ if (lockData->serverLock == HGFS_LOCK_SHARED && replyLock == HGFS_LOCK_SHARED) { newLock = F_RDLCK; actualLock = replyLock; } else { newLock = F_UNLCK; actualLock = HGFS_LOCK_NONE; } /* Downgrade or acknowledge the break altogether. */ if (fcntl(fileDesc, F_SETLEASE, newLock) == -1) { int error = errno; Log("%s: Could not break lease on fd %d: %s\n", __FUNCTION__, fileDesc, strerror(error)); } /* Cleanup. */ HgfsUpdateNodeServerLock(fileDesc, actualLock); free(lockData); } #endif #if defined(__APPLE__) /* *----------------------------------------------------------------------------- * * HgfsGetHiddenXattr -- * * For Mac hosts returns true if file has invisible bit set in the FileFinder * extended attributes. * * Results: * 0 if succeeded getting attribute, error code otherwise otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsInternalStatus HgfsGetHiddenXAttr(char const *fileName, // IN: File name Bool *attribute) // OUT: Hidden atribute { struct attrlist attrList; struct FInfoAttrBuf attrBuf; HgfsInternalStatus err; ASSERT(fileName); ASSERT(attribute); memset(&attrList, 0, sizeof attrList); attrList.bitmapcount = ATTR_BIT_MAP_COUNT; attrList.commonattr = ATTR_CMN_OBJTYPE | ATTR_CMN_FNDRINFO; err = getattrlist(fileName, &attrList, &attrBuf, sizeof attrBuf, 0); if (err == 0) { switch (attrBuf.objType) { case VREG: { FileInfo *info = (FileInfo*) attrBuf.finderInfo; uint16 finderFlags = CFSwapInt16BigToHost(info->finderFlags); *attribute = (finderFlags & kIsInvisible) != 0; break; } case VDIR: { FolderInfo *info = (FolderInfo*) attrBuf.finderInfo; uint16 finderFlags = CFSwapInt16BigToHost(info->finderFlags); *attribute = (finderFlags & kIsInvisible) != 0; break; } default: LOG(4, ("%s: Unrecognized object type %d\n", __FUNCTION__, attrBuf.objType)); err = EINVAL; } } else { LOG(4, ("%s: Error %d when getting attributes\n", __FUNCTION__, err)); } return err; } /* *----------------------------------------------------------------------------- * * ChangeInvisibleFlag -- * * Changes value of the invisible bit in a flags variable to a value defined * by setHidden parameter. * * Results: * TRUE flag has been changed, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool ChangeInvisibleFlag(uint16 *flags, // IN/OUT: variable that contains flags Bool setHidden) // IN: new value for the invisible flag { Bool changed = FALSE; /* * Finder keeps, reports and expects to set flags in big endian format. * Needs to convert to host endian before using constants * and then convert back to big endian before saving */ uint16 finderFlags = CFSwapInt16BigToHost(*flags); Bool isHidden = (finderFlags & kIsInvisible) != 0; if (setHidden) { if (!isHidden) { finderFlags |= kIsInvisible; changed = TRUE; } } else if (isHidden) { finderFlags &= ~kIsInvisible; changed = TRUE; } if (changed) { *flags = CFSwapInt16HostToBig(finderFlags); } return changed; } /* *----------------------------------------------------------------------------- * * HgfsSetHiddenXAttr -- * * Sets new value for the invisible attribute of a file. * * Results: * 0 if succeeded, error code otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsInternalStatus HgfsSetHiddenXAttr(char const *fileName, // IN: path to the file Bool setHidden, // IN: new value to the invisible attribute mode_t permissions) // IN: permissions of the file { HgfsInternalStatus err; Bool changed = FALSE; struct attrlist attrList; struct FInfoAttrBuf attrBuf; ASSERT(fileName); memset(&attrList, 0, sizeof attrList); attrList.bitmapcount = ATTR_BIT_MAP_COUNT; attrList.commonattr = ATTR_CMN_OBJTYPE | ATTR_CMN_FNDRINFO; err = getattrlist(fileName, &attrList, &attrBuf, sizeof attrBuf, 0); if (err == 0) { switch (attrBuf.objType) { case VREG: { FileInfo *info = (FileInfo*) attrBuf.finderInfo; changed = ChangeInvisibleFlag(&info->finderFlags, setHidden); break; } case VDIR: { FolderInfo *info = (FolderInfo*) attrBuf.finderInfo; changed = ChangeInvisibleFlag(&info->finderFlags, setHidden); break; } default: LOG(4, ("%s: Unrecognized object type %d\n", __FUNCTION__, attrBuf.objType)); err = EINVAL; } } else { err = errno; } if (changed) { attrList.commonattr = ATTR_CMN_FNDRINFO; err = setattrlist(fileName, &attrList, attrBuf.finderInfo, sizeof attrBuf.finderInfo, 0); if (0 != err) { err = errno; } if (EACCES == err) { mode_t mode = permissions | S_IWOTH | S_IWGRP | S_IWUSR; if (chmod(fileName, mode) == 0) { err = setattrlist(fileName, &attrList, attrBuf.finderInfo, sizeof attrBuf.finderInfo, 0); if (0 != err) { err = errno; } chmod(fileName, permissions); } else { err = errno; } } } return err; } #else // __APPLE__ /* *----------------------------------------------------------------------------- * * HgfsGetHiddenXAttr -- * * Always returns 0 since there is no support for invisible files in Linux * HGFS server. * * Results: * 0 always. This is required to allow apps that use the hidden feature to * continue to work. attribute value is set to FALSE always. * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsInternalStatus HgfsGetHiddenXAttr(char const *fileName, // IN: File name Bool *attribute) // OUT: Value of the hidden attribute { *attribute = FALSE; return 0; } /* *----------------------------------------------------------------------------- * * HgfsSetHiddenXAttr -- * * Sets new value for the invisible attribute of a file. * Currently Linux server does not support invisible or hiddden files. * So this is a nop. * * Results: * 0 always. This is required to allow apps that use the hidden feature to * continue to work. * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsInternalStatus HgfsSetHiddenXAttr(char const *fileName, // IN: File name Bool value, // IN: Value of the attribute to set mode_t permissions) // IN: permissions of the file { return 0; } #endif // __APPLE__ open-vm-tools-9.4.0-1280544/lib/hgfsServer/hgfsDirNotifyStub.c0000644765153500003110000001353512220061556022113 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * hgfsDirNotifyStub.c -- * * Stubs for directory notification support, used to build guest components. */ #include #include #include "vmware.h" #include "vm_basic_types.h" #include "hgfsProto.h" #include "hgfsServer.h" #include "hgfsUtil.h" #include "hgfsDirNotify.h" /* *----------------------------------------------------------------------------- * * HgfsNotify_Init -- * * Initialization for the notification component. * * Results: * Invalid value error. * * Side effects: * None. * *----------------------------------------------------------------------------- */ HgfsInternalStatus HgfsNotify_Init(void) { return EINVAL; } /* *----------------------------------------------------------------------------- * * HgfsNotify_Exit -- * * Exit for the notification component. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void HgfsNotify_Exit(void) { } /* *----------------------------------------------------------------------------- * * HgfsNotify_Deactivate -- * * Deactivates generating file system change notifications. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void HgfsNotify_Deactivate(HgfsNotifyActivateReason reason) // IN: reason unused { } /* *----------------------------------------------------------------------------- * * HgfsNotify_Activate -- * * Activates generating file system change notifications. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void HgfsNotify_Activate(HgfsNotifyActivateReason reason) // IN: reason unused { } /* *----------------------------------------------------------------------------- * * HgfsNotify_AddSharedFolder -- * * Allocates memory and initializes new shared folder structure. * * Results: * Opaque subscriber handle for the new subscriber or HGFS_INVALID_FOLDER_HANDLE * if adding shared folder fails. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsSharedFolderHandle HgfsNotify_AddSharedFolder(const char *path, // IN: path in the host const char *shareName) // IN: name of the shared folder { return HGFS_INVALID_FOLDER_HANDLE; } /* *----------------------------------------------------------------------------- * * HgfsNotify_AddSubscriber -- * * Allocates memory and initializes new subscriber structure. * Inserts allocated subscriber into corrspondent array. * * Results: * Opaque subscriber handle for the new subscriber or HGFS_INVALID_SUBSCRIBER_HANDLE * if adding subscriber fails. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsSubscriberHandle HgfsNotify_AddSubscriber(HgfsSharedFolderHandle sharedFolder, // IN: shared folder handle const char *path, // IN: relative path uint32 eventFilter, // IN: event filter uint32 recursive, // IN: look in subfolders HgfsNotifyEventReceiveCb eventCb, // IN notification callback struct HgfsSessionInfo *session) // IN: server context { return HGFS_INVALID_SUBSCRIBER_HANDLE; } /* *----------------------------------------------------------------------------- * * HgfsNotify_RemoveSharedFolder -- * * Deallcates memory used by shared folder and performs necessary cleanup. * Also deletes all subscribers that are defined for the shared folder. * * Results: * FALSE. * * Side effects: * Removes all subscribers that correspond to the shared folder and invalidates * thier handles. * *----------------------------------------------------------------------------- */ Bool HgfsNotify_RemoveSharedFolder(HgfsSharedFolderHandle sharedFolder) // IN { return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsNotify_RemoveSubscriber -- * * Deallcates memory used by NotificationSubscriber and performs necessary cleanup. * * Results: * FALSE. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsNotify_RemoveSubscriber(HgfsSubscriberHandle subscriber) // IN { return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsNotify_RemoveSessionSubscribers -- * * Removes all entries that are related to a particular session. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void HgfsNotify_RemoveSessionSubscribers(struct HgfsSessionInfo *session) // IN { } open-vm-tools-9.4.0-1280544/lib/hgfsServer/hgfsServerInt.h0000644765153500003110000016623212220061556021277 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef __HGFS_SERVER_INT_H__ # define __HGFS_SERVER_INT_H__ #include "vm_basic_types.h" /* * Definitions of wrapped internal primitives. * * We wrap open file handles and directory entries so that cross-platform HGFS * server code can use them without platform-specific pre-processing. * * On Linux, we use dirent64 from the kernel headers so as to alleviate any * confusion between what the kernel will give us from the getdents64() * syscall and what userspace will expect. Note that to avoid depending on * kernel headers directly, I've copied the dirent struct, replacing certain * kernel basic types with our own. * * On Windows, we define our own DirectoryEntry struct with d_reclen and * d_name, as those are the only two fields we're interested in. It's not * essential that it match the dirents from another platform, because we * control how they get created and populated, and they never pass down a wire. * * Otherwise, we use the native dirent struct provided by the platform's libc, * as nobody else seems to suffer from the 32-bit vs. 64-bit ino_t and off_t * insanity that plagues Linux. */ #ifndef _WIN32 # ifdef linux typedef struct DirectoryEntry { uint64 d_ino; uint64 d_off; uint16 d_reclen; uint8 d_type; char d_name[256]; } DirectoryEntry; # else # include typedef struct dirent DirectoryEntry; # endif typedef int fileDesc; #else # include typedef HANDLE fileDesc; typedef struct DirectoryEntry { unsigned short d_reclen; /* The total length of this record. */ char d_name[PATH_MAX * 4]; /* 4 bytes is the maximum size of a utf8 */ /* representation of utf-16 encoded */ /* unicode character in the BMP */ } DirectoryEntry; #endif #include "dbllnklst.h" #include "hgfsProto.h" #include "cpName.h" // for HgfsNameStatus #include "hgfsServerPolicy.h" #include "hgfsUtil.h" // for HgfsInternalStatus #include "vm_atomic.h" #include "userlock.h" #define HGFS_DEBUG_ASYNC (0) /* * Does this platform have oplock support? We define it here to avoid long * ifdefs all over the code. For now, Linux and Windows hosts only. * * XXX: Just kidding, no oplock support yet. */ #if 0 #define HGFS_OPLOCKS #endif /* Value of config option to require using host timestamps */ extern Bool alwaysUseHostTime; /* Identifier for a local file */ typedef struct HgfsLocalId { uint64 volumeId; uint64 fileId; } HgfsLocalId; typedef enum { REQ_ASYNC, /* Hint that request should be processed Async. */ REQ_SYNC, /* " Sync. */ } RequestHint; /* Three possible filenode states */ typedef enum { FILENODE_STATE_UNUSED, /* Linked on the free list */ FILENODE_STATE_IN_USE_CACHED, /* Linked on the cached nodes list */ FILENODE_STATE_IN_USE_NOT_CACHED, /* Not linked on any list */ } FileNodeState; /* Three possible search types */ typedef enum { DIRECTORY_SEARCH_TYPE_DIR, /* Objects are files and subdirectories */ DIRECTORY_SEARCH_TYPE_BASE, /* Objects are shares */ DIRECTORY_SEARCH_TYPE_OTHER, /* Objects are the contents of "root/drive" or contents of "root" */ } DirectorySearchType; /* Two possible volume info type */ typedef enum { VOLUME_INFO_TYPE_MIN, VOLUME_INFO_TYPE_MAX, } VolumeInfoType; /* * The "default" share access is used in cross-platform code, so it's helpful * to have a single macro for accessing it. */ #ifdef _WIN32 # define HGFS_DEFAULT_SHARE_ACCESS (FILE_SHARE_READ | FILE_SHARE_WRITE | \ FILE_SHARE_DELETE) #else # define HGFS_DEFAULT_SHARE_ACCESS 0 #endif // _WIN32 typedef struct HgfsShareInfo { /* Filename of the root directory for the shared folder */ const char *rootDir; /* Length of the root directory filename (does not include nul terminator) */ size_t rootDirLen; /* Read permissions for the shared folder, needed for handle => name conversions. */ Bool readPermissions; /* Write permissions for the shared folder, needed for handle => name conversions. */ Bool writePermissions; /* * Shared folder handle used by change directory notification code to identify * shared folder. */ HgfsSharedFolderHandle handle; } HgfsShareInfo; /* * This struct represents a file on the local filesystem that has been * opened by a remote client. We store the name of the local file and * enough state to keep track of whether the file has changed locally * between remote accesses. None of the fields contain cross-platform * types; everything has been converted for the local filesystem. * * A file node object can only be in 1 of these 3 states: * 1) FILENODE_STATE_UNUSED: linked on the free list * 2) FILENODE_STATE_IN_USE_CACHED: Linked on the cached nodes list * 3) FILENODE_STATE_IN_USE_NOT_CACHED: Linked on neither of the above two lists. */ typedef struct HgfsFileNode { /* Links to place the object on various lists */ DblLnkLst_Links links; /* HGFS handle uniquely identifying this node. */ HgfsHandle handle; /* Local filename (in UTF8) */ char *utf8Name; /* Length of filename (does not include nul terminator) */ size_t utf8NameLen; /* share name */ char *shareName; /* Length of share name (does not include nul terminator) */ size_t shareNameLen; /* ID of file in local filesystem */ HgfsLocalId localId; /* File descriptor */ fileDesc fileDesc; /* On POSIX, access mode. On Windows, desired access */ uint32 mode; /* Share access to open with (Windows only) */ uint32 shareAccess; /* The server lock that the node currently has. */ HgfsServerLock serverLock; /* File node state on lists */ FileNodeState state; /* File flags - see below. */ uint32 flags; /* * Context as required by some file operations. Eg: BackupWrite on * Windows: BackupWrite requires the caller to hold on to a pointer * to a Windows internal data structure between subsequent calls to * BackupWrite while restoring a file. */ void *fileCtx; /* Parameters associated with the share. */ HgfsShareInfo shareInfo; } HgfsFileNode; /* HgfsFileNode flags. */ /* TRUE if opened in append mode */ #define HGFS_FILE_NODE_APPEND_FL (1 << 0) /* Whether this file was opened in sequential mode. */ #define HGFS_FILE_NODE_SEQUENTIAL_FL (1 << 1) /* Whether this a shared folder open. */ #define HGFS_FILE_NODE_SHARED_FOLDER_OPEN_FL (1 << 2) /* * This struct represents a file search that a client initiated. * * A search object can only be in 1 of these 2 states: * 1) Unused: linked on the free list * 2) In use: unlinked */ typedef struct HgfsSearch { /* Links to place the object on various lists */ DblLnkLst_Links links; /* HGFS handle uniquely identifying this search. */ HgfsHandle handle; /* Local directory name (in UTF8) */ char *utf8Dir; /* Length of directory name (does not include nul terminator) */ size_t utf8DirLen; /* Share name. */ char *utf8ShareName; /* Share name length. */ size_t utf8ShareNameLen; /* Directory entries for this search */ DirectoryEntry **dents; /* Number of dents */ uint32 numDents; /* * What type of search is this (what objects does it track)? This is * important to know so we can do the right kind of stat operation later * when we want to retrieve the attributes for each dent. */ DirectorySearchType type; /* Parameters associated with the share. */ HgfsShareInfo shareInfo; } HgfsSearch; /* HgfsSessionInfo flags. */ typedef enum { HGFS_SESSION_TYPE_REGULAR, /* Dynamic session, created by the HgfsTransport. */ HGFS_SESSION_TYPE_INTERNAL, /* This is a static session. */ } HgfsSessionInfoType; /* HgfsSessionState, used for session status. */ typedef enum { HGFS_SESSION_STATE_OPEN, HGFS_SESSION_STATE_CLOSED, } HgfsSessionInfoState; typedef struct HgfsTransportSessionInfo { /* Default session id. */ uint64 defaultSessionId; /* Lock to manipulate the list of sessions */ MXUserExclLock *sessionArrayLock; /* List of sessions */ DblLnkLst_Links sessionArray; /* Max packet size that is supported by both client and server. */ uint32 maxPacketSize; /* Total number of sessions present this transport session*/ uint32 numSessions; /* Transport session context. */ void *transportData; /* Current state of the session. */ HgfsSessionInfoState state; /* Session is dynamic or internal. */ HgfsSessionInfoType type; /* Function callbacks into Hgfs Channels. */ HgfsServerChannelCallbacks *channelCbTable; Atomic_uint32 refCount; /* Reference count for session. */ uint32 channelCapabilities; } HgfsTransportSessionInfo; typedef struct HgfsSessionInfo { DblLnkLst_Links links; Bool isInactive; /* Unique session id. */ uint64 sessionId; /* Max packet size that is supported by both client and server. */ uint32 maxPacketSize; /* Transport session context. */ HgfsTransportSessionInfo *transportSession; /* Current state of the session. */ HgfsSessionInfoState state; /* Lock to ensure some fileIO requests are atomic for a handle. */ MXUserExclLock *fileIOLock; int numInvalidationAttempts; Atomic_uint32 refCount; /* Reference count for session. */ /* ** START NODE ARRAY ************************************************** * * Lock for the following 6 fields: the node array, * counters and lists for this session. */ MXUserExclLock *nodeArrayLock; /* Open file nodes of this session. */ HgfsFileNode *nodeArray; /* Number of nodes in the nodeArray. */ uint32 numNodes; /* Free list of file nodes. LIFO to be cache-friendly. */ DblLnkLst_Links nodeFreeList; /* List of cached open nodes. */ DblLnkLst_Links nodeCachedList; /* Current number of open nodes. */ unsigned int numCachedOpenNodes; /* Number of open nodes having server locks. */ unsigned int numCachedLockedNodes; /** END NODE ARRAY ****************************************************/ /* ** START SEARCH ARRAY ************************************************ * * Lock for the following three fields: for the search array * and it's counter and list, for this session. */ MXUserExclLock *searchArrayLock; /* Directory entry cache for this session. */ HgfsSearch *searchArray; /* Number of entries in searchArray. */ uint32 numSearches; /* Free list of searches. LIFO. */ DblLnkLst_Links searchFreeList; /** END SEARCH ARRAY ****************************************************/ /* Array of session specific capabiities. */ HgfsCapability hgfsSessionCapabilities[HGFS_OP_MAX]; uint32 numberOfCapabilities; Bool activeNotification; } HgfsSessionInfo; /* * This represents the maximum number of HGFS sessions that can be * created in a HGFS transport session. We picked a random value * for this variable. There is no specific reason behind picking * this value. */ #define MAX_SESSION_COUNT 1024 /* * This represents the maximum number attempts made by the HGFS * invalidator before completely destroying the HGFS session. We * picked a random value and there is no specific reason behind * the value 4 for thie variable. */ #define MAX_SESSION_INVALIDATION_ATTEMPTS 4 /* * These structs represent information about file open requests, file * attributes, and directory creation requests. * * The main reason for these structs is data abstraction -- we pass * a struct around instead of the individual parameters. This way * as more parameters are implemented, we don't have to add more * parameters to the functions, instead just extend the structs. */ typedef struct HgfsFileOpenInfo { HgfsOp requestType; HgfsHandle file; /* Opaque file ID used by the server */ HgfsOpenValid mask; /* Bitmask that specified which fields are valid. */ HgfsOpenMode mode; /* Which type of access requested. See desiredAccess */ HgfsOpenFlags flags; /* Which flags to open the file with */ HgfsPermissions specialPerms; /* Desired 'special' permissions for file creation */ HgfsPermissions ownerPerms; /* Desired 'owner' permissions for file creation */ HgfsPermissions groupPerms; /* Desired 'group' permissions for file creation */ HgfsPermissions otherPerms; /* Desired 'other' permissions for file creation */ HgfsAttrFlags attr; /* Attributes, if any, for file creation */ uint64 allocationSize; /* How much space to pre-allocate during creation */ uint32 desiredAccess; /* Extended support for windows access modes */ uint32 shareAccess; /* Windows only, share access modes */ HgfsServerLock desiredLock; /* The type of lock desired by the client */ HgfsServerLock acquiredLock; /* The type of lock acquired by the server */ uint32 cpNameSize; char *cpName; char *utf8Name; uint32 caseFlags; /* Case-sensitivity flags. */ HgfsShareInfo shareInfo; /* Parameters associated with the share. */ } HgfsFileOpenInfo; typedef struct HgfsFileAttrInfo { HgfsOp requestType; HgfsAttrValid mask; HgfsFileType type; /* File type */ uint64 size; /* File size (in bytes) */ uint64 creationTime; /* Creation time. Ignored by POSIX */ uint64 accessTime; /* Time of last access */ uint64 writeTime; /* Time of last write */ uint64 attrChangeTime; /* Time file attributes were last * changed. Ignored by Windows */ HgfsPermissions specialPerms; /* Special permissions bits. Ignored by Windows */ HgfsPermissions ownerPerms; /* Owner permissions bits */ HgfsPermissions groupPerms; /* Group permissions bits. Ignored by Windows */ HgfsPermissions otherPerms; /* Other permissions bits. Ignored by Windows */ HgfsAttrFlags flags; /* Various flags and Windows 'attributes' */ uint64 allocationSize; /* Actual size of file on disk */ uint32 userId; /* User identifier, ignored by Windows */ uint32 groupId; /* group identifier, ignored by Windows */ uint64 hostFileId; /* File Id of the file on host: inode_t on Linux */ uint32 volumeId; /* Volume Id of the volune on which the file resides */ uint32 effectivePerms; /* Permissions in effect for the current user */ uint32 eaSize; /* Extended attribute data size */ uint32 reparseTag; /* Windows reparse point tag, valid by attr flag */ HgfsShortFileName shortName; /* Windows DOS 8 dot 3 name for long names */ } HgfsFileAttrInfo; typedef struct HgfsSearchReadEntry { HgfsSearchReadMask mask; /* Info returned mask */ HgfsFileAttrInfo attr; /* Attributes of entry */ uint32 fileIndex; /* Entry directory index */ char *name; /* Name */ uint32 nameLength; /* Name byte length */ } HgfsSearchReadEntry; typedef struct HgfsSearchReadInfo { HgfsOp requestType; /* HGFS request version */ HgfsSearchReadMask requestedMask; /* Entry info requested mask */ HgfsSearchReadFlags flags; /* Request specific flags */ HgfsSearchReadFlags replyFlags; /* Reply specific flags */ char *searchPattern; /* Search pattern to match entries with */ uint32 searchPatternLength; /* Byte length of search pattern */ uint32 startIndex; /* Starting index for entries */ uint32 currentIndex; /* Current index for entries */ uint32 numberRecordsWritten; /* Number of entries written */ void *reply; /* Fixed part of search read reply */ void *replyPayload; /* Variable part (dirent records) of reply */ size_t payloadSize; /* Remaining bytes in reply payload. */ } HgfsSearchReadInfo; typedef struct HgfsCreateDirInfo { HgfsOp requestType; HgfsCreateDirValid mask; HgfsPermissions specialPerms; /* Special permissions bits. Ignored by Windows */ HgfsPermissions ownerPerms; /* Owner permissions bits */ HgfsPermissions groupPerms; /* Group permissions bits. Ignored by Windows */ HgfsPermissions otherPerms; /* Other permissions bits. Ignored by Windows */ uint32 cpNameSize; char *cpName; uint32 caseFlags; /* Case-sensitivity flags. */ HgfsAttrFlags fileAttr; /* Various flags and Windows 'attributes' */ } HgfsCreateDirInfo; typedef struct HgfsCreateSessionInfo { uint32 maxPacketSize; } HgfsCreateSessionInfo; /* Server lock related structure */ typedef struct { fileDesc fileDesc; int32 event; HgfsServerLock serverLock; } ServerLockData; typedef struct HgfsInputParam { const char *metaPacket; size_t metaPacketSize; HgfsSessionInfo *session; HgfsTransportSessionInfo *transportSession; HgfsPacket *packet; void const *payload; uint32 payloadOffset; size_t payloadSize; HgfsOp op; uint32 id; Bool v4header; } HgfsInputParam; Bool HgfsCreateAndCacheFileNode(HgfsFileOpenInfo *openInfo, // IN: Open info struct HgfsLocalId const *localId, // IN: Local unique file ID fileDesc fileDesc, // IN: OS file handle Bool append, // IN: Open with append flag HgfsSessionInfo *session); // IN: Session info Bool HgfsSearchHandle2FileName(HgfsHandle handle, // IN: Hgfs search handle char **fileName, // OUT: cp file name uint32 *fileNameSize); // OUT: cp file name size void HgfsUpdateNodeNames(const char *oldLocalName, // IN: Name of file to look for const char *newLocalName, // IN: Name to replace with HgfsSessionInfo *session); // IN: Session info Bool HgfsRemoveSearch(HgfsHandle searchHandle, HgfsSessionInfo *session); void HgfsServerDumpDents(HgfsHandle searchHandle, // IN: Handle to dump dents from HgfsSessionInfo *session); // IN: Session info DirectoryEntry * HgfsGetSearchResult(HgfsHandle handle, // IN: Handle to search HgfsSessionInfo *session, // IN: Session info uint32 offset, // IN: Offset to retrieve at Bool remove); // IN: If true, removes the result Bool HgfsServerStatFs(const char *pathName, // IN: Path we're interested in size_t pathLength, // IN: Length of path uint64 *freeBytes, // OUT: Free bytes on volume uint64 *totalBytes); // OUT: Total bytes on volume HgfsNameStatus HgfsServerGetAccess(char *in, // IN: CP filename to check size_t inSize, // IN: Size of name in HgfsOpenMode mode, // IN: Requested access mode uint32 caseFlags, // IN: Case-sensitivity flags char **bufOut, // OUT: File name in local fs size_t *outLen); // OUT: Length of name out HgfsNameStatus HgfsServerGetShareInfo(char *cpName, // IN: Cross-platform filename to check size_t cpNameSize, // IN: Size of name cpName uint32 caseFlags, // IN: Case-sensitivity flags HgfsShareInfo* shareInfo,// OUT: Shared folder properties char **bufOut, // OUT: File name in local fs size_t *outLen); // OUT: Length of name out Bool HgfsServerIsSharedFolderOnly(char const *in, // IN: CP filename to check size_t inSize); // IN: Size of name in HgfsInternalStatus HgfsServerScandir(char const *baseDir, // IN: Directory to search in size_t baseDirLen, // IN: Length of directory Bool followSymlinks, // IN: followSymlinks config option DirectoryEntry ***dents, // OUT: Array of DirectoryEntrys int *numDents); // OUT: Number of DirectoryEntrys HgfsInternalStatus HgfsServerSearchRealDir(char const *baseDir, // IN: Directory to search size_t baseDirLen, // IN: Length of directory char const *shareName, // IN: Share name char const *rootDir, // IN: Root directory for the share HgfsSessionInfo *session, // IN: Session info HgfsHandle *handle); // OUT: Search handle HgfsInternalStatus HgfsServerSearchVirtualDir(HgfsGetNameFunc *getName, // IN: Name enumerator HgfsInitFunc *initName, // IN: Init function HgfsCleanupFunc *cleanupName, // IN: Cleanup function DirectorySearchType type, // IN: Kind of search HgfsSessionInfo *session, // IN: Session info HgfsHandle *handle); // OUT: Search handle /* Allocate/Add sessions helper functions. */ Bool HgfsServerAllocateSession(HgfsTransportSessionInfo *transportSession, uint32 channelCapabilities, HgfsSessionInfo **sessionData); void HgfsServerSessionGet(HgfsSessionInfo *session); HgfsInternalStatus HgfsServerTransportAddSessionToList(HgfsTransportSessionInfo *transportSession, HgfsSessionInfo *sessionInfo); /* Unpack/pack requests/reply helper functions. */ Bool HgfsParseRequest(HgfsPacket *packet, // IN: request packet HgfsTransportSessionInfo *transportSession, // IN: current session HgfsInputParam **input, // OUT: request parameters HgfsInternalStatus *status); // OUT: error code void HgfsPackLegacyReplyHeader(HgfsInternalStatus status, // IN: reply status HgfsHandle id, // IN: original packet id HgfsReply *header); // OUT: outgoing packet header Bool HgfsAllocInitReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: incoming packet header size_t payloadSize, // IN: payload size void **payload, // OUT: size of the allocated packet HgfsSessionInfo *session); // IN: Session Info Bool HgfsUnpackOpenRequest(void const *packet, // IN: incoming packet size_t packetSize, // IN: size of packet HgfsOp op, // IN: request type HgfsFileOpenInfo *openInfo); // IN/OUT: open info struct Bool HgfsPackOpenReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsFileOpenInfo *openInfo, // IN: open info struct size_t *payloadSize, // OUT: outgoing packet size HgfsSessionInfo *session); // IN: Session Info Bool HgfsUnpackGetattrRequest(void const *packetHeader, // IN: packet header size_t packetSize, // IN: request packet size HgfsOp op, // IN: request type HgfsFileAttrInfo *attrInfo, // IN/OUT: unpacked attr struct HgfsAttrHint *hints, // OUT: getattr hints char **cpName, // OUT: cpName size_t *cpNameSize, // OUT: cpName size HgfsHandle *file, // OUT: file handle uint32 *caseFlags); // OUT: case-sensitivity flags Bool HgfsUnpackDeleteRequest(void const *packet, // IN: request packet size_t packetSize, // IN: request packet size HgfsOp op, // IN: requested operation char **cpName, // OUT: cpName size_t *cpNameSize, // OUT: cpName size HgfsDeleteHint *hints, // OUT: delete hints HgfsHandle *file, // OUT: file handle uint32 *caseFlags); // OUT: case-sensitivity flags Bool HgfsPackDeleteReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: requested operation size_t *payloadSize, // OUT: size of HGFS packet HgfsSessionInfo *session); // IN: Session Info Bool HgfsUnpackRenameRequest(void const *packet, // IN: request packet size_t packetSize, // IN: request packet size HgfsOp op, // IN: requested operation char **cpOldName, // OUT: rename src size_t *cpOldNameLen, // OUT: rename src size char **cpNewName, // OUT: rename dst size_t *cpNewNameLen, // OUT: rename dst size HgfsRenameHint *hints, // OUT: rename hints HgfsHandle *srcFile, // OUT: src file handle HgfsHandle *targetFile, // OUT: target file handle uint32 *oldCaseFlags, // OUT: old case-sensitivity flags uint32 *newCaseFlags); // OUT: new case-sensitivity flags Bool HgfsPackRenameReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: requested operation size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session); // IN: Session Info Bool HgfsPackGetattrReply(HgfsPacket *packet, // IN/OUT: Hgfs packet char const *packetHeader, // IN: packet header HgfsFileAttrInfo *attr, // IN: attr stucture const char *utf8TargetName, // IN: optional target name uint32 utf8TargetNameLen, // IN: file name length size_t *payloadSize, // OUT: size of HGFS packet HgfsSessionInfo *session); // IN: Session Info Bool HgfsPackSymlinkCreateReply(HgfsPacket *packet, // IN/OUT: Hgfs packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: request type size_t *payloadSize, // OUT: size of HGFS packet HgfsSessionInfo *session); // IN: Session Info Bool HgfsUnpackSearchReadRequest(const void *packet, // IN: request packet size_t packetSize, // IN: packet size HgfsOp op, // IN: requested operation HgfsSearchReadInfo *info, // OUT: search info size_t *baseReplySize, // OUT: op base reply size size_t *inlineReplyDataSize, // OUT: size of inline reply data HgfsHandle *hgfsSearchHandle);// OUT: hgfs search handle Bool HgfsPackSearchReadReplyRecord(HgfsOp requestType, // IN: search read request HgfsSearchReadEntry *entry, // IN: entry info size_t maxRecordSize, // IN: max size in bytes for record void *lastSearchReadRecord, // IN/OUT: last packed entry void *currentSearchReadRecord,// OUT: currrent entry to pack size_t *replyRecordSize); // OUT: size of packet Bool HgfsPackSearchReadReplyHeader(HgfsSearchReadInfo *info, // IN: request info size_t *payloadSize); // OUT: size of packet Bool HgfsUnpackSetattrRequest(void const *packet, // IN: request packet size_t packetSize, // IN: request packet size HgfsOp op, // IN: requested operation HgfsFileAttrInfo *attr, // IN/OUT: getattr info HgfsAttrHint *hints, // OUT: setattr hints char **cpName, // OUT: cpName size_t *cpNameSize, // OUT: cpName size HgfsHandle *file, // OUT: server file ID uint32 *caseFlags); // OUT: case-sensitivity flags Bool HgfsPackSetattrReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: request type size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session); // IN: Session Info Bool HgfsUnpackCreateDirRequest(void const *packet, // IN: HGFS packet size_t packetSize, // IN: size of packet HgfsOp op, // IN: requested operation HgfsCreateDirInfo *info); // IN/OUT: info struct Bool HgfsPackCreateDirReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: request type size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session); // IN: Session Info Bool HgfsPackQueryVolumeReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: request type uint64 freeBytes, // IN: volume free space uint64 totalBytes, // IN: volume capacity size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session); // IN: Session Info Bool HgfsUnpackQueryVolumeRequest(void const *packet, // IN: HGFS packet size_t packetSize, // IN: request packet size HgfsOp op, // IN: request type Bool *useHandle, // OUT: use handle char **fileName, // OUT: file name size_t *fileNameLength, // OUT: file name length uint32 *caseFlags, // OUT: case sensitivity HgfsHandle *file); // OUT: Handle to the volume Bool HgfsUnpackSymlinkCreateRequest(void const *packet, // IN: request packet size_t packetSize, // IN: request packet size HgfsOp op, // IN: request type Bool *srcUseHandle, // OUT: use source handle char **srcFileName, // OUT: source file name size_t *srcFileNameLength, // OUT: source file name length uint32 *srcCaseFlags, // OUT: source case sensitivity HgfsHandle *srcFile, // OUT: source file handle Bool *tgUseHandle, // OUT: use target handle char **tgFileName, // OUT: target file name size_t *tgFileNameLength, // OUT: target file name length uint32 *tgCaseFlags, // OUT: target case sensitivity HgfsHandle *tgFile); // OUT: target file handle Bool HgfsUnpackWriteWin32StreamRequest(void const *packet, // IN: HGFS packet size_t packetSize, // IN: size of packet HgfsOp op, // IN: request type HgfsHandle *file, // OUT: file to write to char **payload, // OUT: data to write size_t *requiredSize, // OUT: size of data Bool *doSecurity); // OUT: restore sec.str. Bool HgfsUnpackCreateSessionRequest(void const *packetHeader, // IN: request packet size_t packetSize, // IN: size of packet HgfsOp op, // IN: request type HgfsCreateSessionInfo *info); // IN/OUT: info struct Bool HgfsPackWriteWin32StreamReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet headert HgfsOp op, // IN: request type uint32 actualSize, // IN: amount written size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session); // IN:Session Info Bool HgfsUnpackCloseRequest(void const *packet, // IN: request packet size_t packetSize, // IN: request packet size HgfsOp op, // IN: request type HgfsHandle *file); // OUT: Handle to close Bool HgfsUnpackSearchOpenRequest(void const *packet, // IN: HGFS packet size_t packetSize, // IN: request packet size HgfsOp op, // IN: request type char **dirName, // OUT: directory name uint32 *dirNameLength, // OUT: name length uint32 *caseFlags); // OUT: case flags Bool HgfsPackCloseReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: request type size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session); // IN: Session Info Bool HgfsUnpackSearchCloseRequest(void const *packet, // IN: request packet size_t packetSize, // IN: request packet size HgfsOp op, // IN: request type HgfsHandle *file); // OUT: Handle to close Bool HgfsPackSearchOpenReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: request type HgfsHandle search, // IN: search handle size_t *packetSize, // OUT: size of packet HgfsSessionInfo *session); // IN: Session Info Bool HgfsPackSearchCloseReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: request type size_t *packetSize, // OUT: size of packet HgfsSessionInfo *session); // IN: Session Info Bool HgfsPackWriteReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: request type uint32 actualSize, // IN: number of bytes that were written size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session); // IN: Session info Bool HgfsUnpackReadRequest(void const *packet, // IN: HGFS request size_t packetSize, // IN: request packet size HgfsOp op, // IN: request type HgfsHandle *file, // OUT: Handle to close uint64 *offset, // OUT: offset to read from uint32 *length); // OUT: length of data to read Bool HgfsUnpackWriteRequest(HgfsInputParam *input, // IN: Input params HgfsHandle *file, // OUT: Handle to write to uint64 *offset, // OUT: offset to write to uint32 *length, // OUT: length of data to write HgfsWriteFlags *flags, // OUT: write flags char **data); // OUT: data to be written Bool HgfsPackCreateSessionReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session); // IN: Session Info Bool HgfsPackDestroySessionReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session); // IN: Session Info void HgfsServerGetDefaultCapabilities(HgfsCapability *capabilities, // OUT: uint32 *numberOfCapabilities); // OUT: Bool HgfsUnpackSetWatchRequest(void const *packet, // IN: HGFS packet size_t packetSize, // IN: request packet size HgfsOp op, // IN: requested operation Bool *useHandle, // OUT: handle or cpName char **cpName, // OUT: cpName size_t *cpNameSize, // OUT: cpName size uint32 *flags, // OUT: flags for the new watch uint32 *events, // OUT: event filter HgfsHandle *dir, // OUT: direrctory handle uint32 *caseFlags); // OUT: case-sensitivity flags Bool HgfsPackSetWatchReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: operation code HgfsSubscriberHandle watchId, // IN: new watch id size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session); // IN: Session info Bool HgfsUnpackRemoveWatchRequest(void const *packet, // IN: HGFS packet size_t packetSize, // IN: packet size HgfsOp op, // IN: operation code HgfsSubscriberHandle *watchId); // OUT: watch Id Bool HgfsPackRemoveWatchReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: operation code size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session); // IN: Session info size_t HgfsPackCalculateNotificationSize(char const *shareName, // IN: shared folder name char *fileName); // IN: file name Bool HgfsPackChangeNotificationRequest(void *packet, // IN/OUT: Hgfs Packet HgfsSubscriberHandle subscriber, // IN: watch char const *shareName, // IN: share name char *fileName, // IN: file name uint32 mask, // IN: event mask uint32 flags, // IN: notify flags HgfsSessionInfo *session, // IN: session size_t *bufferSize); // IN/OUT: packet size /* Node cache functions. */ Bool HgfsRemoveFromCache(HgfsHandle handle, // IN: Hgfs handle of the node HgfsSessionInfo *session); // IN: Session info Bool HgfsAddToCache(HgfsHandle handle, // IN: Hgfs handle of the node HgfsSessionInfo *session); // IN: Session info Bool HgfsIsCached(HgfsHandle handle, // IN: Hgfs handle of the node HgfsSessionInfo *session); // IN: Session info Bool HgfsIsServerLockAllowed(HgfsSessionInfo *session); // IN: session info Bool HgfsHandle2FileDesc(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: session info fileDesc *fd, // OUT: OS handle (file descriptor) void **fileCtx); // OUT: OS file context Bool HgfsFileDesc2Handle(fileDesc fd, // IN: OS handle (file descriptor) HgfsSessionInfo *session, // IN: session info HgfsHandle *handle); // OUT: Hgfs file handle Bool HgfsHandle2ShareMode(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: session info HgfsOpenMode *shareMode); // OUT: UTF8 file name size Bool HgfsHandle2FileName(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: session info char **fileName, // OUT: CP file name size_t *fileNameSize); // OUT: CP file name size Bool HgfsHandle2FileNameMode(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session,// IN: Session info Bool *readPermissions, // OUT: shared folder permissions Bool *writePermissions, // OUT: shared folder permissions char **fileName, // OUT: UTF8 file name size_t *fileNameSize); // OUT: UTF8 file name size Bool HgfsHandle2AppendFlag(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: session info Bool *appendFlag); // OUT: Append flag Bool HgfsHandle2LocalId(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: session info HgfsLocalId *localId); // OUT: Local id info Bool HgfsHandle2ServerLock(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: session info HgfsServerLock *lock); // OUT: Server lock Bool HgfsUpdateNodeFileDesc(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: session info fileDesc fd, // IN: OS handle (file desc void *fileCtx); // IN: OS file context Bool HgfsUpdateNodeServerLock(fileDesc fd, // IN: OS handle HgfsSessionInfo *session, // IN: session info HgfsServerLock serverLock); // IN: new oplock Bool HgfsUpdateNodeAppendFlag(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: session info Bool appendFlag); // OUT: Append flag Bool HgfsFileHasServerLock(const char *utf8Name, // IN: Name in UTF8 HgfsSessionInfo *session, // IN: Session info HgfsServerLock *serverLock, // OUT: Existing oplock fileDesc *fileDesc); // OUT: Existing fd Bool HgfsGetNodeCopy(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: session info Bool copyName, // IN: Should we copy the name? HgfsFileNode *copy); // IN/OUT: Copy of the node Bool HgfsHandleIsSequentialOpen(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: session info Bool *sequentialOpen); // OUT: If open was sequential Bool HgfsHandleIsSharedFolderOpen(HgfsHandle handle, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: session info Bool *sharedFolderOpen); // OUT: If shared folder Bool HgfsGetSearchCopy(HgfsHandle handle, // IN: Hgfs search handle HgfsSessionInfo *session, // IN: Session info HgfsSearch *copy); // IN/OUT: Copy of the search HgfsInternalStatus HgfsCloseFile(fileDesc fileDesc, // IN: OS handle of the file void *fileCtx); // IN: file context Bool HgfsServerGetOpenMode(HgfsFileOpenInfo *openInfo, // IN: Open info to examine uint32 *modeOut); // OUT: Local mode Bool HgfsAcquireServerLock(fileDesc fileDesc, // IN: OS handle HgfsSessionInfo *session, // IN: Session info HgfsServerLock *serverLock); // IN/OUT: Oplock asked for/granted Bool HgfsServerPlatformInit(void); void HgfsServerPlatformDestroy(void); HgfsNameStatus HgfsServerHasSymlink(const char *fileName, // IN: fileName to be checked size_t fileNameLength, // IN const char *sharePath, // IN: share path in question size_t sharePathLen); // IN HgfsNameStatus HgfsServerConvertCase(const char *sharePath, // IN: share path in question size_t sharePathLength, // IN char *fileName, // IN: filename to be looked up size_t fileNameLength, // IN uint32 caseFlags, // IN: case-sensitivity flags char **convertedFileName, // OUT: case-converted filename size_t *convertedFileNameLength); // OUT Bool HgfsServerCaseConversionRequired(void); char* HgfsBuildRelativePath(const char* source, // IN: source file name const char* target); // IN: target file name /* All oplock-specific functionality is defined here. */ #ifdef HGFS_OPLOCKS void HgfsServerOplockBreak(ServerLockData *data); // IN: server lock info void HgfsAckOplockBreak(ServerLockData *lockData, // IN: server lock info HgfsServerLock replyLock); // IN: client has this lock #endif /* Transport related functions. */ Bool HgfsPackAndSendPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet char *packetOut, // IN: Output packet to send size_t packetOutLen, // IN: Output packet size HgfsInternalStatus status, // IN: status HgfsHandle id, // IN: id of the request packet HgfsTransportSessionInfo *transportSession, // IN: session info HgfsSendFlags flags); // IN: flags how to send /* Get the session with a specific session id */ HgfsSessionInfo * HgfsServerTransportGetSessionInfo(HgfsTransportSessionInfo *transportSession, // IN: transport session info uint64 sessionId); // IN: session id Bool HgfsPacketSend(HgfsPacket *packet, // IN/OUT: Hgfs Packet char *packetOut, // IN: Output packet buffer size_t packetOutLen, // IN: Output packet size HgfsTransportSessionInfo *transportSession, // IN: session info HgfsSendFlags flags); // IN: flags how to send Bool HgfsServerCheckOpenFlagsForShare(HgfsFileOpenInfo *openInfo, // IN: Hgfs file handle HgfsOpenFlags *flags); // IN/OUT: open mode HgfsInternalStatus HgfsPlatformConvertFromNameStatus(HgfsNameStatus status); // IN: name status HgfsInternalStatus HgfsPlatformSymlinkCreate(char *localSymlinkName, // IN: symbolic link file name char *localTargetName); // IN: symlink target name HgfsInternalStatus HgfsPlatformGetattrFromName(char *fileName, // IN: file name HgfsShareOptions configOptions, // IN: configuration options char *shareName, // IN: share name HgfsFileAttrInfo *attr, // OUT: file attributes char **targetName); // OUT: Symlink target HgfsInternalStatus HgfsPlatformSearchDir(HgfsNameStatus nameStatus, // IN: name status char *dirName, // IN: relative directory name uint32 dirNameLength, // IN: length of dirName uint32 caseFlags, // IN: case flags HgfsShareInfo *shareInfo, // IN: sharfed folder information char *baseDir, // IN: name of the shared directory uint32 baseDirLen, // IN: length of the baseDir HgfsSessionInfo *session, // IN: session info HgfsHandle *handle); // OUT: search handle HgfsInternalStatus HgfsAccess(char *fileName, // IN: local file path char *shareName, // IN: Name of the share size_t shareNameLen); // IN: Length of the share name HgfsInternalStatus HgfsPlatformReadFile(HgfsHandle file, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: session info uint64 offset, // IN: file offset to read from uint32 requiredSize, // IN: length of data to read void* payload, // OUT: buffer for the read data uint32 *actualSize); // OUT: actual length read HgfsInternalStatus HgfsPlatformWriteFile(HgfsHandle file, // IN: Hgfs file handle HgfsSessionInfo *session, // IN: session info uint64 offset, // IN: file offset to write to uint32 requiredSize, // IN: length of data to write HgfsWriteFlags flags, // IN: write flags void* payload, // IN: data to be written uint32 *actualSize); // OUT: actual length written HgfsInternalStatus HgfsPlatformWriteWin32Stream(HgfsHandle file, // IN: packet header char *dataToWrite, // IN: data to write size_t requiredSize, // IN: data size Bool doSecurity, // IN: write ACL uint32 *actualSize, // OUT: written data size HgfsSessionInfo *session); // IN: session info Bool HgfsValidatePacket(char const *packetIn, // IN: HGFS packet size_t packetSize, // IN: HGFS packet size Bool v4header); // IN: HGFS header type void HgfsPackReplyHeaderV4(HgfsInternalStatus status, // IN: platfrom independent HGFS status code uint32 payloadSize, // IN: size of HGFS operational packet HgfsOp op, // IN: request type uint64 sessionId, // IN: session id uint32 requestId, // IN: request id HgfsHeader *header); // OUT: packet header HgfsInternalStatus HgfsPlatformGetFd(HgfsHandle hgfsHandle, // IN: HGFS file handle HgfsSessionInfo *session, // IN: Session info Bool append, // IN: Open with append flag fileDesc *fd); // OUT: Opened file descriptor HgfsInternalStatus HgfsPlatformFileExists(char *utf8LocalName); // IN: Full file path utf8 encoding /* * NOTE. * This function requires valid localSrcName and localTargetName even when * srcFile and targetFile are specified. * Depending on some various conditions it may fall back on using file names * instead of file handles. */ HgfsInternalStatus HgfsPlatformRename(char *localSrcName, // IN: local path to source file fileDesc srcFile, // IN: source file handle char *localTargetName, // IN: local path to target file fileDesc targetFile, // IN: target file handle HgfsRenameHint hints); // IN: rename hints HgfsInternalStatus HgfsPlatformCreateDir(HgfsCreateDirInfo *info, // IN: direcotry properties char *utf8Name); // IN: full path for the new directory HgfsInternalStatus HgfsPlatformDeleteFileByHandle(HgfsHandle file, // IN: file being deleted HgfsSessionInfo *session); // IN: session info HgfsInternalStatus HgfsPlatformDeleteFileByName(char const *utf8Name); // IN: full file path in utf8 encoding HgfsInternalStatus HgfsPlatformDeleteDirByHandle(HgfsHandle dir, // IN: directory being deleted HgfsSessionInfo *session); // IN: session info HgfsInternalStatus HgfsPlatformDeleteDirByName(char const *utf8Name); // IN: full file path in utf8 encoding HgfsInternalStatus HgfsPlatformHandleIncompleteName(HgfsNameStatus nameStatus, // IN: name status HgfsFileAttrInfo *attr); // OUT: attributes void HgfsPlatformGetDefaultDirAttrs(HgfsFileAttrInfo *attr); // OUT: attributes HgfsInternalStatus HgfsPlatformGetattrFromFd(fileDesc fileDesc, // IN: file descriptor to query HgfsSessionInfo *session, // IN: session info HgfsFileAttrInfo *attr); // OUT: file attributes HgfsInternalStatus HgfsPlatformSetattrFromFd(HgfsHandle file, // IN: file descriptor HgfsSessionInfo *session, // IN: session info HgfsFileAttrInfo *attr, // IN: attrs to set HgfsAttrHint hints); // IN: attr hints HgfsInternalStatus HgfsPlatformSetattrFromName(char *utf8Name, // IN: local file path HgfsFileAttrInfo *attr, // IN: attrs to set HgfsShareOptions configOptions, // IN: share options HgfsAttrHint hints); // IN: attr hints HgfsInternalStatus HgfsPlatformValidateOpen(HgfsFileOpenInfo *openInfo, // IN: Open info struct Bool followLinks, // IN: follow symlinks on the host HgfsSessionInfo *session, // IN: Session info HgfsLocalId *localId, // OUT: Local unique file ID fileDesc *newHandle); // OUT: Handle to the file void * HSPU_GetBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet uint32 startIndex, // IN: start index of iov void **buf, // OUT: Contigous buffer size_t bufSize, // IN: Size of buffer Bool *isAllocated, // OUT: Was buffer allocated ? MappingType mappingType, // IN: Readable/ Writeable ? HgfsTransportSessionInfo *transportSession); // IN: Session Info void * HSPU_GetMetaPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet size_t *metaPacketSize, // OUT: Size of metaPacket HgfsTransportSessionInfo *transportSession); // IN: Session Info void * HSPU_GetDataPacketBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet MappingType mappingType, // IN: Readable/ Writeable ? HgfsTransportSessionInfo *transportSession); // IN: Session Info void HSPU_PutPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet HgfsTransportSessionInfo *transportSession); // IN: Session Info void HSPU_PutBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet uint32 startIndex, // IN: Start of iov void **buf, // IN/OUT: Buffer to be freed size_t *bufSize, // IN: Size of the buffer Bool *isAllocated, // IN: Was buffer allocated ? MappingType mappingType, // IN: Readable/ Writeable ? HgfsTransportSessionInfo *transportSession); // IN: Session info void HSPU_PutDataPacketBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet HgfsTransportSessionInfo *transportSession); // IN: Session Info void HSPU_PutMetaPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet HgfsTransportSessionInfo *transportSession); // IN: Session Info void HSPU_CopyBufToDataIovec(HgfsPacket *packet, // IN/OUT: Hgfs packet void *buf, // IN: Buffer to copy from uint32 bufSize, // IN: Size of buffer HgfsTransportSessionInfo *transportSession);// IN: Session Info void HSPU_CopyBufToIovec(HgfsPacket *packet, // IN/OUT: Hgfs Packet uint32 startIndex, // IN: start index into iov void *buf, // IN: Buffer size_t bufSize, // IN: Size of buffer HgfsTransportSessionInfo *transportSession); // IN: Session Info void * HSPU_GetReplyPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet size_t *replyPacketSize, //IN/OUT: Size of reply Packet HgfsTransportSessionInfo *transportSession); // IN: Session Info void HSPU_PutReplyPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet HgfsTransportSessionInfo *transportSession); // IN: Session Info #endif /* __HGFS_SERVER_INT_H__ */ open-vm-tools-9.4.0-1280544/lib/hgfsServer/Makefile.am0000644765153500003110000000236012220061556020360 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libHgfsServer.la libHgfsServer_la_SOURCES = libHgfsServer_la_SOURCES += hgfsServer.c libHgfsServer_la_SOURCES += hgfsServerLinux.c libHgfsServer_la_SOURCES += hgfsServerPacketUtil.c libHgfsServer_la_SOURCES += hgfsDirNotifyStub.c libHgfsServer_la_SOURCES += hgfsServerParameters.c AM_CFLAGS = AM_CFLAGS += -DVMTOOLS_USE_GLIB AM_CFLAGS += @GLIB2_CPPFLAGS@ open-vm-tools-9.4.0-1280544/lib/hgfsServer/hgfsDirNotify.h0000644765153500003110000000636712220061556021267 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _HGFS_DIRNOTIFY_H #define _HGFS_DIRNOTIFY_H /* * hgfsDirNotify.h -- * * Function definitions for directory change notification. */ #include "hgfsServer.h" // for HgfsSharedFolderHandle #include "hgfsProto.h" // for HgfsSubscriberHandle #include "hgfsUtil.h" // for HgfsInternalStatus struct HgfsSessionInfo; /* * Activate and deactivate reason. * Currently, there are two scenarios: * 1) HGFS server is check point synchronizing: the file system event * generation is deactivated at the start and activated at the end. * 2) The client has added the first subscriber or removed the last * subscriber. The file system event generation is activated on the * addition of the first subscriber and deactivated on removal of * the last one. * * Note, in case 1 above, if there are no subscribers even at the end * of the HGFS server check point syncing, the activation will not * activate the file system events. */ typedef enum { HGFS_NOTIFY_REASON_SERVER_SYNC, HGFS_NOTIFY_REASON_SUBSCRIBERS, } HgfsNotifyActivateReason; /* This is a callback that is implemented in hgfsServer.c */ typedef void HgfsNotifyEventReceiveCb(HgfsSharedFolderHandle sharedFolder, HgfsSubscriberHandle subscriber, char *name, uint32 mask, struct HgfsSessionInfo *session); HgfsInternalStatus HgfsNotify_Init(void); void HgfsNotify_Exit(void); void HgfsNotify_Deactivate(HgfsNotifyActivateReason mode); void HgfsNotify_Activate(HgfsNotifyActivateReason mode); HgfsSharedFolderHandle HgfsNotify_AddSharedFolder(const char *path, const char *shareName); HgfsSubscriberHandle HgfsNotify_AddSubscriber(HgfsSharedFolderHandle sharedFolder, const char *path, uint32 eventFilter, uint32 recursive, HgfsNotifyEventReceiveCb notify, struct HgfsSessionInfo *session); Bool HgfsNotify_RemoveSharedFolder(HgfsSharedFolderHandle sharedFolder); Bool HgfsNotify_RemoveSubscriber(HgfsSubscriberHandle subscriber); void HgfsNotify_RemoveSessionSubscribers(struct HgfsSessionInfo *session); #endif // _HGFS_DIRNOTIFY_H open-vm-tools-9.4.0-1280544/lib/hgfsServer/hgfsServerParameters.c0000644765153500003110000054520512220061556022644 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #include #include #include "vmware.h" #include "str.h" #include "cpName.h" #include "cpNameLite.h" #include "hgfsServerInt.h" #include "hgfsServerPolicy.h" #include "codeset.h" #include "config.h" #include "file.h" #include "util.h" #include "wiper.h" #include "vm_basic_asm.h" #define LOGLEVEL_MODULE hgfs #include "loglevel_user.h" #ifdef _WIN32 #define HGFS_REQUEST_WIN32_SUPPORTED HGFS_REQUEST_SUPPORTED #define HGFS_REQUEST_POSIX_SUPPORTED HGFS_REQUEST_NOT_SUPPORTED #else #define HGFS_REQUEST_WIN32_SUPPORTED HGFS_REQUEST_NOT_SUPPORTED #define HGFS_REQUEST_POSIX_SUPPORTED HGFS_REQUEST_SUPPORTED #endif #define HGFS_ASSERT_PACK_PARAMS \ do { \ ASSERT(packet); \ ASSERT(packetHeader); \ ASSERT(session); \ ASSERT(payloadSize); \ } while(0) /* * This is the default/minimal set of capabilities which is supported by every transport. * Every transport and session may have additional capabilities in addition to these. */ static HgfsCapability hgfsDefaultCapabilityTable[] = { {HGFS_OP_OPEN, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_READ, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_WRITE, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_CLOSE, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_SEARCH_OPEN, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_SEARCH_READ, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_SEARCH_CLOSE, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_GETATTR, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_SETATTR, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_CREATE_DIR, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_DELETE_FILE, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_DELETE_DIR, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_RENAME, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_QUERY_VOLUME_INFO, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_OPEN_V2, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_GETATTR_V2, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_SETATTR_V2, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_SEARCH_READ_V2, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_CREATE_SYMLINK, HGFS_REQUEST_POSIX_SUPPORTED}, {HGFS_OP_SERVER_LOCK_CHANGE, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_CREATE_DIR_V2, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_DELETE_FILE_V2, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_DELETE_DIR_V2, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_RENAME_V2, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_OPEN_V3, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_READ_V3, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_WRITE_V3, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_CLOSE_V3, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_SEARCH_OPEN_V3, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_SEARCH_READ_V3, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_SEARCH_CLOSE_V3, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_GETATTR_V3, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_SETATTR_V3, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_CREATE_DIR_V3, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_DELETE_FILE_V3, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_DELETE_DIR_V3, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_RENAME_V3, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_QUERY_VOLUME_INFO_V3, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_CREATE_SYMLINK_V3, HGFS_REQUEST_POSIX_SUPPORTED}, {HGFS_OP_SERVER_LOCK_CHANGE_V3, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_WRITE_WIN32_STREAM_V3, HGFS_REQUEST_WIN32_SUPPORTED}, {HGFS_OP_CREATE_SESSION_V4, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_DESTROY_SESSION_V4, HGFS_REQUEST_SUPPORTED}, {HGFS_OP_READ_FAST_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_WRITE_FAST_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_SET_WATCH_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_REMOVE_WATCH_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_NOTIFY_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_SEARCH_READ_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_OPEN_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_ENUMERATE_STREAMS_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_GETATTR_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_SETATTR_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_DELETE_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_LINKMOVE_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_FSCTL_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_ACCESS_CHECK_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_FSYNC_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_QUERY_VOLUME_INFO_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_OPLOCK_ACQUIRE_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_OPLOCK_BREAK_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_LOCK_BYTE_RANGE_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_UNLOCK_BYTE_RANGE_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_QUERY_EAS_V4, HGFS_REQUEST_NOT_SUPPORTED}, {HGFS_OP_SET_EAS_V4, HGFS_REQUEST_NOT_SUPPORTED}, }; /* *----------------------------------------------------------------------------- * * HgfsValidatePacket -- * * Validates that packet is not malformed. Checks consistency of various * fields and sizes. * * Results: * TRUE if the packet is correct. * FALSE if the packet is malformed. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsValidatePacket(char const *packetIn, // IN: request packet size_t packetSize, // IN: request packet size Bool v4header) // IN: HGFS header type { HgfsRequest *request = (HgfsRequest *)packetIn; Bool result = TRUE; if (packetSize < sizeof *request) { LOG(4, ("%s: Malformed HGFS packet received - packet too small!\n", __FUNCTION__)); return FALSE; } if (v4header) { HgfsHeader *header = (HgfsHeader *)packetIn; ASSERT(packetSize >= header->packetSize); ASSERT(header->packetSize >= header->headerSize); result = packetSize >= offsetof(HgfsHeader, requestId) && header->headerSize >= offsetof(HgfsHeader, reserved) && header->packetSize >= header->headerSize && packetSize >= header->packetSize; } else { result = packetSize >= sizeof *request; } if (!result) { LOG(4, ("%s: Malformed HGFS packet received!\n", __FUNCTION__)); } return result; } /* *----------------------------------------------------------------------------- * * HgfsValidateReplySize -- * * Verify if the size of a reply does not exceed maximum supported size. * * Results: * TRUE if the packet size is acceptable, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsValidateReplySize(char const *packetIn, HgfsOp op, size_t packetSize) { Bool result; HgfsRequest *request = (HgfsRequest *)packetIn; if (HGFS_V4_LEGACY_OPCODE != request->op) { if (HGFS_OP_READ_V3 == op) { result = packetSize <= HGFS_LARGE_PACKET_MAX; } else { result = packetSize <= HGFS_PACKET_MAX; } } else { result = TRUE; } if (!result) { LOG(4, ("%s: Reply exceeded maximum support size!\n", __FUNCTION__)); } return result; } /* *----------------------------------------------------------------------------- * * HgfsGetPayloadSize -- * * Returns size of the payload based on incoming packet and total * packet size. * * Results: * Size of the payload in bytes. * * Side effects: * None * *----------------------------------------------------------------------------- */ size_t HgfsGetPayloadSize(char const *packetIn, // IN: request packet size_t packetSize) // IN: request packet size { HgfsRequest *request = (HgfsRequest *)packetIn; size_t result; ASSERT(packetSize >= sizeof *request); if (request->op < HGFS_OP_CREATE_SESSION_V4) { result = packetSize - sizeof *request; } else { HgfsHeader *header = (HgfsHeader *)packetIn; ASSERT(packetSize >= header->packetSize); ASSERT(header->packetSize >= header->headerSize); result = header->packetSize - header->headerSize; } return result; } /* *----------------------------------------------------------------------------- * * HgfsParseRequest -- * * Returns requested operation and pointer to the payload based on * incoming packet and total packet size. * * Results: * TRUE if a reply can be sent. * FALSE if incoming packet does not allow sending any response. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsParseRequest(HgfsPacket *packet, // IN: request packet HgfsTransportSessionInfo *transportSession, // IN: current session HgfsInputParam **input, // OUT: request parameters HgfsInternalStatus *status) // OUT: error code { HgfsRequest *request; size_t packetSize; HgfsInternalStatus result = HGFS_ERROR_SUCCESS; HgfsInputParam *localInput; HgfsSessionInfo *session = NULL; request = (HgfsRequest *) HSPU_GetMetaPacket(packet, &packetSize, transportSession); ASSERT_DEVEL(request); LOG(4, ("%s: Recieved a request with opcode %d.\n", __FUNCTION__, (int) request->op)); if (!request) { /* * How can I return error back to the client, clearly the client is either broken or * malicious? We cannot continue from here. */ return FALSE; } *input = Util_SafeMalloc(sizeof *localInput); localInput = *input; memset(localInput, 0, sizeof *localInput); localInput->metaPacket = (char *)request; localInput->metaPacketSize = packetSize; localInput->transportSession = transportSession; localInput->packet = packet; localInput->session = NULL; /* * Error out if less than HgfsRequest size. */ if (packetSize < sizeof *request) { if (packetSize >= sizeof request->id) { localInput->id = request->id; } ASSERT_DEVEL(0); return FALSE; } if (request->op < HGFS_OP_OPEN_V3) { /* Legacy requests do not have a separate header. */ localInput->payload = request; localInput->op = request->op; localInput->payloadSize = packetSize; localInput->id = request->id; } else if (request->op < HGFS_OP_CREATE_SESSION_V4) { /* V3 header. */ if (packetSize > sizeof *request) { localInput->payload = HGFS_REQ_GET_PAYLOAD_V3(request); localInput->payloadSize = packetSize - ((char *)localInput->payload - (char *)request); } localInput->op = request->op; localInput->id = request->id; } else if (HGFS_V4_LEGACY_OPCODE == request->op) { /* V4 header. */ HgfsHeader *header = (HgfsHeader *)request; localInput->v4header = TRUE; localInput->id = header->requestId; localInput->op = header->op; if (packetSize >= offsetof(HgfsHeader, sessionId) + sizeof header->sessionId) { if (packetSize < header->packetSize || header->packetSize < header->headerSize) { LOG(4, ("%s: Malformed HGFS packet received - inconsistent header" " and packet sizes!\n", __FUNCTION__)); result = HGFS_ERROR_PROTOCOL; } if ((HGFS_ERROR_SUCCESS == result) && (header->op != HGFS_OP_CREATE_SESSION_V4)) { session = HgfsServerTransportGetSessionInfo(transportSession, header->sessionId); if (!session || session->state != HGFS_SESSION_STATE_OPEN) { LOG(4, ("%s: HGFS packet with invalid session id!\n", __FUNCTION__)); result = HGFS_ERROR_STALE_SESSION; } } } else { LOG(4, ("%s: Malformed HGFS packet received - header is too small!\n", __FUNCTION__)); result = HGFS_ERROR_PROTOCOL; } if (HGFS_ERROR_SUCCESS == result) { // Passed all tests localInput->payload = (char *)request + header->headerSize; localInput->payloadSize = header->packetSize - header->headerSize; } } else { LOG(4, ("%s: Malformed HGFS packet received - invalid legacy opcode!\n", __FUNCTION__)); result = HGFS_ERROR_PROTOCOL; } if (HGFS_ERROR_SUCCESS != result) { LOG(4, ("%s: Malformed HGFS packet received!\n", __FUNCTION__)); } else if ((NULL == session) && (!localInput->v4header)) { session = HgfsServerTransportGetSessionInfo(transportSession, transportSession->defaultSessionId); if (NULL == session) { /* * Create a new session if the default session doesn't exist. */ if (!HgfsServerAllocateSession(transportSession, transportSession->channelCapabilities, &session)) { result = HGFS_ERROR_NOT_ENOUGH_MEMORY; } else { result = HgfsServerTransportAddSessionToList(transportSession, session); if (HGFS_ERROR_SUCCESS != result) { LOG(4, ("%s: Could not add session to the list.\n", __FUNCTION__)); } else { transportSession->defaultSessionId = session->sessionId; HgfsServerSessionGet(session); } } } } if (session) { session->isInactive = FALSE; } localInput->session = session; localInput->payloadOffset = (char *)localInput->payload - (char *)localInput->metaPacket; *status = result; return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackOpenPayloadV1 -- * * Unpack and validate payload for hgfs open request V1 to the HgfsFileOpenInfo * structure that is used to pass around open request information. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackOpenPayloadV1(HgfsRequestOpen *requestV1, // IN: request payload size_t payloadSize, // IN: request payload size HgfsFileOpenInfo *openInfo) // IN/OUT: open info struct { size_t extra; /* Enforced by the dispatch function. */ if (payloadSize < sizeof *requestV1) { LOG(4, ("%s: Malformed HGFS packet received - payload too small\n", __FUNCTION__)); return FALSE; } extra = payloadSize - sizeof *requestV1; /* * The request file name length is user-provided, so this test must be * carefully written to prevent wraparounds. */ if (requestV1->fileName.length > extra) { /* The input packet is smaller than the request. */ LOG(4, ("%s: Malformed HGFS packet received - payload too small to hold file name\n", __FUNCTION__)); return FALSE; } /* For OpenV1 requests, we know exactly what fields we expect. */ openInfo->mask = HGFS_OPEN_VALID_MODE | HGFS_OPEN_VALID_FLAGS | HGFS_OPEN_VALID_OWNER_PERMS | HGFS_OPEN_VALID_FILE_NAME; openInfo->mode = requestV1->mode; openInfo->cpName = requestV1->fileName.name; openInfo->cpNameSize = requestV1->fileName.length; openInfo->flags = requestV1->flags; openInfo->ownerPerms = requestV1->permissions; return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackOpenPayloadV2 -- * * Unpack and validate payload for hgfs open request V2 to the HgfsFileOpenInfo * structure that is used to pass around open request information. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackOpenPayloadV2(HgfsRequestOpenV2 *requestV2, // IN: request payload size_t payloadSize, // IN: request payload size HgfsFileOpenInfo *openInfo) // IN/OUT: open info struct { size_t extra; /* Enforced by the dispatch function. */ if (payloadSize < sizeof *requestV2) { LOG(4, ("%s: Malformed HGFS packet received - payload too small\n", __FUNCTION__)); return FALSE; } extra = payloadSize - sizeof *requestV2; if (!(requestV2->mask & HGFS_OPEN_VALID_FILE_NAME)) { /* We do not support open requests without a valid file name. */ LOG(4, ("%s: Malformed HGFS packet received - invalid mask\n", __FUNCTION__)); return FALSE; } /* * The request file name length is user-provided, so this test must be * carefully written to prevent wraparounds. */ if (requestV2->fileName.length > extra) { /* The input packet is smaller than the request. */ LOG(4, ("%s: Malformed HGFS packet received - payload too small to hold file name\n", __FUNCTION__)); return FALSE; } /* * Copy all the fields into our carrier struct. Some will probably be * garbage, but it's simpler to copy everything now and check the * valid bits before reading later. */ openInfo->mask = requestV2->mask; openInfo->mode = requestV2->mode; openInfo->cpName = requestV2->fileName.name; openInfo->cpNameSize = requestV2->fileName.length; openInfo->flags = requestV2->flags; openInfo->specialPerms = requestV2->specialPerms; openInfo->ownerPerms = requestV2->ownerPerms; openInfo->groupPerms = requestV2->groupPerms; openInfo->otherPerms = requestV2->otherPerms; openInfo->attr = requestV2->attr; openInfo->allocationSize = requestV2->allocationSize; openInfo->desiredAccess = requestV2->desiredAccess; openInfo->shareAccess = requestV2->shareAccess; openInfo->desiredLock = requestV2->desiredLock; return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackOpenPayloadV3 -- * * Unpack and validate payload for hgfs open request V3 to the HgfsFileOpenInfo * structure that is used to pass around open request information. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackOpenPayloadV3(HgfsRequestOpenV3 *requestV3, // IN: request payload size_t payloadSize, // IN: request payload size HgfsFileOpenInfo *openInfo) // IN/OUT: open info struct { size_t extra; /* Enforced by the dispatch function. */ if (payloadSize < sizeof *requestV3) { LOG(4, ("%s: Malformed HGFS packet received - payload too small\n", __FUNCTION__)); return FALSE; } extra = payloadSize - sizeof *requestV3; if (!(requestV3->mask & HGFS_OPEN_VALID_FILE_NAME)) { /* We do not support open requests without a valid file name. */ LOG(4, ("%s: Malformed HGFS packet received - incorrect mask\n", __FUNCTION__)); return FALSE; } /* * The request file name length is user-provided, so this test must be * carefully written to prevent wraparounds. */ if (requestV3->fileName.length > extra) { /* The input packet is smaller than the request. */ LOG(4, ("%s: Malformed HGFS packet received - payload too small to hold file name\n", __FUNCTION__)); return FALSE; } /* * Copy all the fields into our carrier struct. Some will probably be * garbage, but it's simpler to copy everything now and check the * valid bits before reading later. */ openInfo->mask = requestV3->mask; openInfo->mode = requestV3->mode; openInfo->cpName = requestV3->fileName.name; openInfo->cpNameSize = requestV3->fileName.length; openInfo->caseFlags = requestV3->fileName.caseType; openInfo->flags = requestV3->flags; openInfo->specialPerms = requestV3->specialPerms; openInfo->ownerPerms = requestV3->ownerPerms; openInfo->groupPerms = requestV3->groupPerms; openInfo->otherPerms = requestV3->otherPerms; openInfo->attr = requestV3->attr; openInfo->allocationSize = requestV3->allocationSize; openInfo->desiredAccess = requestV3->desiredAccess; openInfo->shareAccess = requestV3->shareAccess; openInfo->desiredLock = requestV3->desiredLock; return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackOpenRequest -- * * Unpack hgfs open request to the HgfsFileOpenInfo structure that is used * to pass around open request information. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackOpenRequest(void const *packet, // IN: HGFS packet size_t packetSize, // IN: packet size HgfsOp op, // IN: requested operation HgfsFileOpenInfo *openInfo) // IN/OUT: open info structure { Bool result; ASSERT(packet); ASSERT(openInfo); openInfo->requestType = op; openInfo->caseFlags = HGFS_FILE_NAME_DEFAULT_CASE; switch (op) { case HGFS_OP_OPEN_V3: { HgfsRequestOpenV3 *requestV3 = (HgfsRequestOpenV3 *)packet; LOG(4, ("%s: HGFS_OP_OPEN_V3\n", __FUNCTION__)); result = HgfsUnpackOpenPayloadV3(requestV3, packetSize, openInfo); break; } case HGFS_OP_OPEN_V2: { HgfsRequestOpenV2 *requestV2 = (HgfsRequestOpenV2 *)packet; LOG(4, ("%s: HGFS_OP_OPEN_V2\n", __FUNCTION__)); result = HgfsUnpackOpenPayloadV2(requestV2, packetSize, openInfo); break; } case HGFS_OP_OPEN: { HgfsRequestOpen *requestV1 = (HgfsRequestOpen *)packet; LOG(4, ("%s: HGFS_OP_OPEN\n", __FUNCTION__)); result = HgfsUnpackOpenPayloadV1(requestV1, packetSize, openInfo); break; } default: NOT_REACHED(); result = FALSE; } if (!result) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); } return result; } /* *----------------------------------------------------------------------------- * * HgfsPackReplyHeaderV4 -- * * Pack hgfs header that corresponds an incoming packet. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsPackReplyHeaderV4(HgfsInternalStatus status, // IN: reply status uint32 payloadSize, // IN: size of the reply payload HgfsOp op, // IN: request type uint64 sessionId, // IN: session id uint32 requestId, // IN: request id HgfsHeader *header) // OUT: outgoing packet header { memset(header, 0, sizeof *header); header->version = 1; header->dummy = HGFS_V4_LEGACY_OPCODE; header->packetSize = payloadSize + sizeof *header; header->headerSize = sizeof *header; header->requestId = requestId; header->op = op; header->status = HgfsConvertFromInternalStatus(status); header->flags = 0; header->information = status; header->sessionId = sessionId; } /* *----------------------------------------------------------------------------- * * HgfsPackLegacyReplyHeader -- * * Pack pre-V4 reply header. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsPackLegacyReplyHeader(HgfsInternalStatus status, // IN: reply status HgfsHandle id, // IN: original packet id HgfsReply *header) // OUT: outgoing packet header { memset(header, 0, sizeof *header); header->status = HgfsConvertFromInternalStatus(status); header->id = id; } /* *----------------------------------------------------------------------------- * * HgfsPackOpenReplyV3 -- * * Pack hgfs open V3 reply payload to the HgfsReplyOpenV3 structure. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsPackOpenReplyV3(HgfsFileOpenInfo *openInfo, // IN: open info struct HgfsReplyOpenV3 *reply) // OUT: size of packet { reply->file = openInfo->file; reply->reserved = 0; if (openInfo->mask & HGFS_OPEN_VALID_SERVER_LOCK) { reply->acquiredLock = openInfo->acquiredLock; } else { reply->acquiredLock = HGFS_LOCK_NONE; } } /* *----------------------------------------------------------------------------- * * HgfsPackOpenV2Reply -- * * Pack hgfs open V2 reply payload to the HgfsReplyOpenV3 structure. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsPackOpenV2Reply(HgfsFileOpenInfo *openInfo, // IN: open info struct HgfsReplyOpenV2 *reply) // OUT: reply payload { reply->file = openInfo->file; if (openInfo->mask & HGFS_OPEN_VALID_SERVER_LOCK) { reply->acquiredLock = openInfo->acquiredLock; } else { reply->acquiredLock = HGFS_LOCK_NONE; } } /* *----------------------------------------------------------------------------- * * HgfsPackOpenV1Reply -- * * Pack hgfs open V1 reply payload to the HgfsReplyOpenV3 structure. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsPackOpenV1Reply(HgfsFileOpenInfo *openInfo, // IN: open info struct HgfsReplyOpen *reply) // OUT: reply payload { reply->file = openInfo->file; } /* *----------------------------------------------------------------------------- * * HgfsPackOpenReply -- * * Pack hgfs open reply to the HgfsReplyOpen{V2} structure. * * Results: * Always TRUE. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackOpenReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsFileOpenInfo *openInfo, // IN: open info struct size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session) // IN: Session info { Bool result; ASSERT(openInfo); HGFS_ASSERT_PACK_PARAMS; *payloadSize = 0; switch (openInfo->requestType) { case HGFS_OP_OPEN_V3: { HgfsReplyOpenV3 *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { HgfsPackOpenReplyV3(openInfo, reply); *payloadSize = sizeof *reply; } break; } case HGFS_OP_OPEN_V2: { HgfsReplyOpenV2 *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { HgfsPackOpenV2Reply(openInfo, reply); *payloadSize = sizeof *reply; } break; } case HGFS_OP_OPEN: { HgfsReplyOpen *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { HgfsPackOpenV1Reply(openInfo, reply); *payloadSize = sizeof *reply; } break; } default: NOT_REACHED(); result = FALSE; } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackClosePayload -- * * Unpack hgfs close payload to get the handle which need to be closed. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackClosePayload(HgfsRequestClose *request, // IN: payload size_t payloadSize, // IN: payload size HgfsHandle* file) // OUT: HGFS handle to close { LOG(4, ("%s: HGFS_OP_CLOSE\n", __FUNCTION__)); if (payloadSize >= sizeof *request) { *file = request->file; return TRUE; } return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackClosePayloadV3 -- * * Unpack hgfs close payload V3 to get the handle which need to be closed. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackClosePayloadV3(HgfsRequestCloseV3 *requestV3, // IN: payload size_t payloadSize, // IN: payload size HgfsHandle* file) // OUT: HGFS handle to close { LOG(4, ("%s: HGFS_OP_CLOSE_V3\n", __FUNCTION__)); if (payloadSize >= sizeof *requestV3) { *file = requestV3->file; return TRUE; } LOG(4, ("%s: Too small HGFS packet\n", __FUNCTION__)); return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackCloseRequest -- * * Unpack hgfs close request to get the handle to close. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackCloseRequest(void const *packet, // IN: request packet size_t packetSize, // IN: request packet size HgfsOp op, // IN: request type HgfsHandle *file) // OUT: Handle to close { ASSERT(packet); switch (op) { case HGFS_OP_CLOSE_V3: { HgfsRequestCloseV3 *requestV3 = (HgfsRequestCloseV3 *)packet; if (!HgfsUnpackClosePayloadV3(requestV3, packetSize, file)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } case HGFS_OP_CLOSE: { HgfsRequestClose *requestV1 = (HgfsRequestClose *)packet; if (!HgfsUnpackClosePayload(requestV1, packetSize, file)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } default: NOT_REACHED(); return FALSE; } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsPackCloseReply -- * * Pack hgfs close reply to the HgfsReplyClose(V3) structure. * * Results: * Always TRUE. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackCloseReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: request type size_t *payloadSize, // OUT: size of packet excluding header HgfsSessionInfo *session) // IN: Session info { Bool result; HGFS_ASSERT_PACK_PARAMS; *payloadSize = 0; switch (op) { case HGFS_OP_CLOSE_V3: { HgfsReplyCloseV3 *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { /* Reply consists of a reserved field only. */ reply->reserved = 0; *payloadSize = sizeof *reply; } break; } case HGFS_OP_CLOSE: { HgfsReplyClose *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { *payloadSize = sizeof *reply; } break; } default: NOT_REACHED(); result = FALSE; } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackSearchClosePayload -- * * Unpack hgfs search close payload to get the search handle which need to be closed. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackSearchClosePayload(HgfsRequestSearchClose *request, // IN: payload size_t payloadSize, // IN: payload size HgfsHandle* search) // OUT: search to close { LOG(4, ("%s: HGFS_OP_SEARCH_CLOSE\n", __FUNCTION__)); if (payloadSize >= sizeof *request) { *search = request->search; return TRUE; } LOG(4, ("%s: Too small HGFS packet\n", __FUNCTION__)); return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackSearchClosePayloadV3 -- * * Unpack hgfs search close payload V3 to get the search handle which need to * be closed. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackSearchClosePayloadV3(HgfsRequestSearchCloseV3 *requestV3, // IN: payload size_t payloadSize, // IN: payload size HgfsHandle* search) // OUT: search { LOG(4, ("%s: HGFS_OP_SEARCH_CLOSE_V3\n", __FUNCTION__)); if (payloadSize >= sizeof *requestV3) { *search = requestV3->search; return TRUE; } LOG(4, ("%s: Too small HGFS packet\n", __FUNCTION__)); return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackSearchCloseRequest -- * * Unpack hgfs search close request to get the search handle. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackSearchCloseRequest(void const *packet, // IN: request packet size_t packetSize, // IN: request packet size HgfsOp op, // IN: request type HgfsHandle *search) // OUT: search to close { ASSERT(packet); switch (op) { case HGFS_OP_SEARCH_CLOSE_V3: { HgfsRequestSearchCloseV3 *requestV3 = (HgfsRequestSearchCloseV3 *)packet; if (!HgfsUnpackSearchClosePayloadV3(requestV3, packetSize, search)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } case HGFS_OP_SEARCH_CLOSE: { HgfsRequestSearchClose *requestV1 = (HgfsRequestSearchClose *)packet; if (!HgfsUnpackSearchClosePayload(requestV1, packetSize, search)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } default: NOT_REACHED(); return FALSE; } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsPackSearchCloseReply -- * * Pack hgfs SearchClose reply into a HgfsReplySearchClose(V3) structure. * * Results: * Always TRUE, except when it is called with a * wrong op or insufficient output buffer (which is a programming error). * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackSearchCloseReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: request type size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session) // IN: Session info { Bool result; HGFS_ASSERT_PACK_PARAMS; *payloadSize = 0; switch (op) { case HGFS_OP_SEARCH_CLOSE_V3: { HgfsReplyCloseV3 *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { /* Reply consists of only a reserved field. */ reply->reserved = 0; *payloadSize = sizeof *reply; } break; } case HGFS_OP_SEARCH_CLOSE: { HgfsReplyClose *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { *payloadSize = sizeof *reply; } break; } default: NOT_REACHED(); result = FALSE; } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackFileName -- * * Unpack HgfsFileName into a pointer to a CPName and size of the name. * Verifies that input buffer has enough space to hold the name. * * Results: * TRUE on success, FALSE on failure (buffer too small). * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackFileName(HgfsFileName *name, // IN: file name size_t maxNameSize, // IN: space allocated for the name char **cpName, // OUT: CP name size_t *cpNameSize) // OUT: CP name size { /* * The request file name length is user-provided, so this test must be * carefully written to prevent wraparounds. */ if (name->length > maxNameSize) { /* The input packet is smaller than the request. */ return FALSE; } *cpName = name->name; *cpNameSize = name->length; return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackFileNameV3 -- * * Unpack HgfsFileNameV3 into a pointer to a CPName and size of the name * or into file handle. * Verifies that input buffer has enough space to hold the name. * * Results: * TRUE on success, FALSE on failure (buffer too small). * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackFileNameV3(HgfsFileNameV3 *name, // IN: file name size_t maxNameSize, // IN: space allocated for the name Bool *useHandle, // OUT: file name or handle returned? char **cpName, // OUT: CP name size_t *cpNameSize, // OUT: CP name size HgfsHandle *file, // OUT: HGFS file handle uint32 *caseFlags) // OUT: case-sensitivity flags { /* * If we've been asked to reuse a handle, we don't need to look at, let * alone test the filename or its length. */ if (name->flags & HGFS_FILE_NAME_USE_FILE_DESC) { *file = name->fid; *cpName = NULL; *cpNameSize = 0; *caseFlags = HGFS_FILE_NAME_DEFAULT_CASE; *useHandle = TRUE; } else { /* * The request file name length is user-provided, so this test must be * carefully written to prevent wraparounds. */ if (name->length > maxNameSize) { /* The input packet is smaller than the request */ LOG(4, ("%s: Error unpacking file name - buffer too small\n", __FUNCTION__)); return FALSE; } *file = HGFS_INVALID_HANDLE; *cpName = name->name; *cpNameSize = name->length; *caseFlags = name->caseType; *useHandle = FALSE; } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackDeletePayloadV3 -- * * Unpack hgfs delete request V3 payload and initialize a corresponding * HgfsHandle or file name to tell us which to delete. Hints * holds flags to specify a handle or name for the file or * directory to delete. * * Since the structure of the get delete request packet is the same * for Delete File or Directory of the protocol, code is identical for * both operations. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackDeletePayloadV3(HgfsRequestDeleteV3 *requestV3, // IN: request payload size_t payloadSize, // IN: payload size char **cpName, // OUT: cpName size_t *cpNameSize, // OUT: cpName size HgfsDeleteHint *hints, // OUT: delete hints HgfsHandle *file, // OUT: file handle uint32 *caseFlags) // OUT: case-sensitivity flags { Bool result; Bool useHandle; if (payloadSize < sizeof *requestV3) { return FALSE; } *hints = requestV3->hints; result = HgfsUnpackFileNameV3(&requestV3->fileName, payloadSize - sizeof *requestV3, &useHandle, cpName, cpNameSize, file, caseFlags); if (useHandle) { *hints |= HGFS_DELETE_HINT_USE_FILE_DESC; } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackDeletePayloadV2 -- * * Unpack hgfs delete request V2 payload and initialize a corresponding * HgfsHandle or file name to tell us which to delete. Hints * holds flags to specify a handle or name for the file or * directory to delete. * * Since the structure of the get delete request packet is the same * for Delete File or Directory of the protocol, code is identical for * both operations. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackDeletePayloadV2(HgfsRequestDeleteV2 *requestV2, // IN: request payload size_t payloadSize, // IN: payload size char **cpName, // OUT: cpName size_t *cpNameSize, // OUT: cpName size HgfsDeleteHint *hints, // OUT: delete hints HgfsHandle *file) // OUT: file handle { Bool result = TRUE; /* Enforced by the dispatch function. */ ASSERT(payloadSize >= sizeof *requestV2); *file = HGFS_INVALID_HANDLE; *hints = requestV2->hints; /* * If we've been asked to reuse a handle, we don't need to look at, let * alone test the filename or its length. */ if (requestV2->hints & HGFS_DELETE_HINT_USE_FILE_DESC) { *file = requestV2->file; *cpName = NULL; *cpNameSize = 0; } else { result = HgfsUnpackFileName(&requestV2->fileName, payloadSize - sizeof *requestV2, cpName, cpNameSize); } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackDeletePayloadV1 -- * * Unpack hgfs delete request V1 payload and initialize a corresponding * file name to tell us which to delete. * * Since the structure of the get delete request packet is the same * for Delete File or Directory of the protocol, code is identical for * both operations. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackDeletePayloadV1(HgfsRequestDelete *requestV1, // IN: request payload size_t payloadSize, // IN: payload size char **cpName, // OUT: cpName size_t *cpNameSize) // OUT: cpName size { return HgfsUnpackFileName(&requestV1->fileName, payloadSize - sizeof *requestV1, cpName, cpNameSize); } /* *----------------------------------------------------------------------------- * * HgfsUnpackDeleteRequest -- * * Unpack hgfs delete request and initialize a corresponding * HgfsHandle or file name to tell us which to delete. Hints * holds flags to specify a handle or name for the file or * directory to delete. * * Since the structure of the get delete request packet is the same * for Delete File or Directory of the protocol, code is identical for * both operations. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackDeleteRequest(void const *packet, // IN: HGFS packet size_t packetSize, // IN: request packet size HgfsOp op, // IN: requested operation char **cpName, // OUT: cpName size_t *cpNameSize, // OUT: cpName size HgfsDeleteHint *hints, // OUT: delete hints HgfsHandle *file, // OUT: file handle uint32 *caseFlags) // OUT: case-sensitivity flags { ASSERT(packet); ASSERT(cpName); ASSERT(cpNameSize); ASSERT(file); ASSERT(hints); ASSERT(caseFlags); *caseFlags = HGFS_FILE_NAME_DEFAULT_CASE; *hints = 0; *file = HGFS_INVALID_HANDLE; switch (op) { case HGFS_OP_DELETE_FILE_V3: case HGFS_OP_DELETE_DIR_V3: { HgfsRequestDeleteV3 *requestV3 = (HgfsRequestDeleteV3 *)packet; if (!HgfsUnpackDeletePayloadV3(requestV3, packetSize, cpName, cpNameSize, hints, file, caseFlags)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } case HGFS_OP_DELETE_FILE_V2: case HGFS_OP_DELETE_DIR_V2: { HgfsRequestDeleteV2 *requestV2 = (HgfsRequestDeleteV2 *)packet; if (!HgfsUnpackDeletePayloadV2(requestV2, packetSize, cpName, cpNameSize, hints, file)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } case HGFS_OP_DELETE_FILE: case HGFS_OP_DELETE_DIR: { HgfsRequestDelete *requestV1 = (HgfsRequestDelete *)packet; if (!HgfsUnpackDeletePayloadV1(requestV1, packetSize, cpName, cpNameSize)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } default: NOT_REACHED(); LOG(4, ("%s: Invalid opcode\n", __FUNCTION__)); return FALSE; } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsPackDeleteReply -- * * Pack hgfs delete reply. * Since the structure of the delete reply packet hasn't changed in * version 2 of the protocol, HgfsReplyDeleteV2 is identical to * HgfsReplyDelete. So use HgfsReplyDelete type to access packetIn to * keep the code simple. * * Results: * TRUE if valid op version reply filled, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackDeleteReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: requested operation size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session) // IN: Session info { Bool result; HGFS_ASSERT_PACK_PARAMS; *payloadSize = 0; /* No reply payload, just header. */ switch (op) { case HGFS_OP_DELETE_FILE_V3: case HGFS_OP_DELETE_DIR_V3: { HgfsReplyDeleteV3 *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { *payloadSize = sizeof *reply; } break; } case HGFS_OP_DELETE_FILE_V2: case HGFS_OP_DELETE_FILE: case HGFS_OP_DELETE_DIR_V2: case HGFS_OP_DELETE_DIR: { HgfsReplyDelete *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { *payloadSize = sizeof *reply; } break; } default: LOG(4, ("%s: invalid op code %d\n", __FUNCTION__, op)); result = FALSE; NOT_REACHED(); } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackRenamePayloadV3 -- * * Unpack hgfs rename request V3 payload and initialize a corresponding * HgfsHandles or file names to tell us old and new names/handles. Hints * holds flags to specify a handle or name for the file or * directory to rename. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackRenamePayloadV3(HgfsRequestRenameV3 *requestV3, // IN: request payload size_t payloadSize, // IN: payload size char **cpOldName, // OUT: rename src size_t *cpOldNameLen, // OUT: rename src size char **cpNewName, // OUT: rename dst size_t *cpNewNameLen, // OUT: rename dst size HgfsRenameHint *hints, // OUT: rename hints HgfsHandle *srcFile, // OUT: src file handle HgfsHandle *targetFile, // OUT: target file handle uint32 *oldCaseFlags, // OUT: source case flags uint32 *newCaseFlags) // OUT: dest. case flags { size_t extra; HgfsFileNameV3 *newName; Bool useHandle; LOG(4, ("%s: HGFS_OP_RENAME_V3\n", __FUNCTION__)); if (payloadSize < sizeof *requestV3) { return FALSE; } extra = payloadSize - sizeof *requestV3; *hints = requestV3->hints; /* * Get the old and new filenames from the request. * * Getting the new filename is somewhat inconvenient, because we * don't know where request->newName actually starts, thanks to the * fact that request->oldName is of variable length. We get around * this by using an HgfsFileName*, assigning it to the correct address * just after request->oldName ends, and using that to access the * new name. */ /* * If we've been asked to reuse a handle, we don't need to look at, let * alone test the filename or its length. This applies to the source * and the target. */ if (!HgfsUnpackFileNameV3(&requestV3->oldName, extra, &useHandle, cpOldName, cpOldNameLen, srcFile, oldCaseFlags)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } if (useHandle) { *hints |= HGFS_RENAME_HINT_USE_SRCFILE_DESC; newName = &requestV3->newName; } else { newName = (HgfsFileNameV3 *)(requestV3->oldName.name + 1 + *cpOldNameLen); extra -= *cpOldNameLen; } if (!HgfsUnpackFileNameV3(newName, extra, &useHandle, cpNewName, cpNewNameLen, targetFile, newCaseFlags)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } if (useHandle) { *hints |= HGFS_RENAME_HINT_USE_TARGETFILE_DESC; } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackRenamePayloadV2 -- * * Unpack hgfs rename request V2 payload and initialize a corresponding * HgfsHandle or file name to tell us which to delete. Hints * holds flags to specify a handle or name for the file or * directory to rename. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackRenamePayloadV2(HgfsRequestRenameV2 *requestV2, // IN: request payload size_t payloadSize, // IN: payload size char **cpOldName, // OUT: rename src size_t *cpOldNameLen, // OUT: rename src size char **cpNewName, // OUT: rename dst size_t *cpNewNameLen, // OUT: rename dst size HgfsRenameHint *hints, // OUT: rename hints HgfsHandle *srcFile, // OUT: src file handle HgfsHandle *targetFile) // OUT: target file handle { HgfsFileName *newName; size_t extra; /* Enforced by the dispatch function. */ if (payloadSize < sizeof *requestV2) { LOG(4, ("%s: HGFS packet too small\n", __FUNCTION__)); return FALSE; } extra = payloadSize - sizeof *requestV2; *hints = requestV2->hints; /* * If we've been asked to reuse a handle, we don't need to look at, let * alone test the filename or its length. This applies to the source * and the target. */ if (*hints & HGFS_RENAME_HINT_USE_SRCFILE_DESC) { *srcFile = requestV2->srcFile; *cpOldName = NULL; *cpOldNameLen = 0; } else { if (!HgfsUnpackFileName(&requestV2->oldName, extra, cpOldName, cpOldNameLen)) { LOG(4, ("%s: Error decoding HGFS packet - not enough room for file name\n", __FUNCTION__)); return FALSE; } extra -= *cpOldNameLen; } if (*hints & HGFS_RENAME_HINT_USE_TARGETFILE_DESC) { *targetFile = requestV2->targetFile; *cpNewName = NULL; *cpNewNameLen = 0; } else { newName = (HgfsFileName *)((char *)(&requestV2->oldName + 1) + *cpOldNameLen); if (!HgfsUnpackFileName(newName, extra, cpNewName, cpNewNameLen)) { LOG(4, ("%s: Error decoding HGFS packet - not enough room for file name\n", __FUNCTION__)); return FALSE; } } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackRenamePayloadV1 -- * * Unpack hgfs rename request V1 payload and initialize a corresponding * old and new file names. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackRenamePayloadV1(HgfsRequestRename *requestV1, // IN: request payload size_t payloadSize, // IN: payload size char **cpOldName, // OUT: rename src size_t *cpOldNameLen, // OUT: rename src size char **cpNewName, // OUT: rename dst size_t *cpNewNameLen) // OUT: rename dst size { HgfsFileName *newName; uint32 extra; if (payloadSize < sizeof *requestV1) { return FALSE; } extra = payloadSize - sizeof *requestV1; if (!HgfsUnpackFileName(&requestV1->oldName, extra, cpOldName, cpOldNameLen)) { LOG(4, ("%s: Error decoding HGFS packet - not enough room for file name\n", __FUNCTION__)); return FALSE; } extra -= requestV1->oldName.length; newName = (HgfsFileName *)((char *)(&requestV1->oldName + 1) + requestV1->oldName.length); return HgfsUnpackFileName(newName, extra, cpNewName, cpNewNameLen); } /* *----------------------------------------------------------------------------- * * HgfsUnpackRenameRequest -- * * Unpack hgfs rename request and initialize a corresponding * HgfsHandle or file name to tell us which to rename. Hints * holds flags to specify a handle or name for the file or * directory to rename. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackRenameRequest(void const *packet, // IN: HGFS packet size_t packetSize, // IN: request packet size HgfsOp op, // IN: requested operation char **cpOldName, // OUT: rename src size_t *cpOldNameLen, // OUT: rename src size char **cpNewName, // OUT: rename dst size_t *cpNewNameLen, // OUT: rename dst size HgfsRenameHint *hints, // OUT: rename hints HgfsHandle *srcFile, // OUT: src file handle HgfsHandle *targetFile, // OUT: target file handle uint32 *oldCaseFlags, // OUT: source case-sensitivity flags uint32 *newCaseFlags) // OUT: dest. case-sensitivity flags { ASSERT(packet); ASSERT(cpOldName); ASSERT(cpOldNameLen); ASSERT(cpNewName); ASSERT(cpNewNameLen); ASSERT(srcFile); ASSERT(targetFile); ASSERT(hints); ASSERT(oldCaseFlags); ASSERT(newCaseFlags); /* Default values for legacy requests. */ *oldCaseFlags = HGFS_FILE_NAME_DEFAULT_CASE; *newCaseFlags = HGFS_FILE_NAME_DEFAULT_CASE; *hints = 0; switch (op) { case HGFS_OP_RENAME_V3: { HgfsRequestRenameV3 *requestV3 = (HgfsRequestRenameV3 *)packet; if (!HgfsUnpackRenamePayloadV3(requestV3, packetSize, cpOldName, cpOldNameLen, cpNewName, cpNewNameLen, hints, srcFile, targetFile, oldCaseFlags, newCaseFlags)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } case HGFS_OP_RENAME_V2: { HgfsRequestRenameV2 *requestV2 = (HgfsRequestRenameV2 *)packet; if (!HgfsUnpackRenamePayloadV2(requestV2, packetSize, cpOldName, cpOldNameLen, cpNewName, cpNewNameLen, hints, srcFile, targetFile)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } case HGFS_OP_RENAME: { HgfsRequestRename *requestV1 = (HgfsRequestRename *)packet; if (!HgfsUnpackRenamePayloadV1(requestV1, packetSize, cpOldName, cpOldNameLen, cpNewName, cpNewNameLen)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } default: LOG(4, ("%s: Invalid opcode %d\n", __FUNCTION__, op)); NOT_REACHED(); return FALSE; } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsPackRenameReply -- * * Pack hgfs rename reply. * Since the structure of the rename reply packet hasn't changed in * version 2 of the protocol, HgfsReplyRenameV2 is identical to * HgfsReplyRename. So use HgfsReplyRename type to access packetIn to * keep the code simple. * * Results: * TRUE if valid op and reply set, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackRenameReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: requested operation size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session) // IN: Session info { Bool result; HGFS_ASSERT_PACK_PARAMS; *payloadSize = 0; switch (op) { case HGFS_OP_RENAME_V3: { HgfsReplyRenameV3 *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { /* Reply consists of only a reserved field. */ reply->reserved = 0; *payloadSize = sizeof *reply; } break; } case HGFS_OP_RENAME_V2: case HGFS_OP_RENAME: { HgfsReplyRename *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { *payloadSize = sizeof *reply; } break; } default: LOG(4, ("%s: invalid op code %d\n", __FUNCTION__, op)); result = FALSE; NOT_REACHED(); } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackGetattrPayloadV3 -- * * Unpack hgfs get attr request V3 payload and initialize a corresponding * HgfsHandle or file name to tell us which file to get attributes. Hints * holds flags to specify a handle or name for the file or * directory to get attributes. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackGetattrPayloadV3(HgfsRequestGetattrV3 *requestV3,// IN: request payload size_t payloadSize, // IN: payload size char **cpName, // OUT: cpName size_t *cpNameSize, // OUT: cpName size HgfsAttrHint *hints, // OUT: getattr hints HgfsHandle *file, // OUT: file handle uint32 *caseFlags) // OUT: case-sensitivity flags { Bool result; Bool useHandle; if (payloadSize < sizeof *requestV3) { return FALSE; } *hints = requestV3->hints; result = HgfsUnpackFileNameV3(&requestV3->fileName, payloadSize - sizeof *requestV3, &useHandle, cpName, cpNameSize, file, caseFlags); if (useHandle) { *hints |= HGFS_ATTR_HINT_USE_FILE_DESC; } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackGetattrPayloadV2 -- * * Unpack hgfs Getattr request V2 payload and initialize a corresponding * HgfsHandle or file name to tell us which to get attributes. Hints * holds flags to specify a handle or name for the file or * directory to get attributes. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackGetattrPayloadV2(HgfsRequestGetattrV2 *requestV2,// IN: request payload size_t payloadSize, // IN: payload size char **cpName, // OUT: cpName size_t *cpNameSize, // OUT: cpName size HgfsAttrHint *hints, // OUT: delete hints HgfsHandle *file) // OUT: file handle { Bool result = TRUE; if (payloadSize < sizeof *requestV2) { return FALSE; } *file = HGFS_INVALID_HANDLE; *hints = requestV2->hints; /* * If we've been asked to reuse a handle, we don't need to look at, let * alone test the filename or its length. */ if (requestV2->hints & HGFS_ATTR_HINT_USE_FILE_DESC) { *file = requestV2->file; *cpName = NULL; *cpNameSize = 0; } else { result = HgfsUnpackFileName(&requestV2->fileName, payloadSize - sizeof *requestV2, cpName, cpNameSize); } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackGetattrPayloadV1 -- * * Unpack hgfs getattr request V1 payload and initialize a corresponding * file name to tell us which to get attributes. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackGetattrPayloadV1(HgfsRequestGetattr *requestV1, // IN: request payload size_t payloadSize, // IN: payload size char **cpName, // OUT: cpName size_t *cpNameSize) // OUT: cpName size { return HgfsUnpackFileName(&requestV1->fileName, payloadSize - sizeof *requestV1, cpName, cpNameSize); } /* *----------------------------------------------------------------------------- * * HgfsPackAttrV2 -- * * Packs attr version 2 reply structure. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsPackAttrV2(HgfsFileAttrInfo *attr, // IN: attr stucture HgfsAttrV2 *attr2) // OUT: attr in payload { attr2->mask = attr->mask; attr2->type = attr->type; attr2->size = attr->size; attr2->creationTime = attr->creationTime; attr2->accessTime = attr->accessTime; attr2->writeTime = attr->writeTime; attr2->attrChangeTime = attr->attrChangeTime; attr2->specialPerms = attr->specialPerms; attr2->ownerPerms = attr->ownerPerms; attr2->groupPerms = attr->groupPerms; attr2->otherPerms = attr->otherPerms; attr2->flags = attr->flags; attr2->allocationSize = attr->allocationSize; attr2->userId = attr->userId; attr2->groupId = attr->groupId; attr2->hostFileId = attr->hostFileId; attr2->volumeId = attr->volumeId; attr2->effectivePerms = attr->effectivePerms; } /* *----------------------------------------------------------------------------- * * HgfsUnpackAttrV2 -- * * Unpacks attr version 2 reply structure. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsUnpackAttrV2(HgfsAttrV2 *attr2, // IN: attr in payload HgfsFileAttrInfo *attr) // OUT: attr stucture { attr->mask = attr2->mask; attr->type = attr2->type; attr->size = attr2->size; attr->creationTime = attr2->creationTime; attr->accessTime = attr2->accessTime; attr->writeTime = attr2->writeTime; attr->attrChangeTime = attr2->attrChangeTime; attr->specialPerms = attr2->specialPerms; attr->ownerPerms = attr2->ownerPerms; attr->groupPerms = attr2->groupPerms; attr->otherPerms = attr2->otherPerms; attr->flags = attr2->flags; attr->allocationSize = attr2->allocationSize; attr->userId = attr2->userId; attr->groupId = attr2->groupId; attr->hostFileId = attr2->hostFileId; attr->volumeId = attr2->volumeId; attr->effectivePerms = attr2->effectivePerms; } /* *----------------------------------------------------------------------------- * * HgfsInitFileAttr -- * * Initializes HgfsFileAttrInfo structure. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsInitFileAttr(HgfsOp op, // IN: request type HgfsFileAttrInfo *attr) // OUT: attr stucture { /* Initialize all fields with 0. */ memset(attr, 0, sizeof *attr); /* Explicitly initialize fields which need it. */ attr->requestType = op; attr->mask = HGFS_ATTR_VALID_NONE; } /* *----------------------------------------------------------------------------- * * HgfsPackGetattrReplyPayloadV3 -- * * Packs Getattr V3 reply payload. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsPackGetattrReplyPayloadV3(HgfsFileAttrInfo *attr, // IN: attr stucture const char *utf8TargetName, // IN: optional target name uint32 utf8TargetNameLen, // IN: file name length HgfsReplyGetattrV3 *reply) // OUT: payload { LOG(4, ("%s: attr type: %u\n", __FUNCTION__, reply->attr.type)); HgfsPackAttrV2(attr, &reply->attr); reply->reserved = 0; if (utf8TargetName) { memcpy(reply->symlinkTarget.name, utf8TargetName, utf8TargetNameLen); CPNameLite_ConvertTo(reply->symlinkTarget.name, utf8TargetNameLen, DIRSEPC); } else { ASSERT(utf8TargetNameLen == 0); } reply->symlinkTarget.length = utf8TargetNameLen; reply->symlinkTarget.name[utf8TargetNameLen] = '\0'; reply->symlinkTarget.flags = 0; reply->symlinkTarget.fid = 0; reply->symlinkTarget.caseType = HGFS_FILE_NAME_DEFAULT_CASE; } /* *----------------------------------------------------------------------------- * * HgfsPackGetattrReplyPayloadV2 -- * * Packs rename reply payload V2 requests. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsPackGetattrReplyPayloadV2(HgfsFileAttrInfo *attr, // IN: attr stucture const char *utf8TargetName, // IN: optional target name uint32 utf8TargetNameLen, // IN: file name length HgfsReplyGetattrV2 *reply) // OUT: payload { HgfsPackAttrV2(attr, &reply->attr); if (utf8TargetName) { memcpy(reply->symlinkTarget.name, utf8TargetName, utf8TargetNameLen); CPNameLite_ConvertTo(reply->symlinkTarget.name, utf8TargetNameLen, DIRSEPC); } else { ASSERT(utf8TargetNameLen == 0); } reply->symlinkTarget.length = utf8TargetNameLen; reply->symlinkTarget.name[utf8TargetNameLen] = '\0'; } /* *----------------------------------------------------------------------------- * * HgfsPackGetattrReplyPayloadV1 -- * * Packs rename reply payload for V1 requests. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsPackGetattrReplyPayloadV1(HgfsFileAttrInfo *attr, // IN: attr stucture HgfsReplyGetattr *reply) // OUT: reply info { /* In GetattrV1, symlinks are treated as regular files. */ if (attr->type == HGFS_FILE_TYPE_SYMLINK) { reply->attr.type = HGFS_FILE_TYPE_REGULAR; } else { reply->attr.type = attr->type; } reply->attr.size = attr->size; reply->attr.creationTime = attr->creationTime; reply->attr.accessTime = attr->accessTime; reply->attr.writeTime = attr->writeTime; reply->attr.attrChangeTime = attr->attrChangeTime; reply->attr.permissions = attr->ownerPerms; } /* *----------------------------------------------------------------------------- * * HgfsUnpackGetattrRequest -- * * Unpack hgfs getattr request and initialize a corresponding * HgfsFileAttrInfo structure that is used to pass around getattr request * information. * * Since the structure of the get attributes request packet hasn't changed * in version 2 of the protocol, HgfsRequestGetattrV2 is identical to * HgfsRequestGetattr. So use HgfsRequestGetattr type to access packetIn to * keep the code simple. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackGetattrRequest(void const *packet, // IN: HGFS packet size_t packetSize, // IN: request packet size HgfsOp op, // IN request type HgfsFileAttrInfo *attrInfo, // IN/OUT: getattr info HgfsAttrHint *hints, // OUT: getattr hints char **cpName, // OUT: cpName size_t *cpNameSize, // OUT: cpName size HgfsHandle *file, // OUT: file handle uint32 *caseType) // OUT: case-sensitivity flags { ASSERT(packet); ASSERT(attrInfo); ASSERT(cpName); ASSERT(cpNameSize); ASSERT(file); ASSERT(caseType); HgfsInitFileAttr(op, attrInfo); /* Default values for legacy requests. */ *caseType = HGFS_FILE_NAME_DEFAULT_CASE; *hints = 0; *file = HGFS_INVALID_HANDLE; switch (op) { case HGFS_OP_GETATTR_V3: { HgfsRequestGetattrV3 *requestV3 = (HgfsRequestGetattrV3 *)packet; if (!HgfsUnpackGetattrPayloadV3(requestV3, packetSize, cpName, cpNameSize, hints, file, caseType)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } LOG(4, ("%s: HGFS_OP_GETATTR_V3: %u\n", __FUNCTION__, *caseType)); break; } case HGFS_OP_GETATTR_V2: { HgfsRequestGetattrV2 *requestV2 = (HgfsRequestGetattrV2 *)packet; if (!HgfsUnpackGetattrPayloadV2(requestV2, packetSize, cpName, cpNameSize, hints, file)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } case HGFS_OP_GETATTR: { HgfsRequestGetattr *requestV1 = (HgfsRequestGetattr *)packet; if (!HgfsUnpackGetattrPayloadV1(requestV1, packetSize, cpName, cpNameSize)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } default: return FALSE; } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsPackGetattrReply -- * * Pack hgfs getattr reply to the HgfsReplyGetattr structure. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackGetattrReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsFileAttrInfo *attr, // IN: attr stucture const char *utf8TargetName, // IN: optional target name uint32 utf8TargetNameLen, // IN: file name length size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session) // IN: Session info { Bool result; HGFS_ASSERT_PACK_PARAMS; *payloadSize = 0; switch (attr->requestType) { case HGFS_OP_GETATTR_V3: { HgfsReplyGetattrV3 *reply; *payloadSize = sizeof *reply + utf8TargetNameLen; result = HgfsAllocInitReply(packet, packetHeader, *payloadSize, (void **)&reply, session); if (result) { HgfsPackGetattrReplyPayloadV3(attr, utf8TargetName, utf8TargetNameLen, reply); } break; } case HGFS_OP_GETATTR_V2: { HgfsReplyGetattrV2 *reply; *payloadSize = sizeof *reply + utf8TargetNameLen; result = HgfsAllocInitReply(packet, packetHeader, *payloadSize, (void **)&reply, session); if (result) { HgfsPackGetattrReplyPayloadV2(attr, utf8TargetName, utf8TargetNameLen, reply); } break; } case HGFS_OP_GETATTR: { HgfsReplyGetattr *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { HgfsPackGetattrReplyPayloadV1(attr, reply); *payloadSize = sizeof *reply; } break; } default: LOG(4, ("%s: Invalid GetAttr op.\n", __FUNCTION__)); NOT_REACHED(); result = FALSE; } return result; } /* *----------------------------------------------------------------------------- * * HgfsPackSearchReadReplyHeaderV4 -- * * Packs SearchRead V4 reply header part for all entry records returned. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsPackSearchReadReplyHeaderV4(HgfsSearchReadInfo *info, // IN: reply info HgfsReplySearchReadV4 *reply, // OUT: payload size_t *headerSize) // OUT: size written { reply->numberEntriesReturned = info->numberRecordsWritten; reply->offsetToContinue = info->currentIndex; reply->flags = info->replyFlags; reply->reserved = 0; *headerSize = offsetof(HgfsReplySearchReadV4, entries); } /* *----------------------------------------------------------------------------- * * HgfsPackSearchReadReplyRecordV4 -- * * Packs SearchRead V4 reply record. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsPackSearchReadReplyRecordV4(HgfsSearchReadEntry *entry, // IN: entry info HgfsDirEntryV4 *replylastEntry, // IN/OUT: payload HgfsDirEntryV4 *replyCurrentEntry) // OUT: reply buffer for dirent { HgfsFileAttrInfo *attr = &entry->attr; memset(replyCurrentEntry, 0, sizeof *replyCurrentEntry); if (NULL != replylastEntry) { replylastEntry->nextEntryOffset = ((char*)replyCurrentEntry - (char*)replylastEntry); } /* Set the valid data mask for the entry. */ replyCurrentEntry->mask = entry->mask; if (0 != (entry->mask & HGFS_SEARCH_READ_NAME)) { replyCurrentEntry->nextEntryOffset = 0; replyCurrentEntry->fileIndex = entry->fileIndex; if (0 != (replyCurrentEntry->mask & HGFS_SEARCH_READ_FILE_NODE_TYPE)) { replyCurrentEntry->fileType = attr->type; } if (0 != (entry->mask & HGFS_SEARCH_READ_FILE_SIZE)) { replyCurrentEntry->fileSize = attr->size; } if (0 != (entry->mask & HGFS_SEARCH_READ_ALLOCATION_SIZE)) { replyCurrentEntry->allocationSize = attr->allocationSize; } if (0 != (entry->mask & HGFS_SEARCH_READ_TIME_STAMP)) { replyCurrentEntry->creationTime = attr->creationTime; replyCurrentEntry->accessTime = attr->accessTime; replyCurrentEntry->writeTime = attr->writeTime; replyCurrentEntry->attrChangeTime = attr->attrChangeTime; } if (0 != (entry->mask & HGFS_SEARCH_READ_FILE_ATTRIBUTES)) { replyCurrentEntry->attrFlags = attr->flags; } if (0 != (entry->mask & HGFS_SEARCH_READ_FILE_ID)) { replyCurrentEntry->hostFileId = attr->hostFileId; } if (0 != (entry->mask & HGFS_SEARCH_READ_EA_SIZE)) { replyCurrentEntry->eaSize = attr->eaSize; } if (0 != (entry->mask & HGFS_SEARCH_READ_REPARSE_TAG)) { replyCurrentEntry->reparseTag = attr->reparseTag; } if (0 != (entry->mask & HGFS_SEARCH_READ_SHORT_NAME)) { ASSERT(attr->shortName.length > 0); memcpy(replyCurrentEntry->shortName.name, attr->shortName.name, attr->shortName.length); replyCurrentEntry->shortName.length = attr->shortName.length; } memcpy(replyCurrentEntry->fileName.name, entry->name, entry->nameLength); replyCurrentEntry->fileName.name[entry->nameLength] = 0; replyCurrentEntry->fileName.length = entry->nameLength; replyCurrentEntry->reserved = 0; } } /* *----------------------------------------------------------------------------- * * HgfsPackSearchReadReplyHeaderV3 -- * * Packs SearchRead V3 reply record. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsPackSearchReadReplyHeaderV3(HgfsSearchReadInfo *info, // IN: reply info HgfsReplySearchReadV3 *reply, // OUT: payload size_t *headerSize) // OUT: size written { ASSERT(info->numberRecordsWritten <= 1 && 0 != (info->flags & HGFS_SEARCH_READ_SINGLE_ENTRY)); reply->count = info->numberRecordsWritten; reply->reserved = 0; /* * Previous shipping tools expect to account for a whole reply, * which is not strictly correct, but we are stuck with it. */ *headerSize = sizeof *reply; } /* *----------------------------------------------------------------------------- * * HgfsPackSearchReadReplyRecordV3 -- * * Packs SearchRead V3 reply record. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsPackSearchReadReplyRecordV3(HgfsFileAttrInfo *attr, // IN: attr stucture const char *utf8Name, // IN: file name uint32 utf8NameLen, // IN: file name length HgfsDirEntry *replyDirent) // OUT: reply buffer for dirent { replyDirent->fileName.length = (uint32)utf8NameLen; replyDirent->fileName.flags = 0; replyDirent->fileName.fid = 0; replyDirent->fileName.caseType = HGFS_FILE_NAME_DEFAULT_CASE; replyDirent->nextEntry = 0; if (utf8NameLen != 0) { memcpy(replyDirent->fileName.name, utf8Name, utf8NameLen); replyDirent->fileName.name[utf8NameLen] = 0; HgfsPackAttrV2(attr, &replyDirent->attr); } } /* *----------------------------------------------------------------------------- * * HgfsPackSearchReadReplyHeaderV2 -- * * Packs SearchRead V2 reply header (common) part for all records. * V2 replies only contain a single record, so there is nothing to do here. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsPackSearchReadReplyHeaderV2(HgfsSearchReadInfo *info, // IN: unused HgfsReplySearchReadV2 *reply, // OUT: unused size_t *headerSize) // OUT: size written { /* The header has already been accounted for. */ *headerSize = sizeof *reply; } /* *----------------------------------------------------------------------------- * * HgfsPackSearchReadReplyRecordV2 -- * * Packs SearchRead V2 reply record. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsPackSearchReadReplyRecordV2(HgfsFileAttrInfo *attr, // IN: attr stucture const char *utf8Name, // IN: file name uint32 utf8NameLen, // IN: file name length HgfsReplySearchReadV2 *reply) // OUT: reply buffer { reply->fileName.length = (uint32)utf8NameLen; if (utf8NameLen != 0) { memcpy(reply->fileName.name, utf8Name, utf8NameLen); reply->fileName.name[utf8NameLen] = 0; HgfsPackAttrV2(attr, &reply->attr); } } /* *----------------------------------------------------------------------------- * * HgfsPackSearchReadReplyHeaderV1 -- * * Packs SearchRead V1 reply header (common) part for all records. * V1 replies only contain a single record, so there is nothing to do here. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsPackSearchReadReplyHeaderV1(HgfsSearchReadInfo *info, // IN: unused HgfsReplySearchRead *reply, // OUT: unused size_t *headerSize) // OUT: size written { /* The header has already been accounted for. */ *headerSize = sizeof *reply; } /* *----------------------------------------------------------------------------- * * HgfsPackSearchReadReplyRecordV1 -- * * Packs SearchRead V1 reply record. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsPackSearchReadReplyRecordV1(HgfsFileAttrInfo *attr, // IN: attr stucture const char *utf8Name, // IN: file name uint32 utf8NameLen, // IN: file name length HgfsReplySearchRead *reply) // OUT: reply buffer { reply->fileName.length = (uint32)utf8NameLen; if (utf8NameLen != 0) { memcpy(reply->fileName.name, utf8Name, utf8NameLen); reply->fileName.name[utf8NameLen] = 0; /* In SearchReadV1, symlinks are treated as regular files. */ if (attr->type == HGFS_FILE_TYPE_SYMLINK) { reply->attr.type = HGFS_FILE_TYPE_REGULAR; } else { reply->attr.type = attr->type; } reply->attr.size = attr->size; reply->attr.creationTime = attr->creationTime; reply->attr.accessTime = attr->accessTime; reply->attr.writeTime = attr->writeTime; reply->attr.attrChangeTime = attr->attrChangeTime; reply->attr.permissions = attr->ownerPerms; } } /* *----------------------------------------------------------------------------- * * HgfsUnpackSearchReadRequest -- * * Unpack hgfs search read request and initialize a corresponding * HgfsFileAttrInfo structure that is used to pass around attribute * information. * * Since the structure of the search read request packet hasn't changed in * version 2 of the protocol, HgfsRequestSearchReadV2 is identical to * HgfsRequestSearchRead. So use HgfsRequestSearchRead type to access * packetIn to keep the code simple. * * Results: * Always TRUE. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackSearchReadRequest(const void *packet, // IN: request packet size_t packetSize, // IN: packet size HgfsOp op, // IN: reqest type HgfsSearchReadInfo *info, // OUT: search info size_t *baseReplySize, // OUT: op base reply size size_t *inlineReplyDataSize, // OUT: size of inline reply data HgfsHandle *hgfsSearchHandle) // OUT: hgfs search handle { Bool result = TRUE; uint32 *startIndex; HgfsSearchReadMask *mask; HgfsSearchReadFlags *flags; size_t *replyPayloadSize; ASSERT(packet); ASSERT(info); ASSERT(baseReplySize); ASSERT(inlineReplyDataSize); ASSERT(hgfsSearchHandle); info->requestType = op; info->searchPattern = NULL; startIndex = &info->startIndex; replyPayloadSize = &info->payloadSize; mask = &info->requestedMask; flags = &info->flags; *mask = 0; *flags = 0; switch (op) { case HGFS_OP_SEARCH_READ_V4: { HgfsRequestSearchReadV4 *request = (HgfsRequestSearchReadV4 *)packet; /* Enforced by the dispatch function. */ ASSERT(packetSize >= sizeof *request); if (0 != (request->flags & HGFS_SEARCH_READ_FID_OPEN_V4)) { /* * XXX - When this is implemented, the handle will get us a node, * (of directory type) and then with the node, we can look up a * search handle, if the data is cached in the search array. */ NOT_IMPLEMENTED(); } *hgfsSearchHandle = request->fid; *startIndex = request->restartIndex; *mask = request->mask; *flags = request->flags; *baseReplySize = offsetof(HgfsReplySearchReadV4, entries); *replyPayloadSize = request->replyDirEntryMaxSize; *inlineReplyDataSize = 0; ASSERT(*replyPayloadSize > 0); LOG(4, ("%s: HGFS_OP_SEARCH_READ_V4\n", __FUNCTION__)); break; } case HGFS_OP_SEARCH_READ_V3: { HgfsRequestSearchReadV3 *request = (HgfsRequestSearchReadV3 *)packet; /* Enforced by the dispatch function. */ ASSERT(packetSize >= sizeof *request); *hgfsSearchHandle = request->search; *startIndex = request->offset; *flags = HGFS_SEARCH_READ_SINGLE_ENTRY; *mask = (HGFS_SEARCH_READ_FILE_NODE_TYPE | HGFS_SEARCH_READ_NAME | HGFS_SEARCH_READ_FILE_SIZE | HGFS_SEARCH_READ_TIME_STAMP | HGFS_SEARCH_READ_FILE_ATTRIBUTES | HGFS_SEARCH_READ_FILE_ID); *baseReplySize = offsetof(HgfsReplySearchReadV3, payload); *replyPayloadSize = HGFS_PACKET_MAX - *baseReplySize; *inlineReplyDataSize = *replyPayloadSize; LOG(4, ("%s: HGFS_OP_SEARCH_READ_V3\n", __FUNCTION__)); break; } case HGFS_OP_SEARCH_READ_V2: /* * Currently, the HgfsRequestSearchReadV2 is the same as * HgfsRequestSearchRead, so drop through. */ case HGFS_OP_SEARCH_READ: { HgfsRequestSearchRead *request = (HgfsRequestSearchRead *)packet; /* Enforced by the dispatch function. */ ASSERT(packetSize >= sizeof *request); *hgfsSearchHandle = request->search; *startIndex = request->offset; *flags = HGFS_SEARCH_READ_SINGLE_ENTRY; *mask = (HGFS_SEARCH_READ_FILE_NODE_TYPE | HGFS_SEARCH_READ_NAME | HGFS_SEARCH_READ_FILE_SIZE | HGFS_SEARCH_READ_TIME_STAMP | HGFS_SEARCH_READ_FILE_ATTRIBUTES); *baseReplySize = 0; *replyPayloadSize = HGFS_PACKET_MAX; *inlineReplyDataSize = *replyPayloadSize; break; } default: /* Should never occur. */ NOT_REACHED(); result = FALSE; Log("%s: ERROR Invalid OP %u\n", __FUNCTION__, op); break; } ASSERT(result); return result; } /* *----------------------------------------------------------------------------- * * HgfsPackSearchReadReplyRecord -- * * Pack hgfs search read reply record to the current entry record. * If the last record is not NULL then update its offset to the current * entry field. * * Results: * TRUE on success and number of bytes written in replyRecordSize. * FALSE on failure, nothing written. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackSearchReadReplyRecord(HgfsOp requestType, // IN: search read request HgfsSearchReadEntry *entry, // IN: entry info size_t bytesRemaining, // IN: space in bytes for record void *lastSearchReadRecord, // IN/OUT: last packed entry void *currentSearchReadRecord,// OUT: currrent entry to pack size_t *replyRecordSize) // OUT: size of packet { Bool result = TRUE; size_t recordSize = 0; switch (requestType) { case HGFS_OP_SEARCH_READ_V4: { HgfsDirEntryV4 *replyCurrentEntry = currentSearchReadRecord; HgfsDirEntryV4 *replyLastEntry = lastSearchReadRecord; /* Skip the final empty record, it is not needed for V4.*/ if (0 == entry->nameLength) { break; } recordSize = offsetof(HgfsDirEntryV4, fileName.name) + entry->nameLength + 1; if (recordSize > bytesRemaining) { result = FALSE; break; } HgfsPackSearchReadReplyRecordV4(entry, replyLastEntry, replyCurrentEntry); break; } case HGFS_OP_SEARCH_READ_V3: { HgfsDirEntry *replyCurrentEntry = currentSearchReadRecord; /* * Previous shipping tools expect to account for a whole reply, * which is not strictly correct, it should be using * offsetof(HgfsDirEntry, fileName.name) + entry->nameLength + 1 * but we are stuck with it. */ recordSize = sizeof *replyCurrentEntry + entry->nameLength; if (recordSize > bytesRemaining) { result = FALSE; break; } HgfsPackSearchReadReplyRecordV3(&entry->attr, entry->name, entry->nameLength, replyCurrentEntry); break; } case HGFS_OP_SEARCH_READ_V2: { HgfsReplySearchReadV2 *replyV2 = currentSearchReadRecord; /* We have already accounted for the fixed part of the record. */ recordSize = entry->nameLength; if (recordSize > bytesRemaining) { result = FALSE; break; } HgfsPackSearchReadReplyRecordV2(&entry->attr, entry->name, entry->nameLength, replyV2); break; } case HGFS_OP_SEARCH_READ: { HgfsReplySearchRead *replyV1 = currentSearchReadRecord; /* We have already accounted for the fixed part of the record. */ recordSize = entry->nameLength; if (recordSize > bytesRemaining) { result = FALSE; break; } HgfsPackSearchReadReplyRecordV1(&entry->attr, entry->name, entry->nameLength, replyV1); break; } default: { Log("%s: Invalid SearchRead Op.", __FUNCTION__); NOT_REACHED(); result = FALSE; } } if (result) { *replyRecordSize = recordSize; } return result; } /* *----------------------------------------------------------------------------- * * HgfsPackSearchReadReplyHeader -- * * Pack hgfs search read reply header (common) part to all the * entries returned in the search read reply. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackSearchReadReplyHeader(HgfsSearchReadInfo *info, // IN: request info size_t *payloadSize) // OUT: size of packet { Bool result = TRUE; *payloadSize = 0; switch (info->requestType) { case HGFS_OP_SEARCH_READ_V4: { HgfsReplySearchReadV4 *reply = info->reply; HgfsPackSearchReadReplyHeaderV4(info, reply, payloadSize); break; } case HGFS_OP_SEARCH_READ_V3: { HgfsReplySearchReadV3 *reply = info->reply; HgfsPackSearchReadReplyHeaderV3(info, reply, payloadSize); break; } case HGFS_OP_SEARCH_READ_V2: { HgfsReplySearchReadV2 *reply = info->reply; HgfsPackSearchReadReplyHeaderV2(info, reply, payloadSize); break; } case HGFS_OP_SEARCH_READ: { HgfsReplySearchRead *reply = info->reply; HgfsPackSearchReadReplyHeaderV1(info, reply, payloadSize); break; } default: { LOG(4, ("%s: Invalid SearchRead Op.", __FUNCTION__)); NOT_REACHED(); result = FALSE; } } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackSetattrPayloadV3 -- * * Unpack hgfs set attr request V3 payload and initialize a corresponding * HgfsHandle or file name to tell us which file to set attributes. Hints * holds flags to specify a handle or name for the file or * directory to set attributes. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackSetattrPayloadV3(HgfsRequestSetattrV3 *requestV3,// IN: request payload size_t payloadSize, // IN: payload size HgfsFileAttrInfo *attr, // OUT: setattr info char **cpName, // OUT: cpName size_t *cpNameSize, // OUT: cpName size HgfsAttrHint *hints, // OUT: getattr hints HgfsHandle *file, // OUT: file handle uint32 *caseFlags) // OUT: case-sensitivity flags { Bool result; Bool useHandle; if (payloadSize < sizeof *requestV3) { return FALSE; } *hints = requestV3->hints; HgfsUnpackAttrV2(&requestV3->attr, attr); result = HgfsUnpackFileNameV3(&requestV3->fileName, payloadSize - sizeof *requestV3, &useHandle, cpName, cpNameSize, file, caseFlags); if (useHandle) { *hints |= HGFS_ATTR_HINT_USE_FILE_DESC; } LOG(4, ("%s: unpacking HGFS_OP_SETATTR_V3, %u\n", __FUNCTION__, *caseFlags)); return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackSetattrPayloadV2 -- * * Unpack hgfs Setattr request V2 payload and initialize a corresponding * HgfsHandle or file name to tell us which to set attributes. Hints * holds flags to specify a handle or name for the file or * directory to set attributes. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackSetattrPayloadV2(HgfsRequestSetattrV2 *requestV2,// IN: request payload size_t payloadSize, // IN: payload size HgfsFileAttrInfo *attr, // OUT: setattr info char **cpName, // OUT: cpName size_t *cpNameSize, // OUT: cpName size HgfsAttrHint *hints, // OUT: delete hints HgfsHandle *file) // OUT: file handle { Bool result = TRUE; /* Enforced by the dispatch function. */ if (payloadSize < sizeof *requestV2) { return FALSE; } LOG(4, ("%s: unpacking HGFS_OP_SETATTR_V2\n", __FUNCTION__)); *file = HGFS_INVALID_HANDLE; *hints = requestV2->hints; HgfsUnpackAttrV2(&requestV2->attr, attr); if (requestV2->hints & HGFS_ATTR_HINT_USE_FILE_DESC) { *file = requestV2->file; *cpName = NULL; *cpNameSize = 0; } else { result = HgfsUnpackFileName(&requestV2->fileName, payloadSize - sizeof *requestV2, cpName, cpNameSize); } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackSetattrPayloadV1 -- * * Unpack hgfs setattr request V1 payload and initialize a corresponding * file name to tell us which to set attributes. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackSetattrPayloadV1(HgfsRequestSetattr *requestV1, // IN: request payload size_t payloadSize, // IN: payload size HgfsFileAttrInfo *attr, // OUT: setattr info char **cpName, // OUT: cpName size_t *cpNameSize, // OUT: cpName size HgfsAttrHint *hints) // OUT: setattr hints { LOG(4, ("%s: unpacking HGFS_OP_SETATTR\n", __FUNCTION__)); attr->mask = 0; attr->mask |= requestV1->update & HGFS_ATTR_SIZE ? HGFS_ATTR_VALID_SIZE : 0; attr->mask |= requestV1->update & HGFS_ATTR_CREATE_TIME ? HGFS_ATTR_VALID_CREATE_TIME : 0; attr->mask |= requestV1->update & HGFS_ATTR_ACCESS_TIME ? HGFS_ATTR_VALID_ACCESS_TIME : 0; attr->mask |= requestV1->update & HGFS_ATTR_WRITE_TIME ? HGFS_ATTR_VALID_WRITE_TIME : 0; attr->mask |= requestV1->update & HGFS_ATTR_CHANGE_TIME ? HGFS_ATTR_VALID_CHANGE_TIME : 0; attr->mask |= requestV1->update & HGFS_ATTR_PERMISSIONS ? HGFS_ATTR_VALID_OWNER_PERMS : 0; *hints |= requestV1->update & HGFS_ATTR_ACCESS_TIME_SET ? HGFS_ATTR_HINT_SET_ACCESS_TIME : 0; *hints |= requestV1->update & HGFS_ATTR_WRITE_TIME_SET ? HGFS_ATTR_HINT_SET_WRITE_TIME : 0; attr->type = requestV1->attr.type; attr->size = requestV1->attr.size; attr->creationTime = requestV1->attr.creationTime; attr->accessTime = requestV1->attr.accessTime; attr->writeTime = requestV1->attr.writeTime; attr->attrChangeTime = requestV1->attr.attrChangeTime; attr->ownerPerms = requestV1->attr.permissions; return HgfsUnpackFileName(&requestV1->fileName, payloadSize - sizeof *requestV1, cpName, cpNameSize); } /* *----------------------------------------------------------------------------- * * HgfsUnpackSetattrRequest -- * * Unpack hgfs setattr request and initialize a corresponding * HgfsFileAttrInfo structure that is used to pass around setattr request * information. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackSetattrRequest(void const *packet, // IN: HGFS packet size_t packetSize, // IN: request packet size HgfsOp op, // IN: request type HgfsFileAttrInfo *attr, // OUT: setattr info HgfsAttrHint *hints, // OUT: setattr hints char **cpName, // OUT: cpName size_t *cpNameSize, // OUT: cpName size HgfsHandle *file, // OUT: server file ID uint32 *caseType) // OUT: case-sensitivity flags { ASSERT(packet); ASSERT(attr); ASSERT(cpName); ASSERT(cpNameSize); ASSERT(file); ASSERT(caseType); attr->requestType = op; /* Default values for legacy requests. */ *caseType = HGFS_FILE_NAME_DEFAULT_CASE; *hints = 0; *file = HGFS_INVALID_HANDLE; switch (op) { case HGFS_OP_SETATTR_V3: { HgfsRequestSetattrV3 *requestV3 = (HgfsRequestSetattrV3 *)packet; if (!HgfsUnpackSetattrPayloadV3(requestV3, packetSize, attr, cpName, cpNameSize, hints, file, caseType)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } case HGFS_OP_SETATTR_V2: { HgfsRequestSetattrV2 *requestV2 = (HgfsRequestSetattrV2 *)packet; if (!HgfsUnpackSetattrPayloadV2(requestV2, packetSize, attr, cpName, cpNameSize, hints, file)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } case HGFS_OP_SETATTR: { HgfsRequestSetattr *requestV1 = (HgfsRequestSetattr *)packet; if (!HgfsUnpackSetattrPayloadV1(requestV1, packetSize, attr, cpName, cpNameSize, hints)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } default: LOG(4, ("%s: Incorrect opcode %d\n", __FUNCTION__, op)); NOT_REACHED(); return FALSE; } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsPackSetattrReply -- * * Pack hgfs setattr reply. * Since the structure of the set attributes reply packet hasn't changed in * version 2 of the protocol, HgfsReplySetattrV2 is identical to * HgfsReplySetattr. So use HgfsReplySetattr type to access packetIn to * keep the code simple. * * Results: * TRUE if valid op and reply set, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackSetattrReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: request type size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session) // IN: Session info { Bool result; *payloadSize = 0; switch (op) { case HGFS_OP_SETATTR_V3: { HgfsReplySetattrV3 *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { /* Reply consists of only a reserved field. */ reply->reserved = 0; *payloadSize = sizeof *reply; } break; } case HGFS_OP_SETATTR_V2: case HGFS_OP_SETATTR: { HgfsReplySetattr *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { *payloadSize = sizeof *reply; } break; } default: result = FALSE; LOG(4, ("%s: invalid op code %d\n", __FUNCTION__, op)); NOT_REACHED(); } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackCreateDirPayloadV3 -- * * Unpack hgfs create directory request V3 payload and initialize a corresponding * file name to tell us which directory to create. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackCreateDirPayloadV3(HgfsRequestCreateDirV3 *requestV3, // IN: request payload size_t payloadSize, // IN: payload size HgfsCreateDirInfo *info) // IN/OUT: info struct { /* * The request file name length is user-provided, so this test must be * carefully written to prevent wraparounds. */ LOG(4, ("%s: HGFS_OP_CREATE_DIR_V3\n", __FUNCTION__)); ASSERT(payloadSize >= sizeof *requestV3); if (requestV3->fileName.length > payloadSize - sizeof *requestV3) { /* The input packet is smaller than the request. */ return FALSE; } if (!(requestV3->mask & HGFS_CREATE_DIR_VALID_FILE_NAME)) { /* We do not support requests without a valid file name. */ LOG(4, ("%s: Incorrect mask %x\n", __FUNCTION__, (uint32)requestV3->mask)); return FALSE; } /* * Copy all the fields into our carrier struct. Some will probably be * garbage, but it's simpler to copy everything now and check the * valid bits before reading later. */ info->mask = requestV3->mask; info->cpName = requestV3->fileName.name; info->cpNameSize = requestV3->fileName.length; info->caseFlags = requestV3->fileName.caseType; info->specialPerms = requestV3->specialPerms; info->fileAttr = requestV3->fileAttr; info->ownerPerms = requestV3->ownerPerms; info->groupPerms = requestV3->groupPerms; info->otherPerms = requestV3->otherPerms; return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackCreateDirPayloadV2 -- * * Unpack hgfs create directory request V2 payload and initialize a corresponding * file name to tell us which directory to create. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackCreateDirPayloadV2(HgfsRequestCreateDirV2 *requestV2, // IN: request payload size_t payloadSize, // IN: payload size HgfsCreateDirInfo *info) // IN/OUT: info struct { /* * The request file name length is user-provided, so this test must be * carefully written to prevent wraparounds. */ LOG(4, ("%s: HGFS_OP_CREATE_DIR_V2\n", __FUNCTION__)); ASSERT(payloadSize >= sizeof *requestV2); if (requestV2->fileName.length > payloadSize - sizeof *requestV2) { /* The input packet is smaller than the request. */ return FALSE; } if (!(requestV2->mask & HGFS_CREATE_DIR_VALID_FILE_NAME)) { /* We do not support requests without a valid file name. */ LOG(4, ("%s: Incorrect mask %x\n", __FUNCTION__, (uint32)requestV2->mask)); return FALSE; } /* * Copy all the fields into our carrier struct. Some will probably be * garbage, but it's simpler to copy everything now and check the * valid bits before reading later. */ info->mask = requestV2->mask; info->cpName = requestV2->fileName.name; info->cpNameSize = requestV2->fileName.length; info->specialPerms = requestV2->specialPerms; info->ownerPerms = requestV2->ownerPerms; info->groupPerms = requestV2->groupPerms; info->otherPerms = requestV2->otherPerms; info->fileAttr = 0; return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackCreateDirPayloadV1 -- * * Unpack hgfs create directory request V1 payload and initialize a corresponding * file name to tell us which directory to create. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackCreateDirPayloadV1(HgfsRequestCreateDir *requestV1, // IN: request payload size_t payloadSize, // IN: payload size HgfsCreateDirInfo *info) // IN/OUT: info struct { /* * The request file name length is user-provided, so this test must be * carefully written to prevent wraparounds. */ LOG(4, ("%s: HGFS_OP_CREATE_DIR_V1\n", __FUNCTION__)); ASSERT(payloadSize >= sizeof *requestV1); if (requestV1->fileName.length > payloadSize - sizeof *requestV1) { /* The input packet is smaller than the request. */ LOG(4, ("%s: HGFS packet too small for the file name\n", __FUNCTION__)); return FALSE; } /* For CreateDirV1 requests, we know exactly what fields we expect. */ info->mask = HGFS_CREATE_DIR_VALID_OWNER_PERMS | HGFS_CREATE_DIR_VALID_FILE_NAME; info->cpName = requestV1->fileName.name; info->cpNameSize = requestV1->fileName.length; info->ownerPerms = requestV1->permissions; info->fileAttr = 0; return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackCreateDirRequest -- * * Unpack hgfs CreateDir request and initialize a corresponding * HgfsCreateDirInfo structure that is used to pass around CreateDir request * information. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackCreateDirRequest(void const *packet, // IN: incoming packet size_t packetSize, // IN: size of packet HgfsOp op, // IN: request type HgfsCreateDirInfo *info) // IN/OUT: info struct { ASSERT(packet); ASSERT(info); info->requestType = op; /* Default value for legacy requests. */ info->caseFlags = HGFS_FILE_NAME_DEFAULT_CASE; switch (op) { case HGFS_OP_CREATE_DIR_V3: { HgfsRequestCreateDirV3 *requestV3 = (HgfsRequestCreateDirV3 *)packet; if (!HgfsUnpackCreateDirPayloadV3(requestV3, packetSize, info)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } case HGFS_OP_CREATE_DIR_V2: { HgfsRequestCreateDirV2 *requestV2 = (HgfsRequestCreateDirV2 *)packet; if (!HgfsUnpackCreateDirPayloadV2(requestV2, packetSize, info)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } case HGFS_OP_CREATE_DIR: { HgfsRequestCreateDir *requestV1 = (HgfsRequestCreateDir *)packet; if (!HgfsUnpackCreateDirPayloadV1(requestV1, packetSize, info)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } default: LOG(4, ("%s: Incorrect opcode %d\n", __FUNCTION__, op)); NOT_REACHED(); return FALSE; } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsPackCreateDirReply -- * * Pack hgfs CreateDir reply. * * Results: * TRUE if valid op and reply set, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackCreateDirReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: request type size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session) // IN: Session info { Bool result; *payloadSize = 0; switch (op) { case HGFS_OP_CREATE_DIR_V3: { HgfsReplyCreateDirV3 *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { /* Reply consists of only a reserved field. */ reply->reserved = 0; *payloadSize = sizeof *reply; } break; } case HGFS_OP_CREATE_DIR_V2: { HgfsReplyCreateDirV2 *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { *payloadSize = sizeof *reply; } break; } case HGFS_OP_CREATE_DIR: { HgfsReplyCreateDir *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { *payloadSize = sizeof *reply; } break; } default: result = FALSE; LOG(4, ("%s: invalid op code %d\n", __FUNCTION__, op)); NOT_REACHED(); } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackWriteWin32StreamPayloadV3 -- * * Unpack hgfs write stream request V3 payload and initialize a corresponding * file name to tell us which directory to create. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackWriteWin32StreamPayloadV3(HgfsRequestWriteWin32StreamV3 *requestV3, // IN: size_t payloadSize, // IN: HgfsHandle *file, // OUT: char **data, // OUT: size_t *dataSize, // OUT: Bool *doSecurity) // OUT: { LOG(4, ("%s: HGFS_OP_WRITE_WIN32_STREAM_V3\n", __FUNCTION__)); if (payloadSize < sizeof *requestV3) { LOG(4, ("%s: HGFS packet too small\n", __FUNCTION__)); return FALSE; } if (payloadSize >= requestV3->requiredSize + sizeof *requestV3) { *file = requestV3->file; *data = requestV3->payload; *dataSize = requestV3->requiredSize; *doSecurity = (requestV3->flags & HGFS_WIN32_STREAM_IGNORE_SECURITY) == 0; return TRUE; } LOG(4, ("%s: HGFS packet too small - user data do not fit\n", __FUNCTION__)); return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackWriteWin32StreamRequest -- * * Unpack hgfs SendFileUsingReader request. Returns file to write to, data * and whether to restore the security stream. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackWriteWin32StreamRequest(void const *packet, // IN: incoming packet size_t packetSize, // IN: size of packet HgfsOp op, // IN: request type HgfsHandle *file, // OUT: file to write to char **data, // OUT: data to write size_t *dataSize, // OUT: size of data Bool *doSecurity) // OUT: restore sec.str. { ASSERT(packet); ASSERT(file); ASSERT(data); ASSERT(dataSize); ASSERT(doSecurity); if (op != HGFS_OP_WRITE_WIN32_STREAM_V3) { /* The only supported version for the moment is V3. */ LOG(4, ("%s: Incorrect opcode %d\n", __FUNCTION__, op)); NOT_REACHED(); return FALSE; } return HgfsUnpackWriteWin32StreamPayloadV3((HgfsRequestWriteWin32StreamV3 *)packet, packetSize, file, data, dataSize, doSecurity); } /* *----------------------------------------------------------------------------- * * HgfsPackWriteWin32StreamReply -- * * Pack hgfs SendFileUsingReader reply. * Returns the actual amount of data written in the reply. * * Results: * TRUE if valid op and reply set, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackWriteWin32StreamReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: request type uint32 actualSize, // IN: amount written size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session) // IN: Session info { HgfsReplyWriteWin32StreamV3 *reply; Bool result; *payloadSize = 0; if (HGFS_OP_WRITE_WIN32_STREAM_V3 == op) { result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { reply->reserved = 0; reply->actualSize = actualSize; *payloadSize = sizeof *reply; } } else { LOG(4, ("%s: Incorrect opcode %d\n", __FUNCTION__, op)); NOT_REACHED(); result = FALSE; } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackReadPayload -- * * Unpack hgfs read payload to get the file handle and file offset to read from and * the length of data to read. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackReadPayload(HgfsRequestRead *request, // IN: payload size_t payloadSize, // IN: payload size HgfsHandle* file, // OUT: HGFS handle to close uint64 *offset, // OUT: offset to read from uint32 *length) // OUT: length of data to read { LOG(4, ("%s: HGFS_OP_READ\n", __FUNCTION__)); if (payloadSize >= sizeof *request) { *file = request->file; *offset = request->offset; *length = request->requiredSize; return TRUE; } LOG(4, ("%s: HGFS packet too small\n", __FUNCTION__)); return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackReadPayloadV3 -- * * Unpack hgfs read payload V3 to get parameters needed to perform read. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackReadPayloadV3(HgfsRequestReadV3 *requestV3, // IN: payload size_t payloadSize, // IN: payload size HgfsHandle* file, // OUT: HGFS handle to close uint64 *offset, // OUT: offset to read from uint32 *length) // OUT: length of data to read { LOG(4, ("%s: HGFS_OP_READ_V3\n", __FUNCTION__)); if (payloadSize >= sizeof *requestV3) { *file = requestV3->file; *offset = requestV3->offset; *length = requestV3->requiredSize; return TRUE; } LOG(4, ("%s: HGFS packet too small\n", __FUNCTION__)); return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackReadRequest -- * * Unpack hgfs read request. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackReadRequest(void const *packet, // IN: HGFS request size_t packetSize, // IN: request packet size HgfsOp op, // IN: request type HgfsHandle *file, // OUT: Handle to close uint64 *offset, // OUT: offset to read from uint32 *length) // OUT: length of data to read { Bool result; ASSERT(packet); switch (op) { case HGFS_OP_READ_FAST_V4: case HGFS_OP_READ_V3: { HgfsRequestReadV3 *requestV3 = (HgfsRequestReadV3 *)packet; result = HgfsUnpackReadPayloadV3(requestV3, packetSize, file, offset, length); break; } case HGFS_OP_READ: { HgfsRequestRead *requestV1 = (HgfsRequestRead *)packet; result = HgfsUnpackReadPayload(requestV1, packetSize, file, offset, length); break; } default: NOT_REACHED(); result = FALSE; } if (!result) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackWritePayload -- * * Unpack hgfs write payload to get the file handle, file offset, of data to write, * write flags and pointer to the data to write. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackWritePayload(HgfsRequestWrite *request, // IN: request payload size_t payloadSize, // IN: request payload size HgfsHandle* file, // OUT: HGFS handle to write to uint64 *offset, // OUT: offset to read from uint32 *length, // OUT: length of data to write HgfsWriteFlags *flags, // OUT: write flags char **data) // OUT: data to be written { LOG(4, ("%s: HGFS_OP_WRITE\n", __FUNCTION__)); if (payloadSize >= sizeof *request) { if (sizeof *request + request->requiredSize - 1 <= payloadSize) { *file = request->file; *flags = request->flags; *offset = request->offset; *data = request->payload; *length = request->requiredSize; return TRUE; } } LOG(4, ("%s: HGFS packet too small\n", __FUNCTION__)); return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackWritePayloadV3 -- * * Unpack hgfs write payload V3. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackWritePayloadV3(HgfsRequestWriteV3 *requestV3, // IN: payload size_t payloadSize, // IN: request payload size HgfsHandle* file, // OUT: HGFS handle write to uint64 *offset, // OUT: offset to read from uint32 *length, // OUT: length of data to write HgfsWriteFlags *flags, // OUT: write flags char **data) // OUT: data to be written { LOG(4, ("%s: HGFS_OP_WRITE_V3\n", __FUNCTION__)); if (payloadSize >= sizeof *requestV3) { if (sizeof *requestV3 + requestV3->requiredSize - 1 <= payloadSize) { *file = requestV3->file; *flags = requestV3->flags; *offset = requestV3->offset; *data = requestV3->payload; *length = requestV3->requiredSize; return TRUE; } } LOG(4, ("%s: HGFS packet too small\n", __FUNCTION__)); return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackWriteFastPayloadV4 -- * * Unpack hgfs write fast payload V4. * The only difference from V3 payload is that data to write are * provided in the payload but located in a separate buffer. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackWriteFastPayloadV4(HgfsRequestWriteV3 *requestV3, // IN: payload size_t payloadSize, // IN: request payload size HgfsHandle* file, // OUT: HGFS handle write to uint64 *offset, // OUT: offset to write to uint32 *length, // OUT: size of data to write HgfsWriteFlags *flags) // OUT: write flags { LOG(4, ("%s: HGFS_OP_WRITE_V3\n", __FUNCTION__)); if (payloadSize >= sizeof *requestV3) { *file = requestV3->file; *flags = requestV3->flags; *offset = requestV3->offset; *length = requestV3->requiredSize; return TRUE; } LOG(4, ("%s: HGFS packet too small\n", __FUNCTION__)); return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackWriteRequest -- * * Unpack hgfs write request to get parameters and data to write. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackWriteRequest(HgfsInputParam *input, // IN: Input params HgfsHandle *file, // OUT: Handle to write to uint64 *offset, // OUT: offset to write to uint32 *length, // OUT: length of data to write HgfsWriteFlags *flags, // OUT: write flags char **data) // OUT: data to be written { Bool result; ASSERT(input); switch (input->op) { case HGFS_OP_WRITE_FAST_V4: { HgfsRequestWriteV3 *requestV3 = (HgfsRequestWriteV3 *)input->payload; result = HgfsUnpackWriteFastPayloadV4(requestV3, input->payloadSize, file, offset, length, flags); if (result) { *data = HSPU_GetDataPacketBuf(input->packet, BUF_READABLE, input->transportSession); if (NULL == *data) { LOG(4, ("%s: Failed to get data in guest memory\n", __FUNCTION__)); result = FALSE; } } break; } case HGFS_OP_WRITE_V3: { HgfsRequestWriteV3 *requestV3 = (HgfsRequestWriteV3 *)input->payload; result = HgfsUnpackWritePayloadV3(requestV3, input->payloadSize, file, offset, length, flags, data); break; } case HGFS_OP_WRITE: { HgfsRequestWrite *requestV1 = (HgfsRequestWrite *)input->payload; result = HgfsUnpackWritePayload(requestV1, input->payloadSize, file, offset, length, flags, data); break; } default: LOG(4, ("%s: Incorrect opcode %d\n", __FUNCTION__, input->op)); NOT_REACHED(); result = FALSE; } if (!result) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); } return result; } /* *----------------------------------------------------------------------------- * * HgfsPackWriteReply -- * * Pack hgfs write reply to the HgfsReplyWrite structure. * * Results: * TRUE is there are no bugs in the code. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackWriteReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: request type uint32 actualSize, // IN: number of bytes that were written size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session) // IN: Session info { Bool result; *payloadSize = 0; switch (op) { case HGFS_OP_WRITE_FAST_V4: case HGFS_OP_WRITE_V3: { HgfsReplyWriteV3 *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { reply->reserved = 0; reply->actualSize = actualSize; *payloadSize = sizeof *reply; } break; } case HGFS_OP_WRITE: { HgfsReplyWrite *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { reply->actualSize = actualSize; *payloadSize = sizeof *reply; } break; } default: NOT_REACHED(); result = FALSE; } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackQueryVolumePayload -- * * Unpack hgfs query volume payload to get the file name which must be used to query * volume information. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackQueryVolumePayload(HgfsRequestQueryVolume *request, // IN: request payload size_t payloadSize, // IN: request payload size char **fileName, // OUT: volume name size_t *nameLength) // OUT: volume name length { LOG(4, ("%s: HGFS_OP_QUERY_VOLUME_INFO\n", __FUNCTION__)); if (payloadSize >= sizeof *request) { return HgfsUnpackFileName(&request->fileName, payloadSize - sizeof *request + 1, fileName, nameLength); } LOG(4, ("%s: HGFS packet too small\n", __FUNCTION__)); return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackQueryVolumePayloadV3 -- * * Unpack hgfs query volume payload V3. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackQueryVolumePayloadV3(HgfsRequestQueryVolumeV3 *requestV3, // IN: payload size_t payloadSize, // IN: payload size Bool *useHandle, // OUT: use handle HgfsHandle* file, // OUT: HGFS handle char **fileName, // OUT: volume name size_t *nameLength, // OUT: name length uint32 * caseFlags) // OUT: case flags { LOG(4, ("%s: HGFS_OP_QUERY_VOLUME_INFO_V3\n", __FUNCTION__)); if (payloadSize >= sizeof *requestV3) { return HgfsUnpackFileNameV3(&requestV3->fileName, payloadSize - sizeof *requestV3 + 1, useHandle, fileName, nameLength, file, caseFlags); } LOG(4, ("%s: HGFS packet too small\n", __FUNCTION__)); return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackQueryVolumeRequest -- * * Unpack hgfs query volume information request to get parameters related to * query volume operation. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackQueryVolumeRequest(void const *packet, // IN: HGFS packet size_t packetSize, // IN: request packet size HgfsOp op, // IN: request type Bool *useHandle, // OUT: use handle char **fileName, // OUT: file name size_t *fileNameLength, // OUT: file name length uint32 *caseFlags, // OUT: case sensitivity HgfsHandle *file) // OUT: Handle to the volume { ASSERT(packet); switch (op) { case HGFS_OP_QUERY_VOLUME_INFO_V3: { HgfsRequestQueryVolumeV3 *requestV3 = (HgfsRequestQueryVolumeV3 *)packet; if (!HgfsUnpackQueryVolumePayloadV3(requestV3, packetSize, useHandle, file, fileName, fileNameLength, caseFlags)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } case HGFS_OP_QUERY_VOLUME_INFO: { HgfsRequestQueryVolume *requestV1 = (HgfsRequestQueryVolume *)packet; if (!HgfsUnpackQueryVolumePayload(requestV1, packetSize, fileName, fileNameLength)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } *file = HGFS_INVALID_HANDLE; *caseFlags = HGFS_FILE_NAME_DEFAULT_CASE; *useHandle = FALSE; break; } default: LOG(4, ("%s: Incorrect opcode %d\n", __FUNCTION__, op)); NOT_REACHED(); return FALSE; } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsPackQueryVolumeReply -- * * Pack hgfs query volume reply. * * Results: * TRUE if valid op and reply set, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackQueryVolumeReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: request type uint64 freeBytes, // IN: volume free space uint64 totalBytes, // IN: volume capacity size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session) // IN: Session info { Bool result; *payloadSize = 0; switch (op) { case HGFS_OP_QUERY_VOLUME_INFO_V3: { HgfsReplyQueryVolumeV3 *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { reply->reserved = 0; reply->freeBytes = freeBytes; reply->totalBytes = totalBytes; *payloadSize = sizeof *reply; } break; } case HGFS_OP_QUERY_VOLUME_INFO: { HgfsReplyQueryVolume *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { reply->freeBytes = freeBytes; reply->totalBytes = totalBytes; *payloadSize = sizeof *reply; } break; } default: result = FALSE; LOG(4, ("%s: invalid op code %d\n", __FUNCTION__, op)); NOT_REACHED(); } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackSymlinkCreatePayload -- * * Unpack hgfs symbolic link payload to get symbolic link file name * and symbolic link target. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackSymlinkCreatePayload(HgfsRequestSymlinkCreate *request, // IN: request payload size_t payloadSize, // IN: payload size char **srcFileName, // OUT: link file name size_t *srcNameLength, // OUT: file name length char **tgFileName, // OUT: target file name size_t *tgNameLength) // OUT: target name length { uint32 prefixSize; LOG(4, ("%s: HGFS_OP_CREATE_SYMLINK_V3\n", __FUNCTION__)); prefixSize = offsetof(HgfsRequestSymlinkCreate, symlinkName.name); if (payloadSize >= prefixSize) { if (HgfsUnpackFileName(&request->symlinkName, payloadSize - prefixSize, srcFileName, srcNameLength)) { HgfsFileName *targetName = (HgfsFileName *)(*srcFileName + 1 + *srcNameLength); prefixSize = ((char *)targetName - (char *)request) + offsetof(HgfsFileName, name); return HgfsUnpackFileName(targetName, payloadSize - prefixSize, tgFileName, tgNameLength); }; } return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackSymlinkCreatePayloadV3 -- * * Unpack hgfs create symbolic link payload V3. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackSymlinkCreatePayloadV3(HgfsRequestSymlinkCreateV3 *requestV3, // IN: size_t payloadSize, // IN: Bool *srcUseHandle, // OUT: HgfsHandle* srcFile, // OUT: char **srcFileName, // OUT: size_t *srcNameLength, // OUT: uint32 *srcCaseFlags, // OUT: Bool *tgUseHandle, // OUT: HgfsHandle* tgFile, // OUT: char **tgFileName, // OUT: size_t *tgNameLength, // OUT: uint32 * tgCaseFlags) // OUT: { uint32 prefixSize; LOG(4, ("%s: HGFS_OP_CREATE_SYMLINK_V3\n", __FUNCTION__)); prefixSize = offsetof(HgfsRequestSymlinkCreateV3, symlinkName.name); if (payloadSize >= prefixSize) { if (HgfsUnpackFileNameV3(&requestV3->symlinkName, payloadSize - prefixSize, srcUseHandle, srcFileName, srcNameLength, srcFile, srcCaseFlags)) { HgfsFileNameV3 *targetName = (HgfsFileNameV3 *)(*srcFileName + 1 + *srcNameLength); prefixSize = ((char *)targetName - (char *)requestV3) + offsetof(HgfsFileNameV3, name); return HgfsUnpackFileNameV3(targetName, payloadSize - prefixSize, tgUseHandle, tgFileName, tgNameLength, tgFile, tgCaseFlags); } } return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackSymlinkCreateRequest -- * * Unpack hgfs symbolic link creation request to get parameters related to * creating the symbolic link. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackSymlinkCreateRequest(void const *packet, // IN: HGFS packet size_t packetSize, // IN: request packet size HgfsOp op, // IN: request type Bool *srcUseHandle, // OUT: use source handle char **srcFileName, // OUT: source file name size_t *srcFileNameLength, // OUT: source file name length uint32 *srcCaseFlags, // OUT: source case sensitivity HgfsHandle *srcFile, // OUT: source file handle Bool *tgUseHandle, // OUT: use target handle char **tgFileName, // OUT: target file name size_t *tgFileNameLength, // OUT: target file name length uint32 *tgCaseFlags, // OUT: target case sensitivity HgfsHandle *tgFile) // OUT: target file handle { ASSERT(packet); switch (op) { case HGFS_OP_CREATE_SYMLINK_V3: { HgfsRequestSymlinkCreateV3 *requestV3 = (HgfsRequestSymlinkCreateV3 *)packet; if (!HgfsUnpackSymlinkCreatePayloadV3(requestV3, packetSize, srcUseHandle, srcFile, srcFileName, srcFileNameLength, srcCaseFlags, tgUseHandle, tgFile, tgFileName, tgFileNameLength, tgCaseFlags)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } case HGFS_OP_CREATE_SYMLINK: { HgfsRequestSymlinkCreate *requestV1 = (HgfsRequestSymlinkCreate *)packet; if (!HgfsUnpackSymlinkCreatePayload(requestV1, packetSize, srcFileName, srcFileNameLength, tgFileName, tgFileNameLength)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } *srcFile = HGFS_INVALID_HANDLE; *srcCaseFlags = HGFS_FILE_NAME_DEFAULT_CASE; *srcUseHandle = FALSE; *tgFile = HGFS_INVALID_HANDLE; *tgCaseFlags = HGFS_FILE_NAME_DEFAULT_CASE; *tgUseHandle = FALSE; break; } default: LOG(4, ("%s: Incorrect opcode %d\n", __FUNCTION__, op)); NOT_REACHED(); return FALSE; } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsPackSymlinkCreateReply -- * * Pack hgfs symbolic link creation reply. * * Results: * TRUE if valid op and reply set, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackSymlinkCreateReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: request type size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session) // IN: Session info { Bool result; HGFS_ASSERT_PACK_PARAMS; *payloadSize = 0; switch (op) { case HGFS_OP_CREATE_SYMLINK_V3: { HgfsReplySymlinkCreateV3 *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { /* Reply only consists of a reserved field. */ reply->reserved = 0; *payloadSize = sizeof *reply; } break; } case HGFS_OP_CREATE_SYMLINK: { HgfsReplySymlinkCreate *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { *payloadSize = sizeof *reply; } break; } default: result = FALSE; LOG(4, ("%s: invalid op code %d\n", __FUNCTION__, op)); NOT_REACHED(); } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackSearchOpenPayload -- * * Unpack hgfs search open payload to get name of directory to open. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackSearchOpenPayload(HgfsRequestSearchOpen *request, // IN: payload size_t payloadSize, // IN: payload size char **dirName, // OUT: directory name uint32 *dirNameLength) // OUT: name length { LOG(4, ("%s: HGFS_OP_SEARCH_OPEN\n", __FUNCTION__)); if (payloadSize >= sizeof *request) { if (sizeof *request + request->dirName.length - 1 <= payloadSize) { *dirName = request->dirName.name; *dirNameLength = request->dirName.length; return TRUE; } } LOG(4, ("%s: HGFS packet too small\n", __FUNCTION__)); return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackSearchOpenPayloadV3 -- * * Unpack hgfs search open payload V3 to get name of directory to open and * case flags. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackSearchOpenPayloadV3(HgfsRequestSearchOpenV3 *requestV3, // IN: payload size_t payloadSize, // IN: payload size char **dirName, // OUT: directory name uint32 *dirNameLength, // OUT: name length uint32 *caseFlags) // OUT: case flags { LOG(4, ("%s: HGFS_OP_SEARCH_OPEN_V3\n", __FUNCTION__)); if (payloadSize >= sizeof *requestV3) { if (sizeof *requestV3 + requestV3->dirName.length - 1 <= payloadSize) { *dirName = requestV3->dirName.name; *dirNameLength = requestV3->dirName.length; *caseFlags = requestV3->dirName.flags; return TRUE; } } LOG(4, ("%s: HGFS packet too small\n", __FUNCTION__)); return FALSE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackSearchOpenRequest -- * * Unpack hgfs search open request to get directory name and case flags. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackSearchOpenRequest(void const *packet, // IN: HGFS packet size_t packetSize, // IN: request packet size HgfsOp op, // IN: request type char **dirName, // OUT: directory name uint32 *dirNameLength, // OUT: name length uint32 *caseFlags) // OUT: case flags { ASSERT(packet); switch (op) { case HGFS_OP_SEARCH_OPEN_V3: { HgfsRequestSearchOpenV3 *requestV3 = (HgfsRequestSearchOpenV3 *)packet; if (!HgfsUnpackSearchOpenPayloadV3(requestV3, packetSize, dirName, dirNameLength, caseFlags)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } break; } case HGFS_OP_SEARCH_OPEN: { HgfsRequestSearchOpen *requestV1 = (HgfsRequestSearchOpen *)packet; if (!HgfsUnpackSearchOpenPayload(requestV1, packetSize, dirName, dirNameLength)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } *caseFlags = HGFS_FILE_NAME_DEFAULT_CASE; break; } default: LOG(4, ("%s: Incorrect opcode %d\n", __FUNCTION__, op)); NOT_REACHED(); return FALSE; } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsPackSearchOpenReply -- * * Pack hgfs search open reply. * * Results: * TRUE unless it is invoked for a wrong op (which indicates a bug in the code). * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackSearchOpenReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: request type HgfsHandle search, // IN: search handle size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session) // IN: Session info { Bool result; HGFS_ASSERT_PACK_PARAMS; *payloadSize = 0; switch (op) { case HGFS_OP_SEARCH_OPEN_V3: { HgfsReplySearchOpenV3 *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { reply->reserved = 0; reply->search = search; *payloadSize = sizeof *reply; } break; } case HGFS_OP_SEARCH_OPEN: { HgfsReplySearchOpen *reply; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { reply->search = search; *payloadSize = sizeof *reply; } break; } default: NOT_REACHED(); result = FALSE; } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackCreateSessionPayloadV4 -- * * Unpack hgfs create session request V4 payload. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackCreateSessionPayloadV4(HgfsRequestCreateSessionV4 *requestV4, // IN: payload size_t payloadSize, // IN: HgfsCreateSessionInfo *info) // IN/OUT: info { LOG(4, ("%s: HGFS_OP_CREATE_SESSION_V4\n", __FUNCTION__)); if (payloadSize < offsetof(HgfsRequestCreateSessionV4, reserved)) { /* The input packet is smaller than the request. */ return FALSE; } if (requestV4->numCapabilities) { if (payloadSize < offsetof(HgfsRequestCreateSessionV4, capabilities) + requestV4->numCapabilities * sizeof(HgfsCapability)) { LOG(4, ("%s: HGFS packet too small\n", __FUNCTION__)); return FALSE; } } info->maxPacketSize = requestV4->maxPacketSize; return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackCreateSessionRequest -- * * Unpack hgfs CreateSession request and initialize a corresponding * HgfsCreateDirInfo structure that is used to pass around CreateDir request * information. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackCreateSessionRequest(void const *packet, // IN: HGFS packet size_t packetSize, // IN: size of packet HgfsOp op, // IN: request type HgfsCreateSessionInfo *info) // IN/OUT: info struct { HgfsRequestCreateSessionV4 *requestV4; ASSERT(packet); ASSERT(info); ASSERT(op == HGFS_OP_CREATE_SESSION_V4); requestV4 = (HgfsRequestCreateSessionV4 *)packet; if (!HgfsUnpackCreateSessionPayloadV4(requestV4, packetSize, info)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsPackCreateSessionReply -- * * Pack hgfs CreateSession reply. * * Results: * Always TRUE. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackCreateSessionReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session) // IN: Session info { Bool result; HgfsReplyCreateSessionV4 *reply; uint32 numCapabilities = session->numberOfCapabilities; uint32 capabilitiesLen = numCapabilities * sizeof *session->hgfsSessionCapabilities; HGFS_ASSERT_PACK_PARAMS; *payloadSize = offsetof(HgfsReplyCreateSessionV4, capabilities) + capabilitiesLen; result = HgfsAllocInitReply(packet, packetHeader, *payloadSize, (void **)&reply, session); if (result) { reply->sessionId = session->sessionId; reply->numCapabilities = numCapabilities; reply->maxPacketSize = session->maxPacketSize; reply->identityOffset = 0; reply->reserved = 0; memcpy(reply->capabilities, session->hgfsSessionCapabilities, capabilitiesLen); } return result; } /* *----------------------------------------------------------------------------- * * HgfsPackDestroySessionReply -- * * Pack hgfs CreateSession reply. * * Results: * Always TRUE. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackDestroySessionReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session) // IN: Session info { HgfsReplyDestroySessionV4 *reply; Bool result; HGFS_ASSERT_PACK_PARAMS; *payloadSize = 0; result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { /* Reply only consists of a reserved field. */ *payloadSize = sizeof *reply; reply->reserved = 0; } return result; } /* *----------------------------------------------------------------------------- * * HgfsServerGetDefaultCapabilities -- * * Returns list capabilities that are supported by all sessions. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsServerGetDefaultCapabilities(HgfsCapability *capabilities, // OUT: capabilities uint32 *numberOfCapabilities) // OUT: number of items { *numberOfCapabilities = ARRAYSIZE(hgfsDefaultCapabilityTable); ASSERT(*numberOfCapabilities <= HGFS_OP_MAX); memcpy(capabilities, hgfsDefaultCapabilityTable, sizeof hgfsDefaultCapabilityTable); } /* *----------------------------------------------------------------------------- * * HgfsPackSetWatchReplyV4 -- * * Pack hgfs set watch V4 reply payload to the HgfsReplySetWatchV4 structure. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsPackSetWatchReplyV4(HgfsSubscriberHandle watchId, // IN: host id of thee new watch HgfsReplySetWatchV4 *reply) // OUT: reply buffer to fill { reply->watchId = watchId; reply->reserved = 0; } /* *----------------------------------------------------------------------------- * * HgfsPackSetWatchReply -- * * Pack hgfs set watch reply to the HgfsReplySetWatchV4 structure. * * Results: * TRUE if successfully allocated reply request, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackSetWatchReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: operation code HgfsSubscriberHandle watchId, // IN: id of the new watch size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session) // IN: Session info { Bool result; HgfsReplySetWatchV4 *reply; HGFS_ASSERT_PACK_PARAMS; *payloadSize = 0; if (HGFS_OP_SET_WATCH_V4 != op) { NOT_REACHED(); result = FALSE; } else { result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { HgfsPackSetWatchReplyV4(watchId, reply); *payloadSize = sizeof *reply; } } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackSetWatchPayloadV4 -- * * Unpack HGFS set directory notication watch payload version 4 and initializes * a corresponding HgfsHandle or file name to tell us which directory to watch. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool HgfsUnpackSetWatchPayloadV4(HgfsRequestSetWatchV4 *requestV4, // IN: request payload size_t payloadSize, // IN: payload size Bool *useHandle, // OUT: handle or cpName uint32 *flags, // OUT: watch flags uint32 *events, // OUT: event filter char **cpName, // OUT: cpName size_t *cpNameSize, // OUT: cpName size HgfsHandle *dir, // OUT: directory handle uint32 *caseFlags) // OUT: case-sensitivity { if (payloadSize < sizeof *requestV4) { return FALSE; } *flags = requestV4->flags; *events = requestV4->events; return HgfsUnpackFileNameV3(&requestV4->fileName, payloadSize - sizeof *requestV4, useHandle, cpName, cpNameSize, dir, caseFlags); } /* *----------------------------------------------------------------------------- * * HgfsUnpackSetWatchRequest -- * * Unpack hgfs set directory notication watch request and initialize a corresponding * HgfsHandle or directory name to tell us which directory to monitor. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackSetWatchRequest(void const *packet, // IN: HGFS packet size_t packetSize, // IN: request packet size HgfsOp op, // IN: requested operation Bool *useHandle, // OUT: handle or cpName char **cpName, // OUT: cpName size_t *cpNameSize, // OUT: cpName size uint32 *flags, // OUT: flags for the new watch uint32 *events, // OUT: event filter HgfsHandle *dir, // OUT: direrctory handle uint32 *caseFlags) // OUT: case-sensitivity flags { HgfsRequestSetWatchV4 *requestV4 = (HgfsRequestSetWatchV4 *)packet; Bool result; ASSERT(packet); ASSERT(cpName); ASSERT(cpNameSize); ASSERT(dir); ASSERT(flags); ASSERT(events); ASSERT(caseFlags); ASSERT(useHandle); if (HGFS_OP_SET_WATCH_V4 != op) { NOT_REACHED(); result = FALSE; } else { result = HgfsUnpackSetWatchPayloadV4(requestV4, packetSize, useHandle, flags, events, cpName, cpNameSize, dir, caseFlags); } if (!result) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); } return result; } /* *----------------------------------------------------------------------------- * * HgfsPackRemoveWatchReply -- * * Pack hgfs remove watch reply to the HgfsReplyRemoveWatchV4 structure. * * Results: * TRUE if successfully allocated reply request, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackRemoveWatchReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet char const *packetHeader, // IN: packet header HgfsOp op, // IN: operation code size_t *payloadSize, // OUT: size of packet HgfsSessionInfo *session) // IN: Session info { Bool result; HgfsReplyRemoveWatchV4 *reply; HGFS_ASSERT_PACK_PARAMS; *payloadSize = 0; if (HGFS_OP_REMOVE_WATCH_V4 != op) { NOT_REACHED(); result = FALSE; } else { result = HgfsAllocInitReply(packet, packetHeader, sizeof *reply, (void **)&reply, session); if (result) { reply->reserved = 0; *payloadSize = sizeof *reply; } } return result; } /* *----------------------------------------------------------------------------- * * HgfsUnpackRemoveWatchPayload -- * * Unpack HGFS remove directory notication watch payload version 4. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool HgfsUnpackRemoveWatchPayloadV4(HgfsRequestRemoveWatchV4 *requestV4, // IN: request payload size_t payloadSize, // IN: payload size HgfsSubscriberHandle *watchId) // OUT: watch id { if (payloadSize < sizeof *requestV4) { return FALSE; } *watchId = requestV4->watchId; return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsUnpackRemoveWatchRequest -- * * Unpack hgfs remove directory notication watch request. * * Results: * TRUE on success. * FALSE on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsUnpackRemoveWatchRequest(void const *packet, // IN: HGFS packet size_t packetSize, // IN: request packet size HgfsOp op, // IN: requested operation HgfsSubscriberHandle *watchId) // OUT: watch Id to remove { HgfsRequestRemoveWatchV4 *requestV4 = (HgfsRequestRemoveWatchV4 *)packet; ASSERT(packet); ASSERT(watchId); ASSERT(HGFS_OP_REMOVE_WATCH_V4 == op); if (HGFS_OP_REMOVE_WATCH_V4 != op) { return FALSE; } else if (!HgfsUnpackRemoveWatchPayloadV4(requestV4, packetSize, watchId)) { LOG(4, ("%s: Error decoding HGFS packet\n", __FUNCTION__)); return FALSE; } return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsPackCalculateNotificationSize -- * * Calculates size needed for change notification packet. * * Results: * TRUE if successfully allocated reply request, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ size_t HgfsPackCalculateNotificationSize(char const *shareName, // IN: shared folder name char *fileName) // IN: relative file path { size_t result = sizeof(HgfsRequestNotifyV4); if (NULL != fileName) { size_t shareNameLen = strlen(shareName); result += strlen(fileName) + 1 + shareNameLen; } result += sizeof(HgfsHeader); return result; } /* *----------------------------------------------------------------------------- * * HgfsBuildCPName -- * * Build crossplatform name out of share name and relative to the shared folder * file path. * * Results: * Length of the output crossplatform name. * * Side effects: * None * *----------------------------------------------------------------------------- */ static size_t HgfsBuildCPName(char const *shareName, // IN: utf8 share name char *fileName, // IN: utf8 file path char **cpName) // OUT: full name in cp format { size_t shareNameLen = strlen(shareName) + 1; size_t fileNameLen = strlen(fileName) + 1; char *fullName = Util_SafeMalloc(shareNameLen + fileNameLen); size_t result; *cpName = Util_SafeMalloc(shareNameLen + fileNameLen); Str_Strcpy(fullName, shareName, shareNameLen); fullName[shareNameLen - 1] = DIRSEPC; Str_Strcpy(fullName + shareNameLen, fileName, fileNameLen); result = CPName_ConvertTo(fullName, shareNameLen + fileNameLen, *cpName); ASSERT(result > 0); // Unescaped name can't be longer then escaped thus it must fit. free(fullName); return result; } /* *----------------------------------------------------------------------------- * * HgfsPackHgfsName -- * * Pack cpName into HgfsFileName structure. * * Results: * TRUE if there is enough space in the buffer, * FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool HgfsPackHgfsName(char *cpName, // IN: cpName to pack size_t cpNameLen, // IN: length of the cpName size_t availableSpace, // IN: space available for HgfsFileName size_t *nameSize, // OUT: space consumed by HgfsFileName HgfsFileName *fileName) // OUT: structure to pack cpName into { if (availableSpace < offsetof(HgfsFileName, name) + cpNameLen) { return FALSE; } fileName->length = cpNameLen; memcpy(fileName->name, cpName, cpNameLen); *nameSize = offsetof(HgfsFileName, name) + cpNameLen; return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsPackChangeNotifyEventV4 -- * * Pack single change directory notification event information. * * Results: * Length of the packed structure or 0 if the structure does not fit in the * the buffer. * * Side effects: * None * *----------------------------------------------------------------------------- */ static size_t HgfsPackChangeNotifyEventV4(uint32 mask, // IN: event mask char const *shareName, // IN: share name char *fileName, // IN: file name size_t bufferSize, // IN: available space HgfsNotifyEventV4 *reply) // OUT: notificaiton buffer { size_t totalLength; if (sizeof *reply > bufferSize) { return 0; } reply->nextOffset = 0; reply->mask = mask; if (NULL != fileName) { char *fullPath; size_t remainingSize; size_t nameSize; size_t hgfsNameSize; nameSize = HgfsBuildCPName(shareName, fileName, &fullPath); remainingSize = bufferSize - offsetof(HgfsNotifyEventV4, fileName); if (HgfsPackHgfsName(fullPath, nameSize, remainingSize, &hgfsNameSize, &reply->fileName)) { remainingSize -= hgfsNameSize; totalLength = bufferSize - remainingSize; } else { totalLength = 0; } free(fullPath); } else { reply->fileName.length = 0; totalLength = sizeof *reply; } return totalLength; } /* *----------------------------------------------------------------------------- * * HgfsPackChangeNotifyRequestV4 -- * * Pack hgfs directory change notification request to be sent to the guest. * * Results: * Length of the packed structure or 0 if the structure does not fit in the * the buffer. * * Side effects: * None * *----------------------------------------------------------------------------- */ static size_t HgfsPackChangeNotifyRequestV4(HgfsSubscriberHandle watchId, // IN: watch uint32 flags, // IN: notify flags uint32 mask, // IN: event mask char const *shareName, // IN: share name char *fileName, // IN: relative file path size_t bufferSize, // IN: available space HgfsRequestNotifyV4 *reply) // OUT: notification buffer { size_t size; size_t notificationOffset; if (bufferSize < sizeof *reply) { return 0; } reply->watchId = watchId; reply->flags = flags; if ((flags & HGFS_NOTIFY_FLAG_OVERFLOW) == HGFS_NOTIFY_FLAG_OVERFLOW) { size = sizeof *reply; reply->count = 0; reply->flags = HGFS_NOTIFY_FLAG_OVERFLOW; } else { /* * For the moment server sends only one notification at a time and it relies * on transport to coalesce requests. * Later on we may consider supporting multiple notifications. */ reply->count = 1; notificationOffset = offsetof(HgfsRequestNotifyV4, events); size = HgfsPackChangeNotifyEventV4(mask, shareName, fileName, bufferSize - notificationOffset, reply->events); if (size != 0) { size += notificationOffset; } else { /* * Set event flag to tell guest that some events were dropped * when filling out notification details failed. */ size = sizeof *reply; reply->count = 0; reply->flags = HGFS_NOTIFY_FLAG_OVERFLOW; } } return size; } /* *----------------------------------------------------------------------------- * * HgfsPackChangeNotificationRequest -- * * Pack hgfs directory change notification request to the * HgfsRequestNotifyV4 structure. * * Results: * TRUE if successfully allocated reply request, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsPackChangeNotificationRequest(void *packet, // IN/OUT: Hgfs Packet HgfsSubscriberHandle subscriber, // IN: watch char const *shareName, // IN: share name char *fileName, // IN: relative name uint32 mask, // IN: event mask uint32 flags, // IN: notify flags HgfsSessionInfo *session, // IN: session size_t *bufferSize) // INOUT: size of packet { size_t notifyRequestSize; HgfsRequestNotifyV4 *notifyRequest; HgfsHeader *header = packet; Bool result; ASSERT(packet); ASSERT(shareName); ASSERT(NULL != fileName || (flags & HGFS_NOTIFY_FLAG_OVERFLOW) == HGFS_NOTIFY_FLAG_OVERFLOW); ASSERT(session); ASSERT(bufferSize); if (*bufferSize < sizeof *header) { return FALSE; } /* * Initialize notification header. * Set status and requestId to 0 since these fields are not relevant for * notifications. * Initialize payload size to 0 - it is not known yet and will be filled later. */ notifyRequest = (HgfsRequestNotifyV4 *)((char *)header + sizeof *header); notifyRequestSize = HgfsPackChangeNotifyRequestV4(subscriber, flags, mask, shareName, fileName, *bufferSize - sizeof *header, notifyRequest); if (0 != notifyRequestSize) { HgfsPackReplyHeaderV4(0, notifyRequestSize, HGFS_OP_NOTIFY_V4, session->sessionId, 0, header); result = TRUE; } else { result = FALSE; } return result; } open-vm-tools-9.4.0-1280544/lib/hgfsServer/Makefile.in0000644765153500003110000004474012220061622020373 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/hgfsServer DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libHgfsServer_la_LIBADD = am_libHgfsServer_la_OBJECTS = hgfsServer.lo hgfsServerLinux.lo \ hgfsServerPacketUtil.lo hgfsDirNotifyStub.lo \ hgfsServerParameters.lo libHgfsServer_la_OBJECTS = $(am_libHgfsServer_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libHgfsServer_la_SOURCES) DIST_SOURCES = $(libHgfsServer_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libHgfsServer.la libHgfsServer_la_SOURCES = hgfsServer.c hgfsServerLinux.c \ hgfsServerPacketUtil.c hgfsDirNotifyStub.c \ hgfsServerParameters.c AM_CFLAGS = -DVMTOOLS_USE_GLIB @GLIB2_CPPFLAGS@ all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/hgfsServer/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/hgfsServer/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libHgfsServer.la: $(libHgfsServer_la_OBJECTS) $(libHgfsServer_la_DEPENDENCIES) $(EXTRA_libHgfsServer_la_DEPENDENCIES) $(LINK) $(libHgfsServer_la_OBJECTS) $(libHgfsServer_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hgfsDirNotifyStub.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hgfsServer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hgfsServerLinux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hgfsServerPacketUtil.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hgfsServerParameters.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/vmCheck/0000755765153500003110000000000012220061623015560 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/vmCheck/vmcheck.c0000644765153500003110000001550112220061556017353 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vmcheck.c -- * * Utility functions for discovering our virtualization status. */ #include #include #ifdef WINNT_DDK # include #endif #include "vmware.h" #include "vm_version.h" #include "vm_tools_version.h" #if !defined(WINNT_DDK) # include "hostinfo.h" #endif /* * backdoor.h includes some files which redefine constants in ntddk.h. Ignore * warnings about these redefinitions for WIN32 platform. */ #ifdef WINNT_DDK #pragma warning (push) // Warning: Conditional expression is constant. #pragma warning( disable:4127 ) #endif #include "backdoor.h" #ifdef WINNT_DDK #pragma warning (pop) #endif #include "backdoor_def.h" #include "debug.h" typedef Bool (*SafeCheckFn)(void); #if !defined(_WIN32) # include "vmsignal.h" # include "setjmp.h" static sigjmp_buf jmpBuf; static Bool jmpIsSet; /* *---------------------------------------------------------------------- * * VmCheckSegvHandler -- * * Signal handler for segv. Return to the program state saved * by a previous call to sigsetjmp, or Panic if sigsetjmp hasn't * been called yet. This function never returns; * * Return Value: * None. * * Side effects: * See the manpage for sigsetjmp for details. * *---------------------------------------------------------------------- */ static void VmCheckSegvHandler(int clientData) // UNUSED { if (jmpIsSet) { siglongjmp(jmpBuf, 1); } else { Panic("Received SEGV, exiting."); } } #endif /* *---------------------------------------------------------------------- * * VmCheckSafe -- * * Calls a potentially unsafe function, trapping possible exceptions. * * Results: * * Return value of the passed function, or FALSE in case of exception. * * Side effects: * * Temporarily suppresses signals / SEH exceptions * *---------------------------------------------------------------------- */ static Bool VmCheckSafe(SafeCheckFn checkFn) { Bool result = FALSE; /* * On a real host this call should cause a GP and we catch * that and set result to FALSE. */ #if defined(_WIN32) __try { result = checkFn(); } __except(EXCEPTION_EXECUTE_HANDLER) { /* no op */ } #else do { int signals[] = { SIGILL, SIGSEGV, }; struct sigaction olds[ARRAYSIZE(signals)]; if (Signal_SetGroupHandler(signals, olds, ARRAYSIZE(signals), VmCheckSegvHandler) == 0) { Warning("%s: Failed to set signal handlers.\n", __FUNCTION__); break; } if (sigsetjmp(jmpBuf, TRUE) == 0) { jmpIsSet = TRUE; result = checkFn(); } else { jmpIsSet = FALSE; } if (Signal_ResetGroupHandler(signals, olds, ARRAYSIZE(signals)) == 0) { Warning("%s: Failed to reset signal handlers.\n", __FUNCTION__); } } while (0); #endif return result; } /* *---------------------------------------------------------------------- * * VmCheck_GetVersion -- * * Retrieve the version of VMware that's running on the * other side of the backdoor. * * Return value: * TRUE on success * *version contains the VMX version * *type contains the VMX type * FALSE on failure * * Side effects: * None * *---------------------------------------------------------------------- */ Bool VmCheck_GetVersion(uint32 *version, // OUT uint32 *type) // OUT { Backdoor_proto bp; ASSERT(version); ASSERT(type); /* Make sure EBX does not contain BDOOR_MAGIC */ bp.in.size = ~BDOOR_MAGIC; /* Make sure ECX does not contain any known VMX type */ bp.in.cx.halfs.high = 0xFFFF; bp.in.cx.halfs.low = BDOOR_CMD_GETVERSION; Backdoor(&bp); if (bp.out.ax.word == 0xFFFFFFFF) { /* * No backdoor device there. This code is not executing in a VMware * virtual machine. --hpreg */ return FALSE; } if (bp.out.bx.word != BDOOR_MAGIC) { return FALSE; } *version = bp.out.ax.word; /* * Old VMXs (workstation and express) didn't set their type. In that case, * our special pattern will still be there. --hpreg */ /* * Need to expand this out since the toolchain's gcc doesn't like mixing * integral types and enums in the same trinary operator. */ if (bp.in.cx.halfs.high == 0xFFFF) *type = VMX_TYPE_UNSET; else *type = bp.out.cx.word; return TRUE; } /* *---------------------------------------------------------------------- * * VmCheck_IsVirtualWorld -- * * Verify that we're running in a VM & we're version compatible with our * environment. * * Return value: * TRUE if we're in a virtual machine, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool VmCheck_IsVirtualWorld(void) { uint32 version; uint32 dummy; #if !defined(WINNT_DDK) if (VmCheckSafe(Hostinfo_TouchXen)) { Debug("%s: detected Xen.\n", __FUNCTION__); return FALSE; } if (VmCheckSafe(Hostinfo_TouchVirtualPC)) { Debug("%s: detected Virtual PC.\n", __FUNCTION__); return FALSE; } if (!VmCheckSafe(Hostinfo_TouchBackDoor)) { Debug("%s: backdoor not detected.\n", __FUNCTION__); return FALSE; } /* It should be safe to use the backdoor without a crash handler now. */ VmCheck_GetVersion(&version, &dummy); #else /* * The Win32 vmwvaudio driver uses this function, so keep the old, * VMware-only check. */ __try { VmCheck_GetVersion(&version, &dummy); } __except (GetExceptionCode() == STATUS_PRIVILEGED_INSTRUCTION) { return FALSE; } #endif if (version != VERSION_MAGIC) { Debug("The version of this program is incompatible with your %s.\n" "For information on updating your VMware Tools please see\n" "http://www.vmware.com/info?id=99\n" "\n", PRODUCT_LINE_NAME); return FALSE; } return TRUE; } open-vm-tools-9.4.0-1280544/lib/vmCheck/Makefile.am0000644765153500003110000000172412220061556017625 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libVmCheck.la libVmCheck_la_SOURCES = libVmCheck_la_SOURCES += vmcheck.c open-vm-tools-9.4.0-1280544/lib/vmCheck/Makefile.in0000644765153500003110000004356012220061623017635 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/vmCheck DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libVmCheck_la_LIBADD = am_libVmCheck_la_OBJECTS = vmcheck.lo libVmCheck_la_OBJECTS = $(am_libVmCheck_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libVmCheck_la_SOURCES) DIST_SOURCES = $(libVmCheck_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libVmCheck.la libVmCheck_la_SOURCES = vmcheck.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/vmCheck/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/vmCheck/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libVmCheck.la: $(libVmCheck_la_OBJECTS) $(libVmCheck_la_DEPENDENCIES) $(EXTRA_libVmCheck_la_DEPENDENCIES) $(LINK) $(libVmCheck_la_OBJECTS) $(libVmCheck_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmcheck.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/panic/0000755765153500003110000000000012220061622015271 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/panic/Makefile.am0000644765153500003110000000171412220061556017336 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libPanic.la libPanic_la_SOURCES = libPanic_la_SOURCES += panic.c open-vm-tools-9.4.0-1280544/lib/panic/panic.c0000644765153500003110000003325512220061556016545 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * panic.c -- * * Module to encapsulate common Panic behaviors. */ #include #include #include #include #ifdef _WIN32 # include # include #else // Posix # include #endif // Win32 vs Posix #include "vmware.h" #include "vm_version.h" #include "log.h" #include "panic.h" #include "msg.h" #include "str.h" #include "config.h" #include "util.h" #include "userlock.h" #if defined(_WIN32) || !defined(VMX86_TOOLS) #include "coreDump.h" #endif #ifdef _WIN32 #include "win32u.h" #endif typedef enum { PanicBreakLevel_Never, PanicBreakLevel_IfDebuggerAttached, PanicBreakLevel_Always } PanicBreakLevel; static struct PanicState { Bool msgPostOnPanic; Bool coreDumpOnPanic; Bool loopOnPanic; int coreDumpFlags; /* Memorize for clients without init func */ PanicBreakLevel breakOnPanic; /* XXX: should this be DEVEL only? */ char *coreDumpFile; } panicState = { TRUE, TRUE }; /* defaults in lieu of Panic_Init() */ /* *----------------------------------------------------------------------------- * * Panic_Init -- * * Inits the panic module. * * Results: * void * * Side effects: * Sets panic state. * *----------------------------------------------------------------------------- */ void Panic_Init(void) { panicState.coreDumpOnPanic = Config_GetBool(TRUE, "coreDumpOnPanic"); panicState.loopOnPanic = Config_GetBool(FALSE, "panic.loopOnPanic"); panicState.breakOnPanic = Config_GetLong(PanicBreakLevel_Never, "panic.breakOnPanic"); panicState.coreDumpFlags = Config_GetLong(0, "coreDumpFlags"); } /* *---------------------------------------------------------------------- * * Panic_SetPanicMsgPost -- * * Allow the Msg_Post() on panic to be suppressed. If passed FALSE, * then any subsequent Panics will refrain from posting the "VMWARE * Panic:" message. * * Results: * void. * * Side effects: * Enables/Disables Msg_Post on Panic(). * *---------------------------------------------------------------------- */ void Panic_SetPanicMsgPost(Bool postMsg) { panicState.msgPostOnPanic = postMsg; } /* *---------------------------------------------------------------------- * * Panic_GetPanicMsgPost -- * Returns panicState.msgPostOnPanic * * Results: * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool Panic_GetPanicMsgPost(void) { return panicState.msgPostOnPanic; } /* *---------------------------------------------------------------------- * * Panic_SetCoreDumpOnPanic -- * * Allow the core dump on panic to be suppressed. If passed FALSE, * then any subsequent Panics will not attempt to dump core. * * Results: * void. * * Side effects: * Enables/Disables core dump on Panic(). * * Bugs: * This really should act like Panic_Loop and Panic_Break, and just * be Panic_CoreDumpOnPanic, and not have to export the state back * out. That requires this module being the one that knows how to * actually carry out the core dump, which seems like a good thing * anyway. (Then Panic_Panic can do it too.) * *---------------------------------------------------------------------- */ void Panic_SetCoreDumpOnPanic(Bool dumpCore) { panicState.coreDumpOnPanic = dumpCore; } /* *----------------------------------------------------------------------------- * * Panic_GetCoreDumpOnPanic -- * * Returns whether panic should attempt to dump core. * * Results: * TRUE if panics should dump core. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool Panic_GetCoreDumpOnPanic(void) { return panicState.coreDumpOnPanic; } /* *----------------------------------------------------------------------------- * * Panic_GetCoreDumpFlags -- * * Return the core dump flags. The reason this module knows about this * is because it's available to everyone who wants to know, and has an * init function which is a convenient time to read configuration info. * Putting the same functionality elsewhere is harder. * * Results: * flags if set; 0 by default. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int Panic_GetCoreDumpFlags(void) { return panicState.coreDumpFlags; } /* *----------------------------------------------------------------------------- * * Panic_SetCoreDumpFlags -- * * Although the core dump flags are read at init time, we may want to * update this value later. This is especially true because the default * value is read before the VM config is established. * * Results: * None. * * Side effects: * Updates global struct panicState. * *----------------------------------------------------------------------------- */ void Panic_SetCoreDumpFlags(int flags) // IN { panicState.coreDumpFlags = flags; } /* *----------------------------------------------------------------------------- * * Panic_LoopOnPanic -- * * Loop until debugger intervention, if so configured. * * Results: * void, eventually. * * Side effects: * Stall for time. * *----------------------------------------------------------------------------- */ void Panic_LoopOnPanic(void) { if (panicState.loopOnPanic) { fprintf(stderr, "Looping pid=%d\n", (int)getpid()); while (panicState.loopOnPanic) { sleep(1); } } } /* *----------------------------------------------------------------------------- * * Panic_BreakOnPanic -- * * Attract the attention of a nearby debugger. * * Results: * void, eventually. * * Side effects: * DebugBreak. * *----------------------------------------------------------------------------- */ void Panic_BreakOnPanic(void) { #ifdef _WIN32 if (Panic_GetBreakOnPanic()) { Warning("Panic: breaking into debugger\n"); DebugBreak(); } #else /* XXX: Linux experts: is there any equivalent of attaching a JIT debugger? */ #endif } /* *----------------------------------------------------------------------------- * * Panic_SetBreakOnPanic -- * * Allow the debug breakpoint on panic to be suppressed. If passed FALSE, * then any subsequent Panics will not attempt to attract a debugger. * * Results: * void. * * Side effects: * Enables/Disables break into debugger on Panic(). * *----------------------------------------------------------------------------- */ void Panic_SetBreakOnPanic(Bool breakOnPanic) { panicState.breakOnPanic = breakOnPanic ? PanicBreakLevel_Always : PanicBreakLevel_Never; } /* *----------------------------------------------------------------------------- * * Panic_GetBreakOnPanic -- * * Whether or not we should break into the debugger on the current * panic iteration. * * Results: * TRUE if a break is in order, FALSE otherwise * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool Panic_GetBreakOnPanic(void) { Bool shouldBreak = FALSE; switch (panicState.breakOnPanic) { case PanicBreakLevel_Never: break; case PanicBreakLevel_IfDebuggerAttached: #ifdef _WIN32 { typedef BOOL (*pfnIsDebuggerPresent)(void); HMODULE kernelLibrary = Win32U_LoadLibrary("kernel32.dll"); if (kernelLibrary != NULL) { pfnIsDebuggerPresent IsDebuggerPresentFn = (pfnIsDebuggerPresent) GetProcAddress(kernelLibrary, "IsDebuggerPresent"); if (IsDebuggerPresentFn != NULL) { shouldBreak = IsDebuggerPresentFn(); } FreeLibrary(kernelLibrary); } } #else /* XXX: Linux experts? How do you know if you're being ptraced? */ #endif break; default: case PanicBreakLevel_Always: shouldBreak = TRUE; break; } return shouldBreak; } /* *----------------------------------------------------------------------------- * * Panic_SetCoreDumpFileName -- * * Record the filename of a core dump file so that a subsequent * Panic_PostPanicMsg can mention it by name. * * Pass NULL to say there's no core file; pass the empty string to * say there's a core file but you don't know where; pass the name * of the core file if you know it. * * Results: * void * * Side effects: * malloc; overwrites panicState.coreDumpFile * *----------------------------------------------------------------------------- */ void Panic_SetCoreDumpFileName(const char *fileName) { if (panicState.coreDumpFile) { free(panicState.coreDumpFile); } if (fileName) { panicState.coreDumpFile = strdup(fileName); } else { panicState.coreDumpFile = NULL; } } /* *----------------------------------------------------------------------------- * * Panic_GetCoreDumpFileName -- * * Returns the core dump filename if set. * * Results: * coredump filename if set, NULL otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ const char * Panic_GetCoreDumpFileName(void) { return panicState.coreDumpFile; } /* *----------------------------------------------------------------------------- * * Panic_Panic -- * * Panic, possibly core dump * * A nice default implementation that basic Panic can call if you don't * want to write your own. The VMX of course has its own. * * TODO: Figure out how to trigger the Mac OS X Crash Reporter. * * Results: * None. * * Side effects: * Death. * *----------------------------------------------------------------------------- */ void Panic_Panic(const char *format, va_list args) { char buf[1024]; static int count = 0; MXUser_SetInPanic(); Str_Vsnprintf(buf, sizeof buf, format, args); /* * Write the message to stderr first, so there's always * some sort of record. * Don't try to do anything fancy, since this is before * panic loop detection. In particular, try not to call * any of our functions (that may call Panic()). */ fputs(buf, stderr); #ifdef _WIN32 /* * This would nominally be Win32U_OutputDebugString. However, * OutputDebugString is unusual in that the W version converts * to local encoding and calls the A version. * * Since any such conversion is risky (read: can Panic) and * we haven't yet hit the loop detection, we will conservatively * dump UTF-8 via the A version. */ OutputDebugStringA(buf); #endif /* * Make sure Panic gets logged */ Log_DisableThrottling(); /* * Panic loop detection: * first time - do the whole report and shutdown sequence * second time - log and exit * beyond second time - just exit */ switch (count++) { case 0: break; case 1: Log("%s", buf); Log("Panic loop\n"); default: fprintf(stderr, "Panic loop\n"); Util_ExitProcessAbruptly(1); NOT_REACHED(); } #ifdef _WIN32 /* * Output again, in a way that we hope localizes correctly. Since * we are converting, this can Panic, so it must run after loop * detection. */ Win32U_OutputDebugString(buf); #endif /* * Log panic information, and make sure we don't remove * the log file on exit. */ Log("%s", buf); Util_Backtrace(0); Log_SetAlwaysKeep(TRUE); /* * Do the debugging steps early before we have a chance * to double panic. */ Panic_DumpGuiResources(); #if defined(_WIN32) || !defined(VMX86_TOOLS) if (Panic_GetCoreDumpOnPanic()) { CoreDump_CoreDump(); } #endif Panic_LoopOnPanic(); /* * Show pretty panic dialog. * This is where things can go badly wrong. */ Panic_PostPanicMsg(buf); /* * Bye */ Log("Exiting\n"); exit(-1); NOT_REACHED(); } /* *----------------------------------------------------------------------------- * * Panic_DumpGuiResources -- * * Dumps userlevel resources used by the current process. * * Results: * void * * Side effects: * Logs. * *----------------------------------------------------------------------------- */ void Panic_DumpGuiResources(void) { #ifdef _WIN32 HANDLE hUser = Win32U_GetModuleHandle("user32.dll"); if (hUser) { typedef DWORD (WINAPI *fnGetGuiResources)(HANDLE, DWORD); fnGetGuiResources pGetGuiResources = (fnGetGuiResources) GetProcAddress(hUser, "GetGuiResources"); if (pGetGuiResources) { Warning("Win32 object usage: GDI %d, USER %d\n", pGetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS), pGetGuiResources(GetCurrentProcess(), GR_USEROBJECTS)); } } #endif } open-vm-tools-9.4.0-1280544/lib/panic/Makefile.in0000644765153500003110000004351012220061622017341 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/panic DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libPanic_la_LIBADD = am_libPanic_la_OBJECTS = panic.lo libPanic_la_OBJECTS = $(am_libPanic_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libPanic_la_SOURCES) DIST_SOURCES = $(libPanic_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libPanic.la libPanic_la_SOURCES = panic.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/panic/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/panic/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libPanic.la: $(libPanic_la_OBJECTS) $(libPanic_la_DEPENDENCIES) $(EXTRA_libPanic_la_DEPENDENCIES) $(LINK) $(libPanic_la_OBJECTS) $(libPanic_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/panic.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/string/0000755765153500003110000000000012220061623015506 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/string/convertutf.h0000644765153500003110000001402612220061556020066 0ustar dtormts/* ********************************************************** * Copyright 2008 VMware, Inc. All rights reserved. * **********************************************************/ /* * Copyright 2001-2004 Unicode, Inc. * * Disclaimer * * This source code is provided as is by Unicode, Inc. No claims are * made as to fitness for any particular purpose. No warranties of any * kind are expressed or implied. The recipient agrees to determine * applicability of information provided. If this file has been * purchased on magnetic or optical media from Unicode, Inc., the * sole remedy for any claim will be exchange of defective media * within 90 days of receipt. * * Limitations on Rights to Redistribute This Code * * Unicode, Inc. hereby grants the right to freely use the information * supplied in this file in the creation of products supporting the * Unicode Standard, and to make copies of this file in any form * for internal or external distribution as long as this notice * remains attached. */ /* --------------------------------------------------------------------- Conversions between UTF32, UTF-16, and UTF-8. Header file. Several funtions are included here, forming a complete set of conversions between the three formats. UTF-7 is not included here, but is handled in a separate source file. Each of these routines takes pointers to input buffers and output buffers. The input buffers are const. Each routine converts the text between *sourceStart and sourceEnd, putting the result into the buffer between *targetStart and targetEnd. Note: the end pointers are *after* the last item: e.g. *(sourceEnd - 1) is the last item. The return result indicates whether the conversion was successful, and if not, whether the problem was in the source or target buffers. (Only the first encountered problem is indicated.) After the conversion, *sourceStart and *targetStart are both updated to point to the end of last text successfully converted in the respective buffers. Input parameters: sourceStart - pointer to a pointer to the source buffer. The contents of this are modified on return so that it points at the next thing to be converted. targetStart - similarly, pointer to pointer to the target buffer. sourceEnd, targetEnd - respectively pointers to the ends of the two buffers, for overflow checking only. These conversion functions take a ConversionFlags argument. When this flag is set to strict, both irregular sequences and isolated surrogates will cause an error. When the flag is set to lenient, both irregular sequences and isolated surrogates are converted. Whether the flag is strict or lenient, all illegal sequences will cause an error return. This includes sequences such as: , , or in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code must check for illegal sequences. When the flag is set to lenient, characters over 0x10FFFF are converted to the replacement character; otherwise (when the flag is set to strict) they constitute an error. Output parameters: The value "sourceIllegal" is returned from some routines if the input sequence is malformed. When "sourceIllegal" is returned, the source value will point to the illegal value that caused the problem. E.g., in UTF-8 when a sequence is malformed, it points to the start of the malformed sequence. Author: Mark E. Davis, 1994. Rev History: Rick McGowan, fixes & updates May 2001. Fixes & updates, Sept 2001. ------------------------------------------------------------------------ */ /* --------------------------------------------------------------------- The following 4 definitions are compiler-specific. The C standard does not guarantee that wchar_t has at least 16 bits, so wchar_t is no less portable than unsigned short! All should be unsigned values to avoid sign extension during bit mask & shift operations. ------------------------------------------------------------------------ */ #include "vm_basic_types.h" typedef uint32 UTF32; /* at least 32 bits */ typedef uint16 UTF16; /* at least 16 bits */ typedef uint8 UTF8; /* typically 8 bits */ typedef unsigned char Boolean; /* 0 or 1 */ /* Some fundamental constants */ #define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD #define UNI_MAX_BMP (UTF32)0x0000FFFF #define UNI_MAX_UTF16 (UTF32)0x0010FFFF #define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF #define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF typedef enum { conversionOK, /* conversion successful */ sourceExhausted, /* partial character in source, but hit end */ targetExhausted, /* insuff. room in target for conversion */ sourceIllegal /* source sequence is illegal/malformed */ } ConversionResult; typedef enum { strictConversion = 0, lenientConversion } ConversionFlags; /* This is for C++ and does no harm in C */ #ifdef __cplusplus extern "C" { #endif ConversionResult ConvertUTF8toUTF16 ( const UTF8** sourceStart, const UTF8* sourceEnd, UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); ConversionResult ConvertUTF16toUTF8 ( const UTF16** sourceStart, const UTF16* sourceEnd, UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); ConversionResult ConvertUTF8toUTF32 ( const UTF8** sourceStart, const UTF8* sourceEnd, UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); ConversionResult ConvertUTF32toUTF8 ( const UTF32** sourceStart, const UTF32* sourceEnd, UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); ConversionResult ConvertUTF16toUTF32 ( const UTF16** sourceStart, const UTF16* sourceEnd, UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); ConversionResult ConvertUTF32toUTF16 ( const UTF32** sourceStart, const UTF32* sourceEnd, UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); #ifdef __cplusplus } #endif /* --------------------------------------------------------------------- */ open-vm-tools-9.4.0-1280544/lib/string/bsd_vsnprintf.c0000644765153500003110000015057712220061556020557 0ustar dtormts/* ********************************************************** * Copyright 2006 VMware, Inc. All rights reserved. * **********************************************************/ /* * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * 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. */ /* * Note - this code originated as the file vfprintf.c in the FreeBSD * source code, location src/lib/libc/stdio/vfprintf.c, revision * 1.72. It has been borrowed and modified to act like vsnprintf * instead. For now, it only works for Windows. See bsd_output.h for * more. * * If you care to compare, the original is checked into this directory * as bsd_vsnprintf_orig.c. */ #if !defined(STR_NO_WIN32_LIBS) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) /* * Actual printf innards. * * This code is large and complicated... */ #include #include #include #include #ifndef _WIN32 #include #include #endif #include #include #include #include #include "vmware.h" #include "bsd_output_int.h" #include "codeset.h" #include "convertutf.h" #include "str.h" #if defined __ANDROID__ /* * Android doesn't support dtoa() or ldtoa(). */ #define NO_DTOA #define NO_LDTOA #endif static char *__ultoa(u_long, char *, int, int, const char *, int, char, const char *); static void __find_arguments(const char *, va_list, union arg **); static void __grow_type_table(int, enum typeid **, int *); char blanks[PADSIZE] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; char zeroes[PADSIZE] = {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; const char xdigs_lower[17] = "0123456789abcdef?"; const char xdigs_upper[17] = "0123456789ABCDEF?"; static Bool isLenientConversion = TRUE; int BSDFmt_SFVWrite(BSDFmt_StrBuf *sbuf, BSDFmt_UIO *uio) { int i; BSDFmt_IOV *siov; /* * If asprintf(), then grow the buffer as necessary. */ if (sbuf->alloc) { size_t n = sbuf->index + uio->uio_resid + 1; // +1 for \0 if (n > sbuf->size) { char *p; ASSERT(sbuf->size > 0); n = ROUNDUP(n, sbuf->size); if ((p = realloc(sbuf->buf, n)) == NULL) { sbuf->error = TRUE; return 1; } sbuf->buf = p; sbuf->size = n; } } for (i = 0, siov = uio->uio_iov; i < uio->uio_iovcnt; i++, siov++) { int numToWrite = sbuf->size - sbuf->index - 1; // -1 for \0 /* * Overflowing the buffer is not an error. * We just silently truncate because that's what snprintf() does. * * Always leave space for null termination. */ if (numToWrite > siov->iov_len) { numToWrite = siov->iov_len; } memcpy(sbuf->buf + sbuf->index, siov->iov_base, numToWrite); sbuf->index += numToWrite; } return 0; } /* * Flush out all the vectors defined by the given uio, * then reset it so that it can be reused. */ int BSDFmt_SPrint(BSDFmt_StrBuf *sbuf, BSDFmt_UIO *uio) { int err; if (uio->uio_resid == 0) { uio->uio_iovcnt = 0; return (0); } err = BSDFmt_SFVWrite(sbuf, uio); uio->uio_resid = 0; uio->uio_iovcnt = 0; return err; } /* * Convert an unsigned long to ASCII for printf purposes, returning * a pointer to the first character of the string representation. * Octal numbers can be forced to have a leading zero; hex numbers * use the given digits. */ static char * __ultoa(u_long val, char *endp, int base, int octzero, const char *xdigs, int needgrp, char thousep, const char *grp) { char *cp = endp; long sval; int ndig; /* * Handle the three cases separately, in the hope of getting * better/faster code. */ switch (base) { case 10: if (val < 10) { /* many numbers are 1 digit */ *--cp = to_char(val); return (cp); } ndig = 0; /* * On many machines, unsigned arithmetic is harder than * signed arithmetic, so we do at most one unsigned mod and * divide; this is sufficient to reduce the range of * the incoming value to where signed arithmetic works. */ if (val > LONG_MAX) { *--cp = to_char(val % 10); ndig++; sval = val / 10; } else { sval = val; } do { *--cp = to_char(sval % 10); ndig++; /* * If (*grp == CHAR_MAX) then no more grouping * should be performed. */ if (needgrp && ndig == *grp && *grp != CHAR_MAX && sval > 9) { *--cp = thousep; ndig = 0; /* * If (*(grp+1) == '\0') then we have to* use *grp character * (last grouping rule) for all next cases */ if (*(grp+1) != '\0') { grp++; } } sval /= 10; } while (sval != 0); break; case 8: do { *--cp = to_char(val & 7); val >>= 3; } while (val); if (octzero && *cp != '0') { *--cp = '0'; } break; case 16: do { *--cp = xdigs[val & 15]; val >>= 4; } while (val); break; default: /* oops */ abort(); } return (cp); } /* Identical to __ultoa, but for intmax_t. */ char * BSDFmt_UJToA(uintmax_t val, char *endp, int base, int octzero, const char *xdigs, int needgrp, char thousep, const char *grp) { char *cp = endp; intmax_t sval; int ndig; /* quick test for small values; __ultoa is typically much faster */ /* (perhaps instead we should run until small, then call __ultoa?) */ if (val <= ULONG_MAX) { return (__ultoa((u_long)val, endp, base, octzero, xdigs, needgrp, thousep, grp)); } switch (base) { case 10: if (val < 10) { *--cp = to_char(val % 10); return (cp); } ndig = 0; if (val > INTMAX_MAX) { *--cp = to_char(val % 10); ndig++; sval = val / 10; } else { sval = val; } do { *--cp = to_char(sval % 10); ndig++; /* * If (*grp == CHAR_MAX) then no more grouping should be performed. */ if (needgrp && *grp != CHAR_MAX && ndig == *grp && sval > 9) { *--cp = thousep; ndig = 0; /* * If (*(grp+1) == '\0') then we have to use *grp character * (last grouping rule) for all next cases */ if (*(grp+1) != '\0') { grp++; } } sval /= 10; } while (sval != 0); break; case 8: do { *--cp = to_char(val & 7); val >>= 3; } while (val); if (octzero && *cp != '0') { *--cp = '0'; } break; case 16: do { *--cp = xdigs[val & 15]; val >>= 4; } while (val); break; default: abort(); } return (cp); } /* * Convert a wide character string argument to a UTF-8 string * representation. If not -1, 'prec' specifies the maximum number of * bytes to output. The returned string is always NUL-terminated, even * if that results in the string exceeding 'prec' bytes. */ char * BSDFmt_WCharToUTF8(wchar_t *wcsarg, int prec) { ConversionResult cres; char *sourceStart, *sourceEnd; char *targStart, *targEnd; char *targ = NULL; size_t targSize; size_t sourceSize = wcslen(wcsarg) * sizeof(wchar_t); targSize = (-1 == prec) ? sourceSize : MIN(sourceSize, prec); while (TRUE) { /* * Pad by 4, because we need to NUL-terminate. */ targ = realloc(targ, targSize + 4); if (!targ) { goto exit; } targStart = targ; targEnd = targStart + targSize; sourceStart = (char *) wcsarg; sourceEnd = sourceStart + sourceSize; if (2 == sizeof(wchar_t)) { cres = ConvertUTF16toUTF8((const UTF16 **) &sourceStart, (const UTF16 *) sourceEnd, (UTF8 **) &targStart, (UTF8 *) targEnd, isLenientConversion); } else if (4 == sizeof(wchar_t)) { cres = ConvertUTF32toUTF8((const UTF32 **) &sourceStart, (const UTF32 *) sourceEnd, (UTF8 **) &targStart, (UTF8 *) targEnd, isLenientConversion); } else { NOT_IMPLEMENTED(); } if (targetExhausted == cres) { if (targSize == prec) { /* * We've got all the caller wants. */ break; } else { /* * Double buffer. */ targSize = (-1 == prec) ? targSize * 2 : MIN(targSize * 2, prec); } } else if ((sourceExhausted == cres) || (sourceIllegal == cres)) { /* * If lenient, the API converted all it could, so just * proceed, otherwise, barf. */ if (isLenientConversion) { break; } else { free(targ); targ = NULL; goto exit; } } else if (conversionOK == cres) { break; } else { NOT_IMPLEMENTED(); } } /* * Success, NUL-terminate. (The API updated targStart for us). */ ASSERT(targStart <= targEnd); targSize = targStart - targ; memset(targ + targSize, 0, 4); exit: return targ; } int bsd_vsnprintf_core(char **outbuf, char *groupingIn, char thousands_sepIn, char *decimal_point, size_t bufSize, const char *fmt0, va_list ap) { char *fmt; /* format string */ int ch; /* character from fmt */ int n, n2; /* handy integer (short term usage) */ char *cp; /* handy char pointer (short term usage) */ BSDFmt_IOV *iovp; /* for PRINT macro */ int flags; /* flags as above */ int ret; /* return value accumulator */ int width; /* width from format (%8d), or 0 */ int prec; /* precision from format; <0 for N/A */ char sign; /* sign prefix (' ', '+', '-', or \0) */ char thousands_sep; /* locale specific thousands separator */ char *grouping; /* locale specific numeric grouping rules */ #if !defined(NO_FLOATING_POINT) /* * We can decompose the printed representation of floating * point numbers into several parts, some of which may be empty: * * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ * A B ---C--- D E F * * A: 'sign' holds this value if present; '\0' otherwise * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal * C: cp points to the string MMMNNN. Leading and trailing * zeros are not in the string and must be added. * D: expchar holds this character; '\0' if no exponent, e.g. %f * F: at least two digits for decimal, at least one digit for hex */ #if defined __ANDROID__ static char dp = '.'; #endif int signflag; /* true if float is negative */ union { /* floating point arguments %[aAeEfFgG] */ double dbl; long double ldbl; } fparg; int expt = 0; /* integer value of exponent */ char expchar; /* exponent character: [eEpP\0] */ char *dtoaend; /* pointer to end of converted digits */ int expsize; /* character count for expstr */ int lead; /* sig figs before decimal or group sep */ int ndig; /* actual number of digits returned by dtoa */ char expstr[MAXEXPDIG + 2]; /* buffer for exponent string: e+ZZZ */ char *dtoaresult; /* buffer allocated by dtoa */ int nseps; /* number of group separators with ' */ int nrepeats; /* number of repeats of the last group */ #endif u_long ulval; /* integer arguments %[diouxX] */ uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ int base; /* base for [diouxX] conversion */ int dprec; /* a copy of prec if [diouxX], 0 otherwise */ int realsz; /* field size expanded by dprec, sign, etc */ int size; /* size of converted field or string */ int prsize; /* max size of printed field */ const char *xdigs; /* digits for %[xX] conversion */ BSDFmt_UIO uio; /* output information: summary */ BSDFmt_IOV iov[BSDFMT_NIOV]; /* ... and individual io vectors */ char buf[INT_CONV_BUF]; /* buffer with space for digits of uintmax_t */ char ox[2]; /* space for 0x; ox[1] is either x, X, or \0 */ union arg *argtable; /* args, built due to positional arg */ union arg statargtable [STATIC_ARG_TBL_SIZE]; int nextarg; /* 1-based argument index */ #ifndef _WIN32 va_list orgap; /* original argument pointer */ #endif char *convbuf = NULL; /* wide to multibyte conversion result */ BSDFmt_StrBuf sbuf; /* * BEWARE, these `goto error' on error, and PAD uses `n'. */ #define PRINT(ptr, len) { \ iovp->iov_base = (ptr); \ iovp->iov_len = (len) * sizeof (char); \ uio.uio_resid += (len) * sizeof (char); \ iovp++; \ if (++uio.uio_iovcnt >= BSDFMT_NIOV) { \ if (BSDFmt_SPrint(&sbuf, &uio)) \ goto error; \ iovp = iov; \ } \ } #define PAD(howmany, with) { \ if ((n = (howmany)) > 0) { \ while (n > PADSIZE) { \ PRINT(with, PADSIZE); \ n -= PADSIZE; \ } \ PRINT(with, n); \ } \ } #define PRINTANDPAD(p, ep, len, with) do { \ n2 = (ep) - (p); \ if (n2 > (len)) \ n2 = (len); \ if (n2 > 0) \ PRINT((p), n2); \ PAD((len) - (n2 > 0 ? n2 : 0), (with)); \ } while(0) #define FLUSH() { \ if (uio.uio_resid && BSDFmt_SPrint(&sbuf, &uio)) \ goto error; \ uio.uio_iovcnt = 0; \ iovp = iov; \ } /* * Get the argument indexed by nextarg. If the argument table is * built, use it to get the argument. If its not, get the next * argument (and arguments must be gotten sequentially). */ #define GETARG(type) \ ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \ (nextarg++, va_arg(ap, type))) /* * To extend shorts properly, we need both signed and unsigned * argument extraction methods. */ #define SARG() \ (flags&LONGINT ? GETARG(long) : \ flags&SHORTINT ? (long)(short)GETARG(int) : \ flags&CHARINT ? (long)(signed char)GETARG(int) : \ (long)GETARG(int)) #define UARG() \ (flags&LONGINT ? GETARG(u_long) : \ flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \ flags&CHARINT ? (u_long)(u_char)GETARG(int) : \ (u_long)GETARG(u_int)) #define SJARG() \ (flags&INTMAXT ? GETARG(intmax_t) : \ flags&SIZET ? (intmax_t)GETARG(size_t) : \ flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \ (intmax_t)GETARG(long long)) #define UJARG() \ (flags&INTMAXT ? GETARG(uintmax_t) : \ flags&SIZET ? (uintmax_t)GETARG(size_t) : \ flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \ (uintmax_t)GETARG(unsigned long long)) /* * Get * arguments, including the form *nn$. Preserve the nextarg * that the argument can be gotten once the type is determined. */ #define GETASTER(val) \ n2 = 0; \ cp = fmt; \ while (is_digit(*cp)) { \ n2 = 10 * n2 + to_digit(*cp); \ cp++; \ } \ if (*cp == '$') { \ int hold = nextarg; \ FIND_ARGUMENTS(); \ nextarg = n2; \ val = GETARG (int); \ nextarg = hold; \ fmt = ++cp; \ } else { \ val = GETARG (int); \ } /* * Windows can't scan the args twice, so always build argtable. * Otherwise, do it when we see an n$ argument. */ #ifndef _WIN32 #define FIND_ARGUMENTS() \ (argtable == NULL ? \ (argtable = statargtable, \ __find_arguments(fmt0, orgap, &argtable)) : \ (void) 0) #else #define FIND_ARGUMENTS() \ ASSERT(argtable != NULL) #endif xdigs = xdigs_lower; thousands_sep = '\0'; grouping = NULL; convbuf = NULL; #if !defined(NO_FLOATING_POINT) dtoaresult = NULL; #if !defined __ANDROID__ decimal_point = localeconv()->decimal_point; #else /* * Struct lconv is not working! For decimal_point, * using '.' instead is a workaround. */ decimal_point = &dp; #endif #endif fmt = (char *)fmt0; nextarg = 1; #ifndef _WIN32 argtable = NULL; va_copy(orgap, ap); #else argtable = statargtable; __find_arguments(fmt0, ap, &argtable); #endif uio.uio_iov = iovp = iov; uio.uio_resid = 0; uio.uio_iovcnt = 0; ret = 0; /* * Set up output string buffer structure. */ sbuf.alloc = (*outbuf == NULL); sbuf.error = FALSE; sbuf.buf = *outbuf; sbuf.size = bufSize; sbuf.index = 0; /* * If asprintf(), allocate initial buffer based on format length. * Empty format only needs one byte. Otherwise, round up to multiple of 64. */ if (sbuf.alloc) { size_t n = strlen(fmt0) + 1; // +1 for \0 if (n > 1) { n = ROUNDUP(n, 64); } if ((sbuf.buf = malloc(n * sizeof (char))) == NULL) { sbuf.error = TRUE; goto error; } sbuf.size = n; } // shut compile up #if !defined(NO_FLOATING_POINT) expchar = 0; expsize = 0; lead = 0; ndig = 0; nseps = 0; nrepeats = 0; #endif ulval = 0; ujval = 0; /* * Scan the format for conversions (`%' character). */ for (;;) { for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) /* void */; if ((n = fmt - cp) != 0) { if ((unsigned)ret + n > INT_MAX) { ret = EOF; goto error; } PRINT(cp, n); ret += n; } if (ch == '\0') { goto done; } fmt++; /* skip over '%' */ flags = 0; dprec = 0; width = 0; prec = -1; sign = '\0'; ox[1] = '\0'; rflag: ch = *fmt++; reswitch: switch (ch) { case ' ': /*- * ``If the space and + flags both appear, the space flag will be * ignored.'' -- ANSI X3J11 */ if (!sign) { sign = ' '; } goto rflag; case '#': flags |= ALT; goto rflag; case '*': /*- * ``A negative field width argument is taken as a flag followed by * a positive field width.''-- ANSI X3J11 * * They don't exclude field widths read from args. */ GETASTER (width); if (width >= 0) { goto rflag; } width = -width; /* FALLTHROUGH */ case '-': flags |= LADJUST; goto rflag; case '+': sign = '+'; goto rflag; case '\'': flags |= GROUPING; #if !defined __ANDROID__ thousands_sep = thousands_sepIn; grouping = groupingIn; #else /* * Struct lconv is not working! The code below is a workaround. */ thousands_sep = ','; #endif /* * Grouping should not begin with 0, but it nevertheless does (see * bug 281072) and makes the formatting code behave badly, so we * fix it up. */ if (grouping != NULL && *grouping == '\0') { static char g[] = { CHAR_MAX, '\0' }; grouping = g; } goto rflag; case '.': if ((ch = *fmt++) == '*') { GETASTER (prec); goto rflag; } prec = 0; while (is_digit(ch)) { prec = 10 * prec + to_digit(ch); ch = *fmt++; } goto reswitch; case '0': /*- * ``Note that 0 is taken as a flag, not as the beginning of a * field width.'' -- ANSI X3J11 */ flags |= ZEROPAD; goto rflag; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': n = 0; do { n = 10 * n + to_digit(ch); ch = *fmt++; } while (is_digit(ch)); if (ch == '$') { nextarg = n; FIND_ARGUMENTS(); goto rflag; } width = n; goto reswitch; case 'h': if (flags & SHORTINT) { flags &= ~SHORTINT; flags |= CHARINT; } else { flags |= SHORTINT; } goto rflag; case 'j': flags |= INTMAXT; goto rflag; case 'I': /* could be I64 - long long int is 64bit */ if (fmt[0] == '6' && fmt[1] == '4') { fmt += 2; flags |= LLONGINT; goto rflag; } /* could be I32 - normal int is 32bit */ if (fmt[0] == '3' && fmt[1] == '2') { fmt += 2; /* flags |= normal integer - it is 32bit for all our targets */ goto rflag; } /* * I alone - use Microsoft's semantic as size_t modifier. We do * not support glibc's semantic to use alternative digits. */ flags |= SIZET; goto rflag; case 'l': if (flags & LONGINT) { flags &= ~LONGINT; flags |= LLONGINT; } else flags |= LONGINT; goto rflag; case 'L': case 'q': flags |= LLONGINT; /* not necessarily */ goto rflag; case 't': flags |= PTRDIFFT; goto rflag; case 'Z': case 'z': flags |= SIZET; goto rflag; case 'C': flags |= LONGINT; /*FALLTHROUGH*/ case 'c': if (flags & LONGINT) { static const mbstate_t initial; mbstate_t mbs; size_t mbseqlen; mbs = initial; mbseqlen = wcrtomb(cp = buf, (wchar_t) GETARG(wint_t), &mbs); if (mbseqlen == (size_t) -1) { sbuf.error = TRUE; goto error; } size = (int) mbseqlen; } else { *(cp = buf) = GETARG(int); size = 1; } sign = '\0'; break; case 'D': flags |= LONGINT; /*FALLTHROUGH*/ case 'd': case 'i': if (flags & INTMAX_SIZE) { ujval = SJARG(); if ((intmax_t) ujval < 0) { ujval = -ujval; sign = '-'; } } else { ulval = SARG(); if ((long) ulval < 0) { ulval = -ulval; sign = '-'; } } base = 10; goto number; #if !defined(NO_FLOATING_POINT) case 'e': case 'E': expchar = ch; if (prec < 0) { /* account for digit before decpt */ prec = DEFPREC + 1; } else { prec++; } goto fp_begin; case 'f': case 'F': expchar = '\0'; goto fp_begin; case 'g': case 'G': expchar = ch - ('g' - 'e'); if (prec == 0) { prec = 1; } fp_begin: if (prec < 0) { prec = DEFPREC; } if (dtoaresult != NULL) { freedtoa(dtoaresult); } if (flags & LLONGINT) { fparg.ldbl = GETARG(long double); #if defined NO_LDTOA dtoaresult = NULL; /* * Below is to keep compiler happy */ signflag = -1; expt = 0; dtoaend = NULL; #else dtoaresult = cp = ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend); #endif } else { fparg.dbl = GETARG(double); #if defined NO_DTOA dtoaresult = NULL; /* * Below is to keep compiler happy */ signflag = -1; expt = 0; dtoaend = NULL; #else dtoaresult = cp = dtoa(fparg.dbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend); #endif } /* Our dtoa / ldtoa call strdup(), which can fail. PR319844 */ if (dtoaresult == NULL) { sbuf.error = TRUE; goto error; } flags |= FPT; if ((expt == 9999) || ((Str_Strcasecmp(cp, "-inf") == 0) || (Str_Strcasecmp(cp, "inf") == 0) || (Str_Strcasecmp(cp, "nan") == 0))) { if (*cp == '-') { sign = '-'; cp++; } cp = islower(ch) ? Str_ToLower(cp) : Str_ToUpper(cp); expt = INT_MAX; size = strlen(cp); break; } if (signflag) { sign = '-'; } ndig = dtoaend - cp; if (ch == 'g' || ch == 'G') { if (expt > -4 && expt <= prec) { /* Make %[gG] smell like %[fF] */ expchar = '\0'; if (flags & ALT) { prec -= expt; } else { prec = ndig - expt; } if (prec < 0) { prec = 0; } } else { /* * Make %[gG] smell like %[eE], but trim trailing zeroes * if no # flag. */ if (!(flags & ALT)) { prec = ndig; } } } if (expchar) { expsize = BSDFmt_Exponent(expstr, expt - 1, expchar); size = expsize + prec; if (prec > 1 || flags & ALT) { ++size; } } else { /* space for digits before decimal point */ if (expt > 0) { size = expt; } else { /* "0" */ size = 1; } /* space for decimal pt and following digits */ if (prec || flags & ALT) { size += prec + 1; } if (grouping && expt > 0) { /* space for thousands' grouping */ nseps = nrepeats = 0; lead = expt; while (*grouping != CHAR_MAX) { if (lead <= *grouping) { break; } lead -= *grouping; if (*(grouping + 1)) { nseps++; grouping++; } else { nrepeats++; } } size += nseps + nrepeats; } else { lead = expt; } } break; #endif /* !NO_FLOATING_POINT */ case 'n': /* * Assignment-like behavior is specified if the value overflows or * is otherwise unrepresentable. C99 says to use `signed char' * for %hhn conversions. */ if (flags & LLONGINT) { *GETARG(long long *) = ret; } else if (flags & SIZET) { *GETARG(size_t *) = (size_t)ret; } else if (flags & PTRDIFFT) { *GETARG(ptrdiff_t *) = ret; } else if (flags & INTMAXT) { *GETARG(intmax_t *) = ret; } else if (flags & LONGINT) { *GETARG(long *) = ret; } else if (flags & SHORTINT) { *GETARG(short *) = ret; } else if (flags & CHARINT) { *GETARG(signed char *) = ret; } else { *GETARG(int *) = ret; } continue; /* no output */ case 'O': flags |= LONGINT; /*FALLTHROUGH*/ case 'o': if (flags & INTMAX_SIZE) { ujval = UJARG(); } else { ulval = UARG(); } base = 8; goto nosign; case 'p': /*- * ``The argument shall be a pointer to void. The value of the * pointer is converted to a sequence of printable characters, in * an implementation- defined manner.'' -- ANSI X3J11 */ ujval = (uintmax_t)(uintptr_t) GETARG(void *); base = 16; xdigs = xdigs_upper; flags = flags | INTMAXT; /* * PR 103201 * VisualC sscanf doesn't grok '0x', so prefix zeroes. */ // ox[1] = 'x'; goto nosign; case 'S': flags |= LONGINT; /*FALLTHROUGH*/ case 's': if (flags & LONGINT) { wchar_t *wcp; /* Argument is wchar_t * */ if (convbuf != NULL) { free(convbuf); convbuf = NULL; } if ((wcp = GETARG(wchar_t *)) == NULL) { cp = "(null)"; } else { convbuf = BSDFmt_WCharToUTF8(wcp, prec); if (convbuf == NULL) { sbuf.error = TRUE; goto error; } cp = convbuf; } } else if ((cp = GETARG(char *)) == NULL) { /* Argument is char * */ cp = "(null)"; } if (prec >= 0) { /* * can't use strlen; can only look for the NUL in the first * `prec' characters, and strlen() will go further. */ char *p = memchr(cp, 0, (size_t)prec); if (p == NULL) { size = prec; } else { size = p - cp; if (size > prec) { size = prec; } } size = CodeSet_Utf8FindCodePointBoundary(cp, size); } else { size = strlen(cp); } sign = '\0'; break; case 'U': flags |= LONGINT; /*FALLTHROUGH*/ case 'u': if (flags & INTMAX_SIZE) ujval = UJARG(); else ulval = UARG(); base = 10; goto nosign; case 'X': xdigs = xdigs_upper; goto hex; case 'x': xdigs = xdigs_lower; hex: if (flags & INTMAX_SIZE) { ujval = UJARG(); } else { ulval = UARG(); } base = 16; /* leading 0x/X only if non-zero */ if (flags & ALT && (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0)) { ox[1] = ch; } flags &= ~GROUPING; /* unsigned conversions */ nosign: sign = '\0'; /*- * ``... diouXx conversions ... if a precision is specified, the * 0 flag will be ignored.'' -- ANSI X3J11 */ number: if ((dprec = prec) >= 0) { flags &= ~ZEROPAD; } /*- * ``The result of converting a zero value with an explicit * precision of zero is no characters.'' -- ANSI X3J11 * * ``The C Standard is clear enough as is. The call printf("%#.0o", 0) * should print 0.'' -- Defect Report #151 */ cp = buf + INT_CONV_BUF; if (flags & INTMAX_SIZE) { if (ujval != 0 || prec != 0 || (flags & ALT && base == 8)) { cp = BSDFmt_UJToA(ujval, cp, base, flags & ALT, xdigs, flags & GROUPING, thousands_sep, grouping); } } else { if (ulval != 0 || prec != 0 || (flags & ALT && base == 8)) { cp = __ultoa(ulval, cp, base, flags & ALT, xdigs, flags & GROUPING, thousands_sep, grouping); } } size = buf + INT_CONV_BUF - cp; if (size > INT_CONV_BUF) { /* should never happen */ abort(); } break; default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') { goto done; } /* pretend it was %c with argument ch */ cp = buf; *cp = ch; size = 1; sign = '\0'; break; } /* * All reasonable formats wind up here. At this point, `cp' points to * a string which (if not flags&LADJUST) should be padded out to `width' * places. If flags&ZEROPAD, it should first be prefixed by any sign * or other prefix; otherwise, it should be blank padded before the * prefix is emitted. After any left-hand padding and prefixing, emit * zeroes required by a decimal [diouxX] precision, then print the * string proper, then emit zeroes required by any leftover floating * precision; finally, if LADJUST, pad with blanks. * * Compute actual size, so we know how much to pad. size excludes * decimal prec; realsz includes it. */ realsz = dprec > size ? dprec : size; if (sign) { realsz++; } if (ox[1]) { realsz += 2; } prsize = width > realsz ? width : realsz; if ((unsigned)ret + prsize > INT_MAX) { ret = EOF; goto error; } /* right-adjusting blank padding */ if ((flags & (LADJUST | ZEROPAD)) == 0) { PAD(width - realsz, blanks); } /* prefix */ if (sign) { PRINT(&sign, 1); } #if !defined(NO_FLOATING_POINT) /* NAN, INF and -INF */ if ((flags & FPT) && (expt == INT_MAX)) { PRINT(cp, size); goto skip; } #endif if (ox[1]) { /* ox[1] is either x, X, or \0 */ ox[0] = '0'; PRINT(ox, 2); } /* right-adjusting zero padding */ if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) { PAD(width - realsz, zeroes); } /* leading zeroes from decimal precision */ PAD(dprec - size, zeroes); /* the string or number proper */ if (flags & FPT) { /* glue together f_p fragments */ #if defined(NO_FLOATING_POINT) NOT_IMPLEMENTED(); #else if (expchar) { /* %[fF] or sufficiently short %[gG] */ if (prec > 1 || flags & ALT) { buf[0] = *cp++; buf[1] = *decimal_point; PRINT(buf, 2); if (ndig > 0) { PRINT(cp, ndig - 1); PAD(prec - ndig, zeroes); } else { PAD(prec - ndig - 1, zeroes); } } else { /* XeYYY */ PRINT(cp, 1); } PRINT(expstr, expsize); } else { /* %[eE] or sufficiently long %[gG] */ if (expt <= 0) { PRINT(zeroes, 1); if (prec || flags & ALT) { PRINT(decimal_point, 1); } PAD(-expt, zeroes); /* already handled initial 0's */ prec += expt; } else { PRINTANDPAD(cp, dtoaend, lead, zeroes); cp += lead; if (grouping) { while (nseps > 0 || nrepeats > 0) { if (nrepeats > 0) { nrepeats--; } else { grouping--; nseps--; } PRINT(&thousands_sep, 1); PRINTANDPAD(cp, dtoaend, *grouping, zeroes); cp += *grouping; } if (cp > dtoaend) { cp = dtoaend; } } if (prec || flags & ALT) { PRINT(decimal_point, 1); } } PRINTANDPAD(cp, dtoaend, prec, zeroes); } #endif } else { PRINT(cp, size); } skip: /* left-adjusting padding (always blank) */ if (flags & LADJUST) { PAD(width - realsz, blanks); } /* finally, adjust ret */ ret += prsize; FLUSH(); /* copy out the I/O vectors */ } done: FLUSH(); /* * Always null terminate, unless buffer is size 0. */ ASSERT(!sbuf.error && ret >= 0); if (sbuf.size <= 0) { ASSERT(!sbuf.alloc); } else { ASSERT(sbuf.index < sbuf.size); sbuf.buf[sbuf.index] = '\0'; } error: #ifndef _WIN32 va_end(orgap); #endif #if !defined(NO_FLOATING_POINT) if (dtoaresult != NULL) { freedtoa(dtoaresult); } #endif if (convbuf != NULL) { free(convbuf); convbuf = NULL; } if (sbuf.error) { ret = EOF; } if ((argtable != NULL) && (argtable != statargtable)) { free (argtable); } // return allocated buffer on success, free it on failure if (sbuf.alloc) { if (ret < 0) { free(sbuf.buf); } else { *outbuf = sbuf.buf; } } return (ret); /* NOTREACHED */ #undef PRINT #undef PAD #undef PRINTANDPAD #undef FLUSH #undef GETARG #undef SARG #undef SJARG #undef UARG #undef UJARG #undef GETASTER #undef FIND_ARGUMENTS } int bsd_vsnprintf_c_locale(char **outbuf, size_t bufSize, const char *fmt0, va_list ap) { char thousands_sep; char *decimal_point; static char dp = '.'; /* * Perform a "%f" conversion always using the locale associated * with the C locale - "," for thousands, '.' for decimal point. */ thousands_sep = ','; decimal_point = &dp; return bsd_vsnprintf_core(outbuf, NULL, thousands_sep, decimal_point, bufSize, fmt0, ap); } int bsd_vsnprintf(char **outbuf, size_t bufSize, const char *fmt0, va_list ap) { char *grouping; char thousands_sep; char *decimal_point; #if defined(__ANDROID__) static char dp = '.'; /* * Struct lconv is not working! The code below is a workaround. */ NOT_TESTED(); grouping = NULL; thousands_sep = ','; decimal_point = &dp; #else grouping = localeconv()->grouping; thousands_sep = *(localeconv()->thousands_sep); decimal_point = localeconv()->decimal_point; #endif return bsd_vsnprintf_core(outbuf, grouping, thousands_sep, decimal_point, bufSize, fmt0, ap); } /* * Find all arguments when a positional parameter is encountered. Returns a * table, indexed by argument number, of pointers to each arguments. The * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries. * It will be replaces with a malloc-ed one if it overflows. */ static void __find_arguments (const char *fmt0, va_list ap, union arg **argtable) { char *fmt; /* format string */ int ch; /* character from fmt */ int n, n2; /* handy integer (short term usage) */ char *cp; /* handy char pointer (short term usage) */ int flags; /* flags as above */ enum typeid *typetable; /* table of types */ enum typeid stattypetable [STATIC_ARG_TBL_SIZE]; int tablesize; /* current size of type table */ int tablemax; /* largest used index in table */ int nextarg; /* 1-based argument index */ /* * Add an argument type to the table, expanding if necessary. */ #define ADDTYPE(type) \ ((nextarg >= tablesize) ? \ __grow_type_table(nextarg, &typetable, &tablesize) : (void)0, \ (nextarg > tablemax) ? tablemax = nextarg : 0, \ typetable[nextarg++] = type) #define ADDSARG() \ ((flags&INTMAXT) ? ADDTYPE(T_INTMAXT) : \ ((flags&SIZET) ? ADDTYPE(T_SIZET) : \ ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \ ((flags&LLONGINT) ? ADDTYPE(T_LLONG) : \ ((flags&LONGINT) ? ADDTYPE(T_LONG) : ADDTYPE(T_INT)))))) #define ADDUARG() \ ((flags&INTMAXT) ? ADDTYPE(T_UINTMAXT) : \ ((flags&SIZET) ? ADDTYPE(T_SIZET) : \ ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \ ((flags&LLONGINT) ? ADDTYPE(T_U_LLONG) : \ ((flags&LONGINT) ? ADDTYPE(T_U_LONG) : ADDTYPE(T_U_INT)))))) /* * Add * arguments to the type array. */ #define ADDASTER() \ n2 = 0; \ cp = fmt; \ while (is_digit(*cp)) { \ n2 = 10 * n2 + to_digit(*cp); \ cp++; \ } \ if (*cp == '$') { \ int hold = nextarg; \ nextarg = n2; \ ADDTYPE (T_INT); \ nextarg = hold; \ fmt = ++cp; \ } else { \ ADDTYPE (T_INT); \ } fmt = (char *)fmt0; typetable = stattypetable; tablesize = STATIC_ARG_TBL_SIZE; tablemax = 0; nextarg = 1; for (n = 0; n < STATIC_ARG_TBL_SIZE; n++) typetable[n] = T_UNUSED; /* * Scan the format for conversions (`%' character). */ for (;;) { for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) /* void */; if (ch == '\0') goto done; fmt++; /* skip over '%' */ flags = 0; rflag: ch = *fmt++; reswitch: switch (ch) { case ' ': case '#': goto rflag; case '*': ADDASTER (); goto rflag; case '-': case '+': case '\'': goto rflag; case '.': if ((ch = *fmt++) == '*') { ADDASTER (); goto rflag; } while (is_digit(ch)) { ch = *fmt++; } goto reswitch; case '0': goto rflag; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': n = 0; do { n = 10 * n + to_digit(ch); ch = *fmt++; } while (is_digit(ch)); if (ch == '$') { nextarg = n; goto rflag; } goto reswitch; case 'h': if (flags & SHORTINT) { flags &= ~SHORTINT; flags |= CHARINT; } else flags |= SHORTINT; goto rflag; case 'j': flags |= INTMAXT; goto rflag; case 'I': /* could be I64 - long long int is 64bit */ if (fmt[0] == '6' && fmt[1] == '4') { fmt += 2; flags |= LLONGINT; goto rflag; } /* could be I32 - normal int is 32bit */ if (fmt[0] == '3' && fmt[1] == '2') { fmt += 2; /* flags |= normal integer - it is 32bit for all our targets */ goto rflag; } /* * I alone - use Microsoft's semantic as size_t modifier. We do * not support glibc's semantic to use alternative digits. */ flags |= SIZET; goto rflag; case 'l': if (flags & LONGINT) { flags &= ~LONGINT; flags |= LLONGINT; } else flags |= LONGINT; goto rflag; case 'L': case 'q': flags |= LLONGINT; /* not necessarily */ goto rflag; case 't': flags |= PTRDIFFT; goto rflag; case 'Z': case 'z': flags |= SIZET; goto rflag; case 'C': flags |= LONGINT; /*FALLTHROUGH*/ case 'c': if (flags & LONGINT) ADDTYPE(T_WINT); else ADDTYPE(T_INT); break; case 'D': flags |= LONGINT; /*FALLTHROUGH*/ case 'd': case 'i': ADDSARG(); break; #if !defined(NO_FLOATING_POINT) case 'a': case 'A': case 'e': case 'E': case 'f': case 'g': case 'G': if (flags & LLONGINT) ADDTYPE(T_LONG_DOUBLE); else ADDTYPE(T_DOUBLE); break; #endif /* !NO_FLOATING_POINT */ case 'n': if (flags & INTMAXT) ADDTYPE(TP_INTMAXT); else if (flags & PTRDIFFT) ADDTYPE(TP_PTRDIFFT); else if (flags & SIZET) ADDTYPE(TP_SIZET); else if (flags & LLONGINT) ADDTYPE(TP_LLONG); else if (flags & LONGINT) ADDTYPE(TP_LONG); else if (flags & SHORTINT) ADDTYPE(TP_SHORT); else if (flags & CHARINT) ADDTYPE(TP_SCHAR); else ADDTYPE(TP_INT); continue; /* no output */ case 'O': flags |= LONGINT; /*FALLTHROUGH*/ case 'o': ADDUARG(); break; case 'p': ADDTYPE(TP_VOID); break; case 'S': flags |= LONGINT; /*FALLTHROUGH*/ case 's': if (flags & LONGINT) ADDTYPE(TP_WCHAR); else ADDTYPE(TP_CHAR); break; case 'U': flags |= LONGINT; /*FALLTHROUGH*/ case 'u': case 'X': case 'x': ADDUARG(); break; default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') goto done; break; } } done: /* * Build the argument table. */ if (tablemax >= STATIC_ARG_TBL_SIZE) { *argtable = (union arg *) malloc (sizeof (union arg) * (tablemax + 1)); } (*argtable) [0].intarg = 0; for (n = 1; n <= tablemax; n++) { switch (typetable [n]) { case T_UNUSED: /* whoops! */ (*argtable) [n].intarg = va_arg (ap, int); break; case TP_SCHAR: (*argtable) [n].pschararg = va_arg (ap, signed char *); break; case TP_SHORT: (*argtable) [n].pshortarg = va_arg (ap, short *); break; case T_INT: (*argtable) [n].intarg = va_arg (ap, int); break; case T_U_INT: (*argtable) [n].uintarg = va_arg (ap, unsigned int); break; case TP_INT: (*argtable) [n].pintarg = va_arg (ap, int *); break; case T_LONG: (*argtable) [n].longarg = va_arg (ap, long); break; case T_U_LONG: (*argtable) [n].ulongarg = va_arg (ap, unsigned long); break; case TP_LONG: (*argtable) [n].plongarg = va_arg (ap, long *); break; case T_LLONG: (*argtable) [n].longlongarg = va_arg (ap, long long); break; case T_U_LLONG: (*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long); break; case TP_LLONG: (*argtable) [n].plonglongarg = va_arg (ap, long long *); break; case T_PTRDIFFT: (*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t); break; case TP_PTRDIFFT: (*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *); break; case T_SIZET: (*argtable) [n].sizearg = va_arg (ap, size_t); break; case TP_SIZET: (*argtable) [n].psizearg = va_arg (ap, size_t *); break; case T_INTMAXT: (*argtable) [n].intmaxarg = va_arg (ap, intmax_t); break; case T_UINTMAXT: (*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t); break; case TP_INTMAXT: (*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *); break; #if !defined(NO_FLOATING_POINT) case T_DOUBLE: (*argtable) [n].doublearg = va_arg (ap, double); break; case T_LONG_DOUBLE: (*argtable) [n].longdoublearg = va_arg (ap, long double); break; #endif case TP_CHAR: (*argtable) [n].pchararg = va_arg (ap, char *); break; case TP_VOID: (*argtable) [n].pvoidarg = va_arg (ap, void *); break; case T_WINT: (*argtable) [n].wintarg = va_arg (ap, wint_t); break; case TP_WCHAR: (*argtable) [n].pwchararg = va_arg (ap, wchar_t *); break; } } if ((typetable != NULL) && (typetable != stattypetable)) free (typetable); #undef ADDTYPE #undef ADDSARG #undef ADDUARG #undef ADDASTER } /* * Increase the size of the type table. */ static void __grow_type_table (int nextarg, enum typeid **typetable, int *tablesize) { enum typeid *const oldtable = *typetable; const int oldsize = *tablesize; enum typeid *newtable; int n, newsize = oldsize * 2; if (newsize < nextarg + 1) { newsize = nextarg + 1; } if (oldsize == STATIC_ARG_TBL_SIZE) { if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL) { abort(); /* XXX handle better */ } memmove(newtable, oldtable, oldsize * sizeof(enum typeid)); } else { newtable = realloc(oldtable, newsize * sizeof(enum typeid)); if (newtable == NULL) { abort(); /* XXX handle better */ } } for (n = oldsize; n < newsize; n++) { newtable[n] = T_UNUSED; } *typetable = newtable; *tablesize = newsize; } #if !defined(NO_FLOATING_POINT) int BSDFmt_Exponent(char *p0, int exp, int fmtch) { char *p, *t; char expbuf[MAXEXPDIG]; p = p0; *p++ = fmtch; if (exp < 0) { exp = -exp; *p++ = '-'; } else { *p++ = '+'; } t = expbuf + MAXEXPDIG; if (exp < 10) { *p++ = '0'; } // See PR 704706: POSIX specifies that exponents < 100 only have 2 digits // if (exp < 100) { // *p++ = '0'; // } if (exp > 9) { do { *--t = to_char(exp % 10); } while ((exp /= 10) > 9); *--t = to_char(exp); for (; t < expbuf + MAXEXPDIG; *p++ = *t++); } else { *p++ = to_char(exp); } return (p - p0); } #endif /* !NO_FLOATING_POINT */ #endif /* !STR_NO_WIN32_LIBS|*BSD */ open-vm-tools-9.4.0-1280544/lib/string/bsd_output_int.h0000644765153500003110000000636012220061556020733 0ustar dtormts/* ********************************************************** * Copyright 2006 VMware, Inc. All rights reserved. * **********************************************************/ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * 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. */ /* * bsd_output_int.h -- * * Declarations private to the BSD-borrowed formatted output * funtions. */ #ifndef _BSD_OUTPUT_INT_H_ #define _BSD_OUTPUT_INT_H_ #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #include "bsd_output.h" #include "bsdfmt.h" union arg { int intarg; u_int uintarg; long longarg; u_long ulongarg; long long longlongarg; unsigned long long ulonglongarg; ptrdiff_t ptrdiffarg; size_t sizearg; intmax_t intmaxarg; uintmax_t uintmaxarg; void *pvoidarg; char *pchararg; signed char *pschararg; short *pshortarg; int *pintarg; long *plongarg; long long *plonglongarg; ptrdiff_t *pptrdiffarg; size_t *psizearg; intmax_t *pintmaxarg; #ifndef NO_FLOATING_POINT double doublearg; long double longdoublearg; #endif wint_t wintarg; wchar_t *pwchararg; }; /* * Type ids for argument type table. */ enum typeid { T_UNUSED, TP_SHORT, T_INT, T_U_INT, TP_INT, T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG, T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET, T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR, T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR }; #if defined _MSC_VER && _MSC_VER < 1400 /* VC80 has an internal wmemchr */ extern const wchar_t *wmemchr( const wchar_t * buf, wchar_t c, size_t count ); #endif extern wint_t bsd_btowc(int c); #endif // _BSD_OUTPUT_INT_H_ open-vm-tools-9.4.0-1280544/lib/string/Makefile.am0000644765153500003110000000223012220061556017544 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libString.la libString_la_SOURCES = if USE_PRINTF_WRAPPERS libString_la_SOURCES += bsd_output_shared.c libString_la_SOURCES += bsd_vsnprintf.c libString_la_SOURCES += bsd_vsnwprintf.c endif libString_la_SOURCES += convertutf.c libString_la_SOURCES += str.c open-vm-tools-9.4.0-1280544/lib/string/str.c0000644765153500003110000010662212220061556016476 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * str.c -- * * User level string wrappers * * WARNING: * Do not call any variadic functions - those that use "..." repeatedly * with the same va_list or memory corruption and/or crashes will occur. * The suggested way deal with repeated calls is to use a va_copy: * * va_list tmpArgs; * * va_copy(tmpArgs, ap); * // Call the variadic function * va_end(tmpArgs); * */ #ifdef _WIN32 #include #endif #include #include #include #include "vmware.h" #include "str.h" #ifdef HAS_BSD_PRINTF #include "bsd_output.h" #endif #include "codeset.h" #if defined _WIN32 && !defined HAS_BSD_PRINTF #define vsnprintf _vsnprintf #endif #ifndef _WIN32 extern int vasprintf(char **ptr, const char *f, va_list arg); /* * Declare vswprintf on platforms where it's not known to exist. We know * it's available on glibc >= 2.2, FreeBSD >= 5.0, and all versions of * Solaris. * (Re: Solaris, vswprintf has been present since Solaris 8, and we only * support Solaris 9 and above, since that was the first release available * for x86, so we just assume it's already there.) * * XXX Str_Vsnwprintf and friends are still protected by _WIN32 and * glibc >= 2.2. I.e., even though they should be able to work on * FreeBSD 5.0+ and Solaris 8+, they aren't made available there. */ # if !(defined(__linux__) || \ (defined(__FreeBSD__) && (__FreeBSD_version >= 500000)) || \ defined(sun)) extern int vswprintf(wchar_t *wcs, size_t maxlen, const wchar_t *format, va_list args); # endif #endif // _WIN32 /* *---------------------------------------------------------------------- * * Str_Vsnprintf -- * * Compatibility wrapper b/w different libc versions * * Results: * * int - number of bytes stored in 'str' (not including NUL * terminate character), -1 on overflow (insufficient space for * NUL terminate is considered overflow) * * NB: on overflow the buffer WILL be NUL terminated at the last * UTF-8 code point boundary within the buffer's bounds. * * WARNING: See warning at the top of this file. * * Side effects: * None * *---------------------------------------------------------------------- */ int Str_Vsnprintf(char *str, // OUT size_t size, // IN const char *format, // IN va_list ap) // IN { int retval; ASSERT(str != NULL); ASSERT(format != NULL); #ifdef HAS_BSD_PRINTF retval = bsd_vsnprintf(&str, size, format, ap); #else retval = vsnprintf(str, size, format, ap); #endif /* * Linux glibc 2.0.x returns -1 and NUL terminates (which we shouldn't * be linking against), but glibc 2.1.x follows c99 and returns * characters that would have been written. * * In the case of Win32 and !HAS_BSD_PRINTF, we are using * _vsnprintf(), which returns -1 on overflow, returns size * when result fits exactly, and does not NUL terminate in * those cases. */ if ((retval < 0) || (retval >= size)) { if (size > 0) { /* Find UTF-8 code point boundary and place NUL termination there */ int trunc = CodeSet_Utf8FindCodePointBoundary(str, size - 1); str[trunc] = '\0'; } } if (retval >= size) { return -1; } return retval; } #ifdef HAS_BSD_PRINTF /* *---------------------------------------------------------------------- * * Str_Sprintf_C_Locale -- * * sprintf wrapper that fails on overflow. Enforces numeric C locale. * * Results: * Returns the number of bytes stored in 'buf'. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Str_Sprintf_C_Locale(char *buf, // OUT: size_t maxSize, // IN: const char *fmt, // IN: ...) // IN: { uint32 *stack = (uint32*) &buf; va_list args; int retval; ASSERT(buf); ASSERT(fmt); va_start(args, fmt); retval = bsd_vsnprintf_c_locale(&buf, maxSize, fmt, args); va_end(args); if ((retval < 0) || (retval >= maxSize)) { if (maxSize > 0) { /* Find UTF-8 code point boundary and place NUL termination there */ int trunc = CodeSet_Utf8FindCodePointBoundary(buf, maxSize - 1); buf[trunc] = '\0'; } } if (retval >= maxSize) { Panic("%s:%d Buffer too small 0x%x\n", __FILE__, __LINE__, stack[-1]); } return retval; } #endif /* *---------------------------------------------------------------------- * * Str_Sprintf -- * * sprintf wrapper that fails on overflow * * Results: * Returns the number of bytes stored in 'buf'. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Str_Sprintf(char *buf, // OUT size_t maxSize, // IN const char *fmt, // IN ...) // IN { uint32 *stack = (uint32*) &buf; va_list args; int i; va_start(args, fmt); i = Str_Vsnprintf(buf, maxSize, fmt, args); va_end(args); if (i < 0) { Panic("%s:%d Buffer too small 0x%x\n", __FILE__, __LINE__, stack[-1]); } return i; } /* *---------------------------------------------------------------------- * * Str_Snprintf -- * * Compatibility wrapper b/w different libc versions * * Results: * * int - number of bytes stored in 'str' (not including NUL * terminate character), -1 on overflow (insufficient space for * NUL terminate is considered overflow) * * NB: on overflow the buffer WILL be NUL terminated * * Side effects: * None * *---------------------------------------------------------------------- */ int Str_Snprintf(char *str, // OUT size_t size, // IN const char *format, // IN ...) // IN { int retval; va_list args; ASSERT(str != NULL); ASSERT(format != NULL); va_start(args, format); retval = Str_Vsnprintf(str, size, format, args); va_end(args); return retval; } /* *---------------------------------------------------------------------- * * Str_Strcpy -- * * Wrapper for strcpy that checks for buffer overruns. * * Results: * Same as strcpy. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * Str_Strcpy(char *buf, // OUT const char *src, // IN size_t maxSize) // IN { uint32 *stack = (uint32 *)&buf; size_t len; ASSERT(buf != NULL); ASSERT(src != NULL); len = strlen(src); if (len >= maxSize) { Panic("%s:%d Buffer too small 0x%x\n", __FILE__, __LINE__, stack[-1]); ASSERT_BUG(5686, FALSE); } return memcpy(buf, src, len + 1); } /* *---------------------------------------------------------------------- * * Str_Strlen -- * * Calculate length of the string. * * Results: * Length of s not including the terminating '\0' character. * If there is no '\0' for first maxLen bytes, then it * returns maxLen. * * Side Effects: * None * *---------------------------------------------------------------------- */ size_t Str_Strlen(const char *s, // IN size_t maxLen) // IN { const char *end; ASSERT(s != NULL); if ((end = memchr(s, '\0', maxLen)) == NULL) { return maxLen; } return end - s; } /* *---------------------------------------------------------------------- * * Str_Strnstr -- * * Find a substring within a string of length at most n. 'sub' must be * NUL-terminated. 'n' is interpreted as an unsigned int. * * Results: * A pointer to the beginning of the substring, or NULL if not found. * * Side Effects: * None * *---------------------------------------------------------------------- */ char * Str_Strnstr(const char *src, // IN const char *sub, // IN size_t n) // IN { size_t subLen; const char *end; ASSERT(src != NULL); ASSERT(sub != NULL); if ((subLen = strlen(sub)) == 0) { return (char *) src; } if ((end = memchr(src, '\0', n)) == NULL) { end = src + n; } end -= subLen - 1; if (end <= src) { return NULL; } for (; (src = memchr(src, sub[0], end - src)) != NULL && memcmp(src, sub, subLen) != 0; src++) { } return (char *) src; } /* *---------------------------------------------------------------------- * * Str_Strcat -- * * Wrapper for strcat that checks for buffer overruns. * * Results: * Same as strcat. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * Str_Strcat(char *buf, // IN-OUT const char *src, // IN size_t maxSize) // IN { uint32 *stack = (uint32 *)&buf; size_t bufLen; size_t srcLen; ASSERT(buf != NULL); ASSERT(src != NULL); bufLen = strlen(buf); srcLen = strlen(src); /* The first comparison checks for numeric overflow */ if (bufLen + srcLen < srcLen || bufLen + srcLen >= maxSize) { Panic("%s:%d Buffer too small 0x%x\n", __FILE__, __LINE__, stack[-1]); } memcpy(buf + bufLen, src, srcLen + 1); return buf; } /* *---------------------------------------------------------------------- * * Str_Strncat -- * * Wrapper for strncat that checks for buffer overruns. * * Specifically, this function will Panic if a buffer overrun would * have occurred. * * Results: * Same as strncat. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * Str_Strncat(char *buf, // IN-OUT size_t bufSize, // IN: Size of buf const char *src, // IN: String to append size_t n) // IN: Max chars of src to append { uint32 *stack; size_t bufLen; ASSERT(buf != NULL); ASSERT(src != NULL); stack = (uint32 *)&buf; bufLen = strlen(buf); /* * Check bufLen + n first so we can avoid the second call to strlen * if possible. * * The reason the test with bufLen and n is >= rather than just > * is that strncat always NUL-terminates the resulting string, even * if it reaches the length limit n. This means that if it happens that * bufLen + n == bufSize, strncat will write a NUL terminator that * is outside of the buffer. Therefore, we make sure this does not * happen by adding the == case to the Panic test. */ if (bufLen + n >= bufSize && bufLen + strlen(src) >= bufSize) { Panic("%s:%d Buffer too small 0x%x\n", __FILE__,__LINE__, stack[-1]); } /* * We don't need to worry about NUL termination, because it's only * needed on overflow and we Panic above in that case. */ return strncat(buf, src, n); } /* *----------------------------------------------------------------------------- * * Str_Asprintf -- * * Same as Str_Vasprintf(), but parameters are passed inline * * Results: * Same as Str_Vasprintf() * * Side effects: * Same as Str_Vasprintf() * *----------------------------------------------------------------------------- */ char * Str_Asprintf(size_t *length, // OUT const char *format, // IN ...) // IN { va_list arguments; char *result; va_start(arguments, format); result = Str_Vasprintf(length, format, arguments); va_end(arguments); return result; } /* *----------------------------------------------------------------------------- * * Str_SafeAsprintf -- * * Same as Str_SafeVasprintf(), but parameters are passed inline * * Results: * Same as Str_SafeVasprintf() * * Side effects: * Same as Str_SafeVasprintf() * *----------------------------------------------------------------------------- */ char * Str_SafeAsprintf(size_t *length, // OUT const char *format, // IN ...) // IN { va_list arguments; char *result; va_start(arguments, format); result = Str_SafeVasprintf(length, format, arguments); va_end(arguments); return result; } /* *----------------------------------------------------------------------------- * * StrVasprintfInternal -- * * Allocate and format a string, using the GNU libc way to specify the * format (i.e. optionally allow the use of positional parameters) * * Results: * * The allocated string on success (if 'length' is not NULL, *length * is set to the length of the allocated string). * * ASSERTs or returns NULL on failure, depending on the value of * 'assertOnFailure'. * * WARNING: See warning at the top of this file. * * Side effects: * None * *----------------------------------------------------------------------------- */ static char * StrVasprintfInternal(size_t *length, // OUT: const char *format, // IN: va_list arguments, // IN: Bool assertOnFailure) // IN: { char *buf = NULL; int ret; #ifdef HAS_BSD_PRINTF ret = bsd_vsnprintf(&buf, 0, format, arguments); #elif !defined sun && !defined STR_NO_WIN32_LIBS ret = vasprintf(&buf, format, arguments); #else /* * Simple implementation of Str_Vasprintf when we we have vsnprintf * but not vasprintf (e.g. in Win32 or in drivers). We just fallback * to vsnprintf, doubling if we didn't have enough space. */ size_t bufSize = strlen(format); do { /* * Initial allocation of strlen(format) * 2. Should this be tunable? * XXX Yes, this could overflow and spin forever when you get near 2GB * allocations. I don't care. --rrdharan */ char *newBuf; va_list tmpArgs; bufSize *= 2; newBuf = realloc(buf, bufSize); if (!newBuf) { free(buf); buf = NULL; goto exit; } buf = newBuf; va_copy(tmpArgs, arguments); ret = Str_Vsnprintf(buf, bufSize, format, tmpArgs); va_end(tmpArgs); } while (ret < 0); #endif if (ret < 0) { buf = NULL; goto exit; } if (length != NULL) { *length = ret; } exit: if (assertOnFailure) { ASSERT_NOT_IMPLEMENTED(buf); } return buf; } /* *----------------------------------------------------------------------------- * * Str_Vasprintf -- * * See StrVasprintfInternal. * * Results: * Returns NULL on failure. * * WARNING: See warning at the top of this file. * * Side effects: * None *----------------------------------------------------------------------------- */ char * Str_Vasprintf(size_t *length, // OUT const char *format, // IN va_list arguments) // IN { return StrVasprintfInternal(length, format, arguments, FALSE); } /* *----------------------------------------------------------------------------- * * Str_SafeVasprintf -- * * See StrVasprintfInternal. * * Results: * Calls ASSERT_NOT_IMPLEMENTED on failure. * * WARNING: See warning at the top of this file. * * Side effects: * None * *----------------------------------------------------------------------------- */ char * Str_SafeVasprintf(size_t *length, // OUT const char *format, // IN va_list arguments) // IN { return StrVasprintfInternal(length, format, arguments, TRUE); } #if defined(_WIN32) || defined(__linux__) /* *---------------------------------------------------------------------- * * Str_Swprintf -- * * wsprintf wrapper that fails on overflow * * Results: * Returns the number of wchar_ts stored in 'buf'. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Str_Swprintf(wchar_t *buf, // OUT size_t maxSize, // IN: Size of buf, in wide-characters. const wchar_t *fmt, // IN ...) // IN { uint32 *stack = (uint32*) &buf; va_list args; int i; va_start(args,fmt); i = Str_Vsnwprintf(buf, maxSize, fmt, args); va_end(args); if (i < 0) { Panic("%s:%d Buffer too small 0x%x\n", __FILE__, __LINE__, stack[-1]); } return i; } /* *---------------------------------------------------------------------- * * Str_Vsnwprintf -- * * Compatibility wrapper b/w different libc versions * * Results: * * int - number of wchar_ts stored in 'str' (not including NUL * terminate character), -1 on overflow (insufficient space for * NUL terminate is considered overflow) * * NB: on overflow the buffer WILL be NUL terminated * * WARNING: See warning at the top of this file. * * Side effects: * None * *---------------------------------------------------------------------- */ int Str_Vsnwprintf(wchar_t *str, // OUT size_t size, // IN: Size of str, in wide-characters. const wchar_t *format, // IN va_list ap) // IN { int retval; #if defined(HAS_BSD_WPRINTF) && HAS_BSD_WPRINTF retval = bsd_vsnwprintf(&str, size, format, ap); #elif defined(_WIN32) retval = _vsnwprintf(str, size, format, ap); #else retval = vswprintf(str, size, format, ap); #endif /* * Linux glibc 2.0.x returns -1 and NUL terminates (which we shouldn't * be linking against), but glibc 2.1.x follows c99 and returns * characters that would have been written. * * In the case of Win32 and !HAS_BSD_PRINTF, we are using * _vsnwprintf(), which returns -1 on overflow, returns size * when result fits exactly, and does not NUL terminate in * those cases. */ #if defined _WIN32 && !defined HAS_BSD_PRINTF if ((retval < 0 || retval >= size) && size > 0) { str[size - 1] = L'\0'; } #endif if (retval >= size) { return -1; } return retval; } /* *---------------------------------------------------------------------- * * Str_Snwprintf -- * * Compatibility wrapper b/w different libc versions * * Results: * * int - number of wchar_ts stored in 'str' (not including NUL * terminate character), -1 on overflow (insufficient space for * NUL terminate is considered overflow) * * NB: on overflow the buffer WILL be NUL terminated * * Side effects: * None * *---------------------------------------------------------------------- */ int Str_Snwprintf(wchar_t *str, // OUT size_t size, // IN: Size of str, in wide-characters. const wchar_t *format, // IN ...) // IN { int retval; va_list args; va_start(args, format); retval = Str_Vsnwprintf(str, size, format, args); va_end(args); return retval; } /* *---------------------------------------------------------------------- * * Str_Wcscpy -- * * Wrapper for wcscpy that checks for buffer overruns. * * Results: * Same as wcscpy. * * Side effects: * None. * *---------------------------------------------------------------------- */ wchar_t * Str_Wcscpy(wchar_t *buf, // OUT const wchar_t *src, // IN size_t maxSize) // IN: Size of buf, in wide-characters. { uint32 *stack = (uint32 *)&buf; size_t len; len = wcslen(src); if (len >= maxSize) { Panic("%s:%d Buffer too small 0x%x\n", __FILE__, __LINE__, stack[-1]); ASSERT_BUG(5686, FALSE); } return memcpy(buf, src, (len + 1)*sizeof(wchar_t)); } /* *---------------------------------------------------------------------- * * Str_Wcscat -- * * Wrapper for wcscat that checks for buffer overruns. * * Results: * Same as wcscat. * * Side effects: * None. * *---------------------------------------------------------------------- */ wchar_t * Str_Wcscat(wchar_t *buf, // IN-OUT const wchar_t *src, // IN size_t maxSize) // IN: Size of buf, in wide-characters. { uint32 *stack = (uint32 *)&buf; size_t bufLen; size_t srcLen; bufLen = wcslen(buf); srcLen = wcslen(src); /* The first comparison checks for numeric overflow */ if (bufLen + srcLen < srcLen || bufLen + srcLen >= maxSize) { Panic("%s:%d Buffer too small 0x%x\n", __FILE__, __LINE__, stack[-1]); } memcpy(buf + bufLen, src, (srcLen + 1)*sizeof(wchar_t)); return buf; } /* *---------------------------------------------------------------------- * * Str_Wcsncat -- * * Wrapper for wcsncat that checks for buffer overruns. * * Specifically, this function will Panic if a buffer overrun would * have occurred. * * Results: * Same as wcsncat. * * Side effects: * None. * *---------------------------------------------------------------------- */ wchar_t * Str_Wcsncat(wchar_t *buf, // IN-OUT size_t bufSize, // IN: Size of buf, in wide-characters. const wchar_t *src, // IN: String to append size_t n) // IN: Max chars of src to append { uint32 *stack = (uint32 *)&buf; size_t bufLen = wcslen(buf); /* * Check bufLen + n first so we can avoid the second call to wcslen * if possible. * * The reason the test with bufLen and n is >= rather than just > * is that wcsncat always NUL-terminates the resulting string, even * if it reaches the length limit n. This means that if it happens that * bufLen + n == bufSize, wcsncat will write a NUL terminator that * is outside of the buffer. Therefore, we make sure this does not * happen by adding the == case to the Panic test. */ if (bufLen + n >= bufSize && bufLen + wcslen(src) >= bufSize) { Panic("%s:%d Buffer too small 0x%x\n", __FILE__,__LINE__, stack[-1]); } /* * We don't need to worry about NUL termination, because it's only * needed on overflow and we Panic above in that case. */ return wcsncat(buf, src, n); } /* *---------------------------------------------------------------------- * * Str_Mbscpy -- * * Wrapper for _mbscpy that checks for buffer overruns. * * Results: * Same as strcpy. * * Side effects: * None. * *---------------------------------------------------------------------- */ unsigned char * Str_Mbscpy(char *buf, // OUT const char *src, // IN size_t maxSize) // IN { uint32 *stack = (uint32 *)&buf; size_t len; len = strlen((const char *) src); if (len >= maxSize) { Panic("%s:%d Buffer too small 0x%x\n", __FILE__, __LINE__, stack[-1]); } return memcpy(buf, src, len + 1); } /* *---------------------------------------------------------------------- * * Str_Mbscat -- * * Wrapper for _mbscat that checks for buffer overruns. * * The Microsoft _mbscat may or may not deal with tailing * partial multibyte sequence in buf. We don't. * * Results: * Same as strcat. * * Side effects: * None. * *---------------------------------------------------------------------- */ unsigned char * Str_Mbscat(char *buf, // IN-OUT const char *src, // IN size_t maxSize) // IN { uint32 *stack = (uint32 *)&buf; size_t bufLen; size_t srcLen; bufLen = strlen((const char *) buf); srcLen = strlen((const char *) src); /* The first comparison checks for numeric overflow */ if (bufLen + srcLen < srcLen || bufLen + srcLen >= maxSize) { Panic("%s:%d Buffer too small 0x%x\n", __FILE__, __LINE__, stack[-1]); } memcpy(buf + bufLen, src, srcLen + 1); return (unsigned char *)buf; } /* *----------------------------------------------------------------------------- * * StrVaswprintfInternal -- * * Allocate and format a string. * * Results: * The allocated string on success (if 'length' is not NULL, *length * is set to the length of the allocated string, in wchat_ts) * * ASSERTs or returns NULL on failure, depending on the value of * 'assertOnFailure'. * * WARNING: See warning at the top of this file. * * Side effects: * None * *----------------------------------------------------------------------------- */ static wchar_t * StrVaswprintfInternal(size_t *length, // OUT: const wchar_t *format, // IN: va_list arguments, // IN Bool assertOnFailure) // IN { size_t bufSize; wchar_t *buf = NULL; int retval; bufSize = wcslen(format); do { /* * Initial allocation of wcslen(format) * 2. Should this be tunable? * XXX Yes, this could overflow and spin forever when you get near 2GB * allocations. I don't care. --rrdharan */ va_list tmpArgs; wchar_t *newBuf; bufSize *= 2; newBuf = realloc(buf, bufSize * sizeof(wchar_t)); if (!newBuf) { free(buf); buf = NULL; goto exit; } buf = newBuf; va_copy(tmpArgs, arguments); retval = Str_Vsnwprintf(buf, bufSize, format, tmpArgs); va_end(tmpArgs); } while (retval == -1); if (length) { *length = retval; } /* * Try to trim the buffer here to save memory? */ exit: if (assertOnFailure) { ASSERT_NOT_IMPLEMENTED(buf); } return buf; } /* *----------------------------------------------------------------------------- * * Str_Aswprintf -- * * Same as Str_Vaswprintf(), but parameters are passed inline. * * Results: * Same as Str_Vaswprintf() * * Side effects: * Same as Str_Vaswprintf() * *----------------------------------------------------------------------------- */ wchar_t * Str_Aswprintf(size_t *length, // OUT const wchar_t *format, // IN ...) // IN { va_list arguments; wchar_t *result; va_start(arguments, format); result = Str_Vaswprintf(length, format, arguments); va_end(arguments); return result; } /* *----------------------------------------------------------------------------- * * Str_Vaswprintf -- * * See StrVaswprintfInternal. * * Results: * Returns NULL on failure. * * WARNING: See warning at the top of this file. * * Side effects: * None * *----------------------------------------------------------------------------- */ wchar_t * Str_Vaswprintf(size_t *length, // OUT const wchar_t *format, // IN va_list arguments) // IN { return StrVaswprintfInternal(length, format, arguments, FALSE); } /* *----------------------------------------------------------------------------- * * Str_SafeAswprintf -- * * Same as Str_SafeVaswprintf(), but parameters are passed inline. * * Results: * Same as Str_SafeVaswprintf() * * Side effects: * Same as Str_SafeVaswprintf() * *----------------------------------------------------------------------------- */ wchar_t * Str_SafeAswprintf(size_t *length, // OUT const wchar_t *format, // IN ...) // IN { va_list arguments; wchar_t *result; va_start(arguments, format); result = Str_SafeVaswprintf(length, format, arguments); va_end(arguments); return result; } /* *----------------------------------------------------------------------------- * * Str_SafeVaswprintf -- * * See StrVaswprintfInternal. * * Results: * Calls ASSERT_NOT_IMPLEMENTED on failure. * * WARNING: See warning at the top of this file. * * Side effects: * None * *----------------------------------------------------------------------------- */ wchar_t * Str_SafeVaswprintf(size_t *length, // OUT const wchar_t *format, // IN va_list arguments) // IN { return StrVaswprintfInternal(length, format, arguments, TRUE); } #endif // defined(_WIN32) || defined(__linux__) #ifndef _WIN32 /* *----------------------------------------------------------------------------- * * Str_ToLower -- * * Convert a string to lowercase, in-place. Hand-rolled, for non-WIN32. * * Results: * * Returns the same pointer that was passed in. * * Side effects: * * See above. * *----------------------------------------------------------------------------- */ char * Str_ToLower(char *string) // IN { char *c = string; while (*c) { *c = (*c >= 'A' && *c <= 'Z') ? *c + ('a' - 'A') : *c; c++; } return string; } /* *----------------------------------------------------------------------------- * * Str_ToUpper -- * * Convert a string to uppercase, in-place. Hand-rolled, for non-WIN32. * * Results: * * Returns the same pointer that was passed in. * * Side effects: * * See above. * *----------------------------------------------------------------------------- */ char * Str_ToUpper(char *string) // IN { char *c = string; while (*c) { *c = (*c >= 'a' && *c <= 'z') ? *c - ('a' - 'A') : *c; c++; } return string; } #endif // !_WIN32 #if 0 /* * Unit tests. Compares our bsd_vs*printf code output to C-library * code output, where possible. */ static Bool bCompare; #define FAIL(s) \ do { \ printf("FAIL: %s\n", s); \ exit(1); \ } while (0); static void PrintAndCheck(char *fmt, // IN: ...) // IN: { char buf1[1024], buf2[1024]; int count; va_list args; va_start(args, fmt); count = Str_Vsnprintf(buf1, sizeof buf1, fmt, args); va_end(args); if (count < 0) { FAIL("PrintAndCheck new code count off"); } va_start(args, fmt); #ifdef _WIN32 count = _vsnprintf(buf2, sizeof buf2, fmt, args); #else count = vsnprintf(buf2, sizeof buf2, fmt, args); #endif va_end(args); if (count < 0) { FAIL("PrintAndCheck old code count off"); } if (bCompare && (0 != strcmp(buf1, buf2))) { printf("Format string: %s\n", fmt); printf("Our code: %s\n", buf1); printf("Sys code: %s\n", buf2); FAIL("PrintAndCheck compare failed"); } printf(buf1); } static void PrintAndCheckW(wchar_t *fmt, ...) { wchar_t buf1[1024], buf2[1024]; int count; va_list args; va_start(args, fmt); count = Str_Vsnwprintf(buf1, sizeof buf1, fmt, args); va_end(args); if (count < 0) { FAIL("PrintAndCheckW new code count off"); } va_start(args, fmt); #ifdef _WIN32 count = _vsnwprintf(buf2, sizeof buf2, fmt, args); #else count = vswprintf(buf2, sizeof buf2, fmt, args); #endif va_end(args); if (count < 0) { FAIL("PrintAndCheckW old code count off"); } if (bCompare && (0 != wcscmp(buf1, buf2))) { printf("Format string: %S", fmt); printf("Our code: %S", buf1); printf("Sys code: %S", buf2); FAIL("PrintAndCheckW compare failed"); } #ifndef _WIN32 printf("%S", buf1); #endif // _WIN32 } void Str_UnitTests(void) { char buf[1024]; wchar_t bufw[1024]; int count; int32 num1 = 0xDEADBEEF; int32 num2 = 0x927F82CD; int64 num3 = CONST64U(0xCAFEBABE42439021); #ifdef _WIN32 double num4 = 5.1923843; double num5 = 0.000482734; double num6 = 8274102.3872; #endif int numChars; char empty[1] = {'\0'}; wchar_t wempty[1] = {L'\0'}; /* test empty string */ count = Str_Snprintf(buf, 1, empty); if (0 != count) { FAIL("Failed empty string test"); } count = Str_Snwprintf(bufw, 1, wempty); if (0 != count) { FAIL("Failed empty string test (W)"); } /* test borderline overflow */ count = Str_Snprintf(buf, 2, "ba"); if (-1 != count) { FAIL("Failed borderline overflow test - count"); } if (buf[1]) { FAIL("Failed borderline overflow test - NULL term"); } count = Str_Snwprintf(bufw, 2, L"ba"); if (-1 != count) { FAIL("Failed borderline overflow test - count (W)"); } if (bufw[1]) { FAIL("Failed borderline overflow test - NULL term (W)"); } /* test egregious overflow */ count = Str_Snprintf(buf, 2, "baabaa"); if (-1 != count) { FAIL("Failed egregious overflow test - count"); } if (buf[1]) { FAIL("Failed egregious overflow test - NULL term"); } count = Str_Snwprintf(bufw, 2, L"baabaa"); if (-1 != count) { FAIL("Failed egregious overflow test - count (W)"); } if (bufw[1]) { FAIL("Failed egregious overflow test - NULL term (W)"); } /* test 'n' argument */ count = Str_Snprintf(buf, 1024, "foo %n\n", &numChars); if (-1 == count) { FAIL("Failed 'n' arg test - count"); } if (4 != numChars) { FAIL("Failed 'n' arg test - numChars"); } count = Str_Snwprintf(bufw, 1024, L"foo %n\n", &numChars); if (-1 == count) { FAIL("Failed 'n' arg test - count (W)"); } if (4 != numChars) { FAIL("Failed 'n' arg test - numChars (W)"); } bCompare = TRUE; // simple PrintAndCheck("hello\n"); PrintAndCheckW(L"hello\n"); // string arguments PrintAndCheck("whazz %s up %S doc\n", "hello", L"hello"); PrintAndCheckW(L"whazz %s up %S doc\n", L"hello", "hello"); // character arguments PrintAndCheck("whazz %c up %C doc\n", 'a', L'a'); PrintAndCheckW(L"whazz %c up %C doc\n", L'a', 'a'); // 32-bit integer arguments PrintAndCheck("%d %i %o %u %x %X\n", num1, num1, num1, num1, num1, num1); PrintAndCheckW(L"%d %i %o %u %x %X\n", num1, num1, num1, num1, num1, num1); // 'p' argument bCompare = FALSE; PrintAndCheck("%p\n", buf); PrintAndCheckW(L"%p\n", buf); bCompare = TRUE; // 64-bit bCompare = FALSE; PrintAndCheck("%LX %llX %qX\n", num3, num3, num3); PrintAndCheckW(L"%LX %llX %qX\n", num3, num3, num3); bCompare = TRUE; // more 64-bit #ifdef _WIN32 PrintAndCheck("%I64X\n", num3); PrintAndCheckW(L"%I64X\n", num3); #else PrintAndCheck("%LX\n", num3); PrintAndCheckW(L"%LX\n", num3); #endif #ifdef _WIN32 // exponent digits printed differs vs. POSIX // floating-point PrintAndCheck("%e %E %f %g %G\n", num4, num5, num6); PrintAndCheckW(L"%e %E %f %g %G\n", num4, num5, num6); #endif // positional arguments bCompare = FALSE; PrintAndCheck("%3$LX %1$x %2$x\n", num1, num2, num3); PrintAndCheckW(L"%3$LX %1$x %2$x\n", num1, num2, num3); bCompare = TRUE; #ifdef _WIN32 // exponent digits printed differs vs. POSIX // width and precision PrintAndCheck("%15.1g %20.2f %*.*f\n", num6, num6, 15, 3, num6); PrintAndCheckW(L"%15.1g %20.2f %*.*f\n", num6, num6, 15, 3, num6); #endif #ifdef _WIN32 // exponent digits printed differs vs. POSIX // flags PrintAndCheck("%-15e %+f %015g\n", num4, num5, num6); PrintAndCheckW(L"%-15e %+f %015g\n", num4, num5, num6); #endif #ifdef _WIN32 // exponent digits printed differs vs. POSIX // more flags PrintAndCheck("%#X %#E %#G\n", num1, num1, num1); PrintAndCheckW(L"%#X %#E %#G\n", num1, num1, num1); #endif } #endif // 0 open-vm-tools-9.4.0-1280544/lib/string/convertutf.c0000644765153500003110000004545512220061556020073 0ustar dtormts/* ********************************************************** * Copyright 2008 VMware, Inc. All rights reserved. * **********************************************************/ /* * Copyright 2001-2004 Unicode, Inc. * * Disclaimer * * This source code is provided as is by Unicode, Inc. No claims are * made as to fitness for any particular purpose. No warranties of any * kind are expressed or implied. The recipient agrees to determine * applicability of information provided. If this file has been * purchased on magnetic or optical media from Unicode, Inc., the * sole remedy for any claim will be exchange of defective media * within 90 days of receipt. * * Limitations on Rights to Redistribute This Code * * Unicode, Inc. hereby grants the right to freely use the information * supplied in this file in the creation of products supporting the * Unicode Standard, and to make copies of this file in any form * for internal or external distribution as long as this notice * remains attached. */ /* --------------------------------------------------------------------- Conversions between UTF32, UTF-16, and UTF-8. Source code file. Author: Mark E. Davis, 1994. Rev History: Rick McGowan, fixes & updates May 2001. Sept 2001: fixed const & error conditions per mods suggested by S. Parent & A. Lillich. June 2002: Tim Dodd added detection and handling of incomplete source sequences, enhanced error detection, added casts to eliminate compiler warnings. July 2003: slight mods to back out aggressive FFFE detection. Jan 2004: updated switches in from-UTF8 conversions. Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions. See the header file "ConvertUTF.h" for complete documentation. ------------------------------------------------------------------------ */ #include "convertutf.h" #ifdef CVTUTF_DEBUG #include #endif static const int halfShift = 10; /* used for shifting by 10 bits */ static const UTF32 halfBase = 0x0010000UL; static const UTF32 halfMask = 0x3FFUL; #define UNI_SUR_HIGH_START (UTF32)0xD800 #define UNI_SUR_HIGH_END (UTF32)0xDBFF #define UNI_SUR_LOW_START (UTF32)0xDC00 #define UNI_SUR_LOW_END (UTF32)0xDFFF #define false 0 #define true 1 /* --------------------------------------------------------------------- */ ConversionResult ConvertUTF32toUTF16 ( const UTF32** sourceStart, const UTF32* sourceEnd, UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { ConversionResult result = conversionOK; const UTF32* source = *sourceStart; UTF16* target = *targetStart; while (source < sourceEnd) { UTF32 ch; if (target >= targetEnd) { result = targetExhausted; break; } ch = *source++; if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { if (flags == strictConversion) { --source; /* return to the illegal value itself */ result = sourceIllegal; break; } else { *target++ = UNI_REPLACEMENT_CHAR; } } else { *target++ = (UTF16)ch; /* normal case */ } } else if (ch > UNI_MAX_LEGAL_UTF32) { if (flags == strictConversion) { result = sourceIllegal; } else { *target++ = UNI_REPLACEMENT_CHAR; } } else { /* target is a character in range 0xFFFF - 0x10FFFF. */ if (target + 1 >= targetEnd) { --source; /* Back up source pointer! */ result = targetExhausted; break; } ch -= halfBase; *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); } } *sourceStart = source; *targetStart = target; return result; } /* --------------------------------------------------------------------- */ ConversionResult ConvertUTF16toUTF32 ( const UTF16** sourceStart, const UTF16* sourceEnd, UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { ConversionResult result = conversionOK; const UTF16* source = *sourceStart; UTF32* target = *targetStart; UTF32 ch, ch2; while (source < sourceEnd) { const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ ch = *source++; /* If we have a surrogate pair, convert to UTF32 first. */ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { /* If the 16 bits following the high surrogate are in the source buffer... */ if (source < sourceEnd) { ch2 = *source; /* If it's a low surrogate, convert to UTF32. */ if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { ch = ((ch - UNI_SUR_HIGH_START) << halfShift) + (ch2 - UNI_SUR_LOW_START) + halfBase; ++source; } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ --source; /* return to the illegal value itself */ result = sourceIllegal; break; } } else { /* We don't have the 16 bits following the high surrogate. */ --source; /* return to the high surrogate */ result = sourceExhausted; break; } } else if (flags == strictConversion) { /* UTF-16 surrogate values are illegal in UTF-32 */ if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { --source; /* return to the illegal value itself */ result = sourceIllegal; break; } } if (target >= targetEnd) { source = oldSource; /* Back up source pointer! */ result = targetExhausted; break; } *target++ = ch; } *sourceStart = source; *targetStart = target; #ifdef CVTUTF_DEBUG if (result == sourceIllegal) { fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2); fflush(stderr); } #endif return result; } /* --------------------------------------------------------------------- */ /* * Index into the table below with the first byte of a UTF-8 sequence to * get the number of trailing bytes that are supposed to follow it. * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is * left as-is for anyone who may want to do such conversion, which was * allowed in earlier algorithms. */ static const char trailingBytesForUTF8[256] = { 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,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,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,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; /* * Magic values subtracted from a buffer value during UTF8 conversion. * This table contains as many values as there might be trailing bytes * in a UTF-8 sequence. */ static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; /* * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed * into the first byte, depending on how many bytes follow. There are * as many entries in this table as there are UTF-8 sequence types. * (I.e., one byte sequence, two byte... etc.). Remember that sequencs * for *legal* UTF-8 will be 4 or fewer bytes total. */ static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; /* --------------------------------------------------------------------- */ /* The interface converts a whole buffer to avoid function-call overhead. * Constants have been gathered. Loops & conditionals have been removed as * much as possible for efficiency, in favor of drop-through switches. * (See "Note A" at the bottom of the file for equivalent code.) * If your compiler supports it, the "isLegalUTF8" call can be turned * into an inline function. */ /* --------------------------------------------------------------------- */ ConversionResult ConvertUTF16toUTF8 ( const UTF16** sourceStart, const UTF16* sourceEnd, UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { ConversionResult result = conversionOK; const UTF16* source = *sourceStart; UTF8* target = *targetStart; while (source < sourceEnd) { UTF32 ch; unsigned short bytesToWrite = 0; const UTF32 byteMask = 0xBF; const UTF32 byteMark = 0x80; const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ ch = *source++; /* If we have a surrogate pair, convert to UTF32 first. */ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { /* If the 16 bits following the high surrogate are in the source buffer... */ if (source < sourceEnd) { UTF32 ch2 = *source; /* If it's a low surrogate, convert to UTF32. */ if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { ch = ((ch - UNI_SUR_HIGH_START) << halfShift) + (ch2 - UNI_SUR_LOW_START) + halfBase; ++source; } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ --source; /* return to the illegal value itself */ result = sourceIllegal; break; } } else { /* We don't have the 16 bits following the high surrogate. */ --source; /* return to the high surrogate */ result = sourceExhausted; break; } } else if (flags == strictConversion) { /* UTF-16 surrogate values are illegal in UTF-32 */ if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { --source; /* return to the illegal value itself */ result = sourceIllegal; break; } } /* Figure out how many bytes the result will require */ if (ch < (UTF32)0x80) { bytesToWrite = 1; } else if (ch < (UTF32)0x800) { bytesToWrite = 2; } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; } else if (ch < (UTF32)0x110000) { bytesToWrite = 4; } else { bytesToWrite = 3; ch = UNI_REPLACEMENT_CHAR; } target += bytesToWrite; if (target > targetEnd) { source = oldSource; /* Back up source pointer! */ target -= bytesToWrite; result = targetExhausted; break; } switch (bytesToWrite) { /* note: everything falls through. */ case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]); } target += bytesToWrite; } *sourceStart = source; *targetStart = target; return result; } /* --------------------------------------------------------------------- */ /* * Utility routine to tell whether a sequence of bytes is legal UTF-8. * This must be called with the length pre-determined by the first byte. * If not calling this from ConvertUTF8to*, then the length can be set by: * length = trailingBytesForUTF8[*source]+1; * and the sequence is illegal right away if there aren't that many bytes * available. * If presented with a length > 4, this returns false. The Unicode * definition of UTF-8 goes up to 4-byte sequences. */ static Boolean isLegalUTF8(const UTF8 *source, int length) { UTF8 a; const UTF8 *srcptr = source+length; switch (length) { default: return false; /* Everything else falls through when "true"... */ case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; case 2: if ((a = (*--srcptr)) > 0xBF) return false; switch (*source) { /* no fall-through in this inner switch */ case 0xE0: if (a < 0xA0) return false; break; case 0xED: if (a > 0x9F) return false; break; case 0xF0: if (a < 0x90) return false; break; case 0xF4: if (a > 0x8F) return false; break; default: if (a < 0x80) return false; } case 1: if (*source >= 0x80 && *source < 0xC2) return false; } if (*source > 0xF4) return false; return true; } /* --------------------------------------------------------------------- */ /* * Exported function to return whether a UTF-8 sequence is legal or not. * This is not used here; it's just exported. */ Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) { int length = trailingBytesForUTF8[*source]+1; if (source+length > sourceEnd) { return false; } return isLegalUTF8(source, length); } /* --------------------------------------------------------------------- */ ConversionResult ConvertUTF8toUTF16 ( const UTF8** sourceStart, const UTF8* sourceEnd, UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { ConversionResult result = conversionOK; const UTF8* source = *sourceStart; UTF16* target = *targetStart; while (source < sourceEnd) { UTF32 ch = 0; unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; if (source + extraBytesToRead >= sourceEnd) { result = sourceExhausted; break; } /* Do this check whether lenient or strict */ if (! isLegalUTF8(source, extraBytesToRead+1)) { result = sourceIllegal; break; } /* * The cases all fall through. See "Note A" below. */ switch (extraBytesToRead) { case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ case 3: ch += *source++; ch <<= 6; case 2: ch += *source++; ch <<= 6; case 1: ch += *source++; ch <<= 6; case 0: ch += *source++; } ch -= offsetsFromUTF8[extraBytesToRead]; if (target >= targetEnd) { source -= (extraBytesToRead+1); /* Back up source pointer! */ result = targetExhausted; break; } if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ /* UTF-16 surrogate values are illegal in UTF-32 */ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { if (flags == strictConversion) { source -= (extraBytesToRead+1); /* return to the illegal value itself */ result = sourceIllegal; break; } else { *target++ = UNI_REPLACEMENT_CHAR; } } else { *target++ = (UTF16)ch; /* normal case */ } } else if (ch > UNI_MAX_UTF16) { if (flags == strictConversion) { result = sourceIllegal; source -= (extraBytesToRead+1); /* return to the start */ break; /* Bail out; shouldn't continue */ } else { *target++ = UNI_REPLACEMENT_CHAR; } } else { /* target is a character in range 0xFFFF - 0x10FFFF. */ if (target + 1 >= targetEnd) { source -= (extraBytesToRead+1); /* Back up source pointer! */ result = targetExhausted; break; } ch -= halfBase; *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); } } *sourceStart = source; *targetStart = target; return result; } /* --------------------------------------------------------------------- */ ConversionResult ConvertUTF32toUTF8 ( const UTF32** sourceStart, const UTF32* sourceEnd, UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { ConversionResult result = conversionOK; const UTF32* source = *sourceStart; UTF8* target = *targetStart; while (source < sourceEnd) { UTF32 ch; unsigned short bytesToWrite = 0; const UTF32 byteMask = 0xBF; const UTF32 byteMark = 0x80; ch = *source++; if (flags == strictConversion ) { /* UTF-16 surrogate values are illegal in UTF-32 */ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { --source; /* return to the illegal value itself */ result = sourceIllegal; break; } } /* * Figure out how many bytes the result will require. Turn any * illegally large UTF32 things (> Plane 17) into replacement chars. */ if (ch < (UTF32)0x80) { bytesToWrite = 1; } else if (ch < (UTF32)0x800) { bytesToWrite = 2; } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; } else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4; } else { bytesToWrite = 3; ch = UNI_REPLACEMENT_CHAR; result = sourceIllegal; } target += bytesToWrite; if (target > targetEnd) { --source; /* Back up source pointer! */ target -= bytesToWrite; result = targetExhausted; break; } switch (bytesToWrite) { /* note: everything falls through. */ case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]); } target += bytesToWrite; } *sourceStart = source; *targetStart = target; return result; } /* --------------------------------------------------------------------- */ ConversionResult ConvertUTF8toUTF32 ( const UTF8** sourceStart, const UTF8* sourceEnd, UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { ConversionResult result = conversionOK; const UTF8* source = *sourceStart; UTF32* target = *targetStart; while (source < sourceEnd) { UTF32 ch = 0; unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; if (source + extraBytesToRead >= sourceEnd) { result = sourceExhausted; break; } /* Do this check whether lenient or strict */ if (! isLegalUTF8(source, extraBytesToRead+1)) { result = sourceIllegal; break; } /* * The cases all fall through. See "Note A" below. */ switch (extraBytesToRead) { case 5: ch += *source++; ch <<= 6; case 4: ch += *source++; ch <<= 6; case 3: ch += *source++; ch <<= 6; case 2: ch += *source++; ch <<= 6; case 1: ch += *source++; ch <<= 6; case 0: ch += *source++; } ch -= offsetsFromUTF8[extraBytesToRead]; if (target >= targetEnd) { source -= (extraBytesToRead+1); /* Back up the source pointer! */ result = targetExhausted; break; } if (ch <= UNI_MAX_LEGAL_UTF32) { /* * UTF-16 surrogate values are illegal in UTF-32, and anything * over Plane 17 (> 0x10FFFF) is illegal. */ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { if (flags == strictConversion) { source -= (extraBytesToRead+1); /* return to the illegal value itself */ result = sourceIllegal; break; } else { *target++ = UNI_REPLACEMENT_CHAR; } } else { *target++ = ch; } } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */ result = sourceIllegal; *target++ = UNI_REPLACEMENT_CHAR; } } *sourceStart = source; *targetStart = target; return result; } /* --------------------------------------------------------------------- Note A. The fall-through switches in UTF-8 reading code save a temp variable, some decrements & conditionals. The switches are equivalent to the following loop: { int tmpBytesToRead = extraBytesToRead+1; do { ch += *source++; --tmpBytesToRead; if (tmpBytesToRead) ch <<= 6; } while (tmpBytesToRead > 0); } In UTF-8 writing code, the switches on "bytesToWrite" are similarly unrolled loops. --------------------------------------------------------------------- */ open-vm-tools-9.4.0-1280544/lib/string/bsd_output_shared.c0000644765153500003110000002111612220061556021376 0ustar dtormts/* ********************************************************** * Copyright 2006 VMware, Inc. All rights reserved. * **********************************************************/ /* * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * 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. */ /* * Shared code common to the bsd_output_* implementation files. */ //#include #if !defined(STR_NO_WIN32_LIBS) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__ANDROID__) #include #include #ifndef _WIN32 #include #include #endif #include #include #include #include #ifndef _WIN32 #include #endif #include "vmware.h" #include "bsd_output_int.h" #ifndef NO_FLOATING_POINT /* *----------------------------------------------------------------------------- * * dtoa -- * * Pretend to be like the mysterious dtoa function in the FreeBSD * libc source code. It appears to take a double argument, and then * return an ASCII character string representation of this number - * just digits, no sign, decimal point, or exponent symbol. * * If 'mode' is 3, then 'prec' limits the number of digits after the * decimal point, if 'mode' is 2, then total digits. * * The base-10 exponent of the number is returned in 'expOut'. * * 'sign' is returned as 0 for a positive number, otherwise negative. * * 'strEnd' is returned as a pointer to the end of the number in the * string, so don't rely on NULL-termination to tell you where the * number ends. * * Results: * * The allocated string on success (free with freedtoa), NULL on * failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ char * dtoa(double d, // IN int mode, // IN int prec, // IN int *expOut, // OUT int *sign, // OUT char **strEnd) // OUT { char *str = NULL; int dec; #if defined(_WIN32) if (2 == mode) { str = malloc(_CVTBUFSIZE); if (str) { if (_ecvt_s(str, _CVTBUFSIZE, d, prec, &dec, sign)) { free(str); str = NULL; } } } else { ASSERT(3 == mode); str = malloc(_CVTBUFSIZE); if (str) { if (_fcvt_s(str, _CVTBUFSIZE, d, prec, &dec, sign)) { free(str); str = NULL; } } /* * When the value is not zero but rounds to zero at prec digits, * the Windows fcvt() sometimes returns the empty string and * a negative dec that goes too far (as in -dec > prec). * For example, converting 0.001 with prec 1 results in * the empty string and dec -2. (See bug 253674.) * * We just clamp dec to -prec when this happens. * * While this may appear to be a safe and good thing to * do in general. It really only works when the result is * all zeros or empty. Since checking for all zeros is * expensive, we only check for empty string, which works * for this bug. */ if (str && *str == '\0' && dec < 0 && dec < -prec) { dec = -prec; } } #else // _WIN32 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; if (2 == mode) { pthread_mutex_lock(&mutex); str = strdup(ecvt(d, prec, &dec, sign)); pthread_mutex_unlock(&mutex); } else { ASSERT(3 == mode); #ifdef __APPLE__ /* * The Mac fcvt() returns "" when prec is 0, so we have to * compensate. See bug 233530. * While it is conceivable that fcvt(round(d), 1) can return * a string that doesn't end in 0, it doesn't seem to happen * in practice (on the Mac). The problematic case that we * want to avoid is a last digit greater than 4, which requires * rounding up, which we don't want to do, which is why we're * doing the rounding on the number instead of after fcvt() * in the first place. * -- edward */ if (prec == 0) { size_t l; pthread_mutex_lock(&mutex); str = strdup(fcvt(round(d), 1, &dec, sign)); pthread_mutex_unlock(&mutex); if (str) { l = strlen(str); ASSERT(l > 0); l--; ASSERT(str[l] == '0'); str[l] = '\0'; } } else #endif // __APPLE__ { pthread_mutex_lock(&mutex); str = strdup(fcvt(d, prec, &dec, sign)); pthread_mutex_unlock(&mutex); } } #endif // _WIN32 if (str) { *strEnd = str + strlen(str); /* strip trailing zeroes */ while ((*strEnd > str) && ('0' == *((*strEnd) - 1))) { (*strEnd)--; } *expOut = dec; } return str; } /* *----------------------------------------------------------------------------- * * ldtoa -- * * A dtoa wrapper that simply casts its long double argument to a * double. Windows can't handle long double. * * Results: * See dtoa. * * Side effects: * None * *----------------------------------------------------------------------------- */ char * ldtoa(long double *ld, int mode, int prec, int *exp, int *sign, char **strEnd) { double d = (double) *ld; // ghetto fabulous return dtoa(d, mode, prec, exp, sign, strEnd); } /* *----------------------------------------------------------------------------- * * freedtoa -- * * Free the result of dtoa and ldtoa. * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ void freedtoa(void *mem) { free(mem); } #if defined _MSC_VER && _MSC_VER < 1400 /* VC80 has a built-in wmemchar */ /* *----------------------------------------------------------------------------- * * wmemchr -- * * Stolen from FreeBSD. Find 'c' in 's', which is 'n' characters * long. * * Results: * The pointer to the first occurence of 'c' in 's', NULL otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ const wchar_t * wmemchr(const wchar_t *s, wchar_t c, size_t n) { size_t i; for (i = 0; i < n; i++) { if (*s == c) { /* LINTED const castaway */ return (wchar_t *)s; } s++; } return NULL; } #endif /* *----------------------------------------------------------------------------- * * btowc -- * * Stolen from FreeBSD. Convert the MBCS character 'c' to a wide * character. * * Results: * The wide character on success, WEOF on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ wint_t bsd_btowc(int c) { char cc; wchar_t wc; if (c == EOF) return (WEOF); /* * We expect mbtowc() to return 0 or 1, hence the check for n > 1 * which detects error return values as well as "impossible" byte * counts. */ cc = (char)c; if (mbtowc(&wc, &cc, 1) > 1) return (WEOF); return (wc); } #endif /* !NO_FLOATING_POINT */ #endif /* !STR_NO_WIN32_LIBS|*BSD */ open-vm-tools-9.4.0-1280544/lib/string/bsd_vsnwprintf.c0000644765153500003110000014471012220061556020736 0ustar dtormts/* ********************************************************** * Copyright 2006 VMware, Inc. All rights reserved. * **********************************************************/ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * 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. */ /* * Note - this code originated as the file vfwprintf.c in the FreeBSD * source code, location src/lib/libc/stdio/vfwprintf.c, revision * 1.24. It has been borrowed and modified to act like vsnwprintf * instead. See bsd_output.h for more. * * If you care to compare, the original is checked into this directory * as bsd_vsnwprintf_orig.c. */ #if !defined(STR_NO_WIN32_LIBS) && !defined(__FreeBSD__) \ && !defined(__OpenBSD__) && !defined(__NetBSD__) /* * Actual wprintf innards. */ #include #include #include #include #include #include #include #include #include "vmware.h" #include "bsd_output_int.h" #include "msgfmt.h" #include "convertutf.h" typedef struct StrBuf { Bool alloc; Bool error; wchar_t *buf; size_t size; size_t index; } StrBuf; static int __sfvwrite(StrBuf *sbuf, BSDFmt_UIO *uio); static int __sprint(StrBuf *sbuf, BSDFmt_UIO *uio); static wchar_t *__ujtoa(uintmax_t, wchar_t *, int, int, const char *, int, char, const char *); static wchar_t *__ultoa(u_long, wchar_t *, int, int, const char *, int, char, const char *); static wchar_t *BSDFmt_UTF8ToWChar(const char *, int); static void __find_arguments(const wchar_t *, va_list, union arg **); static void __grow_type_table(int, enum typeid **, int *); static Bool isLenientConversion = TRUE; static int __sfvwrite(StrBuf *sbuf, BSDFmt_UIO *uio) { int i; BSDFmt_IOV *siov; /* * If aswprintf(), then grow the buffer as necessary. */ if (sbuf->alloc) { size_t n = sbuf->index + uio->uio_resid + 1; // +1 for \0 if (n > sbuf->size) { wchar_t *p; ASSERT(sbuf->size > 0); n = ROUNDUP(n, sbuf->size); if ((p = realloc(sbuf->buf, n * sizeof(wchar_t))) == NULL) { sbuf->error = TRUE; return 1; } sbuf->buf = p; sbuf->size = n; } } for (i = 0, siov = uio->uio_iov; i < uio->uio_iovcnt; i++, siov++) { int numToWrite; /* * Overflowing the buffer is not an error. * We just silently truncate because that's what snprintf() does. * * Always leave space for null termination. */ numToWrite = sbuf->size - sbuf->index - 1; // -1 for \0 if (numToWrite > siov->iov_len) { numToWrite = siov->iov_len; } memcpy(sbuf->buf + sbuf->index, siov->iov_base, numToWrite * sizeof(wchar_t)); sbuf->index += numToWrite; } return 0; } /* * Flush out all the vectors defined by the given uio, * then reset it so that it can be reused. */ static int __sprint(StrBuf *sbuf, BSDFmt_UIO *uio) { int err; if (uio->uio_resid == 0) { uio->uio_iovcnt = 0; return (0); } err = __sfvwrite(sbuf, uio); uio->uio_resid = 0; uio->uio_iovcnt = 0; return err; } /* * Convert an unsigned long to ASCII for printf purposes, returning * a pointer to the first character of the string representation. * Octal numbers can be forced to have a leading zero; hex numbers * use the given digits. */ static wchar_t * __ultoa(u_long val, wchar_t *endp, int base, int octzero, const char *xdigs, int needgrp, char thousep, const char *grp) { wchar_t *cp = endp; long sval; int ndig; /* * Handle the three cases separately, in the hope of getting * better/faster code. */ switch (base) { case 10: if (val < 10) { /* many numbers are 1 digit */ *--cp = to_char(val); return (cp); } ndig = 0; /* * On many machines, unsigned arithmetic is harder than * signed arithmetic, so we do at most one unsigned mod and * divide; this is sufficient to reduce the range of * the incoming value to where signed arithmetic works. */ if (val > LONG_MAX) { *--cp = to_char(val % 10); ndig++; sval = val / 10; } else sval = val; do { *--cp = to_char(sval % 10); ndig++; /* * If (*grp == CHAR_MAX) then no more grouping * should be performed. */ if (needgrp && ndig == *grp && *grp != CHAR_MAX && sval > 9) { *--cp = thousep; ndig = 0; /* * If (*(grp+1) == '\0') then we have to * use *grp character (last grouping rule) * for all next cases */ if (*(grp+1) != '\0') grp++; } sval /= 10; } while (sval != 0); break; case 8: do { *--cp = to_char(val & 7); val >>= 3; } while (val); if (octzero && *cp != '0') *--cp = '0'; break; case 16: do { *--cp = xdigs[val & 15]; val >>= 4; } while (val); break; default: /* oops */ abort(); } return (cp); } /* Identical to __ultoa, but for intmax_t. */ static wchar_t * __ujtoa(uintmax_t val, wchar_t *endp, int base, int octzero, const char *xdigs, int needgrp, char thousep, const char *grp) { wchar_t *cp = endp; intmax_t sval; int ndig; /* quick test for small values; __ultoa is typically much faster */ /* (perhaps instead we should run until small, then call __ultoa?) */ if (val <= ULONG_MAX) return (__ultoa((u_long)val, endp, base, octzero, xdigs, needgrp, thousep, grp)); switch (base) { case 10: if (val < 10) { *--cp = to_char(val % 10); return (cp); } ndig = 0; if (val > INTMAX_MAX) { *--cp = to_char(val % 10); ndig++; sval = val / 10; } else sval = val; do { *--cp = to_char(sval % 10); ndig++; /* * If (*grp == CHAR_MAX) then no more grouping * should be performed. */ if (needgrp && *grp != CHAR_MAX && ndig == *grp && sval > 9) { *--cp = thousep; ndig = 0; /* * If (*(grp+1) == '\0') then we have to * use *grp character (last grouping rule) * for all next cases */ if (*(grp+1) != '\0') grp++; } sval /= 10; } while (sval != 0); break; case 8: do { *--cp = to_char(val & 7); val >>= 3; } while (val); if (octzero && *cp != '0') *--cp = '0'; break; case 16: do { *--cp = xdigs[val & 15]; val >>= 4; } while (val); break; default: abort(); } return (cp); } /* * Convert a UTF-8 string argument to a wide-character string * representation. If not -1, 'prec' specifies the maximum number of * wide characters to output. The returned string is always NUL-terminated, * even if that results in the string exceeding 'prec' characters. */ wchar_t * BSDFmt_UTF8ToWChar(const char *arg, // IN int prec) // IN { ConversionResult cres; const char *sourceStart, *sourceEnd; wchar_t *targStart, *targEnd; wchar_t *targ = NULL; /* * targSize and sourceSize are measured in wchar_t units, excluding NUL. */ size_t targSize; size_t sourceSize = strlen(arg); ASSERT(prec == -1 || prec >= 0); targSize = sourceSize; if (prec >= 0) { targSize = MIN(targSize, prec); } while (TRUE) { /* * Pad by 1 because we need to NUL-terminate. */ wchar_t *oldTarg = targ; targ = realloc(oldTarg, (targSize + 1) * sizeof *targ); if (!targ) { free(oldTarg); goto exit; } targStart = targ; targEnd = targStart + targSize; sourceStart = arg; sourceEnd = sourceStart + sourceSize; if (2 == sizeof(wchar_t)) { cres = ConvertUTF8toUTF16((const UTF8 **) &sourceStart, (const UTF8 *) sourceEnd, (UTF16 **) &targStart, (UTF16 *) targEnd, isLenientConversion); } else if (4 == sizeof(wchar_t)) { cres = ConvertUTF8toUTF32((const UTF8 **) &sourceStart, (const UTF8 *) sourceEnd, (UTF32 **) &targStart, (UTF32 *) targEnd, isLenientConversion); } else { NOT_IMPLEMENTED(); } if (targetExhausted == cres) { if (targSize == prec) { /* * We've got all the caller wants. */ break; } else { /* * Grow the buffer. */ ASSERT(FALSE); targSize *= 2; if (prec >= 0) { targSize = MIN(targSize, prec); } } } else if ((sourceExhausted == cres) || (sourceIllegal == cres)) { /* * If lenient, the API converted all it could, so just * proceed, otherwise, barf. */ if (isLenientConversion) { break; } else { free(targ); targ = NULL; goto exit; } } else if (conversionOK == cres) { break; } else { NOT_IMPLEMENTED(); } } /* * Success, NUL-terminate. (The API updated targStart for us). */ ASSERT(targStart <= targEnd); *targStart = L'\0'; exit: return targ; } #ifndef NO_FLOATING_POINT static int exponent(wchar_t *, int, wchar_t); #endif /* !NO_FLOATING_POINT */ int bsd_vsnwprintf(wchar_t **outBuf, size_t bufSize, const wchar_t *fmt0, va_list ap) { wchar_t *fmt; /* format string */ wchar_t ch; /* character from fmt */ int n, n2; /* handy integer (short term usage) */ wchar_t *cp; /* handy char pointer (short term usage) */ BSDFmt_IOV *iovp; /* for PRINT macro */ int flags; /* flags as above */ int ret; /* return value accumulator */ int width; /* width from format (%8d), or 0 */ int prec; /* precision from format; <0 for N/A */ wchar_t sign; /* sign prefix (' ', '+', '-', or \0) */ wchar_t thousands_sep; /* locale specific thousands separator */ const char *grouping; /* locale specific numeric grouping rules */ #ifndef NO_FLOATING_POINT /* * We can decompose the printed representation of floating * point numbers into several parts, some of which may be empty: * * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ * A B ---C--- D E F * * A: 'sign' holds this value if present; '\0' otherwise * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal * C: cp points to the string MMMNNN. Leading and trailing * zeros are not in the string and must be added. * D: expchar holds this character; '\0' if no exponent, e.g. %f * F: at least two digits for decimal, at least one digit for hex */ char *decimal_point; /* locale specific decimal point */ int signflag; /* true if float is negative */ union { /* floating point arguments %[aAeEfFgG] */ double dbl; long double ldbl; } fparg; int expt; /* integer value of exponent */ char expchar; /* exponent character: [eEpP\0] */ char *dtoaend; /* pointer to end of converted digits */ int expsize; /* character count for expstr */ int lead; /* sig figs before decimal or group sep */ int ndig; /* actual number of digits returned by dtoa */ wchar_t expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */ char *dtoaresult; /* buffer allocated by dtoa */ int nseps; /* number of group separators with ' */ int nrepeats; /* number of repeats of the last group */ #endif u_long ulval; /* integer arguments %[diouxX] */ uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ int base; /* base for [diouxX] conversion */ int dprec; /* a copy of prec if [diouxX], 0 otherwise */ int realsz; /* field size expanded by dprec, sign, etc */ int size; /* size of converted field or string */ int prsize; /* max size of printed field */ const char *xdigs; /* digits for [xX] conversion */ BSDFmt_UIO uio; /* output information: summary */ BSDFmt_IOV iov[BSDFMT_NIOV]; /* ... and individual io vectors */ wchar_t buf[INT_CONV_BUF]; /* buffer with space for digits of uintmax_t */ wchar_t ox[2]; /* space for 0x hex-prefix */ union arg *argtable; /* args, built due to positional arg */ union arg statargtable [STATIC_ARG_TBL_SIZE]; int nextarg; /* 1-based argument index */ wchar_t *convbuf; /* multibyte to wide conversion result */ #ifndef _WIN32 va_list orgap; #endif StrBuf sbuf; /* * Choose PADSIZE to trade efficiency vs. size. If larger printf * fields occur frequently, increase PADSIZE and make the initialisers * below longer. */ #define PADSIZE 16 /* pad chunk size */ static wchar_t blanks[PADSIZE] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; static wchar_t zeroes[PADSIZE] = {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; static const char xdigs_lower[16] = "0123456789abcdef"; static const char xdigs_upper[16] = "0123456789ABCDEF"; /* * BEWARE, these `goto error' on error, PRINT uses `n2' and * PAD uses `n'. */ /* * BEWARE, these `goto error' on error, and PAD uses `n'. */ #define PRINT(ptr, len) { \ iovp->iov_base = (ptr); \ iovp->iov_len = len; \ uio.uio_resid += len; \ iovp++; \ if (++uio.uio_iovcnt >= BSDFMT_NIOV) { \ if (__sprint(&sbuf, &uio)) \ goto error; \ iovp = iov; \ } \ } #define PAD(howmany, with) do { \ if ((n = (howmany)) > 0) { \ while (n > PADSIZE) { \ PRINT(with, PADSIZE); \ n -= PADSIZE; \ } \ PRINT(with, n); \ } \ } while (0) #define PRINTANDPAD(p, ep, len, with) do { \ n2 = (ep) - (p); \ if (n2 > (len)) \ n2 = (len); \ if (n2 > 0) \ PRINT((p), n2); \ PAD((len) - (n2 > 0 ? n2 : 0), (with)); \ } while(0) #define FLUSH() { \ if (uio.uio_resid && __sprint(&sbuf, &uio)) \ goto error; \ uio.uio_iovcnt = 0; \ iovp = iov; \ } /* * Get the argument indexed by nextarg. If the argument table is * built, use it to get the argument. If its not, get the next * argument (and arguments must be gotten sequentially). */ #define GETARG(type) \ ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \ (nextarg++, va_arg(ap, type))) /* * To extend shorts properly, we need both signed and unsigned * argument extraction methods. */ #define SARG() \ (flags&LONGINT ? GETARG(long) : \ flags&SHORTINT ? (long)(short)GETARG(int) : \ flags&CHARINT ? (long)(signed char)GETARG(int) : \ (long)GETARG(int)) #define UARG() \ (flags&LONGINT ? GETARG(u_long) : \ flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \ flags&CHARINT ? (u_long)(u_char)GETARG(int) : \ (u_long)GETARG(u_int)) #define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT) #define SJARG() \ (flags&INTMAXT ? GETARG(intmax_t) : \ flags&SIZET ? (intmax_t)GETARG(size_t) : \ flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \ (intmax_t)GETARG(long long)) #define UJARG() \ (flags&INTMAXT ? GETARG(uintmax_t) : \ flags&SIZET ? (uintmax_t)GETARG(size_t) : \ flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \ (uintmax_t)GETARG(unsigned long long)) /* * Get * arguments, including the form *nn$. Preserve the nextarg * that the argument can be gotten once the type is determined. */ #define GETASTER(val) \ n2 = 0; \ cp = fmt; \ while (is_digit(*cp)) { \ n2 = 10 * n2 + to_digit(*cp); \ cp++; \ } \ if (*cp == '$') { \ int hold = nextarg; \ nextarg = n2; \ val = GETARG (int); \ nextarg = hold; \ fmt = ++cp; \ } else { \ val = GETARG (int); \ } /* * Windows can't scan the args twice, so always build argtable. * Otherwise, do it when we see an n$ argument. */ #ifndef _WIN32 #define FIND_ARGUMENTS() \ (argtable == NULL ? \ (argtable = statargtable, \ __find_arguments(fmt0, orgap, &argtable)) : \ (void) 0) #else #define FIND_ARGUMENTS() \ ASSERT(argtable != NULL) #endif xdigs = xdigs_lower; thousands_sep = L'\0'; grouping = NULL; #ifndef NO_FLOATING_POINT decimal_point = localeconv()->decimal_point; #endif convbuf = NULL; fmt = (wchar_t *)fmt0; argtable = NULL; nextarg = 1; argtable = statargtable; #ifndef _WIN32 argtable = NULL; va_copy(orgap, ap); #else argtable = statargtable; __find_arguments (fmt0, ap, &argtable); #endif uio.uio_iov = iovp = iov; uio.uio_resid = 0; uio.uio_iovcnt = 0; ret = 0; /* * Set up output string buffer structure. */ sbuf.alloc = *outBuf == NULL; sbuf.error = FALSE; sbuf.buf = *outBuf; sbuf.size = bufSize; sbuf.index = 0; /* * If aswprintf(), allocate initial buffer based on format length. * Empty format only needs one byte. * Otherwise, round up to multiple of 64. */ if (sbuf.alloc) { size_t n = wcslen(fmt0) + 1; // +1 for \0 if (n > 1) { n = ROUNDUP(n, 64); } if ((sbuf.buf = malloc(n * sizeof (wchar_t))) == NULL) { sbuf.error = TRUE; goto error; } sbuf.size = n; } // shut compile up #ifndef NO_FLOATING_POINT expchar = 0; expsize = 0; lead = 0; ndig = 0; nseps = 0; nrepeats = 0; #endif ulval = 0; ujval = 0; /* * Scan the format for conversions (`%' character). */ for (;;) { for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) /* void */; if ((n = fmt - cp) != 0) { if ((unsigned)ret + n > INT_MAX) { ret = EOF; goto error; } PRINT(cp, n); ret += n; } if (ch == '\0') goto done; fmt++; /* skip over '%' */ flags = 0; dprec = 0; width = 0; prec = -1; sign = '\0'; ox[1] = '\0'; rflag: ch = *fmt++; reswitch: switch (ch) { case ' ': /*- * ``If the space and + flags both appear, the space * flag will be ignored.'' * -- ANSI X3J11 */ if (!sign) sign = ' '; goto rflag; case '#': flags |= ALT; goto rflag; case '*': /*- * ``A negative field width argument is taken as a * - flag followed by a positive field width.'' * -- ANSI X3J11 * They don't exclude field widths read from args. */ GETASTER (width); if (width >= 0) goto rflag; width = -width; /* FALLTHROUGH */ case '-': flags |= LADJUST; goto rflag; case '+': sign = '+'; goto rflag; case '\'': flags |= GROUPING; thousands_sep = (wchar_t) *(localeconv()->thousands_sep); grouping = localeconv()->grouping; /* * Grouping should not begin with 0, but it nevertheless * does (see bug 281072) and makes the formatting code * behave badly, so we fix it up. */ if (grouping != NULL && *grouping == '\0') { static char g[] = { CHAR_MAX, '\0' }; grouping = g; } goto rflag; case '.': if ((ch = *fmt++) == '*') { GETASTER (prec); goto rflag; } prec = 0; while (is_digit(ch)) { prec = 10 * prec + to_digit(ch); ch = *fmt++; } goto reswitch; case '0': /*- * ``Note that 0 is taken as a flag, not as the * beginning of a field width.'' * -- ANSI X3J11 */ flags |= ZEROPAD; goto rflag; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': n = 0; do { n = 10 * n + to_digit(ch); ch = *fmt++; } while (is_digit(ch)); if (ch == '$') { nextarg = n; FIND_ARGUMENTS(); goto rflag; } width = n; goto reswitch; case 'h': if (flags & SHORTINT) { flags &= ~SHORTINT; flags |= CHARINT; } else flags |= SHORTINT; goto rflag; case 'j': flags |= INTMAXT; goto rflag; case 'I': /* could be I64 - long long int is 64bit */ if (fmt[0] == '6' && fmt[1] == '4') { fmt += 2; flags |= LLONGINT; goto rflag; } /* could be I32 - normal int is 32bit */ if (fmt[0] == '3' && fmt[1] == '2') { fmt += 2; /* flags |= normal integer - it is 32bit for all our targets */ goto rflag; } /* * I alone - use Microsoft's semantic as size_t modifier. We do * not support glibc's semantic to use alternative digits. */ flags |= SIZET; goto rflag; case 'l': if (flags & LONGINT) { flags &= ~LONGINT; flags |= LLONGINT; } else flags |= LONGINT; goto rflag; case 'L': case 'q': flags |= LLONGINT; /* not necessarily */ goto rflag; case 't': flags |= PTRDIFFT; goto rflag; case 'Z': case 'z': flags |= SIZET; goto rflag; case 'C': flags |= LONGINT; /*FALLTHROUGH*/ case 'c': if (flags & LONGINT) *(cp = buf) = (wchar_t)GETARG(wint_t); else *(cp = buf) = (wchar_t)bsd_btowc(GETARG(int)); size = 1; sign = '\0'; break; case 'D': flags |= LONGINT; /*FALLTHROUGH*/ case 'd': case 'i': if (flags & INTMAX_SIZE) { ujval = SJARG(); if ((intmax_t)ujval < 0) { ujval = -ujval; sign = '-'; } } else { ulval = SARG(); if ((long)ulval < 0) { ulval = -ulval; sign = '-'; } } base = 10; goto number; #ifndef NO_FLOATING_POINT case 'e': case 'E': expchar = ch; if (prec < 0) /* account for digit before decpt */ prec = DEFPREC + 1; else prec++; goto fp_begin; case 'f': case 'F': expchar = '\0'; goto fp_begin; case 'g': case 'G': expchar = ch - ('g' - 'e'); if (prec == 0) prec = 1; fp_begin: if (prec < 0) prec = DEFPREC; if (convbuf != NULL) free(convbuf); if (flags & LLONGINT) { fparg.ldbl = GETARG(long double); dtoaresult = ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend); } else { fparg.dbl = GETARG(double); dtoaresult = dtoa(fparg.dbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend); if (expt == 9999) expt = INT_MAX; } ndig = dtoaend - dtoaresult; cp = convbuf = BSDFmt_UTF8ToWChar(dtoaresult, -1); freedtoa(dtoaresult); if (signflag) sign = '-'; if (expt == INT_MAX) { /* inf or nan */ if (*cp == 'N') { cp = (ch >= 'a') ? L"nan" : L"NAN"; sign = '\0'; } else cp = (ch >= 'a') ? L"inf" : L"INF"; size = 3; break; } flags |= FPT; if (ch == 'g' || ch == 'G') { if (expt > -4 && expt <= prec) { /* Make %[gG] smell like %[fF] */ expchar = '\0'; if (flags & ALT) prec -= expt; else prec = ndig - expt; if (prec < 0) prec = 0; } else { /* * Make %[gG] smell like %[eE], but * trim trailing zeroes if no # flag. */ if (!(flags & ALT)) prec = ndig; } } if (expchar) { expsize = exponent(expstr, expt - 1, expchar); size = expsize + prec; if (prec > 1 || flags & ALT) ++size; } else { /* space for digits before decimal point */ if (expt > 0) size = expt; else /* "0" */ size = 1; /* space for decimal pt and following digits */ if (prec || flags & ALT) size += prec + 1; if (grouping && expt > 0) { /* space for thousands' grouping */ nseps = nrepeats = 0; lead = expt; while (*grouping != CHAR_MAX) { if (lead <= *grouping) break; lead -= *grouping; if (*(grouping+1)) { nseps++; grouping++; } else nrepeats++; } size += nseps + nrepeats; } else lead = expt; } break; #endif /* !NO_FLOATING_POINT */ case 'n': /* * Assignment-like behavior is specified if the * value overflows or is otherwise unrepresentable. * C99 says to use `signed char' for %hhn conversions. */ if (flags & LLONGINT) *GETARG(long long *) = ret; else if (flags & SIZET) *GETARG(size_t *) = (size_t)ret; else if (flags & PTRDIFFT) *GETARG(ptrdiff_t *) = ret; else if (flags & INTMAXT) *GETARG(intmax_t *) = ret; else if (flags & LONGINT) *GETARG(long *) = ret; else if (flags & SHORTINT) *GETARG(short *) = ret; else if (flags & CHARINT) *GETARG(signed char *) = ret; else *GETARG(int *) = ret; continue; /* no output */ case 'O': flags |= LONGINT; /*FALLTHROUGH*/ case 'o': if (flags & INTMAX_SIZE) ujval = UJARG(); else ulval = UARG(); base = 8; goto nosign; case 'p': /*- * ``The argument shall be a pointer to void. The * value of the pointer is converted to a sequence * of printable characters, in an implementation- * defined manner.'' * -- ANSI X3J11 */ ujval = (uintmax_t)(uintptr_t)GETARG(void *); base = 16; xdigs = xdigs_lower; flags = flags | INTMAXT; /* * PR 103201 * VisualC sscanf doesn't grok '0x', so prefix zeroes. */ // ox[1] = 'x'; goto nosign; case 'S': flags |= LONGINT; /*FALLTHROUGH*/ case 's': if (flags & LONGINT) { /* Argument is wchar_t * */ if ((cp = GETARG(wchar_t *)) == NULL) cp = L"(null)"; } else { char *mbp; /* Argument is char * */ if (convbuf!= NULL) free(convbuf); if ((mbp = GETARG(char *)) == NULL) cp = L"(null)"; else { convbuf = BSDFmt_UTF8ToWChar(mbp, prec); if (convbuf == NULL) { sbuf.error = TRUE; goto error; } cp = convbuf; } } if (prec >= 0) { /* * can't use wcslen; can only look for the * NUL in the first `prec' characters, and * wcslen() will go further. */ wchar_t *p = (wchar_t *) wmemchr(cp, 0, (size_t)prec); if (p != NULL) { size = p - cp; if (size > prec) size = prec; } else size = prec; } else size = wcslen(cp); sign = '\0'; break; case 'U': flags |= LONGINT; /*FALLTHROUGH*/ case 'u': if (flags & INTMAX_SIZE) ujval = UJARG(); else ulval = UARG(); base = 10; goto nosign; case 'X': xdigs = xdigs_upper; goto hex; case 'x': xdigs = xdigs_lower; hex: if (flags & INTMAX_SIZE) ujval = UJARG(); else ulval = UARG(); base = 16; /* leading 0x/X only if non-zero */ if (flags & ALT && (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0)) ox[1] = ch; flags &= ~GROUPING; /* unsigned conversions */ nosign: sign = '\0'; /*- * ``... diouXx conversions ... if a precision is * specified, the 0 flag will be ignored.'' * -- ANSI X3J11 */ number: if ((dprec = prec) >= 0) flags &= ~ZEROPAD; /*- * ``The result of converting a zero value with an * explicit precision of zero is no characters.'' * -- ANSI X3J11 * * ``The C Standard is clear enough as is. The call * printf("%#.0o", 0) should print 0.'' * -- Defect Report #151 */ cp = buf + INT_CONV_BUF; if (flags & INTMAX_SIZE) { if (ujval != 0 || prec != 0 || (flags & ALT && base == 8)) cp = __ujtoa(ujval, cp, base, flags & ALT, xdigs, flags & GROUPING, thousands_sep, grouping); } else { if (ulval != 0 || prec != 0 || (flags & ALT && base == 8)) cp = __ultoa(ulval, cp, base, flags & ALT, xdigs, flags & GROUPING, thousands_sep, grouping); } size = buf + INT_CONV_BUF - cp; if (size > INT_CONV_BUF) /* should never happen */ abort(); break; default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') goto done; /* pretend it was %c with argument ch */ cp = buf; *cp = ch; size = 1; sign = '\0'; break; } /* * All reasonable formats wind up here. At this point, `cp' * points to a string which (if not flags&LADJUST) should be * padded out to `width' places. If flags&ZEROPAD, it should * first be prefixed by any sign or other prefix; otherwise, * it should be blank padded before the prefix is emitted. * After any left-hand padding and prefixing, emit zeroes * required by a decimal [diouxX] precision, then print the * string proper, then emit zeroes required by any leftover * floating precision; finally, if LADJUST, pad with blanks. * * Compute actual size, so we know how much to pad. * size excludes decimal prec; realsz includes it. */ realsz = dprec > size ? dprec : size; if (sign) realsz++; if (ox[1]) realsz += 2; prsize = width > realsz ? width : realsz; if ((unsigned)ret + prsize > INT_MAX) { ret = EOF; goto error; } /* right-adjusting blank padding */ if ((flags & (LADJUST|ZEROPAD)) == 0) PAD(width - realsz, blanks); /* prefix */ if (sign) PRINT(&sign, 1); if (ox[1]) { /* ox[1] is either x, X, or \0 */ ox[0] = '0'; PRINT(ox, 2); } /* right-adjusting zero padding */ if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) PAD(width - realsz, zeroes); /* leading zeroes from decimal precision */ PAD(dprec - size, zeroes); /* the string or number proper */ #ifndef NO_FLOATING_POINT if ((flags & FPT) == 0) { PRINT(cp, size); } else { /* glue together f_p fragments */ if (!expchar) { /* %[fF] or sufficiently short %[gG] */ if (expt <= 0) { PRINT(zeroes, 1); if (prec || flags & ALT) { buf[0] = (wchar_t) *decimal_point; PRINT(buf, 1); } PAD(-expt, zeroes); /* already handled initial 0's */ prec += expt; } else { PRINTANDPAD(cp, convbuf + ndig, lead, zeroes); cp += lead; if (grouping) { while (nseps>0 || nrepeats>0) { if (nrepeats > 0) nrepeats--; else { grouping--; nseps--; } PRINT(&thousands_sep, 1); PRINTANDPAD(cp, convbuf + ndig, *grouping, zeroes); cp += *grouping; } if (cp > convbuf + ndig) cp = convbuf + ndig; } if (prec || flags & ALT) { buf[0] = (wchar_t) *decimal_point; PRINT(buf, 1); } } PRINTANDPAD(cp, convbuf + ndig, prec, zeroes); } else { /* %[eE] or sufficiently long %[gG] */ if (prec > 1 || flags & ALT) { buf[0] = *cp++; buf[1] = (wchar_t) *decimal_point; PRINT(buf, 2); PRINT(cp, ndig-1); PAD(prec - ndig, zeroes); } else /* XeYYY */ PRINT(cp, 1); PRINT(expstr, expsize); } } #else PRINT(cp, size); #endif /* left-adjusting padding (always blank) */ if (flags & LADJUST) PAD(width - realsz, blanks); /* finally, adjust ret */ ret += prsize; FLUSH(); /* copy out the I/O vectors */ } done: FLUSH(); /* * Always null terminate, unless buffer is size 0. */ ASSERT(!sbuf.error && ret >= 0); if (sbuf.size <= 0) { ASSERT(!sbuf.alloc); } else { ASSERT(sbuf.index < sbuf.size); sbuf.buf[sbuf.index] = L'\0'; } error: #ifndef _WIN32 va_end(orgap); #endif if (convbuf != NULL) free(convbuf); if (sbuf.error) ret = EOF; if ((argtable != NULL) && (argtable != statargtable)) free (argtable); return (ret); /* NOTREACHED */ #undef FIND_ARGUMENTS } /* * Find all arguments when a positional parameter is encountered. Returns a * table, indexed by argument number, of pointers to each arguments. The * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries. * It will be replaces with a malloc-ed one if it overflows. */static void __find_arguments (const wchar_t *fmt0, va_list ap, union arg **argtable) { wchar_t *fmt; /* format string */ wchar_t ch; /* character from fmt */ int n, n2; /* handy integer (short term usage) */ wchar_t *cp; /* handy char pointer (short term usage) */ int flags; /* flags as above */ enum typeid *typetable; /* table of types */ enum typeid stattypetable [STATIC_ARG_TBL_SIZE]; int tablesize; /* current size of type table */ int tablemax; /* largest used index in table */ int nextarg; /* 1-based argument index */ /* * Add an argument type to the table, expanding if necessary. */ #define ADDTYPE(type) \ ((nextarg >= tablesize) ? \ __grow_type_table(nextarg, &typetable, &tablesize) : (void)0, \ (nextarg > tablemax) ? tablemax = nextarg : 0, \ typetable[nextarg++] = type) #define ADDSARG() \ ((flags&INTMAXT) ? ADDTYPE(T_INTMAXT) : \ ((flags&SIZET) ? ADDTYPE(T_SIZET) : \ ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \ ((flags&LLONGINT) ? ADDTYPE(T_LLONG) : \ ((flags&LONGINT) ? ADDTYPE(T_LONG) : ADDTYPE(T_INT)))))) #define ADDUARG() \ ((flags&INTMAXT) ? ADDTYPE(T_UINTMAXT) : \ ((flags&SIZET) ? ADDTYPE(T_SIZET) : \ ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \ ((flags&LLONGINT) ? ADDTYPE(T_U_LLONG) : \ ((flags&LONGINT) ? ADDTYPE(T_U_LONG) : ADDTYPE(T_U_INT)))))) /* * Add * arguments to the type array. */ #define ADDASTER() \ n2 = 0; \ cp = fmt; \ while (is_digit(*cp)) { \ n2 = 10 * n2 + to_digit(*cp); \ cp++; \ } \ if (*cp == '$') { \ int hold = nextarg; \ nextarg = n2; \ ADDTYPE (T_INT); \ nextarg = hold; \ fmt = ++cp; \ } else { \ ADDTYPE (T_INT); \ } fmt = (wchar_t *)fmt0; typetable = stattypetable; tablesize = STATIC_ARG_TBL_SIZE; tablemax = 0; nextarg = 1; for (n = 0; n < STATIC_ARG_TBL_SIZE; n++) typetable[n] = T_UNUSED; /* * Scan the format for conversions (`%' character). */ for (;;) { for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) /* void */; if (ch == '\0') goto done; fmt++; /* skip over '%' */ flags = 0; rflag: ch = *fmt++; reswitch: switch (ch) { case ' ': case '#': goto rflag; case '*': ADDASTER (); goto rflag; case '-': case '+': case '\'': goto rflag; case '.': if ((ch = *fmt++) == '*') { ADDASTER (); goto rflag; } while (is_digit(ch)) { ch = *fmt++; } goto reswitch; case '0': goto rflag; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': n = 0; do { n = 10 * n + to_digit(ch); ch = *fmt++; } while (is_digit(ch)); if (ch == '$') { nextarg = n; goto rflag; } goto reswitch; case 'h': if (flags & SHORTINT) { flags &= ~SHORTINT; flags |= CHARINT; } else flags |= SHORTINT; goto rflag; case 'j': flags |= INTMAXT; goto rflag; case 'I': /* could be I64 - long long int is 64bit */ if (fmt[0] == '6' && fmt[1] == '4') { fmt += 2; flags |= LLONGINT; goto rflag; } /* could be I32 - normal int is 32bit */ if (fmt[0] == '3' && fmt[1] == '2') { fmt += 2; /* flags |= normal integer - it is 32bit for all our targets */ goto rflag; } /* * I alone - use Microsoft's semantic as size_t modifier. We do * not support glibc's semantic to use alternative digits. */ flags |= SIZET; goto rflag; case 'l': if (flags & LONGINT) { flags &= ~LONGINT; flags |= LLONGINT; } else flags |= LONGINT; goto rflag; case 'L': case 'q': flags |= LLONGINT; /* not necessarily */ goto rflag; case 't': flags |= PTRDIFFT; goto rflag; case 'Z': case 'z': flags |= SIZET; goto rflag; case 'C': flags |= LONGINT; /*FALLTHROUGH*/ case 'c': if (flags & LONGINT) ADDTYPE(T_WINT); else ADDTYPE(T_INT); break; case 'D': flags |= LONGINT; /*FALLTHROUGH*/ case 'd': case 'i': ADDSARG(); break; #ifndef NO_FLOATING_POINT case 'a': case 'A': case 'e': case 'E': case 'f': case 'g': case 'G': if (flags & LLONGINT) ADDTYPE(T_LONG_DOUBLE); else ADDTYPE(T_DOUBLE); break; #endif /* !NO_FLOATING_POINT */ case 'n': if (flags & INTMAXT) ADDTYPE(TP_INTMAXT); else if (flags & PTRDIFFT) ADDTYPE(TP_PTRDIFFT); else if (flags & SIZET) ADDTYPE(TP_SIZET); else if (flags & LLONGINT) ADDTYPE(TP_LLONG); else if (flags & LONGINT) ADDTYPE(TP_LONG); else if (flags & SHORTINT) ADDTYPE(TP_SHORT); else if (flags & CHARINT) ADDTYPE(TP_SCHAR); else ADDTYPE(TP_INT); continue; /* no output */ case 'O': flags |= LONGINT; /*FALLTHROUGH*/ case 'o': ADDUARG(); break; case 'p': ADDTYPE(TP_VOID); break; case 'S': flags |= LONGINT; /*FALLTHROUGH*/ case 's': if (flags & LONGINT) ADDTYPE(TP_WCHAR); else ADDTYPE(TP_CHAR); break; case 'U': flags |= LONGINT; /*FALLTHROUGH*/ case 'u': case 'X': case 'x': ADDUARG(); break; default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') goto done; break; } } done: /* * Build the argument table. */ if (tablemax >= STATIC_ARG_TBL_SIZE) { *argtable = (union arg *) malloc (sizeof (union arg) * (tablemax + 1)); } (*argtable) [0].intarg = 0; for (n = 1; n <= tablemax; n++) { switch (typetable [n]) { case T_UNUSED: /* whoops! */ (*argtable) [n].intarg = va_arg (ap, int); break; case TP_SCHAR: (*argtable) [n].pschararg = va_arg (ap, signed char *); break; case TP_SHORT: (*argtable) [n].pshortarg = va_arg (ap, short *); break; case T_INT: (*argtable) [n].intarg = va_arg (ap, int); break; case T_U_INT: (*argtable) [n].uintarg = va_arg (ap, unsigned int); break; case TP_INT: (*argtable) [n].pintarg = va_arg (ap, int *); break; case T_LONG: (*argtable) [n].longarg = va_arg (ap, long); break; case T_U_LONG: (*argtable) [n].ulongarg = va_arg (ap, unsigned long); break; case TP_LONG: (*argtable) [n].plongarg = va_arg (ap, long *); break; case T_LLONG: (*argtable) [n].longlongarg = va_arg (ap, long long); break; case T_U_LLONG: (*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long); break; case TP_LLONG: (*argtable) [n].plonglongarg = va_arg (ap, long long *); break; case T_PTRDIFFT: (*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t); break; case TP_PTRDIFFT: (*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *); break; case T_SIZET: (*argtable) [n].sizearg = va_arg (ap, size_t); break; case TP_SIZET: (*argtable) [n].psizearg = va_arg (ap, size_t *); break; case T_INTMAXT: (*argtable) [n].intmaxarg = va_arg (ap, intmax_t); break; case T_UINTMAXT: (*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t); break; case TP_INTMAXT: (*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *); break; #ifndef NO_FLOATING_POINT case T_DOUBLE: (*argtable) [n].doublearg = va_arg (ap, double); break; case T_LONG_DOUBLE: (*argtable) [n].longdoublearg = va_arg (ap, long double); break; #endif case TP_CHAR: (*argtable) [n].pchararg = va_arg (ap, char *); break; case TP_VOID: (*argtable) [n].pvoidarg = va_arg (ap, void *); break; case T_WINT: (*argtable) [n].wintarg = va_arg (ap, wint_t); break; case TP_WCHAR: (*argtable) [n].pwchararg = va_arg (ap, wchar_t *); break; } } if ((typetable != NULL) && (typetable != stattypetable)) free (typetable); } /* * Increase the size of the type table. */ static void __grow_type_table (int nextarg, enum typeid **typetable, int *tablesize) { enum typeid *const oldtable = *typetable; const int oldsize = *tablesize; enum typeid *newtable; int n, newsize = oldsize * 2; if (newsize < nextarg + 1) newsize = nextarg + 1; if (oldsize == STATIC_ARG_TBL_SIZE) { if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL) abort(); /* XXX handle better */ memmove(newtable, oldtable, oldsize * sizeof(enum typeid)); } else { newtable = realloc(oldtable, newsize * sizeof(enum typeid)); if (newtable == NULL) abort(); /* XXX handle better */ } for (n = oldsize; n < newsize; n++) newtable[n] = T_UNUSED; *typetable = newtable; *tablesize = newsize; } #ifndef NO_FLOATING_POINT static int exponent(wchar_t *p0, int exp, wchar_t fmtch) { wchar_t *p, *t; wchar_t expbuf[MAXEXPDIG]; p = p0; *p++ = fmtch; if (exp < 0) { exp = -exp; *p++ = '-'; } else *p++ = '+'; t = expbuf + MAXEXPDIG; if (exp < 10) { *p++ = '0'; } if (exp < 100) { *p++ = '0'; } if (exp > 9) { do { *--t = to_char(exp % 10); } while ((exp /= 10) > 9); *--t = to_char(exp); for (; t < expbuf + MAXEXPDIG; *p++ = *t++); } else { *p++ = to_char(exp); } return (p - p0); } #endif /* !NO_FLOATING_POINT */ #endif /* !STR_NO_WIN32_LIBS|*BSD */ open-vm-tools-9.4.0-1280544/lib/string/Makefile.in0000644765153500003110000004506712220061623017567 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @USE_PRINTF_WRAPPERS_TRUE@am__append_1 = bsd_output_shared.c \ @USE_PRINTF_WRAPPERS_TRUE@ bsd_vsnprintf.c bsd_vsnwprintf.c subdir = lib/string DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libString_la_LIBADD = am__libString_la_SOURCES_DIST = bsd_output_shared.c bsd_vsnprintf.c \ bsd_vsnwprintf.c convertutf.c str.c @USE_PRINTF_WRAPPERS_TRUE@am__objects_1 = bsd_output_shared.lo \ @USE_PRINTF_WRAPPERS_TRUE@ bsd_vsnprintf.lo bsd_vsnwprintf.lo am_libString_la_OBJECTS = $(am__objects_1) convertutf.lo str.lo libString_la_OBJECTS = $(am_libString_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libString_la_SOURCES) DIST_SOURCES = $(am__libString_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libString.la libString_la_SOURCES = $(am__append_1) convertutf.c str.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/string/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/string/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libString.la: $(libString_la_OBJECTS) $(libString_la_DEPENDENCIES) $(EXTRA_libString_la_DEPENDENCIES) $(LINK) $(libString_la_OBJECTS) $(libString_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsd_output_shared.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsd_vsnprintf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsd_vsnwprintf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/convertutf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/panicDefault/0000755765153500003110000000000012220061623016577 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/panicDefault/panicDefault.c0000644765153500003110000000272012220061556021350 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * panic.c -- * * Basic Panic() */ #include #include #include #include "vmware.h" #include "panic.h" /* *----------------------------------------------------------------------------- * * Panic -- * * Minimal panic. * * Results: * None. * * Side effects: * Print message, abort. * *----------------------------------------------------------------------------- */ void Panic(const char *fmt, // IN: message format ...) // IN: message format arguments { va_list ap; va_start(ap, fmt); Panic_Panic(fmt, ap); va_end(ap); } open-vm-tools-9.4.0-1280544/lib/panicDefault/Makefile.am0000644765153500003110000000175012220061556020643 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libPanicDefault.la libPanicDefault_la_SOURCES = libPanicDefault_la_SOURCES += panicDefault.c open-vm-tools-9.4.0-1280544/lib/panicDefault/Makefile.in0000644765153500003110000004372412220061623020656 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/panicDefault DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libPanicDefault_la_LIBADD = am_libPanicDefault_la_OBJECTS = panicDefault.lo libPanicDefault_la_OBJECTS = $(am_libPanicDefault_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libPanicDefault_la_SOURCES) DIST_SOURCES = $(libPanicDefault_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libPanicDefault.la libPanicDefault_la_SOURCES = panicDefault.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/panicDefault/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/panicDefault/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libPanicDefault.la: $(libPanicDefault_la_OBJECTS) $(libPanicDefault_la_DEPENDENCIES) $(EXTRA_libPanicDefault_la_DEPENDENCIES) $(LINK) $(libPanicDefault_la_OBJECTS) $(libPanicDefault_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/panicDefault.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/rpcOut/0000755765153500003110000000000012220061623015454 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/rpcOut/rpcout.c0000644765153500003110000003042212220061556017142 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * rpcout.c -- * * Remote Procedure Call between VMware and guest applications * C implementation. * * This module contains implements the out (guest=>host) direction only. * The in and out modules are separate since some applications (e.g. * drivers that want to do RPC-based logging) only want/need/can have the * out direction. */ #if defined(__KERNEL__) || defined(_KERNEL) || defined(KERNEL) # include "kernelStubs.h" #else # include # include # include # include # include "str.h" # include "debug.h" #endif #include "vmware.h" #include "rpcout.h" #include "message.h" /* * The RpcOut object */ struct RpcOut { Message_Channel *channel; }; /* *----------------------------------------------------------------------------- * * RpcOut_Construct -- * * Constructor for the RpcOut object * * Results: * New RpcOut object. * * Side effects: * Allocates memory. * *----------------------------------------------------------------------------- */ RpcOut * RpcOut_Construct(void) { return (RpcOut *)calloc(1, sizeof(RpcOut)); } /* *----------------------------------------------------------------------------- * * RpcOut_Destruct -- * * Destructor for the RpcOut object. * * Results: * None. * * Side effects: * Frees RpcOut object memory. * *----------------------------------------------------------------------------- */ void RpcOut_Destruct(RpcOut *out) // IN { ASSERT(out); ASSERT(out->channel == NULL); free(out); } /* *----------------------------------------------------------------------------- * * RpcOut_start -- * * Open the channel * * Result: * TRUE on success * FALSE on failure * * Side-effects: * None * *----------------------------------------------------------------------------- */ Bool RpcOut_start(RpcOut *out) // IN { ASSERT(out); ASSERT(out->channel == NULL); out->channel = Message_Open(RPCI_PROTOCOL_NUM); if (out->channel == NULL) { Debug("RpcOut: couldn't open channel with RPCI protocol\n"); return FALSE; } return TRUE; } /* *----------------------------------------------------------------------------- * * RpcOut_send -- * * Make VMware synchroneously execute a TCLO command * * Unlike the other send varieties, RpcOut_send requires that the * caller pass non-NULL reply and repLen arguments. * * Result * TRUE on success. 'reply' contains the result of the rpc * FALSE on error. 'reply' will contain a description of the error * * In both cases, the caller should not free the reply. * * Side-effects * None * *----------------------------------------------------------------------------- */ Bool RpcOut_send(RpcOut *out, // IN char const *request, // IN size_t reqLen, // IN char const **reply, // OUT size_t *repLen) // OUT { unsigned char *myReply; size_t myRepLen; Bool success; ASSERT(out); ASSERT(out->channel); if (Message_Send(out->channel, (const unsigned char *)request, reqLen) == FALSE) { *reply = "RpcOut: Unable to send the RPCI command"; *repLen = strlen(*reply); return FALSE; } if (Message_Receive(out->channel, &myReply, &myRepLen) == FALSE) { *reply = "RpcOut: Unable to receive the result of the RPCI command"; *repLen = strlen(*reply); return FALSE; } if (myRepLen < 2 || ( (success = strncmp((const char *)myReply, "1 ", 2) == 0) == FALSE && strncmp((const char *)myReply, "0 ", 2))) { *reply = "RpcOut: Invalid format for the result of the RPCI command"; *repLen = strlen(*reply); return FALSE; } *reply = ((const char *)myReply) + 2; *repLen = myRepLen - 2; return success; } /* *----------------------------------------------------------------------------- * * RpcOut_stop -- * * Close the channel * * Result * TRUE on success * FALSE on failure * * Side-effects * Frees the result of the last command. * *----------------------------------------------------------------------------- */ Bool RpcOut_stop(RpcOut *out) // IN { Bool status; ASSERT(out); status = TRUE; if (out->channel) { /* Try to close the channel */ if (Message_Close(out->channel) == FALSE) { Debug("RpcOut: couldn't close channel\n"); status = FALSE; } out->channel = NULL; } return status; } /* *----------------------------------------------------------------------------- * * RpcOut_sendOne -- * * Make VMware execute a RPCI command * * VMware closes a channel when it detects that there has been no activity * on it for a while. Because we do not know how often this program will * make VMware execute a RPCI, we open/close one channel per RPCI command * * Return value: * TRUE on success. '*reply' contains an allocated result of the rpc * FALSE on error. '*reply' contains an allocated description of the error * or NULL. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool RpcOut_sendOne(char **reply, // OUT: Result size_t *repLen, // OUT: Length of the result char const *reqFmt, // IN: RPCI command ...) // Unspecified { va_list args; Bool status; char *request; size_t reqLen = 0; status = FALSE; /* Format the request string */ va_start(args, reqFmt); request = Str_Vasprintf(&reqLen, reqFmt, args); va_end(args); /* * If Str_Vasprintf failed, write NULL into the reply if the caller wanted * a reply back. */ if (request == NULL) { if (reply) { *reply = NULL; } return FALSE; } /* * If the command doesn't contain a space, add one to the end to maintain * compatibility with old VMXs. * * For a long time, the GuestRpc logic in the VMX was wired to expect a * trailing space in every command, even commands without arguments. That is * no longer true, but we must continue to add a trailing space because we * don't know whether we're talking to an old or new VMX. */ if (strchr(request, ' ') == NULL) { char *tmp; tmp = Str_Asprintf(NULL, "%s ", request); free(request); request = tmp; /* * If Str_Asprintf failed, write NULL into reply if the caller wanted * a reply back. */ if (request == NULL) { if (reply != NULL) { *reply = NULL; } return FALSE; } } status = RpcOut_SendOneRaw(request, reqLen, reply, repLen); free(request); return status; } /* *----------------------------------------------------------------------------- * * RpcOut_SendOneRaw -- * * Make VMware execute a RPCI command * * VMware closes a channel when it detects that there has been no activity * on it for a while. Because we do not know how often this program will * make VMware execute a RPCI, we open/close one channel per RPCI command. * * This function sends a message over the backdoor without using * any of the Str_ functions on the request buffer; Str_Asprintf() in * particular uses FormatMessage on Win32, which corrupts some UTF-8 * strings. Using this function directly instead of using RpcOut_SendOne() * avoids these problems. * * If this is not an issue, you can use RpcOut_sendOne(), which has * varargs. * * Note: It is the caller's responsibility to ensure that the RPCI command * followed by a space appear at the start of the request buffer. See * the command in RpcOut_sendOne for details. * * Return value: * TRUE on success. '*reply' contains an allocated result of the rpc * FALSE on error. '*reply' contains an allocated description of the * error or NULL. * * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool RpcOut_SendOneRaw(void *request, // IN: RPCI command size_t reqLen, // IN: Size of request buffer char **reply, // OUT: Result size_t *repLen) // OUT: Length of the result { Bool status; RpcOut *out = NULL; char const *myReply; size_t myRepLen; status = FALSE; Debug("Rpci: Sending request='%s'\n", (char *)request); out = RpcOut_Construct(); if (out == NULL) { myReply = "RpcOut: Unable to create the RpcOut object"; myRepLen = strlen(myReply); goto sent; } else if (RpcOut_start(out) == FALSE) { myReply = "RpcOut: Unable to open the communication channel"; myRepLen = strlen(myReply); goto sent; } else if (RpcOut_send(out, request, reqLen, &myReply, &myRepLen) == FALSE) { /* We already have the description of the error */ goto sent; } status = TRUE; sent: Debug("Rpci: Sent request='%s', reply='%s', len=%"FMTSZ"u, status=%d\n", (char *)request, myReply, myRepLen, status); if (reply != NULL) { /* * If we got a non-NULL reply, make a copy of it, because the reply * we got back is inside the channel buffer, which will get destroyed * at the end of this function. */ if (myReply != NULL) { /* * We previously used strdup to duplicate myReply, but that * breaks if you are sending binary (not string) data over the * backdoor. Don't assume the data is a string. * * myRepLen is strlen(myReply), so we need an extra byte to * cover the NUL terminator. */ *reply = malloc(myRepLen + 1); if (*reply != NULL) { memcpy(*reply, myReply, myRepLen); /* * The message layer already writes a trailing NUL but we might * change that someday, so do it again here. */ (*reply)[myRepLen] = 0; } } else { /* * Our reply was NULL, so just pass the NULL back up to the caller. */ *reply = NULL; } /* * Only set the length if the caller wanted it and if we got a good * reply. */ if (repLen != NULL && *reply != NULL) { *repLen = myRepLen; } } if (out) { if (RpcOut_stop(out) == FALSE) { /* * We couldn't stop the channel. Free anything we allocated, give our * client a reply of NULL, and return FALSE. */ if (reply != NULL) { free(*reply); *reply = NULL; } Debug("Rpci: unable to close the communication channel\n"); status = FALSE; } RpcOut_Destruct(out); out = NULL; } return status; } open-vm-tools-9.4.0-1280544/lib/rpcOut/Makefile.am0000644765153500003110000000172112220061556017516 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libRpcOut.la libRpcOut_la_SOURCES = libRpcOut_la_SOURCES += rpcout.c open-vm-tools-9.4.0-1280544/lib/rpcOut/Makefile.in0000644765153500003110000004353412220061623017532 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/rpcOut DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libRpcOut_la_LIBADD = am_libRpcOut_la_OBJECTS = rpcout.lo libRpcOut_la_OBJECTS = $(am_libRpcOut_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libRpcOut_la_SOURCES) DIST_SOURCES = $(libRpcOut_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libRpcOut.la libRpcOut_la_SOURCES = rpcout.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/rpcOut/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/rpcOut/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libRpcOut.la: $(libRpcOut_la_OBJECTS) $(libRpcOut_la_DEPENDENCIES) $(EXTRA_libRpcOut_la_DEPENDENCIES) $(LINK) $(libRpcOut_la_OBJECTS) $(libRpcOut_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpcout.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/impersonate/0000755765153500003110000000000012220061622016525 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/impersonate/impersonate.c0000644765153500003110000002354412220061556021235 0ustar dtormts/********************************************************* * Copyright (C) 2003 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * impersonate.c -- * * Description: * Code to impersonate as a user when running under a privileged account. * Nested impersonation is not supported. */ #include #include "vmware.h" #include "auth.h" #include "userlock.h" #include "mutexRankLib.h" #include "impersonateInt.h" static Atomic_Ptr impersonateLockStorage; Bool impersonationEnabled = FALSE; /* *---------------------------------------------------------------------- * * ImpersonateGetLock -- * * Get/create the impersonate lock. * * Results: * See above. * * Side effects: * See above. * *---------------------------------------------------------------------- */ static INLINE MXUserRecLock * ImpersonateGetLock(void) { MXUserRecLock *lock = MXUser_CreateSingletonRecLock(&impersonateLockStorage, "impersonateLock", RANK_impersonateLock); ASSERT_MEM_ALLOC(lock); return lock; } /* *---------------------------------------------------------------------- * * ImpersonateLock -- * * Acquire or release the impersonate lock. Protects access to * the library's static and TLS states. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE void ImpersonateLock(Bool lock) // IN { MXUserRecLock *impersonateLock = ImpersonateGetLock(); if (lock) { MXUser_AcquireRecLock(impersonateLock); } else { MXUser_ReleaseRecLock(impersonateLock); } } /* *---------------------------------------------------------------------- * * Impersonate_Init -- * * Initialize the impersonation module. On windows also load * userenv.dll. * Without calling this, code calling into this module will * essentially be noops. * * Call when single-threaded. * * Side effects: * * Loads the library. We keep the library loaded thereafter. * *---------------------------------------------------------------------- */ void Impersonate_Init(void) { if (!impersonationEnabled) { ImpersonateInit(); impersonationEnabled = TRUE; } } /* *---------------------------------------------------------------------------- * * Impersonate_Runas -- * * Impersonate as the appropriate runas user. In linux this is always * the config file owner regardless the calling context. In windows, the * runas user is the caller passed into the method, except when the VM has * a preconfigured runas user, in which case we will impersonate using his * credentials instead. * * In windows, if caller is not set, fail if preconfigured runas user is * not found. * * Results: * TRUE if impersonation succeeds, FALSE otherwise. * * Side effects: * imp.impersonatedUser may be updated. * *---------------------------------------------------------------------------- */ Bool Impersonate_Runas(const char *cfg, // IN const char *caller, // IN AuthToken callerToken) // IN { Bool res; if (!impersonationEnabled) { return TRUE; } ImpersonateLock(TRUE); res = ImpersonateRunas(cfg, caller, callerToken); ImpersonateLock(FALSE); return res; } /* *---------------------------------------------------------------------------- * * Impersonate_Owner -- * * Impersonate as the owner of the specified file. * * Results: * TRUE if impersonation succeeds, FALSE otherwise. * * Side effects: * imp.impersonatedUser may be updated. * *---------------------------------------------------------------------------- */ Bool Impersonate_Owner(const char *file) // IN { Bool res; if (!impersonationEnabled) { return TRUE; } ImpersonateLock(TRUE); res = ImpersonateOwner(file); ImpersonateLock(FALSE); return res; } /* *---------------------------------------------------------------------------- * * Impersonate_Do -- * * Impersonate as user. Can be nested if impersonated as that same user * each time. Can switch back to root temporarily regardless of nesting * level via Impersonate_ForceRoot. Calling Impersonate_UnforceRoot will * return to original impersonation at the same nesting level. * * Results: * TRUE if impersonation succeeds, FALSE otherwise. * * Side effects: * imp.impersonatedUser may be updated. * imp.impersonatedToken(Win32 only) may be updated. * *---------------------------------------------------------------------------- */ Bool Impersonate_Do(const char *user, // IN AuthToken token) // IN { Bool res; if (!impersonationEnabled) { return TRUE; } ImpersonateLock(TRUE); res = ImpersonateDo(user, token); ImpersonateLock(FALSE); return res; } /* *---------------------------------------------------------------------------- * * Impersonate_Undo -- * * Undoes a previous impersonation. When we undo the last in the nesting * of impersonation ops, switch back to root. * * Results: * TRUE on success, FALSE otherwise * * Side effects: * On reverting back to root, * imp.impersonatedUser is freed. * imp.impersonatedToken (win32) is invalid. * *---------------------------------------------------------------------------- */ Bool Impersonate_Undo(void) { Bool res; ImpersonationState *imp = NULL; if (!impersonationEnabled) { return TRUE; } ImpersonateLock(TRUE); imp = ImpersonateGetTLS(); ASSERT(imp); WIN32_ONLY(ASSERT(!imp->forceRoot)); imp->refCount--; POSIX_ONLY(IMPWARN(("Impersonate_Undo (%x %x) drop refcount to %d\n", getpid(), imp, imp->refCount))); WIN32_ONLY(IMPWARN(("Impersonate_Undo (%x) drop refcount to %d\n", (int) imp, imp->refCount))); if (imp->refCount > 0) { ImpersonateLock(FALSE); return TRUE; } res = ImpersonateUndo(); ImpersonateLock(FALSE); return res; } /* *---------------------------------------------------------------------------- * * Impersonate_Who -- * * Returns currently impersonated user name. If not impersonated, * returns NULL. * * Results: * Currently impersonated user name. NULL if not impersonated. * * Side effects: * None. * *---------------------------------------------------------------------------- */ char * Impersonate_Who(void) { char *impUser; ImpersonationState *imp = NULL; if (!impersonationEnabled) { return strdup(""); } ImpersonateLock(TRUE); imp = ImpersonateGetTLS(); ASSERT(imp); impUser = strdup(imp->impersonatedUser); ASSERT_MEM_ALLOC(impUser); ImpersonateLock(FALSE); return impUser; } /* *---------------------------------------------------------------------------- * * Impersonate_ForceRoot -- * * Go back to base impersonate level (LocalSystem/root) for a brief period * of time. Doesnt do anything on linux. * Should only be used when already impersonated. This call is not nestable. * No other impersonation is permitted before calling Impersonate_UnforceRoot. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * imp.forceRoot is set to TRUE on success. * *---------------------------------------------------------------------------- */ Bool Impersonate_ForceRoot(void) { Bool res; if (!impersonationEnabled) { return TRUE; } ImpersonateLock(TRUE); res = ImpersonateForceRoot(); ImpersonateLock(FALSE); return res; } /* *---------------------------------------------------------------------------- * * Impersonate_UnforceRoot -- * * Go back to impersonate the user that we switched to root from. * See Impersonate_ForceRoot. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * imp.forceRoot is set to FALSE on success. * *---------------------------------------------------------------------------- */ Bool Impersonate_UnforceRoot(void) { Bool res; if (!impersonationEnabled) { return TRUE; } ImpersonateLock(TRUE); res = ImpersonateUnforceRoot(); ImpersonateLock(FALSE); return res; } #ifdef _WIN32 /* *---------------------------------------------------------------------------- * * Impersonate_CfgRunasOnly -- * * Impersonate as the preconfigured runas user for the VM. * Fails if runas user credentials are not found. * * Results: * TRUE if preconfigured runas user is found impersonation succeeds, * FALSE otherwise. * * Side effects: * imp.impersonatedUser may be updated. * *---------------------------------------------------------------------------- */ Bool Impersonate_CfgRunasOnly(const char *cfg) // IN { Bool res; ImpersonateLock(TRUE); res = Impersonate_Runas(cfg, NULL, NULL); ImpersonateLock(FALSE); return res; } #endif //_WIN32 open-vm-tools-9.4.0-1280544/lib/impersonate/impersonatePosix.c0000644765153500003110000002735312220061556022262 0ustar dtormts/********************************************************* * Copyright (C) 2003 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * impersonatePosix.c -- * * Description: * Posix specific functions to impersonate as specific users. */ #include #include #include #include #include #include #include #include #if !defined(VMX86_TOOLS) #include #endif #include #include "impersonateInt.h" #include "su.h" #include "posix.h" #if !defined(VMX86_TOOLS) static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; static pthread_key_t threadLocalStorageKey = INVALID_PTHREAD_KEY_VALUE; static void ThreadLocalFree(void *ptr); #else static ImpersonationState *impLinux = NULL; #endif static Bool ImpersonateDoPosix(struct passwd *pwd); /* *---------------------------------------------------------------------------- * * ImpersonateInit -- * * Linux specific initialization (thread local storage for linux) * * Results: * None. * * Side effects: * Memory created. * *---------------------------------------------------------------------------- */ void ImpersonateInit(void) { #if !defined(VMX86_TOOLS) int status; status = pthread_key_create(&threadLocalStorageKey, ThreadLocalFree); if (status != 0) { Warning("Impersonate: key_create failed: %d\n", status); ASSERT_NOT_IMPLEMENTED(status == 0); return; } ASSERT_NOT_IMPLEMENTED(threadLocalStorageKey != INVALID_PTHREAD_KEY_VALUE); #endif } /* *---------------------------------------------------------------------- * * ThreadLocalFree -- * * A wrapper for "free()". This function is called when a thread * terminates so that the thread-local state can be deallocated. * *---------------------------------------------------------------------- */ #if !defined(VMX86_TOOLS) static void ThreadLocalFree(void *ptr) { ImpersonationState *imp = (ImpersonationState*) ptr; IMPWARN(("Impersonate: ThreadLocalFree(0x%08x)\n", imp)); ASSERT(imp); ASSERT(imp->impersonatedUser == NULL); ASSERT(imp->refCount == 0); free(imp); } #endif /* *---------------------------------------------------------------------------- * * ImpersonateGetTLS -- * * This function abstracts away the differences between Linux and * Windows for obtaining a pointer to thread-local state. * * Results: * Returns pointer to thread-local state. * * Side effects: * On Linux this function will allocate state on the first occasion * that a particular thread calls this function for the first time. * *---------------------------------------------------------------------------- */ ImpersonationState * ImpersonateGetTLS(void) { ImpersonationState *ptr = NULL; int status; /* If a prior call has already allocated state, then use it */ #if !defined(VMX86_TOOLS) /* If a prior call has already allocated state, then use it */ ptr = pthread_getspecific(threadLocalStorageKey); #else ptr = impLinux; #endif if (ptr != NULL) { return ptr; } /* No state allocated, so we need to allocate it */ ptr = calloc(1, sizeof *ptr); ASSERT_MEM_ALLOC(ptr); #if !defined(VMX86_TOOLS) status = pthread_setspecific(threadLocalStorageKey, ptr); #else impLinux = ptr; status = 0; #endif if (status != 0) { Warning("Impersonate: setspecific: %d\n", status); ASSERT_NOT_IMPLEMENTED(status == 0); } return ptr; } /* *---------------------------------------------------------------------------- * * ImpersonateRunas -- * * Impersonate as the appropriate runas user. In linux this is always * the config file owner regardless the calling context. * * Results: * TRUE if impersonation succeeds, FALSE otherwise. * * Side effects: * imp.impersonatedUser may be updated. * *---------------------------------------------------------------------------- */ Bool ImpersonateRunas(const char *cfg, // IN const char *caller, // IN AuthToken callerToken) // IN { /* * In linux, this call always impersonates as the owner of the config file. */ ASSERT(!caller && !callerToken); return ImpersonateOwner(cfg); } /* *---------------------------------------------------------------------------- * * ImpersonateOwner -- * * Impersonate the owner of the config file. Only makes sense on linux. * * Results: * TRUE if impersonation succeeds, false otherwise. * * Side effects: * imp.impersonatedUser may be updated. * *---------------------------------------------------------------------------- */ Bool ImpersonateOwner(const char *file) // IN { struct stat buf; char buffer[BUFSIZ]; struct passwd pw; struct passwd *ppw = &pw; int error; if (Posix_Stat(file, &buf) == -1) { Warning("Failed to lookup owner for: %s. Reason: %s\n", file, Err_Errno2String(errno)); return FALSE; } if ((error = Posix_Getpwuid_r(buf.st_uid, &pw, buffer, BUFSIZ, &ppw)) != 0 || !ppw) { if (error == 0) { error = ENOENT; } Warning("Failed to lookup user with uid: %" FMTUID ". Reason: %s\n", buf.st_uid, Err_Errno2String(error)); return FALSE; } return ImpersonateDoPosix(ppw); } /* *---------------------------------------------------------------------- * * ImpersonateUndo -- Linux specific * * Change back into the superuser * * Side effects: * * EUID is set back to the superuser, and environment variables are * updated back. * *---------------------------------------------------------------------- */ Bool ImpersonateUndo(void) { char buffer[BUFSIZ]; struct passwd pw; struct passwd *ppw = &pw; ImpersonationState *imp = NULL; int ret; int error; #if !defined(VMX86_TOOLS) pthread_mutex_lock(&mut); #endif imp = ImpersonateGetTLS(); ASSERT(imp); //ASSERT(imp->impersonatedUser); if ((error = Posix_Getpwuid_r(0, &pw, buffer, BUFSIZ, &ppw)) != 0 || !ppw) { if (error == 0) { error = ENOENT; } ret = error; Warning("Failed to get password entry for uid 0: %s\n", Err_Errno2String(error)); goto exit; } #if __APPLE__ NOT_IMPLEMENTED(); #else /* Return to root */ ret = Id_SetEUid(ppw->pw_uid); if (ret < 0) { goto exit; } #endif ret = Id_SetGid(ppw->pw_gid); if (ret < 0) { goto exit; } /* * The call to initgroups leaks memory in versions of glibc earlier than 2.1.93. * See bug 10042. -jhu */ ret = initgroups(ppw->pw_name, ppw->pw_gid); if (ret < 0) { goto exit; } /* Restore root's environment */ Posix_Setenv("USER", ppw->pw_name, 1); Posix_Setenv("HOME", ppw->pw_dir, 1); Posix_Setenv("SHELL", ppw->pw_shell, 1); free((char *)imp->impersonatedUser); imp->impersonatedUser = NULL; ret = 0; exit: ASSERT_NOT_IMPLEMENTED(ret == 0); #if !defined(VMX86_TOOLS) pthread_mutex_unlock(&mut); #endif return (ret ? FALSE : TRUE); } /* *---------------------------------------------------------------------------- * * ImpersonateDoPosix -- * * Impersonate as the user corresponding to the passwd entry * XXX: Mostly copied from vmsd_impersonate.c * * Results: * TRUE if impersonation succeeds, FALSE otherwise. * * Side effects: * imp.impersonatedUser is updated. * *---------------------------------------------------------------------------- */ Bool ImpersonateDoPosix(struct passwd *pwd) // IN { int ret = 0; ImpersonationState *imp = NULL; #if !defined(VMX86_TOOLS) pthread_mutex_lock(&mut); #endif imp = ImpersonateGetTLS(); ASSERT(imp); if (pwd->pw_uid == geteuid()) { imp->refCount++; IMPWARN(("ImpersonateDoPosix (%s : %x : %x) refcount = %d\n", imp->impersonatedUser, getpid(), imp, imp->refCount)); goto unlock; } ASSERT(getuid() == 0); ASSERT_NOT_IMPLEMENTED(geteuid() == 0); ret = Id_SetGid(pwd->pw_gid); if (ret < 0) { goto exit; } /* * The call to initgroups leaks memory in versions of glibc earlier than * 2.1.93.See bug 10042. -jhu */ ret = initgroups(pwd->pw_name, pwd->pw_gid); if (ret < 0) { goto exit; } #if __APPLE__ NOT_IMPLEMENTED(); #else ret = Id_SetEUid(pwd->pw_uid); if (ret < 0) { goto exit; } #endif /* Setup the user's environment */ Posix_Setenv("USER", pwd->pw_name, 1); Posix_Setenv("HOME", pwd->pw_dir, 1); Posix_Setenv("SHELL", pwd->pw_shell, 1); imp->impersonatedUser = strdup(pwd->pw_name); ASSERT_MEM_ALLOC(imp->impersonatedUser); exit: imp->refCount = 1; ASSERT_NOT_IMPLEMENTED(ret == 0); unlock: #if !defined(VMX86_TOOLS) pthread_mutex_unlock(&mut); #endif return (ret ? FALSE : TRUE); } /* *---------------------------------------------------------------------------- * * ImpersonateDo -- * * Impersonate as user. Can be nested if impersonated as that same user * each time. Can switch back to root temporarily regardless of nesting * level via Impersonate_ForceRoot. Calling Impersonate_UnforceRoot will * return to original impersonation at the same nesting level. * * Results: * TRUE if impersonation succeeds, FALSE otherwise. * * Side effects: * imp.impersonatedUser may be updated. * *---------------------------------------------------------------------------- */ Bool ImpersonateDo(const char *user, // IN AuthToken token) // IN { char buffer[BUFSIZ]; struct passwd pw; struct passwd *ppw = &pw; int error; if ((error = Posix_Getpwnam_r(user, &pw, buffer, BUFSIZ, &ppw)) != 0 || !ppw) { if (error == 0) { error = ENOENT; } Warning("Failed to get password entry for : %s. Reason: %s\n", user, Err_Errno2String(error)); return FALSE; } return ImpersonateDoPosix(ppw); } /* *---------------------------------------------------------------------------- * * ImpersonateForceRoot -- * * Go back to base impersonate level (LocalSystem/root) for a brief * period of time. * Should only be used when already impersonated. This call is not nestable. * No other impersonation is permitted before calling Impersonate_UnforceRoot. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * imp.forceRoot is set to TRUE on success. * *---------------------------------------------------------------------------- */ Bool ImpersonateForceRoot(void) { return TRUE; } /* *---------------------------------------------------------------------------- * * ImpersonateUnforceRoot -- * * Unforce from root to original impersonation context * * Results: * TRUE on success, FALSE otherwise. * * Side effects: * imp.forceRoot is set to FALSE on success * *---------------------------------------------------------------------------- */ Bool ImpersonateUnforceRoot(void) { return TRUE; } open-vm-tools-9.4.0-1280544/lib/impersonate/impersonateInt.h0000644765153500003110000000375712220061556021721 0ustar dtormts/********************************************************* * Copyright (C) 2003 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * impersonateInt.h -- * * Header file shared by impersonate code */ #ifndef _IMPERSONATE_INT_H_ #define _IMPERSONATE_INT_H_ #include "vmware.h" #include "msg.h" #include "impersonate.h" #include "auth.h" //#define IMP_VERBOSE 1 #define INVALID_PTHREAD_KEY_VALUE (-1) #ifdef IMP_VERBOSE #define IMPWARN(x) Warning x #else #define IMPWARN(x) #endif typedef struct ImpersonationState { const char *impersonatedUser; // the user we are currently impersonating int refCount; // # of times we are impersonating as same user #ifdef _WIN32 HANDLE impersonatedToken; // the access token currently impersonated with Bool forceRoot; // are we temporarily switching back to root? #endif } ImpersonationState; void ImpersonateInit(void); ImpersonationState *ImpersonateGetTLS(void); Bool ImpersonateRunas(const char *cfg, const char *caller, AuthToken callerToken); Bool ImpersonateOwner(const char *file); Bool ImpersonateDo(const char *user, AuthToken token); Bool ImpersonateUndo(void); Bool ImpersonateForceRoot(void); Bool ImpersonateUnforceRoot(void); #endif // ImpersonateInt.h open-vm-tools-9.4.0-1280544/lib/impersonate/Makefile.am0000644765153500003110000000207412220061556020572 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libImpersonate.la libImpersonate_la_SOURCES = libImpersonate_la_SOURCES += impersonate.c libImpersonate_la_SOURCES += impersonatePosix.c AM_CFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ open-vm-tools-9.4.0-1280544/lib/impersonate/Makefile.in0000644765153500003110000004413712220061622020603 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/impersonate DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libImpersonate_la_LIBADD = am_libImpersonate_la_OBJECTS = impersonate.lo impersonatePosix.lo libImpersonate_la_OBJECTS = $(am_libImpersonate_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libImpersonate_la_SOURCES) DIST_SOURCES = $(libImpersonate_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libImpersonate.la libImpersonate_la_SOURCES = impersonate.c impersonatePosix.c AM_CFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/impersonate/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/impersonate/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libImpersonate.la: $(libImpersonate_la_OBJECTS) $(libImpersonate_la_DEPENDENCIES) $(EXTRA_libImpersonate_la_DEPENDENCIES) $(LINK) $(libImpersonate_la_OBJECTS) $(libImpersonate_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impersonate.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impersonatePosix.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/foundryMsg/0000755765153500003110000000000012220061622016334 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/foundryMsg/foundryMsg.c0000644765153500003110000023673012220061556020656 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * foundryMsg.c -- * * This is a library for formatting and parsing the messages sent * between a foundry client and the VMX. It is a stand-alone library * so it can be used by the VMX tree without also linking in the * entire foundry client-side library. */ #include "vmware.h" #include "vm_version.h" #include "util.h" #include "str.h" #include "base64.h" #include "vixOpenSource.h" #include "vixCommands.h" #include "unicodeBase.h" static char PlainToObfuscatedCharMap[256]; static char ObfuscatedToPlainCharMap[256]; /* * An entry in the command info table. There is one VixCommandInfo per op * code, and each entry contains a description of the op code plus security- * related metadata. */ typedef struct VixCommandInfo { int opCode; const char *commandName; VixCommandSecurityCategory category; Bool used; // Is there an opcode for this entry? } VixCommandInfo; #define VIX_DEFINE_COMMAND_INFO(x, category) { x, #x, category, TRUE } #define VIX_DEFINE_UNUSED_COMMAND { 0, NULL, VIX_COMMAND_CATEGORY_UNKNOWN, FALSE } /* * Contains the information for every VIX command op code. This table is * organized to allow for direct look up, so it must be complete. Any index * that does not correspond to a valid VIX op code must be marked with * VIX_DEFINE_UNUSED_COMMAND. * * When you add or remove a command to vixCommands.h, this table needs to * be updated as well. When adding a new command, you need to give it a * security category. There are descriptions of the categories in vixCommands.h * where they are defined, but in general, if the command affects the host or * a VM (but not the guest), then the command should be CATEGORY_PRIVILEGED. * If the command is a guest command (a command the runs inside the guest * OS) than it should be CATEGORY_ALWAYS_ALLOWED. Also, if a command is * required to establish a connection with the VMX, it needs to be * CATEGORY_ALWAYS_ALLOWED. */ static const VixCommandInfo vixCommandInfoTable[] = { VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_UNKNOWN, VIX_COMMAND_CATEGORY_UNKNOWN), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_VM_POWERON, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_VM_POWEROFF, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_VM_RESET, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_VM_SUSPEND, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_RUN_PROGRAM, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_KEYSTROKES, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_READ_REGISTRY, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_WRITE_REGISTRY, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_COPY_FILE_FROM_GUEST_TO_HOST, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_COPY_FILE_FROM_HOST_TO_GUEST, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CREATE_SNAPSHOT, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_REMOVE_SNAPSHOT, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_REVERT_TO_SNAPSHOT, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_VM_CLONE, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_DELETE_GUEST_FILE, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GUEST_FILE_EXISTS, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_FIND_VM, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CALL_PROCEDURE, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_REGISTRY_KEY_EXISTS, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_WIN32_WINDOW_MESSAGE, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CONSOLIDATE_SNAPSHOTS, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_INSTALL_TOOLS, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CANCEL_INSTALL_TOOLS, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_UPGRADE_VIRTUAL_HARDWARE, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_RELOAD_VM, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_DELETE_VM, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_WAIT_FOR_TOOLS, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CREATE_RUNNING_VM_SNAPSHOT, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CONSOLIDATE_RUNNING_VM_SNAPSHOT, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GET_NUM_SHARED_FOLDERS, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GET_SHARED_FOLDER_STATE, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_EDIT_SHARED_FOLDER_STATE, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_REMOVE_SHARED_FOLDER, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_ADD_SHARED_FOLDER, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_RUN_SCRIPT_IN_GUEST, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_OPEN_VM, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, /* GET_HANDLE_STATE is needed for the initial handshake */ VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GET_HANDLE_STATE, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CREATE_WORKING_COPY, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_DISCARD_WORKING_COPY, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SAVE_WORKING_COPY, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CAPTURE_SCREEN, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GET_TOOLS_STATE, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CHANGE_SCREEN_RESOLUTION, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_DIRECTORY_EXISTS, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_DELETE_GUEST_REGISTRY_KEY, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_DELETE_GUEST_DIRECTORY, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_DELETE_GUEST_EMPTY_DIRECTORY, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CREATE_TEMPORARY_FILE, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_LIST_PROCESSES, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_MOVE_GUEST_FILE, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CREATE_DIRECTORY, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CHECK_USER_ACCOUNT, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_LIST_DIRECTORY, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_REGISTER_VM, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_UNREGISTER_VM, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_UNUSED_COMMAND, /* CREATE_SESSION_KEY is needed for the initial handshake */ VIX_DEFINE_COMMAND_INFO(VIX_CREATE_SESSION_KEY_COMMAND, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VMXI_HGFS_SEND_PACKET_COMMAND, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_KILL_PROCESS, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_LOGOUT_IN_GUEST, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_READ_VARIABLE, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_WRITE_VARIABLE, VIX_COMMAND_CATEGORY_MIXED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CONNECT_DEVICE, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_IS_DEVICE_CONNECTED, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GET_FILE_INFO, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SET_FILE_INFO, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_MOUSE_EVENTS, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_OPEN_TEAM, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_ANSWER_MESSAGE, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_ENABLE_SHARED_FOLDERS, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_MOUNT_HGFS_FOLDERS, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_HOT_EXTEND_DISK, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_UNUSED_COMMAND, /* * vProbes are only available remotely through VIX, so we should * let them through. If they get added to the VMODL with their own * permissions, then we will have to revisit. */ VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GET_VPROBES_VERSION, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GET_VPROBES, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_VPROBE_GET_GLOBALS, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_VPROBE_LOAD, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_VPROBE_RESET, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CONNECT_HOST, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CREATE_LINKED_CLONE, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_STOP_SNAPSHOT_LOG_RECORDING, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_STOP_SNAPSHOT_LOG_PLAYBACK, VIX_COMMAND_CATEGORY_PRIVILEGED), /* * HOWTO: Adding a new Vix Command. Step 2b. * Take the command you added to vixCommands.h, and add it to this * table. The command needs to go in the index that matches the command * ID as specified in the enum in vixCommands.h. */ VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SAMPLE_COMMAND, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GET_GUEST_NETWORKING_CONFIG, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SET_GUEST_NETWORKING_CONFIG, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_FAULT_TOLERANCE_REGISTER, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_FAULT_TOLERANCE_UNREGISTER, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_FAULT_TOLERANCE_CONTROL, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_FAULT_TOLERANCE_QUERY_SECONDARY, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_VM_PAUSE, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_VM_UNPAUSE, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GET_PERFORMANCE_DATA, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GET_SNAPSHOT_SCREENSHOT, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_WAIT_FOR_USER_ACTION_IN_GUEST, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CHANGE_VIRTUAL_HARDWARE, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_HOT_PLUG_CPU, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_HOT_PLUG_MEMORY, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_HOT_ADD_DEVICE, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_HOT_REMOVE_DEVICE, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_DEBUGGER_ATTACH, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_DEBUGGER_DETACH, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_DEBUGGER_SEND_COMMAND, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, /* GET_VMX_DEVICE_STATE is needed for the initial handshake. */ VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GET_VMX_DEVICE_STATE, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SET_SNAPSHOT_INFO, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SNAPSHOT_SET_MRU, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_LOGOUT_HOST, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_HOT_PLUG_BEGIN_BATCH, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_HOT_PLUG_COMMIT_BATCH, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_TRANSFER_CONNECTION, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_TRANSFER_REQUEST, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_TRANSFER_FINAL_DATA, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_UNUSED_COMMAND, VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_LIST_FILESYSTEMS, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CHANGE_DISPLAY_TOPOLOGY, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SUSPEND_AND_RESUME, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_REMOVE_BULK_SNAPSHOT, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_COPY_FILE_FROM_READER_TO_GUEST, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GENERATE_NONCE, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CHANGE_DISPLAY_TOPOLOGY_MODES, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_QUERY_CHILDREN, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_LIST_FILES, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CREATE_DIRECTORY_EX, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_MOVE_GUEST_FILE_EX, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_MOVE_GUEST_DIRECTORY, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CREATE_TEMPORARY_FILE_EX, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CREATE_TEMPORARY_DIRECTORY, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SET_GUEST_FILE_ATTRIBUTES, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_COPY_FILE_FROM_GUEST_TO_READER, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_START_PROGRAM, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_LIST_PROCESSES_EX, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_READ_ENV_VARIABLES, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_INITIATE_FILE_TRANSFER_FROM_GUEST, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_INITIATE_FILE_TRANSFER_TO_GUEST, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_ACQUIRE_CREDENTIALS, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_RELEASE_CREDENTIALS, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_VALIDATE_CREDENTIALS, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_TERMINATE_PROCESS, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_DELETE_GUEST_FILE_EX, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_DELETE_GUEST_DIRECTORY_EX, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_HOT_CHANGE_MONITOR_TYPE, VIX_COMMAND_CATEGORY_PRIVILEGED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_ADD_AUTH_ALIAS, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_REMOVE_AUTH_ALIAS, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_LIST_AUTH_PROVIDER_ALIASES, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_LIST_AUTH_MAPPED_ALIASES, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CREATE_REGISTRY_KEY, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_LIST_REGISTRY_KEYS, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_DELETE_REGISTRY_KEY, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SET_REGISTRY_VALUE, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_LIST_REGISTRY_VALUES, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_DELETE_REGISTRY_VALUE, VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED), }; static const VixCommandInfo *VixGetCommandInfoForOpCode(int opCode); static void VixMsgInitializeObfuscationMapping(void); static VixError VixMsgEncodeBuffer(const uint8 *buffer, size_t bufferLength, Bool includeEncodingId, char **result); static VixError VixMsgDecodeBuffer(const char *str, Bool nullTerminateResult, char **result, size_t *bufferLength); static VixError VMAutomationMsgParserInit(const char *caller, unsigned int line, VMAutomationMsgParser *state, const VixMsgHeader *msg, size_t headerLength, size_t fixedLength, size_t miscDataLength, const char *packetType); /* *---------------------------------------------------------------------------- * * VixMsg_AllocResponseMsg -- * * Allocate and initialize a response message. * * Results: * The message, with the headers properly initialized. * * Side effects: * None. * *---------------------------------------------------------------------------- */ VixCommandResponseHeader * VixMsg_AllocResponseMsg(const VixCommandRequestHeader *requestHeader, // IN VixError error, // IN uint32 additionalError, // IN size_t responseBodyLength, // IN const void *responseBody, // IN size_t *responseMsgLength) // OUT { char *responseBuffer = NULL; VixCommandResponseHeader *responseHeader; size_t totalMessageSize; ASSERT((NULL != responseBody) || (0 == responseBodyLength)); /* * We don't have scatter/gather, so copy everything into one buffer. */ totalMessageSize = sizeof(VixCommandResponseHeader) + responseBodyLength; if (totalMessageSize > VIX_COMMAND_MAX_SIZE) { /* * We don't want to allocate any responses larger than * VIX_COMMAND_MAX_SIZE, since the VMX will ignore them. * If we hit this ASSERT, we will need to either revise this * value, or start packetizing certain commands. */ ASSERT(0); return NULL; } responseBuffer = Util_SafeMalloc(totalMessageSize); responseHeader = (VixCommandResponseHeader *) responseBuffer; VixMsg_InitResponseMsg(responseHeader, requestHeader, error, additionalError, totalMessageSize); if ((responseBodyLength > 0) && (responseBody)) { memcpy(responseBuffer + sizeof(VixCommandResponseHeader), responseBody, responseBodyLength); } if (NULL != responseMsgLength) { *responseMsgLength = totalMessageSize; } return responseHeader; } // VixMsg_AllocResponseMsg /* *---------------------------------------------------------------------------- * * VixMsg_InitResponseMsg -- * * Initialize a response message. * * Results: * The message, with the headers properly initialized. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void VixMsg_InitResponseMsg(VixCommandResponseHeader *responseHeader, // IN const VixCommandRequestHeader *requestHeader, // IN VixError error, // IN uint32 additionalError, // IN size_t totalMessageSize) // IN { size_t responseBodyLength; ASSERT(NULL != responseHeader); ASSERT(totalMessageSize >= sizeof(VixCommandResponseHeader)); responseBodyLength = totalMessageSize - sizeof(VixCommandResponseHeader); /* * Fill in the response header. */ responseHeader->commonHeader.magic = VIX_COMMAND_MAGIC_WORD; responseHeader->commonHeader.messageVersion = VIX_COMMAND_MESSAGE_VERSION; responseHeader->commonHeader.totalMessageLength = totalMessageSize; responseHeader->commonHeader.headerLength = sizeof(VixCommandResponseHeader); responseHeader->commonHeader.bodyLength = responseBodyLength; responseHeader->commonHeader.credentialLength = 0; responseHeader->commonHeader.commonFlags = 0; if (NULL != requestHeader) { responseHeader->requestCookie = requestHeader->cookie; } else { responseHeader->requestCookie = 0; } responseHeader->responseFlags = 0; responseHeader->duration = 0xFFFFFFFF; responseHeader->error = error; responseHeader->additionalError = additionalError; responseHeader->errorDataLength = 0; } // VixMsg_InitResponseMsg /* *----------------------------------------------------------------------------- * * VixMsg_AllocRequestMsg -- * * Allocate and initialize a request message. * * Results: * The message, with the headers properly initialized. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixCommandRequestHeader * VixMsg_AllocRequestMsg(size_t msgHeaderAndBodyLength, // IN int opCode, // IN uint64 cookie, // IN int credentialType, // IN const char *credential) // IN { size_t totalMessageSize; VixCommandRequestHeader *commandRequest = NULL; size_t providedCredentialLength = 0; size_t totalCredentialLength = 0; char *destPtr; if ((VIX_USER_CREDENTIAL_NAME_PASSWORD == credentialType) || (VIX_USER_CREDENTIAL_HOST_CONFIG_SECRET == credentialType) || (VIX_USER_CREDENTIAL_HOST_CONFIG_HASHED_SECRET == credentialType) || (VIX_USER_CREDENTIAL_TICKETED_SESSION == credentialType) || (VIX_USER_CREDENTIAL_SSPI == credentialType) || (VIX_USER_CREDENTIAL_SAML_BEARER_TOKEN == credentialType)) { /* * All of these are optional. */ if (NULL != credential) { providedCredentialLength = strlen(credential); totalCredentialLength += providedCredentialLength; } /* * Add 1 to each string to include '\0' for the end of the string. */ totalCredentialLength += 1; } else { totalCredentialLength = 0; } totalMessageSize = msgHeaderAndBodyLength + totalCredentialLength; if (totalMessageSize > VIX_COMMAND_MAX_REQUEST_SIZE) { /* * We don't want to allocate any requests larger than * VIX_COMMAND_MAX_REQUEST_SIZE, since the VMX will ignore them. * If we hit this ASSERT, we will need to either revise this * value, or start packetizing certain commands. */ ASSERT(0); return NULL; } commandRequest = (VixCommandRequestHeader *) Util_SafeCalloc(1, totalMessageSize); commandRequest->commonHeader.magic = VIX_COMMAND_MAGIC_WORD; commandRequest->commonHeader.messageVersion = VIX_COMMAND_MESSAGE_VERSION; commandRequest->commonHeader.totalMessageLength = msgHeaderAndBodyLength + totalCredentialLength; commandRequest->commonHeader.headerLength = sizeof(VixCommandRequestHeader); commandRequest->commonHeader.bodyLength = msgHeaderAndBodyLength - sizeof(VixCommandRequestHeader); commandRequest->commonHeader.credentialLength = totalCredentialLength; commandRequest->commonHeader.commonFlags = VIX_COMMAND_REQUEST; commandRequest->opCode = opCode; commandRequest->cookie = cookie; commandRequest->timeOut = 0xFFFFFFFF; commandRequest->requestFlags = 0; commandRequest->userCredentialType = credentialType; if ((VIX_USER_CREDENTIAL_NAME_PASSWORD == credentialType) || (VIX_USER_CREDENTIAL_HOST_CONFIG_SECRET == credentialType) || (VIX_USER_CREDENTIAL_HOST_CONFIG_HASHED_SECRET == credentialType) || (VIX_USER_CREDENTIAL_TICKETED_SESSION == credentialType) || (VIX_USER_CREDENTIAL_SSPI == credentialType) || (VIX_USER_CREDENTIAL_SAML_BEARER_TOKEN == credentialType)) { destPtr = (char *) commandRequest; destPtr += commandRequest->commonHeader.headerLength; destPtr += commandRequest->commonHeader.bodyLength; if (NULL != credential) { Str_Strcpy(destPtr, credential, providedCredentialLength + 1); destPtr += providedCredentialLength; } *(destPtr++) = 0; } return commandRequest; } // VixMsg_AllocRequestMsg /* *----------------------------------------------------------------------------- * * VixMsg_ValidateMessage -- * * * Results: * VixError * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError VixMsg_ValidateMessage(const void *vMsg, // IN size_t msgLength) // IN { const VixMsgHeader *message; if ((NULL == vMsg) || (msgLength < sizeof *message)) { return VIX_E_INVALID_MESSAGE_HEADER; } /* * Sanity check the header. * Some basic rules: All the length values in the VixMsgHeader * struct are uint32. The headerLength must be large enough to * accomodate the base header: VixMsgHeader. The bodyLength and * the credentialLength can be 0. * * We cannot compare message->totalMessageLength and msgLength. * When we first read just the header, message->totalMessageLength * is > msgLength. When we have read the whole message, then * message->totalMessageLength <= msgLength. So, it depends on * when we call this function. Instead, we just make sure the message * is internally consistent, and then rely on the higher level code to * decide how much to read and when it has read the whole message. */ message = vMsg; if ((VIX_COMMAND_MAGIC_WORD != message->magic) || (message->headerLength < sizeof(VixMsgHeader)) || (message->totalMessageLength < ((uint64)message->headerLength + message->bodyLength + message->credentialLength)) || (message->totalMessageLength > VIX_COMMAND_MAX_SIZE) || (VIX_COMMAND_MESSAGE_VERSION != message->messageVersion)) { return VIX_E_INVALID_MESSAGE_HEADER; } return VIX_OK; } // VixMsg_ValidateMessage /* *----------------------------------------------------------------------------- * * VixMsg_ValidateRequestMsg -- * * * Results: * VixError * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError VixMsg_ValidateRequestMsg(const void *vMsg, // IN size_t msgLength) // IN { VixError err; const VixCommandRequestHeader *message; err = VixMsg_ValidateMessage(vMsg, msgLength); if (VIX_OK != err) { return(err); } /* * Sanity check the parts of the header that are specific to requests. */ message = vMsg; if (message->commonHeader.headerLength < sizeof(VixCommandRequestHeader)) { return VIX_E_INVALID_MESSAGE_HEADER; } if (message->commonHeader.totalMessageLength > VIX_COMMAND_MAX_REQUEST_SIZE) { return VIX_E_INVALID_MESSAGE_HEADER; } if (!(VIX_COMMAND_REQUEST & message->commonHeader.commonFlags)) { return VIX_E_INVALID_MESSAGE_HEADER; } if ((VIX_REQUESTMSG_INCLUDES_AUTH_DATA_V1 & message->requestFlags) && (message->commonHeader.totalMessageLength < (uint64)message->commonHeader.headerLength + message->commonHeader.bodyLength + message->commonHeader.credentialLength + sizeof (VixMsgAuthDataV1))) { return VIX_E_INVALID_MESSAGE_HEADER; } return VIX_OK; } // VixMsg_ValidateRequestMsg /* *----------------------------------------------------------------------------- * * VixMsg_ValidateResponseMsg -- * * * Results: * VixError * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError VixMsg_ValidateResponseMsg(const void *vMsg, // IN size_t msgLength) // IN { VixError err; const VixCommandResponseHeader *message; if ((NULL == vMsg) || (msgLength < sizeof *message)) { return VIX_E_INVALID_MESSAGE_HEADER; } err = VixMsg_ValidateMessage(vMsg, msgLength); if (VIX_OK != err) { return(err); } /* * Sanity check the parts of the header that are specific to responses. */ message = vMsg; if (message->commonHeader.headerLength < sizeof(VixCommandResponseHeader)) { return VIX_E_INVALID_MESSAGE_HEADER; } if (VIX_COMMAND_REQUEST & message->commonHeader.commonFlags) { return VIX_E_INVALID_MESSAGE_HEADER; } return VIX_OK; } // VixMsg_ValidateResponseMsg /* *----------------------------------------------------------------------------- * * VixMsg_ParseWriteVariableRequest -- * * Extract the value's name and the value itself from the request * message, while validating message. * * The strings returned from this function just point to memory in * the message itself, so they must not be free()'d. * * Results: * VixError * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError VixMsg_ParseWriteVariableRequest(VixMsgWriteVariableRequest *msg, // IN char **valueName, // OUT char **value) // OUT { VixError err; char *valueNameLocal = NULL; char *valueLocal = NULL; uint64 headerAndBodyLength; if ((NULL == msg) || (NULL == valueName) || (NULL == value)) { ASSERT(0); err = VIX_E_FAIL; goto abort; } *valueName = NULL; *value = NULL; /* * In most cases we will have already called VixMsg_ValidateResponseMsg() * on this request before, but call it here so that this function will * always be sufficient to validate the request. */ err = VixMsg_ValidateRequestMsg(msg, msg->header.commonHeader.totalMessageLength); if (VIX_OK != err) { goto abort; } if (msg->header.commonHeader.totalMessageLength < sizeof *msg) { err = VIX_E_INVALID_MESSAGE_BODY; goto abort; } headerAndBodyLength = (uint64) msg->header.commonHeader.headerLength + msg->header.commonHeader.bodyLength; if (headerAndBodyLength < ((uint64) sizeof *msg + msg->nameLength + 1 + msg->valueLength + 1)) { err = VIX_E_INVALID_MESSAGE_BODY; goto abort; } valueNameLocal = ((char *) msg) + sizeof(*msg); if ('\0' != valueNameLocal[msg->nameLength]) { err = VIX_E_INVALID_MESSAGE_BODY; goto abort; } valueLocal = valueNameLocal + msg->nameLength + 1; if ('\0' != valueLocal[msg->valueLength]) { err = VIX_E_INVALID_MESSAGE_BODY; goto abort; } *valueName = valueNameLocal; *value = valueLocal; err = VIX_OK; abort: return err; } // VixMsg_ParseWriteVariableRequest /* *----------------------------------------------------------------------------- * * VixMsgInitializeObfuscationMapping -- * * * Results: * None * * Side effects: * None. * *----------------------------------------------------------------------------- */ void VixMsgInitializeObfuscationMapping(void) { size_t charIndex; static Bool initializedTable = FALSE; if (initializedTable) { return; } for (charIndex = 0; charIndex < sizeof(PlainToObfuscatedCharMap); charIndex++) { PlainToObfuscatedCharMap[charIndex] = 0; ObfuscatedToPlainCharMap[charIndex] = 0; } PlainToObfuscatedCharMap['\\'] = '1'; PlainToObfuscatedCharMap['\''] = '2'; PlainToObfuscatedCharMap['\"'] = '3'; PlainToObfuscatedCharMap[' '] = '4'; PlainToObfuscatedCharMap['\r'] = '5'; PlainToObfuscatedCharMap['\n'] = '6'; PlainToObfuscatedCharMap['\t'] = '7'; ObfuscatedToPlainCharMap['1'] = '\\'; ObfuscatedToPlainCharMap['2'] = '\''; ObfuscatedToPlainCharMap['3'] = '\"'; ObfuscatedToPlainCharMap['4'] = ' '; ObfuscatedToPlainCharMap['5'] = '\r'; ObfuscatedToPlainCharMap['6'] = '\n'; ObfuscatedToPlainCharMap['7'] = '\t'; initializedTable = TRUE; } // VixMsgInitializeObfuscationMapping /* *----------------------------------------------------------------------------- * * VixMsg_ObfuscateNamePassword -- * * This is NOT ENCRYPTION. * * This function does 2 things: * * It removes spaces, quotes and other characters that may make * parsing params in a string difficult. The name and password is * passed from the VMX to the tools through the backdoor as a * string containing quoted parameters. * * * It means that somebody doing a trivial string search on * host memory won't see a name/password. * * This is used ONLY between the VMX and guest through the backdoor. * This is NOT secure. * * Results: * VixError * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError VixMsg_ObfuscateNamePassword(const char *userName, // IN const char *password, // IN char **result) // OUT { VixError err = VIX_OK; char *packedBuffer = NULL; char *resultString = NULL; char *destPtr; size_t packedBufferLength = 0; size_t nameLength = 0; size_t passwordLength = 0; if (NULL != userName) { nameLength = strlen(userName); } if (NULL != password) { passwordLength = strlen(password); } /* * Leave space for null terminating characters. */ packedBufferLength = nameLength + 1 + passwordLength + 1; packedBuffer = VixMsg_MallocClientData(packedBufferLength); if (packedBuffer == NULL) { err = VIX_E_OUT_OF_MEMORY; goto abort; } destPtr = packedBuffer; if (NULL != userName) { Str_Strcpy(destPtr, userName, nameLength + 1); destPtr += nameLength; } *(destPtr++) = 0; if (NULL != password) { Str_Strcpy(destPtr, password, passwordLength + 1); destPtr += passwordLength; } *(destPtr++) = 0; err = VixMsgEncodeBuffer(packedBuffer, packedBufferLength, FALSE, &resultString); if (err != VIX_OK) { goto abort; } abort: Util_ZeroFree(packedBuffer, packedBufferLength); if (err == VIX_OK) { *result = resultString; } return err; } // VixMsg_ObfuscateNamePassword /* *----------------------------------------------------------------------------- * * VixMsg_DeObfuscateNamePassword -- * * This reverses VixMsg_ObfuscateNamePassword. * See the notes for that procedure. * * Results: * VixError. VIX_OK if successful. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError VixMsg_DeObfuscateNamePassword(const char *packagedName, // IN char **userNameResult, // OUT char **passwordResult) // OUT { VixError err; char *packedString = NULL; char *srcPtr; size_t packedStringLength; char *userName = NULL; char *passwd = NULL; err = VixMsgDecodeBuffer(packagedName, FALSE, &packedString, &packedStringLength); if (err != VIX_OK) { goto abort; } srcPtr = packedString; if (NULL != userNameResult) { Bool allocateFailed; userName = VixMsg_StrdupClientData(srcPtr, &allocateFailed); if (allocateFailed) { err = VIX_E_OUT_OF_MEMORY; goto abort; } } srcPtr = srcPtr + strlen(srcPtr); srcPtr++; if (NULL != passwordResult) { Bool allocateFailed; passwd = VixMsg_StrdupClientData(srcPtr, &allocateFailed); if (allocateFailed) { err = VIX_E_OUT_OF_MEMORY; goto abort; } } *userNameResult = userName; userName = NULL; *passwordResult = passwd; passwd = NULL; abort: Util_ZeroFree(packedString, packedStringLength); Util_ZeroFreeString(userName); Util_ZeroFreeString(passwd); return err; } // VixMsg_DeObfuscateNamePassword /* *----------------------------------------------------------------------------- * * VixMsg_EncodeString -- * * This makes a string safe to pass over a backdoor Tclo command as a * string. It base64 encodes a string, which removes quote, space, * backslash, and other characters. This will also allow us to pass * UTF-8 strings. * * Results: * VixError * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError VixMsg_EncodeString(const char *str, // IN char **result) // OUT { if (NULL == str) { str = ""; } return VixMsgEncodeBuffer(str, strlen(str), TRUE, result); } // VixMsg_EncodeString /* *----------------------------------------------------------------------------- * * VixMsgEncodeBuffer -- * * This makes a string safe to pass over a backdoor Tclo command as a * string. It base64 encodes a string, which removes quote, space, * backslash, and other characters. This will also allow us to pass * UTF-8 strings. * * Results: * VixError * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError VixMsgEncodeBuffer(const uint8 *buffer, // IN size_t bufferLength, // IN Bool includeEncodingId, // IN: Add 'a' (ASCII) at start of output char ** result) // OUT { VixError err = VIX_OK; char *base64String = NULL; char *resultString = NULL; size_t resultBufferLength = 0; char *srcPtr; char *endSrcPtr; char *destPtr; size_t base64Length; base64Length = Base64_EncodedLength((uint8 const *) buffer, bufferLength); base64String = VixMsg_MallocClientData(base64Length); if (base64String == NULL) { err = VIX_E_OUT_OF_MEMORY; goto abort; } if (!(Base64_Encode((uint8 const *) buffer, bufferLength, base64String, base64Length, &base64Length))) { err = VIX_E_FAIL; goto abort; } VixMsgInitializeObfuscationMapping(); /* * Expand it to make space for escaping some characters. */ resultBufferLength = base64Length * 2; if (includeEncodingId) { resultBufferLength++; } resultString = VixMsg_MallocClientData(resultBufferLength + 1); if (resultString == NULL) { err = VIX_E_OUT_OF_MEMORY; goto abort; } destPtr = resultString; srcPtr = base64String; endSrcPtr = base64String + base64Length; if (includeEncodingId) { /* * Start with the character-set type. * 'a' means ASCII. */ *(destPtr++) = 'a'; } /* * Now, escape problematic characters. */ while (srcPtr < endSrcPtr) { if (PlainToObfuscatedCharMap[(unsigned int) (*srcPtr)]) { *(destPtr++) = '\\'; *(destPtr++) = PlainToObfuscatedCharMap[(unsigned int) (*srcPtr)]; } else { *(destPtr++) = *srcPtr; } srcPtr++; } ASSERT_NOT_IMPLEMENTED((destPtr - resultString) <= resultBufferLength); *destPtr = 0; abort: free(base64String); if (err == VIX_OK) { *result = resultString; } return err; } // VixMsgEncodeBuffer /* *----------------------------------------------------------------------------- * * VixMsg_DecodeString -- * * This reverses VixMsg_EncodeString. * See the notes for that procedure. * * Results: * VixError. VIX_OK if successful. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError VixMsg_DecodeString(const char *str, // IN char **result) // OUT { /* * Check the character set. * 'a' means ASCII. */ if ((NULL == str) || ('a' != *str)) { *result = NULL; return VIX_E_INVALID_ARG; } return VixMsgDecodeBuffer(str + 1, TRUE, result, NULL); } // VixMsg_DecodeString /* *----------------------------------------------------------------------------- * * VixMsgDecodeBuffer -- * * This reverses VixMsgEncodeBuffer. * See the notes for that procedure. * * Results: * VixError. VIX_OK if successful. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError VixMsgDecodeBuffer(const char *str, // IN Bool nullTerminateResult, // OUT char **result, // OUT size_t *bufferLength) // OUT: Optional { VixError err = VIX_OK; char *base64String = NULL; char *resultStr = NULL; char *srcPtr; char *destPtr; size_t resultStrAllocatedLength; size_t resultStrLogicalLength; Bool allocateFailed; if (NULL != bufferLength) { *bufferLength = 0; } /* * Remove escaped special characters. * Do this in a private copy because we will change the string in place. */ VixMsgInitializeObfuscationMapping(); base64String = VixMsg_StrdupClientData(str, &allocateFailed); if (allocateFailed) { err = VIX_E_OUT_OF_MEMORY; goto abort; } destPtr = base64String; srcPtr = base64String; while (*srcPtr) { if ('\\' == *srcPtr) { srcPtr++; /* * There should never be a null byte as part of an escape character or * an escape character than translates into a null byte. */ if ((0 == *srcPtr) || (0 == ObfuscatedToPlainCharMap[(unsigned int) (*srcPtr)])) { goto abort; } *(destPtr++) = ObfuscatedToPlainCharMap[(unsigned int) (*srcPtr)]; } else { *(destPtr++) = *srcPtr; } srcPtr++; } *destPtr = 0; /* * Add 1 to the Base64_DecodedLength(), since we base64 encoded the string * without the NUL terminator and need to add one. */ resultStrAllocatedLength = Base64_DecodedLength(base64String, destPtr - base64String); if (nullTerminateResult) { resultStrAllocatedLength += 1; } resultStr = Util_SafeMalloc(resultStrAllocatedLength); if (!Base64_Decode(base64String, resultStr, resultStrAllocatedLength, &resultStrLogicalLength) || (resultStrLogicalLength > resultStrAllocatedLength)) { free(resultStr); resultStr = NULL; goto abort; } if (nullTerminateResult) { ASSERT_NOT_IMPLEMENTED(resultStrLogicalLength < resultStrAllocatedLength); resultStr[resultStrLogicalLength] = 0; } if (NULL != bufferLength) { *bufferLength = resultStrLogicalLength; } abort: free(base64String); if (err == VIX_OK) { *result = resultStr; } return err; } // VixMsgDecodeBuffer /* *----------------------------------------------------------------------------- * * VixAsyncOp_ValidateCommandInfoTable -- * * Checks that the command info table is generally well-formed. * Makes sure that the table is big enough to contain all the * command op codes and that they are present in the right order. * * Results: * Bool * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool VixMsg_ValidateCommandInfoTable(void) { int i; /* * Check at compile time that there is as many entries in the * command info table as there are commands. We need the +1 since * VIX_COMMAND_UNKNOWN is in the table and its opcode is -1. * * If this has failed for you, you've probably added a new command to VIX * without adding it to the command info table above. */ ASSERT_ON_COMPILE(ARRAYSIZE(vixCommandInfoTable) == (VIX_COMMAND_LAST_NORMAL_COMMAND + 1)); /* * Iterated over all the elements in the command info table to make * sure that op code matches the index (they are shifted by one because * of VIX_COMMAND_UNKNOWN) and that every used entry has a non-NULL name. */ for (i = 0; i < ARRAYSIZE(vixCommandInfoTable); i++) { if (vixCommandInfoTable[i].used && ((vixCommandInfoTable[i].opCode != (i - 1)) || (NULL == vixCommandInfoTable[i].commandName))) { Warning("%s: Mismatch or NULL in command with op code %d at " "index %d.\n", __FUNCTION__, vixCommandInfoTable[i].opCode, i); return FALSE; } } return TRUE; } // VixMsg_ValidateCommandInfoTable /* *----------------------------------------------------------------------------- * * VixAsyncOp_GetDebugStrForOpCode -- * * Get a human readable string representing the given op code, or * "Unrecognized op" if the op code is invalid. * * Results: * const char * * * Side effects: * None * *----------------------------------------------------------------------------- */ const char * VixAsyncOp_GetDebugStrForOpCode(int opCode) // IN { const char *opName = "Unrecognized op"; const VixCommandInfo *commandInfo; commandInfo = VixGetCommandInfoForOpCode(opCode); if (NULL != commandInfo) { opName = commandInfo->commandName; ASSERT(NULL != opName); } return opName; } // VixAsyncOp_GetDebugStrForOpCode /* *----------------------------------------------------------------------------- * * VixMsg_GetCommandSecurityCategory -- * * Get the security category asociated with the given op code. * * Results: * VixCommandSecurityCategory: the security category for the op code, * or VIX_COMMAND_CATEGORY_UNKNOWN is the op code is invalid. * * Side effects: * None * *----------------------------------------------------------------------------- */ VixCommandSecurityCategory VixMsg_GetCommandSecurityCategory(int opCode) // IN { VixCommandSecurityCategory category = VIX_COMMAND_CATEGORY_UNKNOWN; const VixCommandInfo *commandInfo; commandInfo = VixGetCommandInfoForOpCode(opCode); if (NULL != commandInfo) { category = commandInfo->category; } return category; } // VixMsg_GetCommandSecurityCategory /* *----------------------------------------------------------------------------- * * VixGetCommandInfoForOpCode -- * * Looks up the information for an opcode from the global op code table. * * Results: * A const pointer to the command info struct for the opCode, or NULL * if the op code is invalid. * * Side effects: * None * *----------------------------------------------------------------------------- */ static const VixCommandInfo * VixGetCommandInfoForOpCode(int opCode) // IN { const VixCommandInfo *commandInfo = NULL; if ((opCode >= VIX_COMMAND_UNKNOWN) && (opCode < VIX_COMMAND_LAST_NORMAL_COMMAND)) { /* Add 1 to the op code, since VIX_COMMAND_UNKNOWN is -1 */ if (vixCommandInfoTable[opCode + 1].used) { commandInfo = &vixCommandInfoTable[opCode + 1]; } } return commandInfo; } // VixGetCommandInfoForOpCode /* *----------------------------------------------------------------------------- * * VixMsg_AllocGenericRequestMsg -- * * Allocate and initialize a generic request message. * * Assumes the caller holds the lock to 'propertyList'. * * Results: * Returns VixError. * Upon retrun, *request will contain either the message with the * headers properly initialized or NULL. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError VixMsg_AllocGenericRequestMsg(int opCode, // IN uint64 cookie, // IN int credentialType, // IN const char *userNamePassword, // IN int options, // IN VixPropertyListImpl *propertyList, // IN VixCommandGenericRequest **request) // OUT { VixError err; VixCommandGenericRequest *requestLocal = NULL; size_t msgHeaderAndBodyLength; char *serializedBufferBody = NULL; size_t serializedBufferLength = 0; if (NULL == request) { ASSERT(0); err = VIX_E_FAIL; goto abort; } *request = NULL; if (NULL != propertyList) { err = VixPropertyList_Serialize(propertyList, FALSE, &serializedBufferLength, &serializedBufferBody); if (VIX_OK != err) { goto abort; } } msgHeaderAndBodyLength = sizeof(*requestLocal) + serializedBufferLength; requestLocal = (VixCommandGenericRequest *) VixMsg_AllocRequestMsg(msgHeaderAndBodyLength, opCode, cookie, credentialType, userNamePassword); if (NULL == requestLocal) { err = VIX_E_FAIL; goto abort; } requestLocal->options = options; requestLocal->propertyListSize = serializedBufferLength; if (NULL != serializedBufferBody) { char *dst = (char *)request + sizeof(*request); memcpy(dst, serializedBufferBody, serializedBufferLength); } *request = requestLocal; err = VIX_OK; abort: free(serializedBufferBody); return err; } // VixMsg_AllocGenericRequestMsg /* *----------------------------------------------------------------------------- * * VixMsg_ParseGenericRequestMsg -- * * Extract the options and property list from the request * message, while validating message. * * Results: * VixError * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError VixMsg_ParseGenericRequestMsg(const VixCommandGenericRequest *request, // IN int *options, // OUT VixPropertyListImpl *propertyList) // OUT { VixError err; uint64 headerAndBodyLength; if ((NULL == request) || (NULL == options) || (NULL == propertyList)) { ASSERT(0); err = VIX_E_FAIL; goto abort; } *options = 0; VixPropertyList_Initialize(propertyList); /* * In most cases we will have already called VixMsg_ValidateResponseMsg() * on this request before, but call it here so that this function will * always be sufficient to validate the request. */ err = VixMsg_ValidateRequestMsg(request, request->header.commonHeader.totalMessageLength); if (VIX_OK != err) { goto abort; } if (request->header.commonHeader.totalMessageLength < sizeof *request) { err = VIX_E_INVALID_MESSAGE_BODY; goto abort; } headerAndBodyLength = (uint64) request->header.commonHeader.headerLength + request->header.commonHeader.bodyLength; if (headerAndBodyLength < ((uint64) sizeof *request + request->propertyListSize)) { err = VIX_E_INVALID_MESSAGE_BODY; goto abort; } if (request->propertyListSize > 0) { const char *serializedBuffer = (const char *) request + sizeof(*request); err = VixPropertyList_Deserialize(propertyList, serializedBuffer, request->propertyListSize, VIX_PROPERTY_LIST_BAD_ENCODING_ERROR); if (VIX_OK != err) { goto abort; } } *options = request->options; err = VIX_OK; abort: return err; } // VixMsg_ParseGenericRequestMsg /* *----------------------------------------------------------------------------- * * VixMsg_ParseSimpleResponseWithString -- * * Takes a response packet that consists of a VixCommandResponseHeader * followed by a string containing the response data, validates * the packet, and then passes out a pointer to that string. * * Results: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixMsg_ParseSimpleResponseWithString(const VixCommandResponseHeader *response, // IN const char **result) // OUT { VixError err; VMAutomationMsgParser parser; err = VMAutomationMsgParserInitResponse(&parser, response, sizeof *response); if (VIX_OK != err) { goto abort; } err = VMAutomationMsgParserGetOptionalString(&parser, response->commonHeader.bodyLength, result); abort: return err; } /* *----------------------------------------------------------------------------- * * VixMsg_MallocClientData -- * * Allocates the memory needed to copy from a client-provided buffer. * * Results: * Pointer to allocated memory * * Side effects: * None. * *----------------------------------------------------------------------------- */ void * VixMsg_MallocClientData(size_t size) // IN { return malloc(size); } // VixMsg_MallocClientData /* *----------------------------------------------------------------------------- * * VixMsg_ReallocClientData -- * * Reallocates the memory needed to copy from a client-provided buffer. * * Results: * Pointer to allocated memory * * Side effects: * Frees memory pointed to by ptr. * *----------------------------------------------------------------------------- */ void * VixMsg_ReallocClientData(void *ptr, // IN size_t size) // IN { return realloc(ptr, size); } // VixMsg_ReallocClientData /* *----------------------------------------------------------------------------- * * VixMsg_StrdupClientData -- * * Allocates memory and copies client-provided string. * * Results: * Pointer to allocated string * * Side effects: * None. * *----------------------------------------------------------------------------- */ char * VixMsg_StrdupClientData(const char *s, // IN Bool *allocateFailed) // OUT { char* newString = NULL; ASSERT(allocateFailed); if (NULL == allocateFailed) { goto abort; } *allocateFailed = FALSE; if (NULL != s) { #if defined(_WIN32) newString = _strdup(s); #else newString = strdup(s); #endif if (NULL == newString) { *allocateFailed = TRUE; } } abort: return newString; } // VixMsg_StrdupClientData /* *----------------------------------------------------------------------------- * * __VMAutomationValidateString -- * * Verifies that string at specified address is NUL terminated within * specified number of bytes, and is valid UTF-8. * * Results: * VixError. VIX_OK on success. Some other VIX_* code if message is malformed. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static VixError __VMAutomationValidateString(const char *caller, // IN unsigned int line, // IN const char *buffer, // IN size_t available) // IN { size_t stringLength; /* * NUL terminated string needs at least one byte - NUL one. */ if (available < 1) { Log("%s(%u): Message body too short to contain string.\n", caller, line); return VIX_E_INVALID_MESSAGE_BODY; } /* * Reject message if there is no NUL before request end. There must * be one... */ stringLength = Str_Strlen(buffer, available); if (stringLength >= available) { Log("%s(%u): Variable string is not NUL terminated " "before message end.\n", caller, line); return VIX_E_INVALID_MESSAGE_BODY; } /* * If string is shorter than expected, complain. Maybe it is too strict, * but clients seems to not send malformed messages, so keep doing this. */ if (stringLength + 1 != available) { Log("%s(%u): Retrieved fixed string \"%s\" with " "trailing garbage.\n", caller, line, buffer); return VIX_E_INVALID_MESSAGE_BODY; } /* * If string is not UTF-8, reject it. We do not want to pass non-UTF-8 * strings through vmx bowels - they could hit some ASSERT somewhere... */ if (!Unicode_IsBufferValid(buffer, stringLength, STRING_ENCODING_UTF8)) { Log("%s(%u): Variable string is not an UTF8 string.\n", caller, line); return VIX_E_INVALID_UTF8_STRING; } return VIX_OK; } /* *----------------------------------------------------------------------------- * * __VMAutomationValidateStringInBuffer -- * * Verifies that string at specified address is NUL terminated within * specified number of bytes, and is valid UTF-8. * String does not have to occupy the entire buffer. * * Results: * VixError. VIX_OK on success. * Some other VIX_* code if message is malformed. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static VixError __VMAutomationValidateStringInBuffer(const char *caller, // IN unsigned int line, // IN const char *buffer, // IN size_t available, // IN size_t *strLen) // IN { size_t stringLength; /* * NUL terminated string needs at least one byte - NUL one. */ if (available < 1) { Log("%s(%u): Message body too short to contain string.\n", caller, line); return VIX_E_INVALID_MESSAGE_BODY; } /* * Reject message if there is no NUL before request end. There must * be one... */ stringLength = Str_Strlen(buffer, available); *strLen = stringLength; if (stringLength >= available) { Log("%s(%u): Variable string is not NUL terminated " "before message end.\n", caller, line); return VIX_E_INVALID_MESSAGE_BODY; } /* * If string is not UTF-8, reject it. We do not want to pass non-UTF-8 * strings through vmx bowels - they could hit some ASSERT somewhere... */ if (!Unicode_IsBufferValid(buffer, stringLength, STRING_ENCODING_UTF8)) { Log("%s(%u): Variable string is not an UTF8 string.\n", caller, line); return VIX_E_INVALID_UTF8_STRING; } return VIX_OK; } /* *----------------------------------------------------------------------------- * * __VMAutomationMsgParserInitRequest -- * VMAutomationMsgParserInitRequest -- * * Initializes request parser, and performs basic message validation * not performed elsewhere. * * Results: * VixError. VIX_OK on success. Some other VIX_* code if message is malformed. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError __VMAutomationMsgParserInitRequest(const char *caller, // IN unsigned int line, // IN VMAutomationMsgParser *state, // OUT (opt) const VixCommandRequestHeader *msg, // IN size_t fixedLength) // IN { size_t miscDataLength = 0; /* * If the VM is encrypted, there is additional data factored into * the total message size that needs to be accounted for. */ if (VIX_REQUESTMSG_INCLUDES_AUTH_DATA_V1 & msg->requestFlags) { miscDataLength = sizeof(VixMsgAuthDataV1); } else { miscDataLength = 0; } return VMAutomationMsgParserInit(caller, line, state, &msg->commonHeader, sizeof *msg, fixedLength, miscDataLength, "request"); } /* *----------------------------------------------------------------------------- * * __VMAutomationMsgParserInitResponse -- * VMAutomationMsgParserInitResponse -- * * Initializes response parser, and performs basic message validation * not performed elsewhere. * * Results: * VixError. VIX_OK on success. Some other VIX_* code if message is malformed. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError __VMAutomationMsgParserInitResponse(const char *caller, // IN unsigned int line, // IN VMAutomationMsgParser *state, // OUT (opt) const VixCommandResponseHeader *msg, // IN size_t fixedLength) // IN { return VMAutomationMsgParserInit(caller, line, state, &msg->commonHeader, sizeof *msg, fixedLength, 0, "response"); } /* *----------------------------------------------------------------------------- * * VMAutomationMsgParserInit -- * * Initializes message parser, and performs basic message validation * not performed elsewhere. * * Results: * VixError. VIX_OK on success. Some other VIX_* code if message is malformed. * * Side effects: * None * *----------------------------------------------------------------------------- */ static VixError VMAutomationMsgParserInit(const char *caller, // IN unsigned int line, // IN VMAutomationMsgParser *state, // OUT (opt) const VixMsgHeader *msg, // IN size_t headerLength, // IN size_t fixedLength, // IN size_t miscDataLength, // IN const char *packetType) // IN { uint32 headerAndBodyLength; // use int64 to prevent overflow int64 computedTotalLength = (int64)msg->headerLength + (int64)msg->bodyLength + (int64)msg->credentialLength + (int64)miscDataLength; int64 extBodySize = (int64)msg->headerLength + (int64)msg->bodyLength - (int64)fixedLength; if (computedTotalLength != (int64)msg->totalMessageLength) { Log("%s:%d, header information mismatch.\n", __FILE__, __LINE__); return VIX_E_INVALID_MESSAGE_HEADER; } if (extBodySize < 0) { Log("%s:%d, %s too short.\n", __FILE__, __LINE__, packetType); return VIX_E_INVALID_MESSAGE_HEADER; } /* * Protocol allows for headerLength expansion, but predefined structures * do not anticipate that even a bit. So give up if header length is * incompatible with our structures. */ if (msg->headerLength != headerLength) { Log("%s(%u): %s header length %u is not supported " "(%"FMTSZ"u is required).\n", caller, line, packetType, msg->headerLength, headerLength); return VIX_E_INVALID_MESSAGE_HEADER; } /* * Message looks reasonable. Skip over fixed part. */ headerAndBodyLength = msg->headerLength + msg->bodyLength; if (state) { state->currentPtr = (const char *)msg + fixedLength; state->endPtr = (const char *)msg + headerAndBodyLength; } return VIX_OK; } /* *----------------------------------------------------------------------------- * * VMAutomation_VerifyRequestLength -- * * Ensures that request contains at least fixedLength bytes in * header and body. * * Results: * VixError. VIX_OK on success. Some other VIX_* code if message is malformed. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError VMAutomation_VerifyRequestLength(const VixCommandRequestHeader *request, // IN size_t fixedLength) // IN { return VMAutomationMsgParserInitRequest(NULL, request, fixedLength); } /* *----------------------------------------------------------------------------- * * VMAutomationMsgParserGetRemainingData -- * * Fetches all data remaining in the request. * * Results: * Pointer to the data. * * Side effects: * None. * *----------------------------------------------------------------------------- */ const void * VMAutomationMsgParserGetRemainingData(VMAutomationMsgParser *state, // IN/OUT size_t *length) // OUT { const void *data; *length = state->endPtr - state->currentPtr; data = state->currentPtr; state->currentPtr = state->endPtr; return data; } /* *----------------------------------------------------------------------------- * * VMAutomationMsgParserGetData -- * __VMAutomationMsgParserGetData -- * * Fetches specified number of bytes. * * Results: * VixError. VIX_OK on success. Some other VIX_* code if message is malformed. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError __VMAutomationMsgParserGetData(const char *caller, // IN unsigned int line, // IN VMAutomationMsgParser *state, // IN/OUT size_t length, // IN const char **result) // OUT (opt) { size_t available; available = state->endPtr - state->currentPtr; /* If message is too short, return an error. */ if (available < length) { Log("%s(%u): Message has only %"FMTSZ"u bytes available when " "looking for %"FMTSZ"u bytes od data.\n", caller, line, available, length); return VIX_E_INVALID_MESSAGE_BODY; } if (result) { *result = state->currentPtr; } state->currentPtr += length; return VIX_OK; } /* *----------------------------------------------------------------------------- * * VMAutomationMsgParserGetOptionalString -- * __VMAutomationMsgParserGetOptionalString -- * * Fetches string of specified length from the request. Length includes * terminating NUL byte, which must be present. Length of zero results * in NULL being returned. * * Results: * VixError. VIX_OK on success. Some other VIX_* code if message is malformed. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError __VMAutomationMsgParserGetOptionalString(const char *caller, // IN unsigned int line, // IN VMAutomationMsgParser *state, // IN/OUT size_t length, // IN const char **result) // OUT { if (length) { VixError err; const char *string; err = __VMAutomationMsgParserGetData(caller, line, state, length, &string); if (VIX_OK != err) { return err; } err = __VMAutomationValidateString(caller, line, string, length); if (VIX_OK != err) { return err; } *result = string; } else { *result = NULL; } return VIX_OK; } /* *----------------------------------------------------------------------------- * * VMAutomationMsgParserGetOptionalStrings -- * __VMAutomationMsgParserGetOptionalStrings -- * * Fetches an array of strings from the request. Length includes the * terminating NUL byte of each string. * * Results: * VixError. VIX_OK on success. * Some other VIX_* code if message is malformed. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError __VMAutomationMsgParserGetOptionalStrings(const char *caller, // IN unsigned int line, // IN VMAutomationMsgParser *state, // IN/OUT uint32 count, // IN size_t length, // IN const char **result) // OUT { VixError err = VIX_OK; const char *buffer; const char *theResult; int i; size_t strLen; if (0 == count) { *result = NULL; goto abort; } err = __VMAutomationMsgParserGetData(caller, line, state, length, &buffer); if (VIX_OK != err) { return err; } theResult = buffer; for (i = 0; i < count; ++i) { err = __VMAutomationValidateStringInBuffer(caller, line, buffer, length, &strLen); if (VIX_OK != err) { return err; } ASSERT(strLen < length); buffer += (strLen + 1); length -= (strLen + 1); } /* * If string is shorter than expected, complain. Maybe it is too strict, * but clients seems to not send malformed messages, so keep doing this. */ if (length != 0) { Log("%s(%u): Retrieved an array of string with trailing garbage.\n", caller, line); return VIX_E_INVALID_MESSAGE_BODY; } *result = theResult; abort: return err; } /* *----------------------------------------------------------------------------- * * VMAutomationMsgParserGetString -- * __VMAutomationMsgParserGetString -- * * Fetches string of specified length from the request. Length of * string is specified in number of usable characters: function consumes * length + 1 bytes from request, and first length bytes must be non-NUL, * while length+1st byte must be NUL. * * Results: * VixError. VIX_OK on success. Some other VIX_* code if message is malformed. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError __VMAutomationMsgParserGetString(const char *caller, // IN unsigned int line, // IN VMAutomationMsgParser *state, // IN/OUT size_t length, // IN const char **result) // OUT { VixError err; const char *string; length++; if (!length) { Log("%s(%u): String is too long.\n", caller, line); return VIX_E_INVALID_ARG; } err = __VMAutomationMsgParserGetData(caller, line, state, length, &string); if (VIX_OK != err) { return err; } err = __VMAutomationValidateString(caller, line, string, length); if (VIX_OK != err) { return err; } *result = string; return VIX_OK; } /* *----------------------------------------------------------------------------- * * VMAutomationMsgParserGetPropertyList -- * __VMAutomationMsgParserGetPropertyList -- * * Fetches specified number of bytes. * * Results: * VixError. VIX_OK on success. Some other VIX_* code if message is malformed. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError __VMAutomationMsgParserGetPropertyList(const char *caller, // IN unsigned int line, // IN VMAutomationMsgParser *state, // IN/OUT size_t length, // IN VixPropertyListImpl *propList) // IN/OUT { VixError err; err = VIX_OK; if (length) { const char *data; err = __VMAutomationMsgParserGetData(caller, line, state, length, &data); if (VIX_OK == err) { err = VixPropertyList_Deserialize(propList, data, length, VIX_PROPERTY_LIST_BAD_ENCODING_ERROR); } } return err; } open-vm-tools-9.4.0-1280544/lib/foundryMsg/foundryPropertyListCommon.c0000644765153500003110000014064512220061556023760 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * foundryPropertyListCommon.c -- * * Some utility functions for manipulating property lists. Property * lists are now used in both the client and the VMX. The VMX uses them * as part of the socket protocol with the client. As a result, these * functions have been factored out into the stand-alone message library * so it can be used by the VMX tree without also linking in the * entire foundry client-side library. */ #include "vmware.h" #include "vm_version.h" #include "util.h" #include "str.h" #include "unicode.h" #include "vixCommands.h" #include "vixOpenSource.h" /* * The length of the 'size' field is 4 bytes -- avoid the confusion * of size_t on 32 vs 64 bit platforms. */ #define PROPERTY_LENGTH_SIZE 4 /* * Lets not trust sizeof() */ #define PROPERTY_SIZE_INT32 4 #define PROPERTY_SIZE_INT64 8 #define PROPERTY_SIZE_BOOL 1 // The size may be different on different machines. // To be safe, we always use 8 bytes. #define PROPERTY_SIZE_POINTER 8 static VixError VixPropertyListDeserializeImpl(VixPropertyListImpl *propList, const char *buffer, size_t bufferSize, Bool clobber, VixPropertyListBadEncodingAction action); /* *----------------------------------------------------------------------------- * * VixPropertyList_Initialize -- * * Initialize a list to be empty. This is an internal function * that is used both when we allocate a property list that wil be passed * to the client as a handle, and when we allocate an internal property * list that was not allocated as a handle. * * Results: * None. * * Side effects: * *----------------------------------------------------------------------------- */ void VixPropertyList_Initialize(VixPropertyListImpl *propList) // IN { ASSERT(propList); propList->properties = NULL; } // VixPropertyList_Initialize /* *----------------------------------------------------------------------------- * * VixPropertyList_RemoveAllWithoutHandles -- * * Delete all properties in a list. This is an internal procedure * that takes a VixPropertyListImpl as a parameter. * * Results: * None * * Side effects: * The property list is empty. * *----------------------------------------------------------------------------- */ void VixPropertyList_RemoveAllWithoutHandles(VixPropertyListImpl *propList) // IN { VixPropertyValue *property; if (NULL == propList) { return; } while (NULL != propList->properties) { property = propList->properties; propList->properties = property->next; if (VIX_PROPERTYTYPE_STRING == property->type) { if (property->isSensitive) { Util_ZeroString(property->value.strValue); } free(property->value.strValue); } else if (VIX_PROPERTYTYPE_BLOB == property->type) { if (property->isSensitive) { Util_Zero(property->value.blobValue.blobContents, property->value.blobValue.blobSize); } free(property->value.blobValue.blobContents); } free(property); } } // VixPropertyList_RemoveAllWithoutHandles /* *----------------------------------------------------------------------------- * * VixPropertyList_Serialize -- * * Serialize a property list to a buffer. The buffer is allocated by * this routine to be of the required size and should be freed by caller. * * This function should be modified to deal with the case of * properties of type VIX_PROPERTYTYPE_HANDLE. * * * Results: * VixError. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError VixPropertyList_Serialize(VixPropertyListImpl *propList, // IN Bool dirtyOnly, // IN size_t *resultSize, // OUT char **resultBuffer) // OUT { VixError err = VIX_OK; VixPropertyValue *property = NULL; char *serializeBuffer = NULL; int valueLength; size_t headerSize; size_t propertyIDSize; size_t propertyTypeSize; size_t propertyValueLengthSize; size_t bufferSize = 0; size_t pos = 0; ASSERT_ON_COMPILE(PROPERTY_LENGTH_SIZE == sizeof valueLength); if ((NULL == propList) || (NULL == resultSize) || (NULL == resultBuffer)) { err = VIX_E_INVALID_ARG; goto abort; } propertyIDSize = sizeof(property->propertyID); propertyTypeSize = sizeof(property->type); propertyValueLengthSize = PROPERTY_LENGTH_SIZE; headerSize = propertyIDSize + propertyTypeSize + propertyValueLengthSize; /* * Walk the property list to determine size of the needed buffer */ property = propList->properties; while (NULL != property) { /* * If only the dirty properties need to be serialized * then skip the unchanged ones. */ if (dirtyOnly && (!property->isDirty)) { property = property->next; continue; } bufferSize += headerSize; switch (property->type) { //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_INTEGER: bufferSize += PROPERTY_SIZE_INT32; break; //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_STRING: if (property->value.strValue) { valueLength = strlen(property->value.strValue) + 1; /* * The deserialization code rejects all non-UTF-8 strings. * There should not be any non-UTF-8 strings passing * through our code since we should have either converted * non-UTF-8 strings from system APIs to UTF-8, or validated * that any client-provided strings were UTF-8. But this * if we've missed something, this should hopefully catch the * offending code close to the act. */ if (!Unicode_IsBufferValid(property->value.strValue, valueLength, STRING_ENCODING_UTF8)) { Log("%s: attempted to send a non-UTF-8 string for " "property %d.\n", __FUNCTION__, property->propertyID); ASSERT(0); err = VIX_E_INVALID_UTF8_STRING; } bufferSize += valueLength; } else { err = VIX_E_INVALID_ARG; goto abort; } break; //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_BOOL: bufferSize += PROPERTY_SIZE_BOOL; break; //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_INT64: bufferSize += PROPERTY_SIZE_INT64; break; //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_BLOB: bufferSize += property->value.blobValue.blobSize; break; //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_POINTER: /* * We should not serialize any pointer. * Catch such programming errors. */ err = VIX_E_INVALID_ARG; Log("%s:%d, pointer properties cannot be serialized.\n", __FUNCTION__, __LINE__); goto abort; //////////////////////////////////////////////////////// default: err = VIX_E_UNRECOGNIZED_PROPERTY; goto abort; } property = property->next; } *resultBuffer = (char*) VixMsg_MallocClientData(bufferSize); if (NULL == *resultBuffer) { err = VIX_E_OUT_OF_MEMORY; goto abort; } serializeBuffer = *resultBuffer; pos = 0; property = propList->properties; /* * Write out the properties to the buffer in the following format: * PropertyID | PropertyType | DataLength | Data */ while (NULL != property) { /* * If only the dirty properties need to be serialized * then skip the unchanged ones. */ if (dirtyOnly && (!property->isDirty)) { property = property->next; continue; } memcpy(&(serializeBuffer[pos]), &(property->propertyID), propertyIDSize); pos += propertyIDSize; memcpy(&(serializeBuffer[pos]), &(property->type), propertyTypeSize); pos += propertyTypeSize; switch (property->type) { //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_INTEGER: valueLength = PROPERTY_SIZE_INT32; memcpy(&(serializeBuffer[pos]), &valueLength, propertyValueLengthSize); pos += propertyValueLengthSize; memcpy(&(serializeBuffer[pos]), &(property->value.intValue), valueLength); break; //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_STRING: valueLength = (int) strlen(property->value.strValue) + 1; memcpy(&(serializeBuffer[pos]), &valueLength, propertyValueLengthSize); pos += propertyValueLengthSize; Str_Strcpy(&(serializeBuffer[pos]), property->value.strValue, valueLength); break; //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_BOOL: valueLength = PROPERTY_SIZE_BOOL; memcpy(&(serializeBuffer[pos]), &valueLength, propertyValueLengthSize); pos += propertyValueLengthSize; memcpy(&(serializeBuffer[pos]), &(property->value.boolValue), valueLength); break; //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_INT64: valueLength = PROPERTY_SIZE_INT64; memcpy(&(serializeBuffer[pos]), &valueLength, propertyValueLengthSize); pos += propertyValueLengthSize; memcpy(&(serializeBuffer[pos]), &(property->value.int64Value), valueLength); break; //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_BLOB: if (property->value.blobValue.blobContents) { valueLength = property->value.blobValue.blobSize; memcpy(&(serializeBuffer[pos]), &valueLength, propertyValueLengthSize); pos += propertyValueLengthSize; memcpy(&(serializeBuffer[pos]), property->value.blobValue.blobContents, valueLength); } else { err = VIX_E_INVALID_ARG; goto abort; } break; //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_POINTER: NOT_IMPLEMENTED(); //////////////////////////////////////////////////////// default: err = VIX_E_UNRECOGNIZED_PROPERTY; goto abort; } pos += valueLength; property = property->next; } ASSERT(pos == bufferSize); *resultSize = bufferSize; abort: if (VIX_OK != err) { free(serializeBuffer); if (NULL != resultBuffer) { *resultBuffer = NULL; } if (NULL != resultSize) { *resultSize = 0; } } return err; } // FoundryPropertList_Serialize /* *----------------------------------------------------------------------------- * * VixPropertyList_Deserialize -- * * Deserialize a property list from a buffer. Repeated properties * are clobbered. * * Results: * VixError. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError VixPropertyList_Deserialize(VixPropertyListImpl *propList, // IN const char *buffer, // IN size_t bufferSize, // IN VixPropertyListBadEncodingAction action) // IN { return VixPropertyListDeserializeImpl(propList, buffer, bufferSize, TRUE, // clobber action); } // VixPropertyList_Deserialize /* *----------------------------------------------------------------------------- * * VixPropertyList_DeserializeNoClobber -- * * Deserialize a property list from a buffer. Repeated properties * are preserved. * * Results: * VixError. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError VixPropertyList_DeserializeNoClobber(VixPropertyListImpl *propList, // IN const char *buffer, // IN size_t bufferSize, // IN VixPropertyListBadEncodingAction action) // IN { return VixPropertyListDeserializeImpl(propList, buffer, bufferSize, FALSE, // clobber action); } // VixPropertyList_DeserializeNoClobber /* *----------------------------------------------------------------------------- * * VixPropertyListDeserializeImpl -- * * Deserialize a property list from a buffer. * * This function should be modified to deal with the case of * properties of type VIX_PROPERTYTYPE_HANDLE. * * Results: * VixError. * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError VixPropertyListDeserializeImpl(VixPropertyListImpl *propList, // IN const char *buffer, // IN size_t bufferSize, // IN Bool clobber, // IN VixPropertyListBadEncodingAction action) // IN { VixError err = VIX_OK; VixPropertyValue *property = NULL; size_t pos = 0; char *strPtr; int *intPtr; Bool *boolPtr; int64 *int64Ptr; unsigned char* blobPtr; int *propertyIDPtr; int *lengthPtr; size_t propertyIDSize; size_t propertyTypeSize; size_t propertyValueLengthSize; size_t headerSize; VixPropertyType *propertyTypePtr; Bool allocateFailed; Bool needToEscape; if ((NULL == propList) || (NULL == buffer)) { err = VIX_E_INVALID_ARG; goto abort; } propertyIDSize = sizeof(*propertyIDPtr); propertyTypeSize = sizeof(*propertyTypePtr); propertyValueLengthSize = PROPERTY_LENGTH_SIZE; headerSize = propertyIDSize + propertyTypeSize + propertyValueLengthSize; /* * Read properties from the buffer and add them to the property list. */ while ((pos+headerSize) < bufferSize) { propertyIDPtr = (int*) &(buffer[pos]); pos += propertyIDSize; propertyTypePtr = (VixPropertyType*) &(buffer[pos]); pos += propertyTypeSize; lengthPtr = (int*) &(buffer[pos]); pos += propertyValueLengthSize; /* * Do not allow lengths of 0 or fewer bytes. Those do not make sense, * unless you can pass a NULL blob, which Serialize() does not allow. * Also, make sure the value is contained within the bounds of the buffer. */ if ((*lengthPtr < 1) || ((*lengthPtr + pos) > bufferSize)) { err = VIX_E_INVALID_SERIALIZED_DATA; goto abort; } /* * Create the property if missing */ if (clobber) { err = VixPropertyList_FindProperty(propList, *propertyIDPtr, *propertyTypePtr, 0, // index TRUE, //createIfMissing &property); } else { err = VixPropertyListAppendProperty(propList, *propertyIDPtr, *propertyTypePtr, &property); } if (VIX_OK != err) { goto abort; } /* * Initialize the property to the received value */ switch (*propertyTypePtr) { //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_INTEGER: if (PROPERTY_SIZE_INT32 != *lengthPtr) { err = VIX_E_INVALID_SERIALIZED_DATA; goto abort; } intPtr = (int*) &(buffer[pos]); property->value.intValue = *intPtr; break; //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_STRING: strPtr = (char*) &(buffer[pos]); /* * The length that Serialize() generates includes the terminating * NUL character. */ if (strPtr[*lengthPtr - 1] != '\0') { err = VIX_E_INVALID_SERIALIZED_DATA; goto abort; } needToEscape = FALSE; /* * Make sure the string is valid UTF-8 before copying it. We * expect all strings stored in the process to be UTF-8. */ if (!Unicode_IsBufferValid(strPtr, *lengthPtr, STRING_ENCODING_UTF8)) { Log("%s: non-UTF-8 string received for property %d.\n", __FUNCTION__, *propertyIDPtr); switch (action) { case VIX_PROPERTY_LIST_BAD_ENCODING_ERROR: err = VIX_E_INVALID_UTF8_STRING; goto abort; case VIX_PROPERTY_LIST_BAD_ENCODING_ESCAPE: needToEscape = TRUE; } } free(property->value.strValue); if (needToEscape) { property->value.strValue = Unicode_EscapeBuffer(strPtr, *lengthPtr, STRING_ENCODING_UTF8); if (NULL == property->value.strValue) { err = VIX_E_OUT_OF_MEMORY; goto abort; } } else { property->value.strValue = VixMsg_StrdupClientData(strPtr, &allocateFailed); if (allocateFailed) { err = VIX_E_OUT_OF_MEMORY; goto abort; } } break; //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_BOOL: if (PROPERTY_SIZE_BOOL != *lengthPtr) { err = VIX_E_INVALID_SERIALIZED_DATA; goto abort; } boolPtr = (Bool*) &(buffer[pos]); property->value.boolValue = *boolPtr; break; //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_INT64: if (PROPERTY_SIZE_INT64 != *lengthPtr) { err = VIX_E_INVALID_SERIALIZED_DATA; goto abort; } int64Ptr = (int64*) &(buffer[pos]); property->value.int64Value = *int64Ptr; break; //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_BLOB: blobPtr = (unsigned char*) &(buffer[pos]); property->value.blobValue.blobSize = *lengthPtr; /* * Use regular malloc() when allocating amounts specified by another * process. Admittedly we've already bounds checked it, but this is * pretty easy to handle. */ free(property->value.blobValue.blobContents); property->value.blobValue.blobContents = VixMsg_MallocClientData(*lengthPtr); if (NULL == property->value.blobValue.blobContents) { err = VIX_E_OUT_OF_MEMORY; goto abort; } memcpy(property->value.blobValue.blobContents, blobPtr, *lengthPtr); break; //////////////////////////////////////////////////////// case VIX_PROPERTYTYPE_POINTER: /* * Deserialize an pointer property should not be allowed. * An evil peer could send us such data. */ err = VIX_E_INVALID_SERIALIZED_DATA; Log("%s:%d, pointer properties cannot be serialized.\n", __FUNCTION__, __LINE__); goto abort; //////////////////////////////////////////////////////// default: err = VIX_E_UNRECOGNIZED_PROPERTY; goto abort; } pos += *lengthPtr; } abort: if ((VIX_OK != err) && (NULL != propList)) { VixPropertyList_RemoveAllWithoutHandles(propList); } return err; } // VixPropertyList_Deserialize /* *----------------------------------------------------------------------------- * * VixPropertyList_FindProperty -- * * This is an internal routine that finds a property in the list. * * If the property is found, then this also checks that the property * has an expected type; if the types mismatch thenit returns an error. * * It optionally creates a property if it is missing. * * Results: * VixError * * Side effects: * *----------------------------------------------------------------------------- */ VixError VixPropertyList_FindProperty(VixPropertyListImpl *propList, // IN int propertyID, // IN VixPropertyType type, // IN int index, // IN Bool createIfMissing, // IN VixPropertyValue **resultEntry) // OUT { VixError err = VIX_OK; VixPropertyValue *property = NULL; if (NULL == resultEntry) { err = VIX_E_INVALID_ARG; goto abort; } *resultEntry = NULL; property = propList->properties; while (NULL != property) { if (propertyID == property->propertyID) { if (index > 0) { index--; } else { if ((VIX_PROPERTYTYPE_ANY != type) && (type != property->type)) { err = VIX_E_TYPE_MISMATCH; } *resultEntry = property; goto abort; } } // (propertyID == property->propertyID) property = property->next; } // while (NULL != property) /* * If we get to here, then the property doesn't exist. * Either create it or return an error. */ if (!createIfMissing) { err = VIX_E_UNRECOGNIZED_PROPERTY; goto abort; } err = VixPropertyListAppendProperty(propList, propertyID, type, resultEntry); abort: return err; } /* *----------------------------------------------------------------------------- * * VixPropertyListAppendProperty -- * * This is an internal routine that creates a property for the * append routines. * * Results: * VixError * * Side effects: * *----------------------------------------------------------------------------- */ VixError VixPropertyListAppendProperty(VixPropertyListImpl *propList, // IN int propertyID, // IN VixPropertyType type, // IN VixPropertyValue **resultEntry) // OUT { VixError err = VIX_OK; VixPropertyValue *lastProperty; VixPropertyValue *property = NULL; if (NULL == resultEntry) { err = VIX_E_INVALID_ARG; goto abort; } *resultEntry = NULL; property = (VixPropertyValue *) Util_SafeCalloc(1, sizeof(VixPropertyValue)); property->type = type; property->propertyID = propertyID; property->isDirty = TRUE; property->isSensitive = FALSE; /* * We only have to initialize the values that we release, so * we don't try to release an invalid reference. */ if (VIX_PROPERTYTYPE_STRING == property->type) { property->value.strValue = NULL; } else if (VIX_PROPERTYTYPE_BLOB == property->type) { property->value.blobValue.blobContents = NULL; } else if (VIX_PROPERTYTYPE_HANDLE == property->type) { property->value.handleValue = VIX_INVALID_HANDLE; } /* * Put the new property on the end of the list. Some property lists, * like a list of VMs or snapshots, assume the order is meaningful and * so it should be preserved. */ lastProperty = propList->properties; while ((NULL != lastProperty) && (NULL != lastProperty->next)) { lastProperty = lastProperty->next; } if (NULL == lastProperty) { propList->properties = property; } else { lastProperty->next = property; } property->next = NULL; *resultEntry = property; abort: return err; } // VixPropertyListAppendProperty /* *----------------------------------------------------------------------------- * * VixPropertyList_GetString -- * * Return a copy of a string property value. The value is identified * by the integer property ID. * * This fails if the value is not present, or if it is a different * type, or if the caller did not pass a valid out parameter to * receive the value. * * Results: * VixError. VIX_OK if the property was found. * VIX_E_UNRECOGNIZED_PROPERTY if the property was not found. * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixPropertyList_GetString(VixPropertyListImpl *propList, // IN int propertyID, // IN int index, // IN char **resultValue) // OUT { VixError err = VIX_OK; VixPropertyValue *property = NULL; if ((NULL == propList) || (NULL == resultValue)) { err = VIX_E_INVALID_ARG; goto abort; } *resultValue = NULL; err = VixPropertyList_FindProperty(propList, propertyID, VIX_PROPERTYTYPE_STRING, index, FALSE, &property); if (VIX_OK != err) { goto abort; } if (NULL != property->value.strValue) { *resultValue = Util_SafeStrdup(property->value.strValue); } abort: return err; } // VixPropertyList_GetString /* *----------------------------------------------------------------------------- * * VixPropertyList_SetString -- * * Saves a copy of a string property value. The value is identified * by the integer property ID. * * Value names are unique within a single proeprty list. * If a previous value with the same propertyID value already * existed in this property list, then it is replaced with the new * value. Otherwise, a new value is added. * * This fails if the value is present but has a different type. * * Results: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixPropertyList_SetString(VixPropertyListImpl *propList, // IN int propertyID, // IN const char *value) // IN { VixError err = VIX_OK; VixPropertyValue *property = NULL; if (NULL == propList) { err = VIX_E_INVALID_ARG; goto abort; } /* * Find or create an entry for this property. */ err = VixPropertyList_FindProperty(propList, propertyID, VIX_PROPERTYTYPE_STRING, 0, TRUE, &property); if (VIX_OK != err) { goto abort; } if (NULL != property->value.strValue) { free(property->value.strValue); property->value.strValue = NULL; } if (NULL != value) { property->value.strValue = Util_SafeStrdup(value); } property->isDirty = TRUE; abort: return(err); } // VixPropertyList_SetString /* *----------------------------------------------------------------------------- * * VixPropertyList_GetInteger -- * * Return a copy of a integer property value. The value is identified * by the integer property ID. * * This fails if the value is not present, or if it is a different * type, or if the caller did not pass a valid out parameter to * receive the value. * * Results: * VixError. VIX_OK if the property was found. * VIX_E_UNRECOGNIZED_PROPERTY if the property was not found. * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixPropertyList_GetInteger(VixPropertyListImpl *propList, // IN int propertyID, // IN int index, // IN int *resultValue) // OUT { VixError err = VIX_OK; VixPropertyValue *property = NULL; if ((NULL == resultValue) || (NULL == propList)) { err = VIX_E_INVALID_ARG; goto abort; } err = VixPropertyList_FindProperty(propList, propertyID, VIX_PROPERTYTYPE_INTEGER, index, FALSE, &property); if (VIX_OK != err) { goto abort; } *resultValue = property->value.intValue; abort: return err; } // VixPropertyList_GetInteger /* *----------------------------------------------------------------------------- * * VixPropertyList_SetInteger -- * * Saves a copy of a integer property value. The value is identified * by the integer property ID. * * Value names are unique within a single proeprty list. * If a previous value with the same propertyID value already * existed in this property list, then it is replaced with the new * value. Otherwise, a new value is added. * * This fails if the value is present but has a different type. * * Results: * VixError. * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixPropertyList_SetInteger(VixPropertyListImpl *propList, // IN int propertyID, // IN int value) // IN { VixError err = VIX_OK; VixPropertyValue *property = NULL; if (NULL == propList) { err = VIX_E_INVALID_ARG; goto abort; } /* * Find or create an entry for this property. */ err = VixPropertyList_FindProperty(propList, propertyID, VIX_PROPERTYTYPE_INTEGER, 0, TRUE, &property); if (VIX_OK != err) { goto abort; } property->value.intValue = value; property->isDirty = TRUE; abort: return(err); } // VixPropertyList_SetInteger /* *----------------------------------------------------------------------------- * * VixPropertyList_GetBool -- * * Return a copy of a boolean property value. The value is identified * by the integer property ID. * * This fails if the value is not present, or if it is a different * type, or if the caller did not pass a valid out parameter to * receive the value. * * Results: * VixError. VIX_OK if the property was found. * VIX_E_UNRECOGNIZED_PROPERTY if the property was not found. * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixPropertyList_GetBool(VixPropertyListImpl *propList, // IN int propertyID, // IN int index, // IN Bool *resultValue) // OUT { VixError err = VIX_OK; VixPropertyValue *property = NULL; if ((NULL == resultValue) || (NULL == propList)) { err = VIX_E_INVALID_ARG; goto abort; } err = VixPropertyList_FindProperty(propList, propertyID, VIX_PROPERTYTYPE_BOOL, index, FALSE, &property); if (VIX_OK != err) { goto abort; } if (NULL == property) { goto abort; } *resultValue = property->value.boolValue; abort: return err; } // VixPropertyList_GetBool /* *----------------------------------------------------------------------------- * * VixPropertyList_SetBool -- * * Saves a copy of a Bool property value. The value is identified * by the integer property ID. * * Value names are unique within a single proeprty list. * If a previous value with the same propertyID value already * existed in this property list, then it is replaced with the new * value. Otherwise, a new value is added. * * This fails if the value is present but has a different type. * * Results: * VixError. * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixPropertyList_SetBool(VixPropertyListImpl *propList, // IN int propertyID, // IN Bool value) // IN { VixError err = VIX_OK; VixPropertyValue *property = NULL; if (NULL == propList) { err = VIX_E_INVALID_ARG; goto abort; } /* * Find or create an entry for this property. */ err = VixPropertyList_FindProperty(propList, propertyID, VIX_PROPERTYTYPE_BOOL, 0, TRUE, &property); if (VIX_OK != err) { goto abort; } property->value.boolValue = value; property->isDirty = TRUE; abort: return(err); } /* *----------------------------------------------------------------------------- * * VixPropertyList_GetInt64 -- * * Return a copy of a Int64 property value. The value is identified * by the integer property ID. * * This fails if the value is not present, or if it is a different * type, or if the caller did not pass a valid out parameter to * receive the value. * * Results: * VixError. VIX_OK if the property was found. * VIX_E_UNRECOGNIZED_PROPERTY if the property was not found. * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixPropertyList_GetInt64(VixPropertyListImpl *propList, // IN int propertyID, // IN int index, // IN int64 *resultValue) // OUT { VixError err = VIX_OK; VixPropertyValue *property = NULL; if ((NULL == resultValue) || (NULL == propList)) { err = VIX_E_INVALID_ARG; goto abort; } err = VixPropertyList_FindProperty(propList, propertyID, VIX_PROPERTYTYPE_INT64, index, FALSE, &property); if (VIX_OK != err) { goto abort; } *resultValue = property->value.int64Value; abort: return err; } // VixPropertyList_GetInt64 /* *----------------------------------------------------------------------------- * * VixPropertyList_SetInt64 -- * * Saves a copy of a int64 property value. The value is identified * by the integer property ID. * * Value names are unique within a single proeprty list. * If a previous value with the same propertyID value already * existed in this property list, then it is replaced with the new * value. Otherwise, a new value is added. * * This fails if the value is present but has a different type. * * Results: * VixError. * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixPropertyList_SetInt64(VixPropertyListImpl *propList, // IN int propertyID, // IN int64 value) // IN { VixError err = VIX_OK; VixPropertyValue *property = NULL; if (NULL == propList) { err = VIX_E_INVALID_ARG; goto abort; } /* * Find or create an entry for this property. */ err = VixPropertyList_FindProperty(propList, propertyID, VIX_PROPERTYTYPE_INT64, 0, TRUE, &property); if (VIX_OK != err) { goto abort; } property->value.int64Value = value; property->isDirty = TRUE; abort: return(err); } // VixPropertyList_SetInt64 /* *----------------------------------------------------------------------------- * * VixPropertyList_GetBlob -- * * Return a copy of a Blob property value. The value is identified * by the integer property ID. * * This fails if the value is not present, or if it is a different * type, or if the caller did not pass a valid out parameter to * receive the value. * * Results: * VixError. VIX_OK if the property was found. * VIX_E_UNRECOGNIZED_PROPERTY if the property was not found. * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixPropertyList_GetBlob(VixPropertyListImpl *propList, // IN int propertyID, // IN int index, // IN int *resultSize, // OUT unsigned char **resultValue) // OUT { VixError err = VIX_OK; VixPropertyValue *property = NULL; if ((NULL == propList) || (NULL == resultSize) || (NULL == resultValue)) { err = VIX_E_INVALID_ARG; goto abort; } *resultSize = 0; *resultValue = NULL; err = VixPropertyList_FindProperty(propList, propertyID, VIX_PROPERTYTYPE_BLOB, index, FALSE, &property); if (VIX_OK != err) { goto abort; } if ((property->value.blobValue.blobSize > 0) && (NULL != property->value.blobValue.blobContents)) { *resultSize = property->value.blobValue.blobSize; *resultValue = Util_SafeMalloc(property->value.blobValue.blobSize); memcpy(*resultValue, property->value.blobValue.blobContents, property->value.blobValue.blobSize); } abort: return err; } // VixPropertyList_GetBlob /* *----------------------------------------------------------------------------- * * VixPropertyList_SetBlob -- * * Saves a copy of a blob property value. The value is identified * by the integer property ID. * * Value names are unique within a single proeprty list. * If a previous value with the same propertyID value already * existed in this property list, then it is replaced with the new * value. Otherwise, a new value is added. * * This fails if the value is present but has a different type. * * Results: * VixError. * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixPropertyList_SetBlob(VixPropertyListImpl *propList, // IN int propertyID, // IN int blobSize, // IN const unsigned char *value) // IN { VixError err = VIX_OK; VixPropertyValue *property = NULL; if (NULL == propList) { err = VIX_E_INVALID_ARG; goto abort; } /* * Find or create an entry for this property. */ err = VixPropertyList_FindProperty(propList, propertyID, VIX_PROPERTYTYPE_BLOB, 0, TRUE, &property); if (VIX_OK != err) { goto abort; } if (NULL != property->value.blobValue.blobContents) { free(property->value.blobValue.blobContents); property->value.blobValue.blobContents = NULL; } property->value.blobValue.blobSize = blobSize; if ((NULL != value) && (blobSize > 0)) { property->value.blobValue.blobContents = Util_SafeMalloc(blobSize); memcpy(property->value.blobValue.blobContents, value, blobSize); } property->isDirty = TRUE; abort: return(err); } // VixPropertyList_SetBlob /* *----------------------------------------------------------------------------- * * VixPropertyList_GetPtr -- * * Return a copy of a void* property value. The value is identified * by the integer property ID. * * This is a SHALLOW copy. It only copies the pointer, not what the * pointer references. * * This fails if the value is not present, or if it is a different * type, or if the caller did not pass a valid out parameter to * receive the value. * * Results: * VixError. VIX_OK if the property was found. * VIX_E_UNRECOGNIZED_PROPERTY if the property was not found. * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixPropertyList_GetPtr(VixPropertyListImpl *propList, // IN int propertyID, // IN int index, // IN void **resultValue) // OUT { VixError err = VIX_OK; VixPropertyValue *property = NULL; if ((NULL == resultValue) || (NULL == propList)) { err = VIX_E_INVALID_ARG; goto abort; } err = VixPropertyList_FindProperty(propList, propertyID, VIX_PROPERTYTYPE_POINTER, index, FALSE, &property); if (VIX_OK != err) { goto abort; } *resultValue = property->value.ptrValue; abort: return err; } // VixPropertyList_GetPtr /* *----------------------------------------------------------------------------- * * VixPropertyList_SetPtr -- * * Saves a copy of a ptr property value. The value is identified * by the integer property ID. * * This is a SHALLOW copy. It only copies the pointer, not what the * pointer references. * * Value names are unique within a single proeprty list. * If a previous value with the same propertyID value already * existed in this property list, then it is replaced with the new * value. Otherwise, a new value is added. * * This fails if the value is present but has a different type. * * Results: * VixError. * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError VixPropertyList_SetPtr(VixPropertyListImpl *propList, // IN int propertyID, // IN void *value) // IN { VixError err = VIX_OK; VixPropertyValue *property = NULL; if (NULL == propList) { err = VIX_E_INVALID_ARG; goto abort; } /* * Find or create an entry for this property. */ err = VixPropertyList_FindProperty(propList, propertyID, VIX_PROPERTYTYPE_POINTER, 0, TRUE, &property); if (VIX_OK != err) { goto abort; } property->value.ptrValue = value; property->isDirty = TRUE; abort: return(err); } // VixPropertyList_SetPtr /* *----------------------------------------------------------------------------- * * VixPropertyList_PropertyExists -- * * * Results: * Bool * * Side effects: * *----------------------------------------------------------------------------- */ Bool VixPropertyList_PropertyExists(VixPropertyListImpl *propList, // IN int propertyID, // IN VixPropertyType type) // IN { VixError err = VIX_OK; VixPropertyValue *property = NULL; Bool foundIt = FALSE; err = VixPropertyList_FindProperty(propList, propertyID, type, 0, // index FALSE, // createIfMissing &property); if ((VIX_OK == err) && (NULL != property)) { foundIt = TRUE; } return(foundIt); } // VixPropertyList_PropertyExists /* *----------------------------------------------------------------------------- * * VixPropertyList_NumItems -- * * Returns a count of the properties in the list. * * Results: * int - Number of properties in property list. * * Side effects: * None. * *----------------------------------------------------------------------------- */ int VixPropertyList_NumItems(VixPropertyListImpl *propList) // IN { VixPropertyValue *prop; int count = 0; if (propList == NULL) { return 0; } for (prop = propList->properties; prop != NULL; prop = prop->next) { ++count; } return count; } // VixPropertyList_NumItems /* *----------------------------------------------------------------------------- * * VixPropertyList_Empty -- * * Returns whether the property list has no properties. * * Results: * Bool - True iff property list has no properties. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool VixPropertyList_Empty(VixPropertyListImpl *propList) // IN { return (propList == NULL || propList->properties == NULL); } // VixPropertyList_Empty open-vm-tools-9.4.0-1280544/lib/foundryMsg/vixTranslateErrOpenSource.c0000644765153500003110000002361612220061556023656 0ustar dtormts /********************************************************* * Copyright (C) 2003 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vixTranslateErrorOpenSource.c -- * * Routines which translate between various other error code systems * into foundry errors. * * This is the minimal functions needed to build the tools for open source. * Most of the error translation functions are in foundryTranslateError.c, * which is NOT being released as open source. We do not want to include * any unnecessary error functions, since those use lots of different * error code definitions, and that would drag in a lot of headers from * bora/lib/public. */ #include "vmware.h" #include "vixOpenSource.h" #include #include #ifdef _WIN32 #include "win32u.h" #endif /* *----------------------------------------------------------------------------- * * Vix_TranslateGuestRegistryError -- * * Translate a guest windows registry error to a Foundry error. * * Results: * VixError * * Side effects: * None. * *----------------------------------------------------------------------------- */ VixError Vix_TranslateGuestRegistryError(int systemError) // IN { VixError err = VIX_E_FAIL; #ifdef _WIN32 Unicode msg; switch (systemError) { case ERROR_INVALID_PARAMETER: case ERROR_FILE_NOT_FOUND: err = VIX_E_REG_KEY_INVALID; break; case ERROR_ACCESS_DENIED: err = VIX_E_GUEST_USER_PERMISSIONS; break; default: return Vix_TranslateSystemError(systemError); } msg = Win32U_FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, systemError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), NULL); Log("Foundry operation failed with guest windows registry error: %s (%d), translated to %"FMT64"d\n", msg, systemError, err); Unicode_Free(msg); #endif return err; } // Vix_TranslateGuestRegistryError /* *----------------------------------------------------------------------------- * * Vix_TranslateSystemError -- * * Translate a System error to a Foundry error. * * Results: * VixError * * Side effects: * *----------------------------------------------------------------------------- */ VixError Vix_TranslateSystemError(int systemError) // IN { VixError err = VIX_E_FAIL; #ifdef _WIN32 Unicode msg; switch (systemError) { case ERROR_ACCESS_DENIED: err = VIX_E_FILE_ACCESS_ERROR; break; case ERROR_INVALID_NAME: err = VIX_E_FILE_NAME_INVALID; break; case ERROR_FILENAME_EXCED_RANGE: err = VIX_E_FILE_NAME_TOO_LONG; break; case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: case ERROR_BAD_PATHNAME: case ERROR_DIRECTORY: case ERROR_BUFFER_OVERFLOW: err = VIX_E_FILE_NOT_FOUND; break; case ERROR_DIR_NOT_EMPTY: err = VIX_E_DIRECTORY_NOT_EMPTY; break; case ERROR_TOO_MANY_OPEN_FILES: case ERROR_NO_MORE_FILES: case ERROR_WRITE_PROTECT: case ERROR_WRITE_FAULT: case ERROR_READ_FAULT: case ERROR_SHARING_VIOLATION: case ERROR_SEEK: case ERROR_CANNOT_MAKE: Log("%s: system error = %d\n", __FUNCTION__, systemError); err = VIX_E_FILE_ERROR; break; case ERROR_HANDLE_DISK_FULL: case ERROR_DISK_FULL: err = VIX_E_DISK_FULL; break; case ERROR_FILE_EXISTS: case ERROR_ALREADY_EXISTS: err = VIX_E_FILE_ALREADY_EXISTS; break; case ERROR_BUSY: case ERROR_PATH_BUSY: err = VIX_E_OBJECT_IS_BUSY; break; case ERROR_INVALID_PARAMETER: err = VIX_E_INVALID_ARG; break; case ERROR_NOT_SUPPORTED: err = VIX_E_NOT_SUPPORTED; break; case ERROR_NO_DATA: case ERROR_INVALID_DATA: err = VIX_E_NOT_FOUND; break; case ERROR_NOT_ENOUGH_MEMORY: err = VIX_E_OUT_OF_MEMORY; break; default: err = VIX_E_FAIL; } msg = Win32U_FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, systemError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), NULL); Log("Foundry operation failed with system error: %s (%d), translated to %"FMT64"d\n", msg, systemError, err); Unicode_Free(msg); #else // linux, other *nix err = Vix_TranslateErrno(systemError); #endif return err; } // Vix_TranslateSystemError /* *----------------------------------------------------------------------------- * * Vix_TranslateCOMError -- * * Translate a COM (Windows) error to a Foundry error. * * Results: * VixError. * * Side effects: * None. * *----------------------------------------------------------------------------- */ #ifdef _WIN32 VixError Vix_TranslateCOMError(HRESULT hrError) // IN { VixError err = VIX_E_FAIL; switch (hrError) { case E_ACCESSDENIED: err = VIX_E_FILE_ACCESS_ERROR; break; case STG_E_PATHNOTFOUND: case STG_E_FILENOTFOUND: err = VIX_E_FILE_NOT_FOUND; break; case STG_E_MEDIUMFULL: err = VIX_E_DISK_FULL; break; case STG_E_FILEALREADYEXISTS: err = VIX_E_FILE_ALREADY_EXISTS; break; case E_INVALIDARG: case E_POINTER: err = VIX_E_INVALID_ARG; break; case E_NOTIMPL: case E_NOINTERFACE: err = VIX_E_NOT_SUPPORTED; break; case E_OUTOFMEMORY: err = VIX_E_OUT_OF_MEMORY; break; case E_FAIL: default: err = VIX_E_FAIL; } return err; } // Vix_TranslateCOMError #endif /* *----------------------------------------------------------------------------- * * Vix_TranslateCryptoError -- * * Translate a Crypto error to a Foundry error. * * Results: * VixError * * Side effects: * *----------------------------------------------------------------------------- */ VixError Vix_TranslateCryptoError(CryptoError cryptoError) // IN { if (CRYPTO_ERROR_SUCCESS == cryptoError) { return VIX_OK; } else if (CRYPTO_ERROR_OPERATION_FAILED == cryptoError) { return VIX_E_GUEST_USER_PERMISSIONS; } else if (CRYPTO_ERROR_UNKNOWN_ALGORITHM == cryptoError) { return VIX_E_CRYPTO_UNKNOWN_ALGORITHM; } else if (CRYPTO_ERROR_BAD_BUFFER_SIZE == cryptoError) { return VIX_E_CRYPTO_BAD_BUFFER_SIZE; } else if (CRYPTO_ERROR_INVALID_OPERATION == cryptoError) { return VIX_E_CRYPTO_INVALID_OPERATION; } else if (CRYPTO_ERROR_NOMEM == cryptoError) { return VIX_E_OUT_OF_MEMORY; } else if (CRYPTO_ERROR_NEED_PASSWORD == cryptoError) { return VIX_E_CRYPTO_NEED_PASSWORD; } else if (CRYPTO_ERROR_BAD_PASSWORD == cryptoError) { return VIX_E_CRYPTO_BAD_PASSWORD; } else if (CRYPTO_ERROR_IO_ERROR == cryptoError) { Log("%s: crypto error = %d\n", __FUNCTION__, (int)cryptoError); return VIX_E_FILE_ERROR; } else if (CRYPTO_ERROR_UNKNOWN_ERROR == cryptoError) { return VIX_E_FAIL; } else if (CRYPTO_ERROR_NAME_NOT_FOUND == cryptoError) { return VIX_E_CRYPTO_NOT_IN_DICTIONARY; } else if (CRYPTO_ERROR_NO_CRYPTO == cryptoError) { return VIX_E_CRYPTO_NO_CRYPTO; } return VIX_E_FAIL; } /* *----------------------------------------------------------------------------- * * Vix_TranslateErrno -- * * Translate a Posix errno to a Foundry error. * * Results: * VixError * * Side effects: * None * *----------------------------------------------------------------------------- */ VixError Vix_TranslateErrno(int systemError) // IN { VixError err = VIX_E_FAIL; /* * Be careful while adding new error code translations. This function is * complied for both Windows and POSIX guests. Few errors i.e. ETIMEDOUT, * ENOBUFS are defined only for POSIX guests. When a new error code * translation is added, make sure you build a sandbox job and it is * successful. */ switch (systemError) { case EPERM: case EACCES: err = VIX_E_FILE_ACCESS_ERROR; break; case EAGAIN: case EBUSY: err = VIX_E_OBJECT_IS_BUSY; break; case EEXIST: err = VIX_E_FILE_ALREADY_EXISTS; break; case EFBIG: err = VIX_E_FILE_TOO_BIG; break; case ENOTEMPTY: err = VIX_E_DIRECTORY_NOT_EMPTY; break; case ENOTDIR: err = VIX_E_NOT_A_DIRECTORY; break; #ifndef _WIN32 case ETIMEDOUT: case ENOBUFS: #endif case EIO: case EMFILE: case ENFILE: case EMLINK: case EROFS: Log("%s: errno = %d\n", __FUNCTION__, systemError); err = VIX_E_FILE_ERROR; break; case ENODEV: case ENOENT: err = VIX_E_FILE_NOT_FOUND; break; case ENOSPC: err = VIX_E_DISK_FULL; break; case EISDIR: err = VIX_E_NOT_A_FILE; break; case ESRCH: err = VIX_E_NO_SUCH_PROCESS; break; case ENAMETOOLONG: err = VIX_E_FILE_NAME_TOO_LONG; break; #ifndef _WIN32 case EMSGSIZE: #endif case EINVAL: err = VIX_E_INVALID_ARG; break; #ifndef _WIN32 case ELOOP: #endif case ENOMEM: err = VIX_E_OUT_OF_MEMORY; break; default: err = VIX_E_FAIL; } Log("Foundry operation failed with system error: %s (%d), translated to %"FMT64"d\n", strerror(systemError), systemError, err); return err; } // Vix_TranslateErrno open-vm-tools-9.4.0-1280544/lib/foundryMsg/Makefile.am0000644765153500003110000000212012220061556020371 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libFoundryMsg.la libFoundryMsg_la_SOURCES = libFoundryMsg_la_SOURCES += foundryMsg.c libFoundryMsg_la_SOURCES += foundryPropertyListCommon.c libFoundryMsg_la_SOURCES += vixTranslateErrOpenSource.c open-vm-tools-9.4.0-1280544/lib/foundryMsg/Makefile.in0000644765153500003110000004433012220061622020405 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/foundryMsg DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libFoundryMsg_la_LIBADD = am_libFoundryMsg_la_OBJECTS = foundryMsg.lo \ foundryPropertyListCommon.lo vixTranslateErrOpenSource.lo libFoundryMsg_la_OBJECTS = $(am_libFoundryMsg_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libFoundryMsg_la_SOURCES) DIST_SOURCES = $(libFoundryMsg_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libFoundryMsg.la libFoundryMsg_la_SOURCES = foundryMsg.c foundryPropertyListCommon.c \ vixTranslateErrOpenSource.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/foundryMsg/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/foundryMsg/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libFoundryMsg.la: $(libFoundryMsg_la_OBJECTS) $(libFoundryMsg_la_DEPENDENCIES) $(EXTRA_libFoundryMsg_la_DEPENDENCIES) $(LINK) $(libFoundryMsg_la_OBJECTS) $(libFoundryMsg_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foundryMsg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foundryPropertyListCommon.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vixTranslateErrOpenSource.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/hgfsBd/0000755765153500003110000000000012220061622015374 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/hgfsBd/hgfsBd.c0000644765153500003110000002444612220061556016755 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * hgfsBd.c -- * * Backdoor calls used by hgfs pserver. [bac] */ #if defined(__KERNEL__) || defined(_KERNEL) || defined(KERNEL) # include "kernelStubs.h" #else # include # include # include # include # include "str.h" // for Str_Strcpy # include "debug.h" #endif #include "vm_assert.h" #include "rpcout.h" #include "hgfs.h" // for common HGFS definitions #include "hgfsBd.h" /* *----------------------------------------------------------------------------- * * HgfsBdGetBufInt -- * * Allocates a buffer to send a hgfs request in. This can be either a * HGFS_PACKET_MAX or HGFS_LARGE_PACKET_MAX size buffer depending on the * external funciton called. * * Results: * Pointer to a buffer that has the correct backdoor command prefix for * sending hgfs requests over the backdoor. * NULL on failure (not enough memory). * * Side effects: * None. * *----------------------------------------------------------------------------- */ static char * HgfsBdGetBufInt(size_t bufSize) { /* * Allocate a buffer that is large enough for an HGFS packet and the * synchronous HGFS command, write the command, and return a pointer that * points into the buffer, after the command. */ size_t len = bufSize + HGFS_SYNC_REQREP_CLIENT_CMD_LEN; char *buf = (char*) calloc(sizeof(char), len); if (!buf) { Debug("HgfsBd_GetBuf: Failed to allocate a bd buffer\n"); return NULL; } Str_Strcpy(buf, HGFS_SYNC_REQREP_CLIENT_CMD, len); return buf + HGFS_SYNC_REQREP_CLIENT_CMD_LEN; } /* *----------------------------------------------------------------------------- * * HgfsBd_GetBuf -- * * Get a buffer of size HGFS_PACKET_MAX to send hgfs requests in. * * Results: * See HgfsBdGetBufInt. * * Side effects: * Allocates memory that must be freed with a call to HgfsBd_PutBuf. * *----------------------------------------------------------------------------- */ char * HgfsBd_GetBuf(void) { return HgfsBdGetBufInt(HGFS_PACKET_MAX); } /* *----------------------------------------------------------------------------- * * HgfsBd_GetLargeBuf -- * * Get a buffer of size HGFS_LARGE_PACKET_MAX to send hgfs requests in. * * Results: * See HgfsBdGetBufInt. * * Side effects: * Allocates memory that must be freed with a call to HgfsBd_PutBuf. * *----------------------------------------------------------------------------- */ char * HgfsBd_GetLargeBuf(void) { return HgfsBdGetBufInt(HGFS_LARGE_PACKET_MAX); } /* *----------------------------------------------------------------------------- * * HgfsBd_PutBuf -- * * Release a buffer obtained with HgfsBd_GetBuf. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void HgfsBd_PutBuf(char *buf) // IN { ASSERT(buf); free(buf - HGFS_SYNC_REQREP_CLIENT_CMD_LEN); } /* *----------------------------------------------------------------------------- * * HgfsBd_GetChannel -- * * Allocate a new RpcOut channel, and try to open the connection. * * Results: * Pointer to the allocated, opened channel on success. * NULL on failure (not enough memory, or failed to open the connection). * * Side effects: * None * *----------------------------------------------------------------------------- */ RpcOut * HgfsBd_GetChannel(void) { RpcOut *out = RpcOut_Construct(); Bool status; if (!out) { Debug("HgfsBd_GetChannel: Failed to allocate an RpcOut\n"); return NULL; } status = RpcOut_start(out); if (status == FALSE) { RpcOut_Destruct(out); return NULL; } return out; } /* *----------------------------------------------------------------------------- * * HgfsBd_CloseChannel -- * * Close the channel and free the RpcOut object. * * Results: * TRUE if closing the channel succeeded, FALSE if it failed. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsBd_CloseChannel(RpcOut *out) // IN: Channel to close and free { Bool success; ASSERT(out); success = RpcOut_stop(out); if (success == TRUE) { RpcOut_Destruct(out); } return success; } /* *----------------------------------------------------------------------------- * * HgfsBd_Dispatch -- * * Get a reply to an hgfs request. We call RpcOut_Sent, which * returns a buffer with the reply in it, and we pass this back to * the caller. * * Results: * On success, returns zero. On failure, returns a negative error. * * Side effects: * None * *----------------------------------------------------------------------------- */ int HgfsBd_Dispatch(RpcOut *out, // IN: Channel to send on char *packetIn, // IN: Buf containing request packet size_t *packetSize, // IN/OUT: Size of packet in/out char const **packetOut) // OUT: Buf containing reply packet { Bool success; char const *reply; size_t replyLen; char *bdPacket = packetIn - HGFS_SYNC_REQREP_CLIENT_CMD_LEN; ASSERT(out); ASSERT(packetIn); ASSERT(packetSize); ASSERT(packetOut); memcpy(bdPacket, HGFS_SYNC_REQREP_CLIENT_CMD, HGFS_SYNC_REQREP_CLIENT_CMD_LEN); success = RpcOut_send(out, bdPacket, *packetSize + HGFS_CLIENT_CMD_LEN, &reply, &replyLen); if (success == FALSE) { Debug("HgfsBd_Dispatch: RpcOut_send returned failure\n"); return -1; } ASSERT(replyLen <= HGFS_LARGE_PACKET_MAX); *packetOut = reply; *packetSize = replyLen; return 0; } /* *----------------------------------------------------------------------------- * * HgfsBd_Enabled -- * * Test to see if hgfs is enabled on the host. * * Results: * TRUE if hgfs is enabled. * FALSE if hgfs is disabled. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsBd_Enabled(RpcOut *out, // IN: RPCI Channel char *requestPacket) // IN: Buffer (obtained from HgfsBd_GetBuf) { char const *replyPacket; // Buffer returned by HgfsBd_Dispatch size_t replyLen; Bool success; /* * Send a bogus (empty) request to the VMX. If hgfs is disabled on * the host side then the request will fail (because the RPCI call * itself will fail). If hgfs is enabled, we will get a packet back * (it will be an error packet because our request was malformed, * but we just discard it anyway). */ success = RpcOut_send(out, requestPacket - HGFS_CLIENT_CMD_LEN, HGFS_CLIENT_CMD_LEN, &replyPacket, &replyLen); if (success == TRUE) { ASSERT(replyLen <= HGFS_LARGE_PACKET_MAX); } return success; } /* *----------------------------------------------------------------------------- * * HgfsBd_OpenBackdoor -- * * Check if the HGFS channel is open, and, if not, open it. This is a * one-stop convenience wrapper around HgfsBd_Enabled, HgfsBd_GetBuf, and * HgfsBd_GetChannel. * * Results: * TRUE if the backdoor is now open, regardless of its previous state. * FALSE if the backdoor could not be opened. * * Side effects: * May open a channel to the host. * *----------------------------------------------------------------------------- */ Bool HgfsBd_OpenBackdoor(RpcOut **out) // IN/OUT: RPCI Channel { char *packetBuffer = NULL; Bool success = FALSE; ASSERT(out); /* Short-circuit: backdoor is already open. */ if (*out != NULL) { return TRUE; } /* Open the channel. */ *out = HgfsBd_GetChannel(); if (*out == NULL) { return FALSE; } /* Allocate a buffer for use in pinging the HGFS server. */ packetBuffer = HgfsBd_GetBuf(); if (packetBuffer == NULL) { goto out; } /* Ping the HGFS server. */ if (!HgfsBd_Enabled(*out, packetBuffer)) { goto out; } success = TRUE; out: if (packetBuffer != NULL) { HgfsBd_PutBuf(packetBuffer); } if (!success && *out != NULL) { HgfsBd_CloseChannel(*out); *out = NULL; } return success; } /* *----------------------------------------------------------------------------- * * HgfsBd_CloseBackdoor -- * * Closes the backdoor channel, if it's open. * * Results: * TRUE if the channel is now closed, regardless of its previous state. * FALSE if we could not close the channel. * * Side effects: * May close the channel to the host. * *----------------------------------------------------------------------------- */ Bool HgfsBd_CloseBackdoor(RpcOut **out) // IN/OUT: RPCI Channel { Bool success = TRUE; ASSERT(out); if (*out != NULL) { if (!HgfsBd_CloseChannel(*out)) { success = FALSE; } *out = NULL; } return success; } open-vm-tools-9.4.0-1280544/lib/hgfsBd/Makefile.am0000644765153500003110000000172012220061556017436 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libHgfsBd.la libHgfsBd_la_SOURCES = libHgfsBd_la_SOURCES += hgfsBd.c open-vm-tools-9.4.0-1280544/lib/hgfsBd/Makefile.in0000644765153500003110000004353412220061622017452 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/hgfsBd DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libHgfsBd_la_LIBADD = am_libHgfsBd_la_OBJECTS = hgfsBd.lo libHgfsBd_la_OBJECTS = $(am_libHgfsBd_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libHgfsBd_la_SOURCES) DIST_SOURCES = $(libHgfsBd_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libHgfsBd.la libHgfsBd_la_SOURCES = hgfsBd.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/hgfsBd/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/hgfsBd/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libHgfsBd.la: $(libHgfsBd_la_OBJECTS) $(libHgfsBd_la_DEPENDENCIES) $(EXTRA_libHgfsBd_la_DEPENDENCIES) $(LINK) $(libHgfsBd_la_OBJECTS) $(libHgfsBd_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hgfsBd.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/appUtil/0000755765153500003110000000000012220061621015614 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/appUtil/appUtil.c0000644765153500003110000000454512220061556017415 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * appUtil.c -- * * Utility functions for guest applications. */ #include #include #include "vmware.h" #include "appUtil.h" #include "debug.h" #include "rpcout.h" #include "str.h" /* *---------------------------------------------------------------------------- * * AppUtil_SendGuestCaps -- * * Send a list of guest capabilities to the host. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void AppUtil_SendGuestCaps(const GuestCapabilities *caps, // IN: array of capabilities size_t numCaps, // IN: number of capabilities Bool enabled) // IN: capabilities status { char *capsStr = NULL; char *capsTemp = NULL; size_t capIdx; ASSERT(caps); ASSERT(numCaps > 0); capsStr = strdup(GUEST_CAP_FEATURES); for (capIdx = 0; capIdx < numCaps; capIdx++) { if (!capsStr) { Debug("%s: Not enough memory to create capabilities string\n", __FUNCTION__); return; } capsTemp = Str_Asprintf(NULL, "%s %d=%d", capsStr, caps[capIdx], (int)enabled); free(capsStr); capsStr = capsTemp; } if (!RpcOut_sendOne(NULL, NULL, capsStr)) { Debug("%s: could not set capabilities: older vmx?\n", __FUNCTION__); } free(capsStr); } open-vm-tools-9.4.0-1280544/lib/appUtil/appUtilX11.c0000644765153500003110000006012612220061556017704 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * appUtilX11.c -- * * Utility functions to retrieve application icons. */ #define _GNU_SOURCE 1 #include #include #include #include "vmware.h" #include "str.h" #include "posix.h" #include "debug.h" #ifndef GTK2 #error "Gtk 2.0 is required" #endif #include #include #include #include #include #include #include /* *----------------------------------------------------------------------------- * * AppUtilIconThemeReallyHasIcon -- * * Utility function to detect whether an icon is really available. This is necessary * because sometimes gtk_icon_theme_has_icon() lies to us... * * Results: * TRUE if the icon theme really has a usable icon, FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool AppUtilIconThemeReallyHasIcon(GtkIconTheme *iconTheme, // IN const char *iconName) // IN { gint *iconSizes; Bool retval; if (!gtk_icon_theme_has_icon(iconTheme, iconName)) { return FALSE; } iconSizes = gtk_icon_theme_get_icon_sizes(iconTheme, iconName); retval = iconSizes && iconSizes[0]; g_free(iconSizes); return retval; } /* *----------------------------------------------------------------------------- * * AppUtilCollectNamedIcons -- * * Tries to find icons with a particular name (which may be a full filesystem path, * a filename with extension, or just an abstract app name). * * Results: * None. * * Side effects: * May add icons into 'pixbufs' * *----------------------------------------------------------------------------- */ static void AppUtilCollectNamedIcons(GPtrArray *pixbufs, // IN/OUT const char *iconName) // IN { char *myIconName; char *baseIconName; /* * Use the GtkIconTheme to track down any available icons for this app. */ GtkIconTheme *iconTheme = NULL; char *ctmp2; Bool foundItInTheme = FALSE; // Did we find this icon in the GtkIconTheme? Bool foundItInFile = FALSE; // Did we find this icon directly in a file? static const char *extraIconPaths[] = { "/usr/share/icons", "/usr/share/pixmaps", "/usr/local/share/pixmaps", "/usr/local/share/icons", "/opt/kde3/share/icons", "/opt/kde3/share/pixmaps", "/opt/kde4/share/icons", "/opt/kde4/share/pixmaps", "/opt/gnome/share/icons", "/opt/gnome/share/pixmaps" }; int iconNameLen; ASSERT(iconName); Debug("Collecting icons named %s\n", iconName); iconNameLen = strlen(iconName) + 1; baseIconName = g_alloca(iconNameLen); // We need to modify the name sometimes Str_Strcpy(baseIconName, iconName, iconNameLen); ctmp2 = strrchr(baseIconName, '.'); if (*baseIconName != '/' && ctmp2 && strlen(ctmp2) <= 5) { /* * If it's a plain filename that we could possibly feed into GtkIconTheme as an * icon ID, trim the file extension to turn it into an icon ID string and make * GtkIconTheme happy. */ *ctmp2 = '\0'; } iconTheme = gtk_icon_theme_get_default(); g_object_ref(G_OBJECT(iconTheme)); foundItInTheme = AppUtilIconThemeReallyHasIcon(iconTheme, baseIconName); if (!foundItInTheme) { /* * Try looking for it as a non-GtkIconTheme managed file, to deal with older * systems. */ if (iconName[0] != '/') { gchar *iconSearchName; gsize iconSearchNameSize; gboolean triedOtherExts = FALSE; char *ctmp2; int i; static const char *iconExtensions[] = { "", // MUST be first entry. ".png", ".xpm", ".gif", ".svg", }; /* * Make a local copy of iconName in case we need to search for icons with * alternate extensions. */ iconSearchNameSize = strlen(iconName) + 1; iconSearchName = g_alloca(iconSearchNameSize); g_strlcpy(iconSearchName, iconName, iconSearchNameSize); myIconName = NULL; ctmp2 = g_alloca(PATH_MAX); tryingOtherExts: for (i = 0; !myIconName && i < ARRAYSIZE(extraIconPaths); i++) { int j; if (!extraIconPaths[i]) { continue; } /* * Per Desktop Entry Specification and Icon Theme Specification, I don't * believe that the iconName, unless it's an absolute path, should include * the file extension. * * However, empirical evidence shows that -many- applications ignore that * and may specify an icon of, for example, "foo.png". We'll also handle * those special cases here. */ for (j = 0; !myIconName && j < ARRAYSIZE(iconExtensions); j++) { g_snprintf(ctmp2, PATH_MAX, "%s/%s%s", extraIconPaths[i], iconSearchName, iconExtensions[j]); if (!g_file_test(ctmp2, G_FILE_TEST_EXISTS)) { continue; } if (j != 0) { /* * Case 1: We located an icon by appending an image extension to * IconName. Success! */ myIconName = ctmp2; // Will break "i" loop. foundItInFile = TRUE; break; } else { /* * Case 2: We found an icon without appending an extension. Verify * that the filename contains a valid image extension. */ int k; char *ctmpext = strrchr(ctmp2, '.'); for (k = 1; ctmpext && k < ARRAYSIZE(iconExtensions); k++) { if (strcmp(ctmpext, iconExtensions[k]) == 0) { myIconName = ctmp2; // Will break "i" loop. foundItInFile = TRUE; break; } } } } } /* * No dice. But we won't give up hope just yet! In some cases, icon-foo.png * may not exist while icon-foo.xpm does. (Ex: Ubuntu 8.04's hwtest.) We'll * try once more by searching for an icon with an alternate extension. */ if (!foundItInFile && !triedOtherExts) { int extIndex; triedOtherExts = TRUE; /* * Look to see if iconSearchName contains any of the known extensions * listed above. If so, chop it off, then reattempt the search. */ for (extIndex = 1; extIndex < ARRAYSIZE(iconExtensions); extIndex++) { if (g_str_has_suffix(iconSearchName, iconExtensions[extIndex])) { gchar *extension; extension = g_strrstr(iconSearchName, iconExtensions[extIndex]); *extension = '\0'; goto tryingOtherExts; } } } } else { myIconName = g_alloca(iconNameLen + 1); Str_Strcpy(myIconName, iconName, iconNameLen); foundItInFile = TRUE; } } if (!foundItInTheme && !foundItInFile) { /* * Try looking through some auxiliary icon themes. */ int i; static const char *extraThemes[] = { /* * Some other icon themes to try. */ "hicolor", "Bluecurve", "HighContrast-SVG", "HighContrastLargePrint", "crystalsvg", "slick", NULL }; g_object_unref(G_OBJECT(iconTheme)); iconTheme = gtk_icon_theme_new(); for (i = 0; i < ARRAYSIZE(extraIconPaths); i++) { if (extraIconPaths[i]) { if (g_file_test(extraIconPaths[i], G_FILE_TEST_EXISTS)) { gtk_icon_theme_append_search_path(iconTheme, extraIconPaths[i]); } else { extraIconPaths[i] = NULL; } } } for (i = 0; extraThemes[i]; i++) { gtk_icon_theme_set_custom_theme(iconTheme, extraThemes[i]); foundItInTheme = AppUtilIconThemeReallyHasIcon(iconTheme, baseIconName); if (foundItInTheme) { break; } } } if (foundItInTheme) { /* * If we know this icon can be loaded via GtkIconTheme, do so. */ gint *iconSizes; int i; Bool needToUseScalable; iconSizes = gtk_icon_theme_get_icon_sizes(iconTheme, baseIconName); Debug("Loading icon %s from iconTheme\n", baseIconName); ASSERT(iconSizes); needToUseScalable = (iconSizes[0] == -1 && iconSizes[1] == 0); /* * Before we try to actually dump the icons out to the host, count how many we * actually can load. */ for (i = 0; iconSizes[i]; i++) { GdkPixbuf *pixbuf; GtkIconInfo *iconInfo; gint thisSize; thisSize = iconSizes[i]; if (thisSize == -1 && !needToUseScalable) { continue; // Skip scalable icons if we have prerendered versions } if (thisSize == -1) { thisSize = 64; // Render SVG icons to 64x64 } iconInfo = gtk_icon_theme_lookup_icon(iconTheme, baseIconName, thisSize, 0); if (!iconInfo) { Debug("Couldn't find %s icon for size %d\n", baseIconName, thisSize); continue; } pixbuf = gtk_icon_info_load_icon(iconInfo, NULL); if (!pixbuf) { pixbuf = gtk_icon_info_get_builtin_pixbuf(iconInfo); } if (pixbuf) { g_ptr_array_add(pixbufs, pixbuf); } else { Debug("WARNING: Not even a built-in pixbuf for icon %s\n", baseIconName); } gtk_icon_info_free(iconInfo); } g_free(iconSizes); } else if (foundItInFile && myIconName && myIconName[0] == '/') { GdkPixbuf *pixbuf; Debug("Loading icon %s from file\n", myIconName); pixbuf = gdk_pixbuf_new_from_file(myIconName, NULL); if (pixbuf) { g_ptr_array_add(pixbufs, pixbuf); } } if (iconTheme) { g_object_unref(G_OBJECT(iconTheme)); } } /* *----------------------------------------------------------------------------- * * AppUtilComparePixbufSizes -- * * Compares two GdkPixbufs to sort them by image dimensions * * Results: * -1 if A is larger than B, 0 if equal, 1 if A is smaller than B * * Side effects: * None. * *----------------------------------------------------------------------------- */ static gint AppUtilComparePixbufSizes(gconstpointer a, // IN gconstpointer b) // IN { GdkPixbuf *pba; GdkPixbuf *pbb; int asize; int bsize; if (a && !b) { return -1; } else if (!a && b) { return 1; } else if (!a && !b) { return 0; } pba = GDK_PIXBUF(*(gconstpointer *)a); asize = gdk_pixbuf_get_width(pba) * gdk_pixbuf_get_height(pba); pbb = GDK_PIXBUF(*(gconstpointer *)b); bsize = gdk_pixbuf_get_width(pbb) * gdk_pixbuf_get_height(pbb); if (asize > bsize) { return -1; } else if (asize < bsize) { return 1; } return 0; } /* *----------------------------------------------------------------------------- * * AppUtil_CollectIconArray -- * * Given a variety of information about an application (its icon name, X window ID, * etc.), return an array of GdkPixbufs that represent the icons for that * application. * * Results: * GPtrArray of GdkPixbufs, or NULL on failure. The returned array may have zero * elements. The array will be sorted by icon size, largest to smallest. * * Side effects: * Caller becomes owner of the array and pixbufs that are allocated during this * function. * *----------------------------------------------------------------------------- */ GPtrArray * AppUtil_CollectIconArray(const char *iconName, // IN unsigned long windowID) // IN { GPtrArray *pixbufs; pixbufs = g_ptr_array_new(); if (iconName) { AppUtilCollectNamedIcons(pixbufs, iconName); } if (!pixbufs->len && windowID != None) { /* * Try loading the icon from the X Window's _NET_WM_ICON/WM_HINTS property. */ Display *dpy; XWMHints *wmh; Atom actualType = None; int actualFormat; unsigned long nitems = 0; unsigned long bytesLeft; XID *value; XTextProperty wmIconName; dpy = gdk_x11_get_default_xdisplay(); XGetWindowProperty(dpy, windowID, XInternAtom(dpy, "_NET_WM_ICON", FALSE), 0, LONG_MAX, False, XA_CARDINAL, &actualType, &actualFormat, &nitems, &bytesLeft, (unsigned char **)&value); if (nitems) { /* * _NET_WM_ICON: Transform ARGB data into pixbufs... */ int i; for (i = 0; i < nitems; ) { GdkPixbuf *pixbuf; int width; int height; int x; int y; int rowstride; guchar *pixels; ASSERT((nitems - i) >= 2); width = value[i]; height = value[i + 1]; i += 2; pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height); if (pixbuf) { pixels = gdk_pixbuf_get_pixels(pixbuf); rowstride = gdk_pixbuf_get_rowstride(pixbuf); for (y = 0; y < height; y++) { for (x = 0; x < width && i < nitems; x++, i++) { guchar *pixel = &pixels[y * rowstride + x * 4]; XID currentValue = value[i]; /* * Input data: BGRA data (high byte is A, low byte is B - * freedesktop calls this ARGB, but that's not correct). * * Output data: RGBA data. */ *pixel = (currentValue >> 16) & 0xFF; *(pixel + 1) = (currentValue >> 8) & 0xFF; *(pixel + 2) = currentValue & 0xFF; *(pixel + 3) = (currentValue >> 24) & 0xFF; } } g_ptr_array_add(pixbufs, pixbuf); } else { Debug("gdk_pixbuf_new failed when decoding _NET_WM_ICON\n"); break; } } XFree(value); } nitems = 0; if (!pixbufs->len && XGetWindowProperty(dpy, windowID, XInternAtom(dpy, "_NET_WM_ICON_NAME", FALSE), 0, LONG_MAX, False, XInternAtom(dpy, "UTF8_STRING", FALSE), &actualType, &actualFormat, &nitems, &bytesLeft, (unsigned char **)&value) == Success && nitems) { /* * _NET_WM_ICON_NAME */ AppUtilCollectNamedIcons(pixbufs, (char *)value); XFree(value); } if (!pixbufs->len && XGetWMIconName(dpy, windowID, &wmIconName)) { /* * WM_ICON_NAME */ AppUtilCollectNamedIcons(pixbufs, wmIconName.value); XFree(wmIconName.value); } if (!pixbufs->len && (wmh = XGetWMHints(dpy, windowID))) { /* * WM_HINTS */ if (wmh->flags & IconPixmapHint) { Window dummyWin; int x; int y; unsigned int width; unsigned int height; unsigned int border; unsigned int depth; GdkPixbuf *pixbuf = NULL; if (XGetGeometry(dpy, wmh->icon_pixmap, &dummyWin, &x, &y, &width, &height, &border, &depth)) { pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height); if (!gdk_pixbuf_xlib_get_from_drawable (pixbuf, wmh->icon_pixmap, DefaultColormap(dpy, 0), DefaultVisual(dpy, 0), 0, 0, 0, 0, width, height)) { g_object_unref(G_OBJECT(pixbuf)); pixbuf = NULL; } if (pixbuf && (wmh->flags & IconMaskHint)) { /* * Apply the X bitmap mask. */ GdkPixbuf *pixbuf_mask; pixbuf_mask = gdk_pixbuf_xlib_get_from_drawable(pixbuf, wmh->icon_mask, DefaultColormap(dpy, 0), DefaultVisual(dpy, 0), 0, 0, 0, 0, width, height); if (pixbuf_mask) { int x; int y; int rowstride; int rowstride_mask; guchar *pixels; guchar *pixels_mask; int depth_mask; int n_channels_mask; pixels = gdk_pixbuf_get_pixels(pixbuf); pixels_mask = gdk_pixbuf_get_pixels(pixbuf_mask); rowstride = gdk_pixbuf_get_rowstride(pixbuf); rowstride_mask = gdk_pixbuf_get_rowstride(pixbuf_mask); depth_mask = gdk_pixbuf_get_bits_per_sample(pixbuf_mask); ASSERT(gdk_pixbuf_get_bits_per_sample(pixbuf) == 8); n_channels_mask = gdk_pixbuf_get_n_channels(pixbuf_mask); for (y = 0; y < height; y++) { guchar *thisrow_mask = pixels_mask + y * rowstride_mask; guchar *thisrow = pixels + y * rowstride; for (x = 0; x < width; x++) { guchar newAlpha = 0xFF; switch(depth_mask) { case 1: newAlpha = thisrow_mask[x * n_channels_mask / 8]; newAlpha >>= (x % 8); newAlpha = newAlpha ? 0xFF : 0; break; case 8: /* * For some reason, gdk-pixbuf-xlib turns a monochrome * bitmap into 0/1 values in the blue channel of an RGBA * pixmap. */ newAlpha = (thisrow_mask[x * n_channels_mask + 2]) ? 0xFF : 0; break; default: NOT_REACHED(); break; } thisrow[x * 4 + 3] = newAlpha; } } } } if (pixbuf) { g_ptr_array_add(pixbufs, pixbuf); } } } XFree(wmh); } if (!pixbufs->len) { /* * Last resort - try using the WM_CLASS as an icon name */ XClassHint hints; if (XGetClassHint(dpy, windowID, &hints)) { if (hints.res_name) { AppUtilCollectNamedIcons(pixbufs, hints.res_name); } XFree(hints.res_name); XFree(hints.res_class); } } } /* * In order to make it easy for AppUtil users to pick the icon they want, we sort them * largest-to-smallest. */ g_ptr_array_sort(pixbufs, AppUtilComparePixbufSizes); if (!pixbufs->len) { Debug("WARNING: No icons found for %s / %#lx\n", iconName, windowID); } return pixbufs; } /* *----------------------------------------------------------------------------- * * AppUtil_FreeIconArray -- * * Frees the result of AppUtil_CollectIconArray * * Results: * None. * * Side effects: * Array and its contents are destroyed * *----------------------------------------------------------------------------- */ void AppUtil_FreeIconArray(GPtrArray *pixbufs) // IN { int i; if (!pixbufs) { return; } for (i = 0; i < pixbufs->len; i++) { g_object_unref(G_OBJECT(g_ptr_array_index(pixbufs, i))); } g_ptr_array_free(pixbufs, TRUE); } /* *----------------------------------------------------------------------------- * * AppUtil_AppIsSkippable -- * * Can an executable be ignored for the purposes of determining the path to run an * app with? Usually true for interpreters and the like, for which the script path * should be used instead. * * Results: * TRUE if the app should be ignored, FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool AppUtil_AppIsSkippable(const char *appName) { static const char *skipAppsList[] = { "python", "python2.5", "python2.4", "python2.3", "python2.2", "perl", "sh", "bash", }; char cbuf[PATH_MAX]; int i; char *ctmp; Str_Strcpy(cbuf, appName, sizeof cbuf); ctmp = basename(cbuf); for (i = 0; i < ARRAYSIZE(skipAppsList); i++) { if (!strcmp(ctmp, skipAppsList[i])) { return TRUE; } } return FALSE; } /* *----------------------------------------------------------------------------- * * AppUtil_CanonicalizeAppName -- * * Turns the app name (or path) into a full path for the executable. * * Results: * Path, or NULL if not available * * Side effects: * Allocated memory is returned * *----------------------------------------------------------------------------- */ char * AppUtil_CanonicalizeAppName(const char *appName, // IN const char *cwd) // IN { char *ctmp; ASSERT(appName); if (appName[0] == '/') { ctmp = g_strdup(appName); goto exit; } ctmp = g_find_program_in_path(appName); if (ctmp) { goto exit; } /* * It's probably safe to assume that cwd is an absolute path (at the time of * writing, it is derived from /proc), but let's check to be sure. */ if (cwd && cwd[0] == '/') { /* Don't add any unnecessary path separators. */ char *cbuf = Str_Asprintf(NULL, "%s%s%s", cwd, cwd[strlen(cwd) - 1] == '/' ? "" : "/", appName); if (cbuf) { ctmp = Posix_RealPath(cbuf); free(cbuf); } } exit: return ctmp; } /* *----------------------------------------------------------------------------- * * AppUtil_Init -- * * Initializes the AppUtil library for subsequent use. * * Results: * None. * * Side effects: * Internal state is initialized. Currently this is just gdk-pixbuf-xlib. * *----------------------------------------------------------------------------- */ void AppUtil_Init(void) { gdk_pixbuf_xlib_init(gdk_x11_get_default_xdisplay(), 0); } open-vm-tools-9.4.0-1280544/lib/appUtil/Makefile.am0000644765153500003110000000202612220061556017657 0ustar dtormts################################################################################ ### Copyright 2008 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libAppUtil.la libAppUtil_la_SOURCES = libAppUtil_la_SOURCES += appUtil.c libAppUtil_la_SOURCES += appUtilX11.c AM_CFLAGS = @GTK_CPPFLAGS@ open-vm-tools-9.4.0-1280544/lib/appUtil/Makefile.in0000644765153500003110000004376112220061621017674 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2008 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/appUtil DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libAppUtil_la_LIBADD = am_libAppUtil_la_OBJECTS = appUtil.lo appUtilX11.lo libAppUtil_la_OBJECTS = $(am_libAppUtil_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libAppUtil_la_SOURCES) DIST_SOURCES = $(libAppUtil_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libAppUtil.la libAppUtil_la_SOURCES = appUtil.c appUtilX11.c AM_CFLAGS = @GTK_CPPFLAGS@ all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/appUtil/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/appUtil/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libAppUtil.la: $(libAppUtil_la_OBJECTS) $(libAppUtil_la_DEPENDENCIES) $(EXTRA_libAppUtil_la_DEPENDENCIES) $(LINK) $(libAppUtil_la_OBJECTS) $(libAppUtil_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/appUtil.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/appUtilX11.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/auth/0000755765153500003110000000000012220061621015137 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/auth/Makefile.am0000644765153500003110000000175612220061556017213 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libAuth.la libAuth_la_SOURCES = libAuth_la_SOURCES += authPosix.c AM_CFLAGS = @LIB_AUTH_CPPFLAGS@ open-vm-tools-9.4.0-1280544/lib/auth/authPosix.c0000644765153500003110000002335312220061556017304 0ustar dtormts/********************************************************* * Copyright (C) 2003 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #include #include #include #include // for access, crypt, etc. #include "vmware.h" #include "vm_version.h" #include "codeset.h" #include "posix.h" #include "auth.h" #include "str.h" #include "log.h" #ifdef USE_PAM # include "file.h" # include "config.h" # include "localconfig.h" # if defined __APPLE__ # include # if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5 # include # else # include # endif # else # include # endif # include #endif #if defined(HAVE_CONFIG_H) || defined(sun) # include #endif #define LOGLEVEL_MODULE auth #include "loglevel_user.h" #ifdef USE_PAM #if defined(sun) #define CURRENT_PAM_LIBRARY "libpam.so.1" #elif defined(__FreeBSD__) #define CURRENT_PAM_LIBRARY "libpam.so" #elif defined(__APPLE__) #define CURRENT_PAM_LIBRARY "libpam.dylib" #else #define CURRENT_PAM_LIBRARY "libpam.so.0" #endif static typeof(&pam_start) dlpam_start; static typeof(&pam_end) dlpam_end; static typeof(&pam_authenticate) dlpam_authenticate; static typeof(&pam_setcred) dlpam_setcred; static typeof(&pam_acct_mgmt) dlpam_acct_mgmt; static typeof(&pam_strerror) dlpam_strerror; #if 0 /* These three functions are not used yet */ static typeof(&pam_open_session) dlpam_open_session; static typeof(&pam_close_session) dlpam_close_session; static typeof(&pam_chauthtok) dlpam_chauthtok; #endif static struct { void **procaddr; const char *procname; } authPAMImported[] = { #define IMPORT_SYMBOL(x) { (void **)&dl##x, #x } IMPORT_SYMBOL(pam_start), IMPORT_SYMBOL(pam_end), IMPORT_SYMBOL(pam_authenticate), IMPORT_SYMBOL(pam_setcred), IMPORT_SYMBOL(pam_acct_mgmt), IMPORT_SYMBOL(pam_strerror), #undef IMPORT_SYMBOL }; static void *authPamLibraryHandle = NULL; /* *---------------------------------------------------------------------- * * AuthLoadPAM -- * * Attempt to load and initialize PAM library. * * Results: * FALSE if load and/or initialization failed. * TRUE if initialization succeeded. * * Side effects: * libpam loaded. We never unload - some libpam modules use * syslog() function, and glibc does not survive when arguments * specified to openlog() are freeed from memory. * *---------------------------------------------------------------------- */ static Bool AuthLoadPAM(void) { void *pam_library; int i; if (authPamLibraryHandle) { return TRUE; } pam_library = Posix_Dlopen(CURRENT_PAM_LIBRARY, RTLD_LAZY | RTLD_GLOBAL); if (!pam_library) { #if defined(VMX86_TOOLS) /* * XXX do we even try to configure the pam libraries? * potential nightmare on all the possible guest OSes */ Log("System PAM libraries are unusable: %s\n", dlerror()); return FALSE; #else char *liblocation; char *libdir; libdir = LocalConfig_GetPathName(DEFAULT_LIBDIRECTORY, CONFIG_VMWAREDIR); if (!libdir) { Log("System PAM library unusable and bundled one not found.\n"); return FALSE; } liblocation = Str_SafeAsprintf(NULL, "%s/lib/%s/%s", libdir, CURRENT_PAM_LIBRARY, CURRENT_PAM_LIBRARY); free(libdir); pam_library = Posix_Dlopen(liblocation, RTLD_LAZY | RTLD_GLOBAL); if (!pam_library) { Log("Neither system nor bundled (%s) PAM libraries usable: %s\n", liblocation, dlerror()); free(liblocation); return FALSE; } free(liblocation); #endif } for (i = 0; i < ARRAYSIZE(authPAMImported); i++) { void *symbol = dlsym(pam_library, authPAMImported[i].procname); if (!symbol) { Log("PAM library does not contain required function: %s\n", dlerror()); dlclose(pam_library); return FALSE; } *(authPAMImported[i].procaddr) = symbol; } authPamLibraryHandle = pam_library; Log("PAM up and running.\n"); return TRUE; } static const char *PAM_username; static const char *PAM_password; #if defined(sun) static int PAM_conv (int num_msg, // IN: struct pam_message **msg, // IN: struct pam_response **resp, // OUT: void *appdata_ptr) // IN: #else static int PAM_conv (int num_msg, // IN: const struct pam_message **msg, // IN: struct pam_response **resp, // OUT: void *appdata_ptr) // IN: #endif { int count; struct pam_response *reply = calloc(num_msg, sizeof(struct pam_response)); if (!reply) { return PAM_CONV_ERR; } for (count = 0; count < num_msg; count++) { switch (msg[count]->msg_style) { case PAM_PROMPT_ECHO_ON: reply[count].resp_retcode = PAM_SUCCESS; reply[count].resp = PAM_username ? strdup(PAM_username) : NULL; /* PAM frees resp */ break; case PAM_PROMPT_ECHO_OFF: reply[count].resp_retcode = PAM_SUCCESS; reply[count].resp = PAM_password ? strdup(PAM_password) : NULL; /* PAM frees resp */ break; case PAM_TEXT_INFO: reply[count].resp_retcode = PAM_SUCCESS; reply[count].resp = NULL; /* ignore it... */ break; case PAM_ERROR_MSG: reply[count].resp_retcode = PAM_SUCCESS; reply[count].resp = NULL; /* Must be an error of some sort... */ default: while (--count >= 0) { free(reply[count].resp); } free(reply); return PAM_CONV_ERR; } } *resp = reply; return PAM_SUCCESS; } static struct pam_conv PAM_conversation = { &PAM_conv, NULL }; #endif /* USE_PAM */ /* *---------------------------------------------------------------------- * * Auth_AuthenticateUser -- * * Accept username/password And verfiy it * * Side effects: * None. * * Results: * * The vmauthToken for the authenticated user, or NULL if * authentication failed. * *---------------------------------------------------------------------- */ AuthToken Auth_AuthenticateUser(const char *user, // IN: const char *pass) // IN: { struct passwd *pwd; #ifdef USE_PAM pam_handle_t *pamh; int pam_error; #endif if (!CodeSet_Validate(user, strlen(user), "UTF-8")) { Log("User not in UTF-8\n"); return NULL; } if (!CodeSet_Validate(pass, strlen(pass), "UTF-8")) { Log("Password not in UTF-8\n"); return NULL; } #ifdef USE_PAM if (!AuthLoadPAM()) { return NULL; } /* * XXX PAM can blow away our syslog level settings so we need * to call Log_InitEx() again before doing any more Log()s */ #define PAM_BAIL if (pam_error != PAM_SUCCESS) { \ Log_Error("%s:%d: PAM failure - %s (%d)\n", \ __FUNCTION__, __LINE__, \ dlpam_strerror(pamh, pam_error), pam_error); \ dlpam_end(pamh, pam_error); \ return NULL; \ } PAM_username = user; PAM_password = pass; #if defined(VMX86_TOOLS) pam_error = dlpam_start("vmtoolsd", PAM_username, &PAM_conversation, &pamh); #else pam_error = dlpam_start("vmware-authd", PAM_username, &PAM_conversation, &pamh); #endif if (pam_error != PAM_SUCCESS) { Log("Failed to start PAM (error = %d).\n", pam_error); return NULL; } pam_error = dlpam_authenticate(pamh, 0); PAM_BAIL; pam_error = dlpam_acct_mgmt(pamh, 0); PAM_BAIL; pam_error = dlpam_setcred(pamh, PAM_ESTABLISH_CRED); PAM_BAIL; dlpam_end(pamh, PAM_SUCCESS); /* If this point is reached, the user has been authenticated. */ setpwent(); pwd = Posix_Getpwnam(user); endpwent(); #else /* !USE_PAM */ /* All of the following issues are dealt with in the PAM configuration file, so put all authentication/priviledge checks before the corresponding #endif below. */ setpwent(); //XXX can kill? pwd = Posix_Getpwnam(user); endpwent(); //XXX can kill? if (!pwd) { // No such user return NULL; } if (*pwd->pw_passwd != '\0') { char *namep = (char *) crypt(pass, pwd->pw_passwd); if (strcmp(namep, pwd->pw_passwd) != 0) { // Incorrect password return NULL; } // Clear out crypt()'s internal state, too. crypt("glurp", pwd->pw_passwd); } #endif /* !USE_PAM */ return pwd; } /* *---------------------------------------------------------------------- * * Auth_CloseToken -- * * Do nothing. * * Side effects: * None * * Results: * None * *---------------------------------------------------------------------- */ void Auth_CloseToken(AuthToken token) // IN: { } open-vm-tools-9.4.0-1280544/lib/auth/Makefile.in0000644765153500003110000004354312220061621017215 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/auth DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libAuth_la_LIBADD = am_libAuth_la_OBJECTS = authPosix.lo libAuth_la_OBJECTS = $(am_libAuth_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libAuth_la_SOURCES) DIST_SOURCES = $(libAuth_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libAuth.la libAuth_la_SOURCES = authPosix.c AM_CFLAGS = @LIB_AUTH_CPPFLAGS@ all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/auth/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/auth/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libAuth.la: $(libAuth_la_OBJECTS) $(libAuth_la_DEPENDENCIES) $(EXTRA_libAuth_la_DEPENDENCIES) $(LINK) $(libAuth_la_OBJECTS) $(libAuth_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/authPosix.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/backdoor/0000755765153500003110000000000012220061621015762 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/backdoor/backdoorGcc32.c0000644765153500003110000001515112220061556020506 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * backdoorGcc32.c -- * * Implements the real work for guest-side backdoor for GCC, 32-bit * target (supports inline ASM, GAS syntax). The asm sections are marked * volatile since vmware can change the registers content without the * compiler knowing it. * * XXX * I tried to write this more cleanly, but: * - There is no way to specify an "ebp" constraint * - "ebp" is ignored when specified as cloberred register * - gas barfs when there is more than 10 operands * - gas 2.7.2.3, depending on the order of the operands, can * mis-assemble without any warning * --hpreg * * Note that the problems with gas noted above might longer be relevant * now that we've upgraded most of our compiler versions. * --rrdharan */ #ifdef __cplusplus extern "C" { #endif #include "backdoor.h" #include "backdoorInt.h" /* *---------------------------------------------------------------------------- * * Backdoor_InOut -- * * Send a low-bandwidth basic request (16 bytes) to vmware, and return its * reply (24 bytes). * * Results: * Host-side response returned in bp IN/OUT parameter. * * Side effects: * Pokes the backdoor. * *---------------------------------------------------------------------------- */ void Backdoor_InOut(Backdoor_proto *myBp) // IN/OUT { uint32 dummy; __asm__ __volatile__( #ifdef __PIC__ "pushl %%ebx" "\n\t" #endif "pushl %%eax" "\n\t" "movl 20(%%eax), %%edi" "\n\t" "movl 16(%%eax), %%esi" "\n\t" "movl 12(%%eax), %%edx" "\n\t" "movl 8(%%eax), %%ecx" "\n\t" "movl 4(%%eax), %%ebx" "\n\t" "movl (%%eax), %%eax" "\n\t" "inl %%dx, %%eax" "\n\t" "xchgl %%eax, (%%esp)" "\n\t" "movl %%edi, 20(%%eax)" "\n\t" "movl %%esi, 16(%%eax)" "\n\t" "movl %%edx, 12(%%eax)" "\n\t" "movl %%ecx, 8(%%eax)" "\n\t" "movl %%ebx, 4(%%eax)" "\n\t" "popl (%%eax)" "\n\t" #ifdef __PIC__ "popl %%ebx" "\n\t" #endif : "=a" (dummy) : "0" (myBp) /* * vmware can modify the whole VM state without the compiler knowing * it. So far it does not modify EFLAGS. --hpreg */ : #ifndef __PIC__ "ebx", #endif "ecx", "edx", "esi", "edi", "memory" ); } /* *----------------------------------------------------------------------------- * * BackdoorHbIn -- * BackdoorHbOut -- * * Send a high-bandwidth basic request to vmware, and return its * reply. * * Results: * Host-side response returned in bp IN/OUT parameter. * * Side-effects: * Pokes the high-bandwidth backdoor port. * *----------------------------------------------------------------------------- */ void BackdoorHbIn(Backdoor_proto_hb *myBp) // IN/OUT { uint32 dummy; __asm__ __volatile__( #ifdef __PIC__ "pushl %%ebx" "\n\t" #endif "pushl %%ebp" "\n\t" "pushl %%eax" "\n\t" "movl 24(%%eax), %%ebp" "\n\t" "movl 20(%%eax), %%edi" "\n\t" "movl 16(%%eax), %%esi" "\n\t" "movl 12(%%eax), %%edx" "\n\t" "movl 8(%%eax), %%ecx" "\n\t" "movl 4(%%eax), %%ebx" "\n\t" "movl (%%eax), %%eax" "\n\t" "cld" "\n\t" "rep; insb" "\n\t" "xchgl %%eax, (%%esp)" "\n\t" "movl %%ebp, 24(%%eax)" "\n\t" "movl %%edi, 20(%%eax)" "\n\t" "movl %%esi, 16(%%eax)" "\n\t" "movl %%edx, 12(%%eax)" "\n\t" "movl %%ecx, 8(%%eax)" "\n\t" "movl %%ebx, 4(%%eax)" "\n\t" "popl (%%eax)" "\n\t" "popl %%ebp" "\n\t" #ifdef __PIC__ "popl %%ebx" "\n\t" #endif : "=a" (dummy) : "0" (myBp) /* * vmware can modify the whole VM state without the compiler knowing * it. --hpreg */ : #ifndef __PIC__ "ebx", #endif "ecx", "edx", "esi", "edi", "memory", "cc" ); } void BackdoorHbOut(Backdoor_proto_hb *myBp) // IN/OUT { uint32 dummy; __asm__ __volatile__( #ifdef __PIC__ "pushl %%ebx" "\n\t" #endif "pushl %%ebp" "\n\t" "pushl %%eax" "\n\t" "movl 24(%%eax), %%ebp" "\n\t" "movl 20(%%eax), %%edi" "\n\t" "movl 16(%%eax), %%esi" "\n\t" "movl 12(%%eax), %%edx" "\n\t" "movl 8(%%eax), %%ecx" "\n\t" "movl 4(%%eax), %%ebx" "\n\t" "movl (%%eax), %%eax" "\n\t" "cld" "\n\t" "rep; outsb" "\n\t" "xchgl %%eax, (%%esp)" "\n\t" "movl %%ebp, 24(%%eax)" "\n\t" "movl %%edi, 20(%%eax)" "\n\t" "movl %%esi, 16(%%eax)" "\n\t" "movl %%edx, 12(%%eax)" "\n\t" "movl %%ecx, 8(%%eax)" "\n\t" "movl %%ebx, 4(%%eax)" "\n\t" "popl (%%eax)" "\n\t" "popl %%ebp" "\n\t" #ifdef __PIC__ "popl %%ebx" "\n\t" #endif : "=a" (dummy) : "0" (myBp) : #ifndef __PIC__ "ebx", #endif "ecx", "edx", "esi", "edi", "memory", "cc" ); } #ifdef __cplusplus } #endif open-vm-tools-9.4.0-1280544/lib/backdoor/backdoorInt.h0000644765153500003110000000312312220061556020400 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * backdoorInt.h -- * * Internal function prototypes for the real backdoor work. */ void BackdoorHbIn(Backdoor_proto_hb *bp); void BackdoorHbOut(Backdoor_proto_hb *bp); open-vm-tools-9.4.0-1280544/lib/backdoor/Makefile.am0000644765153500003110000000213212220061556020023 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libBackdoor.la libBackdoor_la_SOURCES = libBackdoor_la_SOURCES += backdoor.c if THIRTY_TWO_BIT_USERSPACE libBackdoor_la_SOURCES += backdoorGcc32.c else libBackdoor_la_SOURCES += backdoorGcc64.c endif open-vm-tools-9.4.0-1280544/lib/backdoor/backdoorGcc64.c0000644765153500003110000001641712220061556020521 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * backdoorGcc64.c -- * * Implements the real work for guest-side backdoor for GCC, 64-bit * target (supports inline ASM, GAS syntax). The asm sections are marked * volatile since vmware can change the registers content without the * compiler knowing it. * * See backdoorGCC32.c (from which this code was mostly copied) for * details on why the ASM is written this way. Also note that it might be * possible to write the asm blocks using the symbolic operand specifiers * in such a way that the same asm would generate correct code for both * 32-bit and 64-bit targets, but I'm too lazy to figure it all out. * --rrdharan */ #ifdef __cplusplus extern "C" { #endif #include "backdoor.h" #include "backdoorInt.h" /* *---------------------------------------------------------------------------- * * Backdoor_InOut -- * * Send a low-bandwidth basic request (16 bytes) to vmware, and return its * reply (24 bytes). * * Results: * Host-side response returned in bp IN/OUT parameter. * * Side effects: * Pokes the backdoor. * *---------------------------------------------------------------------------- */ void Backdoor_InOut(Backdoor_proto *myBp) // IN/OUT { uint64 dummy; __asm__ __volatile__( #ifdef __APPLE__ /* * Save %rbx on the stack because the Mac OS GCC doesn't want us to * clobber it - it erroneously thinks %rbx is the PIC register. * (Radar bug 7304232) */ "pushq %%rbx" "\n\t" #endif "pushq %%rax" "\n\t" "movq 40(%%rax), %%rdi" "\n\t" "movq 32(%%rax), %%rsi" "\n\t" "movq 24(%%rax), %%rdx" "\n\t" "movq 16(%%rax), %%rcx" "\n\t" "movq 8(%%rax), %%rbx" "\n\t" "movq (%%rax), %%rax" "\n\t" "inl %%dx, %%eax" "\n\t" /* NB: There is no inq instruction */ "xchgq %%rax, (%%rsp)" "\n\t" "movq %%rdi, 40(%%rax)" "\n\t" "movq %%rsi, 32(%%rax)" "\n\t" "movq %%rdx, 24(%%rax)" "\n\t" "movq %%rcx, 16(%%rax)" "\n\t" "movq %%rbx, 8(%%rax)" "\n\t" "popq (%%rax)" "\n\t" #ifdef __APPLE__ "popq %%rbx" "\n\t" #endif : "=a" (dummy) : "0" (myBp) /* * vmware can modify the whole VM state without the compiler knowing * it. So far it does not modify EFLAGS. --hpreg */ : #ifndef __APPLE__ /* %rbx is unchanged at the end of the function on Mac OS. */ "rbx", #endif "rcx", "rdx", "rsi", "rdi", "memory" ); } /* *----------------------------------------------------------------------------- * * BackdoorHbIn -- * BackdoorHbOut -- * * Send a high-bandwidth basic request to vmware, and return its * reply. * * Results: * Host-side response returned in bp IN/OUT parameter. * * Side-effects: * Pokes the high-bandwidth backdoor port. * *----------------------------------------------------------------------------- */ void BackdoorHbIn(Backdoor_proto_hb *myBp) // IN/OUT { uint64 dummy; __asm__ __volatile__( "pushq %%rbp" "\n\t" #ifdef __APPLE__ /* * Save %rbx on the stack because the Mac OS GCC doesn't want us to * clobber it - it erroneously thinks %rbx is the PIC register. * (Radar bug 7304232) */ "pushq %%rbx" "\n\t" #endif "pushq %%rax" "\n\t" "movq 48(%%rax), %%rbp" "\n\t" "movq 40(%%rax), %%rdi" "\n\t" "movq 32(%%rax), %%rsi" "\n\t" "movq 24(%%rax), %%rdx" "\n\t" "movq 16(%%rax), %%rcx" "\n\t" "movq 8(%%rax), %%rbx" "\n\t" "movq (%%rax), %%rax" "\n\t" "cld" "\n\t" "rep; insb" "\n\t" "xchgq %%rax, (%%rsp)" "\n\t" "movq %%rbp, 48(%%rax)" "\n\t" "movq %%rdi, 40(%%rax)" "\n\t" "movq %%rsi, 32(%%rax)" "\n\t" "movq %%rdx, 24(%%rax)" "\n\t" "movq %%rcx, 16(%%rax)" "\n\t" "movq %%rbx, 8(%%rax)" "\n\t" "popq (%%rax)" "\n\t" #ifdef __APPLE__ "popq %%rbx" "\n\t" #endif "popq %%rbp" : "=a" (dummy) : "0" (myBp) /* * vmware can modify the whole VM state without the compiler knowing * it. --hpreg */ : #ifndef __APPLE__ /* %rbx is unchanged at the end of the function on Mac OS. */ "rbx", #endif "rcx", "rdx", "rsi", "rdi", "memory", "cc" ); } void BackdoorHbOut(Backdoor_proto_hb *myBp) // IN/OUT { uint64 dummy; __asm__ __volatile__( "pushq %%rbp" "\n\t" #ifdef __APPLE__ /* * Save %rbx on the stack because the Mac OS GCC doesn't want us to * clobber it - it erroneously thinks %rbx is the PIC register. * (Radar bug 7304232) */ "pushq %%rbx" "\n\t" #endif "pushq %%rax" "\n\t" "movq 48(%%rax), %%rbp" "\n\t" "movq 40(%%rax), %%rdi" "\n\t" "movq 32(%%rax), %%rsi" "\n\t" "movq 24(%%rax), %%rdx" "\n\t" "movq 16(%%rax), %%rcx" "\n\t" "movq 8(%%rax), %%rbx" "\n\t" "movq (%%rax), %%rax" "\n\t" "cld" "\n\t" "rep; outsb" "\n\t" "xchgq %%rax, (%%rsp)" "\n\t" "movq %%rbp, 48(%%rax)" "\n\t" "movq %%rdi, 40(%%rax)" "\n\t" "movq %%rsi, 32(%%rax)" "\n\t" "movq %%rdx, 24(%%rax)" "\n\t" "movq %%rcx, 16(%%rax)" "\n\t" "movq %%rbx, 8(%%rax)" "\n\t" "popq (%%rax)" "\n\t" #ifdef __APPLE__ "popq %%rbx" "\n\t" #endif "popq %%rbp" : "=a" (dummy) : "0" (myBp) : #ifndef __APPLE__ /* %rbx is unchanged at the end of the function on Mac OS. */ "rbx", #endif "rcx", "rdx", "rsi", "rdi", "memory", "cc" ); } #ifdef __cplusplus } #endif open-vm-tools-9.4.0-1280544/lib/backdoor/Makefile.in0000644765153500003110000004467412220061621020046 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @THIRTY_TWO_BIT_USERSPACE_TRUE@am__append_1 = backdoorGcc32.c @THIRTY_TWO_BIT_USERSPACE_FALSE@am__append_2 = backdoorGcc64.c subdir = lib/backdoor DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libBackdoor_la_LIBADD = am__libBackdoor_la_SOURCES_DIST = backdoor.c backdoorGcc32.c \ backdoorGcc64.c @THIRTY_TWO_BIT_USERSPACE_TRUE@am__objects_1 = backdoorGcc32.lo @THIRTY_TWO_BIT_USERSPACE_FALSE@am__objects_2 = backdoorGcc64.lo am_libBackdoor_la_OBJECTS = backdoor.lo $(am__objects_1) \ $(am__objects_2) libBackdoor_la_OBJECTS = $(am_libBackdoor_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libBackdoor_la_SOURCES) DIST_SOURCES = $(am__libBackdoor_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libBackdoor.la libBackdoor_la_SOURCES = backdoor.c $(am__append_1) $(am__append_2) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/backdoor/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/backdoor/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libBackdoor.la: $(libBackdoor_la_OBJECTS) $(libBackdoor_la_DEPENDENCIES) $(EXTRA_libBackdoor_la_DEPENDENCIES) $(LINK) $(libBackdoor_la_OBJECTS) $(libBackdoor_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backdoor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backdoorGcc32.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backdoorGcc64.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/backdoor/backdoor.c0000644765153500003110000001547112220061556017731 0ustar dtormts/********************************************************* * Copyright (C) 1999 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * backdoor.c -- * * First layer of the internal communication channel between guest * applications and vmware * * This is the backdoor. By using special ports of the virtual I/O space, * and the virtual CPU registers, a guest application can send a * synchroneous basic request to vmware, and vmware can reply to it. */ #ifdef __cplusplus extern "C" { #endif #include "backdoor_def.h" #include "backdoor.h" #include "backdoorInt.h" #if defined(BACKDOOR_DEBUG) && defined(USERLEVEL) #if defined(__KERNEL__) || defined(_KERNEL) #else # include "debug.h" #endif # include # define BACKDOOR_LOG(args) Debug args # define BACKDOOR_LOG_PROTO_STRUCT(x) BackdoorPrintProtoStruct((x)) # define BACKDOOR_LOG_HB_PROTO_STRUCT(x) BackdoorPrintHbProtoStruct((x)) /* *---------------------------------------------------------------------------- * * BackdoorPrintProtoStruct -- * BackdoorPrintHbProtoStruct -- * * Print the contents of the specified backdoor protocol structure via * printf. * * Results: * None. * * Side effects: * Output to stdout. * *---------------------------------------------------------------------------- */ void BackdoorPrintProtoStruct(Backdoor_proto *myBp) { Debug("magic 0x%08x, command %d, size %"FMTSZ"u, port %d\n", myBp->in.ax.word, myBp->in.cx.halfs.low, myBp->in.size, myBp->in.dx.halfs.low); #ifndef VM_X86_64 Debug("ax %#x, " "bx %#x, " "cx %#x, " "dx %#x, " "si %#x, " "di %#x\n", myBp->out.ax.word, myBp->out.bx.word, myBp->out.cx.word, myBp->out.dx.word, myBp->out.si.word, myBp->out.di.word); #else Debug("ax %#"FMT64"x, " "bx %#"FMT64"x, " "cx %#"FMT64"x, " "dx %#"FMT64"x, " "si %#"FMT64"x, " "di %#"FMT64"x\n", myBp->out.ax.quad, myBp->out.bx.quad, myBp->out.cx.quad, myBp->out.dx.quad, myBp->out.si.quad, myBp->out.di.quad); #endif } void BackdoorPrintHbProtoStruct(Backdoor_proto_hb *myBp) { Debug("magic 0x%08x, command %d, size %"FMTSZ"u, port %d, " "srcAddr %"FMTSZ"u, dstAddr %"FMTSZ"u\n", myBp->in.ax.word, myBp->in.bx.halfs.low, myBp->in.size, myBp->in.dx.halfs.low, myBp->in.srcAddr, myBp->in.dstAddr); #ifndef VM_X86_64 Debug("ax %#x, " "bx %#x, " "cx %#x, " "dx %#x, " "si %#x, " "di %#x, " "bp %#x\n", myBp->out.ax.word, myBp->out.bx.word, myBp->out.cx.word, myBp->out.dx.word, myBp->out.si.word, myBp->out.di.word, myBp->out.bp.word); #else Debug("ax %#"FMT64"x, " "bx %#"FMT64"x, " "cx %#"FMT64"x, " "dx %#"FMT64"x, " "si %#"FMT64"x, " "di %#"FMT64"x, " "bp %#"FMT64"x\n", myBp->out.ax.quad, myBp->out.bx.quad, myBp->out.cx.quad, myBp->out.dx.quad, myBp->out.si.quad, myBp->out.di.quad, myBp->out.bp.quad); #endif } #else # define BACKDOOR_LOG(args) # define BACKDOOR_LOG_PROTO_STRUCT(x) # define BACKDOOR_LOG_HB_PROTO_STRUCT(x) #endif /* *----------------------------------------------------------------------------- * * Backdoor -- * * Send a low-bandwidth basic request (16 bytes) to vmware, and return its * reply (24 bytes). * * Result: * None * * Side-effects: * None * *----------------------------------------------------------------------------- */ void Backdoor(Backdoor_proto *myBp) // IN/OUT { ASSERT(myBp); myBp->in.ax.word = BDOOR_MAGIC; myBp->in.dx.halfs.low = BDOOR_PORT; BACKDOOR_LOG(("Backdoor: before ")); BACKDOOR_LOG_PROTO_STRUCT(myBp); Backdoor_InOut(myBp); BACKDOOR_LOG(("Backdoor: after ")); BACKDOOR_LOG_PROTO_STRUCT(myBp); } /* *----------------------------------------------------------------------------- * * Backdoor_HbOut -- * * Send a high-bandwidth basic request to vmware, and return its * reply. * * Result: * The host-side response is returned via the IN/OUT parameter. * * Side-effects: * Pokes the high-bandwidth backdoor. * *----------------------------------------------------------------------------- */ void Backdoor_HbOut(Backdoor_proto_hb *myBp) // IN/OUT { ASSERT(myBp); myBp->in.ax.word = BDOOR_MAGIC; myBp->in.dx.halfs.low = BDOORHB_PORT; BACKDOOR_LOG(("Backdoor_HbOut: before ")); BACKDOOR_LOG_HB_PROTO_STRUCT(myBp); BackdoorHbOut(myBp); BACKDOOR_LOG(("Backdoor_HbOut: after ")); BACKDOOR_LOG_HB_PROTO_STRUCT(myBp); } /* *----------------------------------------------------------------------------- * * Backdoor_HbIn -- * * Send a basic request to vmware, and return its high-bandwidth * reply * * Result: * Host-side response returned via the IN/OUT parameter. * * Side-effects: * Pokes the high-bandwidth backdoor. * *----------------------------------------------------------------------------- */ void Backdoor_HbIn(Backdoor_proto_hb *myBp) // IN/OUT { ASSERT(myBp); myBp->in.ax.word = BDOOR_MAGIC; myBp->in.dx.halfs.low = BDOORHB_PORT; BACKDOOR_LOG(("Backdoor_HbIn: before ")); BACKDOOR_LOG_HB_PROTO_STRUCT(myBp); BackdoorHbIn(myBp); BACKDOOR_LOG(("Backdoor_HbIn: after ")); BACKDOOR_LOG_HB_PROTO_STRUCT(myBp); } #ifdef __cplusplus } #endif open-vm-tools-9.4.0-1280544/lib/guestApp/0000755765153500003110000000000012220061622015767 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/guestApp/Makefile.am0000644765153500003110000000173212220061556020034 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libGuestApp.la libGuestApp_la_SOURCES = libGuestApp_la_SOURCES += guestApp.c open-vm-tools-9.4.0-1280544/lib/guestApp/guestApp.c0000644765153500003110000001671312220061556017741 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * guestApp.c -- * * Utility functions common to all guest applications */ #include #include #include #include "vmware.h" #include "vm_version.h" #include "vm_tools_version.h" #include "guestApp.h" #include "backdoor.h" #include "backdoor_def.h" #include "conf.h" #include "rpcout.h" #include "debug.h" #include "strutil.h" #include "str.h" #include "msg.h" #include "file.h" #include "posix.h" #include "vmware/guestrpc/tclodefs.h" #ifdef _MSC_VER #include #include #include "productState.h" #include "winregistry.h" #include "win32util.h" #endif /* * For Netware/Linux/BSD/Solaris, the install path * is the hardcoded value below. For Windows, it is * determined dynamically in GuestApp_GetInstallPath(), * so the empty string here is just for completeness. */ #if defined _WIN32 # define GUESTAPP_TOOLS_INSTALL_PATH "" #elif defined __APPLE__ # define GUESTAPP_TOOLS_INSTALL_PATH "/Library/Application Support/VMware Tools" #else # define GUESTAPP_TOOLS_INSTALL_PATH "/etc/vmware-tools" #endif /* *----------------------------------------------------------------------------- * * GuestApp_GetDefaultScript -- * * Returns the default power script for the given configuration option. * * Results: * Script name on success, NULL of the option is not recognized. * * Side effects: * None. * *----------------------------------------------------------------------------- */ const char * GuestApp_GetDefaultScript(const char *confName) // IN { const char *value = NULL; if (strcmp(confName, CONFNAME_SUSPENDSCRIPT) == 0) { value = CONFVAL_SUSPENDSCRIPT_DEFAULT; } else if (strcmp(confName, CONFNAME_RESUMESCRIPT) == 0) { value = CONFVAL_RESUMESCRIPT_DEFAULT; } else if (strcmp(confName, CONFNAME_POWEROFFSCRIPT) == 0) { value = CONFVAL_POWEROFFSCRIPT_DEFAULT; } else if (strcmp(confName, CONFNAME_POWERONSCRIPT) == 0) { value = CONFVAL_POWERONSCRIPT_DEFAULT; } return value; } #ifdef _WIN32 /* *------------------------------------------------------------------------------ * * GuestApp_GetInstallPathW -- * * Returns the tools installation path as a UTF-16 encoded string, or NULL on * error. The caller must deallocate the returned string using free. * * Results: * See above. * * Side effects: * None. *------------------------------------------------------------------------------ */ LPWSTR GuestApp_GetInstallPathW(void) { static LPCWSTR TOOLS_KEY_NAME = L"Software\\VMware, Inc.\\VMware Tools"; static LPCWSTR INSTALLPATH_VALUE_NAME = L"InstallPath"; HKEY key = NULL; LONG rc = ERROR_SUCCESS; DWORD cbData = 0; DWORD temp = 0; PWCHAR data = NULL; rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, TOOLS_KEY_NAME, 0, KEY_READ, &key); if (ERROR_SUCCESS != rc) { Debug("%s: Couldn't open key \"%S\".\n", __FUNCTION__, TOOLS_KEY_NAME); Debug("%s: RegOpenKeyExW error 0x%x.\n", __FUNCTION__, GetLastError()); goto exit; } rc = RegQueryValueExW(key, INSTALLPATH_VALUE_NAME, 0, NULL, NULL, &cbData); if (ERROR_SUCCESS != rc) { Debug("%s: Couldn't get length of value \"%S\".\n", __FUNCTION__, INSTALLPATH_VALUE_NAME); Debug("%s: RegQueryValueExW error 0x%x.\n", __FUNCTION__, GetLastError()); goto exit; } /* * The data in the registry may not be null terminated. So allocate enough * space for one extra WCHAR and use that space to write our own NULL. */ data = (LPWSTR) malloc(cbData + sizeof(WCHAR)); if (NULL == data) { Debug("%s: Couldn't allocate %d bytes.\n", __FUNCTION__, cbData); goto exit; } temp = cbData; rc = RegQueryValueExW(key, INSTALLPATH_VALUE_NAME, 0, NULL, (LPBYTE) data, &temp); if (ERROR_SUCCESS != rc) { Debug("%s: Couldn't get data for value \"%S\".\n", __FUNCTION__, INSTALLPATH_VALUE_NAME); Debug("%s: RegQueryValueExW error 0x%x.\n", __FUNCTION__, GetLastError()); goto exit; } data[cbData / sizeof(WCHAR)] = L'\0'; exit: if (NULL != key) { RegCloseKey(key); } return data; } #endif /* *---------------------------------------------------------------------- * * GuestApp_GetInstallPath -- * * Get the tools installation path. The caller is responsible for * freeing the memory allocated for the path. * * Results: * The path in UTF-8 if successful. * NULL otherwise. * * Side effects: * Allocates memory. * *---------------------------------------------------------------------- */ char * GuestApp_GetInstallPath(void) { char *pathUtf8 = NULL; #if defined(_WIN32) size_t pathLen = 0; if (WinReg_GetSZ(HKEY_LOCAL_MACHINE, CONF_VMWARE_TOOLS_REGKEY, "InstallPath", &pathUtf8) != ERROR_SUCCESS) { Warning("%s: Unable to retrieve install path: %s\n", __FUNCTION__, Msg_ErrString()); return NULL; } /* Strip off the trailing backslash, if present */ pathLen = strlen(pathUtf8); if (pathLen > 0) { if (pathUtf8[pathLen - 1] == '\\') { pathUtf8[pathLen - 1] = '\0'; } } #else pathUtf8 = Str_Asprintf(NULL, "%s", GUESTAPP_TOOLS_INSTALL_PATH); #endif return pathUtf8; } /* *---------------------------------------------------------------------- * * GuestApp_GetConfPath -- * * Get the path to the Tools configuration file. * * The return conf path is a dynamically allocated UTF-8 encoded * string that should be freed by the caller. * * However, the function will also return NULL if we fail to create * a "VMware/VMware Tools" directory. This can occur if we're not running * as Administrator, which VMwareUser doesn't. But I believe that * VMwareService will always come up before VMwareUser, so by the time * a non-root user process calls this function, the directory exists. * * Results: * The path in UTF-8, or NULL on failure. * * Side effects: * Allocates memory. * *---------------------------------------------------------------------- */ char * GuestApp_GetConfPath(void) { #if defined(_WIN32) char *path = W32Util_GetVmwareCommonAppDataFilePath(NULL); if (path != NULL) { char *tmp = Str_SafeAsprintf(NULL, "%s%c%s", path, DIRSEPC, ProductState_GetName()); free(path); path = tmp; if (!File_EnsureDirectory(path)) { free(path); path = NULL; } } return path; #else /* Just call into GuestApp_GetInstallPath. */ return GuestApp_GetInstallPath(); #endif } open-vm-tools-9.4.0-1280544/lib/guestApp/Makefile.in0000644765153500003110000004360412220061622020043 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/guestApp DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libGuestApp_la_LIBADD = am_libGuestApp_la_OBJECTS = guestApp.lo libGuestApp_la_OBJECTS = $(am_libGuestApp_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libGuestApp_la_SOURCES) DIST_SOURCES = $(libGuestApp_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libGuestApp.la libGuestApp_la_SOURCES = guestApp.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/guestApp/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/guestApp/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libGuestApp.la: $(libGuestApp_la_OBJECTS) $(libGuestApp_la_DEPENDENCIES) $(EXTRA_libGuestApp_la_DEPENDENCIES) $(LINK) $(libGuestApp_la_OBJECTS) $(libGuestApp_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/guestApp.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/dict/0000755765153500003110000000000012220061621015121 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/dict/Makefile.am0000644765153500003110000000171212220061556017165 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libDict.la libDict_la_SOURCES = libDict_la_SOURCES += dictll.c open-vm-tools-9.4.0-1280544/lib/dict/dictll.c0000644765153500003110000003655712220061556016567 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * dictll.c -- * * Low-level dictionary format --hpreg */ #include #include #include #include #include "vmware.h" #include "vmstdio.h" #include "escape.h" #include "dictll.h" #include "util.h" #define UTF8_BOM "\xEF\xBB\xBF" /* Duplicate a buffer --hpreg. The result is NUL-terminated */ static void * BufDup(void const * const bufIn, // IN: buffer to duplicate unsigned int const sizeIn) // IN: buffer size in bytes { char *bufOut; ASSERT(bufIn); bufOut = Util_SafeMalloc(sizeIn + 1); memcpy(bufOut, bufIn, sizeIn); bufOut[sizeIn] = '\0'; return bufOut; } /* *----------------------------------------------------------------------------- * * Walk -- * * While 'bufIn' points to a byte in 'sentinel', increment it --hpreg * * Note: * If your 'bufIn' is a NUL-terminated C string, you should rather make sure * that the NUL byte is not in your 'sentinel' * * Results: * The new 'buf' * * Side effects: * None * *----------------------------------------------------------------------------- */ static void const * Walk(void const * const bufIn, // IN int const * const sentinel) // IN { char const *buf; buf = (char const *)bufIn; ASSERT(buf); /* Unsigned does matter --hpreg */ while (sentinel[(unsigned char)*buf]) { buf++; } return buf; } /* XXX document the escaping/unescaping process: rationale for which chars we escape, and how we escape --hpreg */ /* * The dictionary line format: * * = * or * = " " * * where * does not contain any whitespace or = or # * does not contain any double-quote or # * does not contain any double-quote * begins with # and ends at the end of the line * is a sequence spaces and/or tabs * and are optional */ /* *----------------------------------------------------------------------------- * * DictLL_UnmarshalLine -- * * Reads a line from the bufSize-byte buffer buf, which holds one or more * new-line delimited lines. The buffer is not necessarily * null-terminated. * * Results: * The beginning of the next line if a line was successfully parsed. In * that case, '*line' is the allocated line. If the line is well-formed, * then '*name' and '*value' are allocated strings. Otherwise they are * both NULL. * * A null pointer at the end of the buffer, in which case *line, *name, * and *value are set to null pointers. * * Side effects: * Advances *buf to the beginning of the next line. * *----------------------------------------------------------------------------- */ const char * DictLL_UnmarshalLine(const char *buf, // IN: buffer to parse size_t bufSize, // IN: buffer size in bytes char **line, // OUT: malloc()'d entire line char **name, // OUT: malloc()'d name or NULL char **value) // OUT: malloc()'d value or NULL { /* Space and tab --hpreg */ static int const ws_in[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 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, 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, 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, }; /* Everything but NUL, space, tab and pound --hpreg */ static int const wsp_out[] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; /* Everything but NUL, space, tab, pound and equal --hpreg */ static int const wspe_out[] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; /* Everything but NUL and double quote --hpreg */ static int const q_out[] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; char const *nBegin; char const *nEnd; char const *vBegin; char const *vEnd; char const *tmp; char *myLine; char *myName; char *myValue; const char *lineEnd; const char *nextLine; ASSERT(buf); ASSERT(line); ASSERT(name); ASSERT(value); /* Check for end of buffer. */ if (bufSize == 0) { *line = NULL; *name = NULL; *value = NULL; return NULL; } /* Find end of this line, beginning of next. */ lineEnd = memchr(buf, '\n', bufSize); if (lineEnd != NULL) { nextLine = lineEnd + 1; } else { nextLine = lineEnd = buf + bufSize; } /* Make local copy of line. */ myLine = BufDup(buf, lineEnd - buf); /* Check if the line is well-formed --hpreg */ nBegin = Walk(myLine, ws_in); nEnd = Walk(nBegin, wspe_out); tmp = Walk(nEnd, ws_in); if (nBegin == nEnd || *tmp != '=') { goto weird; } tmp++; tmp = Walk(tmp, ws_in); if (*tmp == '"') { tmp++; vBegin = tmp; vEnd = Walk(vBegin, q_out); tmp = vEnd; if (*tmp != '"') { goto weird; } tmp++; } else { vBegin = tmp; vEnd = Walk(vBegin, wsp_out); tmp = vEnd; } tmp = Walk(tmp, ws_in); if (*tmp != '\0' && *tmp != '#') { goto weird; } /* The line is well-formed. Extract the name and value --hpreg */ myName = BufDup(nBegin, nEnd - nBegin); myValue = Escape_Undo('|', vBegin, vEnd - vBegin, NULL); ASSERT_MEM_ALLOC(myValue); *line = myLine; *name = myName; *value = myValue; return nextLine; weird: /* The line is not well-formed. Let the upper layers handle it --hpreg */ *line = myLine; *name = NULL; *value = NULL; return nextLine; } /* *----------------------------------------------------------------------------- * * DictLL_ReadLine -- * * Read the next line from a dictionary file --hpreg * * Results: * 2 on success: '*line' is the allocated line * If the line is well-formed, then '*name' and '*value' are * allocated strings. Otherwise they are both NULL. * 1 if there is no next line (end of stream) * 0 on failure: errno is set accordingly * * Side effects: * None * *----------------------------------------------------------------------------- */ int DictLL_ReadLine(FILE *stream, // IN: stream to read char **line, // OUT: malloc()'d line or null pointer char **name, // OUT: malloc()'d name or null pointer char **value) // OUT: malloc()'d value or null pointer { char *myLine; size_t myLineLen; ASSERT(stream); ASSERT(line); ASSERT(name); ASSERT(value); *line = NULL; *name = NULL; *value = NULL; switch (StdIO_ReadNextLine(stream, &myLine, 0, &myLineLen)) { case StdIO_Error: return 0; case StdIO_EOF: return 1; case StdIO_Success: if (DictLL_UnmarshalLine(myLine, myLineLen, line, name, value) == NULL) { *line = BufDup("", 0); } free(myLine); return 2; default: NOT_IMPLEMENTED(); } NOT_REACHED(); } /* *----------------------------------------------------------------------------- * * DictLL_MarshalLine -- * * Marshals a line, appending the data to a DynBuf. If 'name' is NULL, * '*value' contains the whole line to write verbatim. Otherwise a proper * name/value pair is written. * * Results: * TRUE on success, FALSE on failure (caused by memory allocation failure). * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool DictLL_MarshalLine(DynBuf *output, // IN/OUT: output buffer char const *name, // IN: name to marshal char const *value) // IN: value to marshal { size_t size; if (name) { /* * Double quote, pipe, 0x7F, and all control characters but * tab --hpreg * 0x80 to 0xff are unescaped so characters in encodings * like UTF-8 will be displayed normally. */ static int const toEscape[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 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, 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, 1, 0, 0, 1, 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, 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, 0, 0, }; char *evalue; /* Write a well-formed line --hpreg */ evalue = Escape_Do('|', toEscape, value, (uint32)strlen(value), &size); if ( !DynBuf_Append(output, name, (uint32)strlen(name)) || !DynBuf_Append(output, " = \"", 4) || (size && !DynBuf_Append(output, evalue, size)) || !DynBuf_Append(output, "\"", 1)) { free(evalue); return FALSE; } free(evalue); } else { /* Write the line as passed from the upper layers --hpreg */ size = (uint32)strlen(value); if (size && !DynBuf_Append(output, value, size)) { return FALSE; } } /* * Win32 takes care of adding the \r (XXX this assumes that the stream * is opened in ascii mode) --hpreg */ if (!DynBuf_Append(output, "\n", 1)) { return FALSE; } return TRUE; } /* *----------------------------------------------------------------------------- * * DictLL_WriteLine -- * * Marshals a line, writing the data to a file. If 'name' is NULL, '*value' * contains the whole line to write verbatim. Otherwise a proper name/value * pair is written. * * Results: * TRUE on success * FALSE on failure: errno is set accordingly * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool DictLL_WriteLine(FILE *stream, // IN: stream to write char const *name, // IN: name to write char const *value) // IN: value to write { DynBuf buf; DynBuf_Init(&buf); if (!DictLL_MarshalLine(&buf, name, value)) { DynBuf_Destroy(&buf); errno = ENOMEM; return FALSE; } if (fwrite(DynBuf_Get(&buf), DynBuf_GetSize(&buf), 1, stream) != 1) { DynBuf_Destroy(&buf); return FALSE; } DynBuf_Destroy(&buf); return TRUE; } /* *----------------------------------------------------------------------------- * * DictLL_ReadUTF8BOM -- * * Reads a UTF-8 BOM from a file. * * Results: * If successful, returns TRUE and updates the file position. * Returns FALSE if a UTF-8 BOM was not found. * * Side effects: * Might clears the error indicator of the file stream. * *----------------------------------------------------------------------------- */ Bool DictLL_ReadUTF8BOM(FILE *file) // IN/OUT { Bool found; // sizeof on a string literal counts NUL. Exclude it. char buf[sizeof UTF8_BOM - 1] = { 0 }; if (file == stdin) { return FALSE; } found = fread(buf, sizeof buf, 1, file) == 1 && memcmp(UTF8_BOM, buf, sizeof buf) == 0; if (!found) { rewind(file); } return found; } open-vm-tools-9.4.0-1280544/lib/dict/Makefile.in0000644765153500003110000004347212220061621017200 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/dict DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libDict_la_LIBADD = am_libDict_la_OBJECTS = dictll.lo libDict_la_OBJECTS = $(am_libDict_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libDict_la_SOURCES) DIST_SOURCES = $(libDict_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libDict.la libDict_la_SOURCES = dictll.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/dict/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/dict/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libDict.la: $(libDict_la_OBJECTS) $(libDict_la_DEPENDENCIES) $(EXTRA_libDict_la_DEPENDENCIES) $(LINK) $(libDict_la_OBJECTS) $(libDict_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dictll.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/printer/0000755765153500003110000000000012220061623015663 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/printer/printer.c0000644765153500003110000002301112220061556017514 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * printer.c -- * * This file implements assorted printer related functionality. * * This library is currently only implemented for Win32, and uses * Win32 API functions that are only available for Windows NT and * later. However, this library is linked into code that runs on * Win9x, and thus dynamically loads its Win32 API functions * from DLL. * * Therefore, users of this library must call Printer_Init() * before calling anything else. */ #ifdef _WIN32 #undef WIN32_LEAN_AND_MEAN #include #endif #include "vmware.h" #include "err.h" #include "printer.h" #ifdef _WIN32 #include "win32u.h" #endif #define LOGLEVEL_MODULE printer #include "loglevel_user.h" /* * State needed for dynamically loading functions from DLLs. */ #ifdef _WIN32 HMODULE winspoolDll = NULL; typedef BOOL (WINAPI *AddPrinterConnectionFunc)(LPTSTR); typedef BOOL (WINAPI *SetDefaultPrinterFunc)(LPCTSTR); typedef BOOL (WINAPI *GetDefaultPrinterFunc)(LPTSTR, LPDWORD); AddPrinterConnectionFunc addPrinterConnectionFunc = NULL; GetDefaultPrinterFunc getDefaultPrinterFunc = NULL; SetDefaultPrinterFunc setDefaultPrinterFunc = NULL; #endif /* *----------------------------------------------------------------------------- * * Printer_GetDefault -- * * Get the default system printer name. The returned string is * allocated. * * (Currently only implemented on Windows.) * * Results: * Name of default printer * NULL on failure (or if there is no default). * * Side effects: * None * *----------------------------------------------------------------------------- */ char * Printer_GetDefault(void) { #ifdef _WIN32 char *printerName = NULL; DWORD bufSize = 0; DWORD error; Bool success; /* Make sure function has been loaded. */ if (!getDefaultPrinterFunc) { Log("%s: DLL not loaded\n", __FUNCTION__); ASSERT(FALSE); return NULL; } /* Find the necessary buffer size. */ success = getDefaultPrinterFunc(printerName, &bufSize); error = Err_Errno(); if (success) { Log("%s: Didn't fail with zero buffer\n", __FUNCTION__); return NULL; } if (error != ERROR_INSUFFICIENT_BUFFER) { Log("%s: Unexpected failure %d: %s\n", error, __FUNCTION__, Err_Errno2String(error)); return NULL; } printerName = malloc(bufSize); if (!printerName) { Log("%s: Memory allocation failure\n", __FUNCTION__); return NULL; } success = getDefaultPrinterFunc(printerName, &bufSize); if (!success) { error = Err_Errno(); Log("%s: Failed to get default printer\n", __FUNCTION__); free(printerName); return NULL; } return printerName; #else NOT_IMPLEMENTED(); return NULL; #endif } /* *----------------------------------------------------------------------------- * * Printer_SetDefault -- * * Set the default system printer name. * * (Currently only implemented on Windows.) * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool Printer_SetDefault(char const *printerName) // IN { #ifdef _WIN32 DWORD error; /* Make sure function has been loaded. */ if (!setDefaultPrinterFunc) { Log("%s: DLL not loaded\n", __FUNCTION__); ASSERT(FALSE); return FALSE; } /* * Attempt to set the default printer. */ if (!setDefaultPrinterFunc(printerName)) { error = Err_Errno(); Log("%s: Unable to SetDefaultPrinter %d: %s\n", __FUNCTION__, error, Err_Errno2String(error)); return FALSE; } return TRUE; #else NOT_IMPLEMENTED(); return FALSE; #endif } /* *----------------------------------------------------------------------------- * * Printer_AddConnection -- * * Add a connection to the given printer for the current user. * (Win32 only) * * Printer connections are per-user, so this code must be run in * a user's login session in order to work. (Error code 2 is * returned otherwise, e.g. if this code is run from a service.) * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool Printer_AddConnection(char *printerName, // IN: Name of printer to add int *sysError) // OUT: System error code (errno) { #ifdef _WIN32 DWORD error = ERROR_SUCCESS; Bool success = TRUE; ASSERT(printerName); ASSERT(sysError); /* Make sure function has been loaded. */ if (!addPrinterConnectionFunc) { Log("%s: DLL not loaded\n", __FUNCTION__); ASSERT(FALSE); return FALSE; } /* Try to add the printer. */ if (!addPrinterConnectionFunc((LPSTR)printerName)) { error = Err_Errno(); Log("%s: Failed to add printer %s : %d %s\n", __FUNCTION__, printerName, error, Err_Errno2String(error)); success = FALSE; } *sysError = error; return success; #else NOT_IMPLEMENTED(); return FALSE; #endif } /* *----------------------------------------------------------------------------- * * Printer_Init -- * * Load the libraries for needed Win32 API functions. This is * necessary because this code is used in the Tools in Win9x guests, * and Win9x lacks support for some of these functions, so we can't * statically link them. * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool Printer_Init(void) { #ifdef _WIN32 DWORD error; /* * Try to load the necessary library. */ winspoolDll = Win32U_LoadLibrary("Winspool.drv"); if (!winspoolDll) { error = Err_Errno(); Log("%s: Failed to load Winspool.drv %d: %s\n", __FUNCTION__, error, Err_Errno2String(error)); Log("%s: Trying to load Winspool as Winspool.dll...\n", __FUNCTION__); winspoolDll = Win32U_LoadLibrary("Winspool"); if (!winspoolDll) { error = Err_Errno(); Log("%s: Failed to load Winspool.dll %d: %s\n", __FUNCTION__, error, Err_Errno2String(error)); Log("Unable to load Winspool, giving up.\n"); return FALSE; } } /* Load individual functions. */ getDefaultPrinterFunc = (GetDefaultPrinterFunc)GetProcAddress(winspoolDll, "GetDefaultPrinterA"); if (!getDefaultPrinterFunc) { error = Err_Errno(); Log("%s: Failed to load GetDefaultPrinter %d: %s\n", __FUNCTION__, error, Err_Errno2String(error)); goto error; } setDefaultPrinterFunc = (SetDefaultPrinterFunc)GetProcAddress(winspoolDll, "SetDefaultPrinterA"); if (!setDefaultPrinterFunc) { error = Err_Errno(); Log("%s: Failed to load SetDefaultPrinter %d: %s\n", __FUNCTION__, error, Err_Errno2String(error)); goto error; } addPrinterConnectionFunc = (AddPrinterConnectionFunc)GetProcAddress(winspoolDll, "AddPrinterConnectionA"); if (!addPrinterConnectionFunc) { error = Err_Errno(); Log("%s: Failed to load AddPrinterConnection %d: %s\n", __FUNCTION__, error, Err_Errno2String(error)); goto error; } return TRUE; error: addPrinterConnectionFunc = NULL; setDefaultPrinterFunc = NULL; getDefaultPrinterFunc = NULL; return FALSE; #else /* Allow this to succeed for non-Win32. */ return TRUE; #endif } /* *----------------------------------------------------------------------------- * * Printer_Cleanup -- * * Cleanup all the state loaded by Printer_Init(). * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool Printer_Cleanup(void) { #ifdef _WIN32 DWORD error; if (!winspoolDll) { Log("%s: Printer library not loaded.\n", __FUNCTION__); return FALSE; } addPrinterConnectionFunc = NULL; setDefaultPrinterFunc = NULL; getDefaultPrinterFunc = NULL; if (!FreeLibrary(winspoolDll)) { error = Err_Errno(); Log("%s: Failed to FreeLibrary %d: %s\n", __FUNCTION__, error, Err_Errno2String(error)); winspoolDll = NULL; return FALSE; } winspoolDll = NULL; return TRUE; #else /* Allow this to succeed for non-Win32. */ return TRUE; #endif } open-vm-tools-9.4.0-1280544/lib/printer/Makefile.am0000644765153500003110000000172412220061556017730 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libPrinter.la libPrinter_la_SOURCES = libPrinter_la_SOURCES += printer.c open-vm-tools-9.4.0-1280544/lib/printer/Makefile.in0000644765153500003110000004356012220061623017740 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/printer DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libPrinter_la_LIBADD = am_libPrinter_la_OBJECTS = printer.lo libPrinter_la_OBJECTS = $(am_libPrinter_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libPrinter_la_SOURCES) DIST_SOURCES = $(libPrinter_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libPrinter.la libPrinter_la_SOURCES = printer.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/printer/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/printer/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libPrinter.la: $(libPrinter_la_OBJECTS) $(libPrinter_la_DEPENDENCIES) $(EXTRA_libPrinter_la_DEPENDENCIES) $(LINK) $(libPrinter_la_OBJECTS) $(libPrinter_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printer.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/hgfsServerManagerGuest/0000755765153500003110000000000012220061622020620 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/hgfsServerManagerGuest/hgfsChannelGuest.c0000644765153500003110000005077712220061556024242 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * hgfsChannelGuest.c -- * * Channel abstraction for the HGFS server. * */ #include #include "vm_assert.h" #include "vm_atomic.h" #include "util.h" #if defined(VMTOOLS_USE_GLIB) #define G_LOG_DOMAIN "hgfsd" #define Debug g_debug #define Warning g_warning #include "vmware/tools/guestrpc.h" #include "vmware/tools/utils.h" // #include #else #include "debug.h" #endif #include "hgfsChannelGuestInt.h" #include "hgfsServer.h" #include "hgfsServerManager.h" /* * HGFS server connection channel and state object usage. * * Currently, all plugins can share this same HGFS server channel and state. * This allows us to use a common channel so it is only initialized * once, by the first loaded plugin which requires an HGFS channel, and torn * down when the final plugin that uses the HGFS server is unloaded. * * Currently, the plugins are loaded (and unloaded) in any particular order, * and those operations are serialized. (For example the HGFS server plugin * maybe the first plugin loaded that uses this channel, but is not the final * plugin to be unloaded that uses the channel. This also may change in the * future, so no dependencies can be made on order of loading and unloading * of plugins.) * Furthermore, multiple plugins use the HGFS channel and server and some plugins * have multiple connections. Some plugins also create and teardown connections * during general mutlithreaded operation of the tools processes. * * In order to support the above, we must track how many users of the shared * connection there are. This allows us to tear down the shared connection * when the final plugin that is using it is unloaded, and when no * channels are in use the HGFS server state can be torn down. */ /* * The HGFS server state. * * This object is initiliazed once only and is shared across all * connections, shared or private. * Each new channel connection will reference the server and so the HGFS * server is initialized when the first new channel is being created. Each * new channel just increments the reference of server state object. * When the final channel is torn down the final HGFS server reference is * also removed and the HGFS server exit is called and this object is torn down. */ typedef struct HgfsChannelServerData { HgfsServerSessionCallbacks *serverCBTable; /* HGFS server entry points. */ Atomic_uint32 refCount; /* Server data reference count. */ } HgfsChannelServerData; /* * Transport channels context. * * Multiple callers share this same channel currently as only one * transport channel is required. Therefore, the channel is referenced * for each client that it is returned to (a usage count). */ typedef struct HgfsChannelData { const char *name; /* Channel name. */ HgfsGuestChannelCBTable *ops; /* Channel operations. */ uint32 state; /* Channel state (see flags below). */ struct HgfsGuestConn *connection; /* Opaque server connection */ HgfsChannelServerData *serverInfo; /* HGFS server entry points. */ Atomic_uint32 refCount; /* Channel reference count. */ } HgfsChannelData; #define HGFS_CHANNEL_STATE_INIT (1 << 0) #define HGFS_CHANNEL_STATE_CBINIT (1 << 1) /* Static channel registration - assumes only one for now. */ static HgfsChannelData gHgfsChannels[] = { { "guest", &gGuestBackdoorOps, 0, NULL, NULL, {0} }, }; /* HGFS server info state. Referenced by each separate channel that uses it. */ static HgfsChannelServerData gHgfsChannelServerInfo = { NULL, {0} }; static void HgfsChannelTeardownChannel(HgfsChannelData *channel); static void HgfsChannelTeardownServer(HgfsChannelServerData *serverInfo); static void HgfsChannelExitChannel(HgfsChannelData *channel); /* *---------------------------------------------------------------------------- * * HGFS SERVER DATA FUNCTIONS * *---------------------------------------------------------------------------- */ /* *---------------------------------------------------------------------------- * * HgfsChannelGetServer -- * * Increment the server data reference count. * * Results: * The value of the reference count before the increment. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static uint32 HgfsChannelGetServer(HgfsChannelServerData *serverInfo) // IN/OUT: ref count { ASSERT(NULL != serverInfo); return Atomic_FetchAndInc(&serverInfo->refCount); } /* *---------------------------------------------------------------------------- * * HgfsChannelPutServer -- * * Decrement server data reference count. * * Teardown the server data object if removed the final reference. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void HgfsChannelPutServer(HgfsChannelServerData *serverInfo) // IN/OUT: ref count { ASSERT(NULL != serverInfo); if (Atomic_FetchAndDec(&serverInfo->refCount) == 1) { HgfsChannelTeardownServer(serverInfo); } } /* *---------------------------------------------------------------------------- * * HgfsChannelInitServer -- * * Initialize HGFS server and save the state. * * Results: * TRUE if success, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static Bool HgfsChannelInitServer(HgfsChannelServerData *serverInfo) // IN/OUT: ref count { Bool result; ASSERT(NULL == serverInfo->serverCBTable); Debug("%s: Initialize Hgfs server.\n", __FUNCTION__); /* If we have a new connection initialize the server session. */ result = HgfsServer_InitState(&serverInfo->serverCBTable, NULL); if (!result) { Debug("%s: Could not init Hgfs server.\n", __FUNCTION__); } return result; } /* *---------------------------------------------------------------------------- * * HgfsChannelExitServer -- * * Reset the HGFS server and destroy the state. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void HgfsChannelExitServer(HgfsChannelServerData *serverInfo) // IN/OUT: ref count { if (NULL != serverInfo->serverCBTable) { Debug("%s: Teardown Hgfs server.\n", __FUNCTION__); HgfsServer_ExitState(); serverInfo->serverCBTable = NULL; } } /* *---------------------------------------------------------------------------- * * HgfsChannelTeardownServer -- * * Teardown the HGFS server state for all connections. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void HgfsChannelTeardownServer(HgfsChannelServerData *serverInfo) // IN/OUT: connection manager object { HgfsChannelExitServer(serverInfo); } /* *---------------------------------------------------------------------------- * * CHANNEL DATA FUNCTIONS * *---------------------------------------------------------------------------- */ /* *---------------------------------------------------------------------------- * * HgfsChannelGetChannel -- * * Increment channel data reference count. * * Results: * The value of the reference count before the increment. * * Side effects: * None. * *---------------------------------------------------------------------------- */ uint32 HgfsChannelGetChannel(HgfsChannelData *channel) // IN/OUT: ref count { ASSERT(NULL != channel); return Atomic_FetchAndInc(&channel->refCount); } /* *---------------------------------------------------------------------------- * * HgfsChannelPutChannel -- * * Decrement channel reference count. * * Teardown channel object if removed the final reference. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void HgfsChannelPutChannel(HgfsChannelData *channel) // IN/OUT: ref count { ASSERT(NULL != channel); if (Atomic_FetchAndDec(&channel->refCount) == 1) { HgfsChannelTeardownChannel(channel); } } /* *----------------------------------------------------------------------------- * * HgfsChannelInitChannel -- * * Initializes a channel by initializing the HGFS server state. * * Results: * TRUE if the channel initialized, FALSE otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool HgfsChannelInitChannel(HgfsChannelData *channel, // IN/OUT: channel object HgfsChannelServerData *serverInfo) // IN/OUT: server info { Bool result = TRUE; uint32 serverInfoCount; channel->state = 0; /* * Reference the HGFS server as it will be used by the new channel. * The HGFS server should only be initialized once, i.e. on the first * caller instance, otherwise only reference the server info for * the new channel. */ serverInfoCount = HgfsChannelGetServer(serverInfo); /* Referenced the server, save it for dereferencing. */ channel->serverInfo = serverInfo; if (0 == serverInfoCount) { /* The HGFS server has not been initialized, do it now. */ result = HgfsChannelInitServer(channel->serverInfo); if (!result) { Debug("%s: Could not init Hgfs server.\n", __FUNCTION__); goto exit; } } channel->state |= HGFS_CHANNEL_STATE_INIT; exit: if (!result) { HgfsChannelExitChannel(channel); } Debug("%s: Init channel return %d.\n", __FUNCTION__, result); return result; } /* *----------------------------------------------------------------------------- * * HgfsChannelExitChannel -- * * Teardown the channel and teardown the HGFS server. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void HgfsChannelExitChannel(HgfsChannelData *channel) // IN/OUT: channel object { if (NULL != channel->serverInfo) { /* Remove the reference for the HGFS server info. */ HgfsChannelPutServer(channel->serverInfo); channel->serverInfo = NULL; } channel->state = 0; Debug("%s: Exit channel returns.\n", __FUNCTION__); } /* *----------------------------------------------------------------------------- * * HgfsChannelActivateChannel -- * * Activate a channel by calling the channels init callback. * * Results: * TRUE if a channel is active. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool HgfsChannelActivateChannel(HgfsChannelData *channel, // IN/OUT: channel object void *rpc, // IN: Rpc channel void *rpcCallback) // IN: Rpc callback { Bool success = FALSE; struct HgfsGuestConn *connData = NULL; if (channel->ops->init(channel->serverInfo->serverCBTable, rpc, rpcCallback, &connData)) { channel->state |= HGFS_CHANNEL_STATE_CBINIT; channel->connection = connData; success = TRUE; } return success; } /* *----------------------------------------------------------------------------- * * HgfsChannelDeactivateChannel -- * * Deactivate a channel by calling the channels exit callback. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void HgfsChannelDeactivateChannel(HgfsChannelData *channel) // IN/OUT: channel object { channel->ops->exit(channel->connection); channel->state &= ~HGFS_CHANNEL_STATE_CBINIT; channel->connection = NULL; } /* *----------------------------------------------------------------------------- * * HgfsChannelIsChannelActive -- * * Is the channel active (initialized) for processing requests. * * Results: * TRUE if a channel is active. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool HgfsChannelIsChannelActive(HgfsChannelData *channel) // IN/OUT: channel object { return (0 != (channel->state & HGFS_CHANNEL_STATE_INIT) && 0 != (channel->state & HGFS_CHANNEL_STATE_CBINIT)); } /* *----------------------------------------------------------------------------- * * HgfsChannelReceive -- * * Received a request on a channel pass on to the channel callback. * * Results: * TRUE if a channel ws deactivated. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool HgfsChannelReceive(HgfsChannelData *channel, // IN/OUT: channel object char const *packetIn, // IN: incoming packet size_t packetInSize, // IN: incoming packet size char *packetOut, // OUT: outgoing packet size_t *packetOutSize) // IN/OUT: outgoing packet size { return channel->ops->receive(channel->connection, packetIn, packetInSize, packetOut, packetOutSize); } /* *---------------------------------------------------------------------------- * * HgfsChannelTeardownChannel -- * * Teardown the channel for HGFS. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void HgfsChannelTeardownChannel(HgfsChannelData *channel) // IN/OUT: connection manager object { if (HgfsChannelIsChannelActive(channel)) { HgfsChannelDeactivateChannel(channel); } HgfsChannelExitChannel(channel); } /* *---------------------------------------------------------------------------- * * CHANNEL PUBLIC FUNCTIONS * *---------------------------------------------------------------------------- */ /* *---------------------------------------------------------------------------- * * HgfsChannelGuest_Init -- * * Sets up the channel for HGFS. * * Initialize all the defined channels. * At least one channel should succeed it's initialization * completely, else we fail. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool HgfsChannelGuest_Init(HgfsServerMgrData *mgrData) // IN/OUT: connection manager object { Bool success = FALSE; HgfsChannelData *channel = &gHgfsChannels[0]; // Shared channel (internal RPC) uint32 channelRefCount; ASSERT(NULL != mgrData); ASSERT(NULL == mgrData->connection); /* Currently, the RPC override is not implemented. */ ASSERT(NULL == mgrData->rpc); ASSERT(NULL == mgrData->rpcCallback); ASSERT(NULL != mgrData->appName); Debug("%s: app %s rpc = %p rpc cb = %p.\n", __FUNCTION__, mgrData->appName, mgrData->rpc, mgrData->rpcCallback); if (NULL != mgrData->rpc || NULL != mgrData->rpcCallback) { /* * XXX - Would malloc a new channel here and activate * with the required RPC. */ Debug("%s: Guest channel RPC override not supported.\n", __FUNCTION__); goto exit; } /* * Reference the channel. Initialize only for the first * caller instance, otherwise only reference the channel for * return to the caller. */ channelRefCount = HgfsChannelGetChannel(channel); /* We have referenced the channel, save it for later dereference. */ mgrData->connection = channel; if (0 == channelRefCount) { /* Initialize channels objects. */ if (!HgfsChannelInitChannel(channel, &gHgfsChannelServerInfo)) { Debug("%s: Could not init channel.\n", __FUNCTION__); goto exit; } /* Call the channels initializers. */ if (!HgfsChannelActivateChannel(channel, mgrData->rpc, mgrData->rpcCallback)) { Debug("%s: Could not activate channel.\n", __FUNCTION__); goto exit; } } success = TRUE; exit: if (!success) { HgfsChannelGuest_Exit(mgrData); } return success; } /* *---------------------------------------------------------------------------- * * HgfsChannelGuest_Exit -- * * Dereference the channel which for the final reference will * close the channel for HGFS. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsChannelGuest_Exit(HgfsServerMgrData *mgrData) // IN/OUT: connection manager object { HgfsChannelData *channel; ASSERT(NULL != mgrData); ASSERT(NULL != mgrData->appName); channel = mgrData->connection; Debug("%s: app %s rpc = %p rpc cb = %p chn = %p.\n", __FUNCTION__, mgrData->appName, mgrData->rpc, mgrData->rpcCallback, channel); if (NULL != channel) { HgfsChannelPutChannel(channel); mgrData->connection = NULL; } } /* *---------------------------------------------------------------------------- * * HgfsChannelGuest_Receive -- * * Process packet not associated with an HGFS only registered callback. * * * Results: * TRUE if successfully processed FALSE otherwise. * * Side effects: * None * *---------------------------------------------------------------------------- */ Bool HgfsChannelGuest_Receive(HgfsServerMgrData *mgrData, // IN/OUT : conn manager char const *packetIn, // IN: incoming packet size_t packetInSize, // IN: incoming packet size char *packetOut, // OUT: outgoing packet size_t *packetOutSize) // IN/OUT: outgoing packet size { HgfsChannelData *channel = NULL; Bool result = FALSE; ASSERT(NULL != mgrData); ASSERT(NULL != mgrData->connection); ASSERT(NULL != mgrData->appName); channel = mgrData->connection; Debug("%s: %s Channel receive request.\n", __FUNCTION__, mgrData->appName); if (HgfsChannelIsChannelActive(channel)) { result = HgfsChannelReceive(channel, packetIn, packetInSize, packetOut, packetOutSize); } Debug("%s: Channel receive returns %#x.\n", __FUNCTION__, result); return result; } /* *---------------------------------------------------------------------------- * * HgfsChannelGuest_InvalidateInactiveSessions - * * Sends a request to invalidate all the inactive HGFS server sessions. * * Results: * Number of active sessions remaining inside the HGFS server. * * Side effects: * None * *---------------------------------------------------------------------------- */ uint32 HgfsChannelGuest_InvalidateInactiveSessions(HgfsServerMgrData *mgrData) // IN: conn manager { HgfsChannelData *channel = NULL; uint32 result = 0; ASSERT(NULL != mgrData); ASSERT(NULL != mgrData->connection); ASSERT(NULL != mgrData->appName); channel = mgrData->connection; Debug("%s: %s Channel. Invalidating inactive sessions.\n", __FUNCTION__, mgrData->appName); if (HgfsChannelIsChannelActive(channel)) { result = channel->ops->invalidateInactiveSessions(channel->connection); } return result; } open-vm-tools-9.4.0-1280544/lib/hgfsServerManagerGuest/hgfsChannelGuestBd.c0000644765153500003110000005054212220061556024476 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * hgfsChannel.c -- * * Channel abstraction for the HGFS server. * */ #include #include "vm_assert.h" #include "vm_atomic.h" #include "util.h" #include "debug.h" #include "hgfsChannelGuestInt.h" #include "hgfsServer.h" #include "hgfsServerManager.h" typedef enum { HGFS_GST_CONN_UNINITIALIZED, HGFS_GST_CONN_NOTCONNECTED, HGFS_GST_CONN_CONNECTED, } HgfsGuestConnState; /* Since there is only one connection we use globals. */ typedef struct HgfsGuestConn { Atomic_uint32 refCount; /* Reference count. */ HgfsGuestConnState state; HgfsServerSessionCallbacks *serverCbTable; /* Server session callbacks. */ HgfsServerChannelCallbacks channelCbTable; void *serverSession; size_t packetOutLen; unsigned char *clientPacketOut; /* Client supplied buffer. */ unsigned char packetOut[HGFS_LARGE_PACKET_MAX]; /* For RPC msg callbacks. */ } HgfsGuestConn; /* Callback functions. */ static Bool HgfsChannelGuestBdInit(HgfsServerSessionCallbacks *serverCBTable, void *rpc, void *rpcCallback, HgfsGuestConn **connection); static void HgfsChannelGuestBdExit(HgfsGuestConn *data); static Bool HgfsChannelGuestBdSend(void *data, HgfsPacket *packet, char *buffer, size_t bufferLen, HgfsSendFlags flags); static Bool HgfsChannelGuestBdReceive(HgfsGuestConn *data, char const *packetIn, size_t packetInSize, char *packetOut, size_t *packetOutSize); static uint32 HgfsChannelGuestBdInvalidateInactiveSessions(HgfsGuestConn *data); HgfsGuestChannelCBTable gGuestBackdoorOps = { HgfsChannelGuestBdInit, HgfsChannelGuestBdExit, HgfsChannelGuestBdReceive, HgfsChannelGuestBdInvalidateInactiveSessions, }; /* Private functions. */ static Bool HgfsChannelGuestConnConnect(HgfsGuestConn *connData); static void HgfsChannelGuestConnDestroy(HgfsGuestConn *connData); static Bool HgfsChannelGuestReceiveInternal(HgfsGuestConn *connData, char const *packetIn, size_t packetInSize, char *packetOut, size_t *packetOutSize); /* *---------------------------------------------------------------------------- * * CONNECTION DATA FUNCTIONS * *---------------------------------------------------------------------------- */ /* *---------------------------------------------------------------------------- * * HgfsChannelGuestConnGet -- * * Increment connection reference count. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void HgfsChannelGuestConnGet(HgfsGuestConn *connData) // IN: connection { ASSERT(connData); Atomic_Inc(&connData->refCount); } /* *---------------------------------------------------------------------------- * * HgfsChannelGuestConnPut -- * * Decrement connection reference count. * * Free connection data if this is the last reference. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static void HgfsChannelGuestConnPut(HgfsGuestConn *connData) // IN: connection { ASSERT(connData); if (Atomic_FetchAndDec(&connData->refCount) == 1) { HgfsChannelGuestConnDestroy(connData); } } /* *----------------------------------------------------------------------------- * * HgfsChannelGuestConnInit -- * * Initializes the connection. * * Results: * TRUE always and the channel initialized. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool HgfsChannelGuestConnInit(HgfsGuestConn **connData, // IN/OUT: channel object HgfsServerSessionCallbacks *serverCBTable) // IN: server callbacks { HgfsGuestConn *conn = NULL; conn = Util_SafeCalloc(1, sizeof *conn); /* Give ourselves a reference of one. */ HgfsChannelGuestConnGet(conn); conn->serverCbTable = serverCBTable; conn->state = HGFS_GST_CONN_NOTCONNECTED; *connData = conn; return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsChannelGuestConnExit -- * * Teardown the connection. * * Removes the reference and if it is the last will cause the connection * to be destroyed. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void HgfsChannelGuestConnExit(HgfsGuestConn *connData) // IN/OUT: channel object { connData->state = HGFS_GST_CONN_UNINITIALIZED; HgfsChannelGuestConnPut(connData); } /* *----------------------------------------------------------------------------- * * HgfsChannelGuestConnDestroy -- * * Destroy the connection. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void HgfsChannelGuestConnDestroy(HgfsGuestConn *connData) // IN/OUT: channel object { /* Make sure the server closes it's own session data. */ if (NULL != connData->serverSession) { connData->serverCbTable->close(connData->serverSession); connData->serverSession = NULL; } free(connData); } /* *----------------------------------------------------------------------------- * * HgfsChannelGuestConnCreate -- * * Create's the RPC connection for the HGFS guest if asked. * * Create the pseudo connection for the guest - state transition. * (See the comment in the function where the RPC initialization * is expected to be added. * This entails is registering our callback to receive messages for the * connection object passed. We will have the ability to receive * requests until we unregister our callback.) * * NOTE: There is only handler and connction that can be used for * all HGFS guest requests. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void HgfsChannelGuestConnCreate(HgfsGuestConn *connData, // IN: connection void *rpc, // IN: Rpc channel unused void *rpcCallback) // IN: Rpc callback unused { ASSERT(connData->state == HGFS_GST_CONN_NOTCONNECTED); /* * Rpc may be NULL for some cases. For example, if we * just need to provide an HGFS server connection * not associated with an HGFS only RPC connection. */ if (connData->state == HGFS_GST_CONN_NOTCONNECTED) { /* XXX - Here is where we would register an RPC callback if required. */ connData->state = HGFS_GST_CONN_CONNECTED; HgfsChannelGuestConnGet(connData); } } /* *----------------------------------------------------------------------------- * * HgfsChannelGuestConnClose -- * * Closes the connection for the HGFS guest. * * If required unregisters the callback will prevent us from * receiving any more requests closing the connection. * * Results: * TRUE if closed, FALSE if was not connected. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool HgfsChannelGuestConnClose(HgfsGuestConn *connData, // IN: Connection void *rpc, // IN: Rpc channel unused void *rpcCallback) // IN: Rpc callback unused { Bool result = FALSE; if (connData->state == HGFS_GST_CONN_CONNECTED) { /* XXX - Here is where we would unregister an RPC callback. */ /* Clear the connection object since we are unregistered. */ connData->state = HGFS_GST_CONN_NOTCONNECTED; HgfsChannelGuestConnPut(connData); result = TRUE; } return result; } /* *----------------------------------------------------------------------------- * * HgfsChannelGuestConnConnect -- * * Send connection to the server. * * Results: * TRUE if server returns a data object, FALSE if not. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool HgfsChannelGuestConnConnect(HgfsGuestConn *connData) // IN: our connection data { Bool result; connData->channelCbTable.getWriteVa = NULL; connData->channelCbTable.getReadVa = NULL; connData->channelCbTable.putVa = NULL; connData->channelCbTable.send = HgfsChannelGuestBdSend; result = connData->serverCbTable->connect(connData, &connData->channelCbTable, 0, &connData->serverSession); if (result) { HgfsChannelGuestConnGet(connData); } return result; } /* *----------------------------------------------------------------------------- * * HgfsChannelGuestConnDisconnect -- * * Send disconnect to the server. * * NOTE: The server data will be maintained until * the connection is totally closed (last reference is gone). * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void HgfsChannelGuestConnDisconnect(HgfsGuestConn *connData) // IN: connection { if (connData->serverSession != NULL) { /* Tell the server to to disconnect the session. */ connData->serverCbTable->disconnect(connData->serverSession); HgfsChannelGuestConnPut(connData); } } /* *---------------------------------------------------------------------------- * * HgfsChannelGuestConnCloseInternal -- * * Close the client and send a disconnect to the server for the session. * * Results: * None. * * Side effects: * Closes the client connection and empties the queues. * *---------------------------------------------------------------------------- */ static void HgfsChannelGuestConnCloseInternal(HgfsGuestConn *connData, // IN: Connection data void *rpc, // IN: Rpc channel unused void *rpcCallback) // IN: Rpc callback unused { /* Close (unregister the backdoor RPC) connection. */ if (HgfsChannelGuestConnClose(connData, rpc, rpcCallback)) { /* Disconnect the connection from the server. */ HgfsChannelGuestConnDisconnect(connData); } } /* *---------------------------------------------------------------------------- * * HgfsChannelGuestReceiveInternal -- * * Process packet not associated with any session. * * This function is used in the HGFS server inside Tools. * * Create an internal session if not already created, and process the packet. * * Results: * TRUE if received packet ok and processed, FALSE otherwise. * * Side effects: * None * *---------------------------------------------------------------------------- */ static Bool HgfsChannelGuestReceiveInternal(HgfsGuestConn *connData, // IN: connection char const *packetIn, // IN: incoming packet size_t packetInSize, // IN: incoming packet size char *packetOut, // OUT: outgoing packet size_t *packetOutSize) // IN/OUT: outgoing packet size { HgfsPacket packet; ASSERT(packetIn); ASSERT(packetOut); ASSERT(packetOutSize); if (connData->state == HGFS_GST_CONN_UNINITIALIZED) { /* The connection was closed as we are exiting, so bail. */ *packetOutSize = 0; return FALSE; } /* This is just a ping, return nothing. */ if (*packetOutSize == 0) { return TRUE; } /* * Create the session if not already created. * This session is destroyed in HgfsServer_ExitState. */ if (connData->serverSession == NULL) { /* Do our guest connect now which will inform the server. */ if (!HgfsChannelGuestConnConnect(connData)) { *packetOutSize = 0; return FALSE; } } memset(&packet, 0, sizeof packet); /* For backdoor there is only one iov */ packet.iov[0].va = (void *)packetIn; packet.iov[0].len = packetInSize; packet.iovCount = 1; packet.metaPacket = (void *)packetIn; packet.metaPacketSize = packetInSize; packet.replyPacket = packetOut; packet.replyPacketSize = *packetOutSize; /* Misnomer to be fixed, guestInitiated really means client initiated */ packet.guestInitiated = TRUE; /* The server will perform a synchronous processing of requests. */ connData->serverCbTable->receive(&packet, connData->serverSession); *packetOutSize = connData->packetOutLen; return TRUE; } /* *---------------------------------------------------------------------------- * * REGISTERED CALLBACK FUNCTIONS * * XXX - Where we would have any internally registered callback routines. * This routine would call HgfsChannelGuestReceiveInternal to process the * request. * *---------------------------------------------------------------------------- */ /* *---------------------------------------------------------------------------- * * GUEST CHANNEL CALLBACKS * *---------------------------------------------------------------------------- */ /* *---------------------------------------------------------------------------- * * HgfsChannelGuestBdReceive -- * * Process packet not associated with our registered callback. * * * Results: * TRUE if received packet ok and processed, FALSE otherwise. * * Side effects: * None * *---------------------------------------------------------------------------- */ Bool HgfsChannelGuestBdReceive(HgfsGuestConn *connData, // IN: connection char const *packetIn, // IN: incoming packet size_t packetInSize, // IN: incoming packet size char *packetOut, // OUT: outgoing packet size_t *packetOutSize) // IN/OUT: outgoing packet size { Bool result = TRUE; ASSERT(NULL != packetIn); ASSERT(NULL != packetOut); ASSERT(NULL != packetOutSize); ASSERT(NULL != connData); if (NULL == connData) { result = FALSE; goto exit; } connData->packetOutLen = *packetOutSize; connData->clientPacketOut = packetOut; result = HgfsChannelGuestReceiveInternal(connData, packetIn, packetInSize, connData->clientPacketOut, packetOutSize); connData->clientPacketOut = NULL; connData->packetOutLen = sizeof connData->packetOut; exit: return result; } /* *---------------------------------------------------------------------------- * * HgfsChannelGuestBdInvalidateInactiveSessions -- * * Sends a request to invalidate all the inactive HGFS server sessions. * * Results: * Number of active sessions remaining inside the HGFS server. * * Side effects: * None * *---------------------------------------------------------------------------- */ uint32 HgfsChannelGuestBdInvalidateInactiveSessions(HgfsGuestConn *connData) // IN: connection { ASSERT(NULL != connData); if (NULL == connData) { return 0; } if (connData->state == HGFS_GST_CONN_UNINITIALIZED) { /* The connection was closed as we are exiting, so bail. */ return 0; } /* The server will perform a synchronous processing of requests. */ if (connData->serverSession) { return connData->serverCbTable->invalidateInactiveSessions(connData->serverSession); } return 0; } /* *----------------------------------------------------------------------------- * * HgfsChannelGuestBdSend -- * * Send reply to the request * * Results: * Always TRUE. * * Side effects: * None * *----------------------------------------------------------------------------- */ static Bool HgfsChannelGuestBdSend(void *conn, // IN: our connection data HgfsPacket *packet, // IN/OUT: Hgfs Packet char *buffer, // IN: buffer to be sent size_t bufferLen, // IN: buffer length HgfsSendFlags flags) // IN: Flags to say how to process { HgfsGuestConn *connData = conn; ASSERT(NULL != connData); ASSERT(NULL != packet); ASSERT(NULL != buffer); ASSERT(bufferLen <= HGFS_LARGE_PACKET_MAX && bufferLen <= packet->replyPacketSize); ASSERT(bufferLen <= connData->packetOutLen); if (bufferLen > connData->packetOutLen) { bufferLen = connData->packetOutLen; } connData->packetOutLen = (uint32)bufferLen; if (!(flags & HGFS_SEND_NO_COMPLETE)) { connData->serverCbTable->sendComplete(packet, connData->serverSession); } return TRUE; } /* *---------------------------------------------------------------------------- * * HgfsChannelGuestBdInit -- * * Called from channel manager. * * Initializes our channel connections. * * Results: * Always TRUE. * * Side effects: * Registers RPC call. * *---------------------------------------------------------------------------- */ static Bool HgfsChannelGuestBdInit(HgfsServerSessionCallbacks *serverCBTable, // IN: server callbacks void *rpc, // IN: Rpc channel unused void *rpcCallback, // IN: Rpc callback unused HgfsGuestConn **connection) // OUT: connection object { HgfsGuestConn *connData = NULL; Bool result; ASSERT(NULL != connection); /* Create our connection object. */ result = HgfsChannelGuestConnInit(&connData, serverCBTable); if (!result) { Debug("%s: Error: guest connection initialized.\n", __FUNCTION__); goto exit; } /* * Create our connection now with any rpc handle and callback. */ HgfsChannelGuestConnCreate(connData, rpc, rpcCallback); exit: if (!result) { if (NULL != connData) { HgfsChannelGuestBdExit(connData); connData = NULL; } } *connection = connData; Debug("%s: guest initialized.\n", __FUNCTION__); return result; } /* *---------------------------------------------------------------------------- * * HgfsChannelGuestBdExit -- * * Tearsdown our channel connections. * * Results: * None. * * Side effects: * Unregisters RPC call. * *---------------------------------------------------------------------------- */ static void HgfsChannelGuestBdExit(HgfsGuestConn *connData) { ASSERT(NULL != connData); if (NULL != connData) { /* Currently no rpc to unregister. */ HgfsChannelGuestConnCloseInternal(connData, NULL, NULL); HgfsChannelGuestConnExit(connData); } } open-vm-tools-9.4.0-1280544/lib/hgfsServerManagerGuest/hgfsServerManagerGuest.c0000644765153500003110000001030612220061556025413 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * hgfsServerManagerGuest.c -- * * Functionality to utilize the hgfs server in bora/lib from within * a guest application. * */ #include "hgfsServerPolicy.h" #include "hgfsChannelGuestInt.h" #include "hgfsServerManager.h" #include "vm_assert.h" #include "hgfs.h" /* *---------------------------------------------------------------------------- * * HgfsServerManager_ProcessPacket -- * * Handles hgfs requests from a client not by our * registered RPC callback. * * Results: * TRUE on success, FALSE on error. * * Side effects: * None. * *---------------------------------------------------------------------------- */ Bool HgfsServerManager_ProcessPacket(HgfsServerMgrData *mgrData, // IN: hgfs mgr char const *packetIn, // IN: rqst size_t packetInSize, // IN: rqst size char *packetOut, // OUT: rep size_t *packetOutSize) // IN/OUT: rep buf/data size { /* Pass to the channel to handle processing and the server. */ return HgfsChannelGuest_Receive(mgrData, packetIn, packetInSize, packetOut, packetOutSize); } /* *---------------------------------------------------------------------------- * * HgfsServerManager_Register -- * * Registers the hgfs server to be used in classic synchronous fashion. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * Hgfs packets sent to this channel will be handled. * *---------------------------------------------------------------------------- */ Bool HgfsServerManager_Register(HgfsServerMgrData *data) // IN: RpcIn channel { ASSERT(data); ASSERT(data->appName); /* * Passing NULL here is safe because the shares maintained by the guest * policy server never change, invalidating the need for an invalidate * function. */ if (!HgfsServerPolicy_Init(NULL, NULL)) { return FALSE; } if (!HgfsChannelGuest_Init(data)) { HgfsServerPolicy_Cleanup(); return FALSE; } return TRUE; } /* *---------------------------------------------------------------------------- * * HgfsServerManager_InvalidateInactiveSessions -- * * Sends a request to invalidate all the inactive HGFS server sessions. * * Results: * Number of active sessions remaining inside the HGFS server. * * Side effects: * None. * *---------------------------------------------------------------------------- */ uint32 HgfsServerManager_InvalidateInactiveSessions(HgfsServerMgrData *mgrData) // IN: RpcIn channel { ASSERT(mgrData); return HgfsChannelGuest_InvalidateInactiveSessions(mgrData); } /* *---------------------------------------------------------------------------- * * HgfsServerManager_Unregister -- * * Cleans up the hgfs server. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ void HgfsServerManager_Unregister(HgfsServerMgrData *data) // IN: RpcIn channel { ASSERT(data); ASSERT(data->appName != NULL); HgfsChannelGuest_Exit(data); HgfsServerPolicy_Cleanup(); } open-vm-tools-9.4.0-1280544/lib/hgfsServerManagerGuest/Makefile.am0000644765153500003110000000221012220061556022655 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libHgfsServerManagerGuest.la libHgfsServerManagerGuest_la_SOURCES = libHgfsServerManagerGuest_la_SOURCES += hgfsServerManagerGuest.c libHgfsServerManagerGuest_la_SOURCES += hgfsChannelGuest.c libHgfsServerManagerGuest_la_SOURCES += hgfsChannelGuestBd.c open-vm-tools-9.4.0-1280544/lib/hgfsServerManagerGuest/hgfsChannelGuestInt.h0000644765153500003110000000455612220061556024714 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _HGFSCHANNELGUESTINT_H_ #define _HGFSCHANNELGUESTINT_H_ #include "hgfsServer.h" #include "hgfsServerManager.h" /** * @file hgfsChannelGuestInt.h * * Prototypes of Hgfs channel packet process handler found in * hgfsChannelGuest.c */ /* * Opaque structure owned by the guest channel to hold the connection * data to the HGFS server. Only held by the channel manager to pass * back to the guest channel for requests and teardown. * (Or it would be used with any registered internal callback.) */ struct HgfsGuestConn; /* * Guest channel table of callbacks. */ typedef struct HgfsGuestChannelCBTable { Bool (*init)(HgfsServerSessionCallbacks *, void *, void *, struct HgfsGuestConn **); void (*exit)(struct HgfsGuestConn *); Bool (*receive)(struct HgfsGuestConn *, char const *, size_t, char *, size_t *); uint32 (*invalidateInactiveSessions)(struct HgfsGuestConn *); } HgfsGuestChannelCBTable; /* The guest channels callback tables. */ extern HgfsGuestChannelCBTable gGuestBackdoorOps; /* For use by HgfsServerManager. */ Bool HgfsChannelGuest_Init(HgfsServerMgrData *data); void HgfsChannelGuest_Exit(HgfsServerMgrData *data); Bool HgfsChannelGuest_Receive(HgfsServerMgrData *data, char const *packetIn, size_t packetInSize, char *packetOut, size_t *packetOutSize); uint32 HgfsChannelGuest_InvalidateInactiveSessions(HgfsServerMgrData *data); #endif /* _HGFSCHANNELGUESTINT_H_ */ open-vm-tools-9.4.0-1280544/lib/hgfsServerManagerGuest/Makefile.in0000644765153500003110000004463412220061622022700 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/hgfsServerManagerGuest DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libHgfsServerManagerGuest_la_LIBADD = am_libHgfsServerManagerGuest_la_OBJECTS = hgfsServerManagerGuest.lo \ hgfsChannelGuest.lo hgfsChannelGuestBd.lo libHgfsServerManagerGuest_la_OBJECTS = \ $(am_libHgfsServerManagerGuest_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libHgfsServerManagerGuest_la_SOURCES) DIST_SOURCES = $(libHgfsServerManagerGuest_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libHgfsServerManagerGuest.la libHgfsServerManagerGuest_la_SOURCES = hgfsServerManagerGuest.c \ hgfsChannelGuest.c hgfsChannelGuestBd.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/hgfsServerManagerGuest/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/hgfsServerManagerGuest/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libHgfsServerManagerGuest.la: $(libHgfsServerManagerGuest_la_OBJECTS) $(libHgfsServerManagerGuest_la_DEPENDENCIES) $(EXTRA_libHgfsServerManagerGuest_la_DEPENDENCIES) $(LINK) $(libHgfsServerManagerGuest_la_OBJECTS) $(libHgfsServerManagerGuest_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hgfsChannelGuest.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hgfsChannelGuestBd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hgfsServerManagerGuest.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/COPYING0000644765153500003110000006347112220061556015253 0ustar dtormts GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! open-vm-tools-9.4.0-1280544/lib/Makefile.am0000644765153500003110000000331412220061556016242 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ SUBDIRS = SUBDIRS += guestRpc if HAVE_X11 SUBDIRS += appUtil endif SUBDIRS += auth SUBDIRS += backdoor SUBDIRS += dict SUBDIRS += dynxdr SUBDIRS += err SUBDIRS += file SUBDIRS += foundryMsg SUBDIRS += glibUtils SUBDIRS += guestApp SUBDIRS += hgfs SUBDIRS += hgfsBd SUBDIRS += hgfsHelper SUBDIRS += hgfsServer SUBDIRS += hgfsServerManagerGuest SUBDIRS += hgfsServerPolicyGuest SUBDIRS += impersonate SUBDIRS += lock SUBDIRS += message SUBDIRS += misc SUBDIRS += netUtil SUBDIRS += panic SUBDIRS += panicDefault SUBDIRS += printer SUBDIRS += procMgr SUBDIRS += rpcChannel SUBDIRS += rpcIn SUBDIRS += rpcOut SUBDIRS += rpcVmx if USE_SLASH_PROC SUBDIRS += slashProc endif SUBDIRS += string SUBDIRS += stubs SUBDIRS += syncDriver SUBDIRS += system SUBDIRS += unicode SUBDIRS += user SUBDIRS += vmCheck SUBDIRS += vmSignal SUBDIRS += wiper SUBDIRS += xdg open-vm-tools-9.4.0-1280544/lib/guestRpc/0000755765153500003110000000000012220061622015773 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/guestRpc/nicinfo.x0000644765153500003110000001716512220061556017631 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * nicinfo.x -- * * Definition of the data structures used in the GuestRpc commands to * provide information about the guest NICs. */ /* * Enumerates the different versions of the messages. Starting at 2, since * version one is legacy code we can't change. */ enum NicInfoVersion { NIC_INFO_V1 = 1, /* XXX Not represented here. */ NIC_INFO_V2 = 2, NIC_INFO_V3 = 3 }; /* * These are arbitrary limits to avoid possible DoS attacks. * The IP limit is large enough to hold an IP address (either v4 or v6). */ const NICINFO_MAX_IP_LEN = 64; const NICINFO_MAX_IPS = 64; const NICINFO_MAX_NICS = 16; /* MAC Addresses are "AA:BB:CC:DD:EE:FF" = 18 bytes. */ const NICINFO_MAC_LEN = 18; /* * Corresponds to public/guestInfo.h::GuestInfoIPAddressFamilyType. */ enum NicInfoAddrType { NICINFO_ADDR_IPV4 = 0, NICINFO_ADDR_IPV6 = 1 }; struct VmIpAddress { NicInfoAddrType addressFamily; Bool dhcpEnabled; char ipAddress[NICINFO_MAX_IP_LEN]; /* * For IPv4, may be either a hexadecimal mask ("0xffffff00") or CIDR-style * prefix length ("24"). For IPv6, will only be a prefix length. */ char subnetMask[NICINFO_MAX_IP_LEN]; }; struct GuestNic { char macAddress[NICINFO_MAC_LEN]; struct VmIpAddress ips; }; /* * This structure is not entirely necessary, but it makes the generated * code nicer to code to. */ struct GuestNicList { struct GuestNic nics; }; /* *----------------------------------------------------------------------------- * * NIC Info version 3. * * V3 adds routing, DNS, and WINS information to the NIC list. * *----------------------------------------------------------------------------- */ /* * IP v4 and v6 addressing. * * These types were redefined primarily to allow much more efficient wire * encoding. */ /* * See RFC 4001, InetAddress. */ const INET_ADDRESS_MAX_LEN = 255; typedef opaque InetAddress; /* * See RFC 4001, InetAddressType. */ enum InetAddressType { IAT_UNKNOWN = 0, IAT_IPV4 = 1, IAT_IPV6 = 2, IAT_IPV4Z = 3, IAT_IPV6Z = 4, IAT_DNS = 16 }; /* * See RFC 4001, InetAddressPrefixLength. */ typedef unsigned int InetAddressPrefixLength; /* * See RFC 4293, IpAddressOriginTC. */ enum IpAddressOrigin { IAO_OTHER = 1, IAO_MANUAL = 2, IAO_DHCP = 4, IAO_LINKLAYER = 5, IAO_RANDOM = 6 }; /* * See RFC 4293, IpAddressStatusTC. * * "The status of an address. Most of the states correspond to states * from the IPv6 Stateless Address Autoconfiguration protocol. * ... * "In the absence of other information, an IPv4 address is always * preferred(1)." */ enum IpAddressStatus { IAS_PREFERRED = 1, IAS_DEPRECATED = 2, IAS_INVALID = 3, IAS_INACCESSIBLE = 4, IAS_UNKNOWN = 5, IAS_TENTATIVE = 6, IAS_DUPLICATE = 7, IAS_OPTIMISTIC = 8 }; /* * Convenient type for lists of addresses. */ struct TypedIpAddress { InetAddressType ipAddressAddrType; InetAddress ipAddressAddr; }; /* * See RFC 4293, IpAddressEntry. * * "An address mapping for a particular interface." * * We deviate from the RFC in a few places: * - The prefix length is listed explicitly here rather than reference * a separate prefix table. * - Interface indices aren't included as this structure is dependent * upon/encapsulated by a GuestNicV3 structure. */ struct IpAddressEntry { TypedIpAddress ipAddressAddr; InetAddressPrefixLength ipAddressPrefixLength; IpAddressOrigin *ipAddressOrigin; IpAddressStatus *ipAddressStatus; }; /* * Runtime DNS resolver state. */ /* * Quoth RFC 2181 §11 (Name Syntax): * "The length of any one label is limited to between 1 and 63 octets. A * full domain name is limited to 255 octets (including the separators)." */ const DNSINFO_MAX_ADDRLEN = 255; typedef string DnsHostname; /* * Arbitrary limits. */ const DNSINFO_MAX_SUFFIXES = 10; const DNSINFO_MAX_SERVERS = 16; struct DnsConfigInfo { DnsHostname *hostName; DnsHostname *domainName; TypedIpAddress serverList; DnsHostname searchSuffixes; }; /* * Runtime WINS resolver state. Addresses are assumed to be IPv4 only. */ struct WinsConfigInfo { TypedIpAddress primary; TypedIpAddress secondary; }; /* * Runtime routing tables. */ /* * Arbitrary limit. */ const NICINFO_MAX_ROUTES = 100; /* * See RFC 4292 for details. */ enum InetCidrRouteType { ICRT_OTHER = 1, ICRT_REJECT = 2, ICRT_LOCAL = 3, ICRT_REMOTE = 4 }; struct InetCidrRouteEntry { TypedIpAddress inetCidrRouteDest; InetAddressPrefixLength inetCidrRoutePfxLen; /* * Next hop isn't mandatory. */ TypedIpAddress *inetCidrRouteNextHop; /* * inetCidrRouteProto is omitted as we're concerned only with static/ * netmgmt routes. */ /* This is an array index into GuestNicListV3::nics. */ uint32 inetCidrRouteIfIndex; /* XXX Do we really need this? */ InetCidrRouteType inetCidrRouteType; /* -1 == unused. */ uint32 inetCidrRouteMetric; }; /* * Fun with DHCP */ const DHCP_MAX_CONFIG_SIZE = 16384; struct DhcpConfigInfo { bool enabled; string dhcpSettings; }; /* * Top-level containers. */ /* * Describes a single NIC. */ struct GuestNicV3 { string macAddress; IpAddressEntry ips; DnsConfigInfo *dnsConfigInfo; WinsConfigInfo *winsConfigInfo; DhcpConfigInfo *dhcpConfigInfov4; DhcpConfigInfo *dhcpConfigInfov6; }; /* * Attempts to model general network state. */ struct NicInfoV3 { GuestNicV3 nics; InetCidrRouteEntry routes; DnsConfigInfo *dnsConfigInfo; WinsConfigInfo *winsConfigInfo; DhcpConfigInfo *dhcpConfigInfov4; DhcpConfigInfo *dhcpConfigInfov6; }; /* * This defines the protocol for a "nic info" message. The union allows * us to create new versions of the protocol later by creating new values * in the NicInfoVersion enumeration, without having to change much of * the code calling the (de)serialization functions. * * Since the union doesn't have a default case, de-serialization will fail * if an unknown version is provided on the wire. */ union GuestNicProto switch (NicInfoVersion ver) { case NIC_INFO_V2: struct GuestNicList *nicsV2; case NIC_INFO_V3: struct NicInfoV3 *nicInfoV3; }; open-vm-tools-9.4.0-1280544/lib/guestRpc/Makefile.am0000644765153500003110000000326412220061556020042 0ustar dtormts################################################################################ ### Copyright 2008 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libGuestRpc.la libGuestRpc_la_SOURCES = libGuestRpc_la_SOURCES += nicinfo_xdr.c # XXX: Autoreconf complains about this and recommends using AM_CFLAGS instead. # Problem is, $(CFLAGS) is appended to the compiler command line after AM_CFLAGS # and after libGuestRpc_la_CFLAGS, so "-Wall -Werror" will override this flag. CFLAGS += -Wno-unused CLEANFILES = CLEANFILES += nicinfo.h CLEANFILES += nicinfo_xdr.c EXTRA_DIST = EXTRA_DIST += nicinfo.x # Rules to invoke rpcgen. rpcgen will generate funny paths in the generated # files if not invoked in the same directory as the source file, so we need # to copy the sources to the build dir before compiling them. nicinfo.h: nicinfo.x @RPCGEN_WRAPPER@ lib/guestRpc/nicinfo.x $@ nicinfo_xdr.c: nicinfo.x nicinfo.h @RPCGEN_WRAPPER@ lib/guestRpc/nicinfo.x $@ open-vm-tools-9.4.0-1280544/lib/guestRpc/Makefile.in0000644765153500003110000004513712220061622020052 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2008 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/guestRpc DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libGuestRpc_la_LIBADD = am_libGuestRpc_la_OBJECTS = nicinfo_xdr.lo libGuestRpc_la_OBJECTS = $(am_libGuestRpc_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libGuestRpc_la_SOURCES) DIST_SOURCES = $(libGuestRpc_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ # XXX: Autoreconf complains about this and recommends using AM_CFLAGS instead. # Problem is, $(CFLAGS) is appended to the compiler command line after AM_CFLAGS # and after libGuestRpc_la_CFLAGS, so "-Wall -Werror" will override this flag. CFLAGS = @CFLAGS@ -Wno-unused COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libGuestRpc.la libGuestRpc_la_SOURCES = nicinfo_xdr.c CLEANFILES = nicinfo.h nicinfo_xdr.c EXTRA_DIST = nicinfo.x all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/guestRpc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/guestRpc/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libGuestRpc.la: $(libGuestRpc_la_OBJECTS) $(libGuestRpc_la_DEPENDENCIES) $(EXTRA_libGuestRpc_la_DEPENDENCIES) $(LINK) $(libGuestRpc_la_OBJECTS) $(libGuestRpc_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nicinfo_xdr.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Rules to invoke rpcgen. rpcgen will generate funny paths in the generated # files if not invoked in the same directory as the source file, so we need # to copy the sources to the build dir before compiling them. nicinfo.h: nicinfo.x @RPCGEN_WRAPPER@ lib/guestRpc/nicinfo.x $@ nicinfo_xdr.c: nicinfo.x nicinfo.h @RPCGEN_WRAPPER@ lib/guestRpc/nicinfo.x $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/vmSignal/0000755765153500003110000000000012220061623015760 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/vmSignal/Makefile.am0000644765153500003110000000173012220061556020022 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libVmSignal.la libVmSignal_la_SOURCES = libVmSignal_la_SOURCES += vmsignal.c open-vm-tools-9.4.0-1280544/lib/vmSignal/vmsignal.c0000644765153500003110000000601012220061556017746 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vmsignal.c -- * * Posix signal handling utility functions * */ #ifndef VMX86_DEVEL #endif #include #include #include #include "vmsignal.h" /* * Signal_SetGroupHandler -- * * Set a signal handler for a group of signals. * We carefully ensure that if the handler is only used to handle the * signals of the group, the handling of all the signals of the group is * serialized, which means that the handler is not re-entrant. * * Return value: * 1 on success * 0 on failure (detail is displayed) * * Side effects: * None * */ int Signal_SetGroupHandler(int const *signals, // IN struct sigaction *olds, // OUT unsigned int nr, // IN void (*handler)(int signal)) // IN { unsigned int i; struct sigaction new; new.sa_handler = handler; if (sigemptyset(&new.sa_mask)) { fprintf(stderr, "Unable to empty a signal set: %s.\n\n", strerror(errno)); return 0; } for (i = 0; i < nr; i++) { if (sigaddset(&new.sa_mask, signals[i])) { fprintf(stderr, "Unable to add a signal to a signal set: %s.\n\n", strerror(errno)); return 0; } } new.sa_flags = 0; for (i = 0; i < nr; i++) { if (sigaction(signals[i], &new, &olds[i])) { fprintf(stderr, "Unable to modify the handler of the signal %d: %s.\n\n", signals[i], strerror(errno)); return 0; } } return 1; } /* * Signal_ResetGroupHandler -- * * Reset the handler of each signal of a group of signals * * Return value: * 1 on success * 0 on failure (detail is displayed) * * Side effects: * None * */ int Signal_ResetGroupHandler(int const *signals, // IN struct sigaction const *olds, // IN unsigned int nr) // IN { unsigned int i; for (i = 0; i < nr; i++) { if (sigaction(signals[i], &olds[i], NULL)) { fprintf(stderr, "Unable to reset the handler of the signal %d: %s.\n\n", signals[i], strerror(errno)); return 0; } } return 1; } open-vm-tools-9.4.0-1280544/lib/vmSignal/Makefile.in0000644765153500003110000004360412220061623020034 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/vmSignal DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libVmSignal_la_LIBADD = am_libVmSignal_la_OBJECTS = vmsignal.lo libVmSignal_la_OBJECTS = $(am_libVmSignal_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libVmSignal_la_SOURCES) DIST_SOURCES = $(libVmSignal_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libVmSignal.la libVmSignal_la_SOURCES = vmsignal.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/vmSignal/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/vmSignal/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libVmSignal.la: $(libVmSignal_la_OBJECTS) $(libVmSignal_la_DEPENDENCIES) $(EXTRA_libVmSignal_la_DEPENDENCIES) $(LINK) $(libVmSignal_la_OBJECTS) $(libVmSignal_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmsignal.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/hgfsServerPolicyGuest/0000755765153500003110000000000012220061622020505 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/hgfsServerPolicyGuest/hgfsServerPolicyGuest.c0000644765153500003110000004541112220061556025172 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * hgfsServerPolicyGuest.c -- * * Implementation of access policy for hgfs server running in a * VM. All access is allowed. */ #ifdef sun # include # include #elif defined(__FreeBSD__) # include #endif #include "vmware.h" #include "hgfsServerPolicy.h" #define LOGLEVEL_MODULE hgfs #include "loglevel_user.h" typedef struct HgfsServerPolicyState { /* * An empty list means that the policy server enforces the "deny all access * requests" policy --hpreg */ DblLnkLst_Links shares; } HgfsServerPolicyState; static HgfsServerPolicyState myState; /* *----------------------------------------------------------------------------- * * HgfsServerPolicyDestroyShare -- * * Destroy the internal representation of a share --hpreg * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerPolicyDestroyShare(HgfsSharedFolder *share) // IN { ASSERT(share); free(share); } /* *----------------------------------------------------------------------------- * * HgfsServerPolicyDestroyShares -- * * Destroy the internal representation of all shares. The function is * idempotent --hpreg * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static void HgfsServerPolicyDestroyShares(DblLnkLst_Links *head) // IN { ASSERT(head); while (head->next != head) { HgfsSharedFolder *share; share = DblLnkLst_Container(head->next, HgfsSharedFolder, links); ASSERT(share); DblLnkLst_Unlink1(&share->links); HgfsServerPolicyDestroyShare(share); } } /* *----------------------------------------------------------------------------- * * HgfsServerPolicy_Init -- * * Initialize the HGFS security server state. * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsServerPolicy_Init(HgfsInvalidateObjectsFunc *invalidateObjects, // Unused HgfsRegisterSharedFolderFunc *registerFolder) // Unused { HgfsSharedFolder *rootShare; /* * We do not recognize this callback, so make sure our caller doesn't pass * it in. */ ASSERT(!invalidateObjects); DblLnkLst_Init(&myState.shares); /* For the guest, we hard code a "root" share */ rootShare = (HgfsSharedFolder *)malloc(sizeof *rootShare); if (!rootShare) { LOG(4, ("HgfsServerPolicy_Init: memory allocation failed\n")); return FALSE; } DblLnkLst_Init(&rootShare->links); /* * A path = "" has special meaning; it indicates that access is * granted to the root of the server filesystem, and in Win32 * causes everything after the share name in the request to be * interpreted as either a drive letter or UNC name. [bac] */ rootShare->path = ""; rootShare->name = HGFS_SERVER_POLICY_ROOT_SHARE_NAME; rootShare->readAccess = TRUE; rootShare->writeAccess = TRUE; /* These are strictly optimizations to save work later */ rootShare->pathLen = strlen(rootShare->path); rootShare->nameLen = strlen(rootShare->name); rootShare->handle = HGFS_INVALID_FOLDER_HANDLE; /* Add the root node to the end of the list */ DblLnkLst_LinkLast(&myState.shares, &rootShare->links); return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsServerPolicy_Cleanup -- * * Cleanup the HGFS security server state. * * Results: * TRUE on success * FALSE on failure * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsServerPolicy_Cleanup(void) { HgfsServerPolicyDestroyShares(&myState.shares); return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsServerPolicyGetShare -- * * Get the share whose name matches the given name (if any). * * Results: * The share, if a match is found. * NULL otherwise * * Side effects: * None * *----------------------------------------------------------------------------- */ static HgfsSharedFolder * HgfsServerPolicyGetShare(HgfsServerPolicyState *state, // IN char const *nameIn, // IN: Name to check size_t nameInLen) // IN: Length of nameIn { DblLnkLst_Links *l; ASSERT(state); ASSERT(nameIn); /* * First try to find a share that matches the given name exactly. * This is to handle the case where 2 share names differ in case only. */ for (l = state->shares.next; l != &state->shares; l = l->next) { HgfsSharedFolder *share; share = DblLnkLst_Container(l, HgfsSharedFolder, links); ASSERT(share); if (nameInLen == share->nameLen && !memcmp(nameIn, share->name, nameInLen)) { return share; } } /* * There was no match. As a fall back try a case insensitive match. * This is because some Windows applications uppercase or lowercase the * entire path before sending the request. */ for (l = state->shares.next; l != &state->shares; l = l->next) { HgfsSharedFolder *share; char *tempName; /* * Null terminate the input name before a case insensitive comparison. * This is just to protect against bad implementations of strnicmp. */ if (!(tempName = (char *)malloc(nameInLen + 1))) { LOG(4, ("HgfsServerPolicyGetShare: couldn't allocate tempName\n")); return NULL; } memcpy(tempName, nameIn, nameInLen); tempName[nameInLen] = 0; share = DblLnkLst_Container(l, HgfsSharedFolder, links); ASSERT(share); if (nameInLen == share->nameLen && #ifdef _WIN32 !strnicmp(tempName, share->name, nameInLen)) { #else !strncasecmp(tempName, share->name, nameInLen)) { #endif free(tempName); return share; } free(tempName); } return NULL; } /* State used by HgfsServerPolicy_GetShares and friends */ typedef struct State { DblLnkLst_Links *next; } GetSharesState; /* *----------------------------------------------------------------------------- * * HgfsServerPolicy_GetSharesInit -- * * Setup state for HgfsServerPolicy_GetShares * * Results: * Pointer to state on success. * NULL on failure. * * Side effects: * None * *----------------------------------------------------------------------------- */ void * HgfsServerPolicy_GetSharesInit(void) { GetSharesState *that; that = malloc(sizeof *that); if (!that) { LOG(4, ("HgfsServerPolicy_GetSharesInit: couldn't allocate state\n")); return NULL; } that->next = myState.shares.next; return that; } /* *----------------------------------------------------------------------------- * * HgfsServerPolicy_GetShares -- * * Enumerate share names one at a time. * * When finished, sets "done" to TRUE. * * Should be called with the results obtained by calling * HgfsServerPolicy_GetSharesInit. * * Results: * TRUE on success. * FALSE on failure (never happens). * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsServerPolicy_GetShares(void *data, // IN: Callback data char const **name, // OUT: Share name size_t *len, // OUT: Name length Bool *done) // OUT: Completion status { GetSharesState *that; HgfsSharedFolder *share; that = (GetSharesState *)data; ASSERT(that); ASSERT(name); ASSERT(len); ASSERT(done); if (that->next == &myState.shares) { /* No more shares */ *done = TRUE; return TRUE; } share = DblLnkLst_Container(that->next, HgfsSharedFolder, links); ASSERT(share); that->next = share->links.next; *name = share->name; *len = share->nameLen; LOG(4, ("HgfsServerPolicy_GetShares: Share name is \"%s\"\n", *name)); *done = FALSE; return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsServerPolicy_GetSharesCleanup -- * * Cleanup state from HgfsServerPolicy_GetShares * * Results: * TRUE on success. * FALSE on failure (never happens). * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsServerPolicy_GetSharesCleanup(void *data) // IN: Callback data { GetSharesState *that; that = (GetSharesState *)data; ASSERT(that); free(that); return TRUE; } /* *----------------------------------------------------------------------------- * * HgfsServerPolicy_GetSharePath -- * * Get the local path for a share name by looking at the requested * name, finding the matching share (if any), checking access * permissions, and returning the share's local path. * * Results: * An HgfsNameStatus value indicating the result is returned. * * The local path for the shareName is also returned if a match is found and * access is permitted. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsNameStatus HgfsServerPolicy_GetSharePath(char const *nameIn, // IN: Name to check size_t nameInLen, // IN: Length of nameIn HgfsOpenMode mode, // IN: Requested access mode size_t *sharePathLen, // OUT: Length of share path char const **sharePath) // OUT: Share path { HgfsSharedFolder *myShare; ASSERT(nameIn); ASSERT(sharePathLen); ASSERT(sharePath); myShare = HgfsServerPolicyGetShare(&myState, nameIn, nameInLen); if (!myShare) { LOG(4, ("HgfsServerPolicy_GetSharePath: No matching share name\n")); return HGFS_NAME_STATUS_DOES_NOT_EXIST; } /* * See if access is allowed in the requested mode. * * XXX Yeah, this is retarded. We should be using bits instead of * an enum for HgfsOpenMode. Add it to the todo list. [bac] */ switch (HGFS_OPEN_MODE_ACCMODE(mode)) { case HGFS_OPEN_MODE_READ_ONLY: if (!myShare->readAccess) { LOG(4, ("HgfsServerPolicy_GetSharePath: Read access denied\n")); return HGFS_NAME_STATUS_ACCESS_DENIED; } break; case HGFS_OPEN_MODE_WRITE_ONLY: if (!myShare->writeAccess) { LOG(4, ("HgfsServerPolicy_GetSharePath: Write access denied\n")); return HGFS_NAME_STATUS_ACCESS_DENIED; } break; case HGFS_OPEN_MODE_READ_WRITE: if (!myShare->readAccess || !myShare->writeAccess) { LOG(4, ("HgfsServerPolicy_GetSharePath: Read/write access denied\n")); return HGFS_NAME_STATUS_ACCESS_DENIED; } break; default: LOG(0, ("HgfsServerPolicy_GetSharePath: Invalid mode\n")); return HGFS_NAME_STATUS_FAILURE; break; } *sharePathLen = myShare->pathLen; *sharePath = myShare->path; return HGFS_NAME_STATUS_COMPLETE; } /* *----------------------------------------------------------------------------- * * HgfsServerPolicy_ProcessCPName -- * * Get the local path for a share name by looking at the requested * name, finding the matching share (if any) and returning the share's * local path local path and permissions. * * Results: * An HgfsNameStatus value indicating the result is returned. * * The local path for the shareName is also returned if a match is found. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsNameStatus HgfsServerPolicy_ProcessCPName(char const *nameIn, // IN: name in CPName form size_t nameInLen, // IN: length of the name Bool *readAccess, // OUT: Read permissions Bool *writeAccess, // OUT: Write permissions HgfsSharedFolderHandle *handle,// OUT: folder handle char const **shareBaseDir) // OUT: Shared directory { HgfsSharedFolder *myShare; ASSERT(nameIn); ASSERT(shareBaseDir); myShare = HgfsServerPolicyGetShare(&myState, nameIn, nameInLen); if (!myShare) { LOG(4, ("%s: No matching share name\n", __FUNCTION__)); return HGFS_NAME_STATUS_DOES_NOT_EXIST; } *readAccess = myShare->readAccess; *writeAccess = myShare->writeAccess; *shareBaseDir = myShare->path; *handle = myShare->handle; return HGFS_NAME_STATUS_COMPLETE; } /* *----------------------------------------------------------------------------- * * HgfsServerPolicy_GetShareOptions -- * * Get the HGFS share config options by looking at the requested name, * finding the matching share (if any). * * Results: * HGFS_NAME_STATUS_COMPLETE on success, and HGFS_NAME_STATUS_DOES_NOT_EXIST * if no matching share. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsNameStatus HgfsServerPolicy_GetShareOptions(char const *nameIn, // IN: Share name size_t nameInLen, // IN: Share name length HgfsShareOptions *configOptions)// OUT: Config options { HgfsSharedFolder *share; char const *inEnd; char *next; int len; ASSERT(nameIn); ASSERT(configOptions); inEnd = nameIn + nameInLen; len = CPName_GetComponent(nameIn, inEnd, (char const **) &next); if (len < 0) { LOG(4, ("HgfsServerPolicy_GetShareOptions: get first component failed\n")); return HGFS_NAME_STATUS_FAILURE; } share = HgfsServerPolicyGetShare(&myState, nameIn, len); if (!share) { LOG(4, ("HgfsServerPolicy_GetShareOptions: No matching share name.\n")); return HGFS_NAME_STATUS_DOES_NOT_EXIST; } *configOptions = share->configOptions; return HGFS_NAME_STATUS_COMPLETE; } /* *----------------------------------------------------------------------------- * * HgfsServerPolicy_IsShareOptionSet -- * * Check if the specified config option is set. * * Results: * TRUE if set. * FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsServerPolicy_IsShareOptionSet(HgfsShareOptions configOptions, // IN: config options uint32 option) // IN: option to check { return (configOptions & option) == option; } /* *----------------------------------------------------------------------------- * * HgfsServerPolicy_GetShareMode -- * * Get the access mode for a share by looking at the requested * name, finding the matching share (if any), and returning * the share's access mode. * * Results: * An HgfsNameStatus value indicating the result is returned. * * The access mode for the shareName is also returned if a match is found. * * Side effects: * None * *----------------------------------------------------------------------------- */ HgfsNameStatus HgfsServerPolicy_GetShareMode(char const *nameIn, // IN: Share name to retrieve size_t nameInLen, // IN: Length of Share name HgfsOpenMode *mode) // OUT: Share's access mode { HgfsSharedFolder *share; ASSERT(nameIn); ASSERT(mode); share = HgfsServerPolicyGetShare(&myState, nameIn, nameInLen); if (!share) { LOG(4, ("HgfsServerPolicy_GetShareMode: No matching share name\n")); return HGFS_NAME_STATUS_DOES_NOT_EXIST; } /* * Get the access mode. */ if (share->readAccess && share->writeAccess) { *mode = HGFS_OPEN_MODE_READ_WRITE; } else if (share->readAccess) { *mode = HGFS_OPEN_MODE_READ_ONLY; } else if (share->writeAccess) { *mode = HGFS_OPEN_MODE_WRITE_ONLY; } else { /* Share should be at least read or write access. */ ASSERT(FALSE); LOG(4, ("HgfsServerPolicy_GetShareMode: Invalid access mode\n")); return HGFS_NAME_STATUS_FAILURE; } return HGFS_NAME_STATUS_COMPLETE; } /* *----------------------------------------------------------------------------- * * HgfsServerPolicy_CheckMode -- * * Checks if the requested mode may be granted depending on read/write permissions. * * Results: * TRUE if the requested mode can be granted, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool HgfsServerPolicy_CheckMode(HgfsOpenMode mode, // IN: mode to check Bool writePermissions, // IN: callers write permissions Bool readPermissions) // IN: callers read permissions { /* * See if access is allowed in the requested mode. * * XXX Yeah, this is retarded. We should be using bits instead of * an enum for HgfsOpenMode. Add it to the todo list. [bac] */ switch (HGFS_OPEN_MODE_ACCMODE(mode)) { case HGFS_OPEN_MODE_READ_ONLY: if (!readPermissions) { LOG(4, ("HgfsServerPolicyCheckMode: Read access denied\n")); return FALSE; } break; case HGFS_OPEN_MODE_WRITE_ONLY: if (!writePermissions) { LOG(4, ("HgfsServerPolicyCheckMode: Write access denied\n")); return FALSE; } break; case HGFS_OPEN_MODE_READ_WRITE: if (!readPermissions || !writePermissions) { LOG(4, ("HgfsServerPolicyCheckMode: Read/write access denied\n")); return FALSE; } break; default: LOG(0, ("HgfsServerPolicyCheckMode: Invalid mode\n")); ASSERT(FALSE); return FALSE; } return TRUE; } open-vm-tools-9.4.0-1280544/lib/hgfsServerPolicyGuest/Makefile.am0000644765153500003110000000201412220061556022544 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libHgfsServerPolicyGuest.la libHgfsServerPolicyGuest_la_SOURCES = libHgfsServerPolicyGuest_la_SOURCES += hgfsServerPolicyGuest.c open-vm-tools-9.4.0-1280544/lib/hgfsServerPolicyGuest/Makefile.in0000644765153500003110000004421412220061622022557 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/hgfsServerPolicyGuest DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libHgfsServerPolicyGuest_la_LIBADD = am_libHgfsServerPolicyGuest_la_OBJECTS = hgfsServerPolicyGuest.lo libHgfsServerPolicyGuest_la_OBJECTS = \ $(am_libHgfsServerPolicyGuest_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libHgfsServerPolicyGuest_la_SOURCES) DIST_SOURCES = $(libHgfsServerPolicyGuest_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libHgfsServerPolicyGuest.la libHgfsServerPolicyGuest_la_SOURCES = hgfsServerPolicyGuest.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/hgfsServerPolicyGuest/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/hgfsServerPolicyGuest/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libHgfsServerPolicyGuest.la: $(libHgfsServerPolicyGuest_la_OBJECTS) $(libHgfsServerPolicyGuest_la_DEPENDENCIES) $(EXTRA_libHgfsServerPolicyGuest_la_DEPENDENCIES) $(LINK) $(libHgfsServerPolicyGuest_la_OBJECTS) $(libHgfsServerPolicyGuest_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hgfsServerPolicyGuest.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/lock/0000755765153500003110000000000012220061622015127 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/lock/ulInt.h0000644765153500003110000003362712220061556016414 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _ULINT_H_ #define _ULINT_H_ #if defined(_WIN32) #include #endif #include #include #include #include #if defined(_WIN32) typedef DWORD MXUserThreadID; #define MXUSER_INVALID_OWNER 0xFFFFFFFF #else #include "safetime.h" #include typedef pthread_t MXUserThreadID; #endif #include "vm_basic_types.h" #include "vthreadBase.h" #include "hostinfo.h" #include "circList.h" #define MXUSER_STAT_CLASS_ACQUISITION "a" #define MXUSER_STAT_CLASS_HELD "h" /* * A portable recursive lock. */ #define MXUSER_MAX_REC_DEPTH 16 typedef struct { #if defined(_WIN32) CRITICAL_SECTION nativeLock; // Native lock object #else pthread_mutex_t nativeLock; // Native lock object #endif int referenceCount; // Acquisition count MXUserThreadID nativeThreadID; // Native thread ID } MXRecLock; /* * Environment specific implementations of portable recursive locks. * * A recursive lock is used throughput the MXUser locks because: * - it can be used recursively for recursive locks * - exclusive (non-recursive) locks catch the recursion and panic * rather than deadlock. * * There are 9 environment specific primitives: * * MXUserNativeThreadID Return native thread ID * MXRecLockCreateInternal Create lock before use * MXRecLockDestroyInternal Destroy lock after use * MXRecLockIsOwner Is lock owned by the caller? * MXRecLockSetNoOwner Set lock as owner by "nobody" * MXRecLockSetOwner Set lock owner * MXRecLockAcquireInternal Lock the lock * MXRecLockTryAcquireInternal Conditionally acquire the lock * MXRecLockReleaseInternal Unlock the lock * * Windows has a native recursive lock, the CRITICAL_SECTION. POSIXen, * unfortunately, do not ensure access to such a facility. The recursive * attribute of pthread_mutex_t is not implemented in all environments so * we create a recursive implementation using an exclusive pthread_mutex_t * and a few lines of code (most of which we need to do anyway). */ #if defined(_WIN32) static INLINE int MXRecLockCreateInternal(MXRecLock *lock) // IN/OUT: { Bool success; /* http://msdn.microsoft.com/en-us/library/ms682530(VS.85).aspx */ /* magic number - allocate resources immediately; spin 0x400 times */ success = InitializeCriticalSectionAndSpinCount(&lock->nativeLock, 0x80000400); return success ? 0 : GetLastError(); } static INLINE int MXRecLockDestroyInternal(MXRecLock *lock) // IN/OUT: { DeleteCriticalSection(&lock->nativeLock); return 0; } static INLINE MXUserThreadID MXUserNativeThreadID(void) { return GetCurrentThreadId(); } static INLINE Bool MXRecLockIsOwner(const MXRecLock *lock) // IN: { return lock->nativeThreadID == MXUserNativeThreadID(); } static INLINE void MXRecLockSetNoOwner(MXRecLock *lock) // IN: { lock->nativeThreadID = MXUSER_INVALID_OWNER; } static INLINE void MXRecLockSetOwner(MXRecLock *lock) // IN/OUT: { lock->nativeThreadID = MXUserNativeThreadID(); } static INLINE int MXRecLockAcquireInternal(MXRecLock *lock) // IN: { EnterCriticalSection(&lock->nativeLock); return 0; } static INLINE int MXRecLockTryAcquireInternal(MXRecLock *lock) // IN: { return TryEnterCriticalSection(&lock->nativeLock) ? 0 : EBUSY; } static INLINE int MXRecLockReleaseInternal(MXRecLock *lock) // IN: { LeaveCriticalSection(&lock->nativeLock); return 0; } #else static INLINE int MXRecLockCreateInternal(MXRecLock *lock) // IN/OUT: { return pthread_mutex_init(&lock->nativeLock, NULL); } static INLINE int MXRecLockDestroyInternal(MXRecLock *lock) // IN: { return pthread_mutex_destroy(&lock->nativeLock); } static INLINE MXUserThreadID MXUserNativeThreadID(void) { return pthread_self(); } static INLINE Bool MXRecLockIsOwner(const MXRecLock *lock) // IN: { return pthread_equal(lock->nativeThreadID, MXUserNativeThreadID()); } static INLINE void MXRecLockSetNoOwner(MXRecLock *lock) // IN/OUT: { /* a hack but it works portably */ memset((void *) &lock->nativeThreadID, 0xFF, sizeof(lock->nativeThreadID)); } static INLINE void MXRecLockSetOwner(MXRecLock *lock) // IN: { lock->nativeThreadID = MXUserNativeThreadID(); } static INLINE int MXRecLockAcquireInternal(MXRecLock *lock) // IN: { return pthread_mutex_lock(&lock->nativeLock); } static INLINE int MXRecLockTryAcquireInternal(MXRecLock *lock) // IN: { return pthread_mutex_trylock(&lock->nativeLock); } static INLINE int MXRecLockReleaseInternal(MXRecLock *lock) // IN: { return pthread_mutex_unlock(&lock->nativeLock); } #endif static INLINE Bool MXRecLockInit(MXRecLock *lock) // IN/OUT: { Bool success = (MXRecLockCreateInternal(lock) == 0); if (success) { MXRecLockSetNoOwner(lock); lock->referenceCount = 0; } return success; } static INLINE void MXRecLockDestroy(MXRecLock *lock) // IN/OUT: { int err = MXRecLockDestroyInternal(lock); if (vmx86_debug && (err != 0)) { Panic("%s: MXRecLockDestroyInternal returned %d\n", __FUNCTION__, err); } } static INLINE int MXRecLockCount(const MXRecLock *lock) // IN: { ASSERT(lock->referenceCount >= 0); ASSERT(lock->referenceCount < MXUSER_MAX_REC_DEPTH); return lock->referenceCount; } static INLINE void MXRecLockIncCount(MXRecLock *lock, // IN/OUT: int count) // IN: { ASSERT(count >= 0); if (MXRecLockCount(lock) == 0) { MXRecLockSetOwner(lock); } lock->referenceCount += count; } static INLINE void MXRecLockAcquire(MXRecLock *lock, // IN/OUT: VmTimeType *duration) // OUT/OPT: { int err; VmTimeType start = 0; if ((MXRecLockCount(lock) > 0) && MXRecLockIsOwner(lock)) { MXRecLockIncCount(lock, 1); if (duration != NULL) { *duration = 0ULL; } return; // Uncontended } err = MXRecLockTryAcquireInternal(lock); if (err == 0) { MXRecLockIncCount(lock, 1); if (duration != NULL) { *duration = 0ULL; } return; // Uncontended } if (vmx86_debug && (err != EBUSY)) { Panic("%s: MXRecLockTryAcquireInternal error %d\n", __FUNCTION__, err); } if (duration != NULL) { start = Hostinfo_SystemTimerNS(); } err = MXRecLockAcquireInternal(lock); if (duration != NULL) { *duration = Hostinfo_SystemTimerNS() - start; } if (vmx86_debug && (err != 0)) { Panic("%s: MXRecLockAcquireInternal error %d\n", __FUNCTION__, err); } ASSERT(MXRecLockCount(lock) == 0); MXRecLockIncCount(lock, 1); return; // Contended } static INLINE Bool MXRecLockTryAcquire(MXRecLock *lock) // IN/OUT: { int err; if ((MXRecLockCount(lock) > 0) && MXRecLockIsOwner(lock)) { MXRecLockIncCount(lock, 1); return TRUE; // Was acquired } err = MXRecLockTryAcquireInternal(lock); if (err == 0) { MXRecLockIncCount(lock, 1); return TRUE; // Was acquired } if (vmx86_debug && (err != EBUSY)) { Panic("%s: MXRecLockTryAcquireInternal error %d\n", __FUNCTION__, err); } return FALSE; // Was not acquired } static INLINE void MXRecLockDecCount(MXRecLock *lock, // IN/OUT: int count) // IN: { ASSERT(count >= 0); lock->referenceCount -= count; if (MXRecLockCount(lock) == 0) { MXRecLockSetNoOwner(lock); } } static INLINE void MXRecLockRelease(MXRecLock *lock) // IN/OUT: { MXRecLockDecCount(lock, 1); if (MXRecLockCount(lock) == 0) { int err = MXRecLockReleaseInternal(lock); if (vmx86_debug && (err != 0)) { Panic("%s: MXRecLockReleaseInternal returned %d\n", __FUNCTION__, err); } } } /* *----------------------------------------------------------------------------- * * MXUserCastedThreadID -- * * Obtains a unique thread identifier (ID) which can be stored in a * pointer; typically these thread ID values are used for tracking * purposes. * * These values are not typically used with the MXUser MXRecLock * implementation. Native constructs that are very low overhead are * used. * * Results: * As above * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE void * MXUserCastedThreadID(void) { return (void *) (uintptr_t) VThread_CurID(); // unsigned } /* * MXUser object type ID values. */ typedef enum { MXUSER_TYPE_NEVER_USE = 0, MXUSER_TYPE_RW = 1, MXUSER_TYPE_REC = 2, MXUSER_TYPE_RANK = 3, MXUSER_TYPE_EXCL = 4, MXUSER_TYPE_SEMA = 5, MXUSER_TYPE_CONDVAR = 6, MXUSER_TYPE_BARRIER = 7 } MXUserObjectType; /* * MXUser header - all MXUser objects start with this */ typedef struct MXUserHeader { uint32 signature; char *name; MX_Rank rank; uint32 serialNumber; void (*dumpFunc)(struct MXUserHeader *); void (*statsFunc)(struct MXUserHeader *); ListItem item; } MXUserHeader; /* * Internal functions */ void MXUserDumpAndPanic(MXUserHeader *header, const char *fmt, ...); MXRecLock *MXUserInternalSingleton(Atomic_Ptr *storage); uint32 MXUserGetSignature(MXUserObjectType objectType); #if defined(MXUSER_DEBUG) void MXUserAcquisitionTracking(MXUserHeader *header, Bool checkRank); void MXUserReleaseTracking(MXUserHeader *header); void MXUserValidateHeader(MXUserHeader *header, MXUserObjectType objectType); #else static INLINE void MXUserAcquisitionTracking(MXUserHeader *header, // IN: Bool checkRank) // IN: { return; } static INLINE void MXUserReleaseTracking(MXUserHeader *header) // IN: { return; } static INLINE void MXUserValidateHeader(MXUserHeader *header, // IN: MXUserObjectType objectType) // IN: { return; } #endif static INLINE Bool MXUserTryAcquireFail(const char *name) // IN: { extern Bool (*MXUserTryAcquireForceFail)(const char *name); return vmx86_debug && MXUserTryAcquireForceFail && (*MXUserTryAcquireForceFail)(name); } MXUserCondVar *MXUserCreateCondVar(MXUserHeader *header, MXRecLock *lock); void MXUserWaitCondVar(MXUserHeader *header, MXRecLock *lock, MXUserCondVar *condVar, uint32 msecWait); typedef struct { char *typeName; // Name uint64 numSamples; // Population sample size uint64 minTime; // Minimum uint64 maxTime; // Maximum uint64 timeSum; // Sum of times (for mean) double timeSquaredSum; // Sum of times^2 (for S.D.) } MXUserBasicStats; typedef struct { uint64 numAttempts; uint64 numSuccesses; uint64 numSuccessesContended; uint64 successContentionTime; uint64 totalContentionTime; MXUserBasicStats basicStats; } MXUserAcquisitionStats; typedef struct { MXUserBasicStats basicStats; // total held statistics } MXUserReleaseStats; uint32 MXUserAllocSerialNumber(void); void MXUserAddToList(MXUserHeader *header); void MXUserRemoveFromList(MXUserHeader *header); uint32 MXUserStatsMode(void); typedef struct MXUserHisto MXUserHisto; MXUserHisto *MXUserHistoSetUp(char *typeName, uint64 minValue, uint32 decades); void MXUserHistoTearDown(MXUserHisto *histo); void MXUserHistoSample(MXUserHisto *histo, uint64 value, void *caller); void MXUserHistoDump(MXUserHisto *histo, MXUserHeader *header); void MXUserAcquisitionStatsSetUp(MXUserAcquisitionStats *stats); void MXUserAcquisitionSample(MXUserAcquisitionStats *stats, Bool wasAcquired, Bool wasContended, uint64 elapsedTime); void MXUserDumpAcquisitionStats(MXUserAcquisitionStats *stats, MXUserHeader *header); void MXUserAcquisitionStatsTearDown(MXUserAcquisitionStats *stats); void MXUserBasicStatsSetUp(MXUserBasicStats *stats, char *typeName); void MXUserBasicStatsSample(MXUserBasicStats *stats, uint64 value); void MXUserDumpBasicStats(MXUserBasicStats *stats, MXUserHeader *header); void MXUserBasicStatsTearDown(MXUserBasicStats *stats); void MXUserKitchen(MXUserAcquisitionStats *stats, double *contentionRatio, Bool *isHot, Bool *doLog); void MXUserForceHisto(Atomic_Ptr *histoPtr, char *typeName, uint64 minValue, uint32 decades); extern void (*MXUserMX_LockRec)(struct MX_MutexRec *lock); extern void (*MXUserMX_UnlockRec)(struct MX_MutexRec *lock); extern Bool (*MXUserMX_TryLockRec)(struct MX_MutexRec *lock); extern Bool (*MXUserMX_IsLockedByCurThreadRec)(const struct MX_MutexRec *lock); #endif open-vm-tools-9.4.0-1280544/lib/lock/ul.c0000644765153500003110000005410612220061556015727 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #include "vmware.h" #include "str.h" #include "util.h" #include "userlock.h" #include "ulInt.h" #include "ulIntShared.h" #include "hashTable.h" #include "random.h" static Bool mxInPanic = FALSE; // track when involved in a panic Bool (*MXUserTryAcquireForceFail)() = NULL; static MX_Rank (*MXUserMxCheckRank)(void) = NULL; static void (*MXUserMxLockLister)(void) = NULL; void (*MXUserMX_LockRec)(struct MX_MutexRec *lock) = NULL; void (*MXUserMX_UnlockRec)(struct MX_MutexRec *lock) = NULL; Bool (*MXUserMX_TryLockRec)(struct MX_MutexRec *lock) = NULL; Bool (*MXUserMX_IsLockedByCurThreadRec)(const struct MX_MutexRec *lock) = NULL; /* *----------------------------------------------------------------------------- * * MXUserInternalSingleton -- * * A "singleton" function for the MXUser internal recursive lock. * * Internal MXUser recursive locks have no statistics gathering or * tracking abilities. They need to used with care and rarely. * * Results: * NULL Failure * !NULL A pointer to an initialized MXRecLock * * Side effects: * Manifold. * *----------------------------------------------------------------------------- */ MXRecLock * MXUserInternalSingleton(Atomic_Ptr *storage) // IN: { MXRecLock *lock = (MXRecLock *) Atomic_ReadPtr(storage); if (UNLIKELY(lock == NULL)) { MXRecLock *newLock = Util_SafeMalloc(sizeof(MXRecLock)); if (MXRecLockInit(newLock)) { lock = Atomic_ReadIfEqualWritePtr(storage, NULL, (void *) newLock); if (lock) { MXRecLockDestroy(newLock); free(newLock); } else { lock = Atomic_ReadPtr(storage); } } else { free(newLock); lock = Atomic_ReadPtr(storage); // maybe another thread succeeded } } return lock; } #define MXUSER_SYNDROME #if defined(MXUSER_SYNDROME) /* *----------------------------------------------------------------------------- * * MXUserSydrome -- * * Generate the syndrome bits for this MXUser library. * * Each MXUser library has unique syndrome bits enabling the run time * detection of locks created with one copy of the MXUser library and * passed to another copy of the MXUser library. * * The syndrome bits are important as they prevent incompatible versions * of the MXUser library from trashing each other. * * The bits are generated by using a source of bits that is external to * a program and its libraries. This way no code or data based scheme * can be spoofed or aliased. * * Results: * As above * * Side effects: * None * *----------------------------------------------------------------------------- */ static uint32 MXUserSyndrome(void) { uint32 syndrome; static Atomic_uint32 syndromeMem; // implicitly zero -- mbellon syndrome = Atomic_Read(&syndromeMem); if (syndrome == 0) { #if defined(_WIN32) syndrome = GetTickCount(); #else syndrome = time(NULL) & 0xFFFFFFFF; #endif /* * Protect against a total failure. */ if (syndrome == 0) { syndrome++; } /* blind write; if racing one thread or the other will do */ Atomic_ReadIfEqualWrite(&syndromeMem, 0, syndrome); syndrome = Atomic_Read(&syndromeMem); } ASSERT(syndrome); return syndrome; } #endif /* *----------------------------------------------------------------------------- * * MXUserGetSignature -- * * Return a signature appropriate for the specified object type. * * Results: * As above * * Side effects: * None * *----------------------------------------------------------------------------- */ uint32 MXUserGetSignature(MXUserObjectType objectType) // IN: { uint32 signature; ASSERT((objectType >= 0) && (objectType < 16) && (objectType != MXUSER_TYPE_NEVER_USE)); #if defined(MXUSER_SYNDROME) /* * Use a random syndrome combined with a unique bit pattern mapping * of objectType to bits in a nibble. The random portion of the signature * can be used to catch multiple copies of lib/lock that are "leaking" * locks between them (which may be incompatible due to internal changes). */ signature = (MXUserSyndrome() & 0x0FFFFFFF) | (objectType << 28); #else /* * Map the abstract objectType back to the bit patterns used in older * versions of lib/lock. This provides absolute compatibility with * these older libraries. */ switch (objectType) { case MXUSER_TYPE_RW: signature = 0x57524B4C; break; case MXUSER_TYPE_REC: signature = 0x43524B4C; break; case MXUSER_TYPE_RANK: signature = 0x4E4B5241; break; case MXUSER_TYPE_EXCL: signature = 0x58454B4C; break; case MXUSER_TYPE_SEMA: signature = 0x414D4553; break; case MXUSER_TYPE_CONDVAR: signature = 0x444E4F43; break; case MXUSER_TYPE_BARRIER: signature = 0x52524142; break; default: Panic("%s: unknown objectType %d\n", __FUNCTION__, objectType); } #endif ASSERT(signature); return signature; } /* *----------------------------------------------------------------------------- * * MXUserDumpAndPanic -- * * Dump a lock, print a message and die * * Results: * A panic. * * Side effects: * Manifold. * *----------------------------------------------------------------------------- */ void MXUserDumpAndPanic(MXUserHeader *header, // IN: const char *fmt, // IN: ...) // IN: { char *msg; va_list ap; ASSERT((header != NULL) && (header->dumpFunc != NULL)); (*header->dumpFunc)(header); va_start(ap, fmt); msg = Str_SafeVasprintf(NULL, fmt, ap); va_end(ap); Panic("%s", msg); } /* *--------------------------------------------------------------------- * * MXUser_SetInPanic -- * Notify the locking system that a panic is occurring. * * This is the "out of the monitor" - userland - implementation. The "in * the monitor" implementation lives in mutex.c. * * Results: * Set the internal "in a panic" global variable. * * Side effects: * None * *--------------------------------------------------------------------- */ void MXUser_SetInPanic(void) { mxInPanic = TRUE; } /* *--------------------------------------------------------------------- * * MXUser_InPanic -- * Is the caller in the midst of a panic? * * This is the "out of the monitor" - userland - implementation. The "in * the monitor" implementation lives in mutex.c. * * Results: * TRUE Yes * FALSE No * * Side effects: * None * *--------------------------------------------------------------------- */ Bool MXUser_InPanic(void) { return mxInPanic; } /* *----------------------------------------------------------------------------- * * MXUserInstallMxHooks -- * * The MX facility may notify the MXUser facility that it is place and * that MXUser should check with it. This function should be called from * MX_Init. * * Results: * As Above. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void MXUserInstallMxHooks(void (*theLockListFunc)(void), MX_Rank (*theRankFunc)(void), void (*theLockFunc)(struct MX_MutexRec *lock), void (*theUnlockFunc)(struct MX_MutexRec *lock), Bool (*theTryLockFunc)(struct MX_MutexRec *lock), Bool (*theIsLockedFunc)(const struct MX_MutexRec *lock)) { /* * This function can be called more than once but the second and later * invocations must be attempting to install the same hook functions as * the first invocation. */ if ((MXUserMxLockLister == NULL) && (MXUserMxCheckRank == NULL) && (MXUserMX_LockRec == NULL) && (MXUserMX_UnlockRec == NULL) && (MXUserMX_TryLockRec == NULL) && (MXUserMX_IsLockedByCurThreadRec == NULL)) { MXUserMxLockLister = theLockListFunc; MXUserMxCheckRank = theRankFunc; MXUserMX_LockRec = theLockFunc; MXUserMX_UnlockRec = theUnlockFunc; MXUserMX_TryLockRec = theTryLockFunc; MXUserMX_IsLockedByCurThreadRec = theIsLockedFunc; } else { ASSERT((MXUserMxLockLister == theLockListFunc) && (MXUserMxCheckRank == theRankFunc) && (MXUserMX_LockRec == theLockFunc) && (MXUserMX_UnlockRec == theUnlockFunc) && (MXUserMX_TryLockRec == theTryLockFunc) && (MXUserMX_IsLockedByCurThreadRec == theIsLockedFunc) ); } } #if defined(MXUSER_DEBUG) #define MXUSER_MAX_LOCKS_PER_THREAD (2 * MXUSER_MAX_REC_DEPTH) typedef struct MXUserPerThread { struct MXUserPerThread *next; uint32 locksHeld; MXUserHeader *lockArray[MXUSER_MAX_LOCKS_PER_THREAD]; } MXUserPerThread; static Atomic_Ptr perThreadLockMem; static MXUserPerThread *perThreadFreeList = NULL; static Atomic_Ptr hashTableMem; /* *----------------------------------------------------------------------------- * * MXUserAllocPerThread -- * * Allocate a perThread structure. * * Memory is allocated for the specified thread as necessary. Use a * victim cache in front of malloc to provide a slight performance * advantage. The lock here is equivalent to the lock buried inside * malloc but no complex calculations are necessary to perform an * allocation most of the time. * * The maximum size of the list will be roughly the maximum number of * threads having taken locks at the same time - a bounded number less * than or equal to the maximum of threads created. * * Results: * As above. * * Side effects: * Memory may be allocated. * *----------------------------------------------------------------------------- */ static MXUserPerThread * MXUserAllocPerThread(void) { MXUserPerThread *perThread; MXRecLock *perThreadLock = MXUserInternalSingleton(&perThreadLockMem); ASSERT(perThreadLock); MXRecLockAcquire(perThreadLock, NULL); // non-stats if (perThreadFreeList == NULL) { perThread = Util_SafeMalloc(sizeof *perThread); } else { perThread = perThreadFreeList; perThreadFreeList = perThread->next; } MXRecLockRelease(perThreadLock); ASSERT(perThread); memset(perThread, 0, sizeof *perThread); // ensure all zeros return perThread; } /* *----------------------------------------------------------------------------- * * MXUserFreePerThread -- * * Free a perThread structure. * * The structure is placed on the free list -- for "later". * * Results: * As above. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void MXUserFreePerThread(MXUserPerThread *perThread) // IN: { MXRecLock *perThreadLock; ASSERT(perThread); ASSERT(perThread->next == NULL); perThreadLock = MXUserInternalSingleton(&perThreadLockMem); ASSERT(perThreadLock); MXRecLockAcquire(perThreadLock, NULL); // non-stats perThread->next = perThreadFreeList; perThreadFreeList = perThread; MXRecLockRelease(perThreadLock); } /* *----------------------------------------------------------------------------- * * MXUserGetPerThread -- * * Return a pointer to the per thread data for the specified thread. * * Memory is allocated for the specified thread as necessary. This memory * is never released since it it is highly likely a thread will use a * lock and need to record data in the perThread. * * Results: * NULL mayAlloc was FALSE and the thread doesn't have a perThread * !NULL the perThread of the specified thread * * Side effects: * Memory may be allocated. * *----------------------------------------------------------------------------- */ static MXUserPerThread * MXUserGetPerThread(Bool mayAlloc) // IN: alloc perThread if not present? { HashTable *hash; MXUserPerThread *perThread = NULL; void *tid = MXUserCastedThreadID(); hash = HashTable_AllocOnce(&hashTableMem, 1024, HASH_INT_KEY | HASH_FLAG_ATOMIC, NULL); if (!HashTable_Lookup(hash, tid, (void **) &perThread)) { /* No entry for this tid was found, allocate one? */ if (mayAlloc) { MXUserPerThread *newEntry = MXUserAllocPerThread(); /* * Attempt to (racey) insert a perThread on behalf of the specified * thread. If yet another thread takes care of this first, clean up * the mess. */ perThread = HashTable_LookupOrInsert(hash, tid, newEntry); ASSERT(perThread); if (perThread != newEntry) { MXUserFreePerThread(newEntry); } } else { perThread = NULL; } } return perThread; } /* *----------------------------------------------------------------------------- * * MXUserListLocks * * Allow a caller to list, via warnings, the list of locks the caller * has acquired. Ensure that no memory for lock tracking is allocated * if no locks have been taken. * * Results: * The list is printed * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUserListLocks(void) { MXUserPerThread *perThread = MXUserGetPerThread(FALSE); if (perThread != NULL) { uint32 i; for (i = 0; i < perThread->locksHeld; i++) { MXUserHeader *hdr = perThread->lockArray[i]; Warning("\tMXUser lock %s (@0x%p) rank 0x%x\n", hdr->name, hdr, hdr->rank); } } } /* *----------------------------------------------------------------------------- * * MXUser_IsCurThreadHoldingLocks -- * * Are any MXUser locks held by the calling thread? * * Results: * TRUE Yes * FALSE No * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool MXUser_IsCurThreadHoldingLocks(void) { MXUserPerThread *perThread = MXUserGetPerThread(FALSE); return (perThread == NULL) ? FALSE : (perThread->locksHeld != 0); } /* *----------------------------------------------------------------------------- * * MXUserThreadRank -- * * Return the highest rank held by the specified thread via MXUser locks. * * Results: * As above * * Side effects: * Can optionally determine if a lock has been locked before. * *----------------------------------------------------------------------------- */ static MX_Rank MXUserThreadRank(MXUserPerThread *perThread, // IN: MXUserHeader *header, // IN: Bool *firstUse) // OUT: { uint32 i; Bool foundOnce = TRUE; MX_Rank maxRank = RANK_UNRANKED; ASSERT(perThread); /* * Determine the maximum rank held. Note if the lock being acquired * was previously entered into the tracking system. */ for (i = 0; i < perThread->locksHeld; i++) { MXUserHeader *chkHdr = perThread->lockArray[i]; maxRank = MAX(chkHdr->rank, maxRank); if (chkHdr == header) { foundOnce = FALSE; } } if (firstUse) { *firstUse = foundOnce; } return maxRank; } /* *----------------------------------------------------------------------------- * * MXUserCurrentRank -- * * Return the highest rank held by the current thread via MXUser locks. * * Results: * As above * * Side effects: * None * *----------------------------------------------------------------------------- */ MX_Rank MXUserCurrentRank(void) { MX_Rank maxRank; MXUserPerThread *perThread = MXUserGetPerThread(FALSE); if (perThread == NULL) { maxRank = RANK_UNRANKED; } else { maxRank = MXUserThreadRank(perThread, NULL, NULL); } return maxRank; } /* *----------------------------------------------------------------------------- * * MXUserAcquisitionTracking -- * * Perform the appropriate tracking for lock acquisition. * * Results: * Panic when a rank violation is detected (checkRank is TRUE). * Add a lock instance to perThread lock list. * * Side effects: * Manifold. * *----------------------------------------------------------------------------- */ void MXUserAcquisitionTracking(MXUserHeader *header, // IN: Bool checkRank) // IN: { MXUserPerThread *perThread = MXUserGetPerThread(TRUE); ASSERT_NOT_IMPLEMENTED(perThread->locksHeld < MXUSER_MAX_LOCKS_PER_THREAD); /* * Rank checking anyone? * * Rank checking is abandoned once we're in a panic situation. This will * improve the chances of obtaining a good log and/or coredump. */ if (checkRank && (header->rank != RANK_UNRANKED) && !MXUser_InPanic()) { MX_Rank maxRank; Bool firstInstance = TRUE; /* * Determine the highest rank held by the calling thread. Check for * MX locks if they are present. */ maxRank = MXUserThreadRank(perThread, header, &firstInstance); if (MXUserMxCheckRank) { maxRank = MAX(maxRank, (*MXUserMxCheckRank)()); } /* * Perform rank checking when a lock is entered into the tracking * system for the first time. This works out well because: * * Recursive locks are rank checked only upon their first acquisition... * just like MX locks. * * Exclusive locks will have a second entry added into the tracking * system but will immediately panic due to the run time checking - no * (real) harm done. */ if (firstInstance && (header->rank <= maxRank)) { Warning("%s: lock rank violation by thread %s\n", __FUNCTION__, VThread_CurName()); Warning("%s: locks held:\n", __FUNCTION__); if (MXUserMxLockLister) { (*MXUserMxLockLister)(); } MXUserListLocks(); MXUserDumpAndPanic(header, "%s: rank violation maxRank=0x%x\n", __FUNCTION__, maxRank); } } /* Add lock instance to the calling threads perThread information */ perThread->lockArray[perThread->locksHeld++] = header; } /* *----------------------------------------------------------------------------- * * MXUserReleaseTracking -- * * Perform the appropriate tracking for lock release. * * Results: * A panic. * * Side effects: * Manifold. * *----------------------------------------------------------------------------- */ void MXUserReleaseTracking(MXUserHeader *header) // IN: lock, via its header { uint32 i; uint32 lastEntry; MXUserPerThread *perThread = MXUserGetPerThread(FALSE); /* MXUserAcquisitionTracking should have already created a perThread */ if (UNLIKELY(perThread == NULL)) { MXUserDumpAndPanic(header, "%s: perThread not found! (thread 0x%p)\n", __FUNCTION__, MXUserCastedThreadID()); } /* Search the perThread for the argument lock */ for (i = 0; i < perThread->locksHeld; i++) { if (perThread->lockArray[i] == header) { break; } } /* The argument lock had better be in the perThread */ if (UNLIKELY(i >= perThread->locksHeld)) { MXUserDumpAndPanic(header, "%s: lock not found! (thread 0x%p; count %u)\n", __FUNCTION__, MXUserCastedThreadID(), perThread->locksHeld); } /* Remove the argument lock from the perThread */ lastEntry = perThread->locksHeld - 1; if (i < lastEntry) { perThread->lockArray[i] = perThread->lockArray[lastEntry]; } perThread->lockArray[lastEntry] = NULL; // tidy up memory perThread->locksHeld--; } /* *----------------------------------------------------------------------------- * * MXUser_TryAcquireFailureControl -- * * Should a TryAcquire operation fail, no matter "what", sometimes? * * Failures occur statistically in debug builds to force our code down * all of its paths. * * Results: * Unknown * * Side effects: * Always entertaining... * *----------------------------------------------------------------------------- */ void MXUser_TryAcquireFailureControl(Bool (*func)(const char *name)) // IN: { MXUserTryAcquireForceFail = func; } /* *----------------------------------------------------------------------------- * * MXUserValidateHeader -- * * Validate an MXUser object header * * Results: * Return All is well * Panic All is NOT well * * Side effects: * Always entertaining... * *----------------------------------------------------------------------------- */ void MXUserValidateHeader(MXUserHeader *header, // IN: MXUserObjectType objectType) // IN: { uint32 expected = MXUserGetSignature(objectType); if (header->signature != expected) { MXUserDumpAndPanic(header, "%s: signature failure! expected 0x%X observed 0x%X\n", __FUNCTION__, expected, header->signature); } if (header->serialNumber == 0) { MXUserDumpAndPanic(header, "%s: Invalid serial number!", __FUNCTION__); } } #endif open-vm-tools-9.4.0-1280544/lib/lock/ulSema.c0000644765153500003110000005551312220061556016540 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #if defined(_WIN32) #include #else #if defined(__APPLE__) #include #include #include #else #if (_XOPEN_SOURCE < 600) && !defined(__FreeBSD__) && !defined(sun) #undef _XOPEN_SOURCE #define _XOPEN_SOURCE 600 #endif #include #include #endif #endif #include "vmware.h" #include "str.h" #include "util.h" #include "userlock.h" #include "ulInt.h" #include "hostinfo.h" #if defined(_WIN32) #include "win32u.h" #endif #define MXUSER_A_BILLION (1000 * 1000 * 1000) #if defined(_WIN32) typedef HANDLE NativeSemaphore; #else #if defined(__APPLE__) typedef semaphore_t NativeSemaphore; #else typedef sem_t NativeSemaphore; #endif #endif typedef struct { MXUserAcquisitionStats data; Atomic_Ptr histo; } MXUserAcquireStats; struct MXUserSemaphore { MXUserHeader header; Atomic_uint32 activeUserCount; NativeSemaphore nativeSemaphore; Atomic_Ptr acquireStatsMem; }; /* *----------------------------------------------------------------------------- * * Environment specific implementations of portable semaphores. * * All of these functions return zero (0) for success and non-zero upon * failure. The non-zero value is a host specified error code. * * All down operations return a boolean which indicates if the down * operation actually occurred (the counting variable was decremented; * a sleep may have occurred). This boolean is valid regardless of the * value returned from the down functions. * * Timed operations always wait for the length of time specified. Should * the native system allow interruptions/signals, retries will be performed * until the specified amount of time has elapsed. * * There are 6 environment specific primitives: * * MXUserInit Initialize a native semaphore * MXUserDestroy Destroy a native semaphore * MXUserDown Perform a down (P) operation * MXUserTimedDown Perform a down (P) operation with a timeout * MXUserTryDown Perform a try down (P) operation * MXUserUp Perform an up (V) operation * *----------------------------------------------------------------------------- */ #if defined(_WIN32) static int MXUserInit(NativeSemaphore *sema) // IN: { *sema = Win32U_CreateSemaphore(NULL, 0, INT_MAX, NULL); return (*sema == NULL) ? GetLastError() : 0; } static int MXUserDestroy(NativeSemaphore *sema) // IN: { return CloseHandle(*sema) ? 0 : GetLastError(); } static int MXUserTimedDown(NativeSemaphore *sema, // IN: uint32 msecWait, // IN: Bool *downOccurred) // OUT: { int err; DWORD status; status = WaitForSingleObject(*sema, msecWait); switch (status) { case WAIT_OBJECT_0: // The down (decrement) occurred *downOccurred = TRUE; err = 0; break; case WAIT_TIMEOUT: // Timed out; the down (decrement) did not occur *downOccurred = FALSE; err = 0; break; default: // Something really terrible has happened... Panic("%s: WaitForSingleObject return value %x\n", __FUNCTION__, status); } return err; } static int MXUserDown(NativeSemaphore *sema) // IN: { int err; Bool downOccurred; /* * Use an infinite timed wait to implement down. If the timed down * succeeds, assert that the down actually occurred. */ err = MXUserTimedDown(sema, INFINITE, &downOccurred); if (err == 0) { ASSERT(downOccurred); } return err; } static int MXUserTryDown(NativeSemaphore *sema, // IN: Bool *downOccurred) // OUT: { /* * Use a wait for zero time to implement the try operation. This timed * down will either succeed immediately (down occurred), fail (something * terrible happened) or time out immediately (the down could not be * performed and that is OK). */ return MXUserTimedDown(sema, 0, downOccurred); } static int MXUserUp(NativeSemaphore *sema) // IN: { return ReleaseSemaphore(*sema, 1, NULL) ? 0 : GetLastError(); } #elif defined(__APPLE__) static int MXUserInit(NativeSemaphore *sema) // IN: { return semaphore_create(mach_task_self(), sema, SYNC_POLICY_FIFO, 0); } static int MXUserDestroy(NativeSemaphore *sema) // IN: { return semaphore_destroy(mach_task_self(), *sema); } static int MXUserTimedDown(NativeSemaphore *sema, // IN: uint32 msecWait, // IN: Bool *downOccurred) // OUT: { uint64 nsecWait; VmTimeType before; kern_return_t err; ASSERT_ON_COMPILE(KERN_SUCCESS == 0); /* * Work in nanoseconds. Time the semaphore_timedwait operation in case * it is interrupted (KERN_ABORT). If it is, determine how much time is * necessary to fulfill the specified wait time and retry with a new * and appropriate timeout. */ nsecWait = 1000000ULL * (uint64) msecWait; before = Hostinfo_SystemTimerNS(); do { VmTimeType after; mach_timespec_t ts; ts.tv_sec = nsecWait / MXUSER_A_BILLION; ts.tv_nsec = nsecWait % MXUSER_A_BILLION; err = semaphore_timedwait(*sema, ts); after = Hostinfo_SystemTimerNS(); if (err == KERN_SUCCESS) { *downOccurred = TRUE; } else { *downOccurred = FALSE; if (err == KERN_OPERATION_TIMED_OUT) { /* Really timed out; no down occurred, no error */ err = KERN_SUCCESS; } else { if (err == KERN_ABORTED) { VmTimeType duration = after - before; if (duration < nsecWait) { nsecWait -= duration; before = after; } else { err = KERN_SUCCESS; // "timed out" anyway... no error } } } } } while (nsecWait && (err == KERN_ABORTED)); return err; } static int MXUserDown(NativeSemaphore *sema) // IN: { return semaphore_wait(*sema); } static int MXUserTryDown(NativeSemaphore *sema, // IN: Bool *downOccurred) // OUT: { /* * Use a wait for zero time to implement the try operation. This timed * down will either succeed immediately (down occurred), fail (something * terrible happened) or time out immediately (the down could not be * performed and that is OK). */ return MXUserTimedDown(sema, 0, downOccurred); } static int MXUserUp(NativeSemaphore *sema) // IN: { return semaphore_signal(*sema); } #else static int MXUserInit(NativeSemaphore *sema) // IN: { return (sem_init(sema, 0, 0) == -1) ? errno : 0; } static int MXUserDestroy(NativeSemaphore *sema) // IN: { return (sem_destroy(sema) == -1) ? errno : 0; } static int MXUserDown(NativeSemaphore *sema) // IN: { int err; /* Retry any interruptions (EINTR) */ do { err = (sem_wait(sema) == -1) ? errno : 0; } while (err == EINTR); return err; } static int MXUserTimedDown(NativeSemaphore *sema, // IN: uint32 msecWait, // IN: Bool *downOccurred) // OUT: { int err; uint64 endNS; struct timeval curTime; struct timespec endTime; /* * sem_timedwait takes an absolute time. Yes, this is beyond ridiculous, * and the justifications for this vs. relative time makes no sense, but * it is what it is... */ gettimeofday(&curTime, NULL); endNS = ((uint64) curTime.tv_sec * MXUSER_A_BILLION) + ((uint64) curTime.tv_usec * 1000) + ((uint64) msecWait * (1000 * 1000)); endTime.tv_sec = (time_t) (endNS / MXUSER_A_BILLION); endTime.tv_nsec = (long int) (endNS % MXUSER_A_BILLION); do { err = (sem_timedwait(sema, &endTime) == -1) ? errno : 0; if (err == 0) { *downOccurred = TRUE; } else { *downOccurred = FALSE; /* Really timed out; no down occurred, no error */ if (err == ETIMEDOUT) { err = 0; } } } while (err == EINTR); return err; } static int MXUserTryDown(NativeSemaphore *sema, // IN: Bool *downOccurred) // OUT: { int err = (sem_trywait(sema) == -1) ? errno : 0; if (err == 0) { *downOccurred = TRUE; } else { *downOccurred = FALSE; /* * If the error that occured indicates that the try operation cannot * succeed (EAGAIN) or was interrupted (EINTR) suppress the error * indicator as these are considered "normal", non-error cases. * * It's OK to not loop on EINTR here since this is a try operation. */ if ((err == EAGAIN) || (err == EINTR)) { err = 0; // no error } } return err; } static int MXUserUp(NativeSemaphore *sema) // IN: { return (sem_post(sema) == -1) ? errno : 0; } #endif // _WIN32 /* *----------------------------------------------------------------------------- * * MXUserStatsActionSema -- * * Perform the statistics action for the specified semaphore. * * Results: * As above. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void MXUserStatsActionSema(MXUserHeader *header) // IN: { MXUserSemaphore *sema = (MXUserSemaphore *) header; MXUserAcquireStats *acquireStats = Atomic_ReadPtr(&sema->acquireStatsMem); if (LIKELY(acquireStats != NULL)) { Bool isHot; Bool doLog; double contentionRatio; /* * Dump the statistics for the specified semaphore. */ MXUserDumpAcquisitionStats(&acquireStats->data, header); if (Atomic_ReadPtr(&acquireStats->histo) != NULL) { MXUserHistoDump(Atomic_ReadPtr(&acquireStats->histo), header); } /* * Has the semaphore gone "hot"? If so, implement the hot actions. */ MXUserKitchen(&acquireStats->data, &contentionRatio, &isHot, &doLog); if (isHot) { MXUserForceHisto(&acquireStats->histo, MXUSER_STAT_CLASS_ACQUISITION, MXUSER_DEFAULT_HISTO_MIN_VALUE_NS, MXUSER_DEFAULT_HISTO_DECADES); if (doLog) { Log("HOT SEMAPHORE (%s); contention ratio %f\n", sema->header.name, contentionRatio); } } } } /* *----------------------------------------------------------------------------- * * MXUserDumpSemaphore -- * * Dump a semaphore. * * Results: * A dump. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUserDumpSemaphore(MXUserHeader *header) // IN: { MXUserSemaphore *sema = (MXUserSemaphore *) header; Warning("%s: semaphore @ %p\n", __FUNCTION__, sema); Warning("\tsignature 0x%X\n", sema->header.signature); Warning("\tname %s\n", sema->header.name); Warning("\trank 0x%X\n", sema->header.rank); Warning("\tserial number %u\n", sema->header.serialNumber); Warning("\treference count %u\n", Atomic_Read(&sema->activeUserCount)); Warning("\taddress of native semaphore %p\n", &sema->nativeSemaphore); } /* *----------------------------------------------------------------------------- * * MXUser_CreateSemaphore -- * * Create a (counting) semaphore. * * The initial count of the semaphore is zero (0). The maximum count that * a semaphore handles is unknown but may be assumed to be large; the * largest signed 32-bit number is an acceptable choice. * * Results: * A pointer to a semaphore. * * Side effects: * None * *----------------------------------------------------------------------------- */ MXUserSemaphore * MXUser_CreateSemaphore(const char *userName, // IN: MX_Rank rank) // IN: { char *properName; MXUserSemaphore *sema; sema = Util_SafeCalloc(1, sizeof(*sema)); if (userName == NULL) { properName = Str_SafeAsprintf(NULL, "Sema-%p", GetReturnAddress()); } else { properName = Util_SafeStrdup(userName); } if (LIKELY(MXUserInit(&sema->nativeSemaphore) == 0)) { sema->header.signature = MXUserGetSignature(MXUSER_TYPE_SEMA); sema->header.name = properName; sema->header.rank = rank; sema->header.serialNumber = MXUserAllocSerialNumber(); sema->header.dumpFunc = MXUserDumpSemaphore; if (MXUserStatsMode() == 0) { sema->header.statsFunc = NULL; Atomic_WritePtr(&sema->acquireStatsMem, NULL); } else { MXUserAcquireStats *acquireStats; acquireStats = Util_SafeCalloc(1, sizeof(*acquireStats)); MXUserAcquisitionStatsSetUp(&acquireStats->data); sema->header.statsFunc = MXUserStatsActionSema; Atomic_WritePtr(&sema->acquireStatsMem, acquireStats); } MXUserAddToList(&sema->header); } else { free(properName); free(sema); sema = NULL; } return sema; } /* *----------------------------------------------------------------------------- * * MXUser_DestroySemaphore -- * * Destroy a semaphore * * Results: * The semaphore is destroyed. Don't try to use the pointer again. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUser_DestroySemaphore(MXUserSemaphore *sema) // IN: { if (LIKELY(sema != NULL)) { int err; MXUserValidateHeader(&sema->header, MXUSER_TYPE_SEMA); if (Atomic_Read(&sema->activeUserCount) != 0) { MXUserDumpAndPanic(&sema->header, "%s: Attempted destroy on semaphore while in use\n", __FUNCTION__); } sema->header.signature = 0; // just in case... err = MXUserDestroy(&sema->nativeSemaphore); if (UNLIKELY(err != 0)) { MXUserDumpAndPanic(&sema->header, "%s: Internal error (%d)\n", __FUNCTION__, err); } MXUserRemoveFromList(&sema->header); if (vmx86_stats) { MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&sema->acquireStatsMem); if (LIKELY(acquireStats != NULL)) { MXUserAcquisitionStatsTearDown(&acquireStats->data); MXUserHistoTearDown(Atomic_ReadPtr(&acquireStats->histo)); free(acquireStats); } } free(sema->header.name); sema->header.name = NULL; free(sema); } } /* *----------------------------------------------------------------------------- * * MXUser_DownSemaphore -- * * Perform a down (P; probeer te verlagen; "try to reduce") operation * on a semaphore. * * Results: * The count will be decremented; a sleep may occur until the decement * is possible. * * Side effects: * The caller may sleep. * *----------------------------------------------------------------------------- */ void MXUser_DownSemaphore(MXUserSemaphore *sema) // IN/OUT: { int err; ASSERT(sema); MXUserValidateHeader(&sema->header, MXUSER_TYPE_SEMA); Atomic_Inc(&sema->activeUserCount); MXUserAcquisitionTracking(&sema->header, TRUE); // rank checking if (vmx86_stats) { VmTimeType start = 0; Bool tryDownSuccess = FALSE; MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&sema->acquireStatsMem); if (LIKELY(acquireStats != NULL)) { start = Hostinfo_SystemTimerNS(); } err = MXUserTryDown(&sema->nativeSemaphore, &tryDownSuccess); if (LIKELY(err == 0)) { if (!tryDownSuccess) { err = MXUserDown(&sema->nativeSemaphore); } } if (LIKELY((err == 0) && (acquireStats != NULL))) { MXUserHisto *histo; VmTimeType value = Hostinfo_SystemTimerNS() - start; MXUserAcquisitionSample(&acquireStats->data, TRUE, !tryDownSuccess, value); histo = Atomic_ReadPtr(&acquireStats->histo); if (UNLIKELY(histo != NULL)) { MXUserHistoSample(histo, value, GetReturnAddress()); } } } else { err = MXUserDown(&sema->nativeSemaphore); } if (UNLIKELY(err != 0)) { MXUserDumpAndPanic(&sema->header, "%s: Internal error (%d)\n", __FUNCTION__, err); } MXUserReleaseTracking(&sema->header); Atomic_Dec(&sema->activeUserCount); } /* *----------------------------------------------------------------------------- * * MXUser_TimedDownSemaphore -- * * Perform a down (P; probeer te verlagen; "try to reduce") operation * on a semaphore with a timeout. The wait time will always have elapsed * before the routine returns. * * Results: * TRUE Down operation occurred (count has been decremented) * FALSE Down operation did not occur (time out occurred) * * Side effects: * The caller may sleep. * *----------------------------------------------------------------------------- */ Bool MXUser_TimedDownSemaphore(MXUserSemaphore *sema, // IN/OUT: uint32 msecWait) // IN: { int err; Bool downOccurred = FALSE; ASSERT(sema); MXUserValidateHeader(&sema->header, MXUSER_TYPE_SEMA); Atomic_Inc(&sema->activeUserCount); MXUserAcquisitionTracking(&sema->header, TRUE); // rank checking if (vmx86_stats) { VmTimeType start = 0; Bool tryDownSuccess = FALSE; MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&sema->acquireStatsMem); if (LIKELY(acquireStats != NULL)) { start = Hostinfo_SystemTimerNS(); } err = MXUserTryDown(&sema->nativeSemaphore, &tryDownSuccess); if (LIKELY(err == 0)) { if (tryDownSuccess) { downOccurred = TRUE; } else { err = MXUserTimedDown(&sema->nativeSemaphore, msecWait, &downOccurred); } } if (LIKELY((err == 0) && (acquireStats != NULL))) { VmTimeType value = Hostinfo_SystemTimerNS() - start; MXUserAcquisitionSample(&acquireStats->data, downOccurred, !tryDownSuccess, value); if (downOccurred) { MXUserHisto *histo = Atomic_ReadPtr(&acquireStats->histo); if (UNLIKELY(histo != NULL)) { MXUserHistoSample(histo, value, GetReturnAddress()); } } } } else { err = MXUserTimedDown(&sema->nativeSemaphore, msecWait, &downOccurred); } if (UNLIKELY(err != 0)) { MXUserDumpAndPanic(&sema->header, "%s: Internal error (%d)\n", __FUNCTION__, err); } MXUserReleaseTracking(&sema->header); Atomic_Dec(&sema->activeUserCount); return downOccurred; } /* *----------------------------------------------------------------------------- * * MXUser_TryDownSemaphore -- * * Perform a try down (P; probeer te verlagen; "try to reduce") operation * on a semaphore. * * Results: * TRUE Down operation occurred (count has been decremented) * FALSE Down operation did not occur * * Side effects: * None * * NOTE: * A "TryAcquire" does not rank check should the down operation succeed. * This duplicates the behavor of MX semaphores. * *----------------------------------------------------------------------------- */ Bool MXUser_TryDownSemaphore(MXUserSemaphore *sema) // IN/OUT: { int err; Bool downOccurred = FALSE; ASSERT(sema); MXUserValidateHeader(&sema->header, MXUSER_TYPE_SEMA); Atomic_Inc(&sema->activeUserCount); err = MXUserTryDown(&sema->nativeSemaphore, &downOccurred); if (UNLIKELY(err != 0)) { MXUserDumpAndPanic(&sema->header, "%s: Internal error (%d)\n", __FUNCTION__, err); } if (vmx86_stats) { MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&sema->acquireStatsMem); if (LIKELY(acquireStats != NULL)) { MXUserAcquisitionSample(&acquireStats->data, downOccurred, !downOccurred, 0ULL); } } Atomic_Dec(&sema->activeUserCount); return downOccurred; } /* *----------------------------------------------------------------------------- * * MXUser_UpSemaphore -- * * Perform an up (V; verhogen; "increase") operation on a semaphore. * * Results: * The semaphore count is incremented. Any thread waiting on the * semaphore is awoken. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUser_UpSemaphore(MXUserSemaphore *sema) // IN/OUT: { int err; ASSERT(sema); MXUserValidateHeader(&sema->header, MXUSER_TYPE_SEMA); Atomic_Inc(&sema->activeUserCount); err = MXUserUp(&sema->nativeSemaphore); if (UNLIKELY(err != 0)) { MXUserDumpAndPanic(&sema->header, "%s: Internal error (%d)\n", __FUNCTION__, err); } Atomic_Dec(&sema->activeUserCount); } /* *----------------------------------------------------------------------------- * * MXUser_CreateSingletonSemaphore -- * * Ensures that the specified backing object (Atomic_Ptr) contains a * semaphore. This is useful for modules that need to protect something * with a semaphore but don't have an existing Init() entry point where a * semaphore can be created. * * Results: * A pointer to the requested semaphore. * * Side effects: * Generally the semaphore's resources are intentionally leaked * (by design). * *----------------------------------------------------------------------------- */ MXUserSemaphore * MXUser_CreateSingletonSemaphore(Atomic_Ptr *semaStorage, // IN/OUT: const char *name, // IN: MX_Rank rank) // IN: { MXUserSemaphore *sema; ASSERT(semaStorage); sema = Atomic_ReadPtr(semaStorage); if (UNLIKELY(sema == NULL)) { MXUserSemaphore *newSema = MXUser_CreateSemaphore(name, rank); sema = Atomic_ReadIfEqualWritePtr(semaStorage, NULL, (void *) newSema); if (sema) { MXUser_DestroySemaphore(newSema); } else { sema = Atomic_ReadPtr(semaStorage); } } return sema; } open-vm-tools-9.4.0-1280544/lib/lock/ulIntShared.h0000644765153500003110000000303112220061556017525 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _ULINTSHARED_H_ #define _ULINTSHARED_H_ #if defined(MXUSER_DEBUG) extern void MXUserListLocks(void); #else static INLINE void MXUserListLocks(void) { return; } #endif MX_Rank MXUserCurrentRank(void); extern void MXUserInstallMxHooks(void (*theLockListFunc)(void), MX_Rank (*theRankFunc)(void), void (*theLockFunc)(struct MX_MutexRec *lock), void (*theUnlockFunc)(struct MX_MutexRec *lock), Bool (*theTryLockFunc)(struct MX_MutexRec *lock), Bool (*theIsLockedFunc)(const struct MX_MutexRec *lock)); #endif open-vm-tools-9.4.0-1280544/lib/lock/ulRec.c0000644765153500003110000007446712220061556016375 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #include "vmware.h" #include "str.h" #include "util.h" #include "userlock.h" #include "hostinfo.h" #include "ulInt.h" #include "vm_atomic.h" typedef struct { MXUserAcquisitionStats data; Atomic_Ptr histo; } MXUserAcquireStats; typedef struct { VmTimeType holdStart; MXUserBasicStats data; Atomic_Ptr histo; } MXUserHeldStats; struct MXUserRecLock { MXUserHeader header; MXRecLock recursiveLock; Atomic_Ptr heldStatsMem; Atomic_Ptr acquireStatsMem; Atomic_uint32 refCount; /* * This is the MX recursive lock override pointer. It is used within the * VMX only. * * NULL Use the MXRecLock within this structure * MXUser_CreateRecLock was used to create the lock * * !NULL Use the MX_MutexRec pointed to by vmmLock * MXUser_BindMXMutexRec was used to create the lock */ struct MX_MutexRec *vmmLock; }; /* *----------------------------------------------------------------------------- * * MXUserStatsActionRec -- * * Perform the statistics action for the specified lock. * * Results: * As above. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void MXUserStatsActionRec(MXUserHeader *header) // IN: { MXUserRecLock *lock = (MXUserRecLock *) header; MXUserHeldStats *heldStats = Atomic_ReadPtr(&lock->heldStatsMem); MXUserAcquireStats *acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); if (UNLIKELY(heldStats != NULL)) { MXUserDumpBasicStats(&heldStats->data, header); if (Atomic_ReadPtr(&heldStats->histo) != NULL) { MXUserHistoDump(Atomic_ReadPtr(&heldStats->histo), header); } } if (LIKELY(acquireStats != NULL)) { Bool isHot; Bool doLog; double contentionRatio; /* * Dump the statistics for the specified lock. */ MXUserDumpAcquisitionStats(&acquireStats->data, header); if (Atomic_ReadPtr(&acquireStats->histo) != NULL) { MXUserHistoDump(Atomic_ReadPtr(&acquireStats->histo), header); } /* * Has the lock gone "hot"? If so, implement the hot actions. */ MXUserKitchen(&acquireStats->data, &contentionRatio, &isHot, &doLog); if (UNLIKELY(isHot)) { MXUserForceHisto(&acquireStats->histo, MXUSER_STAT_CLASS_ACQUISITION, MXUSER_DEFAULT_HISTO_MIN_VALUE_NS, MXUSER_DEFAULT_HISTO_DECADES); if (UNLIKELY(heldStats != NULL)) { MXUserForceHisto(&heldStats->histo, MXUSER_STAT_CLASS_HELD, MXUSER_DEFAULT_HISTO_MIN_VALUE_NS, MXUSER_DEFAULT_HISTO_DECADES); } if (doLog) { Log("HOT LOCK (%s); contention ratio %f\n", lock->header.name, contentionRatio); } } } } /* *----------------------------------------------------------------------------- * * MXUser_ControlRecLock -- * * Perform the specified command on the specified lock. * * Results: * TRUE succeeded * FALSE failed * * Side effects: * Depends on the command, no? * *----------------------------------------------------------------------------- */ Bool MXUser_ControlRecLock(MXUserRecLock *lock, // IN/OUT: uint32 command, // IN: ...) // IN: { Bool result; ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC); Atomic_Inc(&lock->refCount); switch (command) { case MXUSER_CONTROL_ACQUISITION_HISTO: { if (vmx86_stats) { MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); if ((acquireStats != NULL) && (lock->vmmLock == NULL)) { va_list a; uint32 decades; uint64 minValue; va_start(a, command); minValue = va_arg(a, uint64); decades = va_arg(a, uint32); va_end(a); MXUserForceHisto(&acquireStats->histo, MXUSER_STAT_CLASS_ACQUISITION, minValue, decades); result = TRUE; } else { result = FALSE; } } else { result = FALSE; } break; } case MXUSER_CONTROL_HELD_HISTO: { if (vmx86_stats) { MXUserHeldStats *heldStats = Atomic_ReadPtr(&lock->heldStatsMem); if ((heldStats != NULL) && (lock->vmmLock == NULL)) { va_list a; uint32 decades; uint32 minValue; va_start(a, command); minValue = va_arg(a, uint64); decades = va_arg(a, uint32); va_end(a); MXUserForceHisto(&heldStats->histo, MXUSER_STAT_CLASS_HELD, minValue, decades); result = TRUE; } else { result = FALSE; } } else { result = FALSE; } break; } case MXUSER_CONTROL_ENABLE_STATS: { if (vmx86_stats) { va_list a; Bool trackHeldTimes; MXUserHeldStats *heldStats; MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); if (LIKELY(acquireStats == NULL)) { MXUserAcquireStats *before; acquireStats = Util_SafeCalloc(1, sizeof(*acquireStats)); MXUserAcquisitionStatsSetUp(&acquireStats->data); before = Atomic_ReadIfEqualWritePtr(&lock->acquireStatsMem, NULL, (void *) acquireStats); if (before) { free(acquireStats); } } va_start(a, command); trackHeldTimes = va_arg(a, int); va_end(a); heldStats = Atomic_ReadPtr(&lock->heldStatsMem); if ((heldStats == NULL) && trackHeldTimes) { MXUserHeldStats *before; heldStats = Util_SafeCalloc(1, sizeof(*heldStats)); MXUserBasicStatsSetUp(&heldStats->data, MXUSER_STAT_CLASS_HELD); before = Atomic_ReadIfEqualWritePtr(&lock->heldStatsMem, NULL, (void *) heldStats); if (before) { free(heldStats); } } lock->header.statsFunc = MXUserStatsActionRec; result = TRUE; } else { result = FALSE; } break; } default: result = FALSE; } if (Atomic_FetchAndDec(&lock->refCount) == 1) { Panic("%s: Zero reference count upon exit\n", __FUNCTION__); } return result; } /* *----------------------------------------------------------------------------- * * MXUserDumpRecLock -- * * Dump a recursive lock. * * Results: * A dump. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void MXUserDumpRecLock(MXUserHeader *header) // IN: { MXUserRecLock *lock = (MXUserRecLock *) header; Warning("%s: Recursive lock @ %p\n", __FUNCTION__, lock); Warning("\tsignature 0x%X\n", lock->header.signature); Warning("\tname %s\n", lock->header.name); Warning("\trank 0x%X\n", lock->header.rank); Warning("\tserial number %u\n", lock->header.serialNumber); Warning("\treference count %u\n", Atomic_Read(&lock->refCount)); if (lock->vmmLock == NULL) { Warning("\tlock count %d\n", MXRecLockCount(&lock->recursiveLock)); Warning("\taddress of owner data %p\n", &lock->recursiveLock.nativeThreadID); } else { Warning("\tvmmLock %p\n", lock->vmmLock); } } /* *----------------------------------------------------------------------------- * * MXUserCreateRecLock -- * * Create a recursive lock specifying if the lock must always be * silent. * * Only the owner (thread) of a recursive lock may recurse on it. * * Results: * NULL Creation failed * !NULL Creation succeeded * * Side effects: * None * *----------------------------------------------------------------------------- */ static MXUserRecLock * MXUserCreateRecLock(const char *userName, // IN: MX_Rank rank, // IN: Bool beSilent) // IN: { uint32 statsMode; char *properName; MXUserRecLock *lock; lock = Util_SafeCalloc(1, sizeof(*lock)); if (userName == NULL) { properName = Str_SafeAsprintf(NULL, "R-%p", GetReturnAddress()); } else { properName = Util_SafeStrdup(userName); } if (!MXRecLockInit(&lock->recursiveLock)) { free(properName); free(lock); return NULL; } lock->vmmLock = NULL; Atomic_Write(&lock->refCount, 1); lock->header.signature = MXUserGetSignature(MXUSER_TYPE_REC); lock->header.name = properName; lock->header.rank = rank; lock->header.serialNumber = MXUserAllocSerialNumber(); lock->header.dumpFunc = MXUserDumpRecLock; statsMode = beSilent ? 0 : MXUserStatsMode(); switch (statsMode) { case 0: lock->header.statsFunc = NULL; Atomic_WritePtr(&lock->acquireStatsMem, NULL); Atomic_WritePtr(&lock->heldStatsMem, NULL); break; case 1: MXUser_ControlRecLock(lock, MXUSER_CONTROL_ENABLE_STATS, FALSE); break; case 2: MXUser_ControlRecLock(lock, MXUSER_CONTROL_ENABLE_STATS, TRUE); break; default: Panic("%s: unknown stats mode: %d!\n", __FUNCTION__, statsMode); } MXUserAddToList(&lock->header); return lock; } /* *----------------------------------------------------------------------------- * * MXUser_CreateRecLockSilent -- * * Create a recursive lock specifying if the lock must always be * silent - never logging any messages. Silent locks will never * produce any statistics, amongst the aspects of "silent". * * Only the owner (thread) of a recursive lock may recurse on it. * * Results: * NULL Creation failed * !NULL Creation succeeded * * Side effects: * None * *----------------------------------------------------------------------------- */ MXUserRecLock * MXUser_CreateRecLockSilent(const char *userName, // IN: MX_Rank rank) // IN: { return MXUserCreateRecLock(userName, rank, TRUE); } /* *----------------------------------------------------------------------------- * * MXUser_CreateRecLock -- * * Create a recursive lock. * * Only the owner (thread) of a recursive lock may recurse on it. * * Results: * NULL Creation failed * !NULL Creation succeeded * * Side effects: * None * *----------------------------------------------------------------------------- */ MXUserRecLock * MXUser_CreateRecLock(const char *userName, // IN: MX_Rank rank) // IN: { return MXUserCreateRecLock(userName, rank, FALSE); } /* *----------------------------------------------------------------------------- * * MXUserCondDestroyRecLock -- * * Destroy a recursive lock -- but only if its reference count is zero. * * When the lock is bound to a MX lock, only the MXUser "wrapper" is * freed. The caller is responsible for calling MX_DestroyLockRec() on * the MX lock before calling this routine. * * Results: * Lock is destroyed upon correct reference count. Don't use the * pointer again. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void MXUserCondDestroyRecLock(MXUserRecLock *lock) // IN: { ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC); if (Atomic_FetchAndDec(&lock->refCount) == 1) { if (lock->vmmLock == NULL) { if (MXRecLockCount(&lock->recursiveLock) > 0) { MXUserDumpAndPanic(&lock->header, "%s: Destroy of an acquired recursive lock\n", __FUNCTION__); } MXRecLockDestroy(&lock->recursiveLock); MXUserRemoveFromList(&lock->header); if (vmx86_stats) { MXUserHeldStats *heldStats; MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); if (acquireStats) { MXUserAcquisitionStatsTearDown(&acquireStats->data); MXUserHistoTearDown(Atomic_ReadPtr(&acquireStats->histo)); free(acquireStats); } heldStats = Atomic_ReadPtr(&lock->heldStatsMem); if (UNLIKELY(heldStats != NULL)) { MXUserBasicStatsTearDown(&heldStats->data); MXUserHistoTearDown(Atomic_ReadPtr(&heldStats->histo)); free(heldStats); } } } lock->header.signature = 0; // just in case... free(lock->header.name); lock->header.name = NULL; free(lock); } } void MXUser_DestroyRecLock(MXUserRecLock *lock) // IN: { if (lock != NULL) { MXUserCondDestroyRecLock(lock); } } /* *----------------------------------------------------------------------------- * * MXUserAcquireRecLock -- * * An acquisition is made (lock is taken) on the specified recursive lock. * * Only the owner (thread) of a recursive lock may recurse on it. * * Results: * The lock is acquired (locked). * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUser_AcquireRecLock(MXUserRecLock *lock) // IN/OUT: { ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC); Atomic_Inc(&lock->refCount); if (lock->vmmLock) { ASSERT(MXUserMX_LockRec); (*MXUserMX_LockRec)(lock->vmmLock); } else { /* Rank checking is only done on the first acquisition */ MXUserAcquisitionTracking(&lock->header, TRUE); if (vmx86_stats) { VmTimeType value = 0; MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); MXRecLockAcquire(&lock->recursiveLock, (acquireStats == NULL) ? NULL : &value); if (LIKELY(acquireStats != NULL)) { if (MXRecLockCount(&lock->recursiveLock) == 1) { MXUserHeldStats *heldStats; MXUserHisto *histo = Atomic_ReadPtr(&acquireStats->histo); MXUserAcquisitionSample(&acquireStats->data, TRUE, value != 0, value); histo = Atomic_ReadPtr(&acquireStats->histo); if (UNLIKELY(histo != NULL)) { MXUserHistoSample(histo, value, GetReturnAddress()); } heldStats = Atomic_ReadPtr(&lock->heldStatsMem); if (UNLIKELY(heldStats != NULL)) { heldStats->holdStart = Hostinfo_SystemTimerNS(); } } } } else { MXRecLockAcquire(&lock->recursiveLock, NULL); // non-stats } } if (Atomic_FetchAndDec(&lock->refCount) == 1) { Panic("%s: Zero reference count upon exit\n", __FUNCTION__); } } /* *----------------------------------------------------------------------------- * * MXUser_ReleaseRecLock -- * * Release (unlock) a recursive lock. * * Results: * The lock is released. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUser_ReleaseRecLock(MXUserRecLock *lock) // IN/OUT: { ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC); Atomic_Inc(&lock->refCount); if (lock->vmmLock) { ASSERT(MXUserMX_UnlockRec); (*MXUserMX_UnlockRec)(lock->vmmLock); } else { if (vmx86_stats) { MXUserHeldStats *heldStats = Atomic_ReadPtr(&lock->heldStatsMem); if (LIKELY(heldStats != NULL)) { if (MXRecLockCount(&lock->recursiveLock) == 1) { MXUserHeldStats *heldStats; heldStats = Atomic_ReadPtr(&lock->heldStatsMem); if (UNLIKELY(heldStats != NULL)) { VmTimeType value; MXUserHisto *histo = Atomic_ReadPtr(&heldStats->histo); value = Hostinfo_SystemTimerNS() - heldStats->holdStart; MXUserBasicStatsSample(&heldStats->data, value); if (UNLIKELY(histo != NULL)) { MXUserHistoSample(histo, value, GetReturnAddress()); } } } } } if (vmx86_debug) { if (MXRecLockCount(&lock->recursiveLock) == 0) { MXUserDumpAndPanic(&lock->header, "%s: Release of an unacquired recursive lock\n", __FUNCTION__); } if (!MXRecLockIsOwner(&lock->recursiveLock)) { MXUserDumpAndPanic(&lock->header, "%s: Non-owner release of an recursive lock\n", __FUNCTION__); } } MXUserReleaseTracking(&lock->header); MXRecLockRelease(&lock->recursiveLock); } /* * Don't screw up the reference count! When this is the last reference * the lock will self destruct on a release if it is the last "hold" * of the lock. */ MXUserCondDestroyRecLock(lock); } /* *----------------------------------------------------------------------------- * * MXUser_TryAcquireRecLock -- * * An attempt is made to conditionally acquire (lock) a recursive lock. * * Only the owner (thread) of a recursive lock may recurse on it. * * Results: * TRUE Acquired (locked) * FALSE Not acquired * * Side effects: * None * * NOTE: * A "TryAcquire" does not rank check should the acquisition succeed. * This duplicates the behavor of MX locks. * *----------------------------------------------------------------------------- */ Bool MXUser_TryAcquireRecLock(MXUserRecLock *lock) // IN/OUT: { Bool success; ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC); Atomic_Inc(&lock->refCount); if (lock->vmmLock) { ASSERT(MXUserMX_TryLockRec); success = (*MXUserMX_TryLockRec)(lock->vmmLock); } else { if (MXUserTryAcquireFail(lock->header.name)) { success = FALSE; goto bail; } success = MXRecLockTryAcquire(&lock->recursiveLock); if (success) { MXUserAcquisitionTracking(&lock->header, FALSE); } if (vmx86_stats) { MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); if (LIKELY(acquireStats != NULL)) { MXUserAcquisitionSample(&acquireStats->data, success, !success, 0ULL); } } } bail: if (Atomic_FetchAndDec(&lock->refCount) == 1) { Panic("%s: Zero reference count upon exit\n", __FUNCTION__); } return success; } /* *----------------------------------------------------------------------------- * * MXUser_IsCurThreadHoldingRecLock -- * * Is a recursive lock held by the calling thread? * * Results: * TRUE Yes * FALSE No * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool MXUser_IsCurThreadHoldingRecLock(MXUserRecLock *lock) // IN: { Bool result; ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC); Atomic_Inc(&lock->refCount); if (lock->vmmLock) { ASSERT(MXUserMX_IsLockedByCurThreadRec); result = (*MXUserMX_IsLockedByCurThreadRec)(lock->vmmLock); } else { result = MXRecLockIsOwner(&lock->recursiveLock); } if (Atomic_FetchAndDec(&lock->refCount) == 1) { Panic("%s: Zero reference count upon exit\n", __FUNCTION__); } return result; } /* *----------------------------------------------------------------------------- * * MXUser_CreateSingletonRecLock -- * * Ensures that the specified backing object (Atomic_Ptr) contains a * recursive lock. This is useful for modules that need to protect * something with a lock but don't have an existing Init() entry point * where a lock can be created. * * Results: * A pointer to the requested lock. * * Side effects: * Generally the lock's resources are intentionally leaked (by design). * *----------------------------------------------------------------------------- */ MXUserRecLock * MXUser_CreateSingletonRecLock(Atomic_Ptr *lockStorage, // IN/OUT: const char *name, // IN: MX_Rank rank) // IN: { MXUserRecLock *lock; ASSERT(lockStorage); lock = Atomic_ReadPtr(lockStorage); if (UNLIKELY(lock == NULL)) { MXUserRecLock *newLock = MXUser_CreateRecLock(name, rank); lock = Atomic_ReadIfEqualWritePtr(lockStorage, NULL, (void *) newLock); if (lock) { MXUser_DestroyRecLock(newLock); } else { lock = Atomic_ReadPtr(lockStorage); } } return lock; } /* *----------------------------------------------------------------------------- * * MXUser_CreateCondVarRecLock -- * * Create a condition variable for use with the specified recurisve lock. * * Results: * As above. * * Side effects: * The created condition variable will cause a run-time error if it is * used with a lock other than the one it was created for. * *----------------------------------------------------------------------------- */ MXUserCondVar * MXUser_CreateCondVarRecLock(MXUserRecLock *lock) { MXUserCondVar *condVar; ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC); ASSERT(lock->vmmLock == NULL); // only unbound locks Atomic_Inc(&lock->refCount); condVar = MXUserCreateCondVar(&lock->header, &lock->recursiveLock); if (Atomic_FetchAndDec(&lock->refCount) == 1) { Panic("%s: Zero reference count upon exit\n", __FUNCTION__); } return condVar; } /* *----------------------------------------------------------------------------- * * MXUser_WaitCondVarRecLock -- * * Block (sleep) on the specified condition variable. The specified lock * is released upon blocking and is reacquired before returning from this * function. * * Results: * As above. * * Side effects: * It is possible to return from this routine without the condtion * variable having been signalled (spurious wake up); code accordingly! * *----------------------------------------------------------------------------- */ void MXUser_WaitCondVarRecLock(MXUserRecLock *lock, // IN: MXUserCondVar *condVar) // IN: { ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC); ASSERT(lock->vmmLock == NULL); // only unbound locks Atomic_Inc(&lock->refCount); MXUserWaitCondVar(&lock->header, &lock->recursiveLock, condVar, MXUSER_WAIT_INFINITE); if (Atomic_FetchAndDec(&lock->refCount) == 1) { Panic("%s: Zero reference count upon exit\n", __FUNCTION__); } } /* *----------------------------------------------------------------------------- * * MXUser_TimedWaitCondVarRecLock -- * * Block (sleep) on the specified condition variable for no longer than * the specified amount of time. The specified lock is released upon * blocking and is reacquired before returning from this function. * * Results: * As above * * Side effects: * It is possible to return from this routine without the condtion * variable having been signalled (spurious wake up); code accordingly! * *----------------------------------------------------------------------------- */ void MXUser_TimedWaitCondVarRecLock(MXUserRecLock *lock, // IN: MXUserCondVar *condVar, // IN: uint32 msecWait) // IN: { ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC); ASSERT(lock->vmmLock == NULL); // only unbound locks Atomic_Inc(&lock->refCount); MXUserWaitCondVar(&lock->header, &lock->recursiveLock, condVar, msecWait); if (Atomic_FetchAndDec(&lock->refCount) == 1) { Panic("%s: Zero reference count upon exit\n", __FUNCTION__); } } /* *----------------------------------------------------------------------------- * * MXUser_DumpRecLock -- * * Dump a recursive lock. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void MXUser_DumpRecLock(MXUserRecLock *lock) // IN: { ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC); Atomic_Inc(&lock->refCount); MXUserDumpRecLock(&lock->header); if (Atomic_FetchAndDec(&lock->refCount) == 1) { Panic("%s: Zero reference count upon exit\n", __FUNCTION__); } } /* *----------------------------------------------------------------------------- * * MXUser_GetRecLockVmm -- * * Return lock->vmmLock. Perhaps this lock is bound to an MX lock. * * Results: * lock->vmmLock is returned. * * Side effects: * None * *----------------------------------------------------------------------------- */ struct MX_MutexRec * MXUser_GetRecLockVmm(MXUserRecLock *lock) // IN: { ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC); return lock->vmmLock; } /* *----------------------------------------------------------------------------- * * MXUser_GetRecLockRank -- * * Return the rank of the specified recursive lock. * * Results: * The rank of the specified recursive lock is returned. * * Side effects: * None * *----------------------------------------------------------------------------- */ MX_Rank MXUser_GetRecLockRank(MXUserRecLock *lock) // IN: { ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC); return lock->header.rank; } /* *----------------------------------------------------------------------------- * * MXUser_BindMXMutexRec -- * * Create an MXUserRecLock that is bound to an (already) initialized * MX_MutexRec. * * Results: * NULL Creation failed * !NULL Creation succeeded * * Side effects: * None * *----------------------------------------------------------------------------- */ MXUserRecLock * MXUser_BindMXMutexRec(struct MX_MutexRec *mutex, // IN: MX_Rank rank) // IN: { MXUserRecLock *lock; ASSERT(mutex); /* * Cannot perform a binding unless MX_Init has been called. As a side * effect it registers these hook functions. */ if ((MXUserMX_LockRec == NULL) || (MXUserMX_UnlockRec == NULL) || (MXUserMX_TryLockRec == NULL) || (MXUserMX_IsLockedByCurThreadRec == NULL)) { return NULL; } /* * Initialize the header (so it looks correct in memory) but don't connect * this lock to the MXUser statistics or debugging tracking - the MX lock * system will take care of this. */ lock = Util_SafeCalloc(1, sizeof(*lock)); lock->header.signature = MXUserGetSignature(MXUSER_TYPE_REC); lock->header.name = Str_SafeAsprintf(NULL, "MX_%p", mutex); lock->header.rank = rank; lock->header.serialNumber = MXUserAllocSerialNumber(); lock->header.dumpFunc = NULL; lock->header.statsFunc = NULL; Atomic_WritePtr(&lock->acquireStatsMem, NULL); Atomic_WritePtr(&lock->heldStatsMem, NULL); Atomic_Write(&lock->refCount, 1); lock->vmmLock = mutex; return lock; } /* *----------------------------------------------------------------------------- * * MXUser_IncRefRecLock -- * * Add a reference to the lock to prevent an immediate destory from * succeeding. * * Results: * As above * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUser_IncRefRecLock(MXUserRecLock *lock) // IN: { ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC); Atomic_Inc(&lock->refCount); } /* *----------------------------------------------------------------------------- * * MXUser_DecRefRecLock -- * * Remove a reference to the lock. If the reference count is zero, * the lock is destroyed. * * Results: * As above * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUser_DecRefRecLock(MXUserRecLock *lock) // IN: { ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC); MXUserCondDestroyRecLock(lock); } #if defined(VMX86_VMX) #include "mutex.h" #include "mutexRankVMX.h" /* *---------------------------------------------------------------------------- * * MXUser_InitFromMXRec -- * * Initialize a MX_MutexRec lock and create a MXUserRecLock that binds * to it. * * Results: * Pointer to the MXUserRecLock. * * Side effects: * None. * *---------------------------------------------------------------------------- */ MXUserRecLock * MXUser_InitFromMXRec(const char *name, // IN: MX_MutexRec *mutex, // IN: MX_Rank rank, // IN: Bool isBelowBull) // IN: { MXUserRecLock *userLock; ASSERT(isBelowBull == (rank < RANK_userlevelLock)); MX_InitLockRec(name, rank, mutex); userLock = MXUser_BindMXMutexRec(mutex, rank); ASSERT(userLock); return userLock; } #endif open-vm-tools-9.4.0-1280544/lib/lock/ulStats.c0000644765153500003110000006541112220061556016747 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #include // for sqrt; should be removed soon #if defined(_WIN32) #include #endif #include "vmware.h" #include "str.h" #include "util.h" #include "userlock.h" #include "ulInt.h" #include "hostinfo.h" #include "log.h" #include "logFixed.h" #define BINS_PER_DECADE 100 static double mxUserContentionRatio = 0.0; // always "off" static uint64 mxUserContentionCount = 0; // always "off" static Atomic_Ptr mxLockMemPtr; // internal singleton lock static ListItem *mxUserLockList; // list of all MXUser locks typedef struct { void *address; uint64 timeValue; } TopOwner; #define TOPOWNERS 10 struct MXUserHisto { char *typeName; // Type (name) of histogram uint64 *binData; // Hash table bins uint64 totalSamples; // Population sample size uint64 minValue; // Min value allowed uint64 maxValue; // Max value allowed uint32 numBins; // Number of histogram bins TopOwner ownerArray[TOPOWNERS]; // List of top owners }; static Bool mxUserTrackHeldTimes = FALSE; static char *mxUserHistoLine = NULL; static uint32 mxUserMaxLineLength = 0; static void *mxUserStatsContext = NULL; static void (*mxUserStatsFunc)(void *context, const char *fmt, va_list ap) = NULL; /* *----------------------------------------------------------------------------- * * MXUserAddToList -- * * Add a newly created lock to the list of all userland locks. * * Results: * The lock is added to the list. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUserAddToList(MXUserHeader *header) // IN: { MXRecLock *listLock = MXUserInternalSingleton(&mxLockMemPtr); /* Tolerate a failure. This is too low down to log */ if (listLock) { MXRecLockAcquire(listLock, NULL); // non-stats LIST_QUEUE(&header->item, &mxUserLockList); MXRecLockRelease(listLock); } } /* *----------------------------------------------------------------------------- * * MXUserRemoveFromList -- * * Remove a lock from the list of all userland locks. * * Results: * The lock is removed from the list. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUserRemoveFromList(MXUserHeader *header) // IN: { MXRecLock *listLock = MXUserInternalSingleton(&mxLockMemPtr); /* Tolerate a failure. This is too low down to log */ if (listLock) { MXRecLockAcquire(listLock, NULL); // non-stats LIST_DEL(&header->item, &mxUserLockList); MXRecLockRelease(listLock); } } /* *----------------------------------------------------------------------------- * * MXUserHistoIndex -- * * Return the index into the histogram bins. This makes use of a * fixed point approximation method. * * Results: * (uint32) (BINS_PER_DECADE * log10(value)) * * Side effects: * The computed value may actually be larger than expected by a tiny * amount - the log10 method is a ratio of two integers. * *----------------------------------------------------------------------------- */ static uint32 MXUserHistoIndex(uint64 value) // IN: { uint32 index; if (value == 0) { index = 0; } else { uint32 numerator = 0; uint32 denominator = 0; LogFixed_Base10(value, &numerator, &denominator); index = (BINS_PER_DECADE * numerator) / denominator; } return index; } /* *----------------------------------------------------------------------------- * * MXUserHistoSetup -- * * Set up a histogram object using the specified minimum value and * decade coverage. The minimum value must be 1 or a power of 10. * * These histograms coverage values from the minimum to * minimum * 10^decades with BINS_PER_DECADE bins for each decade * covered. * * Results: * NULL Failure * !NULL Success (a histogram object pointer is returned) * * Side effects: * None * *----------------------------------------------------------------------------- */ MXUserHisto * MXUserHistoSetUp(char *typeName, // type (name) of histogram uint64 minValue, // IN: ns; 1, 10, 100, 1000... uint32 decades) // IN: decimal decades to cover from min { MXUserHisto *histo; ASSERT(decades > 0); ASSERT((minValue != 0) && ((minValue == 1) || ((minValue % 10) == 0))); histo = Util_SafeCalloc(sizeof(*histo), 1); histo->typeName = Util_SafeStrdup(typeName); histo->numBins = BINS_PER_DECADE * decades; histo->binData = Util_SafeCalloc(sizeof(uint64), histo->numBins); histo->totalSamples = 0; histo->minValue = minValue; histo->maxValue = histo->minValue; while (decades--) { histo->maxValue *= 10; } return histo; } /* *----------------------------------------------------------------------------- * * MXUserHistoTearDown -- * * Tear down a histogram object; * * Results: * The histogram object is torn down. Don't use it after this. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUserHistoTearDown(MXUserHisto *histo) // IN: { if (histo != NULL) { free(histo->typeName); free(histo->binData); free(histo); } } /* *----------------------------------------------------------------------------- * * MXUserHistoSample -- * * Add a sample to the specified histogram. * * Out-of-bounds on the low end are summed in bin[0]. * Out-of-bounds on the high end are summed in bin[numBins - 1]. * * Results: * As expected. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUserHistoSample(MXUserHisto *histo, // IN/OUT: uint64 durationNS, // IN: void *ownerRetAddr) // IN: { uint32 i; uint32 index; ASSERT(histo); histo->totalSamples++; if (durationNS < histo->minValue) { index = 0; } else { index = MXUserHistoIndex(durationNS / histo->minValue); if (index > histo->numBins - 1) { index = histo->numBins - 1; } } ASSERT(index < histo->numBins); histo->binData[index]++; index = 0; for (i = 0; i < TOPOWNERS; i++) { if (histo->ownerArray[i].address == ownerRetAddr) { index = i; break; } if (histo->ownerArray[i].timeValue < histo->ownerArray[index].timeValue) { index = i; } } if (durationNS > histo->ownerArray[index].timeValue) { histo->ownerArray[index].address = ownerRetAddr; histo->ownerArray[index].timeValue = durationNS; } } /* *----------------------------------------------------------------------------- * * MXUserStatsLog -- * * Output the statistics data * * Results: * As above * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void MXUserStatsLog(const char *fmt, // IN: ...) // IN: { va_list ap; ASSERT(mxUserStatsFunc); va_start(ap, fmt); (*mxUserStatsFunc)(mxUserStatsContext, fmt, ap); va_end(ap); } /* *----------------------------------------------------------------------------- * * MXUserHistoDump -- * * Dump the specified histogram for the specified lock. * * Results: * The histogram is dumped to the statistics log. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUserHistoDump(MXUserHisto *histo, // IN: MXUserHeader *header) // IN: { ASSERT(header); ASSERT(histo); if (histo->totalSamples) { char *p; uint32 i; uint32 spaceLeft; ASSERT(mxUserHistoLine); i = Str_Sprintf(mxUserHistoLine, mxUserMaxLineLength, "MXUser: h l=%u t=%s min=%"FMT64"u max=%"FMT64"u\n", header->serialNumber, histo->typeName, histo->minValue, histo->maxValue); /* * The terminating "\n\0" will be overwritten each time a histogram * bin is added to the line. This will ensure that the line is always * properly terminated no matter what happens. */ p = &mxUserHistoLine[i - 1]; spaceLeft = mxUserMaxLineLength - i - 2; /* Add as many histogram bins as possible within the line limitations */ for (i = 0; i < histo->numBins; i++) { if (histo->binData[i] != 0) { uint32 len; char binEntry[32]; len = Str_Sprintf(binEntry, sizeof binEntry, " %u-%"FMT64"u\n", i, histo->binData[i]); if (len < spaceLeft) { /* * Append the bin number, bin count pair to the end of the * string. This includes the terminating "\n\0". Update the * pointer to the next free place to point to the '\n'. If * another entry is made, things work out properly. If not * the string is properly terminated as a line. */ Str_Strcpy(p, binEntry, len + 1); p += len - 1; spaceLeft -= len; } else { break; } } } MXUserStatsLog("%s", mxUserHistoLine); i = Str_Sprintf(mxUserHistoLine, mxUserMaxLineLength, "MXUser: ht l=%u t=%s\n", header->serialNumber, histo->typeName); p = &mxUserHistoLine[i - 1]; spaceLeft = mxUserMaxLineLength - i - 2; for (i = 0; i < TOPOWNERS; i++) { if (histo->ownerArray[i].address != NULL) { uint32 len; char binEntry[32]; /* Use a debugger to change the address to a symbol */ len = Str_Sprintf(binEntry, sizeof binEntry, " %p-%"FMT64"u\n", histo->ownerArray[i].address, histo->ownerArray[i].timeValue); if (len < spaceLeft) { /* * Append the address, time value pair to the end of the * string. This includes the terminating "\n\0". Update the * pointer to the next free place to point to the '\n'. If * another entry is made, things work out properly. If not * the string is properly terminated as a line. */ Str_Strcpy(p, binEntry, len + 1); p += len - 1; spaceLeft -= len; } else { break; } } } MXUserStatsLog("%s", mxUserHistoLine); } } /* *----------------------------------------------------------------------------- * * MXUserBasicStatsSample -- * * Add a sample to the "pure" statistics object. * * Results: * The sample is added. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUserBasicStatsSample(MXUserBasicStats *stats, // IN/OUT: uint64 durationNS) // IN: { stats->numSamples++; if (durationNS < stats->minTime) { stats->minTime = durationNS; } if (durationNS > stats->maxTime) { stats->maxTime = durationNS; } stats->timeSum += durationNS; /* Do things in floating point to avoid uint64 overflow */ stats->timeSquaredSum += ((double) durationNS) * ((double) durationNS); } /* *----------------------------------------------------------------------------- * * MXUserBasicStatsSetUp -- * * Set up the "pure" statistics object. * * Results: * The statistics are set up. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUserBasicStatsSetUp(MXUserBasicStats *stats, // IN/OUT: char *typeName) // IN: { stats->typeName = Util_SafeStrdup(typeName); stats->numSamples = 0; stats->minTime = ~CONST64U(0); stats->maxTime = 0; stats->timeSum = 0; stats->timeSquaredSum = 0.0; } /* *----------------------------------------------------------------------------- * * MXUserDumpBasicStats -- * * Dump the basic statistics. This routine may run during concurrent * locking activity so explicit checks are necessary to deal with * jittering data. * * Results: * Interesting data is added to the statistics log. * * Side effects: * None * *----------------------------------------------------------------------------- */ static double MXUserSqrt(double x) // IN: hack until next round when FP goes away { double xn; double xn1 = x; if (x == 0.0) { return 0.0; } do { xn = xn1; xn1 = (xn + x/xn) / 2.0; } while (fabs(xn1 - xn) > 1E-10); return xn1; } void MXUserDumpBasicStats(MXUserBasicStats *stats, // IN: MXUserHeader *header) // IN: { uint64 stdDev; if (stats->numSamples < 2) { /* * It's possible to get a request to dump statistics when there * aren't any (e.g. a lock has been acquired but never released so * there are no "held" statistics yet). Ignore requests to dump * statistics when there aren't any. */ if (stats->numSamples == 0) { return; } stdDev = 0; } else { double num; double mean; double variance; num = (double) stats->numSamples; mean = ((double) stats->timeSum) / num; variance = (stats->timeSquaredSum - (num*mean*mean)) / (num - 1.0); stdDev = (variance < 0.0) ? 0 : (uint64) (MXUserSqrt(variance) + 0.5); } MXUserStatsLog("MXUser: e l=%u t=%s c=%"FMT64"u min=%"FMT64"u " "max=%"FMT64"u mean=%"FMT64"u sd=%"FMT64"u\n", header->serialNumber, stats->typeName, stats->numSamples, stats->minTime, stats->maxTime, stats->timeSum/stats->numSamples, stdDev); } /* *----------------------------------------------------------------------------- * * MXUserBasicStatsTearDown -- * * Tear down an basic statistics object. * * Results: * The statistics are set up. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUserBasicStatsTearDown(MXUserBasicStats *stats) // IN/OUT: { free(stats->typeName); stats->typeName = NULL; } /* *----------------------------------------------------------------------------- * * MXUserAcquisitionStatsSetUp -- * * Set up an acquisition statistics object. * * Results: * The statistics are set up. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUserAcquisitionStatsSetUp(MXUserAcquisitionStats *stats) // IN/OUT: { MXUserBasicStatsSetUp(&stats->basicStats, MXUSER_STAT_CLASS_ACQUISITION); stats->numAttempts = 0; stats->numSuccesses = 0; stats->numSuccessesContended = 0; stats->totalContentionTime = 0; stats->successContentionTime = 0; } /* *----------------------------------------------------------------------------- * * MXUserAcquisitionSample -- * * Track the acquisition specific statistical data. * * Results: * Much CPU time may be used. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUserAcquisitionSample(MXUserAcquisitionStats *stats, // IN/OUT: Bool wasAcquired, // IN: Bool wasContended, // IN: uint64 elapsedTime) // IN: { stats->numAttempts++; if (wasAcquired) { stats->numSuccesses++; if (wasContended) { stats->numSuccessesContended++; stats->totalContentionTime += elapsedTime; stats->successContentionTime += elapsedTime; } MXUserBasicStatsSample(&stats->basicStats, elapsedTime); } else { ASSERT(wasContended); stats->totalContentionTime += elapsedTime; } } /* *----------------------------------------------------------------------------- * * MXUserDumpAcquisitionStats -- * * Dump the acquisition statistics for the specified lock. * * Results: * Much CPU time may be used. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUserDumpAcquisitionStats(MXUserAcquisitionStats *stats, // IN: MXUserHeader *header) // IN: { if (stats->numAttempts > 0) { if (stats->numSuccesses > 0) { MXUserDumpBasicStats(&stats->basicStats, header); } MXUserStatsLog("MXUser: ce l=%u a=%"FMT64"u s=%"FMT64"u sc=%"FMT64"u " "sct=%"FMT64"u t=%"FMT64"u\n", header->serialNumber, stats->numAttempts, stats->numSuccesses, stats->numSuccessesContended, stats->successContentionTime, stats->totalContentionTime); } } /* *----------------------------------------------------------------------------- * * MXUserAcquisitionStatsTearDown -- * * Tear down an acquisition statistics object. * * Results: * The statistics are set up. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUserAcquisitionStatsTearDown(MXUserAcquisitionStats *stats) // IN/OUT: { MXUserBasicStatsTearDown(&stats->basicStats); } /* *----------------------------------------------------------------------------- * * MXUserKitchen -- * * If you can't take the heat, get out of the kitchen! Report on the * heat generated by the specified lock's acquisition statistics. * * Results: * Data is returned. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUserKitchen(MXUserAcquisitionStats *stats, // IN: double *contentionRatio, // OUT: Bool *isHot, // OUT: Bool *doLog) // OUT: { /* * How much "heat" is this lock generating? */ if (stats->numAttempts == 0) { *contentionRatio = 0.0; } else { double basic; double acquisition; /* * Contention shows up in two ways - failed attempts to acquire * and detected contention while acquiring. Determine which is * the largest and use that as the contention ratio for the * specified statistics. */ basic = ((double) stats->numAttempts - stats->numSuccesses) / ((double) stats->numAttempts); acquisition = ((double) stats->numSuccessesContended) / ((double) stats->numSuccesses); *contentionRatio = (basic < acquisition) ? acquisition : basic; } /* * Handle the explicit control cases. * * An mxUserContentionCount value of zero (0) forces all locks to be * considered "cold", regardless of their activity. * * An mxUserContentionCount value of ~((uint64) 0) (all Fs) forces all * locks to be considered "hot" regardless of their activity, with the * side effect that no logging of "temperature changes" is done. */ if (mxUserContentionCount == 0) { // never "hot" *isHot = FALSE; *doLog = FALSE; return; } if (mxUserContentionCount == ~((uint64) 0)) { // always "hot"; no logging *isHot = TRUE; *doLog = FALSE; return; } /* * Did the thermostat trip? */ ASSERT((mxUserContentionRatio > 0.0) && (mxUserContentionRatio <= 1.0)); if (*contentionRatio >= mxUserContentionRatio) { // Yes *isHot = TRUE; *doLog = TRUE; } else { // No *doLog = FALSE; *isHot = FALSE; } } /* *----------------------------------------------------------------------------- * * MXUser_StatisticsControl -- * * Specify the settings for automatic "hot locks" operation. * * Results: * Enhanced statistics will be used or never used, depending on these * values; * * Side effects: * Unknown... * *----------------------------------------------------------------------------- */ void MXUser_StatisticsControl(double contentionRatio, // IN: uint64 minCount) // IN: { ASSERT((contentionRatio > 0.0) && (contentionRatio <= 1.0)); mxUserContentionRatio = contentionRatio; mxUserContentionCount = minCount; } /* *----------------------------------------------------------------------------- * * MXUserForceHisto -- * * Force histogram taking for the specified histogram. * * Results: * As above. * * Side effects: * Memory is allocated. * *----------------------------------------------------------------------------- */ void MXUserForceHisto(Atomic_Ptr *histoPtr, // IN/OUT: char *typeName, // IN: uint64 minValue, // IN: uint32 decades) // IN: { MXUserHisto *ptr = Atomic_ReadPtr(histoPtr); if (ptr == NULL) { MXUserHisto *before; ptr = MXUserHistoSetUp(typeName, minValue, decades); before = (MXUserHisto *) Atomic_ReadIfEqualWritePtr(histoPtr, NULL, (void *) ptr); if (before) { MXUserHistoTearDown(ptr); } } } /* *----------------------------------------------------------------------------- * * MXUserStatsMode -- * * What's to be done with statistics? * * Results: * 0 Statstics are disabled * 1 Collect statistics without tracking held times * 2 Collect statistics with track held times * * Side effects: * None * *----------------------------------------------------------------------------- */ uint32 MXUserStatsMode(void) { if (vmx86_stats && (mxUserStatsFunc != NULL) && (mxUserMaxLineLength > 0)) { return mxUserTrackHeldTimes ? 2 : 1; } else { return 0; } } /* *----------------------------------------------------------------------------- * * MXUser_SetStatsFunc -- * * Establish statistics taking and reporting. This is done by registering * a statistics context, a reporting function and a maximum line length. * * A maxLineLength of zero (0) and/or a statsFunc of NULL will * disable/prevent statistics gathering. * * Results: * As above * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUser_SetStatsFunc(void *context, // IN: uint32 maxLineLength, // IN: Bool trackHeldTimes, // IN: void (*statsFunc)(void *context, // IN: const char *fmt, va_list ap)) { ASSERT(maxLineLength >= 1024); // assert a rational minimum free(mxUserHistoLine); mxUserHistoLine = Util_SafeMalloc(maxLineLength); mxUserStatsContext = context; mxUserMaxLineLength = maxLineLength; mxUserStatsFunc = statsFunc; mxUserTrackHeldTimes = trackHeldTimes; } /* *----------------------------------------------------------------------------- * * MXUser_PerLockData -- * * Perform the statistics logging duties. * * The dumping is done on active locks so the data is, at best, * approximate. This is OK for statistics builds since things should * be "close enough". * * This routine is called from within the statistics collection framework. * It is called, periodically, at the end of each statistical "epoch". * * Results: * Lots of statistics in statistics (obj/opt/stats) builds. * * Side effects: * The overhead of the statistics process may affect the timing of * events and expose bugs. Be prepared! * *----------------------------------------------------------------------------- */ void MXUser_PerLockData(void) { MXRecLock *listLock = MXUserInternalSingleton(&mxLockMemPtr); if (mxUserStatsFunc == NULL) { return; } if (listLock && MXRecLockTryAcquire(listLock)) { ListItem *entry; uint32 highestSerialNumber; static uint32 lastReportedSerialNumber = 0; highestSerialNumber = lastReportedSerialNumber; LIST_SCAN(entry, mxUserLockList) { MXUserHeader *header = LIST_CONTAINER(entry, MXUserHeader, item); /* Log the ID information for a lock that did exist previously */ if (header->serialNumber > lastReportedSerialNumber) { MXUserStatsLog("MXUser: n n=%s l=%d r=0x%x\n", header->name, header->serialNumber, header->rank); if (header->serialNumber > highestSerialNumber) { highestSerialNumber = header->serialNumber; } } /* * Perform the statistics action for any lock that has one. */ if (header->statsFunc) { (*header->statsFunc)(header); } } lastReportedSerialNumber = highestSerialNumber; MXRecLockRelease(listLock); } } /* *----------------------------------------------------------------------------- * * MXUserAllocSerialNumber -- * * Allocate and return an MXUser serial number. * * MXUser serial numbers are never recycled. * * Results: * As above. * * Side effects: * None. * *----------------------------------------------------------------------------- */ uint32 MXUserAllocSerialNumber(void) { static Atomic_uint32 firstFreeSerialNumber = { 1 }; // must start not zero return Atomic_FetchAndInc(&firstFreeSerialNumber); } open-vm-tools-9.4.0-1280544/lib/lock/ulRW.c0000644765153500003110000006701012220061556016176 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #if defined(_WIN32) #include #endif #include "vmware.h" #include "vm_basic_asm.h" #include "str.h" #include "util.h" #include "hashTable.h" #include "userlock.h" #include "hostinfo.h" #include "ulInt.h" static void MXUserFreeHashEntry(void *data) // IN: { free(data); } /* * Environment specific implementations of portable read-write locks. * * There are 5 environment specific primitives: * * MXUserNativeRWSupported Are native read-write locks supported? * MXUserNativeRWInit Allocate and initialize a native read-write lock * MXUserNativeRWDestroy Destroy a native read-write lock * MXUserNativeRWAcquire Acquire a native read-write lock * MXUserNativeRWRelease Release a native read-write lock */ #if defined(_WIN32) typedef SRWLOCK NativeRWLock; typedef VOID (WINAPI *InitializeSRWLockFn)(PSRWLOCK lock); typedef VOID (WINAPI *AcquireSRWLockSharedFn)(PSRWLOCK lock); typedef VOID (WINAPI *ReleaseSRWLockSharedFn)(PSRWLOCK lock); typedef VOID (WINAPI *AcquireSRWLockExclusiveFn)(PSRWLOCK lock); typedef VOID (WINAPI *ReleaseSRWLockExclusiveFn)(PSRWLOCK lock); static InitializeSRWLockFn pInitializeSRWLock; static AcquireSRWLockSharedFn pAcquireSRWLockShared; static ReleaseSRWLockSharedFn pReleaseSRWLockShared; static AcquireSRWLockExclusiveFn pAcquireSRWLockExclusive; static ReleaseSRWLockExclusiveFn pReleaseSRWLockExclusive; static Bool MXUserNativeRWSupported(void) { static Bool result; static Bool done = FALSE; if (!done) { HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll"); if (kernel32) { pInitializeSRWLock = (InitializeSRWLockFn) GetProcAddress(kernel32, "InitializeSRWLock"); pAcquireSRWLockShared = (AcquireSRWLockSharedFn) GetProcAddress(kernel32, "AcquireSRWLockShared"); pReleaseSRWLockShared = (ReleaseSRWLockSharedFn) GetProcAddress(kernel32, "ReleaseSRWLockShared"); pAcquireSRWLockExclusive = (AcquireSRWLockExclusiveFn) GetProcAddress(kernel32, "AcquireSRWLockExclusive"); pReleaseSRWLockExclusive = (ReleaseSRWLockExclusiveFn) GetProcAddress(kernel32, "ReleaseSRWLockExclusive"); COMPILER_MEM_BARRIER(); result = ((pInitializeSRWLock != NULL) && (pAcquireSRWLockShared != NULL) && (pReleaseSRWLockShared != NULL) && (pAcquireSRWLockExclusive != NULL) && (pReleaseSRWLockExclusive != NULL)); COMPILER_MEM_BARRIER(); } else { result = FALSE; } done = TRUE; } return result; } static Bool MXUserNativeRWInit(NativeRWLock *lock) // IN: { ASSERT(pInitializeSRWLock); (*pInitializeSRWLock)(lock); return TRUE; } static int MXUserNativeRWDestroy(NativeRWLock *lock) // IN: { return 0; // nothing to do } static INLINE Bool MXUserNativeRWAcquire(NativeRWLock *lock, // IN: Bool forRead, // IN: int *err) // OUT: { if (forRead) { ASSERT(pAcquireSRWLockShared); (*pAcquireSRWLockShared)(lock); } else { ASSERT(pAcquireSRWLockExclusive); (*pAcquireSRWLockExclusive)(lock); } *err = 0; return FALSE; } static INLINE int MXUserNativeRWRelease(NativeRWLock *lock, // IN: Bool forRead) // IN: { if (forRead) { ASSERT(pReleaseSRWLockShared); (*pReleaseSRWLockShared)(lock); } else { ASSERT(pReleaseSRWLockExclusive); (*pReleaseSRWLockExclusive)(lock); } return 0; } #else // _WIN32 #if defined(PTHREAD_RWLOCK_INITIALIZER) typedef pthread_rwlock_t NativeRWLock; #else typedef int NativeRWLock; #endif static Bool MXUserNativeRWSupported(void) { #if defined(PTHREAD_RWLOCK_INITIALIZER) return TRUE; #else return FALSE; #endif } static Bool MXUserNativeRWInit(NativeRWLock *lock) // IN: { #if defined(PTHREAD_RWLOCK_INITIALIZER) return (pthread_rwlock_init(lock, NULL) == 0); #else return FALSE; #endif } static int MXUserNativeRWDestroy(NativeRWLock *lock) // IN: { #if defined(PTHREAD_RWLOCK_INITIALIZER) return pthread_rwlock_destroy(lock); #else return ENOSYS; #endif } static INLINE Bool MXUserNativeRWAcquire(NativeRWLock *lock, // IN: Bool forRead, // IN: int *err) // OUT: { Bool contended; #if defined(PTHREAD_RWLOCK_INITIALIZER) *err = (forRead) ? pthread_rwlock_tryrdlock(lock) : pthread_rwlock_trywrlock(lock); contended = (*err != 0); if (*err == EBUSY) { *err = (forRead) ? pthread_rwlock_rdlock(lock) : pthread_rwlock_wrlock(lock); } #else *err = ENOSYS; contended = FALSE; #endif return contended; } static INLINE int MXUserNativeRWRelease(NativeRWLock *lock, // IN: Bool forRead) // IN: { #if defined(PTHREAD_RWLOCK_INITIALIZER) return pthread_rwlock_unlock(lock); #else return ENOSYS; #endif } #endif // _WIN32 typedef enum { RW_UNLOCKED, RW_LOCKED_FOR_READ, RW_LOCKED_FOR_WRITE } HolderState; typedef struct { HolderState state; VmTimeType holdStart; } HolderContext; typedef struct { MXUserAcquisitionStats data; Atomic_Ptr histo; } MXUserAcquireStats; typedef struct { MXUserBasicStats data; Atomic_Ptr histo; } MXUserHeldStats; struct MXUserRWLock { MXUserHeader header; Bool useNative; NativeRWLock nativeLock; MXRecLock recursiveLock; Atomic_uint32 holderCount; HashTable *holderTable; Atomic_Ptr heldStatsMem; Atomic_Ptr acquireStatsMem; }; /* *----------------------------------------------------------------------------- * * MXUserStatsActionRW -- * * Perform the statistics action for the specified lock. * * Results: * As above. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void MXUserStatsActionRW(MXUserHeader *header) // IN: { MXUserRWLock *lock = (MXUserRWLock *) header; MXUserHeldStats *heldStats = Atomic_ReadPtr(&lock->heldStatsMem); MXUserAcquireStats *acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); if (heldStats) { MXUserDumpBasicStats(&heldStats->data, header); if (Atomic_ReadPtr(&heldStats->histo) != NULL) { MXUserHistoDump(Atomic_ReadPtr(&heldStats->histo), header); } } if (acquireStats) { Bool isHot; Bool doLog; double contentionRatio; /* * Dump the statistics for the specified lock. */ MXUserDumpAcquisitionStats(&acquireStats->data, header); if (Atomic_ReadPtr(&acquireStats->histo) != NULL) { MXUserHistoDump(Atomic_ReadPtr(&acquireStats->histo), header); } /* * Has the lock gone "hot"? If so, implement the hot actions. */ MXUserKitchen(&acquireStats->data, &contentionRatio, &isHot, &doLog); if (isHot) { MXUserForceHisto(&acquireStats->histo, MXUSER_STAT_CLASS_ACQUISITION, MXUSER_DEFAULT_HISTO_MIN_VALUE_NS, MXUSER_DEFAULT_HISTO_DECADES); if (heldStats) { MXUserForceHisto(&heldStats->histo, MXUSER_STAT_CLASS_HELD, MXUSER_DEFAULT_HISTO_MIN_VALUE_NS, MXUSER_DEFAULT_HISTO_DECADES); } if (doLog) { Log("HOT LOCK (%s); contention ratio %f\n", lock->header.name, contentionRatio); } } } } /* *----------------------------------------------------------------------------- * * MXUser_ControlRWLock -- * * Perform the specified command on the specified lock. * * Results: * TRUE succeeded * FALSE failed * * Side effects: * Depends on the command, no? * *----------------------------------------------------------------------------- */ Bool MXUser_ControlRWLock(MXUserRWLock *lock, // IN/OUT: uint32 command, // IN: ...) // IN: { Bool result; ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_RW); switch (command) { case MXUSER_CONTROL_ACQUISITION_HISTO: { if (vmx86_stats) { MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); if (acquireStats == NULL) { result = FALSE; } else { va_list a; uint32 decades; uint64 minValue; va_start(a, command); minValue = va_arg(a, uint64); decades = va_arg(a, uint32); va_end(a); MXUserForceHisto(&acquireStats->histo, MXUSER_STAT_CLASS_ACQUISITION, minValue, decades); result = TRUE; } } else { result = FALSE; } break; } case MXUSER_CONTROL_HELD_HISTO: { if (vmx86_stats) { MXUserHeldStats *heldStats = Atomic_ReadPtr(&lock->heldStatsMem); if (heldStats == NULL) { result = FALSE; } else { va_list a; uint32 decades; uint32 minValue; va_start(a, command); minValue = va_arg(a, uint64); decades = va_arg(a, uint32); va_end(a); MXUserForceHisto(&heldStats->histo, MXUSER_STAT_CLASS_HELD, minValue, decades); result = TRUE; } } else { result = FALSE; } break; } case MXUSER_CONTROL_ENABLE_STATS: { if (vmx86_stats) { va_list a; Bool trackHeldTimes; MXUserHeldStats *heldStats; MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); if (LIKELY(acquireStats == NULL)) { MXUserAcquireStats *before; acquireStats = Util_SafeCalloc(1, sizeof(*acquireStats)); MXUserAcquisitionStatsSetUp(&acquireStats->data); before = Atomic_ReadIfEqualWritePtr(&lock->acquireStatsMem, NULL, (void *) acquireStats); if (before) { free(acquireStats); } } va_start(a, command); trackHeldTimes = va_arg(a, int); va_end(a); heldStats = Atomic_ReadPtr(&lock->heldStatsMem); if ((heldStats == NULL) && trackHeldTimes) { MXUserHeldStats *before; heldStats = Util_SafeCalloc(1, sizeof(*heldStats)); MXUserBasicStatsSetUp(&heldStats->data, MXUSER_STAT_CLASS_HELD); before = Atomic_ReadIfEqualWritePtr(&lock->heldStatsMem, NULL, (void *) heldStats); if (before) { free(heldStats); } } lock->header.statsFunc = MXUserStatsActionRW; result = TRUE; } else { result = FALSE; } break; } default: result = FALSE; } return result; } /* *----------------------------------------------------------------------------- * * MXUserDumpRWLock -- * * Dump an read-write lock. * * Results: * A dump. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUserDumpRWLock(MXUserHeader *header) // IN: { MXUserRWLock *lock = (MXUserRWLock *) header; Warning("%s: Read-write lock @ 0x%p\n", __FUNCTION__, lock); Warning("\tsignature 0x%X\n", lock->header.signature); Warning("\tname %s\n", lock->header.name); Warning("\trank 0x%X\n", lock->header.rank); Warning("\tserial number %u\n", lock->header.serialNumber); if (LIKELY(lock->useNative)) { Warning("\taddress of native lock 0x%p\n", &lock->nativeLock); } else { Warning("\tcount %d\n", MXRecLockCount(&lock->recursiveLock)); } Warning("\tholderCount %d\n", Atomic_Read(&lock->holderCount)); } /* *----------------------------------------------------------------------------- * * MXUser_CreateRWLock -- * * Create a read/write lock. * * If native read-write locks are not available, a recursive lock will * be used to provide one reader or one writer access... which is * better than nothing. * * Results: * A pointer to a read/write lock. * * Side effects: * None * *----------------------------------------------------------------------------- */ MXUserRWLock * MXUser_CreateRWLock(const char *userName, // IN: MX_Rank rank) // IN: { Bool lockInited; char *properName; MXUserRWLock *lock; Bool useNative = MXUserNativeRWSupported(); lock = Util_SafeCalloc(1, sizeof(*lock)); if (userName == NULL) { if (LIKELY(useNative)) { properName = Str_SafeAsprintf(NULL, "RW-%p", GetReturnAddress()); } else { /* emulated */ properName = Str_SafeAsprintf(NULL, "RWemul-%p", GetReturnAddress()); } } else { properName = Util_SafeStrdup(userName); } lock->header.signature = MXUserGetSignature(MXUSER_TYPE_RW); lock->header.name = properName; lock->header.rank = rank; lock->header.serialNumber = MXUserAllocSerialNumber(); lock->header.dumpFunc = MXUserDumpRWLock; /* * Always attempt to use native locks when they are available. If, for some * reason, a native lock should be available but isn't, fall back to using * an internal recursive lock - something is better than nothing. */ lock->useNative = useNative && MXUserNativeRWInit(&lock->nativeLock); lockInited = MXRecLockInit(&lock->recursiveLock); if (LIKELY(lockInited)) { uint32 statsMode; lock->holderTable = HashTable_Alloc(256, HASH_INT_KEY | HASH_FLAG_ATOMIC, MXUserFreeHashEntry); statsMode = MXUserStatsMode(); switch (statsMode) { case 0: lock->header.statsFunc = NULL; Atomic_WritePtr(&lock->acquireStatsMem, NULL); Atomic_WritePtr(&lock->heldStatsMem, NULL); break; case 1: MXUser_ControlRWLock(lock, MXUSER_CONTROL_ENABLE_STATS, FALSE); break; case 2: MXUser_ControlRWLock(lock, MXUSER_CONTROL_ENABLE_STATS, TRUE); break; default: Panic("%s: unknown stats mode: %d!\n", __FUNCTION__, statsMode); } MXUserAddToList(&lock->header); } else { if (lock->useNative) { MXUserNativeRWDestroy(&lock->nativeLock); } free(properName); free(lock); lock = NULL; } return lock; } /* *----------------------------------------------------------------------------- * * MXUser_DestroyRWLock -- * * Destroy a read-write lock. * * Results: * The lock is destroyed. Don't try to use the pointer again. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUser_DestroyRWLock(MXUserRWLock *lock) // IN: { if (LIKELY(lock != NULL)) { MXUserValidateHeader(&lock->header, MXUSER_TYPE_RW); if (Atomic_Read(&lock->holderCount) != 0) { MXUserDumpAndPanic(&lock->header, "%s: Destroy on an acquired read-write lock\n", __FUNCTION__); } if (LIKELY(lock->useNative)) { int err = MXUserNativeRWDestroy(&lock->nativeLock); if (UNLIKELY(err != 0)) { MXUserDumpAndPanic(&lock->header, "%s: Internal error (%d)\n", __FUNCTION__, err); } } lock->header.signature = 0; // just in case... MXRecLockDestroy(&lock->recursiveLock); MXUserRemoveFromList(&lock->header); if (vmx86_stats) { MXUserHeldStats *heldStats; MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); if (LIKELY(acquireStats != NULL)) { MXUserAcquisitionStatsTearDown(&acquireStats->data); MXUserHistoTearDown(Atomic_ReadPtr(&acquireStats->histo)); free(acquireStats); } heldStats = Atomic_ReadPtr(&lock->heldStatsMem); if (UNLIKELY(heldStats != NULL)) { MXUserBasicStatsTearDown(&heldStats->data); MXUserHistoTearDown(Atomic_ReadPtr(&heldStats->histo)); free(heldStats); } } HashTable_FreeUnsafe(lock->holderTable); free(lock->header.name); lock->header.name = NULL; free(lock); } } /* *----------------------------------------------------------------------------- * * MXUserGetHolderContext -- * * Look up the context of the calling thread with respect to the * specified lock and return it. * * Results: * As above. * * Side effects: * None * *----------------------------------------------------------------------------- */ static HolderContext * MXUserGetHolderContext(MXUserRWLock *lock) // IN: { HolderContext *result; void *threadID = MXUserCastedThreadID(); ASSERT(lock->holderTable); if (!HashTable_Lookup(lock->holderTable, threadID, (void **) &result)) { HolderContext *newContext = Util_SafeMalloc(sizeof(HolderContext)); newContext->holdStart = 0; newContext->state = RW_UNLOCKED; result = HashTable_LookupOrInsert(lock->holderTable, threadID, (void *) newContext); if (result != newContext) { free(newContext); } } return result; } /* *----------------------------------------------------------------------------- * * MXUserAcquisition -- * * Acquire a read-write lock in the specified mode. * * Results: * As above. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void MXUserAcquisition(MXUserRWLock *lock, // IN/OUT: Bool forRead) // IN: { HolderContext *myContext; ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_RW); MXUserAcquisitionTracking(&lock->header, TRUE); myContext = MXUserGetHolderContext(lock); if (UNLIKELY(myContext->state != RW_UNLOCKED)) { MXUserDumpAndPanic(&lock->header, "%s: AcquireFor%s after AcquireFor%s\n", __FUNCTION__, forRead ? "Read" : "Write", (myContext->state == RW_LOCKED_FOR_READ) ? "Read" : "Write"); } if (vmx86_stats) { VmTimeType value; MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); if (lock->useNative) { int err = 0; Bool contended; VmTimeType begin = Hostinfo_SystemTimerNS(); contended = MXUserNativeRWAcquire(&lock->nativeLock, forRead, &err); value = contended ? Hostinfo_SystemTimerNS() - begin : 0; if (UNLIKELY(err != 0)) { MXUserDumpAndPanic(&lock->header, "%s: Error %d: contended %d\n", __FUNCTION__, err, contended); } } else { value = 0; MXRecLockAcquire(&lock->recursiveLock, (acquireStats == NULL) ? NULL : &value); } if (LIKELY(acquireStats != NULL)) { MXUserHisto *histo; MXUserHeldStats *heldStats; /* * The statistics are not atomically safe so protect them when * necessary. */ if (forRead && lock->useNative) { MXRecLockAcquire(&lock->recursiveLock, NULL); // non-stats } MXUserAcquisitionSample(&acquireStats->data, TRUE, value != 0, value); histo = Atomic_ReadPtr(&acquireStats->histo); if (UNLIKELY(histo != NULL)) { MXUserHistoSample(histo, value, GetReturnAddress()); } if (forRead && lock->useNative) { MXRecLockRelease(&lock->recursiveLock); } heldStats = Atomic_ReadPtr(&lock->heldStatsMem); if (UNLIKELY(heldStats != NULL)) { myContext->holdStart = Hostinfo_SystemTimerNS(); } } } else { if (LIKELY(lock->useNative)) { int err = 0; MXUserNativeRWAcquire(&lock->nativeLock, forRead, &err); if (UNLIKELY(err != 0)) { MXUserDumpAndPanic(&lock->header, "%s: Error %d\n", __FUNCTION__, err); } } else { MXRecLockAcquire(&lock->recursiveLock, NULL); // non-stats } } if (!forRead || !lock->useNative) { ASSERT(Atomic_Read(&lock->holderCount) == 0); } Atomic_Inc(&lock->holderCount); myContext->state = forRead ? RW_LOCKED_FOR_READ : RW_LOCKED_FOR_WRITE; } /* *----------------------------------------------------------------------------- * * MXUser_AcquireForRead -- * * Acquire a read-write lock for read-shared access. A thread may have * only one read lock outstanding on a read-write lock - no recursive * access. * * Results: * The lock is acquired. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUser_AcquireForRead(MXUserRWLock *lock) // IN/OUT: { MXUserAcquisition(lock, TRUE); } /* *----------------------------------------------------------------------------- * * MXUser_AcquireForWrite -- * * Acquire a read-write lock for write-exclusive access. A thread may * have only a single write lock outstanding on a read-write lock. * * Results: * The lock is acquired. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUser_AcquireForWrite(MXUserRWLock *lock) // IN/OUT: { MXUserAcquisition(lock, FALSE); } /* *----------------------------------------------------------------------------- * * MXUser_IsCurThreadHolding -- * * Is the read-write lock held in the mode queried? * * Results: * TRUE Yes * FALSE No * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool MXUser_IsCurThreadHoldingRWLock(MXUserRWLock *lock, // IN: uint32 queryType) // IN: { HolderContext *myContext; ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_RW); myContext = MXUserGetHolderContext(lock); switch (queryType) { case MXUSER_RW_FOR_READ: return myContext->state == RW_LOCKED_FOR_READ; case MXUSER_RW_FOR_WRITE: return myContext->state == RW_LOCKED_FOR_WRITE; case MXUSER_RW_LOCKED: return myContext->state != RW_UNLOCKED; default: Panic("%s: unknown query type %d\n", __FUNCTION__, queryType); } } /* *----------------------------------------------------------------------------- * * MXUser_ReleaseRWLock -- * * A read-write lock is released (unlocked). * * Results: * The lock is released (unlocked). * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUser_ReleaseRWLock(MXUserRWLock *lock) // IN/OUT: { HolderContext *myContext; ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_RW); myContext = MXUserGetHolderContext(lock); if (vmx86_stats) { MXUserHeldStats *heldStats = Atomic_ReadPtr(&lock->heldStatsMem); if (UNLIKELY(heldStats != NULL)) { MXUserHisto *histo; VmTimeType duration = Hostinfo_SystemTimerNS() - myContext->holdStart; /* * The statistics are not always atomically safe so protect them * when necessary */ if ((myContext->state == RW_LOCKED_FOR_READ) && lock->useNative) { MXRecLockAcquire(&lock->recursiveLock, NULL); // non-stats } MXUserBasicStatsSample(&heldStats->data, duration); histo = Atomic_ReadPtr(&heldStats->histo); if (UNLIKELY(histo != NULL)) { MXUserHistoSample(histo, duration, GetReturnAddress()); } if ((myContext->state == RW_LOCKED_FOR_READ) && lock->useNative) { MXRecLockRelease(&lock->recursiveLock); } } } if (UNLIKELY(myContext->state == RW_UNLOCKED)) { MXUserDumpAndPanic(&lock->header, "%s: Release of an unacquired read-write lock\n", __FUNCTION__); } MXUserReleaseTracking(&lock->header); Atomic_Dec(&lock->holderCount); if (LIKELY(lock->useNative)) { int err = MXUserNativeRWRelease(&lock->nativeLock, myContext->state == RW_LOCKED_FOR_READ); if (UNLIKELY(err != 0)) { MXUserDumpAndPanic(&lock->header, "%s: Internal error (%d)\n", __FUNCTION__, err); } } else { ASSERT(Atomic_Read(&lock->holderCount) == 0); MXRecLockRelease(&lock->recursiveLock); } myContext->state = RW_UNLOCKED; } /* *----------------------------------------------------------------------------- * * MXUser_CreateSingletonRWLock -- * * Ensures that the specified backing object (Atomic_Ptr) contains a * RW lock. This is useful for modules that need to protect something * with a lock but don't have an existing Init() entry point where a * lock can be created. * * Results: * A pointer to the requested lock. * * Side effects: * Generally the lock's resources are intentionally leaked (by design). * *----------------------------------------------------------------------------- */ MXUserRWLock * MXUser_CreateSingletonRWLock(Atomic_Ptr *lockStorage, // IN/OUT: const char *name, // IN: MX_Rank rank) // IN: { MXUserRWLock *lock; ASSERT(lockStorage); lock = Atomic_ReadPtr(lockStorage); if (UNLIKELY(lock == NULL)) { MXUserRWLock *newLock = MXUser_CreateRWLock(name, rank); lock = Atomic_ReadIfEqualWritePtr(lockStorage, NULL, (void *) newLock); if (lock) { MXUser_DestroyRWLock(newLock); } else { lock = Atomic_ReadPtr(lockStorage); } } return lock; } open-vm-tools-9.4.0-1280544/lib/lock/Makefile.am0000644765153500003110000000230412220061556017170 0ustar dtormts################################################################################ ### Copyright 2010 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libLock.la libLock_la_SOURCES = libLock_la_SOURCES += ul.c libLock_la_SOURCES += ulCondVar.c libLock_la_SOURCES += ulExcl.c libLock_la_SOURCES += ulRec.c libLock_la_SOURCES += ulRW.c libLock_la_SOURCES += ulSema.c libLock_la_SOURCES += ulBarrier.c libLock_la_SOURCES += ulStats.c AM_CFLAGS = @LIB_USER_CPPFLAGS@ open-vm-tools-9.4.0-1280544/lib/lock/ulExcl.c0000644765153500003110000004760612220061556016552 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #include "vmware.h" #include "str.h" #include "util.h" #include "userlock.h" #include "hostinfo.h" #include "ulInt.h" #include "vm_atomic.h" typedef struct { MXUserAcquisitionStats data; Atomic_Ptr histo; } MXUserAcquireStats; typedef struct { VmTimeType holdStart; MXUserBasicStats data; Atomic_Ptr histo; } MXUserHeldStats; struct MXUserExclLock { MXUserHeader header; MXRecLock recursiveLock; Atomic_Ptr heldStatsMem; Atomic_Ptr acquireStatsMem; }; /* *----------------------------------------------------------------------------- * * MXUserStatsActionExcl -- * * Perform the statistics action for the specified lock. * * Results: * As above. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void MXUserStatsActionExcl(MXUserHeader *header) // IN: { MXUserExclLock *lock = (MXUserExclLock *) header; MXUserHeldStats *heldStats = Atomic_ReadPtr(&lock->heldStatsMem); MXUserAcquireStats *acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); if (UNLIKELY(heldStats != NULL)) { MXUserDumpBasicStats(&heldStats->data, header); if (Atomic_ReadPtr(&heldStats->histo) != NULL) { MXUserHistoDump(Atomic_ReadPtr(&heldStats->histo), header); } } if (LIKELY(acquireStats != NULL)) { Bool isHot; Bool doLog; double contentionRatio; /* * Dump the statistics for the specified lock. */ MXUserDumpAcquisitionStats(&acquireStats->data, header); if (Atomic_ReadPtr(&acquireStats->histo) != NULL) { MXUserHistoDump(Atomic_ReadPtr(&acquireStats->histo), header); } /* * Has the lock gone "hot"? If so, implement the hot actions. */ MXUserKitchen(&acquireStats->data, &contentionRatio, &isHot, &doLog); if (UNLIKELY(isHot)) { MXUserForceHisto(&acquireStats->histo, MXUSER_STAT_CLASS_ACQUISITION, MXUSER_DEFAULT_HISTO_MIN_VALUE_NS, MXUSER_DEFAULT_HISTO_DECADES); if (UNLIKELY(heldStats != NULL)) { MXUserForceHisto(&heldStats->histo, MXUSER_STAT_CLASS_HELD, MXUSER_DEFAULT_HISTO_MIN_VALUE_NS, MXUSER_DEFAULT_HISTO_DECADES); } if (doLog) { Log("HOT LOCK (%s); contention ratio %f\n", lock->header.name, contentionRatio); } } } } /* *----------------------------------------------------------------------------- * * MXUser_ControlExclLock -- * * Perform the specified command on the specified lock. * * Results: * TRUE succeeded * FALSE failed * * Side effects: * Depends on the command, no? * *----------------------------------------------------------------------------- */ Bool MXUser_ControlExclLock(MXUserExclLock *lock, // IN/OUT: uint32 command, // IN: ...) // IN: { Bool result; ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_EXCL); switch (command) { case MXUSER_CONTROL_ACQUISITION_HISTO: { if (vmx86_stats) { MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); if (acquireStats == NULL) { result = FALSE; } else { va_list a; uint32 decades; uint64 minValue; va_start(a, command); minValue = va_arg(a, uint64); decades = va_arg(a, uint32); va_end(a); MXUserForceHisto(&acquireStats->histo, MXUSER_STAT_CLASS_ACQUISITION, minValue, decades); result = TRUE; } } else { result = FALSE; } break; } case MXUSER_CONTROL_HELD_HISTO: { if (vmx86_stats) { MXUserHeldStats *heldStats = Atomic_ReadPtr(&lock->heldStatsMem); if (heldStats == NULL) { result = FALSE; } else { va_list a; uint32 decades; uint32 minValue; va_start(a, command); minValue = va_arg(a, uint64); decades = va_arg(a, uint32); va_end(a); MXUserForceHisto(&heldStats->histo, MXUSER_STAT_CLASS_HELD, minValue, decades); result = TRUE; } } else { result = FALSE; } break; } case MXUSER_CONTROL_ENABLE_STATS: { if (vmx86_stats) { va_list a; Bool trackHeldTimes; MXUserHeldStats *heldStats; MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); if (LIKELY(acquireStats == NULL)) { MXUserAcquireStats *before; acquireStats = Util_SafeCalloc(1, sizeof(*acquireStats)); MXUserAcquisitionStatsSetUp(&acquireStats->data); before = Atomic_ReadIfEqualWritePtr(&lock->acquireStatsMem, NULL, (void *) acquireStats); if (before) { free(acquireStats); } } va_start(a, command); trackHeldTimes = va_arg(a, int); va_end(a); heldStats = Atomic_ReadPtr(&lock->heldStatsMem); if ((heldStats == NULL) && trackHeldTimes) { MXUserHeldStats *before; heldStats = Util_SafeCalloc(1, sizeof(*heldStats)); MXUserBasicStatsSetUp(&heldStats->data, MXUSER_STAT_CLASS_HELD); before = Atomic_ReadIfEqualWritePtr(&lock->heldStatsMem, NULL, (void *) heldStats); if (before) { free(heldStats); } } lock->header.statsFunc = MXUserStatsActionExcl; result = TRUE; } else { result = FALSE; } break; } default: result = FALSE; } return result; } /* *----------------------------------------------------------------------------- * * MXUserDumpExclLock -- * * Dump an exclusive lock. * * Results: * A dump. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void MXUserDumpExclLock(MXUserHeader *header) // IN: { MXUserExclLock *lock = (MXUserExclLock *) header; Warning("%s: Exclusive lock @ %p\n", __FUNCTION__, lock); Warning("\tsignature 0x%X\n", lock->header.signature); Warning("\tname %s\n", lock->header.name); Warning("\trank 0x%X\n", lock->header.rank); Warning("\tserial number %u\n", lock->header.serialNumber); Warning("\tlock count %d\n", MXRecLockCount(&lock->recursiveLock)); Warning("\taddress of owner data %p\n", &lock->recursiveLock.nativeThreadID); } /* *----------------------------------------------------------------------------- * * MXUser_CreateExclLock -- * * Create an exclusive lock. * * Results: * NULL Creation failed * !NULL Creation succeeded * * Side effects: * None * *----------------------------------------------------------------------------- */ MXUserExclLock * MXUser_CreateExclLock(const char *userName, // IN: MX_Rank rank) // IN: { uint32 statsMode; char *properName; MXUserExclLock *lock; lock = Util_SafeCalloc(1, sizeof(*lock)); if (userName == NULL) { properName = Str_SafeAsprintf(NULL, "X-%p", GetReturnAddress()); } else { properName = Util_SafeStrdup(userName); } if (!MXRecLockInit(&lock->recursiveLock)) { free(properName); free(lock); return NULL; } lock->header.signature = MXUserGetSignature(MXUSER_TYPE_EXCL); lock->header.name = properName; lock->header.rank = rank; lock->header.serialNumber = MXUserAllocSerialNumber(); lock->header.dumpFunc = MXUserDumpExclLock; statsMode = MXUserStatsMode(); switch (statsMode) { case 0: lock->header.statsFunc = NULL; Atomic_WritePtr(&lock->acquireStatsMem, NULL); Atomic_WritePtr(&lock->heldStatsMem, NULL); break; case 1: MXUser_ControlExclLock(lock, MXUSER_CONTROL_ENABLE_STATS, FALSE); break; case 2: MXUser_ControlExclLock(lock, MXUSER_CONTROL_ENABLE_STATS, TRUE); break; default: Panic("%s: unknown stats mode: %d!\n", __FUNCTION__, statsMode); } MXUserAddToList(&lock->header); return lock; } /* *----------------------------------------------------------------------------- * * MXUser_DestroyExclLock -- * * Destroy an exclusive lock. * * Results: * Lock is destroyed. Don't use the pointer again. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUser_DestroyExclLock(MXUserExclLock *lock) // IN: { if (lock != NULL) { MXUserValidateHeader(&lock->header, MXUSER_TYPE_EXCL); if (MXRecLockCount(&lock->recursiveLock) > 0) { MXUserDumpAndPanic(&lock->header, "%s: Destroy of an acquired exclusive lock\n", __FUNCTION__); } lock->header.signature = 0; // just in case... MXRecLockDestroy(&lock->recursiveLock); MXUserRemoveFromList(&lock->header); if (vmx86_stats) { MXUserHeldStats *heldStats; MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); if (LIKELY(acquireStats != NULL)) { MXUserAcquisitionStatsTearDown(&acquireStats->data); MXUserHistoTearDown(Atomic_ReadPtr(&acquireStats->histo)); free(acquireStats); } heldStats = Atomic_ReadPtr(&lock->heldStatsMem); if (UNLIKELY(heldStats != NULL)) { MXUserBasicStatsTearDown(&heldStats->data); MXUserHistoTearDown(Atomic_ReadPtr(&heldStats->histo)); free(heldStats); } } free(lock->header.name); lock->header.name = NULL; free(lock); } } /* *----------------------------------------------------------------------------- * * MXUser_AcquireExclLock -- * * An acquisition is made (lock is taken) on the specified exclusive lock. * * Results: * The lock is acquired (locked). * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUser_AcquireExclLock(MXUserExclLock *lock) // IN/OUT: { ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_EXCL); MXUserAcquisitionTracking(&lock->header, TRUE); if (vmx86_stats) { VmTimeType value = 0; MXUserHeldStats *heldStats; MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); MXRecLockAcquire(&lock->recursiveLock, (acquireStats == NULL) ? NULL : &value); if (LIKELY(acquireStats != NULL)) { MXUserHisto *histo; MXUserAcquisitionSample(&acquireStats->data, TRUE, value != 0, value); histo = Atomic_ReadPtr(&acquireStats->histo); if (UNLIKELY(histo != NULL)) { MXUserHistoSample(histo, value, GetReturnAddress()); } heldStats = Atomic_ReadPtr(&lock->heldStatsMem); if (UNLIKELY(heldStats != NULL)) { heldStats->holdStart = Hostinfo_SystemTimerNS(); } } } else { MXRecLockAcquire(&lock->recursiveLock, NULL); // non-stats } if (vmx86_debug && (MXRecLockCount(&lock->recursiveLock) > 1)) { MXUserDumpAndPanic(&lock->header, "%s: Acquire on an acquired exclusive lock\n", __FUNCTION__); } } /* *----------------------------------------------------------------------------- * * MXUser_ReleaseExclLock -- * * Release (unlock) an exclusive lock. * * Results: * The lock is released. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUser_ReleaseExclLock(MXUserExclLock *lock) // IN/OUT: { ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_EXCL); if (vmx86_stats) { MXUserHeldStats *heldStats = Atomic_ReadPtr(&lock->heldStatsMem); if (UNLIKELY(heldStats != NULL)) { VmTimeType value = Hostinfo_SystemTimerNS() - heldStats->holdStart; MXUserHisto *histo = Atomic_ReadPtr(&heldStats->histo); MXUserBasicStatsSample(&heldStats->data, value); if (UNLIKELY(histo != NULL)) { MXUserHistoSample(histo, value, GetReturnAddress()); } } } if (vmx86_debug) { if (MXRecLockCount(&lock->recursiveLock) == 0) { MXUserDumpAndPanic(&lock->header, "%s: Release of an unacquired exclusive lock\n", __FUNCTION__); } if (!MXRecLockIsOwner(&lock->recursiveLock)) { MXUserDumpAndPanic(&lock->header, "%s: Non-owner release of a exclusive lock\n", __FUNCTION__); } } MXUserReleaseTracking(&lock->header); MXRecLockRelease(&lock->recursiveLock); } /* *----------------------------------------------------------------------------- * * MXUser_TryAcquireExclLock -- * * An attempt is made to conditionally acquire (lock) an exclusive lock. * * Results: * TRUE Acquired (locked) * FALSE Not acquired * * Side effects: * None * * NOTE: * A "TryAcquire" does not rank check should the acquisition succeed. * This duplicates the behavor of MX locks. * *----------------------------------------------------------------------------- */ Bool MXUser_TryAcquireExclLock(MXUserExclLock *lock) // IN/OUT: { Bool success; ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_EXCL); if (MXUserTryAcquireFail(lock->header.name)) { return FALSE; } success = MXRecLockTryAcquire(&lock->recursiveLock); if (success) { MXUserAcquisitionTracking(&lock->header, FALSE); if (vmx86_debug && (MXRecLockCount(&lock->recursiveLock) > 1)) { MXUserDumpAndPanic(&lock->header, "%s: Acquire on an acquired exclusive lock\n", __FUNCTION__); } } if (vmx86_stats) { MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); if (LIKELY(acquireStats != NULL)) { MXUserAcquisitionSample(&acquireStats->data, success, !success, 0ULL); } } return success; } /* *----------------------------------------------------------------------------- * * MXUser_IsCurThreadHoldingExclLock -- * * Is an exclusive lock held by the calling thread? * * Results: * TRUE Yes * FALSE No * * Side effects: * None * *----------------------------------------------------------------------------- */ Bool MXUser_IsCurThreadHoldingExclLock(MXUserExclLock *lock) // IN: { ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_EXCL); return MXRecLockIsOwner(&lock->recursiveLock); } /* *----------------------------------------------------------------------------- * * MXUser_CreateSingletonExclLock -- * * Ensures that the specified backing object (Atomic_Ptr) contains a * exclusive lock. This is useful for modules that need to protect * something with a lock but don't have an existing Init() entry point * where a lock can be created. * * Results: * A pointer to the requested lock. * * Side effects: * Generally the lock's resources are intentionally leaked (by design). * *----------------------------------------------------------------------------- */ MXUserExclLock * MXUser_CreateSingletonExclLock(Atomic_Ptr *lockStorage, // IN/OUT: const char *name, // IN: MX_Rank rank) // IN: { MXUserExclLock *lock; ASSERT(lockStorage); lock = Atomic_ReadPtr(lockStorage); if (UNLIKELY(lock == NULL)) { MXUserExclLock *newLock = MXUser_CreateExclLock(name, rank); lock = Atomic_ReadIfEqualWritePtr(lockStorage, NULL, (void *) newLock); if (lock) { MXUser_DestroyExclLock(newLock); } else { lock = Atomic_ReadPtr(lockStorage); } } return lock; } /* *----------------------------------------------------------------------------- * * MXUser_CreateCondVarExclLock -- * * Create a condition variable for use with the specified exclusive lock. * * Results: * As above. * * Side effects: * The created condition variable will cause a run-time error if it is * used with a lock other than the one it was created for. * *----------------------------------------------------------------------------- */ MXUserCondVar * MXUser_CreateCondVarExclLock(MXUserExclLock *lock) { ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_EXCL); return MXUserCreateCondVar(&lock->header, &lock->recursiveLock); } /* *----------------------------------------------------------------------------- * * MXUser_WaitCondVarExclLock -- * * Block (sleep) on the specified condition variable. The specified lock * is released upon blocking and is reacquired before returning from this * function. * * Results: * As above. * * Side effects: * It is possible to return from this routine without the condtion * variable having been signalled (spurious wake up); code accordingly! * *----------------------------------------------------------------------------- */ void MXUser_WaitCondVarExclLock(MXUserExclLock *lock, // IN: MXUserCondVar *condVar) // IN: { ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_EXCL); MXUserWaitCondVar(&lock->header, &lock->recursiveLock, condVar, MXUSER_WAIT_INFINITE); } /* *----------------------------------------------------------------------------- * * MXUser_TimedWaitCondVarExclLock -- * * Block (sleep) on the specified condition variable for no longer than * the specified amount of time. The specified lock is released upon * blocking and is reacquired before returning from this function. * * Results: * As above * * Side effects: * It is possible to return from this routine without the condtion * variable having been signalled (spurious wake up); code accordingly! * *----------------------------------------------------------------------------- */ void MXUser_TimedWaitCondVarExclLock(MXUserExclLock *lock, // IN: MXUserCondVar *condVar, // IN: uint32 msecWait) // IN: { ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_EXCL); MXUserWaitCondVar(&lock->header, &lock->recursiveLock, condVar, msecWait); } open-vm-tools-9.4.0-1280544/lib/lock/ulBarrier.c0000644765153500003110000002255112220061556017235 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #include "vmware.h" #include "str.h" #include "util.h" #include "userlock.h" #include "ulInt.h" struct BarrierContext { uint32 count; // Number of threads currently in this context MXUserCondVar *condVar; // Threads within this context are parked here }; typedef struct BarrierContext BarrierContext; struct MXUserBarrier { MXUserHeader header; // Barrier's ID information MXUserExclLock *lock; // Barrier's (internal) lock uint32 configCount; // Hold until this many threads arrive volatile uint32 curContext; // Arrivals go to this context BarrierContext contexts[2]; // The normal and abnormal contexts }; /* *----------------------------------------------------------------------------- * * MXUserDumpBarrier -- * * Dump a barrier. * * Results: * A dump. * * Side effects: * None * *----------------------------------------------------------------------------- */ static void MXUserDumpBarrier(MXUserHeader *header) // IN: { uint32 curContext; MXUserBarrier *barrier = (MXUserBarrier *) header; Warning("%s: Barrier @ 0x%p\n", __FUNCTION__, barrier); Warning("\tsignature 0x%X\n", barrier->header.signature); Warning("\tname %s\n", barrier->header.name); Warning("\trank 0x%X\n", barrier->header.rank); Warning("\tserial number %u\n", barrier->header.serialNumber); Warning("\tlock 0x%p\n", barrier->lock); Warning("\tconfigured count %u\n", barrier->configCount); curContext = barrier->curContext; Warning("\tcurrent context %u\n", curContext); Warning("\tcontext[%u] count %u\n", curContext, barrier->contexts[curContext].count); Warning("\tcontext[%u] condVar 0x%p\n", curContext, &barrier->contexts[curContext].condVar); curContext = (curContext + 1) & 0x1; Warning("\tcontext[%u] count %u\n", curContext, barrier->contexts[curContext].count); Warning("\tcontext[%u] condVar 0x%p\n", curContext, &barrier->contexts[curContext].condVar); } /* *----------------------------------------------------------------------------- * * MXUser_CreateBarrier -- * * Create a computational barrier. * * The barriers are self regenerating - they do not need to be * initialized or reset after creation. * * Results: * A pointer to a barrier. * * Side effects: * None * *----------------------------------------------------------------------------- */ MXUserBarrier * MXUser_CreateBarrier(const char *userName, // IN: shall be known as MX_Rank rank, // IN: internal lock's rank uint32 count) // IN: { char *properName; MXUserBarrier *barrier; ASSERT(count); barrier = Util_SafeCalloc(1, sizeof(*barrier)); if (userName == NULL) { properName = Str_SafeAsprintf(NULL, "Barrier-%p", GetReturnAddress()); } else { properName = Util_SafeStrdup(userName); } barrier->lock = MXUser_CreateExclLock(properName, rank); if (barrier->lock == NULL) { free(properName); free(barrier); return NULL; } barrier->contexts[0].condVar = MXUser_CreateCondVarExclLock(barrier->lock); barrier->contexts[1].condVar = MXUser_CreateCondVarExclLock(barrier->lock); if ((barrier->contexts[0].condVar == NULL) || (barrier->contexts[1].condVar == NULL)) { MXUser_DestroyCondVar(barrier->contexts[0].condVar); MXUser_DestroyCondVar(barrier->contexts[1].condVar); MXUser_DestroyExclLock(barrier->lock); free(properName); free(barrier); return NULL; } barrier->configCount = count; barrier->curContext = 0; barrier->header.signature = MXUserGetSignature(MXUSER_TYPE_BARRIER); barrier->header.name = properName; barrier->header.rank = rank; barrier->header.serialNumber = MXUserAllocSerialNumber(); barrier->header.dumpFunc = MXUserDumpBarrier; barrier->header.statsFunc = NULL; MXUserAddToList(&barrier->header); return barrier; } /* *----------------------------------------------------------------------------- * * MXUser_DestroyBarrier -- * * Destroy a barrier. * * Results: * The barrier is destroyed. Don't try to use the pointer again. * * Side effects: * None * *----------------------------------------------------------------------------- */ void MXUser_DestroyBarrier(MXUserBarrier *barrier) // IN: { if (LIKELY(barrier != NULL)) { MXUserValidateHeader(&barrier->header, MXUSER_TYPE_BARRIER); if ((barrier->contexts[0].count != 0) || (barrier->contexts[1].count != 0)) { MXUserDumpAndPanic(&barrier->header, "%s: Attempted destroy on barrier while in use\n", __FUNCTION__); } barrier->header.signature = 0; // just in case... MXUserRemoveFromList(&barrier->header); MXUser_DestroyCondVar(barrier->contexts[0].condVar); MXUser_DestroyCondVar(barrier->contexts[1].condVar); MXUser_DestroyExclLock(barrier->lock); free(barrier->header.name); barrier->header.name = NULL; free(barrier); } } /* *----------------------------------------------------------------------------- * * MXUser_EnterBarrier -- * * Enter a barrier * * All threads entering the barrier will be suspended until the number * threads that have entered reaches the configured number upon which * time all of the threads will return from this routine. * * "Nobody comes out until everone goes in." * * Results: * None * * Side effects: * The caller may sleep. * *----------------------------------------------------------------------------- */ void MXUser_EnterBarrier(MXUserBarrier *barrier) // IN/OUT: { BarrierContext *ptr; uint32 context; ASSERT(barrier); MXUserValidateHeader(&barrier->header, MXUSER_TYPE_BARRIER); MXUser_AcquireExclLock(barrier->lock); context = barrier->curContext; ptr = &barrier->contexts[context]; ptr->count++; if (ptr->count == barrier->configCount) { /* * The last thread has entered; release the other threads * * Flip the current context. Should a thread leave the barrier and * enter the barrier while the barrier is "emptying" the thread will * park on the condVar that is not "emptying". Eventually everything * will "work out" and all of the threads will be parked on the opposite * context's condVar. */ barrier->curContext = (context + 1) & 0x1; ASSERT(barrier->contexts[barrier->curContext].count == 0); /* Wake up all of the waiting threads. */ MXUser_BroadcastCondVar(ptr->condVar); } else { /* * Not the last thread in... wait/sleep until the last thread appears. * Protect against spurious wakeups. */ while (barrier->curContext == context) { MXUser_WaitCondVarExclLock(barrier->lock, ptr->condVar); } } ptr->count--; MXUser_ReleaseExclLock(barrier->lock); } /* *----------------------------------------------------------------------------- * * MXUser_CreateSingletonBarrier -- * * Ensures that the specified backing object (Atomic_Ptr) contains a * barrier. This is useful for modules that need to protect something * with a barrier but don't have an existing Init() entry point where a * barrier can be created. * * Results: * A pointer to the requested barrier. * * Side effects: * Generally the barrier's resources are intentionally leaked (by design). * *----------------------------------------------------------------------------- */ MXUserBarrier * MXUser_CreateSingletonBarrier(Atomic_Ptr *barrierStorage, // IN/OUT: const char *name, // IN: MX_Rank rank, // IN: uint32 count) // IN: { MXUserBarrier *barrier; ASSERT(barrierStorage); barrier = (MXUserBarrier *) Atomic_ReadPtr(barrierStorage); if (UNLIKELY(barrier == NULL)) { MXUserBarrier *newBarrier = MXUser_CreateBarrier(name, rank, count); barrier = (MXUserBarrier *) Atomic_ReadIfEqualWritePtr(barrierStorage, NULL, (void *) newBarrier); if (barrier) { MXUser_DestroyBarrier(newBarrier); } else { barrier = (MXUserBarrier *) Atomic_ReadPtr(barrierStorage); } } return barrier; } open-vm-tools-9.4.0-1280544/lib/lock/ulCondVar.c0000644765153500003110000004745112220061556017211 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #if defined(_WIN32) #include #else #include #endif #include "vmware.h" #include "vm_basic_asm.h" #include "str.h" #include "err.h" #include "util.h" #include "userlock.h" #include "ulInt.h" /* * A portable condition variable */ struct MXUserCondVar { uint32 signature; MXUserHeader *header; MXRecLock *ownerLock; Atomic_uint32 referenceCount; #if defined(_WIN32) union { struct { CRITICAL_SECTION condVarLock; HANDLE signalEvent; uint32 numWaiters; uint32 numForRelease; } compat; CONDITION_VARIABLE condObject; } x; #else pthread_cond_t condObject; #endif }; #if defined(_WIN32) typedef VOID (WINAPI *InitializeConditionVariableFn)(PCONDITION_VARIABLE cv); typedef BOOL (WINAPI *SleepConditionVariableCSFn)(PCONDITION_VARIABLE cv, PCRITICAL_SECTION cs, DWORD msSleep); typedef VOID (WINAPI *WakeAllConditionVariableFn)(PCONDITION_VARIABLE cv); typedef VOID (WINAPI *WakeConditionVariableFn)(PCONDITION_VARIABLE cv); static InitializeConditionVariableFn pInitializeConditionVariable; static SleepConditionVariableCSFn pSleepConditionVariableCS; static WakeAllConditionVariableFn pWakeAllConditionVariable; static WakeConditionVariableFn pWakeConditionVariable; /* *----------------------------------------------------------------------------- * * MXUserNativeCVSupported -- * * Does native condition variable support exist for the Windows the * caller is running on? * * Results: * TRUE Yes * FALSE No * * Side effects: * Function pointers to the native routines are initialized upon success. * *----------------------------------------------------------------------------- */ static Bool MXUserNativeCVSupported(void) { static Bool result; static Bool done = FALSE; if (!done) { HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll"); if (kernel32) { pInitializeConditionVariable = (InitializeConditionVariableFn) GetProcAddress(kernel32, "InitializeConditionVariable"); pSleepConditionVariableCS = (SleepConditionVariableCSFn) GetProcAddress(kernel32, "SleepConditionVariableCS"); pWakeAllConditionVariable = (WakeAllConditionVariableFn) GetProcAddress(kernel32, "WakeAllConditionVariable"); pWakeConditionVariable = (WakeConditionVariableFn) GetProcAddress(kernel32, "WakeConditionVariable"); COMPILER_MEM_BARRIER(); result = ((pInitializeConditionVariable != NULL) && (pSleepConditionVariableCS != NULL) && (pWakeAllConditionVariable != NULL) && (pWakeConditionVariable != NULL)); } else { result = FALSE; } done = TRUE; } return result; } /* *----------------------------------------------------------------------------- * * MXUserCreateInternal -- * * Create/initialize the environmentally specific portion of an * MXUserCondVar. * * Results: * TRUE Success * FALSE Failure * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE Bool MXUserCreateInternal(MXUserCondVar *condVar) // IN/OUT: { Bool success; if (MXUserNativeCVSupported()) { ASSERT(pInitializeConditionVariable); (*pInitializeConditionVariable)(&condVar->x.condObject); success = TRUE; } else { if (InitializeCriticalSectionAndSpinCount(&condVar->x.compat.condVarLock, 0x80000400) == 0) { success = FALSE; } else { condVar->x.compat.numWaiters = 0; condVar->x.compat.numForRelease = 0; condVar->x.compat.signalEvent = CreateEvent(NULL, // no security TRUE, // manual-reset FALSE, // non-signaled NULL); // unnamed success = (condVar->x.compat.signalEvent != NULL); if (!success) { DeleteCriticalSection(&condVar->x.compat.condVarLock); } } } return success; } /* *----------------------------------------------------------------------------- * * MXUserDestroyInternal -- * * Destroy the environmentally specific portion of an MXUserCondVar. * * Results: * As expect. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void MXUserDestroyInternal(MXUserCondVar *condVar) // IN/OUT: { if (pInitializeConditionVariable == NULL) { DeleteCriticalSection(&condVar->x.compat.condVarLock); CloseHandle(condVar->x.compat.signalEvent); } } /* *----------------------------------------------------------------------------- * * MXUserWaitInternal -- * * Perform the environmentally specific portion of a wait on an * MXUserCondVar. * * Results: * As above * * Side effects: * It is possible to return from this routine without the condtion * variable having been signalled (spurious wake up); code accordingly! * *----------------------------------------------------------------------------- */ static INLINE void MXUserWaitInternal(MXRecLock *lock, // IN: MXUserCondVar *condVar, // IN: uint32 msecWait) // IN: { int lockCount = MXRecLockCount(lock); DWORD waitTime = (msecWait == MXUSER_WAIT_INFINITE) ? INFINITE : msecWait; if (pSleepConditionVariableCS) { /* * When using the native lock found within the MXUser lock, be sure to * decrement the count before the wait/sleep and increment it after the * wait/sleep - the (native) wait/sleep will perform a lock release * before the wait/sleep and a lock acquisition after the wait/sleep. * The MXUser internal accounting information must be maintained. */ MXRecLockDecCount(lock, lockCount); (*pSleepConditionVariableCS)(&condVar->x.condObject, &lock->nativeLock, waitTime); MXRecLockIncCount(lock, lockCount); } else { DWORD err; Bool done = FALSE; EnterCriticalSection(&condVar->x.compat.condVarLock); condVar->x.compat.numWaiters++; LeaveCriticalSection(&condVar->x.compat.condVarLock); MXRecLockDecCount(lock, lockCount - 1); MXRecLockRelease(lock); do { DWORD status = WaitForSingleObject(condVar->x.compat.signalEvent, waitTime); EnterCriticalSection(&condVar->x.compat.condVarLock); ASSERT(condVar->x.compat.numWaiters > 0); if (status == WAIT_OBJECT_0) { if (condVar->x.compat.numForRelease > 0) { condVar->x.compat.numWaiters--; if (--condVar->x.compat.numForRelease == 0) { ResetEvent(condVar->x.compat.signalEvent); } err = ERROR_SUCCESS; done = TRUE; } } else { condVar->x.compat.numWaiters--; if (status == WAIT_TIMEOUT) { if (msecWait == MXUSER_WAIT_INFINITE) { err = ERROR_CALL_NOT_IMPLEMENTED; // ACK! "IMPOSSIBLE" } else { err = ERROR_SUCCESS; } } else if (status == WAIT_ABANDONED) { err = ERROR_WAIT_NO_CHILDREN; } else { ASSERT(status == WAIT_FAILED); err = GetLastError(); } done = TRUE; } LeaveCriticalSection(&condVar->x.compat.condVarLock); } while (!done); MXRecLockAcquire(lock, NULL); // non-stats MXRecLockIncCount(lock, lockCount - 1); if (err != ERROR_SUCCESS) { Panic("%s: failure %d on condVar (0x%p; %s)\n", __FUNCTION__, err, condVar, condVar->header->name); } } } /* *----------------------------------------------------------------------------- * * MXUserSignalInternal -- * * Perform the environmentally specific portion of signalling an * MXUserCondVar. * * Results: * 0 Success * !0 Error * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE int MXUserSignalInternal(MXUserCondVar *condVar) // IN/OUT: { if (pWakeConditionVariable) { (*pWakeConditionVariable)(&condVar->x.condObject); } else { EnterCriticalSection(&condVar->x.compat.condVarLock); if (condVar->x.compat.numWaiters > condVar->x.compat.numForRelease) { SetEvent(condVar->x.compat.signalEvent); condVar->x.compat.numForRelease++; } LeaveCriticalSection(&condVar->x.compat.condVarLock); } return 0; } /* *----------------------------------------------------------------------------- * * MXUserBroadcastInternal -- * * Perform the environmentally specific portion of broadasting on an * MXUserCondVar. * * Results: * 0 Success * !0 Error * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE int MXUserBroadcastInternal(MXUserCondVar *condVar) // IN/OUT: { if (pWakeAllConditionVariable) { (*pWakeAllConditionVariable)(&condVar->x.condObject); } else { EnterCriticalSection(&condVar->x.compat.condVarLock); if (condVar->x.compat.numWaiters > condVar->x.compat.numForRelease) { SetEvent(condVar->x.compat.signalEvent); condVar->x.compat.numForRelease = condVar->x.compat.numWaiters; } LeaveCriticalSection(&condVar->x.compat.condVarLock); } return 0; } #else /* _WIN32 */ /* *----------------------------------------------------------------------------- * * MXUserCreateInternal -- * * Create/initialize the environmentally specific portion of an * MXUserCondVar. * * Results: * TRUE Success * FALSE Failure * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE Bool MXUserCreateInternal(MXUserCondVar *condVar) // IN/OUT: { return pthread_cond_init(&condVar->condObject, NULL) == 0; } /* *----------------------------------------------------------------------------- * * MXUserDestroyInternal -- * * Destroy the environmentally specific portion of an MXUserCondVar. * * Results: * As expected. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void MXUserDestroyInternal(MXUserCondVar *condVar) // IN/OUT: { pthread_cond_destroy(&condVar->condObject); } /* *----------------------------------------------------------------------------- * * MXUserWaitInternal -- * * Perform the environmentally specific portion of a wait on an * MXUserCondVar. * * Results: * As above * * Side effects: * It is possible to return from this routine without the condtion * variable having been signalled (spurious wake up); code accordingly! * *----------------------------------------------------------------------------- */ static INLINE void MXUserWaitInternal(MXRecLock *lock, // IN: MXUserCondVar *condVar, // IN: uint32 msecWait) // IN: { int err; int lockCount = MXRecLockCount(lock); /* * When using the native lock found within the MXUser lock, be sure to * decrement the count before the wait/sleep and increment it after the * wait/sleep - the (native) wait/sleep will perform a lock release before * the wait/sleep and a lock acquisition after the wait/sleep. The * MXUser internal accounting information must be maintained. */ MXRecLockDecCount(lock, lockCount); if (msecWait == MXUSER_WAIT_INFINITE) { err = pthread_cond_wait(&condVar->condObject, &lock->nativeLock); } else { struct timeval curTime; struct timespec endTime; uint64 endNS; /* * pthread_cond_timedwait takes an absolute time. Yes, this is * beyond ridiculous, and the justifications for this * vs. relative time make no sense. But IIWII. */ #define A_BILLION (1000 * 1000 * 1000) gettimeofday(&curTime, NULL); endNS = ((uint64) curTime.tv_sec * A_BILLION) + ((uint64) curTime.tv_usec * 1000) + ((uint64) msecWait * (1000 * 1000)); endTime.tv_sec = (time_t) (endNS / A_BILLION); endTime.tv_nsec = (long int) (endNS % A_BILLION); #undef A_BILLION err = pthread_cond_timedwait(&condVar->condObject, &lock->nativeLock, &endTime); } MXRecLockIncCount(lock, lockCount); if (err != 0) { if (err != ETIMEDOUT) { Panic("%s: failure %d on condVar (0x%p; %s)\n", __FUNCTION__, err, condVar, condVar->header->name); } } } /* *----------------------------------------------------------------------------- * * MXUserSignalInternal -- * * Perform the environmentally specific portion of signalling an * MXUserCondVar. * * Results: * 0 Success * !0 Error * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE int MXUserSignalInternal(MXUserCondVar *condVar) // IN/OUT: { return pthread_cond_signal(&condVar->condObject); } /* *----------------------------------------------------------------------------- * * MXUserBroadcaseInternal -- * * Perform the environmentally specific portion of broadasting on an * MXUserCondVar. * * Results: * 0 Success * !0 Error * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE int MXUserBroadcastInternal(MXUserCondVar *condVar) // IN/OUT: { return pthread_cond_broadcast(&condVar->condObject); } #endif /* _WIN32 */ /* *----------------------------------------------------------------------------- * * MXUserCreateCondVar -- * * Create/initialize a condition variable associated with the specified * lock. * * Results: * !NULL Success; a pointer to the (new) condition variable * NULL Failure * * Side effects: * None. * *----------------------------------------------------------------------------- */ MXUserCondVar * MXUserCreateCondVar(MXUserHeader *header, // IN: MXRecLock *lock) // IN: { MXUserCondVar *condVar = Util_SafeCalloc(1, sizeof(*condVar)); if (MXUserCreateInternal(condVar)) { condVar->signature = MXUserGetSignature(MXUSER_TYPE_CONDVAR); condVar->header = header; condVar->ownerLock = lock; } else { free(condVar); condVar = NULL; } return condVar; } /* *----------------------------------------------------------------------------- * * MXUserWaitCondVar -- * * The internal wait on a condition variable routine. * * Results: * As above * * Side effects: * An attempt to use a lock other than the one the specified condition * variable was specified for will result in a panic. * *----------------------------------------------------------------------------- */ void MXUserWaitCondVar(MXUserHeader *header, // IN: MXRecLock *lock, // IN: MXUserCondVar *condVar, // IN: uint32 msecWait) // IN: { ASSERT(header); ASSERT(lock); ASSERT(condVar); ASSERT(condVar->signature == MXUserGetSignature(MXUSER_TYPE_CONDVAR)); if (condVar->ownerLock != lock) { Panic("%s: invalid use of lock %s with condVar (0x%p; %s)\n", __FUNCTION__, header->name, condVar, condVar->header->name); } if (vmx86_debug && !MXRecLockIsOwner(lock)) { Panic("%s: lock %s for condVar (0x%p) not owned\n", __FUNCTION__, condVar->header->name, condVar); } Atomic_Inc(&condVar->referenceCount); MXUserWaitInternal(lock, condVar, msecWait); Atomic_Dec(&condVar->referenceCount); } /* *----------------------------------------------------------------------------- * * MXUser_SignalCondVar * * Signal on a condVar - wake up one thread blocked on the specified * condition variable. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void MXUser_SignalCondVar(MXUserCondVar *condVar) // IN: { int err; ASSERT(condVar); ASSERT(condVar->signature == MXUserGetSignature(MXUSER_TYPE_CONDVAR)); err = MXUserSignalInternal(condVar); if (err != 0) { Panic("%s: failure %d on condVar (0x%p; %s) \n", __FUNCTION__, err, condVar, condVar->header->name); } } /* *----------------------------------------------------------------------------- * * MXUser_BroadcastCondVar * * Broadcast on a condVar - wake up all threads blocked on the specified * condition variable. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void MXUser_BroadcastCondVar(MXUserCondVar *condVar) // IN: { int err; ASSERT(condVar); ASSERT(condVar->signature == MXUserGetSignature(MXUSER_TYPE_CONDVAR)); err = MXUserBroadcastInternal(condVar); if (err != 0) { Panic("%s: failure %d on condVar (0x%p; %s) \n", __FUNCTION__, err, condVar, condVar->header->name); } } /* *----------------------------------------------------------------------------- * * MXUser_DestroyCondVar -- * * Destroy a condition variable. * * A condVar must be destroyed before the lock it is associated with. * * Results: * As above. Don't use the pointer again... * * Side effects: * None. * *----------------------------------------------------------------------------- */ void MXUser_DestroyCondVar(MXUserCondVar *condVar) // IN: { if (condVar != NULL) { ASSERT(condVar->signature == MXUserGetSignature(MXUSER_TYPE_CONDVAR)); if (Atomic_Read(&condVar->referenceCount) != 0) { Panic("%s: Attempted destroy on active condVar (0x%p; %s)\n", __FUNCTION__, condVar, condVar->header->name); } condVar->signature = 0; // just in case... MXUserDestroyInternal(condVar); condVar->header = NULL; condVar->ownerLock = NULL; free(condVar); } } open-vm-tools-9.4.0-1280544/lib/lock/Makefile.in0000644765153500003110000004472612220061622017211 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2010 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/lock DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libLock_la_LIBADD = am_libLock_la_OBJECTS = ul.lo ulCondVar.lo ulExcl.lo ulRec.lo ulRW.lo \ ulSema.lo ulBarrier.lo ulStats.lo libLock_la_OBJECTS = $(am_libLock_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libLock_la_SOURCES) DIST_SOURCES = $(libLock_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libLock.la libLock_la_SOURCES = ul.c ulCondVar.c ulExcl.c ulRec.c ulRW.c ulSema.c \ ulBarrier.c ulStats.c AM_CFLAGS = @LIB_USER_CPPFLAGS@ all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/lock/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/lock/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libLock.la: $(libLock_la_OBJECTS) $(libLock_la_DEPENDENCIES) $(EXTRA_libLock_la_DEPENDENCIES) $(LINK) $(libLock_la_OBJECTS) $(libLock_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ul.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ulBarrier.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ulCondVar.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ulExcl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ulRW.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ulRec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ulSema.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ulStats.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/hgfsHelper/0000755765153500003110000000000012220061622016266 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/hgfsHelper/hgfsHelperPosix.c0000644765153500003110000000537412220061556021563 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * hgfsHelperPosix.c -- * * Provides a posix helper library for guest applications to access * the HGFS file system. * */ #if !defined __linux__ && !defined __FreeBSD__ && !defined sun && !defined __APPLE__ # error This file should not be compiled #endif #include "vmware.h" #include "debug.h" #include "hgfsHelper.h" #if defined __linux__ #define HGFSHLPR_DEFAULT_MOUNT_PATH "/mnt/hgfs" #elif defined sun #define HGFSHLPR_DEFAULT_MOUNT_PATH "/hgfs" #elif defined __APPLE__ #define HGFSHLPR_DEFAULT_MOUNT_PATH "/Volumes/VMware Shared Folders" #endif /* *----------------------------------------------------------------------------- * * HgfsHlpr_QuerySharesDefaultRootPath -- * * Queries the driver for its share's root paths. * Currently only one is expected to be supported * and returned, although later versions may not. * E.g. "/mnt/hgfs" is the root path to * the HGFS shares. * * Results: * TRUE always. * * Side Effects: * None. * *----------------------------------------------------------------------------- */ Bool HgfsHlpr_QuerySharesDefaultRootPath(Unicode *hgfsRootPath) { #if defined __FreeBSD__ return FALSE; #else ASSERT(hgfsRootPath != NULL); *hgfsRootPath = Unicode_AllocWithUTF8(HGFSHLPR_DEFAULT_MOUNT_PATH); Debug("%s: HGFS shares root path name \"%s\"\n", __FUNCTION__, UTF8(*hgfsRootPath)); return TRUE; #endif } /* *----------------------------------------------------------------------------- * * HgfsHlpr_FreeSharesRootPath -- * * Frees the share's root paths previously returned * to the caller from the HgfsHlpr_QuerySharesRootPath. * * Results: * None. * * Side Effects: * None. * *----------------------------------------------------------------------------- */ void HgfsHlpr_FreeSharesRootPath(Unicode hgfsRootPath) { Unicode_Free(hgfsRootPath); } open-vm-tools-9.4.0-1280544/lib/hgfsHelper/Makefile.am0000644765153500003110000000174612220061556020340 0ustar dtormts################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libHgfsHelper.la libHgfsHelper_la_SOURCES = libHgfsHelper_la_SOURCES += hgfsHelperPosix.c open-vm-tools-9.4.0-1280544/lib/hgfsHelper/Makefile.in0000644765153500003110000004367312220061622020350 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2009 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/hgfsHelper DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libHgfsHelper_la_LIBADD = am_libHgfsHelper_la_OBJECTS = hgfsHelperPosix.lo libHgfsHelper_la_OBJECTS = $(am_libHgfsHelper_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libHgfsHelper_la_SOURCES) DIST_SOURCES = $(libHgfsHelper_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libHgfsHelper.la libHgfsHelper_la_SOURCES = hgfsHelperPosix.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/hgfsHelper/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/hgfsHelper/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libHgfsHelper.la: $(libHgfsHelper_la_OBJECTS) $(libHgfsHelper_la_DEPENDENCIES) $(EXTRA_libHgfsHelper_la_DEPENDENCIES) $(LINK) $(libHgfsHelper_la_OBJECTS) $(libHgfsHelper_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hgfsHelperPosix.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/stubs/0000755765153500003110000000000012220061623015340 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/stubs/stub-log.c0000644765153500003110000000325012220061556017245 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * stub-log.c -- * * Stub for lib/log. * */ #include #include #include "str.h" #include "log.h" /* * XXX: the check is a hack to work around stupid libraries, like * bora/lib/install, that provide implementations for only some of * the functions of the real library, but not all. */ #if !defined(NO_LOG_STUB) void LogV(uint32 unused, const char *fmt, va_list args) { char *str; str = Str_Vasprintf(NULL, fmt, args); if (str != NULL) { fputs(str, stderr); free(str); } } void Log(const char *fmt, ...) { va_list args; va_start(args, fmt); LogV(VMW_LOG_INFO, fmt, args); va_end(args); } #endif void Log_DisableThrottling(void) { } const char * Log_GetFileName(void) { return NULL; } void Log_SetAlwaysKeep(Bool alwaysKeep) { } open-vm-tools-9.4.0-1280544/lib/stubs/stub-user-util.c0000644765153500003110000000244412220061556020421 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * stub-user-util.c -- * * Stubs for Util_* functions in lib/user. * */ #if defined(_WIN32) # include #endif #include #include "vm_assert.h" #include "util.h" void Util_Backtrace(int bugNr) { NOT_IMPLEMENTED(); } void Util_ExitProcessAbruptly(int code) // IN { #if defined(_WIN32) TerminateProcess(GetCurrentProcess(),code); #else exit(code); #endif } int Util_HasAdminPriv() { return 1; } open-vm-tools-9.4.0-1280544/lib/stubs/stub-msgfmt-fbsd.c0000644765153500003110000000416412220061556020702 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * stub-msgfmt-fbsd.c -- * * FreeBSD-specific stubs for lib/misc/msgfmt.c. This stubs out two * specific funtions in that file - MsgFmt_Asprintf and MsgFmt_Snprintf, * which don't have FreeBSD implementations in our code base. * * Tools don't really use the Msg_* functions for error reporting and etc, * so this is easier than getting all that stuff to compile on FreeBSD. * * The stubs won't assert, but they're sort of dumb: they'll just * print the format string with no substitutions to the output. */ #include "msgfmt.h" #include "str.h" int MsgFmt_Snprintf(char *buf, // OUT: formatted string size_t size, // IN: size of buffer const char *format, // IN: format const MsgFmt_Arg *args, // IN: message arguments int numArgs) // IN: number of arguments { return Str_Snprintf(buf, size, "%s", format); } char * MsgFmt_Asprintf(size_t *length, // OUT: length of returned string const char *format, // IN: format const MsgFmt_Arg *args, // IN: message arguments int numArgs) // IN: number of arguments { return Str_Asprintf(length, "%s", format); } open-vm-tools-9.4.0-1280544/lib/stubs/stub-user-panic.c0000644765153500003110000000237412220061556020540 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * stub-user-panic.c -- * * Stubs for Panic_* functions in lib/user. * */ #include #include #include "vmware.h" #include "panic.h" #include "str.h" void Panic_PostPanicMsg(const char *fmt, ...) { char *str; va_list args; va_start(args, fmt); str = Str_Vasprintf(NULL, fmt, args); va_end(args); if (str != NULL) { fputs(str, stderr); } } open-vm-tools-9.4.0-1280544/lib/stubs/stub-user-msg.c0000644765153500003110000000377012220061556020235 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * stub-user-msg.c -- * * Stubs for Msg_* functions in lib/user. * */ #if defined(_WIN32) # include #endif #include "vm_assert.h" #include "msg.h" #include "str.h" void Msg_AppendMsgList(const MsgList *msgs) { while (msgs != NULL) { Warning("%s [STUB]: %s\n", __FUNCTION__, msgs->id); msgs = msgs->next; } } void Msg_Append(const char *fmt, ...) { static char buf[1000]; va_list args; va_start(args, fmt); Str_Vsnprintf(buf, sizeof buf, fmt, args); va_end(args); Warning("%s [STUB]: %s\n", __FUNCTION__, buf); } void Msg_Post(MsgSeverity severity, const char *idFmt, ...) { NOT_IMPLEMENTED(); } unsigned int Msg_Question(Msg_String const *buttons, int defaultAnswer, char const *fmt, ...) { static char buf[1000]; va_list args; va_start(args, fmt); Str_Vsnprintf(buf, sizeof buf, fmt, args); va_end(args); Warning("%s [STUB]: %s\n", __FUNCTION__, buf); return (unsigned int) defaultAnswer; } void Msg_Reset(Bool log) { NOT_IMPLEMENTED(); } char * Msg_FormatSizeInBytes(uint64 size) { return NULL; } open-vm-tools-9.4.0-1280544/lib/stubs/Makefile.am0000644765153500003110000000261412220061556017404 0ustar dtormts################################################################################ ### Copyright 2008 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libStubs.la libStubs_la_SOURCES = libStubs_la_SOURCES += stub-config.c libStubs_la_SOURCES += stub-log.c libStubs_la_SOURCES += stub-warning.c libStubs_la_SOURCES += stub-user-msg.c libStubs_la_SOURCES += stub-user-panic.c libStubs_la_SOURCES += stub-user-util.c noinst_LTLIBRARIES += libStubsCS.la libStubsCS_la_SOURCES = libStubsCS_la_SOURCES += stub-config.c libStubsCS_la_SOURCES += stub-user-msg.c libStubsCS_la_SOURCES += stub-user-panic.c if !LINUX libStubsCS_la_SOURCES += stub-msgfmt-fbsd.c endif open-vm-tools-9.4.0-1280544/lib/stubs/stub-warning.c0000644765153500003110000000223512220061556020133 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * stub-warning.c -- * * Stub for Warning(). * */ #include #include "str.h" void Warning(const char *fmt, ...) { char *str; va_list args; va_start(args, fmt); str = Str_Vasprintf(NULL, fmt, args); va_end(args); if (str != NULL) { fputs(str, stderr); } } open-vm-tools-9.4.0-1280544/lib/stubs/Makefile.in0000644765153500003110000004623412220061623017416 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2008 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @LINUX_FALSE@am__append_1 = stub-msgfmt-fbsd.c subdir = lib/stubs DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libStubs_la_LIBADD = am_libStubs_la_OBJECTS = stub-config.lo stub-log.lo stub-warning.lo \ stub-user-msg.lo stub-user-panic.lo stub-user-util.lo libStubs_la_OBJECTS = $(am_libStubs_la_OBJECTS) libStubsCS_la_LIBADD = am__libStubsCS_la_SOURCES_DIST = stub-config.c stub-user-msg.c \ stub-user-panic.c stub-msgfmt-fbsd.c @LINUX_FALSE@am__objects_1 = stub-msgfmt-fbsd.lo am_libStubsCS_la_OBJECTS = stub-config.lo stub-user-msg.lo \ stub-user-panic.lo $(am__objects_1) libStubsCS_la_OBJECTS = $(am_libStubsCS_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libStubs_la_SOURCES) $(libStubsCS_la_SOURCES) DIST_SOURCES = $(libStubs_la_SOURCES) \ $(am__libStubsCS_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libStubs.la libStubsCS.la libStubs_la_SOURCES = stub-config.c stub-log.c stub-warning.c \ stub-user-msg.c stub-user-panic.c stub-user-util.c libStubsCS_la_SOURCES = stub-config.c stub-user-msg.c \ stub-user-panic.c $(am__append_1) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/stubs/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/stubs/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libStubs.la: $(libStubs_la_OBJECTS) $(libStubs_la_DEPENDENCIES) $(EXTRA_libStubs_la_DEPENDENCIES) $(LINK) $(libStubs_la_OBJECTS) $(libStubs_la_LIBADD) $(LIBS) libStubsCS.la: $(libStubsCS_la_OBJECTS) $(libStubsCS_la_DEPENDENCIES) $(EXTRA_libStubsCS_la_DEPENDENCIES) $(LINK) $(libStubsCS_la_OBJECTS) $(libStubsCS_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stub-config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stub-log.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stub-msgfmt-fbsd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stub-user-msg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stub-user-panic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stub-user-util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stub-warning.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/stubs/stub-config.c0000644765153500003110000000430612220061556017734 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * stub-config.c -- * * Stubs for lib/config. * */ #include #include "vm_assert.h" #include "config.h" #include "preference.h" Bool Config_GetBool(Bool defaultValue, const char *fmt, ...) { return defaultValue; } int32 Config_GetLong(int32 defaultValue, const char *fmt, ...) { return defaultValue; } char * Config_GetString(const char *defaultValue, const char *fmt, ...) { return (defaultValue == NULL) ? NULL : strdup(defaultValue); } Bool Preference_Init(void) { return TRUE; } Bool Preference_GetBool(Bool defaultValue, const char *name) { return defaultValue; } char * Preference_GetString(const char *defaultValue, const char *name) { return (defaultValue == NULL) ? NULL : strdup(defaultValue); } char * Preference_GetPathName(const char *defaultValue, const char *fmt) { return (defaultValue == NULL) ? NULL : strdup(defaultValue); } int32 Config_GetTriState(int32 defaultValue, const char *fmt, ...) { return defaultValue; } char * Config_GetPathName(const char *defaultValue, const char *format, ...) { return defaultValue ? strdup(defaultValue) : NULL; } Bool Config_NotSet(const char *fmt, ...) { return FALSE; } open-vm-tools-9.4.0-1280544/lib/glibUtils/0000755765153500003110000000000012220061622016135 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/glibUtils/sysLogger.c0000644765153500003110000001372612220061556020276 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file sysLogger.c * * Logger that writes to syslog(3). Since there's only one "syslog connection" * for the whole application, this code does reference counting to allow * different domains to be configured with a "syslog" handler, and still be * able to call closelog(3) when appropriate. */ #include "glibUtils.h" #include #include #include typedef struct SysLogger { GlibLogger handler; gchar *domain; gint refcount; } SysLogger; static SysLogger *gSysLogger; static GStaticMutex gSysLoggerLock = G_STATIC_MUTEX_INIT; /* ******************************************************************************* * SysLoggerLog -- */ /** * * @brief Sends the given log message to syslog. * * @param[in] domain Unused. * @param[in] level Log level. * @param[in] message Message to log. * @param[in] data Unused. * ****************************************************************************** */ static void SysLoggerLog(const gchar *domain, GLogLevelFlags level, const gchar *message, gpointer data) { gchar *local; int priority; /* glib and syslog disagree about critical / error. */ if (level & G_LOG_LEVEL_ERROR) { priority = LOG_CRIT; } else if (level & G_LOG_LEVEL_CRITICAL) { priority = LOG_ERR; } else if (level & G_LOG_LEVEL_WARNING) { priority = LOG_WARNING; } else if (level & G_LOG_LEVEL_MESSAGE) { priority = LOG_NOTICE; } else if (level & G_LOG_LEVEL_INFO) { priority = LOG_INFO; } else { priority = LOG_DEBUG; } local = g_locale_from_utf8(message, -1, NULL, NULL, NULL); if (local != NULL) { syslog(priority, "%s", local); g_free(local); } else { syslog(priority, "%s", message); } } /* ******************************************************************************* * SysLoggerUnref -- */ /** * * @brief Decreases the ref count and closes syslog if it reaches 0. * * @param[in] data Unused. * ******************************************************************************* */ static void SysLoggerUnref(gpointer data) { g_return_if_fail(data == gSysLogger); g_return_if_fail(gSysLogger->refcount > 0); g_static_mutex_lock(&gSysLoggerLock); gSysLogger->refcount -= 1; if (gSysLogger->refcount == 0) { closelog(); g_free(gSysLogger->domain); g_free(gSysLogger); gSysLogger = NULL; } g_static_mutex_unlock(&gSysLoggerLock); } /* ******************************************************************************* * GlibUtils_CreateSysLogger -- */ /** * * @brief Initializes syslog if it hasn't been done yet. * * Since syslog is shared, it's not recommended to change the default domain * during the lifetime of the application, since that may not reflect on the * syslogs (and, when it does, it might be confusing). * * @param[in] domain Application name, used as the syslog identity. * @param[in] facility Facility to use. One of: "daemon", "local[0-7]", "user" (default). * * @return Syslog logger data. * ******************************************************************************* */ GlibLogger * GlibUtils_CreateSysLogger(const char *domain, const char *facility) { g_static_mutex_lock(&gSysLoggerLock); if (gSysLogger == NULL) { int facid = LOG_USER; if (facility != NULL) { int idx; if (strcmp(facility, "daemon") == 0) { facid = LOG_DAEMON; } else if (sscanf(facility, "local%d", &idx) == 1) { switch (idx) { case 0: facid = LOG_LOCAL0; break; case 1: facid = LOG_LOCAL1; break; case 2: facid = LOG_LOCAL2; break; case 3: facid = LOG_LOCAL3; break; case 4: facid = LOG_LOCAL4; break; case 5: facid = LOG_LOCAL5; break; case 6: facid = LOG_LOCAL6; break; case 7: facid = LOG_LOCAL7; break; default: g_message("Invalid local facility for %s: %s\n", domain, facility); break; } } else if (strcmp(facility, "user") != 0) { g_message("Invalid syslog facility for %s: %s\n", domain, facility); } } gSysLogger = g_new0(SysLogger, 1); gSysLogger->handler.addsTimestamp = TRUE; gSysLogger->handler.shared = FALSE; gSysLogger->handler.logfn = SysLoggerLog; gSysLogger->handler.dtor = SysLoggerUnref; gSysLogger->domain = g_strdup(domain); gSysLogger->refcount = 1; openlog(gSysLogger->domain, LOG_CONS | LOG_PID, facid); } else { gSysLogger->refcount += 1; } g_static_mutex_unlock(&gSysLoggerLock); return &gSysLogger->handler; } open-vm-tools-9.4.0-1280544/lib/glibUtils/stdLogger.c0000644765153500003110000001503612220061556020246 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file stdLogger.c * * A very simplified version of a file logger that uses the standard output * streams (stdout / stderr). */ #include "glibUtils.h" #include #if defined(_WIN32) static GStaticMutex gConsoleLock = G_STATIC_MUTEX_INIT; static gint gRefCount = 0; #endif typedef struct StdLogger { GlibLogger handler; #if defined(_WIN32) gboolean attached; #endif } StdLogger; /* ******************************************************************************* * StdLoggerLog -- */ /** * * Logs a message to stdout or stderr depending on its severity. * * @param[in] domain Unused. * @param[in] level Log level. * @param[in] message Message to log. * @param[in] data Logger data. * ******************************************************************************* */ static void StdLoggerLog(const gchar *domain, GLogLevelFlags level, const gchar *message, gpointer data) { gchar *local; FILE *dest = (level < G_LOG_LEVEL_MESSAGE) ? stderr : stdout; #if defined(_WIN32) StdLogger *sdata = data; if (!sdata->attached) { g_static_mutex_lock(&gConsoleLock); if (gRefCount != 0 || GlibUtils_AttachConsole()) { gRefCount++; sdata->attached = TRUE; } g_static_mutex_unlock(&gConsoleLock); } if (!sdata->attached) { return; } #endif local = g_locale_from_utf8(message, -1, NULL, NULL, NULL); if (local != NULL) { fputs(local, dest); g_free(local); } else { fputs(message, dest); } } /* ******************************************************************************* * StdLoggerDestroy -- */ /** * * Cleans up the internal state of the logger. * * @param[in] data Logger data. * ******************************************************************************* */ static void StdLoggerDestroy(gpointer data) { #if defined(_WIN32) StdLogger *sdata = data; g_static_mutex_lock(&gConsoleLock); if (sdata->attached && --gRefCount == 0) { FreeConsole(); } g_static_mutex_unlock(&gConsoleLock); #endif g_free(data); } #if defined(_WIN32) /* ******************************************************************************* * GlibUtilsIsRedirected -- */ /** * * Checks whether given standard device (standard input, standard output, * or standard error) has been redirected to an on-disk file/pipe. * Win32-only. * * @param[in] nStdHandle The standard device number. * * @return TRUE if device redirected to a file/pipe. * ******************************************************************************* */ static gboolean GlibUtilsIsRedirected(DWORD nStdHandle) { HANDLE handle = GetStdHandle(nStdHandle); DWORD type = handle ? GetFileType(handle) : FILE_TYPE_UNKNOWN; return type == FILE_TYPE_DISK || type == FILE_TYPE_PIPE; } /* ******************************************************************************* * GlibUtils_AttachConsole -- */ /** * * Attaches a console to the current process. If the parent process already has * a console open, reuse it. Otherwise, create a new console for the current * process. Win32-only. * * It's safe to call this function multiple times (it won't do anything if * the process already has a console). * * @note Attaching to the parent process's console is only available on XP and * later. * * @return Whether the process is attached to a console. * ******************************************************************************* */ gboolean GlibUtils_AttachConsole(void) { typedef BOOL (WINAPI *AttachConsoleFn)(DWORD); gboolean ret = TRUE; AttachConsoleFn _AttachConsole; BOOL reopenStdout; BOOL reopenStderr; if (GetConsoleWindow() != NULL) { goto exit; } reopenStdout = !GlibUtilsIsRedirected(STD_OUTPUT_HANDLE); reopenStderr = !GlibUtilsIsRedirected(STD_ERROR_HANDLE); if (!reopenStdout && !reopenStderr) { goto exit; } _AttachConsole = (AttachConsoleFn) GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "AttachConsole"); if ((_AttachConsole != NULL && _AttachConsole(ATTACH_PARENT_PROCESS)) || AllocConsole()) { FILE *fptr; if (reopenStdout) { fptr = _wfreopen(L"CONOUT$", L"a", stdout); if (fptr == NULL) { g_warning("_wfreopen failed for stdout/CONOUT$: %d (%s)", errno, strerror(errno)); ret = FALSE; } } if (reopenStderr) { fptr = _wfreopen(L"CONOUT$", L"a", stderr); if (fptr == NULL) { g_warning("_wfreopen failed for stderr/CONOUT$: %d (%s)", errno, strerror(errno)); ret = FALSE; } else { setvbuf(fptr, NULL, _IONBF, 0); } } } else { ret = FALSE; } exit: if (!ret) { g_warning("Console redirection unavailable."); } return ret; } #endif /* ******************************************************************************* * GlibUtils_CreateStdLogger -- */ /** * * @brief Configures a new std logger. * * @return A new logger instance. * ******************************************************************************* */ GlibLogger * GlibUtils_CreateStdLogger(void) { StdLogger *data = g_new0(StdLogger, 1); data->handler.logfn = StdLoggerLog; data->handler.addsTimestamp = FALSE; data->handler.shared = FALSE; data->handler.dtor = StdLoggerDestroy; return &data->handler; } open-vm-tools-9.4.0-1280544/lib/glibUtils/fileLogger.c0000644765153500003110000002754112220061556020377 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file fileLogger.c * * Logger that uses file streams and provides optional log rotation. */ #include "glibUtils.h" #include #include #include #if defined(G_PLATFORM_WIN32) # include # include #else # include # include #endif typedef struct FileLogger { GlibLogger handler; GIOChannel *file; gchar *path; gint logSize; guint64 maxSize; guint maxFiles; gboolean append; gboolean error; GStaticMutex lock; } FileLogger; #if !defined(_WIN32) /* ******************************************************************************* * FileLoggerIsValid -- */ /** * * Checks that the file descriptor backing this logger is still valid. * * This is a racy workaround for an issue with glib code; or, rather, two * issues. The first issue is that we can't intercept G_LOG_FLAG_RECURSION, * and glib just aborts when that happens (see gnome bug 618956). The second * is that if a GIOChannel channel write fails, that calls * g_io_channel_error_from_errno, which helpfully logs stuff, causing recursion. * Don't get me started on why that's, well, at least questionable. * * This is racy because between the check and the actual GIOChannel operation, * the state of the FD may have changed. In reality, since the bug this is * fixing happens in very special situations where code outside this file is * doing weird things like closing random fds, it should be OK. * * We may still get other write errors from the GIOChannel than EBADF, but * those would be harder to work around. Hopefully this handles the most usual * cases. * * See bug 783999 for some details about what triggers the bug. * * @param[in] logger The logger instance. * * @return TRUE if the I/O channel is still valid. * ******************************************************************************* */ static gboolean FileLoggerIsValid(FileLogger *logger) { if (logger->file != NULL) { int fd = g_io_channel_unix_get_fd(logger->file); return fcntl(fd, F_GETFD) >= 0; } return FALSE; } #else #define FileLoggerIsValid(logger) TRUE #endif /* ******************************************************************************* * FileLoggerGetPath -- */ /** * * Parses the given template file name and expands embedded variables, and * places the log index information at the right position. * * The following variables are expanded: * * - ${USER}: user's login name. * - ${PID}: current process's pid. * - ${IDX}: index of the log file (for rotation). * * @param[in] data Log handler data. * @param[in] index Index of the log file. * * @return The expanded log file path. * ****************************************************************************** */ static gchar * FileLoggerGetPath(FileLogger *data, gint index) { gboolean hasIndex = FALSE; gchar indexStr[11]; gchar *logpath; gchar *vars[] = { "${USER}", NULL, "${PID}", NULL, "${IDX}", indexStr, }; gchar *tmp; size_t i; logpath = g_strdup(data->path); vars[1] = (char *) g_get_user_name(); vars[3] = g_strdup_printf("%u", (unsigned int) getpid()); g_snprintf(indexStr, sizeof indexStr, "%d", index); for (i = 0; i < G_N_ELEMENTS(vars); i += 2) { char *last = logpath; char *start; while ((start = strstr(last, vars[i])) != NULL) { gchar *tmp; char *end = start + strlen(vars[i]); size_t offset = (start - last) + strlen(vars[i+1]); *start = '\0'; tmp = g_strdup_printf("%s%s%s", logpath, vars[i+1], end); g_free(logpath); logpath = tmp; last = logpath + offset; /* XXX: ugly, but well... */ if (i == 4) { hasIndex = TRUE; } } } g_free(vars[3]); /* * Always make sure we add the index if it's not 0, since that's used for * backing up old log files. */ if (index != 0 && !hasIndex) { char *sep = strrchr(logpath, '.'); char *pathsep = strrchr(logpath, '/'); if (pathsep == NULL) { pathsep = strrchr(logpath, '\\'); } if (sep != NULL && sep > pathsep) { *sep = '\0'; sep++; tmp = g_strdup_printf("%s.%d.%s", logpath, index, sep); } else { tmp = g_strdup_printf("%s.%d", logpath, index); } g_free(logpath); logpath = tmp; } return logpath; } /* ******************************************************************************* * FileLoggerOpen -- */ /** * * Opens a log file for writing, backing up the existing log file if one is * present. Only one old log file is preserved. * * @note Make sure this function is called with the write lock held. * * @param[in] data Log handler data. * * @return Log file pointer (NULL on error). * ******************************************************************************* */ static GIOChannel * FileLoggerOpen(FileLogger *data) { GIOChannel *logfile = NULL; gchar *path; g_return_val_if_fail(data != NULL, NULL); path = FileLoggerGetPath(data, 0); if (g_file_test(path, G_FILE_TEST_EXISTS)) { struct stat fstats; if (g_stat(path, &fstats) > -1) { data->logSize = (gint) fstats.st_size; } if (!data->append || data->logSize >= data->maxSize) { /* * Find the last log file and iterate back, changing the indices as we go, * so that the oldest log file has the highest index (the new log file * will always be index "0"). When not rotating, "maxFiles" is 1, so we * always keep one backup. */ gchar *log; guint id; GPtrArray *logfiles = g_ptr_array_new(); /* * Find the id of the last log file. The pointer array will hold * the names of all existing log files + the name of the last log * file, which may or may not exist. */ for (id = 0; id < data->maxFiles; id++) { log = FileLoggerGetPath(data, id); g_ptr_array_add(logfiles, log); if (!g_file_test(log, G_FILE_TEST_IS_REGULAR)) { break; } } /* Rename the existing log files, increasing their index by 1. */ for (id = logfiles->len - 1; id > 0; id--) { gchar *dest = g_ptr_array_index(logfiles, id); gchar *src = g_ptr_array_index(logfiles, id - 1); if (!g_file_test(dest, G_FILE_TEST_IS_DIR) && (!g_file_test(dest, G_FILE_TEST_EXISTS) || g_unlink(dest) == 0)) { g_rename(src, dest); } else { g_unlink(src); } } /* Cleanup. */ for (id = 0; id < logfiles->len; id++) { g_free(g_ptr_array_index(logfiles, id)); } g_ptr_array_free(logfiles, TRUE); data->logSize = 0; data->append = FALSE; } } logfile = g_io_channel_new_file(path, data->append ? "a" : "w", NULL); g_free(path); if (logfile != NULL) { g_io_channel_set_encoding(logfile, NULL, NULL); } return logfile; } /* ******************************************************************************* * FileLoggerLog -- */ /** * * Logs a message to the configured destination file. Also opens the file for * writing if it hasn't been done yet. * * @param[in] domain Log domain. * @param[in] level Log level. * @param[in] message Message to log. * @param[in] data File logger. * ******************************************************************************* */ static void FileLoggerLog(const gchar *domain, GLogLevelFlags level, const gchar *message, gpointer data) { FileLogger *logger = data; gsize written; g_static_mutex_lock(&logger->lock); if (logger->error) { goto exit; } if (logger->file == NULL) { if (logger->file == NULL) { logger->file = FileLoggerOpen(data); } if (logger->file == NULL) { logger->error = TRUE; goto exit; } } if (!FileLoggerIsValid(logger)) { logger->error = TRUE; goto exit; } /* Write the log file and do log rotation accounting. */ if (g_io_channel_write_chars(logger->file, message, -1, &written, NULL) == G_IO_STATUS_NORMAL) { if (logger->maxSize > 0) { logger->logSize += (gint) written; if (logger->logSize >= logger->maxSize) { g_io_channel_unref(logger->file); logger->append = FALSE; logger->file = FileLoggerOpen(logger); } else { g_io_channel_flush(logger->file, NULL); } } else { g_io_channel_flush(logger->file, NULL); } } exit: g_static_mutex_unlock(&logger->lock); } /* ****************************************************************************** * FileLoggerDestroy -- */ /** * * Cleans up the internal state of a file logger. * * @param[in] _data File logger data. * ****************************************************************************** */ static void FileLoggerDestroy(gpointer data) { FileLogger *logger = data; if (logger->file != NULL) { g_io_channel_unref(logger->file); } g_static_mutex_free(&logger->lock); g_free(logger->path); g_free(logger); } /* ******************************************************************************* * GlibUtils_CreateFileLogger -- */ /** * * @brief Creates a new file logger based on the given configuration. * * @param[in] path Path to log file. * @param[in] append Whether to append to existing log file. * @param[in] maxSize Maximum log file size (in MB, 0 = no limit). * @param[in] maxFiles Maximum number of old files to be kept. * * @return A new logger, or NULL on error. * ******************************************************************************* */ GlibLogger * GlibUtils_CreateFileLogger(const char *path, gboolean append, guint maxSize, guint maxFiles) { FileLogger *data = NULL; g_return_val_if_fail(path != NULL, NULL); data = g_new0(FileLogger, 1); data->handler.addsTimestamp = FALSE; data->handler.shared = FALSE; data->handler.logfn = FileLoggerLog; data->handler.dtor = FileLoggerDestroy; data->path = g_filename_from_utf8(path, -1, NULL, NULL, NULL); if (data->path == NULL) { g_free(data); return NULL; } data->append = append; data->maxSize = maxSize * 1024 * 1024; data->maxFiles = maxFiles + 1; /* To account for the active log file. */ g_static_mutex_init(&data->lock); return &data->handler; } open-vm-tools-9.4.0-1280544/lib/glibUtils/Makefile.am0000644765153500003110000000216412220061556020202 0ustar dtormts################################################################################ ### Copyright 2011 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libGlibUtils.la libGlibUtils_la_CPPFLAGS = libGlibUtils_la_CPPFLAGS += @GLIB2_CPPFLAGS@ libGlibUtils_la_SOURCES = libGlibUtils_la_SOURCES += fileLogger.c libGlibUtils_la_SOURCES += stdLogger.c libGlibUtils_la_SOURCES += sysLogger.c open-vm-tools-9.4.0-1280544/lib/glibUtils/Makefile.in0000644765153500003110000005245012220061622020210 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2011 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/glibUtils DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libGlibUtils_la_LIBADD = am_libGlibUtils_la_OBJECTS = libGlibUtils_la-fileLogger.lo \ libGlibUtils_la-stdLogger.lo libGlibUtils_la-sysLogger.lo libGlibUtils_la_OBJECTS = $(am_libGlibUtils_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libGlibUtils_la_SOURCES) DIST_SOURCES = $(libGlibUtils_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libGlibUtils.la libGlibUtils_la_CPPFLAGS = @GLIB2_CPPFLAGS@ libGlibUtils_la_SOURCES = fileLogger.c stdLogger.c sysLogger.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/glibUtils/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/glibUtils/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libGlibUtils.la: $(libGlibUtils_la_OBJECTS) $(libGlibUtils_la_DEPENDENCIES) $(EXTRA_libGlibUtils_la_DEPENDENCIES) $(LINK) $(libGlibUtils_la_OBJECTS) $(libGlibUtils_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGlibUtils_la-fileLogger.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGlibUtils_la-stdLogger.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGlibUtils_la-sysLogger.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libGlibUtils_la-fileLogger.lo: fileLogger.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libGlibUtils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libGlibUtils_la-fileLogger.lo -MD -MP -MF $(DEPDIR)/libGlibUtils_la-fileLogger.Tpo -c -o libGlibUtils_la-fileLogger.lo `test -f 'fileLogger.c' || echo '$(srcdir)/'`fileLogger.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libGlibUtils_la-fileLogger.Tpo $(DEPDIR)/libGlibUtils_la-fileLogger.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fileLogger.c' object='libGlibUtils_la-fileLogger.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libGlibUtils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libGlibUtils_la-fileLogger.lo `test -f 'fileLogger.c' || echo '$(srcdir)/'`fileLogger.c libGlibUtils_la-stdLogger.lo: stdLogger.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libGlibUtils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libGlibUtils_la-stdLogger.lo -MD -MP -MF $(DEPDIR)/libGlibUtils_la-stdLogger.Tpo -c -o libGlibUtils_la-stdLogger.lo `test -f 'stdLogger.c' || echo '$(srcdir)/'`stdLogger.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libGlibUtils_la-stdLogger.Tpo $(DEPDIR)/libGlibUtils_la-stdLogger.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='stdLogger.c' object='libGlibUtils_la-stdLogger.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libGlibUtils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libGlibUtils_la-stdLogger.lo `test -f 'stdLogger.c' || echo '$(srcdir)/'`stdLogger.c libGlibUtils_la-sysLogger.lo: sysLogger.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libGlibUtils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libGlibUtils_la-sysLogger.lo -MD -MP -MF $(DEPDIR)/libGlibUtils_la-sysLogger.Tpo -c -o libGlibUtils_la-sysLogger.lo `test -f 'sysLogger.c' || echo '$(srcdir)/'`sysLogger.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libGlibUtils_la-sysLogger.Tpo $(DEPDIR)/libGlibUtils_la-sysLogger.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sysLogger.c' object='libGlibUtils_la-sysLogger.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libGlibUtils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libGlibUtils_la-sysLogger.lo `test -f 'sysLogger.c' || echo '$(srcdir)/'`sysLogger.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/dynxdr/0000755765153500003110000000000012220061621015506 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/dynxdr/Makefile.am0000644765153500003110000000176412220061556017561 0ustar dtormts################################################################################ ### Copyright 2008 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libDynxdr.la libDynxdr_la_SOURCES = libDynxdr_la_SOURCES += dynxdr.c libDynxdr_la_SOURCES += xdrutil.c open-vm-tools-9.4.0-1280544/lib/dynxdr/xdrutil.c0000644765153500003110000000573612220061556017367 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * xdrutil.c -- * * Utility functions for code that uses XDR to encode/decode data. */ #include #include #include "vm_assert.h" #include "vmxrpc.h" #include "xdrutil.h" /* *----------------------------------------------------------------------------- * * XdrUtil_ArrayAppend -- * * Appends 'cnt' new elements of size 'sz' at the end of the given array. * If successful, len will contain the count of elements in the new * array. * * The newly allocated memory is zeroed out. * * Results: * NULL on allocation failure, pointer to the first new element otherwise. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void * XdrUtil_ArrayAppend(void **array, // IN/OUT u_int *arrayLen, // IN/OUT size_t elemSz, // IN u_int elemCnt) // IN { void *ret = NULL; void *newarray; newarray = realloc(*array, (*arrayLen + elemCnt) * elemSz); if (newarray != NULL) { ret = &((char *)newarray)[*arrayLen * elemSz]; memset(ret, 0, elemSz * elemCnt); *array = newarray; *arrayLen = *arrayLen + elemCnt; } return ret; } /* *----------------------------------------------------------------------------- * * XdrUtil_Deserialize -- * * Deserializes the given data into the provided destination, using the * given XDR function. * * Results: * Whether deserialization was successful. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool XdrUtil_Deserialize(const void *data, // IN size_t dataLen, // IN void *xdrProc, // IN void *dest) // IN { Bool ret; xdrproc_t proc = xdrProc; XDR xdrs; ASSERT(data != NULL); ASSERT(xdrProc != NULL); ASSERT(dest != NULL); xdrmem_create(&xdrs, (char *) data, dataLen, XDR_DECODE); ret = (Bool) proc(&xdrs, dest); xdr_destroy(&xdrs); if (!ret) { VMX_XDR_FREE(proc, dest); } return ret; } open-vm-tools-9.4.0-1280544/lib/dynxdr/dynxdr.c0000644765153500003110000002655012220061556017201 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #include #if defined(_WIN32) # include #else # include # include # include # include #endif #include "dynxdr.h" #include "dynbuf.h" /* * dynxdr.c -- * * Implements an XDR stream backed by a DynBuf. */ typedef struct DynXdrData { DynBuf data; Bool freeMe; } DynXdrData; /* * FreeBSD < 5.0 and Solaris do not declare some parameters as "const". */ #if defined(sun) || (defined(__FreeBSD__) && __FreeBSD_version < 500000) # define DYNXDR_CONST #else # define DYNXDR_CONST const #endif /* * Mac OS X, FreeBSD and Solaris don't take a const parameter to the * "x_getpostn" function. */ #if defined(__APPLE__) || defined(__FreeBSD__) || defined(sun) # define DYNXDR_GETPOS_CONST #else # define DYNXDR_GETPOS_CONST const #endif /* * Solaris defines the parameter to "x_putbytes" as an int. */ #if defined(sun) # define DYNXDR_SIZE_T int #else # define DYNXDR_SIZE_T u_int #endif /* * Mac OS 64-bit defines the parameter to "x_putlong" as an int. */ #if defined __APPLE__ && defined __LP64__ # define DYNXDR_LONG int #else # define DYNXDR_LONG long #endif #if defined(sun) # define DYNXDR_INLINE_T rpc_inline_t # define DYNXDR_INLINE_LEN_T int #else # define DYNXDR_INLINE_T int32_t # define DYNXDR_INLINE_LEN_T u_int #endif /* *----------------------------------------------------------------------------- * * DynXdrPutBytes -- * * Writes a byte array into the XDR stream. * * Results: * TRUE: all ok * FALSE: failed to add data do dynbuf. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static bool_t DynXdrPutBytes(XDR *xdrs, // IN/OUT DYNXDR_CONST char *data, // IN DYNXDR_SIZE_T len) // IN { DynXdrData *priv = (DynXdrData *) xdrs->x_private; return DynBuf_Append(&priv->data, data, len); } /* *----------------------------------------------------------------------------- * * DynXdrGetPos -- * * Returns the current position of the buffer, which is the same as * the current buffer size. * * XXX: The Mac OS X headers don't expect a "const" argument. * * Results: * The size of the underlying buffer. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static u_int DynXdrGetPos(DYNXDR_GETPOS_CONST XDR *xdrs) // IN { DynXdrData *priv = (DynXdrData *) xdrs->x_private; return (u_int) DynBuf_GetSize(&priv->data); } /* *----------------------------------------------------------------------------- * * DynXdrSetPos -- * * Sets the position of the XDR stream. The current data in the buffer is * not affected, just the pointer to the current position. * * Results: * TRUE if pos is within the bounds of the backing buffer. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static bool_t DynXdrSetPos(XDR *xdrs, // IN u_int pos) // IN { DynXdrData *priv = (DynXdrData *) xdrs->x_private; if (pos <= DynBuf_GetAllocatedSize(&priv->data)) { DynBuf_SetSize(&priv->data, (size_t) pos); return TRUE; } return FALSE; } #if defined(__GLIBC__) || (defined(sun) && (defined(_LP64) || defined(_KERNEL))) /* *----------------------------------------------------------------------------- * * DynXdrPutInt32 -- * * Writes a 32-bit int to the XDR stream. * * XXX: This seems to be a glibc-only extenstion. It's present since at * least glibc 2.1, according to their CVS. * * XXX: Investigate this further. This XDR operation exists in Solaris * since at least Solaris 9. * * Results: * TRUE: all ok * FALSE: failed to add data do dynbuf. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static bool_t DynXdrPutInt32(XDR *xdrs, // IN/OUT DYNXDR_CONST int32_t *ip) // IN { int32_t out = htonl(*ip); DynXdrData *priv = (DynXdrData *) xdrs->x_private; return DynBuf_Append(&priv->data, &out, sizeof out); } #endif /* *----------------------------------------------------------------------------- * * DynXdrPutLong -- * * Writes a 32-bit int to the XDR stream. * * Results: * TRUE: all ok * FALSE: failed to add data do dynbuf. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static bool_t DynXdrPutLong(XDR *xdrs, // IN/OUT DYNXDR_CONST DYNXDR_LONG *lp) // IN { int32 out; DynXdrData *priv = (DynXdrData *) xdrs->x_private; #ifdef __APPLE__ ASSERT_ON_COMPILE(sizeof *lp <= sizeof (int32)); #endif out = htonl((int32)*lp); return DynBuf_Append(&priv->data, &out, sizeof out); } /* *----------------------------------------------------------------------------- * * DynXdrInline -- * * Return a pointer to a contiguous buffer of len bytes. On XDR_ENCODE, * is used to preallocate chunks of the backing buffer such that the caller * may set bulk 4-byte members w/o reallocating each time. * * Results: * Valid pointer on success, NULL on failure. * * Side effects: * Backing DynBuf may be enlarged. * *----------------------------------------------------------------------------- */ static DYNXDR_INLINE_T * DynXdrInline(XDR *xdrs, // IN/OUT DYNXDR_INLINE_LEN_T len) // IN { DynXdrData *priv = (DynXdrData *)xdrs->x_private; DynBuf *buf = &priv->data; DYNXDR_INLINE_T *retAddr; ASSERT(len >= 0); ASSERT(xdrs->x_op == XDR_ENCODE); if (len == 0) { return (DYNXDR_INLINE_T *)&buf->data[buf->size]; } if (buf->allocated - buf->size < len) { /* DynBuf too small. Grow it. */ if (!DynBuf_Enlarge(buf, buf->size + len)) { return NULL; } } retAddr = (DYNXDR_INLINE_T *)&buf->data[buf->size]; buf->size += len; return retAddr; } /* *----------------------------------------------------------------------------- * * DynXdr_Create -- * * Creates a new XDR struct backed by a DynBuf. The XDR stream is created * in XDR_ENCODE mode. The "in" argument is optional - if NULL, a new XDR * structure will be allocated. * * Results: * The XDR struct, or NULL on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ XDR * DynXdr_Create(XDR *in) // IN { static struct xdr_ops dynXdrOps = { /* * Yes, these macros are a little redundant, but I figure it helps with * readability to group the sun/_KERNEL bits together. */ #if !defined(sun) || (defined(sun) && !defined(_KERNEL)) NULL, /* x_getlong */ DynXdrPutLong, /* x_putlong */ #endif NULL, /* x_getbytes */ DynXdrPutBytes, /* x_putbytes */ DynXdrGetPos, /* x_getpostn */ DynXdrSetPos, /* x_setpostn */ DynXdrInline, /* x_inline */ NULL, /* x_destroy */ #if defined(__GLIBC__) NULL, /* x_getint32 */ DynXdrPutInt32, /* x_putint32 */ #elif defined(__APPLE__) NULL, /* x_control */ #elif defined(sun) && (defined(_LP64) || defined(_KERNEL)) NULL, /* x_control */ NULL, /* x_getint32 */ DynXdrPutInt32, /* x_putint32 */ #endif }; XDR *ret; DynXdrData *priv; if (in == NULL) { ret = malloc(sizeof *ret); if (ret == NULL) { goto error; } } else { ret = in; } priv = malloc(sizeof *priv); if (priv == NULL) { goto error; } priv->freeMe = (in == NULL); DynBuf_Init(&priv->data); ret->x_op = XDR_ENCODE; ret->x_public = NULL; ret->x_private = (char *) priv; ret->x_base = 0; ret->x_ops = &dynXdrOps; return ret; error: if (in == NULL) { free(ret); } return NULL; } /* *----------------------------------------------------------------------------- * * DynXdr_AppendRaw -- * * Appends some raw bytes to the XDR stream's internal dynbuf. This is * useful when non-XDR data may need to be added to the buffer, avoiding * the need to create another buffer and copying the existing data. * * Results: * Whether appending the data was successful. * * Side effects: * None. * *----------------------------------------------------------------------------- */ Bool DynXdr_AppendRaw(XDR *xdrs, // IN const void *buf, // IN size_t len) // IN { DynBuf *intbuf = &((DynXdrData *) xdrs->x_private)->data; return DynBuf_Append(intbuf, buf, len); } /* *----------------------------------------------------------------------------- * * DynXdr_GetData -- * * Returns a copy of the current data in the XDR buffer. Caller is * responsible for freeing the data. * * Results: * The current data in the buffer, or NULL if there's no data, or failed * to allocate data. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void * DynXdr_AllocGet(XDR *xdrs) // IN { DynBuf *buf = &((DynXdrData *) xdrs->x_private)->data; return DynBuf_AllocGet(buf); } /* *----------------------------------------------------------------------------- * * DynXdr_Get -- * * Returns the current data in the XDR buffer. * * Results: * The current data in the buffer, or NULL if there's no data. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void * DynXdr_Get(XDR *xdrs) // IN { DynBuf *buf = &((DynXdrData *) xdrs->x_private)->data; return DynBuf_Get(buf); } /* *----------------------------------------------------------------------------- * * DynXdr_Destroy -- * * Frees data in the XDR stream, optionally destroying the underlying * DynBuf (if "release" is TRUE). If the XDR stream was dynamically * allocated by DynXdr_Create(), it will be freed. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ void DynXdr_Destroy(XDR *xdrs, // IN Bool release) // IN { if (xdrs) { DynXdrData *priv = (DynXdrData *) xdrs->x_private; if (release) { DynBuf_Destroy(&priv->data); } if (priv->freeMe) { free(xdrs); } free(priv); } } open-vm-tools-9.4.0-1280544/lib/dynxdr/Makefile.in0000644765153500003110000004367112220061621017566 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2008 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/dynxdr DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libDynxdr_la_LIBADD = am_libDynxdr_la_OBJECTS = dynxdr.lo xdrutil.lo libDynxdr_la_OBJECTS = $(am_libDynxdr_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libDynxdr_la_SOURCES) DIST_SOURCES = $(libDynxdr_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libDynxdr.la libDynxdr_la_SOURCES = dynxdr.c xdrutil.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/dynxdr/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/dynxdr/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libDynxdr.la: $(libDynxdr_la_OBJECTS) $(libDynxdr_la_DEPENDENCIES) $(EXTRA_libDynxdr_la_DEPENDENCIES) $(LINK) $(libDynxdr_la_OBJECTS) $(libDynxdr_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dynxdr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdrutil.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/rpcIn/0000755765153500003110000000000012220061623015253 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/rpcIn/Makefile.am0000644765153500003110000000202012220061556017306 0ustar dtormts################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ noinst_LTLIBRARIES = libRpcIn.la libRpcIn_la_SOURCES = libRpcIn_la_SOURCES += rpcin.c libRpcIn_la_CPPFLAGS = libRpcIn_la_CPPFLAGS += @VMTOOLS_CPPFLAGS@ open-vm-tools-9.4.0-1280544/lib/rpcIn/rpcin.c0000644765153500003110000005137112220061556016546 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * rpcin.c -- * * Remote Procedure Call between VMware and guest applications * C implementation. * * This module implements the guest=>host direction only. * The in and out modules are separate since some applications (e.g. * drivers that want to do RPC-based logging) only want/need/can have the * out direction (the in direction is more complicated). */ #ifdef __KERNEL__ # include "kernelStubs.h" #else # include # include # include # include # if defined(_WIN32) && defined(_MSC_VER) # include # endif # include "debug.h" # include "str.h" # include "strutil.h" #endif #if defined(VMTOOLS_USE_GLIB) # include "vmware/tools/guestrpc.h" # include "vmware/tools/utils.h" #endif #include "vmware.h" #include "message.h" #include "rpcin.h" #if defined(VMTOOLS_USE_GLIB) #define RPCIN_SCHED_EVENT(in, src) do { \ (in)->nextEvent = src; \ g_source_set_callback((in)->nextEvent, RpcInLoop, (in), NULL); \ g_source_attach((in)->nextEvent, (in)->mainCtx); \ } while (0) #else /* VMTOOLS_USE_GLIB */ #include "eventManager.h" /* Which event queue should RPC events be added to? */ static DblLnkLst_Links *gTimerEventQueue; /* * The RpcIn object */ /* The list of TCLO command callbacks we support */ typedef struct RpcInCallbackList { const char *name; size_t length; /* Length of name so we don't have to strlen a lot */ RpcIn_Callback callback; struct RpcInCallbackList *next; void *clientData; } RpcInCallbackList; #endif /* VMTOOLS_USE_GLIB */ struct RpcIn { #if defined(VMTOOLS_USE_GLIB) GSource *nextEvent; GMainContext *mainCtx; RpcIn_Callback dispatch; gpointer clientData; #else RpcInCallbackList *callbacks; Event *nextEvent; #endif Message_Channel *channel; unsigned int delay; /* The delay of the previous iteration of RpcInLoop */ unsigned int maxDelay; /* The maximum delay to schedule in RpcInLoop */ RpcIn_ErrorFunc *errorFunc; void *errorData; /* * State of the result associated to the last TCLO request we received */ /* Should we send the result back? */ Bool mustSend; /* The result itself */ char *last_result; /* The size of the result */ size_t last_resultLen; /* * It's possible for a callback dispatched by RpcInLoop to call RpcIn_stop. * When this happens, we corrupt the state of the RpcIn struct, resulting in * a crash the next time RpcInLoop is called. To prevent corruption of the * RpcIn struct, we check inLoop when RpcIn_stop is called, and if it is * true, we set shouldStop to TRUE instead of actually stopping the * channel. When RpcInLoop exits, it will stop the channel if shouldStop is * TRUE. */ Bool inLoop; // RpcInLoop is running. Bool shouldStop; // Stop the channel the next time RpcInLoop exits. }; /* * The following functions are only needed in the non-glib version of the * library. The glib version of the library only deals with the transport * aspects of the code - RPC dispatching and other RPC-layer concerns are * handled by the rpcChannel abstraction library, or by the application. */ #if !defined(VMTOOLS_USE_GLIB) /* *----------------------------------------------------------------------------- * * RpcInPingCallback -- * * Replies to a ping message from the VMX. * * Results: * TRUE. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static Bool RpcInPingCallback(char const **result, // OUT size_t *resultLen, // OUT const char *name, // IN const char *args, // IN size_t argsSize, // IN void *clientData) // IN { return RpcIn_SetRetVals(result, resultLen, "", TRUE); } /* *----------------------------------------------------------------------------- * * RpcIn_Construct -- * * Constructor for the RpcIn object. * * Results: * New RpcIn object. * * Side effects: * Sets the current timer event queue, allocates memory. * *----------------------------------------------------------------------------- */ RpcIn * RpcIn_Construct(DblLnkLst_Links *eventQueue) { RpcIn *result; result = (RpcIn *)calloc(1, sizeof(RpcIn)); gTimerEventQueue = result? eventQueue: NULL; return result; } /* *----------------------------------------------------------------------------- * * RpcInLookupCallback -- * * Lookup a callback struct in our list. * * Results: * The callback if found * NULL if not found * * Side effects: * None * *----------------------------------------------------------------------------- */ static RpcInCallbackList * RpcInLookupCallback(RpcIn *in, // IN const char *name) // IN { RpcInCallbackList *p; ASSERT(in); ASSERT(name); for (p = in->callbacks; p; p = p->next) { if (strcmp(name, p->name) == 0) { return p; } } return NULL; } /* *----------------------------------------------------------------------------- * * RpcIn_RegisterCallback -- * * Register an old-style callback to happen when a TCLO message is * received. When a TCLO message beginning with 'name' is * sent, the callback will be called with: the cmd name, the args * (starting with the char directly after the cmd name; that's why * it's helpful to add a space to the name if arguments are expected), * and a pointer to the result. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void RpcIn_RegisterCallback(RpcIn *in, // IN const char *name, // IN RpcIn_Callback cb, // IN void *clientData) // IN { RpcInCallbackList *p; Debug("Registering callback '%s'\n", name); ASSERT(in); ASSERT(name); ASSERT(cb); ASSERT(RpcInLookupCallback(in, name) == NULL); // not there yet p = (RpcInCallbackList *) malloc(sizeof(RpcInCallbackList)); ASSERT_NOT_IMPLEMENTED(p); p->length = strlen(name); p->name = strdup(name); p->callback = cb; p->clientData = clientData; p->next = in->callbacks; in->callbacks = p; } /* *----------------------------------------------------------------------------- * * RpcIn_UnregisterCallback -- * * Unregisters an RpcIn callback by name. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ void RpcIn_UnregisterCallback(RpcIn *in, // IN const char *name) // IN { RpcInCallbackList *cur, *prev; ASSERT(in); ASSERT(name); Debug("Unregistering callback '%s'\n", name); for (cur = in->callbacks, prev = NULL; cur && strcmp(cur->name, name); prev = cur, cur = cur->next); /* * If we called UnregisterCallback on a name that doesn't exist, we * have a problem. */ ASSERT(cur != NULL); if (prev == NULL) { in->callbacks = cur->next; } else { prev->next = cur->next; } free((void *)cur->name); free(cur); } #else /* VMTOOLS_USE_GLIB */ /* *----------------------------------------------------------------------------- * * RpcIn_Construct -- * * Constructor for the RpcIn object. Ties the RpcIn loop to the given * glib main loop, and uses the given callback to dispatch incoming * RPC messages. * * The dispatch callback receives data in a slightly different way than * the regular RPC callbacks. Basically, the raw data from the backdoor * is provided in the "args" field of the RpcInData struct, and "name" * is NULL. So the dispatch function is responsible for parsing the RPC * message, and preparing the RpcInData instance for proper use by the * final consumer. * * Results: * New RpcIn object. * * Side effects: * None. * *----------------------------------------------------------------------------- */ RpcIn * RpcIn_Construct(GMainContext *mainCtx, // IN RpcIn_Callback dispatch, // IN gpointer clientData) // IN { RpcIn *result; ASSERT(mainCtx != NULL); ASSERT(dispatch != NULL); result = calloc(1, sizeof *result); if (result != NULL) { result->mainCtx = mainCtx; result->clientData = clientData; result->dispatch = dispatch; } return result; } #endif /* VMTOOLS_USE_GLIB */ /* *----------------------------------------------------------------------------- * * RpcIn_Destruct -- * * Destructor for the RpcIn object. * * Results: * None. * * Side effects: * Frees all memory associated with the RpcIn object, resets the global * timer event queue. * *----------------------------------------------------------------------------- */ void RpcIn_Destruct(RpcIn *in) // IN { ASSERT(in); ASSERT(in->channel == NULL); ASSERT(in->nextEvent == NULL); ASSERT(in->mustSend == FALSE); #if !defined(VMTOOLS_USE_GLIB) while (in->callbacks) { RpcInCallbackList *p; p = in->callbacks->next; free((void *) in->callbacks->name); free(in->callbacks); in->callbacks = p; } gTimerEventQueue = NULL; #endif free(in); } /* *----------------------------------------------------------------------------- * * RpcInSend -- * * Send the last result back to VMware * * Results: * TRUE on success * FALSE on failure * * Side-effects: * None. * *----------------------------------------------------------------------------- */ static Bool RpcInSend(RpcIn *in) // IN { Bool status; ASSERT(in); ASSERT(in->channel); ASSERT(in->mustSend); status = Message_Send(in->channel, (unsigned char *)in->last_result, in->last_resultLen); if (status == FALSE) { Debug("RpcIn: couldn't send back the last result\n"); } free(in->last_result); in->last_result = NULL; in->last_resultLen = 0; in->mustSend = FALSE; return status; } /* *----------------------------------------------------------------------------- * * RpcInStop -- * * Stop the RPC channel. * * Results: * None * * Side effects: * Sends the last result back to the host. * *----------------------------------------------------------------------------- */ static void RpcInStop(RpcIn *in) // IN { ASSERT(in); if (in->nextEvent) { /* The loop is started. Stop it */ #if defined(VMTOOLS_USE_GLIB) if (!in->inLoop) { g_source_destroy(in->nextEvent); } g_source_unref(in->nextEvent); #else EventManager_Remove(in->nextEvent); #endif in->nextEvent = NULL; } if (in->channel) { /* The channel is open */ if (in->mustSend) { /* There is a final result to send back. Try to send it */ RpcInSend(in); ASSERT(in->mustSend == FALSE); } /* Try to close the channel */ if (Message_Close(in->channel) == FALSE) { Debug("RpcIn: couldn't close channel\n"); } in->channel = NULL; } } /* *----------------------------------------------------------------------------- * * RpcIn_stop -- * * Stop the RPC channel. * * Results: * None * * Side-effects: * Sends the last result to the host, if one exists. * *----------------------------------------------------------------------------- */ void RpcIn_stop(RpcIn *in) // IN { if (in->inLoop) { in->shouldStop = TRUE; } else { RpcInStop(in); } } /* *----------------------------------------------------------------------------- * * RpcInLoop -- * * Receives an RPC from the host. * * Result: * For the Event Manager implementation, always TRUE. * * For the glib implementation, returns FALSE if the timer was rescheduled * so that g_main_loop will unregister the old timer, or TRUE otherwise. * * Side-effects: * Stops the RPC channel on error. * *----------------------------------------------------------------------------- */ #if defined(VMTOOLS_USE_GLIB) static gboolean #else static Bool #endif RpcInLoop(void *clientData) // IN { RpcIn *in; char const *errmsg; char const *reply; size_t repLen; #if defined(VMTOOLS_USE_GLIB) unsigned int current; Bool resched = FALSE; #endif in = (RpcIn *)clientData; ASSERT(in); ASSERT(in->nextEvent); ASSERT(in->channel); ASSERT(in->mustSend); #if defined(VMTOOLS_USE_GLIB) current = in->delay; #else /* * The event has fired: it is no longer valid. Note that this is * not true in the glib case! */ in->nextEvent = NULL; #endif in->inLoop = TRUE; /* * Workaround for bug 780404. Remove if we ever figure out the root cause. * Note that the ASSERT above catches this on non-release builds. */ if (in->channel == NULL) { errmsg = "RpcIn: Channel is not active"; goto error; } /* * This is very important: this is the only way to signal the existence of * this guest application to VMware. */ if (RpcInSend(in) == FALSE) { errmsg = "RpcIn: Unable to send"; goto error; } if (Message_Receive(in->channel, (unsigned char **)&reply, &repLen) == FALSE) { errmsg = "RpcIn: Unable to receive"; goto error; } if (repLen) { unsigned int status; char const *statusStr; unsigned int statusLen; char *result; size_t resultLen; Bool freeResult = FALSE; /* * Execute the RPC */ #if defined(VMTOOLS_USE_GLIB) RpcInData data = { NULL, reply, repLen, NULL, 0, FALSE, NULL, in->clientData }; status = in->dispatch(&data); result = data.result; resultLen = data.resultLen; freeResult = data.freeResult; #else char *cmd; unsigned int index = 0; RpcInCallbackList *cb = NULL; cmd = StrUtil_GetNextToken(&index, reply, " "); if (cmd != NULL) { cb = RpcInLookupCallback(in, cmd); free(cmd); if (cb) { result = NULL; status = cb->callback((char const **) &result, &resultLen, cb->name, reply + cb->length, repLen - cb->length, cb->clientData); ASSERT(result); } else { status = FALSE; result = "Unknown Command"; resultLen = strlen(result); } } else { status = FALSE; result = "Bad command"; resultLen = strlen(result); } #endif if (status) { statusStr = "OK "; statusLen = 3; } else { statusStr = "ERROR "; statusLen = 6; } in->last_result = (char *)malloc(statusLen + resultLen); if (in->last_result == NULL) { errmsg = "RpcIn: Not enough memory"; goto error; } memcpy(in->last_result, statusStr, statusLen); memcpy(in->last_result + statusLen, result, resultLen); in->last_resultLen = statusLen + resultLen; if (freeResult) { free(result); } /* * Run the event pump (in case VMware sends a long sequence of RPCs and * perfoms a time-consuming job) and continue to loop immediately */ in->delay = 0; } else { /* * Nothing to execute */ /* No request -> No result */ ASSERT(in->last_result == NULL); ASSERT(in->last_resultLen == 0); /* * Continue to loop in a while. Use an exponential back-off, doubling * the time to wait each time there isn't a new message, up to the max * delay. */ if (in->delay < in->maxDelay) { if (in->delay > 0) { /* * Catch overflow. */ in->delay = ((in->delay * 2) > in->delay) ? (in->delay * 2) : in->maxDelay; } else { in->delay = 1; } in->delay = MIN(in->delay, in->maxDelay); } } ASSERT(in->mustSend == FALSE); in->mustSend = TRUE; if (!in->shouldStop) { #if defined(VMTOOLS_USE_GLIB) if (in->delay != current) { resched = TRUE; g_source_unref(in->nextEvent); RPCIN_SCHED_EVENT(in, VMTools_CreateTimer(in->delay * 10)); } #else in->nextEvent = EventManager_Add(gTimerEventQueue, in->delay, RpcInLoop, in); #endif if (in->nextEvent == NULL) { errmsg = "RpcIn: Unable to run the loop"; goto error; } } exit: if (in->shouldStop) { RpcInStop(in); in->shouldStop = FALSE; #if defined(VMTOOLS_USE_GLIB) /* Force the GMainContext to unref the GSource that runs the RpcIn loop. */ resched = TRUE; #endif } in->inLoop = FALSE; #if defined(VMTOOLS_USE_GLIB) return !resched; #else return TRUE; #endif error: /* Call the error routine */ (*in->errorFunc)(in->errorData, errmsg); in->shouldStop = TRUE; goto exit; } /* *----------------------------------------------------------------------------- * * RpcIn_start -- * * Start the background loop that receives RPC from VMware * * Result * TRUE on success * FALSE on failure * * Side-effects * None * *----------------------------------------------------------------------------- */ #if defined(VMTOOLS_USE_GLIB) Bool RpcIn_start(RpcIn *in, // IN unsigned int delay, // IN RpcIn_ErrorFunc *errorFunc, // IN void *errorData) // IN #else Bool RpcIn_start(RpcIn *in, // IN unsigned int delay, // IN RpcIn_Callback resetCallback, // IN void *resetClientData, // IN RpcIn_ErrorFunc *errorFunc, // IN void *errorData) // IN #endif { ASSERT(in); in->delay = 0; in->maxDelay = delay; in->errorFunc = errorFunc; in->errorData = errorData; ASSERT(in->channel == NULL); in->channel = Message_Open(0x4f4c4354); if (in->channel == NULL) { Debug("RpcIn_start: couldn't open channel with TCLO protocol\n"); goto error; } /* No initial result */ ASSERT(in->last_result == NULL); ASSERT(in->last_resultLen == 0); ASSERT(in->mustSend == FALSE); in->mustSend = TRUE; ASSERT(in->nextEvent == NULL); #if defined(VMTOOLS_USE_GLIB) RPCIN_SCHED_EVENT(in, VMTools_CreateTimer(in->delay * 10)); #else in->nextEvent = EventManager_Add(gTimerEventQueue, 0, RpcInLoop, in); if (in->nextEvent == NULL) { Debug("RpcIn_start: couldn't start the loop\n"); goto error; } #endif #if !defined(VMTOOLS_USE_GLIB) /* Register the 'reset' handler */ if (resetCallback) { RpcIn_RegisterCallback(in, "reset", resetCallback, resetClientData); } RpcIn_RegisterCallback(in, "ping", RpcInPingCallback, NULL); #endif return TRUE; error: RpcInStop(in); return FALSE; } #if !defined(VMTOOLS_USE_GLIB) /* *----------------------------------------------------------------------------- * * RpcIn_SetRetVals -- * * Utility method to set the return values of a tclo command. * Example: * return RpcIn_SetRetVals(result, resultLen, * "Message", FALSE); * * Results: * retVal * * Side effects: * Sets *result to resultVal & resultLen to strlen(*result). * *----------------------------------------------------------------------------- */ unsigned int RpcIn_SetRetVals(char const **result, // OUT size_t *resultLen, // OUT const char *resultVal, // IN Bool retVal) // IN { ASSERT(result); ASSERT(resultLen); ASSERT(resultVal); *result = resultVal; *resultLen = strlen(*result); return retVal; } #endif open-vm-tools-9.4.0-1280544/lib/rpcIn/Makefile.in0000644765153500003110000004547012220061623017332 0ustar dtormts# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ ################################################################################ ### Copyright 2007 VMware, Inc. All rights reserved. ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of version 2 of the GNU General Public License as ### published by the Free Software Foundation. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/rpcIn DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libRpcIn_la_LIBADD = am_libRpcIn_la_OBJECTS = libRpcIn_la-rpcin.lo libRpcIn_la_OBJECTS = $(am_libRpcIn_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libRpcIn_la_SOURCES) DIST_SOURCES = $(libRpcIn_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@ COMMON_XLIBS = @COMMON_XLIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DNET_CPPFLAGS = @DNET_CPPFLAGS@ DNET_LIBS = @DNET_LIBS@ DOT = @DOT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FUSE_CPPFLAGS = @FUSE_CPPFLAGS@ FUSE_LIBS = @FUSE_LIBS@ GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GREP = @GREP@ GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@ GTHREAD_LIBS = @GTHREAD_LIBS@ GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@ GTKMM_LIBS = @GTKMM_LIBS@ GTK_CPPFLAGS = @GTK_CPPFLAGS@ GTK_LIBS = @GTK_LIBS@ HAVE_DOT = @HAVE_DOT@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HGFS_LIBS = @HGFS_LIBS@ ICU_CPPFLAGS = @ICU_CPPFLAGS@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTVMSG = @INSTVMSG@ KERNEL_RELEASE = @KERNEL_RELEASE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@ LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@ LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@ LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@ LINUXINCLUDE = @LINUXINCLUDE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MODULES = @MODULES@ MODULES_DIR = @MODULES_DIR@ MODULES_OS = @MODULES_OS@ MSCGEN = @MSCGEN@ MSCGEN_DIR = @MSCGEN_DIR@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PREFIX = @PAM_PREFIX@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@ PROCPS_LIBS = @PROCPS_LIBS@ RANLIB = @RANLIB@ RPCGEN = @RPCGEN@ RPCGENFLAGS = @RPCGENFLAGS@ RPCGEN_WRAPPER = @RPCGEN_WRAPPER@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSDIR = @SYSDIR@ TARGET_OS = @TARGET_OS@ TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@ TOOLS_VERSION = @TOOLS_VERSION@ VERSION = @VERSION@ VIX_LIBADD = @VIX_LIBADD@ VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@ VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@ VMTOOLS_LIBS = @VMTOOLS_LIBS@ VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@ XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ XDR_LIBS = @XDR_LIBS@ XMKMF = @XMKMF@ XSM_LIBS = @XSM_LIBS@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_vmw_lib_cfg = @ac_vmw_lib_cfg@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_cxx = @have_cxx@ have_doxygen = @have_doxygen@ have_genmarshal = @have_genmarshal@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libRpcIn.la libRpcIn_la_SOURCES = rpcin.c libRpcIn_la_CPPFLAGS = @VMTOOLS_CPPFLAGS@ all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/rpcIn/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/rpcIn/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libRpcIn.la: $(libRpcIn_la_OBJECTS) $(libRpcIn_la_DEPENDENCIES) $(EXTRA_libRpcIn_la_DEPENDENCIES) $(LINK) $(libRpcIn_la_OBJECTS) $(libRpcIn_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libRpcIn_la-rpcin.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libRpcIn_la-rpcin.lo: rpcin.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libRpcIn_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libRpcIn_la-rpcin.lo -MD -MP -MF $(DEPDIR)/libRpcIn_la-rpcin.Tpo -c -o libRpcIn_la-rpcin.lo `test -f 'rpcin.c' || echo '$(srcdir)/'`rpcin.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libRpcIn_la-rpcin.Tpo $(DEPDIR)/libRpcIn_la-rpcin.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpcin.c' object='libRpcIn_la-rpcin.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libRpcIn_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libRpcIn_la-rpcin.lo `test -f 'rpcin.c' || echo '$(srcdir)/'`rpcin.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: open-vm-tools-9.4.0-1280544/lib/include/0000755765153500003110000000000012220061556015630 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/include/guest_os.h0000644765153500003110000005363012220061556017640 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _GUEST_OS_H_ #define _GUEST_OS_H_ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #include "guest_os_tables.h" /* * There's no practical max to the number of guests that can be defined in * the list below (guest IDs are limited to 2^32), but there is a maximum * of MAXGOSSET guests that can comprise a set, such as ALLLINUX, ALLDARWIN, * or ALLWIN64. * * Be conservative and only declare entries in this list if you need to refer * to the guest specifically in vmx/main/guest_os.c, * vmcore/vmx/main/monitorControl.c, or similar. Don't rely on every supported * guest having an entry in this list. */ typedef enum GuestOSType { GUEST_OS_BASE = 0x5000, GUEST_OS_BASE_MINUS_ONE = 0x4fff, /* So that ANY is equal to BASE */ #define GOT(_name) _name, GUEST_OS_TYPE_GEN #undef GOT } GuestOSType; /* * Maximum number of guests in a set, must be <= LIST_SIZE in geninfo.h */ #define MAXGOSSET 64 typedef enum GuestOSFamilyType { GUEST_OS_FAMILY_ANY = 0x0000, GUEST_OS_FAMILY_LINUX = 0x0001, GUEST_OS_FAMILY_WINDOWS = 0x0002, GUEST_OS_FAMILY_WIN9X = 0x0004, GUEST_OS_FAMILY_WINNT = 0x0008, GUEST_OS_FAMILY_WIN2000 = 0x0010, GUEST_OS_FAMILY_WINXP = 0x0020, GUEST_OS_FAMILY_WINNET = 0x0040, GUEST_OS_FAMILY_NETWARE = 0x0080, GUEST_OS_FAMILY_DARWIN = 0x0100 } GuestOSFamilyType; #define ALLOS GUEST_OS_ANY #define BS(suf) GUEST_OS_##suf #define GOS_IN_SET(gos, ...) Gos_InSet(gos, __VA_ARGS__, 0) #define GOS_IN_SET_ARRAY(gos, set) Gos_InSetArray(gos, set) Bool Gos_InSet(uint32 gos, ...); Bool Gos_InSetArray(uint32 gos, const uint32 *set); #define ALLWIN9X BS(WIN95), BS(WIN98), BS(WINME) #define ALLWIN2000 BS(WIN2000) #define ALLWINXP32 BS(WINXP) #define ALLWINXP64 BS(WINXPPRO_64) #define ALLWINXP ALLWINXP32, ALLWINXP64 #define ALLFREEBSD BS(FREEBSD), BS(FREEBSD_64) #define ALLWINNET32 BS(WINNET) #define ALLWINNET64 BS(WINNET_64) #define ALLWINNET ALLWINNET32, ALLWINNET64 #define ALLWINLONGHORN32 BS(LONGHORN) #define ALLWINLONGHORN64 BS(LONGHORN_64) #define ALLWINLONGHORN ALLWINLONGHORN32, ALLWINLONGHORN64 #define ALLWINVISTA32 BS(WINVISTA) #define ALLWINVISTA64 BS(WINVISTA_64) #define ALLWINVISTA ALLWINVISTA32, ALLWINVISTA64 #define ALLWIN2008R2_64 BS(WIN2008R2_64) #define ALLWIN2008R2 ALLWIN2008R2_64 #define ALLWINSEVEN32 BS(WINSEVEN) #define ALLWINSEVEN64 BS(WINSEVEN_64) #define ALLWINSEVEN ALLWINSEVEN32, ALLWINSEVEN64 #define ALLWINEIGHTSERVER64 BS(WINEIGHTSERVER_64) #define ALLWINEIGHTSERVER ALLWINEIGHTSERVER64 #define ALLWINEIGHTCLIENT32 BS(WINEIGHT) #define ALLWINEIGHTCLIENT64 BS(WINEIGHT_64) #define ALLWINEIGHTCLIENT ALLWINEIGHTCLIENT32, ALLWINEIGHTCLIENT64 #define ALLHYPER_V BS(HYPER_V) #define ALLWINVISTA_OR_HIGHER ALLWINVISTA, ALLWINLONGHORN, \ ALLWIN2008R2, ALLWINSEVEN, \ ALLWINEIGHTSERVER, ALLHYPER_V, \ ALLWINEIGHTCLIENT #define ALLWINNT32 BS(WINNT), ALLWIN2000, ALLWINXP32, \ ALLWINNET32, ALLWINVISTA32, \ ALLWINLONGHORN32, ALLWINSEVEN32, \ ALLWINEIGHTCLIENT32 #define ALLWINNT64 ALLWINXP64, ALLWINNET64, \ ALLWINVISTA64, ALLWINLONGHORN64, \ ALLWINSEVEN64, ALLWIN2008R2_64, \ ALLWINEIGHTCLIENT64, \ ALLWINEIGHTSERVER, ALLHYPER_V #define ALLWINNT ALLWINNT32, ALLWINNT64 #define ALLWIN32 ALLWIN9X, ALLWINNT32 #define ALLWIN64 ALLWINNT64 #define ALLWIN ALLWIN32, ALLWIN64 #define ALLWIN_EXCEPT9XAND2000 \ ALLWINXP, ALLWINNET, ALLWINLONGHORN, \ ALLWINVISTA, ALLWIN2008R2, ALLWINSEVEN,\ ALLWINEIGHTSERVER, ALLWINEIGHTCLIENT, \ ALLHYPER_V, BS(WINNT) #define ALLSOLARIS BS(SOLARIS_6_AND_7), BS(SOLARIS8), \ BS(SOLARIS9), BS(SOLARIS10), \ BS(SOLARIS10_64) #define ALLSOLARIS10 BS(SOLARIS10), BS(SOLARIS10_64) #define ALLNETWARE BS(NETWARE4), BS(NETWARE5), BS(NETWARE6) #define ALL26XLINUX32 BS(OTHER26XLINUX), BS(DEBIAN45), \ BS(RHEL), BS(UBUNTU) #define ALL26XLINUX64 BS(OTHER26XLINUX_64), BS(DEBIAN45_64), \ BS(RHEL_64) #define ALL3XLINUX32 BS(OTHER3XLINUX) #define ALL3XLINUX64 BS(OTHER3XLINUX_64) #define ALLVMKERNEL BS(VMKERNEL), BS(VMKERNEL5) #define ALLLINUX32 BS(OTHER24XLINUX), ALL26XLINUX32, ALL3XLINUX32, \ BS(OTHERLINUX), BS(VMKERNEL) #define ALLLINUX64 BS(OTHER24XLINUX_64), ALL26XLINUX64, \ ALL3XLINUX64, BS(OTHERLINUX_64) #define ALLLINUX ALLLINUX32, ALLLINUX64 #define ALLDARWIN32 BS(DARWIN9), BS(DARWIN10), BS(DARWIN11) #define ALLDARWIN64 BS(DARWIN9_64), BS(DARWIN10_64), \ BS(DARWIN11_64), BS(DARWIN12_64), \ BS(DARWIN13_64) #define ALLDARWIN ALLDARWIN32, ALLDARWIN64 #define ALL64 ALLWIN64, ALLLINUX64, BS(SOLARIS10_64), \ BS(FREEBSD_64), ALLDARWIN64, \ BS(OTHER_64), ALLVMKERNEL #define ALLECOMSTATION BS(ECOMSTATION), BS(ECOMSTATION2) #define ALLOS2 BS(OS2), ALLECOMSTATION #define ALLOS_EXCEPTDARWINANDVMKERNEL \ ALLWIN, ALLFREEBSD, ALLSOLARIS, \ ALLNETWARE, ALLLINUX, ALLECOMSTATION, \ ALLOS2, BS(DOS), BS(WIN31), \ BS(UNIXWARE7), BS(OPENSERVER_5_AND_6), \ BS(OTHER), BS(OTHER_64) /* * These constants are generated by GuestInfoGetOSName which is in * the bora-vmsoft subtree. */ /* vmkernel (ESX) */ #define STR_OS_ESX_4 "VMware ESX 4" #define STR_OS_ESX_5 "VMware ESX 5" /* Linux */ #define STR_OS_ANNVIX "Annvix" #define STR_OS_ARCH "Arch" #define STR_OS_ARKLINUX "Arklinux" #define STR_OS_ASIANUX_3 "asianux3" #define STR_OS_ASIANUX_4 "asianux4" #define STR_OS_AUROX "Aurox" #define STR_OS_ASIANUX "asianux" #define STR_OS_BLACKCAT "BlackCat" #define STR_OS_CENTOS "centos" #define STR_OS_COBALT "Cobalt" #define STR_OS_CONECTIVA "Conectiva" #define STR_OS_DEBIAN "Debian" #define STR_OS_DEBIAN_4 "debian4" #define STR_OS_DEBIAN_5 "debian5" #define STR_OS_DEBIAN_6 "debian6" #define STR_OS_DEBIAN_7 "debian7" #define STR_OS_FEDORA "Fedora" #define STR_OS_GENTOO "Gentoo" #define STR_OS_IMMUNIX "Immunix" #define STR_OS_LINUX "linux" #define STR_OS_LINUX_FROM_SCRATCH "Linux-From-Scratch" #define STR_OS_LINUX_FULL "Other Linux" #define STR_OS_LINUX_PPC "Linux-PPC" #define STR_OS_MANDRAKE "mandrake" #define STR_OS_MANDRAKE_FULL "Mandrake Linux" #define STR_OS_MANDRIVA "mandriva" #define STR_OS_MKLINUX "MkLinux" #define STR_OS_NOVELL "nld9" #define STR_OS_NOVELL_FULL "Novell Linux Desktop 9" #define STR_OS_ORACLE "oraclelinux" #define STR_OS_OTHER "otherlinux" #define STR_OS_OTHER_24 "other24xlinux" #define STR_OS_OTHER_24_FULL "Other Linux 2.4.x kernel" #define STR_OS_OTHER_26 "other26xlinux" #define STR_OS_OTHER_26_FULL "Other Linux 2.6.x kernel" #define STR_OS_OTHER_3X "other3xlinux" #define STR_OS_OTHER_3X_FULL "Other Linux 3.x kernel" #define STR_OS_OTHER_FULL "Other Linux" #define STR_OS_PLD "PLD" #define STR_OS_RED_HAT "redhat" #define STR_OS_RED_HAT_EN "rhel" #define STR_OS_RED_HAT_FULL "Red Hat Linux" #define STR_OS_SLACKWARE "Slackware" #define STR_OS_SLES "sles" #define STR_OS_SLES_FULL "SUSE Linux Enterprise Server" #define STR_OS_SLES_10 "sles10" #define STR_OS_SLES_10_FULL "SUSE Linux Enterprise Server 10" #define STR_OS_SLES_11 "sles11" #define STR_OS_SLES_11_FULL "SUSE Linux Enterprise Server 11" #define STR_OS_SLES_12 "sles12" #define STR_OS_SLES_12_FULL "SUSE Linux Enterprise Server 12" #define STR_OS_SUSE "suse" #define STR_OS_SUSE_FULL "SUSE Linux" #define STR_OS_OPENSUSE "opensuse" #define STR_OS_SMESERVER "SMEServer" #define STR_OS_SUN_DESK "sjds" #define STR_OS_SUN_DESK_FULL "Sun Java Desktop System" #define STR_OS_TINYSOFA "Tiny Sofa" #define STR_OS_TURBO "turbolinux" #define STR_OS_TURBO_FULL "Turbolinux" #define STR_OS_UBUNTU "ubuntu" #define STR_OS_ULTRAPENGUIN "UltraPenguin" #define STR_OS_UNITEDLINUX "UnitedLinux" #define STR_OS_VALINUX "VALinux" #define STR_OS_YELLOW_DOG "Yellow Dog" #define STR_OS_ECOMSTATION "eComStation" /* Windows */ #define STR_OS_WIN_31 "win31" #define STR_OS_WIN_31_FULL "Windows 3.1" #define STR_OS_WIN_95 "win95" #define STR_OS_WIN_95_FULL "Windows 95" #define STR_OS_WIN_98 "win98" #define STR_OS_WIN_98_FULL "Windows 98" #define STR_OS_WIN_ME "winMe" #define STR_OS_WIN_ME_FULL "Windows Me" #define STR_OS_WIN_NT "winNT" #define STR_OS_WIN_NT_FULL "Windows NT" #define STR_OS_WIN_2000_PRO "win2000Pro" #define STR_OS_WIN_2000_PRO_FULL "Windows 2000 Professional" #define STR_OS_WIN_2000_SERV "win2000Serv" #define STR_OS_WIN_2000_SERV_FULL "Windows 2000 Server" #define STR_OS_WIN_2000_ADV_SERV "win2000AdvServ" #define STR_OS_WIN_2000_ADV_SERV_FULL "Windows 2000 Advanced Server" #define STR_OS_WIN_2000_DATACENT_SERV "win2000DataCentServ" #define STR_OS_WIN_2000_DATACENT_SERV_FULL "Windows 2000 Data Center Server" #define STR_OS_WIN_XP_HOME "winXPHome" #define STR_OS_WIN_XP_HOME_FULL "Windows XP Home Edition" #define STR_OS_WIN_XP_PRO "winXPPro" #define STR_OS_WIN_XP_PRO_FULL "Windows XP Professional" #define STR_OS_WIN_XP_PRO_X64 "winXPPro-64" #define STR_OS_WIN_XP_PRO_X64_FULL "Windows XP Professional x64 Edition" #define STR_OS_WIN_NET_WEB "winNetWeb" #define STR_OS_WIN_NET_WEB_FULL "Windows Server 2003 Web Edition" #define STR_OS_WIN_NET_ST "winNetStandard" #define STR_OS_WIN_NET_ST_FULL "Windows Server 2003 Standard Edition" #define STR_OS_WIN_NET_EN "winNetEnterprise" #define STR_OS_WIN_NET_EN_FULL "Windows Server 2003 Enterprise Edition" #define STR_OS_WIN_NET_BUS "winNetBusiness" #define STR_OS_WIN_NET_BUS_FULL "Windows Server 2003 Small Business" #define STR_OS_WIN_NET_COMPCLUSTER "winNetComputeCluster" #define STR_OS_WIN_NET_COMPCLUSTER_FULL "Windows Server 2003 Compute Cluster Edition" #define STR_OS_WIN_NET_STORAGESERVER "winNetStorageSvr" #define STR_OS_WIN_NET_STORAGESERVER_FULL "Windows Storage Server 2003" #define STR_OS_WIN_NET_DC_FULL "Windows Server 2003 Datacenter Edition" #define STR_OS_WIN_NET_DC "winNetDatacenter" #define STR_OS_WIN_LONG "longhorn" #define STR_OS_WIN_VISTA "winVista" #define STR_OS_WIN_VISTA_FULL "Windows Vista" #define STR_OS_WIN_VISTA_X64 "winVista-64" #define STR_OS_WIN_VISTA_X64_FULL "Windows Vista x64 Edition" #define STR_OS_WIN_VISTA_ULTIMATE "winVistaUltimate-32" #define STR_OS_WIN_VISTA_ULTIMATE_FULL "Windows Vista Ultimate Edition" #define STR_OS_WIN_VISTA_HOME_PREMIUM "winVistaHomePremium-32" #define STR_OS_WIN_VISTA_HOME_PREMIUM_FULL "Windows Vista Home Premium Edition" #define STR_OS_WIN_VISTA_HOME_BASIC "winVistaHomeBasic-32" #define STR_OS_WIN_VISTA_HOME_BASIC_FULL "Windows Vista Home Basic Edition" #define STR_OS_WIN_VISTA_ENTERPRISE "winVistaEnterprise-32" #define STR_OS_WIN_VISTA_ENTERPRISE_FULL "Windows Vista Enterprise Edition" #define STR_OS_WIN_VISTA_BUSINESS "winVistaBusiness-32" #define STR_OS_WIN_VISTA_BUSINESS_FULL "Windows Vista Business Edition" #define STR_OS_WIN_VISTA_STARTER "winVistaStarter-32" #define STR_OS_WIN_VISTA_STARTER_FULL "Windows Vista Starter Edition" #define STR_OS_WIN_2008_CLUSTER "winServer2008Cluster-32" #define STR_OS_WIN_2008_CLUSTER_FULL "Windows Server 2008 Cluster Server Edition" #define STR_OS_WIN_2008_DATACENTER "winServer2008Datacenter-32" #define STR_OS_WIN_2008_DATACENTER_FULL "Windows Server 2008 Datacenter Edition" #define STR_OS_WIN_2008_DATACENTER_CORE "winServer2008DatacenterCore-32" #define STR_OS_WIN_2008_DATACENTER_CORE_FULL "Windows Server 2008 Datacenter Edition (core installation)" #define STR_OS_WIN_2008_ENTERPRISE "winServer2008Enterprise-32" #define STR_OS_WIN_2008_ENTERPRISE_FULL "Windows Server 2008 Enterprise Edition" #define STR_OS_WIN_2008_ENTERPRISE_CORE "winServer2008EnterpriseCore-32" #define STR_OS_WIN_2008_ENTERPRISE_CORE_FULL "Windows Server 2008 Enterprise Edition (core installation)" #define STR_OS_WIN_2008_ENTERPRISE_ITANIUM "winServer2008EnterpriseItanium-32" #define STR_OS_WIN_2008_ENTERPRISE_ITANIUM_FULL "Windows Server 2008 Enterprise Edition for Itanium-based Systems" #define STR_OS_WIN_2008_MEDIUM_MANAGEMENT "winServer2008MediumManagement-32" #define STR_OS_WIN_2008_MEDIUM_MANAGEMENT_FULL "Windows Essential Business Server Management Server" #define STR_OS_WIN_2008_MEDIUM_MESSAGING "winServer2008MediumMessaging-32" #define STR_OS_WIN_2008_MEDIUM_MESSAGING_FULL "Windows Essential Business Server Messaging Server" #define STR_OS_WIN_2008_MEDIUM_SECURITY "winServer2008MediumSecurity-32" #define STR_OS_WIN_2008_MEDIUM_SECURITY_FULL "Windows Essential Business Server Security Server" #define STR_OS_WIN_2008_SERVER_FOR_SMALLBUSINESS "winServer2008ForSmallBusiness-32" #define STR_OS_WIN_2008_SERVER_FOR_SMALLBUSINESS_FULL "Windows Server 2008 for Windows Essential Server Solutions" #define STR_OS_WIN_2008_SMALL_BUSINESS "winServer2008SmallBusiness-32" #define STR_OS_WIN_2008_SMALL_BUSINESS_FULL "Windows Server 2008 Small Business Server" #define STR_OS_WIN_2008_SMALL_BUSINESS_PREMIUM "winServer2008SmallBusinessPremium-32" #define STR_OS_WIN_2008_SMALL_BUSINESS_PREMIUM_FULL "Windows Server 2008 Small Business Server Premium Edition" #define STR_OS_WIN_2008_STANDARD "winServer2008Standard-32" #define STR_OS_WIN_2008_STANDARD_FULL "Windows Server 2008 Standard Edition" #define STR_OS_WIN_2008_STANDARD_CORE "winServer2008StandardCore-32" #define STR_OS_WIN_2008_STANDARD_CORE_FULL "Windows Server 2008 Standard Edition (core installation)" #define STR_OS_WIN_2008_STORAGE_ENTERPRISE "winServer2008StorageEnterprise-32" #define STR_OS_WIN_2008_STORAGE_ENTERPRISE_FULL "Windows Server 2008 Storage Server Enterprise" #define STR_OS_WIN_2008_STORAGE_EXPRESS "winServer2008StorageExpress-32" #define STR_OS_WIN_2008_STORAGE_EXPRESS_FULL "Windows Server 2008 Storage Server Express" #define STR_OS_WIN_2008_STORAGE_STANDARD "winServer2008StorageStandard-32" #define STR_OS_WIN_2008_STORAGE_STANDARD_FULL "Windows Server 2008 Storage Server Standard" #define STR_OS_WIN_2008_STORAGE_WORKGROUP "winServer2008StorageWorkgroup-32" #define STR_OS_WIN_2008_STORAGE_WORKGROUP_FULL "Windows Server 2008 Storage Server Workgroup" #define STR_OS_WIN_2008_WEB_SERVER "winServer2008Web-32" #define STR_OS_WIN_2008_WEB_SERVER_FULL "Windows Server 2008 Web Server Edition" /* Windows 64-bit */ #define STR_OS_WIN_VISTA_ULTIMATE_X64 "winVistaUltimate-64" #define STR_OS_WIN_VISTA_HOME_PREMIUM_X64 "winVistaHomePremium-64" #define STR_OS_WIN_VISTA_HOME_BASIC_X64 "winVistaHomeBasic-64" #define STR_OS_WIN_VISTA_ENTERPRISE_X64 "winVistaEnterprise-64" #define STR_OS_WIN_VISTA_BUSINESS_X64 "winVistaBusiness-64" #define STR_OS_WIN_VISTA_STARTER_X64 "winVistaStarter-64" #define STR_OS_WIN_2008_CLUSTER_X64 "winServer2008Cluster-64" #define STR_OS_WIN_2008_DATACENTER_X64 "winServer2008Datacenter-64" #define STR_OS_WIN_2008_DATACENTER_CORE_X64 "winServer2008DatacenterCore-64" #define STR_OS_WIN_2008_ENTERPRISE_X64 "winServer2008Enterprise-64" #define STR_OS_WIN_2008_ENTERPRISE_CORE_X64 "winServer2008EnterpriseCore-64" #define STR_OS_WIN_2008_ENTERPRISE_ITANIUM_X64 "winServer2008EnterpriseItanium-64" #define STR_OS_WIN_2008_MEDIUM_MANAGEMENT_X64 "winServer2008MediumManagement-64" #define STR_OS_WIN_2008_MEDIUM_MESSAGING_X64 "winServer2008MediumMessaging-64" #define STR_OS_WIN_2008_MEDIUM_SECURITY_X64 "winServer2008MediumSecurity-64" #define STR_OS_WIN_2008_SERVER_FOR_SMALLBUSINESS_X64 "winServer2008ForSmallBusiness-64" #define STR_OS_WIN_2008_SMALL_BUSINESS_X64 "winServer2008SmallBusiness-64" #define STR_OS_WIN_2008_SMALL_BUSINESS_PREMIUM_X64 "winServer2008SmallBusinessPremium-64" #define STR_OS_WIN_2008_STANDARD_X64 "winServer2008Standard-64" #define STR_OS_WIN_2008_STANDARD_CORE_X64 "winServer2008StandardCore-64" #define STR_OS_WIN_2008_STORAGE_ENTERPRISE_X64 "winServer2008StorageEnterprise-64" #define STR_OS_WIN_2008_STORAGE_EXPRESS_X64 "winServer2008StorageExpress-64" #define STR_OS_WIN_2008_STORAGE_STANDARD_X64 "winServer2008StorageStandard-64" #define STR_OS_WIN_2008_STORAGE_WORKGROUP_X64 "winServer2008StorageWorkgroup-64" #define STR_OS_WIN_2008_WEB_SERVER_X64 "winServer2008Web-64" /* Windows 7 */ #define STR_OS_WIN_SEVEN "windows7" #define STR_OS_WIN_SEVEN_X64 "windows7-64" #define STR_OS_WIN_SEVEN_GENERIC "Windows 7" #define STR_OS_WIN_SEVEN_STARTER_FULL "Windows 7 Starter" #define STR_OS_WIN_SEVEN_HOME_BASIC_FULL "Windows 7 Home Basic" #define STR_OS_WIN_SEVEN_HOME_PREMIUM_FULL "Windows 7 Home Premium" #define STR_OS_WIN_SEVEN_ULTIMATE_FULL "Windows 7 Ultimate" #define STR_OS_WIN_SEVEN_PROFESSIONAL_FULL "Windows 7 Professional" #define STR_OS_WIN_SEVEN_ENTERPRISE_FULL "Windows 7 Enterprise" /* Windows Server 2008 R2 (based on Windows 7) */ #define STR_OS_WIN_2008R2_X64 "windows7srv-64" #define STR_OS_WIN_2008R2_FOUNDATION_FULL "Windows Server 2008 R2 Foundation Edition" #define STR_OS_WIN_2008R2_STANDARD_FULL "Windows Server 2008 R2 Standard Edition" #define STR_OS_WIN_2008R2_ENTERPRISE_FULL "Windows Server 2008 R2 Enterprise Edition" #define STR_OS_WIN_2008R2_DATACENTER_FULL "Windows Server 2008 R2 Datacenter Edition" #define STR_OS_WIN_2008R2_WEB_SERVER_FULL "Windows Web Server 2008 R2 Edition" /* Windows 8 */ #define STR_OS_WIN_EIGHT "windows8" #define STR_OS_WIN_EIGHT_X64 "windows8-64" #define STR_OS_WIN_EIGHT_GENERIC "Windows 8" #define STR_OS_WIN_EIGHTSERVER_GENERIC "Windows Server 2012" /* * XXX - These need to be updated when MS announces official Win 8 names. * For now they are unused, see: lib/misc/hostinfoWin32.c */ #define STR_OS_WIN_EIGHT_STARTER_FULL "Windows 8 Starter" #define STR_OS_WIN_EIGHT_HOME_BASIC_FULL "Windows 8 Home Basic" #define STR_OS_WIN_EIGHT_HOME_PREMIUM_FULL "Windows 8 Home Premium" #define STR_OS_WIN_EIGHT_ULTIMATE_FULL "Windows 8 Ultimate" #define STR_OS_WIN_EIGHT_PROFESSIONAL_FULL "Windows 8 Professional" #define STR_OS_WIN_EIGHT_ENTERPRISE_FULL "Windows 8 Enterprise" /* Windows Server 2012 */ #define STR_OS_WIN_EIGHTSERVER_X64 "windows8srv-64" #define STR_OS_WIN_2012_FOUNDATION_FULL "Windows Server 2012 Foundation Edition" #define STR_OS_WIN_2012_STANDARD_FULL "Windows Server 2012 Standard Edition" #define STR_OS_WIN_2012_ENTERPRISE_FULL "Windows Server 2012 Enterprise Edition" #define STR_OS_WIN_2012_DATACENTER_FULL "Windows Server 2012 Datacenter Edition" #define STR_OS_WIN_2012_WEB_SERVER_FULL "Windows Web Server 2012 Edition" /* Microsoft Hyper-V */ #define STR_OS_HYPER_V "winHyperV" #define STR_OS_HYPER_V_FULL "Hyper-V Server" /* Windows Future/Unknown */ #define STR_OS_WIN_FUTURE "windowsUnknown" #define STR_OS_WIN_FUTURE_X64 "windowsUnknown-64" #define STR_OS_WIN_FUTURE_GENERIC "Windows Unknown" /* Modifiers for Windows Vista, Windows Server 2008, and later. */ #define STR_OS_WIN_32_BIT_EXTENSION ", 32-bit" #define STR_OS_WIN_64_BIT_EXTENSION ", 64-bit" /* FreeBSD */ #define STR_OS_FREEBSD "FreeBSD" /* Solaris */ #define STR_OS_SOLARIS "solaris" /* Mac OS */ #define STR_OS_MACOS "darwin" /* All */ #define STR_OS_64BIT_SUFFIX "-64" #define STR_OS_64BIT_SUFFIX_FULL " (64 bit)" #define STR_OS_EMPTY "" #endif open-vm-tools-9.4.0-1280544/lib/include/strutil.h0000644765153500003110000000573012220061556017514 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * strutil.h -- * * String utility functions. */ #ifndef STRUTIL_H #define STRUTIL_H #include #include "vm_basic_types.h" struct DynBuf; char *StrUtil_GetNextToken(unsigned int *index, const char *str, const char *delimiters); Bool StrUtil_GetNextIntToken(int32 *out, unsigned int *index, const char *str, const char *delimiters); Bool StrUtil_GetNextUintToken(uint32 *out, unsigned int *index, const char *str, const char *delimiters); Bool StrUtil_GetNextInt64Token(int64 *out, unsigned int *index, const char *str, const char *delimiters); Bool StrUtil_DecimalStrToUint(unsigned int *out, const char **str); Bool StrUtil_StrToInt(int32 *out, const char *str); Bool StrUtil_StrToUint(uint32 *out, const char *str); Bool StrUtil_StrToInt64(int64 *out, const char *str); Bool StrUtil_StrToUint64(uint64 *out, const char *str); Bool StrUtil_StrToSizet(size_t *out, const char *str); Bool StrUtil_StrToDouble(double *out, const char *str); Bool StrUtil_CapacityToBytes(SectorType *out, const char *str, unsigned int bytes); Bool StrUtil_CapacityToSectorType(SectorType *out, const char *str, unsigned int bytes); char *StrUtil_FormatSizeInBytesUnlocalized(uint64 size); size_t StrUtil_GetLongestLineLength(const char *buf, size_t bufLength); Bool StrUtil_StartsWith(const char *s, const char *prefix); Bool StrUtil_CaselessStartsWith(const char *s, const char *prefix); Bool StrUtil_EndsWith(const char *s, const char *suffix); Bool StrUtil_IsASCII(const char *s); Bool StrUtil_VDynBufPrintf(struct DynBuf *b, const char *fmt, va_list args); Bool StrUtil_DynBufPrintf(struct DynBuf *b, const char *fmt, ...) PRINTF_DECL(2, 3); void StrUtil_SafeDynBufPrintf(struct DynBuf *b, const char *fmt, ...) PRINTF_DECL(2, 3); void StrUtil_SafeStrcat(char **prefix, const char *str); void StrUtil_SafeStrcatFV(char **prefix, const char *fmt, va_list args); void StrUtil_SafeStrcatF(char **prefix, const char *fmt, ...) PRINTF_DECL(2, 3); #endif /* STRUTIL_H */ open-vm-tools-9.4.0-1280544/lib/include/removable_device.h0000644765153500003110000000221212220061556021271 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _REMOVABLE_DEVICE_H_ #define _REMOVABLE_DEVICE_H_ #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #define REMOVABLE_DEVICE_PRETTY_NAME_LENGTH 32 typedef struct { char name[REMOVABLE_DEVICE_PRETTY_NAME_LENGTH]; uint32 uid; Bool enabled; } RD_Info; #endif open-vm-tools-9.4.0-1280544/lib/include/mutexRank.h0000644765153500003110000000514612220061556017765 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * mutexRank.h -- * * Base lock rank defines. See userlock.h for the related APIs. */ #ifndef _MUTEXRANK_H_ #define _MUTEXRANK_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" /* * Core rank defines. */ #define RANK_UNRANKED 0 #define RANK_LEAF 0xFF000000 #define RANK_INVALID 0xFFFFFFFF /* * For situations where we need to create locks on behalf of * third-party code, but we don't know what ranking scheme, if any, * that code uses. For now, the only usage is in bora/lib/ssl. */ #define RANK_THIRDPARTY RANK_UNRANKED /* * Log lock rank. * * Very special case. Don't change it. The effect is that critical * logging code cannot call anything else which requires a lock, but * everyone else can safely Log() while holding a leaf lock. */ #define RANK_logLock (RANK_LEAF + 1) /* * bora/lib/allocTrack rank (not really). * * This is another special case. It hooks malloc/free and the like, * and thus can basically sneak in underneath anyone. To that end * allocTrack uses unranked, native locks internally to avoid any * complications. */ /* * VMX/VMM/device lock rank space. * * This rank space is at the bottom, from 1 to RANK_VMX_LEAF. See * vmx/public/mutexRankVMX.h for definitions. */ /* * Foundry lock rank space. * * This rank space is from RANK_foundryLockBase on up to * RANK_foundryLockLeaf. See apps/lib/foundry/mutexRankFoundry.h for * definitions. */ #define RANK_foundryLockBase 0x80000000 /* * bora/lib lock rank space. * * This rank space is from RANK_libLockBase on up to RANK_LEAF. See * lib/public/mutexRankLib.h for definitions. */ #define RANK_libLockBase 0xF0000000 #endif // ifndef _MUTEXRANK_H_ open-vm-tools-9.4.0-1280544/lib/include/backdoor_def.h0000644765153500003110000002455712220061556020420 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * backdoor_def.h -- * * This contains backdoor defines that can be included from * an assembly language file. */ #ifndef _BACKDOOR_DEF_H_ #define _BACKDOOR_DEF_H_ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" /* * If you want to add a new low-level backdoor call for a guest userland * application, please consider using the GuestRpc mechanism instead. --hpreg */ #define BDOOR_MAGIC 0x564D5868 /* Low-bandwidth backdoor port. --hpreg */ #define BDOOR_PORT 0x5658 #define BDOOR_CMD_GETMHZ 1 /* * BDOOR_CMD_APMFUNCTION is used by: * * o The FrobOS code, which instead should either program the virtual chipset * (like the new BIOS code does, matthias offered to implement that), or not * use any VM-specific code (which requires that we correctly implement * "power off on CLI HLT" for SMP VMs, boris offered to implement that) * * o The old BIOS code, which will soon be jettisoned * * --hpreg */ #define BDOOR_CMD_APMFUNCTION 2 /* CPL0 only. */ #define BDOOR_CMD_GETDISKGEO 3 #define BDOOR_CMD_GETPTRLOCATION 4 #define BDOOR_CMD_SETPTRLOCATION 5 #define BDOOR_CMD_GETSELLENGTH 6 #define BDOOR_CMD_GETNEXTPIECE 7 #define BDOOR_CMD_SETSELLENGTH 8 #define BDOOR_CMD_SETNEXTPIECE 9 #define BDOOR_CMD_GETVERSION 10 #define BDOOR_CMD_GETDEVICELISTELEMENT 11 #define BDOOR_CMD_TOGGLEDEVICE 12 #define BDOOR_CMD_GETGUIOPTIONS 13 #define BDOOR_CMD_SETGUIOPTIONS 14 #define BDOOR_CMD_GETSCREENSIZE 15 #define BDOOR_CMD_MONITOR_CONTROL 16 /* Disabled by default. */ #define BDOOR_CMD_GETHWVERSION 17 #define BDOOR_CMD_OSNOTFOUND 18 /* CPL0 only. */ #define BDOOR_CMD_GETUUID 19 #define BDOOR_CMD_GETMEMSIZE 20 #define BDOOR_CMD_HOSTCOPY 21 /* Devel only. */ //#define BDOOR_CMD_SERVICE_VM 22 /* Not in use. Never shipped. */ #define BDOOR_CMD_GETTIME 23 /* Deprecated -> GETTIMEFULL. */ #define BDOOR_CMD_STOPCATCHUP 24 #define BDOOR_CMD_PUTCHR 25 /* Disabled by default. */ #define BDOOR_CMD_ENABLE_MSG 26 /* Devel only. */ #define BDOOR_CMD_GOTO_TCL 27 /* Devel only. */ #define BDOOR_CMD_INITPCIOPROM 28 /* CPL 0 only. */ //#define BDOOR_CMD_INT13 29 /* Not in use. */ #define BDOOR_CMD_MESSAGE 30 #define BDOOR_CMD_SIDT 31 #define BDOOR_CMD_SGDT 32 #define BDOOR_CMD_SLDT_STR 33 #define BDOOR_CMD_ISACPIDISABLED 34 //#define BDOOR_CMD_TOE 35 /* Not in use. */ #define BDOOR_CMD_ISMOUSEABSOLUTE 36 #define BDOOR_CMD_PATCH_SMBIOS_STRUCTS 37 /* CPL 0 only. */ #define BDOOR_CMD_MAPMEM 38 /* Devel only */ #define BDOOR_CMD_ABSPOINTER_DATA 39 #define BDOOR_CMD_ABSPOINTER_STATUS 40 #define BDOOR_CMD_ABSPOINTER_COMMAND 41 //#define BDOOR_CMD_TIMER_SPONGE 42 /* Not in use. */ #define BDOOR_CMD_PATCH_ACPI_TABLES 43 /* CPL 0 only. */ //#define BDOOR_CMD_DEVEL_FAKEHARDWARE 44 /* Not in use. */ #define BDOOR_CMD_GETHZ 45 #define BDOOR_CMD_GETTIMEFULL 46 #define BDOOR_CMD_STATELOGGER 47 /* Disabled by default. */ #define BDOOR_CMD_CHECKFORCEBIOSSETUP 48 /* CPL 0 only. */ #define BDOOR_CMD_LAZYTIMEREMULATION 49 /* CPL 0 only. */ #define BDOOR_CMD_BIOSBBS 50 /* CPL 0 only. */ //#define BDOOR_CMD_VASSERT 51 /* Not in use. */ #define BDOOR_CMD_ISGOSDARWIN 52 #define BDOOR_CMD_DEBUGEVENT 53 #define BDOOR_CMD_OSNOTMACOSXSERVER 54 /* CPL 0 only. */ #define BDOOR_CMD_GETTIMEFULL_WITH_LAG 55 #define BDOOR_CMD_ACPI_HOTPLUG_DEVICE 56 /* Devel only. */ #define BDOOR_CMD_ACPI_HOTPLUG_MEMORY 57 /* Devel only. */ #define BDOOR_CMD_ACPI_HOTPLUG_CBRET 58 /* Devel only. */ //#define BDOOR_CMD_GET_HOST_VIDEO_MODES 59 /* Not in use. */ #define BDOOR_CMD_ACPI_HOTPLUG_CPU 60 /* Devel only. */ //#define BDOOR_CMD_USB_HOTPLUG_MOUSE 61 /* Not in use. Never shipped. */ #define BDOOR_CMD_XPMODE 62 /* CPL 0 only. */ #define BDOOR_CMD_NESTING_CONTROL 63 #define BDOOR_CMD_FIRMWARE_INIT 64 /* CPL 0 only. */ #define BDOOR_CMD_FIRMWARE_ACPI_SERVICES 65 /* CPL 0 only. */ # define BDOOR_CMD_FAS_GET_TABLE_SIZE 0 # define BDOOR_CMD_FAS_GET_TABLE_DATA 1 # define BDOOR_CMD_FAS_GET_PLATFORM_NAME 2 # define BDOOR_CMD_FAS_GET_PCIE_OSC_MASK 3 # define BDOOR_CMD_FAS_GET_APIC_ROUTING 4 # define BDOOR_CMD_FAS_GET_TABLE_SKIP 5 # define BDOOR_CMD_FAS_GET_SLEEP_ENABLES 6 #define BDOOR_CMD_SENDPSHAREHINTS 66 #define BDOOR_CMD_ENABLE_USB_MOUSE 67 #define BDOOR_CMD_GET_VCPU_INFO 68 # define BDOOR_CMD_VCPU_SLC64 0 # define BDOOR_CMD_VCPU_SYNC_VTSCS 1 # define BDOOR_CMD_VCPU_HV_REPLAY_OK 2 # define BDOOR_CMD_VCPU_RESERVED 31 #define BDOOR_CMD_EFI_SERIALCON_CONFIG 69 /* CPL 0 only. */ #define BDOOR_CMD_BUG328986 70 /* CPL 0 only. */ #define BDOOR_CMD_FIRMWARE_ERROR 71 /* CPL 0 only. */ # define BDOOR_CMD_FE_INSUFFICIENT_MEM 0 # define BDOOR_CMD_FE_EXCEPTION 1 #define BDOOR_CMD_VMK_INFO 72 #define BDOOR_CMD_EFI_BOOT_CONFIG 73 /* CPL 0 only. */ # define BDOOR_CMD_EBC_LEGACYBOOT_ENABLED 0 # define BDOOR_CMD_EBC_GET_ORDER 1 # define BDOOR_CMD_EBC_SHELL_ACTIVE 2 #define BDOOR_CMD_GET_HW_MODEL 74 /* CPL 0 only. */ #define BDOOR_CMD_GET_SVGA_CAPABILITIES 75 /* CPL 0 only. */ #define BDOOR_CMD_GET_FORCE_X2APIC 76 /* CPL 0 only */ #define BDOOR_CMD_SET_PCI_HOLE 77 /* CPL 0 only */ #define BDOOR_CMD_GET_PCI_HOLE 78 /* CPL 0 only */ #define BDOOR_CMD_GET_PCI_BAR 79 /* CPL 0 only */ #define BDOOR_CMD_SHOULD_GENERATE_SYSTEMID 80 /* CPL 0 only */ #define BDOOR_CMD_MAX 81 /* * IMPORTANT NOTE: When modifying the behavior of an existing backdoor command, * you must adhere to the semantics expected by the oldest Tools who use that * command. Specifically, do not alter the way in which the command modifies * the registers. Otherwise backwards compatibility will suffer. */ /* Processing mode for guest pshare hints (SENDPSHAREHINTS cmd) */ #define BDOOR_PSHARE_HINTS_ASYNC 0 #define BDOOR_PSHARE_HINTS_SYNC 1 #define BDOOR_PSHARE_HINTS_TYPE(ecx) (((ecx) >> 16) & 0x1) /* Version of backdoor pshare hints protocol */ #define BDOOR_PSHARE_HINTS_VERSION 1 #define BDOOR_PSHARE_HINTS_VER(ecx) (((ecx) >> 17) & 0x7f) /* Task applied to backdoor pshare hints */ #define BDOOR_PSHARE_HINTS_CMD_SHARE 0 #define BDOOR_PSHARE_HINTS_CMD_DROP 1 #define BDOOR_PSHARE_HINTS_CMD_MAX 2 #define BDOOR_PSHARE_HINTS_CMD(ecx) (((ecx) >> 24) & 0xff) /* Nesting control operations */ #define NESTING_CONTROL_RESTRICT_BACKDOOR 0 #define NESTING_CONTROL_OPEN_BACKDOOR 1 #define NESTING_CONTROL_QUERY 2 #define NESTING_CONTROL_MAX 2 /* EFI Boot Order options, nibble-sized. */ #define EFI_BOOT_ORDER_TYPE_EFI 0x0 #define EFI_BOOT_ORDER_TYPE_LEGACY 0x1 #define EFI_BOOT_ORDER_TYPE_NONE 0xf /* High-bandwidth backdoor port. --hpreg */ #define BDOORHB_PORT 0x5659 #define BDOORHB_CMD_MESSAGE 0 #define BDOORHB_CMD_VASSERT 1 #define BDOORHB_CMD_MAX 2 /* * There is another backdoor which allows access to certain TSC-related * values using otherwise illegal PMC indices when the pseudo_perfctr * control flag is set. */ #define BDOOR_PMC_HW_TSC 0x10000 #define BDOOR_PMC_REAL_NS 0x10001 #define BDOOR_PMC_APPARENT_NS 0x10002 #define BDOOR_PMC_PSEUDO_TSC 0x10003 #define IS_BDOOR_PMC(index) (((index) | 3) == 0x10003) #define BDOOR_CMD(ecx) ((ecx) & 0xffff) /* Sub commands for BDOOR_CMD_VMK_INFO */ #define BDOOR_CMD_VMK_INFO_ENTRY 1 #ifdef VMM /* *---------------------------------------------------------------------- * * Backdoor_CmdRequiresFullyValidVCPU -- * * A few backdoor commands require the full VCPU to be valid * (including GDTR, IDTR, TR and LDTR). The rest get read/write * access to GPRs and read access to Segment registers (selectors). * * Result: * True iff VECX contains a command that require the full VCPU to * be valid. * *---------------------------------------------------------------------- */ static INLINE Bool Backdoor_CmdRequiresFullyValidVCPU(unsigned cmd) { return cmd == BDOOR_CMD_SIDT || cmd == BDOOR_CMD_SGDT || cmd == BDOOR_CMD_SLDT_STR; } #endif #endif open-vm-tools-9.4.0-1280544/lib/include/win32util.h0000644765153500003110000002206312220061556017644 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * Win32Util.h -- * * misc Windows utilities */ #ifndef WIN32UTIL_H_ #define WIN32UTIL_H_ #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #include "vm_basic_types.h" #include "vm_atomic.h" #include "unicodeTypes.h" #ifdef _WIN32 #include /* Type definitions */ typedef enum AutorunState { AUTORUN_UNDEFINED, AUTORUN_ON, AUTORUN_OFF } AutorunState; /* Defines */ #define VMX_SHUTDOWN_ORDER 0x100 // Application reserved last shutdown range. #define UI_SHUTDOWN_ORDER 0x300 // Application reserved first shutdown range. #define TOOLS_SHUTDOWN_ORDER 0x100 // Application reserved last shutdown range /* Function declarations */ Unicode W32Util_GetInstallPath(void); Unicode W32Util_GetInstallPath64(void); /* * The string returned is allocated on the heap and must be freed by the * calling routine. */ Unicode W32Util_GetAppDataFilePath(ConstUnicode fileName); Unicode W32Util_GetLocalAppDataFilePath(ConstUnicode fileName); Unicode W32Util_GetCommonAppDataFilePath(ConstUnicode fileName); Unicode W32Util_GetVmwareCommonAppDataFilePath(ConstUnicode fileName); Unicode W32Util_GetMyDocumentPath(void); Unicode W32Util_GetMyVideoPath(BOOL myDocumentsOnFail); Unicode W32Util_GetDefaultVMPath(ConstUnicode pref); Unicode W32Util_GetInstalledFilePath(ConstUnicode fileName); Unicode W32Util_GetInstalledFilePath64(ConstUnicode fileName); HKEY W32Util_OpenProductRegKey(REGSAM access); HKEY W32Util_OpenUserRegKey(REGSAM access); LPTOP_LEVEL_EXCEPTION_FILTER W32Util_SetUnhandledExceptionFilter(void); Bool W32Util_CreateProcessArgv(ConstUnicode lpApplicationName, ConstUnicode *argv, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, ConstUnicode lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation); void W32Util_SplitCommandLine(char *commandLine, int maxArgs, char *progName, int *argc, char **argv); BOOL W32Util_ReadFileTimeout(HANDLE hFile, // handle of file to read LPVOID lpBuffer, // pointer to buffer that receives data DWORD nNumberOfBytesToRead, // number of bytes to read LPDWORD lpNumberOfBytesRead, // pointer to number of bytes read DWORD msTimeout); // timeout in milliseconds BOOL W32Util_WriteFileTimeout(HANDLE hFile, // handle to file to write to LPCVOID lpBuffer, // pointer to data to write to file DWORD nNumberOfBytesToWrite, // number of bytes to write LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written DWORD msTimeout); // timeout in milliseconds Unicode W32Util_RealPath(ConstUnicode path); BOOL W32Util_CheckForPrivilegeHeld(HANDLE token, LPCTSTR priv); typedef BOOL (*SidFilterFunction)(PSID psid, void *cbData); BOOL W32Util_GetEffectiveRightsForName(ConstUnicode user, ConstUnicode path, DWORD *rights); BOOL W32Util_GetEffectiveRightsForSid(PSID psid, ConstUnicode path, DWORD *rights); BOOL W32Util_ModifyRights(PSID psid, ConstUnicode path, DWORD rights, BOOL isAllow); void W32Util_FreeSids(PSID *sidList); BOOL W32Util_GetMatchingSids(ConstUnicode path, PSID **psidList, SidFilterFunction matchCb, void *cbData); LPSTR W32Util_WideStrToAsciiStr(LPCWSTR wideStr); LPWSTR W32Util_AsciiStrToWideStr(LPCSTR multiStr); LPSTR W32Util_WideStrToMultiByteStr(LPCWSTR wideStr, UINT codePage); LPWSTR W32Util_MultiByteStrToWideStr(LPCSTR multiStr, UINT codePage); BOOL W32Util_WinSockAddReference(void); BOOL W32Util_WinSockDereference(void); Bool W32Util_RegisterService(Bool bRegister, ConstUnicode name, ConstUnicode displayName, ConstUnicode description, ConstUnicode binaryPath, Unicode *errString); Bool W32Util_DebugService(ConstUnicode dbgFile); Bool W32Util_RegisterEventLog(ConstUnicode serviceName, Bool registryVolatile, DWORD typesSupported, ConstUnicode eventMsgFile, ConstUnicode categoryMsgFile, DWORD categoryCount, ConstUnicode paramMsgFile); Bool W32Util_UnregisterEventLog(ConstUnicode serviceName); typedef enum SetSDPrivsAccounts { SDPRIV_GROUP_ADMIN = 0x1, SDPRIV_GROUP_VMWARE = 0x2, SDPRIV_USER_CURRENT = 0x4, } SetSDPrivsAccounts; Bool W32Util_SetSDPrivs(PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD accessType, SetSDPrivsAccounts accounts, PACL *pAcl, Unicode *errString); BOOL W32Util_SetSecurityDescriptorW(PSECURITY_DESCRIPTOR pSecurityDescriptor, ConstUnicode Owner, PACL *pAcl); BOOL W32Util_SetSecurityDescriptorSid(PSECURITY_DESCRIPTOR sd, PSID sid, PACL *pAcl); BOOL W32Util_GetThreadHandle(HANDLE *handle); Bool W32Util_AccessCheck(HANDLE token, PSECURITY_DESCRIPTOR pSecurityDescriptor, int desiredAccess); Bool W32Util_HasAccessToFile(ConstUnicode filename, ACCESS_MASK desiredAccess, HANDLE token); Bool W32Util_GetSecurityDescriptor(ConstUnicode path, PSECURITY_DESCRIPTOR *ppSecurityDescriptor); void W32Util_InitStdioConsole(void); void W32Util_ExitStdioConsole(void); Bool W32Util_CreateWellKnownSid(WELL_KNOWN_SID_TYPE wsdType, PSID domainSid, PSID *pSid); Bool W32Util_GetCurrentUserSid(PSID *pSid); Bool W32Util_GetLocalAdminGroupSid(PSID *pSid); Bool W32Util_GetVMwareGroupSid(PSID *pSid); Bool W32Util_MakeSafeDirectory(ConstUnicode path); Bool W32Util_IsDirectorySafe(ConstUnicode path); Bool W32Util_DoesVolumeSupportAcls(ConstUnicode path); Bool W32Util_GetRegistryAutorun(AutorunState* state); Bool W32Util_SetRegistryAutorun(const AutorunState state); Bool W32Util_AllowAdminCOM(void); Unicode W32Util_GetAppDataPath(void); Unicode W32Util_RobustGetLongPath(ConstUnicode path); typedef enum SecureObjectType { SecureObject_Process, SecureObject_Thread } SecureObjectType; PSECURITY_DESCRIPTOR W32Util_ConstructSecureObjectSD(HANDLE hToken, SecureObjectType type); Bool W32Util_ReplaceObjectSD(HANDLE hObject, const PSECURITY_DESCRIPTOR pSD); HMODULE W32Util_GetModuleByAddress(const void *addr); Bool W32Util_VerifyXPModeHostLicense(void); Unicode W32Util_GetPipeNameFromFilePath(ConstUnicode fileName); Bool W32Util_CheckGroupMembership(HANDLE hToken, BOOL respectUAC, Unicode *errString, BOOL *bMember); Bool W32Util_DismountVolumes(uint16 drive, uint64 offset, uint64 size, void **handle); Bool W32Util_CloseDismountHandle(void *handle); Bool W32Util_EnableSafePathSearching(void); CRITICAL_SECTION *W32Util_GetSingletonCriticalSection(Atomic_Ptr *csMemory); #endif // _WIN32 #endif // WIN32UTIL_H_ open-vm-tools-9.4.0-1280544/lib/include/msg.h0000644765153500003110000001705412220061556016576 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * msg.h -- * * user interaction through (non-modal) messages and (modal) dialogs */ #ifndef _MSG_H_ #define _MSG_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #include #include #include "err.h" #include "vm_basic_types.h" #include "msgid.h" #include "msgfmt.h" #include "msgList.h" #if defined VMX86_SERVER && !defined VMCORE #include "voblib.h" #endif #define INVALID_MSG_CODE (-1) /* * Data structures, types, and constants */ typedef struct Msg_String { const char *idFmt; } Msg_String; typedef enum MsgSeverity { MSG_INFO, MSG_INFO_TIMEOUT, MSG_WARNING, MSG_ERROR, MSG_CONFIG_EDITOR, MSG_WEB_LINK_GET_LICENSE_ERROR, MSG_WEB_LINK_EXTEND_LICENSE_ERROR, MSG_WEB_LINK_EXTEND_LICENSE_INFO, MSG_WEB_LINK_HOME_PAGE_INFO, MSG_NUM_SEVERITIES } MsgSeverity; typedef enum HintResult { HINT_CONTINUE, HINT_CANCEL, HINT_NOT_SHOWN } HintResult; typedef enum HintOptions { HINT_OK, HINT_OKCANCEL } HintOptions; typedef struct MsgCallback { void (*post)(MsgSeverity severity, const char *msgID, const char *message); int (*question)(char const * const *names, int defaultAnswer, const char *msgID, const char *message); int (*progress)(const char *msgID, const char *message, int percent, Bool cancelButton); HintResult (*hint)(HintOptions options, const char *msgID, const char *message); void *(*lazyProgressStart)(const char *msgID, const char *message, Bool allowCancel); Bool (*lazyProgress)(void *handle, const char *msgID, const char *message, Bool allowCancel, int percent); void (*lazyProgressEnd)(void *handle); void (*postList)(MsgSeverity severity, MsgList *messages); int (*questionList)(const Msg_String *buttons, int defaultAnswer, MsgList *messages); int (*progressList)(MsgList *messages, int percent, Bool cancelButton); HintResult (*hintList)(HintOptions options, MsgList *messages); void *(*lazyProgressStartList)(MsgList *messages); void (*forceUnblock)(void); } MsgCallback; #define MSG_QUESTION_MAX_BUTTONS 10 #define MSG_PROGRESS_START (-1) #define MSG_PROGRESS_STOP 101 VMX86_EXTERN_DATA Msg_String const Msg_YesNoButtons[]; VMX86_EXTERN_DATA Msg_String const Msg_OKButtons[]; VMX86_EXTERN_DATA Msg_String const Msg_RetryCancelButtons[]; VMX86_EXTERN_DATA Msg_String const Msg_OKCancelButtons[]; VMX86_EXTERN_DATA Msg_String const Msg_RetryAbortButtons[]; extern Msg_String const Msg_Severities[]; /* * Functions */ void Msg_Append(const char *idFmt, ...) PRINTF_DECL(1, 2); void Msg_AppendStr(const char *id); void Msg_AppendMsgList(const MsgList *msgs); static INLINE void Msg_AppendVobContext(void) { #if defined VMX86_SERVER && !defined VMCORE /* inline to avoid lib/vob dependency unless necessary */ MsgList *msgs = NULL; VobLib_CurrentContextMsgAppend(&msgs); Msg_AppendMsgList(msgs); MsgList_Free(msgs); #endif } void Msg_Post(MsgSeverity severity, const char *idFmt, ...) PRINTF_DECL(2, 3); void Msg_PostMsgList(MsgSeverity severity, const MsgList *msgs); char *Msg_Format(const char *idFmt, ...) PRINTF_DECL(1, 2); char *Msg_VFormat(const char *idFmt, va_list arguments); unsigned Msg_Question(Msg_String const *buttons, int defaultAnswer, const char *idFmt, ...) PRINTF_DECL(3, 4); /* * Unfortunately, gcc warns about both NULL and "" being passed as format * strings, and callers of Msg_Progress() like to do that. So I'm removing * the PRINTF_DECL() for now. --Jeremy. */ int Msg_Progress(int percentDone, Bool cancelButton, const char *idFmt, ...); int Msg_ProgressScaled(int percentDone, int opsDone, int opsTotal, Bool cancelButton); void *Msg_LazyProgressStart(Bool allowCancel, const char *idFmt, ...) PRINTF_DECL(2, 3); Bool Msg_LazyProgress(void *handle, Bool allowCancel, int percent, const char *idFmt, ...) PRINTF_DECL(4, 5); void Msg_LazyProgressEnd(void *handle); HintResult Msg_Hint(Bool defaultShow, HintOptions options, const char *idFmt, ...) PRINTF_DECL(3, 4); HintResult Msg_HintMsgList(Bool defaultShow, HintOptions options, MsgList *msg); int Msg_CompareAnswer(Msg_String const *buttons, unsigned answer, const char *string); char *Msg_GetString(const char *idString); char *Msg_GetStringSafe(const char *idString); char *Msg_GetPlainButtonText(const char *idString); char *Msg_GetLocale(void); void Msg_SetLocale(const char *locale, const char *binaryName); void Msg_SetLocaleEx(const char *locale, const char *binaryName, const char *baseDirPath); char *Msg_FormatFloat(double value, unsigned int precision); char *Msg_FormatSizeInBytes(uint64 size); Bool Msg_LoadMessageFile(const char *locale, const char *fileName); void Msg_ForceUnblock(void); /* * Message buffer management */ const char *Msg_GetMessages(void); const char *Msg_GetMessagesAndReset(void); void Msg_LogAndReset(void); MsgList *Msg_GetMsgList(void); MsgList *Msg_GetMsgListAndReset(void); char *Msg_LocalizeList(const MsgList *messages); void Msg_Reset(Bool log); Bool Msg_Present(void); void Msg_ExitThread(void); void Msg_Exit(void); /* * Don't know, don't care. -- edward */ #define MSG_POST_NOMEM() \ Msg_Post(MSG_ERROR, MSGID(msg.noMem) "Cannot allocate memory.\n") #ifndef VMX86_DEBUG #define MSG_CHECK_ORPHANED_MESSAGES(id, fmt, arg) #elif defined VMX86_DEVEL #define MSG_CHECK_ORPHANED_MESSAGES(id, fmt, arg) ( \ Msg_Present() ? \ Msg_Post(MSG_INFO, \ id fmt "THIS MESSAGE ON DEVEL BUILDS only - " \ "Please file bug about orphan Msg_Append\n", \ arg) : \ (void) 0 \ ) #else #define MSG_CHECK_ORPHANED_MESSAGES(id, fmt, arg) ( \ Msg_Present() ? \ (Log(fmt, arg), \ Msg_Reset(TRUE)) : \ (void) 0 \ ) #endif /* * To implement message dialogs */ void Msg_SetCallback(MsgCallback *cb); void Msg_SetThreadCallback(MsgCallback *cb); void Msg_GetCallback(MsgCallback *cb); void Msg_GetThreadCallback(MsgCallback *cb); /* * Conversion functions */ #define Msg_ErrString() (Err_ErrString()) #define Msg_Errno2String(errorNumber) ( \ Err_Errno2String(errorNumber) ) #ifdef _WIN32 const char *Msg_HResult2String(long hr); #endif #endif // ifndef _MSG_H_ open-vm-tools-9.4.0-1280544/lib/include/base64.h0000644765153500003110000000347712220061556017100 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * base64.h -- * * Functions to base64 encode/decode buffers. Implemented in * lib/misc/base64.c. */ #ifndef _BASE64_H #define _BASE64_H Bool Base64_Encode(uint8 const *src, size_t srcLength, char *target, size_t targSize, size_t *dataLength); Bool Base64_Decode(char const *src, uint8 *target, size_t targSize, size_t *dataLength); Bool Base64_ChunkDecode(char const *src, size_t inSize, uint8 *target, size_t targSize, size_t *dataLength); Bool Base64_ValidEncoding(char const *src, size_t srcLength); size_t Base64_EncodedLength(uint8 const *src, size_t srcLength); size_t Base64_DecodedLength(char const *src, size_t srcLength); Bool Base64_EasyEncode(const uint8 *src, size_t srcLength, char **target); Bool Base64_EasyDecode(const char *src, uint8 **target, size_t *targSize); #endif open-vm-tools-9.4.0-1280544/lib/include/hgfs.h0000644765153500003110000002074112220061556016734 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * hgfs.h -- * * Header file for public common data types used in the VMware * Host/Guest File System (hgfs). * * This file is included by hgfsProto.h, which defines message formats * used in the hgfs protocol, and by hgfsDev.h, which defines the * interface between the kernel and the hgfs pserver. [bac] */ #ifndef _HGFS_H_ # define _HGFS_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_DISTRIBUTE #include "includeCheck.h" #include "vm_assert.h" /* * Maximum number of pages to transfer to/from the HGFS server for V3 protocol * operations that support large requests/replies, e.g. reads and writes. */ #define HGFS_LARGE_IO_MAX_PAGES 15 /* * Maximum allowed packet size in bytes. All hgfs code should be made * safe with respect to this limit. */ #define HGFS_PACKET_MAX 6144 /* * The HGFS_LARGE_PACKET_MAX size is used to allow guests to make * read / write requests of sizes larger than HGFS_PACKET_MAX. The larger size * can only be used with server operations that are specified to be large packet * capable in hgfsProto.h. */ #define HGFS_LARGE_PACKET_MAX ((4096 * HGFS_LARGE_IO_MAX_PAGES) + 2048) /* Maximum number of bytes to read or write to a hgfs server in a single packet. */ #define HGFS_IO_MAX 4096 /* Maximum number of bytes to read or write to a V3 server in a single hgfs packet. */ #define HGFS_LARGE_IO_MAX (HGFS_LARGE_IO_MAX_PAGES * 4096) /* * Open mode * * These are equivalent to the O_RDONLY, O_WRONLY, O_RDWR open flags * in Unix; they specify which type of access is being requested. These three * modes are mutually exclusive and one is required; all other flags are * modifiers to the mode and must come afterwards as a bitmask. Beware that * HGFS_OPEN_MODE_READ_ONLY contains the value 0 so simply masking another * variable with it to detect its presence is not safe. The _ACCMODES entry in * the enum serves as a bitmask for the others. * * Changing the order of this enum will break stuff. * * This definition is used in some places that don't include * hgfsProto.h, which is why it is here instead of there. */ typedef enum { HGFS_OPEN_MODE_READ_ONLY, HGFS_OPEN_MODE_WRITE_ONLY, HGFS_OPEN_MODE_READ_WRITE, HGFS_OPEN_MODE_ACCMODES, /* You cannot add anything else here. Really. */ } HgfsOpenMode; /* * Open flags. * * Each should be shifted left by HGFS_OPEN_MODE_READ_WRITE plus whatever flag * number they are, starting with zero. * * The sequential flag indicates that reads and writes on this handle should * not seek on each operation; instead, the system's file pointer will be used * so each operation is performed where the last one finished. This flag is * necessary when reading from or writing to non-seekable files (such as procfs * nodes on Linux) but can also lead to inconsistent results if a client shares * a handle amongst several of its callers. This flag should only be used when * the client knows the file is non-seekable and the burden of ensuring file * handles aren't shared falls upon the hgfs client, not the server. */ #define HGFS_OPEN_SEQUENTIAL (1 << HGFS_OPEN_MODE_READ_WRITE) /* Masking helpers. */ #define HGFS_OPEN_MODE_ACCMODE(mode) (mode & HGFS_OPEN_MODE_ACCMODES) #define HGFS_OPEN_MODE_FLAGS(mode) (mode & ~HGFS_OPEN_MODE_ACCMODES) #define HGFS_OPEN_MODE_IS_VALID_MODE(mode) \ (HGFS_OPEN_MODE_ACCMODE(mode) == HGFS_OPEN_MODE_READ_ONLY || \ HGFS_OPEN_MODE_ACCMODE(mode) == HGFS_OPEN_MODE_WRITE_ONLY || \ HGFS_OPEN_MODE_ACCMODE(mode) == HGFS_OPEN_MODE_READ_WRITE) /* * Return status for replies from the server. * * Changing the order of this enum will break the protocol; new status * types should be added at the end. * * This definition is used in some places that don't include * hgfsProto.h, which is why it is here instead of there. * * XXX: So we have a problem here. At some point, HGFS_STATUS_INVALID_NAME was * added to the list of errors. Later, HGFS_STATUS_GENERIC_ERROR was added, but * it was added /before/ HGFS_STATUS_INVALID_NAME. Nobody noticed because the * error codes travelled from hgfsProto.h to hgfs.h in that same change. Worse, * we GA'ed a product (Server 1.0) this way. * * XXX: I've reversed the order because otherwise new HGFS clients working * against WS55-era HGFS servers will think they got HGFS_STATUS_GENERIC_ERROR * when the server sent them HGFS_STATUS_INVALID_NAME. This was a problem * the Linux client converts HGFS_STATUS_GENERIC_ERROR to -EIO, which causes * HgfsLookup to fail unexpectedly (normally HGFS_STATUS_INVALID_NAME is * converted to -ENOENT, an expected result in HgfsLookup). */ typedef enum { HGFS_STATUS_SUCCESS, HGFS_STATUS_NO_SUCH_FILE_OR_DIR, HGFS_STATUS_INVALID_HANDLE, HGFS_STATUS_OPERATION_NOT_PERMITTED, HGFS_STATUS_FILE_EXISTS, HGFS_STATUS_NOT_DIRECTORY, HGFS_STATUS_DIR_NOT_EMPTY, HGFS_STATUS_PROTOCOL_ERROR, HGFS_STATUS_ACCESS_DENIED, HGFS_STATUS_INVALID_NAME, HGFS_STATUS_GENERIC_ERROR, HGFS_STATUS_SHARING_VIOLATION, HGFS_STATUS_NO_SPACE, HGFS_STATUS_OPERATION_NOT_SUPPORTED, HGFS_STATUS_NAME_TOO_LONG, HGFS_STATUS_INVALID_PARAMETER, HGFS_STATUS_NOT_SAME_DEVICE, /* * Following error codes are for V4 and above protocol only. * Server must never retun these codes for legacy clients. */ HGFS_STATUS_STALE_SESSION, HGFS_STATUS_TOO_MANY_SESSIONS, HGFS_STATUS_TRANSPORT_ERROR, } HgfsStatus; /* * HGFS RPC commands * * HGFS servers can run in a variety of places across several different * transport layers. These definitions constitute all known RPC commands. * * For each definition, there is both the server string (the command itself) * as well as a client "prefix", which is the command followed by a space. * This is provided for convenience, since clients will need to copy both * the command and the space into some buffer that is then sent over the * backdoor. * * In Host --> Guest RPC traffic, the host endpoint is TCLO and the guest * endpoint is RpcIn. TCLO is a particularly confusing name choice which dates * back to when the host was to send raw TCL code to the guest (TCL Out == * TCLO). * * In Guest --> Host RPC traffic, the guest endpoint is RpcOut and the host * endpoint is RPCI. */ /* * When an RPCI listener registers for this command, HGFS requests are expected * to be synchronously sent from the guest and replies are expected to be * synchronously returned. * * When an RpcIn listener registers for this command, requests are expected to * be asynchronously sent from the host and synchronously returned from the * guest. * * In short, an endpoint sending this command is sending a request whose reply * should be returned synchronously. */ #define HGFS_SYNC_REQREP_CMD "f" #define HGFS_SYNC_REQREP_CLIENT_CMD HGFS_SYNC_REQREP_CMD " " #define HGFS_SYNC_REQREP_CLIENT_CMD_LEN (sizeof HGFS_SYNC_REQREP_CLIENT_CMD - 1) /* * This is just for the sake of macro naming. Since we are guaranteed * equal command lengths, defining command length via a generalized macro name * will prevent confusion. */ #define HGFS_CLIENT_CMD_LEN HGFS_SYNC_REQREP_CLIENT_CMD_LEN #endif // _HGFS_H_ open-vm-tools-9.4.0-1280544/lib/include/vm_procps.h0000644765153500003110000000517012220061556020014 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vm_procps.h -- * * Provides an interface to Linux's libproc.so. * * The upstream procps package is structured such that most Linux * distributions do not provide a libproc-dev package containing the * interface to libproc.so. Instead, we provide this header containing * just enough bits and pieces of the procps headers to satisfy our needs. */ #ifndef _VM_PROCPS_H_ #define _VM_PROCPS_H_ /* * The getstat() function below makes use of restricted pointers (added in C99) * and the 'jiff' type. */ #if !defined(restrict) && __STDC_VERSION__ < 199901 # if __GNUC__ > 2 || __GNUC_MINOR__ >= 92 # define restrict __restrict__ # else # warning No restrict keyword? # define restrict # endif #endif typedef unsigned long long jiff; /* * Global variables */ extern unsigned long long Hertz; extern unsigned long kb_main_buffers; extern unsigned long kb_main_cached; extern unsigned long kb_main_free; extern unsigned long kb_active; extern unsigned long kb_inactive; /* * Global functions */ extern void getstat(jiff *restrict cuse, jiff *restrict cice, jiff *restrict csys, jiff *restrict cide, jiff *restrict ciow, jiff *restrict cxxx, jiff *restrict cyyy, jiff *restrict czzz, unsigned long *restrict pin, unsigned long *restrict pout, unsigned long *restrict s_in, unsigned long *restrict sout, unsigned *restrict intr, unsigned *restrict ctxt, unsigned int *restrict running, unsigned int *restrict blocked, unsigned int *restrict btime, unsigned int *restrict processes); extern void meminfo(void); #endif // ifndef _VM_PROCPS_H_ open-vm-tools-9.4.0-1280544/lib/include/vmblock.h0000644765153500003110000002106012220061556017435 0ustar dtormts/********************************************************* * Copyright (C) 2006-2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * vmblock.h -- * * User-level interface to the vmblock device. * * VMBLOCK_DEVICE should be opened with VMBLOCK_DEVICE_MODE mode. Then * VMBLOCK_CONTROL should be called to perform blocking operations. * The links which can be blocked are in the directory VMBLOCK_MOUNT_POINT. * * VMBLOCK_CONTROL takes the file descriptor of the VMBLOCK_DEVICE, an * operation, and the path of the target of the file being operated on (if * applicable). * * The operation should be one of: * VMBLOCK_ADD_FILEBLOCK * VMBLOCK_DEL_FILEBLOCK * VMBLOCK_LIST_FILEBLOCKS * * path should be something in /tmp/VMwareDnD/ rather than in * VMBLOCK_MOUNT_POINT. * * VMBLOCK_CONTROL returns 0 on success or returns -1 and sets errno on * failure. */ #ifndef _VMBLOCK_H_ #define _VMBLOCK_H_ #if defined(sun) || defined(__FreeBSD__) # include #endif #if defined(__FreeBSD__) # include #endif /* * FUSE definitions. They are supposed to be used by userspace code and * therefore not guarded by ARCH defines since FUSE can potentially * be used on different operating systems. */ #define VMBLOCK_FUSE_ADD_FILEBLOCK 'a' #define VMBLOCK_FUSE_DEL_FILEBLOCK 'd' #ifdef VMX86_DEVEL # define VMBLOCK_FUSE_LIST_FILEBLOCKS 'l' #endif /* VMX86_DEVEL */ /* * If you try 'read'-ing from file descriptor vmblock-fuse is supposed * to respond with the following. It is used to check whether we deal * with FUSE or in-kernel implementation. */ #define VMBLOCK_FUSE_READ_RESPONSE "I am VMBLOCK-FUSE" #define VMBLOCK_FUSE_FS_NAME "fuse.vmware-vmblock" #define VMBLOCK_FUSE_MOUNT_POINT "/var/run/vmblock-fuse" #define VMBLOCK_FUSE_CTRL_MNTPNT "blockdir" #define VMBLOCK_FUSE_FS_ROOT VMBLOCK_FUSE_MOUNT_POINT "/" VMBLOCK_FUSE_CTRL_MNTPNT #define VMBLOCK_FUSE_DEVICE_NAME "dev" #define VMBLOCK_FUSE_DEVICE VMBLOCK_FUSE_MOUNT_POINT "/" VMBLOCK_FUSE_DEVICE_NAME #define VMBLOCK_FUSE_DEVICE_MODE O_RDWR /* Commands for the control half of vmblock driver */ #if defined(vmblock_fuse) /* These definitions are for vmblock-fuse module itself */ # include # include # include # include # include "vm_basic_types.h" # define VMBLOCK_ADD_FILEBLOCK VMBLOCK_FUSE_ADD_FILEBLOCK # define VMBLOCK_DEL_FILEBLOCK VMBLOCK_FUSE_DEL_FILEBLOCK # ifdef VMX86_DEVEL # define VMBLOCK_LIST_FILEBLOCKS VMBLOCK_FUSE_LIST_FILEBLOCKS # endif /* VMX86_DEVEL */ /* * Some of the following names don't actually make much sense on their own. * They're used for consistency with the other ports. See the file header for * explanations of what they're used for. */ # define VMBLOCK_FS_NAME VMBLOCK_FUSE_FS_NAME # define VMBLOCK_DEVICE_NAME VMBLOCK_FUSE_DEVICE_NAME # define VMBLOCK_CONTROL_MOUNTPOINT VMBLOCK_FUSE_CTRL_MNTPNT # define VMBLOCK_FS_ROOT VMBLOCK_FUSE_FS_ROOT # define VMBLOCK_DEVICE VMBLOCK_FUSE_DEVICE # define VMBLOCK_DEVICE_MODE VMBLOCK_FUSE_DEVICE_MODE # define VMBLOCK_MOUNT_POINT VMBLOCK_FUSE_MOUNT_POINT #elif defined(linux) # define VMBLOCK_ADD_FILEBLOCK 98 # define VMBLOCK_DEL_FILEBLOCK 99 # ifdef VMX86_DEVEL # define VMBLOCK_LIST_FILEBLOCKS 100 # endif # define VMBLOCK_FS_NAME "vmblock" # define VMBLOCK_CONTROL_DIRNAME VMBLOCK_FS_NAME # define VMBLOCK_CONTROL_DEVNAME "dev" # define VMBLOCK_CONTROL_MOUNTPOINT "mountPoint" # define VMBLOCK_CONTROL_PROC_DIRNAME "fs/" VMBLOCK_CONTROL_DIRNAME # define VMBLOCK_MOUNT_POINT "/proc/" VMBLOCK_CONTROL_PROC_DIRNAME \ "/" VMBLOCK_CONTROL_MOUNTPOINT # define VMBLOCK_FS_ROOT VMBLOCK_MOUNT_POINT # define VMBLOCK_DEVICE "/proc/" VMBLOCK_CONTROL_PROC_DIRNAME \ "/" VMBLOCK_CONTROL_DEVNAME # define VMBLOCK_DEVICE_MODE O_WRONLY #elif defined(sun) || defined(__FreeBSD__) # define VMBLOCK_FS_NAME "vmblock" # define VMBLOCK_MOUNT_POINT "/var/run/" VMBLOCK_FS_NAME # define VMBLOCK_FS_ROOT VMBLOCK_MOUNT_POINT # define VMBLOCK_DEVICE VMBLOCK_MOUNT_POINT # define VMBLOCK_DEVICE_MODE O_RDONLY # if defined(sun) /* if (sun) { */ /* * Construct ioctl(2) commands for blocks. _IO() is a helper macro to * construct unique command values more easily. I chose 'v' because I * didn't see it being used elsewhere, and the command numbers begin at one. */ # define VMBLOCK_ADD_FILEBLOCK _IO('v', 1) # define VMBLOCK_DEL_FILEBLOCK _IO('v', 2) # ifdef VMX86_DEVEL # define VMBLOCK_LIST_FILEBLOCKS _IO('v', 3) # endif # elif defined(__FreeBSD__) /* } else if (FreeBSD) { */ /* * Similar to Solaris, construct ioctl(2) commands for block operations. * Since the FreeBSD implementation does not change the user's passed-in * data (pathname), we use the _IOW macro to define commands which write * to the kernel. (As opposed to _IOR or _IOWR.) Groups 'v' and 'V' * are taken by terminal drivers, so I opted for group 'Z'. */ # define VMBLOCK_ADD_FILEBLOCK _IOW('Z', 1, char[MAXPATHLEN] ) # define VMBLOCK_DEL_FILEBLOCK _IOW('Z', 2, char[MAXPATHLEN] ) # ifdef VMX86_DEVEL # define VMBLOCK_LIST_FILEBLOCKS _IO('Z', 3) # define VMBLOCK_PURGE_FILEBLOCKS _IO('Z', 4) # endif # endif /* } */ #else # error "Unknown platform for vmblock." #endif #endif /* _VMBLOCK_H_ */ open-vm-tools-9.4.0-1280544/lib/include/backdoor.h0000644765153500003110000000360412220061556017570 0ustar dtormts/********************************************************* * Copyright (C) 1999 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * backdoor.h -- * * First layer of the internal communication channel between guest * applications and vmware */ #ifndef _BACKDOOR_H_ #define _BACKDOOR_H_ #include "vm_basic_types.h" #include "vm_assert.h" #include "backdoor_types.h" void Backdoor(Backdoor_proto *bp); // IN/OUT void Backdoor_InOut(Backdoor_proto *bp); // IN/OUT void Backdoor_HbOut(Backdoor_proto_hb *bp); // IN/OUT void Backdoor_HbIn(Backdoor_proto_hb *bp); // IN/OUT #endif /* _BACKDOOR_H_ */ open-vm-tools-9.4.0-1280544/lib/include/config.h0000644765153500003110000001110212220061556017241 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _CONFIG_H_ #define _CONFIG_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #include "vm_basic_types.h" #include "preference.h" /* * Well-known configuration variable names */ #define CONFIG_VMWAREDIR "libdir" struct CryptoKey; struct KeySafeUserRing; void Config_SetAny(const char *value, const char *fmt, ...) PRINTF_DECL(2, 3); void Config_SetString(const char *value, const char *fmt, ...) PRINTF_DECL(2, 3); void Config_SetStringPlain(const char *value, const char *fmt, ...) PRINTF_DECL(2, 3); void Config_SetBool(Bool value, const char *fmt, ...) PRINTF_DECL(2, 3); void Config_SetBoolPlain(Bool value, const char *fmt, ...) PRINTF_DECL(2, 3); void Config_SetLong(int32 value, const char *fmt, ...) PRINTF_DECL(2, 3); void Config_SetInt64(int64 value, const char *fmt, ...) PRINTF_DECL(2, 3); void Config_SetLongPlain(int32 value, const char *fmt, ...) PRINTF_DECL(2, 3); void Config_SetDouble(double value, const char *fmt, ...) PRINTF_DECL(2, 3); char *Config_GetString(const char *defaultValue, const char *fmt, ...) PRINTF_DECL(2, 3); char *Config_GetStringPlain(const char *defaultValue, const char *fmt, ...) PRINTF_DECL(2, 3); char *Config_GetAsString(const char *fmt, ...) PRINTF_DECL(1, 2); char *Config_GetStringEnum(const char *defaultValue, const char **choices, const char *fmt, ...) PRINTF_DECL(3, 4); int Config_CompareVersion(const char *version); int Config_CompareVersions(const char *version1, const char *version2); char *Config_GetPathName(const char *defaultValue, const char *fmt, ...) PRINTF_DECL(2, 3); Bool Config_GetBool(Bool defaultValue, const char *fmt, ...) PRINTF_DECL(2, 3); Bool Config_GetBoolPlain(Bool defaultValue, const char *fmt, ...) PRINTF_DECL(2, 3); int32 Config_GetLong(int32 defaultValue, const char *fmt, ...) PRINTF_DECL(2, 3); int64 Config_GetInt64(int64 defaultValue, const char *fmt, ...) PRINTF_DECL(2, 3); int32 Config_GetLongPlain(int32 defaultValue, const char *fmt, ...) PRINTF_DECL(2, 3); int32 Config_GetTriState(int32 defaultValue, const char *fmt, ...) PRINTF_DECL(2, 3); double Config_GetDouble(double defaultValue, const char *fmt, ...) PRINTF_DECL(2, 3); Bool Config_NotSet(const char *fmt, ...) PRINTF_DECL(1, 2); void Config_Unset(const char *fmt, ...) PRINTF_DECL(1, 2); void Config_UnsetWithPrefix(const char *fmt, ...) PRINTF_DECL(1, 2); void Config_Set(void *value, int type, const char *fmt, ...) PRINTF_DECL(3, 4); /* * This is tricky to call because it returns allocated storage. Use * the typed wrappers instead (Config_Get*). */ void *Config_Get(const void *pDefaultValue, int type, const char *fmt, ...) PRINTF_DECL(3, 4); void Config_MarkModified(const char *fmt, ...) PRINTF_DECL(1, 2); Bool Config_Load(const char *filename); Bool Config_Write(const char *dummy); Bool Config_WriteNoMsg(void); Bool Config_FileIsPresent(void); Bool Config_FileIsWritable(void); uint32 Config_GetMask(uint32 defaultMask, const char *optionName); uint64 Config_GetMask64(uint64 defaultMask, const char *optionName); Bool Config_GetDataFileKey(struct CryptoKey **key, struct KeySafeUserRing **userRing); Bool Config_GetDataFileKeys(struct KeySafeUserRing **parentKeys, struct KeySafeUserRing **allKeys); #endif // _CONFIG_H_ open-vm-tools-9.4.0-1280544/lib/include/buildNumber.h0000644765153500003110000000043412220061556020252 0ustar dtormts#define BUILD_NUMBER \ "build-1280544" #define BUILD_NUMBER_NUMERIC \ 1280544 #define BUILD_NUMBER_NUMERIC_STRING \ "1280544" #define PRODUCT_BUILD_NUMBER \ "product-build-25793" #define PRODUCT_BUILD_NUMBER_NUMERIC \ 25793 #define PRODUCT_BUILD_NUMBER_NUMERIC_STRING \ "25793" open-vm-tools-9.4.0-1280544/lib/include/cpuid_info.h0000644765153500003110000000457212220061556020130 0ustar dtormts/********************************************************* * Copyright (C) 1998-2011 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _CPUID_INFO_H #define _CPUID_INFO_H #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vm_basic_asm.h" #include "x86cpuid_asm.h" typedef struct CPUID0 { int numEntries; char name[16]; // 4 extra bytes to null terminate } CPUID0; typedef struct CPUID1 { uint32 version; uint32 ebx; uint32 ecxFeatures; uint32 edxFeatures; } CPUID1; typedef struct CPUID80 { uint32 numEntries; uint32 ebx; uint32 ecx; uint32 edx; } CPUID80; typedef struct CPUID81 { uint32 eax; uint32 ebx; uint32 ecxFeatures; uint32 edxFeatures; } CPUID81; typedef struct CPUIDSummary { CPUID0 id0; CPUID1 id1; CPUIDRegs ida; CPUID80 id80; CPUID81 id81; CPUIDRegs id88, id8a; } CPUIDSummary; /* *---------------------------------------------------------------------- * * CPUIDSummary_RegsFromCpuid0 -- * * Fills in the given CPUIDRegs struct with the values from the CPUID0 struct. * * Results: * Returns the CPUIDRegs pointer passed in. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE CPUIDRegs* CPUIDSummary_RegsFromCpuid0(CPUID0* id0In, CPUIDRegs* id0Out) { id0Out->eax = id0In->numEntries; id0Out->ebx = *(uint32 *) (id0In->name + 0); id0Out->edx = *(uint32 *) (id0In->name + 4); id0Out->ecx = *(uint32 *) (id0In->name + 8); return id0Out; } #endif open-vm-tools-9.4.0-1280544/lib/include/util_shared.h0000644765153500003110000001010412220061556020300 0ustar dtormts/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vm_assert.h" #include "vm_basic_types.h" /* * Defines util functions shared between the userlevel code and the monitor. */ /* *---------------------------------------------------------------------- * * Util_Throttle -- * * Use for throttling of warnings. * * Results: * Will return TRUE for an increasingly sparse set of counter values: * 1, 2, ..., 100, 200, 300, ..., 10000, 20000, 30000, ..., . * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool Util_Throttle(uint32 count) // IN: { return count < 100 || (count < 10000 && count % 100 == 0) || (count < 1000000 && count % 10000 == 0) || count % 1000000 == 0; } /* *---------------------------------------------------------------------- * * Util_FastRand -- * * Generates the next random number in the pseudo-random sequence * defined by the multiplicative linear congruential generator * S' = 16807 * S mod (2^31 - 1). * This is the ACM "minimal standard random number generator". * Based on method described by D.G. Carta in CACM, January 1990. * Usage: provide previous random number as the seed for next one. * * Precondition: * 0 < seed && seed < UTIL_FASTRAND_SEED_MAX * * Results: * A random number. * * Side effects: * None. * *---------------------------------------------------------------------- */ #define UTIL_FASTRAND_SEED_MAX (0x7fffffff) uint32 Util_FastRand(uint32 seed) { uint64 product = 33614 * (uint64)seed; uint32 product_lo = (uint32)(product & 0xffffffff) >> 1; uint32 product_hi = product >> 32; int32 test = product_lo + product_hi; ASSERT(0 < seed && seed < UTIL_FASTRAND_SEED_MAX); return (test > 0) ? test : (test & UTIL_FASTRAND_SEED_MAX) + 1; } #if defined(USERLEVEL) || defined(VMX86_DEBUG) static uint32 crcTable[256]; static void UtilCRCMakeTable(void) { uint32 c; int n, k; for (n = 0; n < 256; n++) { c = (uint32) n; for (k = 0; k < 8; k++) { if (c & 1) { c = 0xedb88320L ^ (c >> 1); } else { c = c >> 1; } } crcTable[n] = c; } } static INLINE_SINGLE_CALLER uint32 UtilCRCUpdate(uint32 crc, const uint8 *buf, int len) { uint32 c = crc; int n; static int crcTableComputed = 0; if (!crcTableComputed) { UtilCRCMakeTable(); crcTableComputed = 1; } for (n = 0; n < len; n++) { c = crcTable[(c ^ buf[n]) & 0xff] ^ (c >> 8); } return c; } /* *---------------------------------------------------------------------- * * CRC_Compute -- * * computes the CRC of a block of data * * Results: * * CRC code * * Side effects: * Sets up the crc table if it hasn't already been computed. * *---------------------------------------------------------------------- */ uint32 CRC_Compute(const uint8 *buf, int len) { return UtilCRCUpdate(0xffffffffL, buf, len) ^ 0xffffffffL; } #endif /* defined (USERLEVEL) || defined(VMX86_DEBUG) */ open-vm-tools-9.4.0-1280544/lib/include/str.h0000644765153500003110000001643512220061556016622 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * str.h -- * * string wrapping functions */ #ifndef _STR_H_ #define _STR_H_ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #if defined(__linux__) #include #elif defined(_WIN32) #include #elif __APPLE__ #include #endif #include "compat/compat_stdarg.h" // Provides stdarg.h plus va_copy #include "vm_basic_types.h" /* * These platforms use bsd_vsnprintf(). * This does not mean it has bsd_vsnwprintf(). */ #if (defined _WIN32 && !defined STR_NO_WIN32_LIBS) || \ (defined __linux__ && !defined __UCLIBC__) || defined __APPLE__ #define HAS_BSD_PRINTF 1 #endif /* * And these platforms/setups use bsd_vsnwprintf() */ #if (defined _WIN32 && !defined STR_NO_WIN32_LIBS) || \ (defined __GNUC__ && (__GNUC__ < 2 \ || (__GNUC__ == 2 \ && __GNUC_MINOR__ < 96))) #define HAS_BSD_WPRINTF 1 #endif /* * ASCII/UTF-8 versions * * NOTE: All size_t arguments and integer returns values are in bytes. * * NOTE: Str_Asprintf/Str_Vasprintf return NULL on failure, while * Str_SafeAsprintf/Str_SafeVasprintf ASSERT_NOT_IMPLEMENTED. * * NOTE: "%s" refers to strings of "char" units, while "%S" refers to * strings of "wchar_t" units, regardless of platform. */ #ifdef HAS_BSD_PRINTF int Str_Sprintf_C_Locale(char *buf, size_t max, const char *fmt, ...) PRINTF_DECL(3, 4); #endif int Str_Sprintf(char *buf, size_t max, const char *fmt, ...) PRINTF_DECL(3, 4); int Str_Snprintf(char *buf, size_t len, const char *fmt, ...) PRINTF_DECL(3, 4); int Str_Vsnprintf(char *buf, size_t len, const char *fmt, va_list args); size_t Str_Strlen(const char *src, size_t maxLen); char *Str_Strnstr(const char *src, const char *sub, size_t n); char *Str_Strcpy(char *dst, const char *src, size_t maxLen); char *Str_Strcat(char *dst, const char *src, size_t maxLen); char *Str_Strncat(char *buf, size_t bufSize, const char *src, size_t n); char *Str_Asprintf(size_t *length, const char *format, ...) PRINTF_DECL(2, 3); char *Str_Vasprintf(size_t *length, const char *format, va_list arguments); char *Str_SafeAsprintf(size_t *length, const char *format, ...) PRINTF_DECL(2, 3); char *Str_SafeVasprintf(size_t *length, const char *format, va_list arguments); #if defined(_WIN32) || defined(__linux__) // { /* * wchar_t versions * * NOTE: All size_t arguments and integer return values are in * wchar_ts, not bytes. * * NOTE: Str_Aswprintf/Str_Vaswprintf return NULL on failure, while * Str_SafeAswprintf/Str_SafeVaswprintf ASSERT_NOT_IMPLEMENTED. * * NOTE: "%s" refers to strings of "char" units, while "%S" refers to * strings of "wchar_t" units, regardless of platform. */ int Str_Swprintf(wchar_t *buf, size_t max, const wchar_t *fmt, ...); int Str_Snwprintf(wchar_t *buf, size_t len, const wchar_t *fmt, ...); int Str_Vsnwprintf(wchar_t *buf, size_t len, const wchar_t *fmt, va_list args); wchar_t *Str_Wcscpy(wchar_t *dst, const wchar_t *src, size_t maxLen); wchar_t *Str_Wcscat(wchar_t *dst, const wchar_t *src, size_t maxLen); wchar_t *Str_Wcsncat(wchar_t *buf, size_t bufSize, const wchar_t *src, size_t n); wchar_t *Str_Aswprintf(size_t *length, const wchar_t *format, ...); wchar_t *Str_Vaswprintf(size_t *length, const wchar_t *format, va_list arguments); wchar_t *Str_SafeAswprintf(size_t *length, const wchar_t *format, ...); wchar_t *Str_SafeVaswprintf(size_t *length, const wchar_t *format, va_list arguments); unsigned char *Str_Mbscpy(char *buf, const char *src, size_t maxSize); unsigned char *Str_Mbscat(char *buf, const char *src, size_t maxSize); /* * These are handly for Windows programmers. They are like * the _tcs functions, but with Str_Strcpy-style bounds checking. * * We don't have Str_Mbsncat() because it has some odd semantic * ambiguity (whether to truncate in the middle of a multibyte * sequence) that I want to stay away from. -- edward */ #ifdef _WIN32 #ifdef UNICODE #define Str_Tcscpy(s1, s2, n) Str_Wcscpy(s1, s2, n) #define Str_Tcscat(s1, s2, n) Str_Wcscat(s1, s2, n) #else #define Str_Tcscpy(s1, s2, n) Str_Mbscpy(s1, s2, n) #define Str_Tcscat(s1, s2, n) Str_Mbscat(s1, s2, n) #endif #endif #endif // } defined(_WIN32) || defined(__linux__) /* * Wrappers for standard string functions * * These are either for Windows-Posix compatibility, * or just gratuitous wrapping for consistency. */ #define Str_Strcmp(s1, s2) strcmp(s1, s2) #define Str_Strncmp(s1, s2, n) strncmp(s1, s2, n) #define Str_Strchr(s, c) strchr(s, c) #define Str_Strrchr(s, c) strrchr(s, c) #define Str_Strspn(s1, s2) strspn(s1, s2) #define Str_Strcspn(s1, s2) strcspn(s1, s2) #if defined(_WIN32) #define Str_Strcasecmp(s1, s2) _stricmp(s1, s2) #define Str_Strncasecmp(s1, s2, n) _strnicmp(s1, s2, n) #define Str_ToUpper(s) _strupr(s) #define Str_ToLower(s) _strlwr(s) #else #define Str_Strcasecmp(s1, s2) strcasecmp(s1, s2) #define Str_Strncasecmp(s1, s2, n) strncasecmp(s1, s2, n) char *Str_ToUpper(char *string); char *Str_ToLower(char *string); #endif #ifdef _WIN32 #define Str_Tcscmp(s1, s2) _tcscmp(s1, s2) #define Str_Tcsncmp(s1, s2, n) _tcsncmp(s1, s2, n) #define Str_Tcsicmp(s1, s2) _tcsicmp(s1, s2) #define Str_Tcsnicmp(s1, s2, n) _tcsnicmp(s1, s2, n) #define Str_Tcschr(s, c) _tcschr(s, c) #define Str_Tcsrchr(s, c) _tcsrchr(s, c) #define Str_Tcsspn(s1, s2) _tcsspn(s1, s2) #define Str_Tcscspn(s1, s2) _tcscspn(s1, s2) #define Str_Tcsupr(s) _tcsupr(s) #define Str_Tcslwr(s) _tcslwr(s) #endif #endif /* _STR_H_ */ open-vm-tools-9.4.0-1280544/lib/include/xdrutil.h0000644765153500003110000001022712220061556017476 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _XDRUTIL_H_ #define _XDRUTIL_H_ /* * xdrutil.h -- * * Utility functions for code that uses XDR to encode/decode data. */ #include #include "vm_basic_types.h" #include "util.h" /* * Helper macros for iterating over an rpcgen-generated array. Given a struct S: * * struct S { * struct { * u_int f_len; * T *f_val; * } f; * }; * * Iterate over the array like this: * * S s; * u_int i; * * XDRUTIL_FOREACH(i, &s, f) { * T *t = XDRUTIL_GETITEM(&s, f, i); * } * * 'f' should be a string with the field name. */ #define XDRUTIL_COUNT(ptr, field) ((ptr)->field.field##_len) #define XDRUTIL_FOREACH(counter, ptr, field) \ for ((counter) = 0; (counter) < XDRUTIL_COUNT(ptr, field); (counter)++) #define XDRUTIL_GETITEM(ptr, field, idx) &((ptr)->field.field##_val[idx]) /* * Wrapper for XdrUtil_ArrayAppend that automatically populates the arguments * from a given XDR array. */ #ifdef __GNUC__ # define XDRUTIL_ARRAYAPPEND(ptr, field, cnt) \ (typeof ((ptr)->field.field##_val)) \ XdrUtil_ArrayAppend((void **) &(ptr)->field.field##_val, \ &(ptr)->field.field##_len, \ sizeof *(ptr)->field.field##_val, \ (cnt)) #else # define XDRUTIL_ARRAYAPPEND(ptr, field, cnt) \ XdrUtil_ArrayAppend((void **) &(ptr)->field.field##_val, \ &(ptr)->field.field##_len, \ sizeof *(ptr)->field.field##_val, \ (cnt)) #endif /* * Macros for assigning to XDR optional strings, opaque fields, and * optional opaque fields. * * Usage: * // XDR * struct MyFoo { string *foo; }; * struct MyBar { opaque bar; }; * struct MyOptBar { opaque *bar; }; * * // C * char buf[] = { 0xca, 0xfe, 0xba, 0xbe, 0x80, 0x08 }; * * MyFoo foo; * XDRUTIL_STRING_OPT(&foo.foo, "Hello, world!"); * * MyBar bar; * XDRUTIL_OPAQUE(&bar.bar, buf, sizeof buf); * * MyOptBar obar; * XDRUTIL_OPAQUE_OPT(&obar.bar, buf, sizeof buf); */ #define XDRUTIL_STRING_OPT(ptr, src) do { \ (ptr) = Util_SafeMalloc(sizeof *(ptr)); \ *(ptr) = Util_SafeStrdup((src)); \ } while (0) #define XDRUTIL_OPAQUE(ptr, src, srcSize) do { \ struct { u_int len; char *val; } __opaque_temp = {(srcSize), NULL}; \ ASSERT_ON_COMPILE(sizeof(*(ptr)) == sizeof(__opaque_temp)); \ \ __opaque_temp.val = Util_SafeMalloc((srcSize)); \ memcpy(__opaque_temp.val, (src), (srcSize)); \ memcpy(ptr, &__opaque_temp, sizeof __opaque_temp); \ } while (0) #define XDRUTIL_OPAQUE_OPT(ptr, src, srcSize) do { \ *(ptr) = Util_SafeMalloc(sizeof (struct { u_len; void*; })); \ XDRUTIL_OPAQUE(*(ptr), (src), (srcSize)); \ } while(0) void * XdrUtil_ArrayAppend(void **array, u_int *arrayLen, size_t elemSz, u_int elemCnt); Bool XdrUtil_Deserialize(const void *data, size_t dataLen, void *xdrProc, void *dest); #endif /* _XDRUTIL_H_ */ open-vm-tools-9.4.0-1280544/lib/include/cpName.h0000644765153500003110000001070212220061556017204 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * cpName.h -- * * Cross-platform name format used by hgfs. * */ #ifndef __CP_NAME_H__ #define __CP_NAME_H__ #ifdef __KERNEL__ # include "driver-config.h" # include #elif defined __FreeBSD__ # if defined _KERNEL # include # define strchr(s,c) index(s,c) # else # include # endif #elif defined __APPLE__ && defined KERNEL # include #elif !defined sun # include # include #endif #include "vm_basic_types.h" /* Status codes for processing share names */ typedef enum { HGFS_NAME_STATUS_COMPLETE, /* Name is complete */ HGFS_NAME_STATUS_FAILURE, /* Name processing failed */ HGFS_NAME_STATUS_INCOMPLETE_BASE, /* Name is base of namespace */ HGFS_NAME_STATUS_INCOMPLETE_ROOT, /* Name is "root" only */ HGFS_NAME_STATUS_INCOMPLETE_DRIVE, /* Name is "root drive" only */ HGFS_NAME_STATUS_INCOMPLETE_UNC, /* Name is "root unc" only */ HGFS_NAME_STATUS_INCOMPLETE_UNC_MACH, /* Name is "root unc " only */ HGFS_NAME_STATUS_DOES_NOT_EXIST, /* Name does not exist */ HGFS_NAME_STATUS_ACCESS_DENIED, /* Desired access to share denied */ HGFS_NAME_STATUS_SYMBOLIC_LINK, /* Name contains a symbolic link */ HGFS_NAME_STATUS_OUT_OF_MEMORY, /* Out of memory while processing */ HGFS_NAME_STATUS_TOO_LONG, /* Name has overly long component */ HGFS_NAME_STATUS_NOT_A_DIRECTORY, /* Name has path component not a dir */ } HgfsNameStatus; int CPName_ConvertTo(char const *nameIn, // IN: The buf to convert size_t bufOutSize, // IN: The size of the output buffer char *bufOut); // OUT: The output buffer int CPName_LinuxConvertTo(char const *nameIn, // IN: buf to convert size_t bufOutSize, // IN: size of the output buffer char *bufOut); // OUT: output buffer int CPName_WindowsConvertTo(char const *nameIn, // IN: buf to convert size_t bufOutSize, // IN: size of the output buffer char *bufOut); // OUT: output buffer int CPName_ConvertFrom(char const **bufIn, // IN/OUT: Input to convert size_t *inSize, // IN/OUT: Size of input buffer size_t *outSize, // IN/OUT: Size of output buffer char **bufOut); // IN/OUT: Output buffer HgfsNameStatus CPName_ConvertFromRoot(char const **bufIn, // IN/OUT: Input to convert size_t *inSize, // IN/OUT: Size of input size_t *outSize, // IN/OUT: Size of output buf char **bufOut); // IN/OUT: Output buffer int CPName_GetComponent(char const *begin, // IN: Beginning of buffer char const *end, // IN: End of buffer char const **next); // OUT: Next component char const * CPName_Print(char const *in, // IN: Name to print size_t size); // IN: Size of name #endif /* __CP_NAME_H__ */ open-vm-tools-9.4.0-1280544/lib/include/su.h0000644765153500003110000000644012220061556016434 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * su.h -- * * Manage super-user priviledges * */ #ifndef USER_SU_H #define USER_SU_H #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #include "vm_basic_types.h" #include "vm_assert.h" #if defined(__APPLE__) #include #include int Id_SetGid(gid_t egid); int Id_SetREUid(uid_t ruid, uid_t euid); int Id_SetRESUid(uid_t ruid, uid_t euid, uid_t suid); #define Id_GetEUid() geteuid() void *Id_AuthGetLocal(); void *Id_AuthGetExternal(size_t *size); Bool Id_AuthSet(void const *buf, size_t size); Bool Id_AuthCheck(char const *right, char const *localizedDescription, Bool showDialogIfNeeded); #elif (defined(__linux__) || defined(sun) || defined(__FreeBSD__)) #include #include /* Our set of set*id functions which affect current thread only */ int Id_SetUid(uid_t euid); int Id_SetGid(gid_t egid); int Id_SetREUid(uid_t ruid, uid_t euid); int Id_SetREGid(gid_t rgid, gid_t egid); int Id_SetRESUid(uid_t ruid, uid_t euid, uid_t suid); int Id_SetRESGid(gid_t rgid, gid_t egid, gid_t sgid); /* For symmetry */ #define Id_GetEUid() geteuid() /* *---------------------------------------------------------------------------- * * Id_SetEUid -- * * Set specified effective uid for current thread. Does not affect * real uid or saved uid. * * Results: * 0 on success, -1 on failure, errno set * * Side effects: * errno may be modified on success * *---------------------------------------------------------------------------- */ static INLINE int Id_SetEUid(uid_t euid) { return Id_SetRESUid((uid_t)-1, euid, (uid_t)-1); } /* *---------------------------------------------------------------------------- * * Id_SetEGid -- * * Set specified effective gid for current thread. Does not affect * real gid or saved gid. * * Results: * 0 on success, -1 on failure, errno set * * Side effects: * errno may be modified on success * *---------------------------------------------------------------------------- */ static INLINE int Id_SetEGid(gid_t egid) { return Id_SetRESGid((gid_t)-1, egid, (gid_t)-1); } #endif /* linux */ #if defined(_WIN32) #define Id_BeginSuperUser() (-1) #define Id_EndSuperUser(uid) #define Id_IsSuperUser() TRUE #else #define Id_IsSuperUser() (0 == geteuid()) uid_t Id_BeginSuperUser(void); void Id_EndSuperUser(uid_t uid); #endif #endif /* USER_SU_H */ open-vm-tools-9.4.0-1280544/lib/include/vmk_exports.h0000644765153500003110000001005712220061556020365 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * vmk_exports.h -- * * Macros for exporting symbols from vmkernel */ #ifndef _VMK_EXPORTS_H #define _VMK_EXPORTS_H #ifdef VMKERNEL #include "vmkapi.h" #include "vm_basic_defs.h" /* * The following macros allow you to export symbols from vmkernel, * thus making them available for modules to access. * * The versions with no explicit name-space and version imply the * default vmkernel name-space/version. They should be considered * deprecated as they impede your ability to create very stable APIs. * * Sample usage: * * VMK_KERNEL_EXPORT(foo) : export foo * * VMK_KERNEL_ALIAS(foo, fooAlias) : export foo as fooAlias * * VMK_KERNEL_EXPORT_TO_NAMESPACE(foo, "ns", "ver") : * export foo @ns:ver * * VMK_KERNEL_ALIAS_TO_NAMESPACE(foo, fooAlias, "ns", "ver") : * export foo as fooAlias @ns:ver * * Further details on the name-space/version implementation can be * found in the VMKAPI module headers and documentation. The 2 second * version is that if you export foo@myns:1, modules wanting access to * that symbol will require an explicit * VMK_MODULE_NAMESPACE_REQUIRED("myns", "1") tag to see that symbol. */ #define VMK_KERNEL_EXPORT_SEC ".vmkexports" #define VMK_KERNEL_EXPORT(symbol) \ asm(".pushsection " VMK_KERNEL_EXPORT_SEC ",\"aS\", @progbits\n" \ "\t.string \"" XSTR(symbol) "\" \n" "\t.popsection\n"); #define VMK_KERNEL_ALIAS(symbol, alias) \ asm(".pushsection " VMK_KERNEL_EXPORT_SEC ",\"aS\", @progbits\n" \ "\t.string \"" XSTR(symbol) "!" XSTR(alias) "\" \n" \ "\t.popsection\n"); /* name@namespace:version */ #define VMK_KERNEL_EXPORT_TO_NAMESPACE(symbol, namespace, version) \ asm(".pushsection " VMK_KERNEL_EXPORT_SEC ",\"aS\", @progbits\n" \ "\t.string \"" XSTR(symbol) "@" namespace ":" version "\" \n" \ "\t.popsection\n"); /* name!alias@namespace:version */ #define VMK_KERNEL_ALIAS_TO_NAMESPACE(symbol, alias, namespace, version) \ asm(".pushsection " VMK_KERNEL_EXPORT_SEC ",\"aS\", @progbits\n" \ "\t.string \"" XSTR(symbol) "!" XSTR(alias) "@" namespace ":" \ version "\" \n\t.popsection\n"); #else /* ! defined VMKERNEL */ /* * Empty definitions for kernel exports when built in non-kernel environments. */ #define VMK_KERNEL_EXPORT(_symbol) #define VMK_KERNEL_ALIAS(symbol, alias) #define VMK_KERNEL_EXPORT_TO_NAMESPACE(symbol, namespace, version) #define VMK_KERNEL_ALIAS_TO_NAMESPACE(symbol, alias, namespace, version) #endif /* defined VMKERNEL */ #endif /* _VMK_EXPORTS_H */ open-vm-tools-9.4.0-1280544/lib/include/miscSolaris.h0000644765153500003110000000236412220061556020276 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* *---------------------------------------------------------------------- * * miscSolaris -- * * Implementation of new Linux functions for Solaris. * *---------------------------------------------------------------------- */ #ifndef _MISCSOLARIS_H_ #define _MISCSOLARIS_H_ #define INCLUDE_ALLOW_USERLEVEL int daemon(int nochdir, int noclose); #endif /* _MISCSOLARIS_H_ */ open-vm-tools-9.4.0-1280544/lib/include/msgid.h0000644765153500003110000000532212220061556017106 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * msgid.h -- * * Message ID magic */ #ifndef _MSGID_H_ #define _MSGID_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "msgidDefs.h" #include "vm_basic_defs.h" #ifndef VMKERNEL #include #endif // the X hides MSG_MAGIC so it won't appear in the object file #define MSG_MAGICAL(s) \ (s != NULL && strncmp(s, MSG_MAGIC"X", MSG_MAGIC_LEN) == 0) // Start after MSG_MAGIC so it won't appear in the object file either. #define MSG_HAS_BUTTONID(s) \ (MSG_MAGICAL(s) && \ (strncmp(&(s)[MSG_MAGIC_LEN], MSG_BUTTON_ID, MSG_BUTTON_ID_LEN) == 0)) /* *----------------------------------------------------------------------------- * * Msg_HasMsgID -- * * Check that a string has a message ID. * The full "MSG_MAGIC(...)" prefix is required, not just MSG_MAGIC. * * Results: * True if string has a message ID. * * Side Effects: * None * *----------------------------------------------------------------------------- */ static INLINE Bool Msg_HasMsgID(const char *s) { return MSG_MAGICAL(s) && *(s += MSG_MAGIC_LEN) == '(' && strchr(s + 1, ')') != NULL; } /* *----------------------------------------------------------------------------- * * Msg_StripMSGID -- * * Returns the string that is inside the MSGID() or if it doesn't * have a MSGID just return the string. * * Results: * The unlocalized string. * * Side Effects: * None * *----------------------------------------------------------------------------- */ static INLINE const char * Msg_StripMSGID(const char *idString) // IN { const char *s = idString; if (MSG_MAGICAL(s) && *(s += MSG_MAGIC_LEN) == '(' && (s = strchr(s + 1, ')')) != NULL) { return s + 1; } return idString; } #endif // ifndef _MSGID_H_ open-vm-tools-9.4.0-1280544/lib/include/vm_api.h0000644765153500003110000000601612220061556017257 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * * vm_api.h -- * * Import/export macro definitions. */ #ifndef VM_API_H #define VM_API_H /* * DLL/DSO import/export macros. * * These macros can be used by libraries to automatically export/import symbols. * The general approach is: * * 1) libfoo defines a macro, say FOO_COMPILING_DYNAMIC, * in its Makefile/Scons file. * * 2) libfoo has the following code in a header file, e.g. foo/config.h, that is * included by all headers that export/import symbols: * #include * #ifdef FOO_COMPILING_DYNAMIC * # define FOO_API VMW_LIB_DYNAMIC * #else * # define FOO_API VMW_LIB_CLIENT * #endif // FOO_COMPILING_DYNAMIC * * For example: * // In a file named FooObject.h * #ifndef FOO_OBJECT_H * #define FOO_OBJECT_H * * #include * * class FOO_API FooObject { }; * FOO_API FooObject *GetFooObject(); * #endif // FOO_OBJECT_H * * 3) libfoo can now use FOO_API for all symbols it would like to export, which * resolves to VMW_LIB_DYNAMIC, while compiling libfoo as a dynamic shared * library. * * 4) Whenever a client of libfoo includes its headers, these symbols will be * marked with VMW_LIB_CLIENT, since FOO_COMPILING_DYNAMIC is not defined for * the client. * * NOTE: By default, symbols are hidden when compiling with MSC and exported * when compiling with GCC. Thus, it's best to compile with GCC's * -fvisibility=hidden and -fvisibility-inlines-hidden flags, so that only * symbols explicitly marked with VMW_LIB_DYNAMIC are exported. Also note that * these flags, as well as the attributes, are available in GCC 4 and later. */ #ifdef _MSC_VER # define VMW_LIB_CLIENT __declspec(dllimport) # define VMW_LIB_DYNAMIC __declspec(dllexport) # define VMW_LIB_STATIC #elif defined __GNUC__ && __GNUC__ >= 4 /* !_MSC_VER */ # define VMW_LIB_CLIENT __attribute__ ((visibility ("default"))) # define VMW_LIB_DYNAMIC __attribute__ ((visibility ("default"))) # define VMW_LIB_STATIC __attribute__ ((visibility ("hidden"))) #else # define VMW_LIB_CLIENT # define VMW_LIB_DYNAMIC # define VMW_LIB_STATIC #endif /* _MSC_VER */ #endif /* VM_API_H */ open-vm-tools-9.4.0-1280544/lib/include/procMgr.h0000644765153500003110000001170412220061556017415 0ustar dtormts/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * procMgr.h -- * * Process management library. * */ #ifndef __PROCMGR_H__ # define __PROCMGR_H__ #include "vm_basic_types.h" #include "auth.h" #include "dynarray.h" #if !defined(_WIN32) # include #endif #include /* * Keeps track of the platform-specific handle(s) to an asynchronous process. */ typedef struct ProcMgr_AsyncProc ProcMgr_AsyncProc; #if defined(_WIN32) typedef DWORD ProcMgr_Pid; #else /* POSIX */ typedef pid_t ProcMgr_Pid; #endif /* * Process information structure. * This holds basic information we return per process * when listing process information inside the guest. */ typedef struct ProcMgrProcInfo { ProcMgr_Pid procId; char *procCmdName; // UTF-8 char *procCmdLine; // UTF-8 char *procOwner; // UTF-8 #if defined(_WIN32) Bool procDebugged; #endif time_t procStartTime; } ProcMgrProcInfo; DEFINE_DYNARRAY_TYPE(ProcMgrProcInfo); typedef struct ProcMgr_ProcArgs { #if defined(_WIN32) /* * If a caller needs to use a non-default set of arguments for * CreateProcess[AsUser] in ProcMgr_Exec[A]sync, this structure should be used. * * - If 'userArgs' is NULL, defaults are used: * - bInheritHandles defaults to TRUE * - lpStartupInfo is instantiated and initialized with: * - cb initialized to size of the object * - dwFlags initialized to STARTF_USESHOWWINDOW * - wShowWindow initialized to SW_MINIMIZE. * - defaults for all other parameters are NULL/FALSE * * - If 'userArgs' is not NULL, the values in the 'userArgs' object are used * according to the following rules: * - If lpStartupInfo is NULL, it is instantiated and initialized with: * - cb initialized to size of the object * - dwFlags initialized to STARTF_USESHOWWINDOW * - wShowWindow initialized to SW_MINIMIZE. * - The caller would need to do some of this initialization if they set * lpStartupInfo. * - If hToken is set: * - if lpStartupInfo->lpDesktop is not NULL, then it is used directly. Otherwise, * lpStartupInfo->lpDesktop is initialized appropriately. * * XXX: Make it more convenient for callers(like ToolsDaemonTcloRunProgramImpl) * to set just wShowWindow without needing to instantiate and initialize a * STARTUPINFO object. */ HANDLE hToken; LPCWSTR lpApplicationName; LPSECURITY_ATTRIBUTES lpProcessAttributes; LPSECURITY_ATTRIBUTES lpThreadAttributes; BOOL bInheritHandles; DWORD dwCreationFlags; LPVOID lpEnvironment; LPCWSTR lpCurrentDirectory; LPSTARTUPINFO lpStartupInfo; #else /* * The environment variables to run the program with. If NULL, use the current * environment. */ char **envp; /* * If non-NULL, the directory to be changed to before the process is * started. */ char *workingDirectory; #endif } ProcMgr_ProcArgs; typedef void ProcMgr_Callback(Bool status, void *clientData); #if defined(_WIN32) typedef HANDLE Selectable; #else typedef int Selectable; #endif ProcMgrProcInfoArray *ProcMgr_ListProcesses(void); void ProcMgr_FreeProcList(ProcMgrProcInfoArray *procList); Bool ProcMgr_KillByPid(ProcMgr_Pid procId); Bool ProcMgr_ExecSync(char const *cmd, // UTF-8 ProcMgr_ProcArgs *userArgs); ProcMgr_AsyncProc *ProcMgr_ExecAsync(char const *cmd, // UTF-8 ProcMgr_ProcArgs *userArgs); void ProcMgr_Kill(ProcMgr_AsyncProc *asyncProc); Selectable ProcMgr_GetAsyncProcSelectable(ProcMgr_AsyncProc *asyncProc); ProcMgr_Pid ProcMgr_GetPid(ProcMgr_AsyncProc *asyncProc); Bool ProcMgr_IsAsyncProcRunning(ProcMgr_AsyncProc *asyncProc); int ProcMgr_GetExitCode(ProcMgr_AsyncProc *asyncProc, int *result); void ProcMgr_Free(ProcMgr_AsyncProc *asyncProc); #if !defined(_WIN32) Bool ProcMgr_ImpersonateUserStart(const char *user, // UTF-8 AuthToken token); Bool ProcMgr_ImpersonateUserStop(void); #endif Bool ProcMgr_GetImpersonatedUserInfo(char **username, char **homeDir); #endif /* __PROCMGR_H__ */ open-vm-tools-9.4.0-1280544/lib/include/embed_version.h0000644765153500003110000000366412220061556020633 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * embed_version.h -- * * Embeds a version string in an ELF binary that is readable by modinfo. */ #ifndef _EMBED_VERSION_H_ #define _EMBED_VERSION_H_ /* * Using section attributes, embed the specified version in the "modinfo" * section of the ELF binary. We don't do this on Windows, where the PE format * already has version information stuffed inside it, nor on Mac OS X, which * doesn't use ELF. * * We can't declare vm_version as static, otherwise it may get optimized out. * I've seen this when building with gcc 4.1, but not with 3.3. * * The argument to the macro should be the base name for the version number * macros to embed in the final binary, as described in vm_version.h (see * declaration of VM_VERSION_TO_STR). */ #if !defined(_WIN32) && !defined(__APPLE__) #include "vm_version.h" #define VM_EMBED_VERSION(ver) \ const char vm_version[] \ __attribute__((section(".modinfo"), unused)) = "version=" ver #else #define VM_EMBED_VERSION(ver) #endif #endif /* _EMBED_VERSION_H_ */ open-vm-tools-9.4.0-1280544/lib/include/circList.h0000644765153500003110000002370012220061556017557 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * circList.h -- * * macros, prototypes and struct definitions for double-linked * circular lists. */ #ifndef _CIRCLIST_H_ #define _CIRCLIST_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vmware.h" typedef struct ListItem { struct ListItem *prev; struct ListItem *next; } ListItem; /* A list with no elements is a null pointer. */ #define LIST_ITEM_DEF(name) \ ListItem * name = NULL #define LIST_EMPTY(l) ((l) == NULL) /* initialize list item */ #define INIT_LIST_ITEM(p) \ do { \ (p)->prev = (p)->next = (p); \ } while (0) /* check if initialized */ #define IS_LIST_ITEM_INITIALIZED(li) \ (((li) == (li)->prev) && ((li) == (li)->next)) /* return first element in the list */ #define LIST_FIRST(l) (l) #define LIST_FIRST_CHK(l) (l) /* return last element in the list */ #define LIST_LAST(l) ((l)->prev) #define LIST_LAST_CHK(l) (LIST_EMPTY(l) ? NULL : LIST_LAST(l)) /* * LIST_CONTAINER - get the struct for this entry (like list_entry) * @ptr: the &struct ListItem pointer. * @type: the type of the struct this is embedded in. * @member: the name of the list struct within the struct. */ #define LIST_CONTAINER(ptr, type, member) \ VMW_CONTAINER_OF(ptr, type, member) /* * delete item from the list */ #define LIST_DEL DelListItem /* * link two lists together */ #define LIST_SPLICE SpliceLists /* * Split a list into two lists */ #define LIST_SPLIT SplitLists /* * Add item to front of stack. List pointer points to new head. */ #define LIST_PUSH PushListItem /* * Add item at back of queue. List pointer only changes if list was empty. */ #define LIST_QUEUE QueueListItem /* * Get the list size. */ #define LIST_SIZE GetListSize /* * LIST_SCAN_FROM scans the list from "from" up until "until". * The loop variable p should not be destroyed in the process. * "from" is an element in the list where to start scanning. * "until" is the element where search should stop. * member is the field to use for the search - either "next" or "prev". */ #define LIST_SCAN_FROM(p, from, until, member) \ for (p = (from); (p) != NULL; \ (p) = (((p)->member == (until)) ? NULL : (p)->member)) /* scan the entire list (non-destructively) */ #define LIST_SCAN(p, l) \ LIST_SCAN_FROM(p, LIST_FIRST(l), LIST_FIRST(l), next) /* scan a list backward from last element to first (non-destructively) */ #define LIST_SCAN_BACK(p, l) \ LIST_SCAN_FROM(p, LIST_LAST_CHK(l), LIST_LAST(l), prev) /* scan the entire list where loop element may be destroyed */ #define LIST_SCAN_SAFE(p, pn, l) \ if (!LIST_EMPTY(l)) \ for (p = (l), (pn) = NextListItem(p, l); (p) != NULL; \ (p) = (pn), (pn) = NextListItem(p, l)) /* scan the entire list backwards where loop element may be destroyed */ #define LIST_SCAN_BACK_SAFE(p, pn, l) \ if (!LIST_EMPTY(l)) \ for (p = LIST_LAST(l), (pn) = PrevListItem(p, l); (p) != NULL; \ (p) = (pn), (pn) = PrevListItem(p, l)) /* function definitions */ /* *---------------------------------------------------------------------- * * NextListItem -- * * Returns the next member of a doubly linked list, or NULL if last. * Assumes: p is member of the list headed by head. * * Result: * If head or p is NULL, return NULL. Otherwise, * next list member (or null if last). * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE ListItem * NextListItem(ListItem *p, // IN ListItem *head) // IN { if (head == NULL || p == NULL) { return NULL; } /* both p and head are non-null */ p = p->next; return p == head ? NULL : p; } /* *---------------------------------------------------------------------- * * PrevListItem -- * * Returns the prev member of a doubly linked list, or NULL if first. * Assumes: p is member of the list headed by head. * * Result: * If head or prev is NULL, return NULL. Otherwise, * prev list member (or null if first). * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE ListItem * PrevListItem(ListItem *p, // IN ListItem *head) // IN { if (head == NULL || p == NULL) { return NULL; } /* both p and head are non-null */ return p == head ? NULL : p->prev; } /* *---------------------------------------------------------------------- * * DelListItem -- * * Deletes a member of a doubly linked list, possibly modifies the * list header itself. * Assumes neither p nor headp is null and p is a member of *headp. * * Result: * None * * Side effects: * Modifies *headp. * *---------------------------------------------------------------------- */ static INLINE void DelListItem(ListItem *p, // IN ListItem **headp) // IN/OUT { ListItem *next; ASSERT(p); ASSERT(headp); next = p->next; if (p == next) { *headp = NULL; } else { next->prev = p->prev; p->prev->next = next; if (*headp == p) { *headp = next; } } } /* *---------------------------------------------------------------------- * * QueueListItem -- * * Adds a new member to the back of a doubly linked list (queue) * Assumes neither p nor headp is null and p is not a member of *headp. * * Result: * None * * Side effects: * Modifies *headp. * *---------------------------------------------------------------------- */ static INLINE void QueueListItem(ListItem *p, // IN ListItem **headp) // IN/OUT { ListItem *head; head = *headp; if (LIST_EMPTY(head)) { INIT_LIST_ITEM(p); *headp = p; } else { p->prev = head->prev; p->next = head; p->prev->next = p; head->prev = p; } } /* *---------------------------------------------------------------------- * * PushListItem -- * * Adds a new member to the front of a doubly linked list (stack) * Assumes neither p nor headp is null and p is not a member of *headp. * * Result: * None * * Side effects: * Modifies *headp. * *---------------------------------------------------------------------- */ static INLINE void PushListItem(ListItem *p, // IN ListItem **headp) // IN/OUT { QueueListItem(p, headp); *headp = p; } /* *---------------------------------------------------------------------- * * SpliceLists -- * * Make a single list {l1 l2} from {l1} and {l2} and return it. * It is okay for one or both lists to be NULL. * No checking is done. It is assumed that l1 and l2 are two * distinct lists. * * Result: * A list { l1 l2 }. * * Side effects: * Modifies l1 and l2 list pointers. * *---------------------------------------------------------------------- */ static INLINE ListItem * SpliceLists(ListItem *l1, // IN ListItem *l2) // IN { ListItem *l1Last, *l2Last; if (LIST_EMPTY(l1)) { return l2; } if (LIST_EMPTY(l2)) { return l1; } l1Last = l1->prev; /* last elem of l1 */ l2Last = l2->prev; /* last elem of l2 */ /* * l1 -> ... -> l1Last l2 -> ... l2Last */ l1Last->next = l2; l2->prev = l1Last; l1->prev = l2Last; l2Last->next = l1; return l1; } /* *---------------------------------------------------------------------- * * SplitLists -- * * Make a list l = {l1 l2} into two separate lists {l1} and {l2}, where: * l = { ... x -> p -> ... } split into: * l1 = { ... -> x } * l2 = { p -> ... } * Assumes neither p nor l is null and p is a member of l. * If p is the first element of l, then l1 will be NULL. * * Result: * None. * * Side effects: * Sets *l1p and *l2p to the resulting two lists. * Modifies l's pointers. * *---------------------------------------------------------------------- */ static INLINE void SplitLists(ListItem *p, // IN ListItem *l, // IN ListItem **l1p, // OUT ListItem **l2p) // OUT { ListItem *last; if (p == LIST_FIRST(l)) { /* first element */ *l1p = NULL; *l2p = l; return; } last = l->prev; *l1p = l; p->prev->next = l; l->prev = p->prev; *l2p = p; p->prev = last; last->next = p; } /* *---------------------------------------------------------------------- * * GetListSize -- * * Return the number of items in the list. * * Result: * The number of items in the list. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE int GetListSize(ListItem *head) // IN { ListItem *li; int ret = 0; LIST_SCAN(li, head) { ret++; } return ret; } #endif /* _CIRCLIST_H_ */ open-vm-tools-9.4.0-1280544/lib/include/dynbuf.h0000644765153500003110000001147312220061556017276 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * dynbuf.h -- * * Dynamic buffers */ #ifndef __DYNBUF_H__ # define __DYNBUF_H__ #include #include "vm_basic_types.h" #include "vm_assert.h" typedef struct DynBuf { char *data; size_t size; size_t allocated; } DynBuf; void DynBuf_Init(DynBuf *b); // IN void DynBuf_Destroy(DynBuf *b); // IN void * DynBuf_AllocGet(DynBuf const *b); // IN void DynBuf_Attach(DynBuf *b, // IN size_t size, // IN void *data); // IN void * DynBuf_Detach(DynBuf *b); // IN Bool DynBuf_Enlarge(DynBuf *b, // IN size_t min_size); // IN Bool DynBuf_Append(DynBuf *b, // IN void const *data, // IN size_t size); // IN Bool DynBuf_Trim(DynBuf *b); // IN Bool DynBuf_Copy(DynBuf *src, // IN DynBuf *dest); // OUT void DynBuf_SafeInternalAppend(DynBuf *b, // IN void const *data, // IN size_t size, // IN char const *file, // IN unsigned int lineno); // IN #define DynBuf_SafeAppend(_buf, _data, _size) \ DynBuf_SafeInternalAppend(_buf, _data, _size, __FILE__, __LINE__) /* *----------------------------------------------------------------------------- * * DynBuf_Get -- * * Retrieve a pointer to the data contained in a dynamic buffer --hpreg * * Results: * The pointer to the data * * Side effects: * None * *----------------------------------------------------------------------------- */ #if defined(SWIG) static void * #else static INLINE void * #endif DynBuf_Get(DynBuf const *b) // IN { ASSERT(b); return b->data; } /* *----------------------------------------------------------------------------- * * DynBuf_GetSize -- * * Returns the current size of the dynamic buffer --hpreg * * Results: * The current size of the dynamic buffer * * Side effects: * None * *----------------------------------------------------------------------------- */ #if defined(SWIG) static size_t #else static INLINE size_t #endif DynBuf_GetSize(DynBuf const *b) // IN { ASSERT(b); return b->size; } /* *----------------------------------------------------------------------------- * * DynBuf_SetSize -- * * Set the current size of a dynamic buffer --hpreg * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ #if defined(SWIG) static void #else static INLINE void #endif DynBuf_SetSize(DynBuf *b, // IN size_t size) // IN { ASSERT(b); ASSERT(size <= b->allocated); b->size = size; } /* *----------------------------------------------------------------------------- * * DynBuf_GetAllocatedSize -- * * Returns the current allocated size of the dynamic buffer --hpreg * * Results: * The current allocated size of the dynamic buffer * * Side effects: * None * *----------------------------------------------------------------------------- */ #if defined(SWIG) static size_t #else static INLINE size_t #endif DynBuf_GetAllocatedSize(DynBuf const *b) // IN { ASSERT(b); return b->allocated; } /* *---------------------------------------------------------------------------- * * DynBuf_AppendString -- * * Append the string to the specified DynBuf object. Basically a * fancy strcat(). * * Results: * TRUE on success * FALSE on failure (not enough memory) * * * Side effects: * DynBuf may change its size or allocate additional memory. * *---------------------------------------------------------------------------- */ #if defined(SWIG) static Bool #else static INLINE Bool #endif DynBuf_AppendString(DynBuf *buf, // IN const char *string) // IN { /* * Make sure to copy the NULL. */ return DynBuf_Append(buf, string, strlen(string) + 1); } #endif /* __DYNBUF_H__ */ open-vm-tools-9.4.0-1280544/lib/include/wiper.h0000644765153500003110000000607412220061556017136 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * wiper.h -- * * Library for wiping a virtual disk. * */ #ifndef _WIPER_H_ # define _WIPER_H_ #if defined(_WIN32) && defined(_MSC_VER) #include #endif #include "vm_basic_types.h" #include "dbllnklst.h" typedef enum { PARTITION_UNSUPPORTED = 0, PARTITION_EXT2, PARTITION_EXT3, PARTITION_REISERFS, PARTITION_NTFS, PARTITION_FAT, PARTITION_UFS, PARTITION_PCFS, PARTITION_EXT4, PARTITION_HFS, PARTITION_ZFS, } WiperPartition_Type; /* Max size of a path */ #define NATIVE_MAX_PATH 256 #define MAX_WIPER_FILE_SIZE (2 << 30) /* The maximum wiper file size in bytes */ typedef struct WiperPartition { unsigned char mountPoint[NATIVE_MAX_PATH]; /* Type of the partition */ WiperPartition_Type type; /* * Clients should specifically set this flag to TRUE to enable free space * reclamation using unmaps. */ Bool attemptUnmaps; /* * NULL if type is not PARTITION_UNSUPPORTED, otherwise describes * why the partition can not be wiped. */ const char *comment; #if defined(_WIN32) /* Private flags used by the Win32 implementation */ DWORD flags; #endif DblLnkLst_Links link; } WiperPartition; typedef struct WiperPartition_List { DblLnkLst_Links link; } WiperPartition_List; typedef struct WiperInitData { #if defined(_WIN32) HINSTANCE resourceModule; #endif } WiperInitData; Bool Wiper_Init(WiperInitData *clientData); Bool WiperPartition_Open(WiperPartition_List *pl); void WiperPartition_Close(WiperPartition_List *pl); WiperPartition *WiperSinglePartition_Allocate(void); WiperPartition *WiperSinglePartition_Open(const char *mntpt); void WiperSinglePartition_Close(WiperPartition *); Bool Wiper_IsWipeSupported(const WiperPartition *); unsigned char *WiperSinglePartition_GetSpace(const WiperPartition *p, uint64 *free, uint64 *total); /* External definition of the wiper state */ struct Wiper_State; typedef struct Wiper_State Wiper_State; Wiper_State *Wiper_Start(const WiperPartition *p, unsigned int maxWiperFileSize); unsigned char *Wiper_Next(Wiper_State **s, unsigned int *progress); unsigned char *Wiper_Cancel(Wiper_State **s); #endif /* _WIPER_H_ */ open-vm-tools-9.4.0-1280544/lib/include/xdg.h0000644765153500003110000000214412220061556016564 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * xdg.h -- * * vmware-xdg-* script wrapper library. */ #ifndef _VMWARE_XDG_H_ #define _VMWARE_XDG_H_ #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" extern const char *Xdg_DetectDesktopEnv(void); #endif // ifndef _VMWARE_XDG_H_ open-vm-tools-9.4.0-1280544/lib/include/hgfsEscape.h0000644765153500003110000000371212220061556020054 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * hgfsEscape.h -- * * Escape and unescape filenames that are not legal on a particular * platform. * */ #ifndef __HGFS_ESCAPE_H__ #define __HGFS_ESCAPE_H__ int HgfsEscape_GetSize(char const *bufIn, // IN uint32 sizeIn); // IN int HgfsEscape_Do(char const *bufIn, // IN uint32 sizeIn, // IN uint32 sizeBufOut, // IN char *bufOut); // OUT int HgfsEscape_Undo(char *bufIn, // IN uint32 sizeIn); // IN #endif // __HGFS_ESCAPE_H__ open-vm-tools-9.4.0-1280544/lib/include/x86cpuid.h0000644765153500003110000020447412220061556017466 0ustar dtormts/********************************************************* * Copyright (C) 1998-2012 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ #ifndef _X86CPUID_H_ #define _X86CPUID_H_ /* http://www.sandpile.org/ia32/cpuid.htm */ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMX #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_DISTRIBUTE #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMMON #include "includeCheck.h" #include "vm_basic_types.h" #include "community_source.h" #include "x86vendor.h" #include "vm_assert.h" /* * The linux kernel's ptrace.h stupidly defines the bare * EAX/EBX/ECX/EDX, which wrecks havoc with our preprocessor tricks. */ #undef EAX #undef EBX #undef ECX #undef EDX typedef struct CPUIDRegs { uint32 eax, ebx, ecx, edx; } CPUIDRegs; typedef union CPUIDRegsUnion { uint32 array[4]; CPUIDRegs regs; } CPUIDRegsUnion; /* * Results of calling cpuid(eax, ecx) on all host logical CPU. */ #ifdef _MSC_VER #pragma warning (disable :4200) // non-std extension: zero-sized array in struct #endif typedef #include "vmware_pack_begin.h" struct CPUIDReply { /* * Unique host logical CPU identifier. It does not change across queries, so * we use it to correlate the replies of multiple queries. */ uint64 tag; // OUT CPUIDRegs regs; // OUT } #include "vmware_pack_end.h" CPUIDReply; typedef #include "vmware_pack_begin.h" struct CPUIDQuery { uint32 eax; // IN uint32 ecx; // IN uint32 numLogicalCPUs; // IN/OUT CPUIDReply logicalCPUs[0]; // OUT } #include "vmware_pack_end.h" CPUIDQuery; /* * CPUID levels the monitor caches and ones that are not cached, but * have fields defined below (short name and actual value). * * The first parameter defines whether the level has its default masks * generated from the values in this file. Any level which is marked * as FALSE here *must* have all monitor support types set to NA. A * static assert in lib/cpuidcompat/cpuidcompat.c will check this. */ #define CPUID_CACHED_LEVELS \ CPUIDLEVEL(TRUE, 0, 0) \ CPUIDLEVEL(TRUE, 1, 1) \ CPUIDLEVEL(FALSE, 5, 5) \ CPUIDLEVEL(TRUE, 7, 7) \ CPUIDLEVEL(FALSE, A, 0xA) \ CPUIDLEVEL(TRUE, D, 0xD) \ CPUIDLEVEL(FALSE,400, 0x40000000) \ CPUIDLEVEL(FALSE,401, 0x40000001) \ CPUIDLEVEL(FALSE,402, 0x40000002) \ CPUIDLEVEL(FALSE,403, 0x40000003) \ CPUIDLEVEL(FALSE,404, 0x40000004) \ CPUIDLEVEL(FALSE,405, 0x40000005) \ CPUIDLEVEL(FALSE,406, 0x40000006) \ CPUIDLEVEL(FALSE,410, 0x40000010) \ CPUIDLEVEL(FALSE, 80, 0x80000000) \ CPUIDLEVEL(TRUE, 81, 0x80000001) \ CPUIDLEVEL(FALSE, 87, 0x80000007) \ CPUIDLEVEL(FALSE, 88, 0x80000008) \ CPUIDLEVEL(TRUE, 8A, 0x8000000A) #define CPUID_UNCACHED_LEVELS \ CPUIDLEVEL(FALSE, 4, 4) \ CPUIDLEVEL(FALSE, 6, 6) \ CPUIDLEVEL(FALSE, B, 0xB) \ CPUIDLEVEL(FALSE, 85, 0x80000005) \ CPUIDLEVEL(FALSE, 86, 0x80000006) \ CPUIDLEVEL(FALSE, 819, 0x80000019) \ CPUIDLEVEL(FALSE, 81A, 0x8000001A) \ CPUIDLEVEL(FALSE, 81B, 0x8000001B) \ CPUIDLEVEL(FALSE, 81C, 0x8000001C) \ CPUIDLEVEL(FALSE, 81D, 0x8000001D) \ CPUIDLEVEL(FALSE, 81E, 0x8000001E) #define CPUID_ALL_LEVELS \ CPUID_CACHED_LEVELS \ CPUID_UNCACHED_LEVELS /* Define cached CPUID levels in the form: CPUID_LEVEL_ */ typedef enum { #define CPUIDLEVEL(t, s, v) CPUID_LEVEL_##s, CPUID_CACHED_LEVELS #undef CPUIDLEVEL CPUID_NUM_CACHED_LEVELS } CpuidCachedLevel; /* Enum to translate between shorthand name and actual CPUID level value. */ enum { #define CPUIDLEVEL(t, s, v) CPUID_LEVEL_VAL_##s = v, CPUID_ALL_LEVELS #undef CPUIDLEVEL }; /* Named feature leaves */ #define CPUID_FEATURE_INFORMATION 0x01 #define CPUID_PROCESSOR_TOPOLOGY 4 #define CPUID_MWAIT_FEATURES 5 #define CPUID_XSAVE_FEATURES 0xd #define CPUID_HYPERVISOR_LEVEL_0 0x40000000 #define CPUID_SVM_FEATURES 0x8000000a /* * CPUID result registers */ #define CPUID_REGS \ CPUIDREG(EAX, eax) \ CPUIDREG(EBX, ebx) \ CPUIDREG(ECX, ecx) \ CPUIDREG(EDX, edx) typedef enum { #define CPUIDREG(uc, lc) CPUID_REG_##uc, CPUID_REGS #undef CPUIDREG CPUID_NUM_REGS } CpuidReg; #define CPUID_INTEL_VENDOR_STRING "GenuntelineI" #define CPUID_AMD_VENDOR_STRING "AuthcAMDenti" #define CPUID_CYRIX_VENDOR_STRING "CyriteadxIns" #define CPUID_VIA_VENDOR_STRING "CentaulsaurH" #define CPUID_HYPERV_HYPERVISOR_VENDOR_STRING "Microsoft Hv" #define CPUID_KVM_HYPERVISOR_VENDOR_STRING "KVMKVMKVM\0\0\0" #define CPUID_VMWARE_HYPERVISOR_VENDOR_STRING "VMwareVMware" #define CPUID_XEN_HYPERVISOR_VENDOR_STRING "XenVMMXenVMM" #define CPUID_INTEL_VENDOR_STRING_FIXED "GenuineIntel" #define CPUID_AMD_VENDOR_STRING_FIXED "AuthenticAMD" #define CPUID_CYRIX_VENDOR_STRING_FIXED "CyrixInstead" #define CPUID_VIA_VENDOR_STRING_FIXED "CentaurHauls" /* * FIELD can be defined to process the CPUID information provided * in the following CPUID_FIELD_DATA macro. The first parameter is * the CPUID level of the feature (must be defined in * CPUID_ALL_LEVELS, above. The second parameter is the CPUID result * register in which the field is returned (defined in CPUID_REGS). * The third field is the vendor(s) this feature applies to. "COMMON" * means all vendors apply. UNKNOWN may not be used here. The fourth * and fifth parameters are the bit position of the field and the * width, respectively. The sixth is the text name of the field. * * The seventh parameters specifies the monitor support * characteristics for this field. The value must be a valid * CpuidFieldSupported value (omitting CPUID_FIELD_SUPPORT_ for * convenience). The meaning of those values are described below. * * The eighth parameter describes whether the feature is capable of * being used by usermode code (TRUE), or just CPL0 kernel code * (FALSE). * * FLAG is defined identically to FIELD, but its accessors are more * appropriate for 1-bit flags, and compile-time asserts enforce that * the size is 1 bit wide. */ /* * CpuidFieldSupported is made up of the following values: * * NO: A feature/field that IS NOT SUPPORTED by the monitor. Even * if the host supports this feature, we will never expose it to * the guest. * * YES: A feature/field that IS SUPPORTED by the monitor. If the * host supports this feature, we will expose it to the guest. If * not, then we will not set the feature. * * ANY: A feature/field that IS ALWAYS SUPPORTED by the monitor. * Even if the host does not support the feature, the monitor can * expose the feature to the guest. * * NA: Only legal for levels not masked/tested by default (see * above for this definition). Such fields must always be marked * as NA. * * These distinctions, when combined with the feature's CPL3 * properties can be translated into a common CPUID mask string as * follows: * * NO + CPL3 --> "R" (Reserved). We don't support the feature, * but we can't properly hide this from applications when using * direct execution or HV with apps that do try/catch/fail, so we * must still perform compatibility checks. * * NO + !CPL3 --> "0" (Masked). We can hide this from the guest. * * YES --> "H" (Host). We support the feature, so show it to the * guest if the host has the feature. * * ANY/NA --> "X" (Ignore). By default, don't perform checks for * this feature bit. Per-GOS masks may choose to set this bit in * the guest. (e.g. the APIC feature bit is always set to 1.) * * See lib/cpuidcompat/cpuidcompat.c for any possible overrides to * these defaults. */ typedef enum { CPUID_FIELD_SUPPORTED_NO, CPUID_FIELD_SUPPORTED_YES, CPUID_FIELD_SUPPORTED_ANY, CPUID_FIELD_SUPPORTED_NA, CPUID_NUM_FIELD_SUPPORTEDS } CpuidFieldSupported; /* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, CPL3 */ #define CPUID_FIELD_DATA_LEVEL_0 \ FIELD( 0, 0, EAX, 0, 32, NUMLEVELS, ANY, FALSE) \ FIELD( 0, 0, EBX, 0, 32, VENDOR1, YES, TRUE) \ FIELD( 0, 0, ECX, 0, 32, VENDOR3, YES, TRUE) \ FIELD( 0, 0, EDX, 0, 32, VENDOR2, YES, TRUE) /* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, CPL3 */ #define CPUID_FIELD_DATA_LEVEL_1 \ FIELD( 1, 0, EAX, 0, 4, STEPPING, ANY, FALSE) \ FIELD( 1, 0, EAX, 4, 4, MODEL, ANY, FALSE) \ FIELD( 1, 0, EAX, 8, 4, FAMILY, YES, FALSE) \ FIELD( 1, 0, EAX, 12, 2, TYPE, ANY, FALSE) \ FIELD( 1, 0, EAX, 16, 4, EXTENDED_MODEL, ANY, FALSE) \ FIELD( 1, 0, EAX, 20, 8, EXTENDED_FAMILY, YES, FALSE) \ FIELD( 1, 0, EBX, 0, 8, BRAND_ID, ANY, FALSE) \ FIELD( 1, 0, EBX, 8, 8, CLFL_SIZE, ANY, FALSE) \ FIELD( 1, 0, EBX, 16, 8, LCPU_COUNT, ANY, FALSE) \ FIELD( 1, 0, EBX, 24, 8, APICID, ANY, FALSE) \ FLAG( 1, 0, ECX, 0, 1, SSE3, YES, TRUE) \ FLAG( 1, 0, ECX, 1, 1, PCLMULQDQ, YES, TRUE) \ FLAG( 1, 0, ECX, 2, 1, DTES64, NO, FALSE) \ FLAG( 1, 0, ECX, 3, 1, MWAIT, YES, FALSE) \ FLAG( 1, 0, ECX, 4, 1, DSCPL, NO, FALSE) \ FLAG( 1, 0, ECX, 5, 1, VMX, YES, FALSE) \ FLAG( 1, 0, ECX, 6, 1, SMX, NO, FALSE) \ FLAG( 1, 0, ECX, 7, 1, EIST, NO, FALSE) \ FLAG( 1, 0, ECX, 8, 1, TM2, NO, FALSE) \ FLAG( 1, 0, ECX, 9, 1, SSSE3, YES, TRUE) \ FLAG( 1, 0, ECX, 10, 1, CNXTID, NO, FALSE) \ FLAG( 1, 0, ECX, 11, 1, NDA11, NO, FALSE) \ FLAG( 1, 0, ECX, 12, 1, FMA, YES, TRUE) \ FLAG( 1, 0, ECX, 13, 1, CMPXCHG16B, YES, TRUE) \ FLAG( 1, 0, ECX, 14, 1, xTPR, NO, FALSE) \ FLAG( 1, 0, ECX, 15, 1, PDCM, NO, FALSE) \ FLAG( 1, 0, ECX, 17, 1, PCID, YES, FALSE) \ FLAG( 1, 0, ECX, 18, 1, DCA, NO, FALSE) \ FLAG( 1, 0, ECX, 19, 1, SSE41, YES, TRUE) \ FLAG( 1, 0, ECX, 20, 1, SSE42, YES, TRUE) \ FLAG( 1, 0, ECX, 21, 1, x2APIC, ANY, FALSE) \ FLAG( 1, 0, ECX, 22, 1, MOVBE, YES, TRUE) \ FLAG( 1, 0, ECX, 23, 1, POPCNT, YES, TRUE) \ FLAG( 1, 0, ECX, 24, 1, TSC_DEADLINE, NO, FALSE) \ FLAG( 1, 0, ECX, 25, 1, AES, YES, TRUE) \ FLAG( 1, 0, ECX, 26, 1, XSAVE, YES, FALSE) \ FLAG( 1, 0, ECX, 27, 1, OSXSAVE, ANY, FALSE) \ FLAG( 1, 0, ECX, 28, 1, AVX, YES, FALSE) \ FLAG( 1, 0, ECX, 29, 1, F16C, YES, TRUE) \ FLAG( 1, 0, ECX, 30, 1, RDRAND, YES, TRUE) \ FLAG( 1, 0, ECX, 31, 1, HYPERVISOR, ANY, TRUE) \ FLAG( 1, 0, EDX, 0, 1, FPU, YES, TRUE) \ FLAG( 1, 0, EDX, 1, 1, VME, YES, FALSE) \ FLAG( 1, 0, EDX, 2, 1, DE, YES, FALSE) \ FLAG( 1, 0, EDX, 3, 1, PSE, YES, FALSE) \ FLAG( 1, 0, EDX, 4, 1, TSC, YES, TRUE) \ FLAG( 1, 0, EDX, 5, 1, MSR, YES, FALSE) \ FLAG( 1, 0, EDX, 6, 1, PAE, YES, FALSE) \ FLAG( 1, 0, EDX, 7, 1, MCE, YES, FALSE) \ FLAG( 1, 0, EDX, 8, 1, CX8, YES, TRUE) \ FLAG( 1, 0, EDX, 9, 1, APIC, ANY, FALSE) \ FLAG( 1, 0, EDX, 11, 1, SEP, YES, TRUE) \ FLAG( 1, 0, EDX, 12, 1, MTRR, YES, FALSE) \ FLAG( 1, 0, EDX, 13, 1, PGE, YES, FALSE) \ FLAG( 1, 0, EDX, 14, 1, MCA, YES, FALSE) \ FLAG( 1, 0, EDX, 15, 1, CMOV, YES, TRUE) \ FLAG( 1, 0, EDX, 16, 1, PAT, YES, FALSE) \ FLAG( 1, 0, EDX, 17, 1, PSE36, YES, FALSE) \ FLAG( 1, 0, EDX, 18, 1, PSN, YES, FALSE) \ FLAG( 1, 0, EDX, 19, 1, CLFSH, YES, TRUE) \ FLAG( 1, 0, EDX, 21, 1, DS, YES, FALSE) \ FLAG( 1, 0, EDX, 22, 1, ACPI, ANY, FALSE) \ FLAG( 1, 0, EDX, 23, 1, MMX, YES, TRUE) \ FLAG( 1, 0, EDX, 24, 1, FXSR, YES, TRUE) \ FLAG( 1, 0, EDX, 25, 1, SSE, YES, TRUE) \ FLAG( 1, 0, EDX, 26, 1, SSE2, YES, TRUE) \ FLAG( 1, 0, EDX, 27, 1, SS, YES, FALSE) \ FLAG( 1, 0, EDX, 28, 1, HTT, ANY, FALSE) \ FLAG( 1, 0, EDX, 29, 1, TM, NO, FALSE) \ FLAG( 1, 0, EDX, 30, 1, IA64, NO, FALSE) \ FLAG( 1, 0, EDX, 31, 1, PBE, NO, FALSE) /* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, CPL3 */ #define CPUID_FIELD_DATA_LEVEL_4 \ FIELD( 4, 0, EAX, 0, 5, LEAF4_CACHE_TYPE, NA, FALSE) \ FIELD( 4, 0, EAX, 5, 3, LEAF4_CACHE_LEVEL, NA, FALSE) \ FLAG( 4, 0, EAX, 8, 1, LEAF4_CACHE_SELF_INIT, NA, FALSE) \ FLAG( 4, 0, EAX, 9, 1, LEAF4_CACHE_FULLY_ASSOC, NA, FALSE) \ FIELD( 4, 0, EAX, 14, 12, LEAF4_CACHE_NUMHT_SHARING, NA, FALSE) \ FIELD( 4, 0, EAX, 26, 6, LEAF4_CORE_COUNT, NA, FALSE) \ FIELD( 4, 0, EBX, 0, 12, LEAF4_CACHE_LINE, NA, FALSE) \ FIELD( 4, 0, EBX, 12, 10, LEAF4_CACHE_PART, NA, FALSE) \ FIELD( 4, 0, EBX, 22, 10, LEAF4_CACHE_WAYS, NA, FALSE) \ FIELD( 4, 0, ECX, 0, 32, LEAF4_CACHE_SETS, NA, FALSE) \ FLAG( 4, 0, EDX, 0, 1, LEAF4_CACHE_WBINVD_NOT_GUARANTEED, NA, FALSE) \ FLAG( 4, 0, EDX, 1, 1, LEAF4_CACHE_IS_INCLUSIVE, NA, FALSE) \ FLAG( 4, 0, EDX, 2, 1, LEAF4_CACHE_COMPLEX_INDEXING, NA, FALSE) /* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, CPL3 */ #define CPUID_FIELD_DATA_LEVEL_5 \ FIELD( 5, 0, EAX, 0, 16, MWAIT_MIN_SIZE, NA, FALSE) \ FIELD( 5, 0, EBX, 0, 16, MWAIT_MAX_SIZE, NA, FALSE) \ FLAG( 5, 0, ECX, 0, 1, MWAIT_EXTENSIONS, NA, FALSE) \ FLAG( 5, 0, ECX, 1, 1, MWAIT_INTR_BREAK, NA, FALSE) \ FIELD( 5, 0, EDX, 0, 4, MWAIT_C0_SUBSTATE, NA, FALSE) \ FIELD( 5, 0, EDX, 4, 4, MWAIT_C1_SUBSTATE, NA, FALSE) \ FIELD( 5, 0, EDX, 8, 4, MWAIT_C2_SUBSTATE, NA, FALSE) \ FIELD( 5, 0, EDX, 12, 4, MWAIT_C3_SUBSTATE, NA, FALSE) \ FIELD( 5, 0, EDX, 16, 4, MWAIT_C4_SUBSTATE, NA, FALSE) /* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, CPL3 */ #define CPUID_FIELD_DATA_LEVEL_6 \ FLAG( 6, 0, EAX, 0, 1, THERMAL_SENSOR, NA, FALSE) \ FLAG( 6, 0, EAX, 1, 1, TURBO_MODE, NA, FALSE) \ FLAG( 6, 0, EAX, 2, 1, APIC_INVARIANT, NA, FALSE) \ FIELD( 6, 0, EBX, 0, 4, NUM_INTR_THRESHOLDS, NA, FALSE) \ FLAG( 6, 0, ECX, 0, 1, HW_COORD_FEEDBACK, NA, FALSE) \ FLAG( 6, 0, ECX, 3, 1, ENERGY_PERF_BIAS, NA, FALSE) #define CPUID_7_EBX_13 /* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, CPL3 */ #define CPUID_FIELD_DATA_LEVEL_7 \ FLAG( 7, 0, EBX, 0, 1, FSGSBASE, YES, FALSE) \ FLAG( 7, 0, EBX, 3, 1, BMI1, YES, TRUE) \ FLAG( 7, 0, EBX, 4, 1, HLE, NO, TRUE) \ FLAG( 7, 0, EBX, 5, 1, AVX2, NO, TRUE) \ FLAG( 7, 0, EBX, 7, 1, SMEP, YES, FALSE) \ FLAG( 7, 0, EBX, 8, 1, BMI2, NO, TRUE) \ FLAG( 7, 0, EBX, 9, 1, ENFSTRG, YES, FALSE) \ FLAG( 7, 0, EBX, 10, 1, INVPCID, NO, FALSE) \ FLAG( 7, 0, EBX, 11, 1, RTM, NO, TRUE) \ CPUID_7_EBX_13 /* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, CPL3 */ #define CPUID_FIELD_DATA_LEVEL_A \ FIELD( A, 0, EAX, 0, 8, PMC_VERSION, NA, FALSE) \ FIELD( A, 0, EAX, 8, 8, PMC_NUM_GEN, NA, FALSE) \ FIELD( A, 0, EAX, 16, 8, PMC_WIDTH_GEN, NA, FALSE) \ FIELD( A, 0, EAX, 24, 8, PMC_EBX_LENGTH, NA, FALSE) \ FLAG( A, 0, EBX, 0, 1, PMC_CORE_CYCLES, NA, FALSE) \ FLAG( A, 0, EBX, 1, 1, PMC_INSTR_RETIRED, NA, FALSE) \ FLAG( A, 0, EBX, 2, 1, PMC_REF_CYCLES, NA, FALSE) \ FLAG( A, 0, EBX, 3, 1, PMC_LAST_LVL_CREF, NA, FALSE) \ FLAG( A, 0, EBX, 4, 1, PMC_LAST_LVL_CMISS, NA, FALSE) \ FLAG( A, 0, EBX, 5, 1, PMC_BR_INST_RETIRED, NA, FALSE) \ FLAG( A, 0, EBX, 6, 1, PMC_BR_MISS_RETIRED, NA, FALSE) \ FIELD( A, 0, EDX, 0, 5, PMC_NUM_FIXED, NA, FALSE) \ FIELD( A, 0, EDX, 5, 8, PMC_WIDTH_FIXED, NA, FALSE) /* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, CPL3 */ #define CPUID_FIELD_DATA_LEVEL_B \ FIELD( B, 0, EAX, 0, 5, TOPOLOGY_MASK_WIDTH, NA, FALSE) \ FIELD( B, 0, EBX, 0, 16, TOPOLOGY_CPUS_SHARING_LEVEL, NA, FALSE) \ FIELD( B, 0, ECX, 0, 8, TOPOLOGY_LEVEL_NUMBER, NA, FALSE) \ FIELD( B, 0, ECX, 8, 8, TOPOLOGY_LEVEL_TYPE, NA, FALSE) \ FIELD( B, 0, EDX, 0, 32, TOPOLOGY_X2APIC_ID, NA, FALSE) /* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, CPL3 */ #define CPUID_FIELD_DATA_LEVEL_D \ FLAG( D, 0, EAX, 0, 1, XCR0_MASTER_LEGACY_FP, YES, FALSE) \ FLAG( D, 0, EAX, 1, 1, XCR0_MASTER_SSE, YES, FALSE) \ FLAG( D, 0, EAX, 2, 1, XCR0_MASTER_YMM_H, YES, FALSE) \ FIELD( D, 0, EAX, 3, 29, XCR0_MASTER_LOWER, NO, FALSE) \ FIELD( D, 0, EBX, 0, 32, XSAVE_ENABLED_SIZE, ANY, FALSE) \ FIELD( D, 0, ECX, 0, 32, XSAVE_MAX_SIZE, YES, FALSE) \ FIELD( D, 0, EDX, 0, 29, XCR0_MASTER_UPPER, NO, FALSE) \ FLAG( D, 0, EDX, 30, 1, XCR0_MASTER_LWP, NO, FALSE) \ FLAG( D, 0, EDX, 31, 1, XCR0_MASTER_EXTENDED_XSAVE, NO, FALSE) \ FLAG( D, 1, EAX, 0, 1, XSAVEOPT, NO, FALSE) \ FIELD( D, 2, EAX, 0, 32, XSAVE_YMM_SIZE, YES, FALSE) \ FIELD( D, 2, EBX, 0, 32, XSAVE_YMM_OFFSET, YES, FALSE) \ FIELD( D, 2, ECX, 0, 32, XSAVE_YMM_RSVD1, YES, FALSE) \ FIELD( D, 2, EDX, 0, 32, XSAVE_YMM_RSVD2, YES, FALSE) \ FIELD( D, 62, EAX, 0, 32, XSAVE_LWP_SIZE, NO, FALSE) \ FIELD( D, 62, EBX, 0, 32, XSAVE_LWP_OFFSET, NO, FALSE) \ FIELD( D, 62, ECX, 0, 32, XSAVE_LWP_RSVD1, NO, FALSE) \ FIELD( D, 62, EDX, 0, 32, XSAVE_LWP_RSVD2, NO, FALSE) /* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, CPL3 */ #define CPUID_FIELD_DATA_LEVEL_400 \ FIELD(400, 0, EAX, 0, 32, NUM_HYP_LEVELS, NA, FALSE) \ FIELD(400, 0, EBX, 0, 32, HYPERVISOR1, NA, FALSE) \ FIELD(400, 0, ECX, 0, 32, HYPERVISOR2, NA, FALSE) \ FIELD(400, 0, EDX, 0, 32, HYPERVISOR3, NA, FALSE) /* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, CPL3 */ #define CPUID_FIELD_DATA_LEVEL_410 \ FIELD(410, 0, EAX, 0, 32, TSC_HZ, NA, FALSE) \ FIELD(410, 0, EBX, 0, 32, ACPIBUS_HZ, NA, FALSE) /* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, CPL3 */ #define CPUID_FIELD_DATA_LEVEL_80 \ FIELD( 80, 0, EAX, 0, 32, NUM_EXT_LEVELS, NA, FALSE) \ FIELD( 80, 0, EBX, 0, 32, LEAF80_VENDOR1, NA, FALSE) \ FIELD( 80, 0, ECX, 0, 32, LEAF80_VENDOR3, NA, FALSE) \ FIELD( 80, 0, EDX, 0, 32, LEAF80_VENDOR2, NA, FALSE) #define CPUID_81_ECX_17 /* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, CPL3 */ #define CPUID_FIELD_DATA_LEVEL_81 \ FIELD( 81, 0, EAX, 0, 32, UNKNOWN81EAX, ANY, FALSE) \ FIELD( 81, 0, EAX, 0, 4, LEAF81_STEPPING, ANY, FALSE) \ FIELD( 81, 0, EAX, 4, 4, LEAF81_MODEL, ANY, FALSE) \ FIELD( 81, 0, EAX, 8, 4, LEAF81_FAMILY, ANY, FALSE) \ FIELD( 81, 0, EAX, 12, 2, LEAF81_TYPE, ANY, FALSE) \ FIELD( 81, 0, EAX, 16, 4, LEAF81_EXTENDED_MODEL, ANY, FALSE) \ FIELD( 81, 0, EAX, 20, 8, LEAF81_EXTENDED_FAMILY, ANY, FALSE) \ FIELD( 81, 0, EBX, 0, 32, UNKNOWN81EBX, ANY, FALSE) \ FIELD( 81, 0, EBX, 0, 16, LEAF81_BRAND_ID, ANY, FALSE) \ FIELD( 81, 0, EBX, 16, 16, UNDEF, ANY, FALSE) \ FLAG( 81, 0, ECX, 0, 1, LAHF64, YES, TRUE) \ FLAG( 81, 0, ECX, 1, 1, CMPLEGACY, ANY, FALSE) \ FLAG( 81, 0, ECX, 2, 1, SVM, YES, FALSE) \ FLAG( 81, 0, ECX, 3, 1, EXTAPICSPC, YES, FALSE) \ FLAG( 81, 0, ECX, 4, 1, CR8AVAIL, YES, FALSE) \ FLAG( 81, 0, ECX, 5, 1, ABM, YES, TRUE) \ FLAG( 81, 0, ECX, 6, 1, SSE4A, YES, TRUE) \ FLAG( 81, 0, ECX, 7, 1, MISALIGNED_SSE, YES, TRUE) \ FLAG( 81, 0, ECX, 8, 1, 3DNPREFETCH, YES, TRUE) \ FLAG( 81, 0, ECX, 9, 1, OSVW, ANY, FALSE) \ FLAG( 81, 0, ECX, 10, 1, IBS, NO, FALSE) \ FLAG( 81, 0, ECX, 11, 1, XOP, YES, TRUE) \ FLAG( 81, 0, ECX, 12, 1, SKINIT, NO, FALSE) \ FLAG( 81, 0, ECX, 13, 1, WATCHDOG, NO, FALSE) \ FLAG( 81, 0, ECX, 15, 1, LWP, NO, FALSE) \ FLAG( 81, 0, ECX, 16, 1, FMA4, YES, TRUE) \ CPUID_81_ECX_17 \ FLAG( 81, 0, ECX, 19, 1, NODEID_MSR, NO, FALSE) \ FLAG( 81, 0, ECX, 21, 1, TBM, YES, TRUE) \ FLAG( 81, 0, ECX, 22, 1, TOPOLOGY, NO, FALSE) \ FLAG( 81, 0, ECX, 23, 1, PERFCORE, ANY, TRUE) \ FLAG( 81, 0, EDX, 0, 1, LEAF81_FPU, YES, TRUE) \ FLAG( 81, 0, EDX, 1, 1, LEAF81_VME, YES, FALSE) \ FLAG( 81, 0, EDX, 2, 1, LEAF81_DE, YES, FALSE) \ FLAG( 81, 0, EDX, 3, 1, LEAF81_PSE, YES, FALSE) \ FLAG( 81, 0, EDX, 4, 1, LEAF81_TSC, YES, TRUE) \ FLAG( 81, 0, EDX, 5, 1, LEAF81_MSR, YES, FALSE) \ FLAG( 81, 0, EDX, 6, 1, LEAF81_PAE, YES, FALSE) \ FLAG( 81, 0, EDX, 7, 1, LEAF81_MCE, YES, FALSE) \ FLAG( 81, 0, EDX, 8, 1, LEAF81_CX8, YES, TRUE) \ FLAG( 81, 0, EDX, 9, 1, LEAF81_APIC, ANY, FALSE) \ FLAG( 81, 0, EDX, 11, 1, SYSC, ANY, TRUE) \ FLAG( 81, 0, EDX, 12, 1, LEAF81_MTRR, YES, FALSE) \ FLAG( 81, 0, EDX, 13, 1, LEAF81_PGE, YES, FALSE) \ FLAG( 81, 0, EDX, 14, 1, LEAF81_MCA, YES, FALSE) \ FLAG( 81, 0, EDX, 15, 1, LEAF81_CMOV, YES, TRUE) \ FLAG( 81, 0, EDX, 16, 1, LEAF81_PAT, YES, FALSE) \ FLAG( 81, 0, EDX, 17, 1, LEAF81_PSE36, YES, FALSE) \ FLAG( 81, 0, EDX, 20, 1, NX, YES, FALSE) \ FLAG( 81, 0, EDX, 22, 1, MMXEXT, YES, TRUE) \ FLAG( 81, 0, EDX, 23, 1, LEAF81_MMX, YES, TRUE) \ FLAG( 81, 0, EDX, 24, 1, LEAF81_FXSR, YES, TRUE) \ FLAG( 81, 0, EDX, 25, 1, FFXSR, YES, FALSE) \ FLAG( 81, 0, EDX, 26, 1, PDPE1GB, YES, FALSE) \ FLAG( 81, 0, EDX, 27, 1, RDTSCP, YES, TRUE) \ FLAG( 81, 0, EDX, 29, 1, LM, YES, FALSE) \ FLAG( 81, 0, EDX, 30, 1, 3DNOWPLUS, YES, TRUE) \ FLAG( 81, 0, EDX, 31, 1, 3DNOW, YES, TRUE) #define CPUID_8A_EDX_11 \ FLAG( 8A, 0, EDX, 11, 1, SVMEDX_RSVD1, NO, FALSE) #define CPUID_8A_EDX_13_31 \ FIELD( 8A, 0, EDX, 13, 19, SVMEDX_RSVD2, NO, FALSE) /* LEVEL, REG, POS, SIZE, NAME, MON SUPP, CPL3 */ #define CPUID_FIELD_DATA_LEVEL_8x \ FIELD( 85, 0, EAX, 0, 8, ITLB_ENTRIES_2M4M_PGS, NA, FALSE) \ FIELD( 85, 0, EAX, 8, 8, ITLB_ASSOC_2M4M_PGS, NA, FALSE) \ FIELD( 85, 0, EAX, 16, 8, DTLB_ENTRIES_2M4M_PGS, NA, FALSE) \ FIELD( 85, 0, EAX, 24, 8, DTLB_ASSOC_2M4M_PGS, NA, FALSE) \ FIELD( 85, 0, EBX, 0, 8, ITLB_ENTRIES_4K_PGS, NA, FALSE) \ FIELD( 85, 0, EBX, 8, 8, ITLB_ASSOC_4K_PGS, NA, FALSE) \ FIELD( 85, 0, EBX, 16, 8, DTLB_ENTRIES_4K_PGS, NA, FALSE) \ FIELD( 85, 0, EBX, 24, 8, DTLB_ASSOC_4K_PGS, NA, FALSE) \ FIELD( 85, 0, ECX, 0, 8, L1_DCACHE_LINE_SIZE, NA, FALSE) \ FIELD( 85, 0, ECX, 8, 8, L1_DCACHE_LINES_PER_TAG, NA, FALSE) \ FIELD( 85, 0, ECX, 16, 8, L1_DCACHE_ASSOC, NA, FALSE) \ FIELD( 85, 0, ECX, 24, 8, L1_DCACHE_SIZE, NA, FALSE) \ FIELD( 85, 0, EDX, 0, 8, L1_ICACHE_LINE_SIZE, NA, FALSE) \ FIELD( 85, 0, EDX, 8, 8, L1_ICACHE_LINES_PER_TAG, NA, FALSE) \ FIELD( 85, 0, EDX, 16, 8, L1_ICACHE_ASSOC, NA, FALSE) \ FIELD( 85, 0, EDX, 24, 8, L1_ICACHE_SIZE, NA, FALSE) \ FIELD( 86, 0, EAX, 0, 12, L2_ITLB_ENTRIES_2M4M_PGS, NA, FALSE) \ FIELD( 86, 0, EAX, 12, 4, L2_ITLB_ASSOC_2M4M_PGS, NA, FALSE) \ FIELD( 86, 0, EAX, 16, 12, L2_DTLB_ENTRIES_2M4M_PGS, NA, FALSE) \ FIELD( 86, 0, EAX, 28, 4, L2_DTLB_ASSOC_2M4M_PGS, NA, FALSE) \ FIELD( 86, 0, EBX, 0, 12, L2_ITLB_ENTRIES_4K_PGS, NA, FALSE) \ FIELD( 86, 0, EBX, 12, 4, L2_ITLB_ASSOC_4K_PGS, NA, FALSE) \ FIELD( 86, 0, EBX, 16, 12, L2_DTLB_ENTRIES_4K_PGS, NA, FALSE) \ FIELD( 86, 0, EBX, 28, 4, L2_DTLB_ASSOC_4K_PGS, NA, FALSE) \ FIELD( 86, 0, ECX, 0, 8, L2CACHE_LINE, NA, FALSE) \ FIELD( 86, 0, ECX, 8, 4, L2CACHE_LINE_PER_TAG, NA, FALSE) \ FIELD( 86, 0, ECX, 12, 4, L2CACHE_WAYS, NA, FALSE) \ FIELD( 86, 0, ECX, 16, 16, L2CACHE_SIZE, NA, FALSE) \ FIELD( 86, 0, EDX, 0, 8, L3CACHE_LINE, NA, FALSE) \ FIELD( 86, 0, EDX, 8, 4, L3CACHE_LINE_PER_TAG, NA, FALSE) \ FIELD( 86, 0, EDX, 12, 4, L3CACHE_WAYS, NA, FALSE) \ FIELD( 86, 0, EDX, 18, 14, L3CACHE_SIZE, NA, FALSE) \ FLAG( 87, 0, EDX, 0, 1, TS, NA, FALSE) \ FLAG( 87, 0, EDX, 1, 1, FID, NA, FALSE) \ FLAG( 87, 0, EDX, 2, 1, VID, NA, FALSE) \ FLAG( 87, 0, EDX, 3, 1, TTP, NA, FALSE) \ FLAG( 87, 0, EDX, 4, 1, LEAF87_TM, NA, FALSE) \ FLAG( 87, 0, EDX, 5, 1, STC, NA, FALSE) \ FLAG( 87, 0, EDX, 6, 1, 100MHZSTEPS, NA, FALSE) \ FLAG( 87, 0, EDX, 7, 1, HWPSTATE, NA, FALSE) \ FLAG( 87, 0, EDX, 8, 1, TSC_INVARIANT, NA, FALSE) \ FLAG( 87, 0, EDX, 9, 1, CORE_PERF_BOOST, NA, FALSE) \ FIELD( 88, 0, EAX, 0, 8, PHYS_BITS, NA, FALSE) \ FIELD( 88, 0, EAX, 8, 8, VIRT_BITS, NA, FALSE) \ FIELD( 88, 0, EAX, 16, 8, GUEST_PHYS_ADDR_SZ, NA, FALSE) \ FIELD( 88, 0, ECX, 0, 8, LEAF88_CORE_COUNT, NA, FALSE) \ FIELD( 88, 0, ECX, 12, 4, APICID_COREID_SIZE, NA, FALSE) \ FIELD( 8A, 0, EAX, 0, 8, SVM_REVISION, YES, FALSE) \ FLAG( 8A, 0, EAX, 8, 1, SVM_HYPERVISOR, NO, FALSE) \ FIELD( 8A, 0, EAX, 9, 23, SVMEAX_RSVD, NO, FALSE) \ FIELD( 8A, 0, EBX, 0, 32, SVM_NUM_ASIDS, YES, FALSE) \ FIELD( 8A, 0, ECX, 0, 32, SVMECX_RSVD, NO, FALSE) \ FLAG( 8A, 0, EDX, 0, 1, SVM_NPT, YES, FALSE) \ FLAG( 8A, 0, EDX, 1, 1, SVM_LBR, NO, FALSE) \ FLAG( 8A, 0, EDX, 2, 1, SVM_LOCK, ANY, FALSE) \ FLAG( 8A, 0, EDX, 3, 1, SVM_NRIP, YES, FALSE) \ FLAG( 8A, 0, EDX, 4, 1, SVM_TSC_RATE_MSR, NO, FALSE) \ FLAG( 8A, 0, EDX, 5, 1, SVM_VMCB_CLEAN, YES, FALSE) \ FLAG( 8A, 0, EDX, 6, 1, SVM_FLUSH_BY_ASID, YES, FALSE) \ FLAG( 8A, 0, EDX, 7, 1, SVM_DECODE_ASSISTS, YES, FALSE) \ FIELD( 8A, 0, EDX, 8, 2, SVMEDX_RSVD0, NO, FALSE) \ FLAG( 8A, 0, EDX, 10, 1, SVM_PAUSE_FILTER, NO, FALSE) \ CPUID_8A_EDX_11 \ FLAG( 8A, 0, EDX, 12, 1, SVM_PAUSE_THRESHOLD, NO, FALSE) \ CPUID_8A_EDX_13_31 /* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, CPL3 */ #define CPUID_FIELD_DATA_LEVEL_81x \ FIELD(819, 0, EAX, 0, 12, L1_ITLB_ENTRIES_1G_PGS, NA, FALSE) \ FIELD(819, 0, EAX, 12, 4, L1_ITLB_ASSOC_1G_PGS, NA, FALSE) \ FIELD(819, 0, EAX, 16, 12, L1_DTLB_ENTRIES_1G_PGS, NA, FALSE) \ FIELD(819, 0, EAX, 28, 4, L1_DTLB_ASSOC_1G_PGS, NA, FALSE) \ FIELD(819, 0, EBX, 0, 12, L2_ITLB_ENTRIES_1G_PGS, NA, FALSE) \ FIELD(819, 0, EBX, 12, 4, L2_ITLB_ASSOC_1G_PGS, NA, FALSE) \ FIELD(819, 0, EBX, 16, 12, L2_DTLB_ENTRIES_1G_PGS, NA, FALSE) \ FIELD(819, 0, EBX, 28, 4, L2_DTLB_ASSOC_1G_PGS, NA, FALSE) \ FLAG( 81A, 0, EAX, 0, 1, FP128, NA, FALSE) \ FLAG( 81A, 0, EAX, 1, 1, MOVU, NA, FALSE) \ FLAG( 81B, 0, EAX, 0, 1, IBS_FFV, NA, FALSE) \ FLAG( 81B, 0, EAX, 1, 1, IBS_FETCHSAM, NA, FALSE) \ FLAG( 81B, 0, EAX, 2, 1, IBS_OPSAM, NA, FALSE) \ FLAG( 81B, 0, EAX, 3, 1, RW_OPCOUNT, NA, FALSE) \ FLAG( 81B, 0, EAX, 4, 1, OPCOUNT, NA, FALSE) \ FLAG( 81B, 0, EAX, 5, 1, BRANCH_TARGET_ADDR, NA, FALSE) \ FLAG( 81B, 0, EAX, 6, 1, OPCOUNT_EXT, NA, FALSE) \ FLAG( 81B, 0, EAX, 7, 1, RIP_INVALID_CHECK, NA, FALSE) \ FLAG( 81C, 0, EAX, 0, 1, LWP_AVAIL, NA, FALSE) \ FLAG( 81C, 0, EAX, 1, 1, LWP_VAL_AVAIL, NA, FALSE) \ FLAG( 81C, 0, EAX, 2, 1, LWP_IRE_AVAIL, NA, FALSE) \ FLAG( 81C, 0, EAX, 3, 1, LWP_BRE_AVAIL, NA, FALSE) \ FLAG( 81C, 0, EAX, 4, 1, LWP_DME_AVAIL, NA, FALSE) \ FLAG( 81C, 0, EAX, 5, 1, LWP_CNH_AVAIL, NA, FALSE) \ FLAG( 81C, 0, EAX, 6, 1, LWP_RNH_AVAIL, NA, FALSE) \ FLAG( 81C, 0, EAX, 31, 1, LWP_INT_AVAIL, NA, FALSE) \ FIELD(81C, 0, EBX, 0, 8, LWP_CB_SIZE, NA, FALSE) \ FIELD(81C, 0, EBX, 8, 8, LWP_EVENT_SIZE, NA, FALSE) \ FIELD(81C, 0, EBX, 16, 8, LWP_MAX_EVENTS, NA, FALSE) \ FIELD(81C, 0, EBX, 24, 8, LWP_EVENT_OFFSET, NA, FALSE) \ FIELD(81C, 0, ECX, 0, 4, LWP_LATENCY_MAX, NA, FALSE) \ FLAG( 81C, 0, ECX, 5, 1, LWP_DATA_ADDR_VALID, NA, FALSE) \ FIELD(81C, 0, ECX, 6, 3, LWP_LATENCY_ROUND, NA, FALSE) \ FIELD(81C, 0, ECX, 9, 7, LWP_VERSION, NA, FALSE) \ FIELD(81C, 0, ECX, 16, 8, LWP_MIN_BUF_SIZE, NA, FALSE) \ FLAG( 81C, 0, ECX, 28, 1, LWP_BRANCH_PRED, NA, FALSE) \ FLAG( 81C, 0, ECX, 29, 1, LWP_IP_FILTERING, NA, FALSE) \ FLAG( 81C, 0, ECX, 30, 1, LWP_CACHE_LEVEL, NA, FALSE) \ FLAG( 81C, 0, ECX, 31, 1, LWP_CACHE_LATENCY, NA, FALSE) \ FLAG( 81C, 0, EDX, 0, 1, LWP_SUPPORTED, NA, FALSE) \ FLAG( 81C, 0, EDX, 1, 1, LWP_VAL_SUPPORTED, NA, FALSE) \ FLAG( 81C, 0, EDX, 2, 1, LWP_IRE_SUPPORTED, NA, FALSE) \ FLAG( 81C, 0, EDX, 3, 1, LWP_BRE_SUPPORTED, NA, FALSE) \ FLAG( 81C, 0, EDX, 4, 1, LWP_DME_SUPPORTED, NA, FALSE) \ FLAG( 81C, 0, EDX, 5, 1, LWP_CNH_SUPPORTED, NA, FALSE) \ FLAG( 81C, 0, EDX, 6, 1, LWP_RNH_SUPPORTED, NA, FALSE) \ FLAG( 81C, 0, EDX, 31, 1, LWP_INT_SUPPORTED, NA, FALSE) \ FIELD(81D, 0, EAX, 0, 5, LEAF81D_CACHE_TYPE, NA, FALSE) \ FIELD(81D, 0, EAX, 5, 3, LEAF81D_CACHE_LEVEL, NA, FALSE) \ FLAG( 81D, 0, EAX, 8, 1, LEAF81D_CACHE_SELF_INIT, NA, FALSE) \ FLAG( 81D, 0, EAX, 9, 1, LEAF81D_CACHE_FULLY_ASSOC, NA, FALSE) \ FIELD(81D, 0, EAX, 14, 12, LEAF81D_NUM_SHARING_CACHE, NA, FALSE) \ FIELD(81D, 0, EBX, 0, 12, LEAF81D_CACHE_LINE_SIZE, NA, FALSE) \ FIELD(81D, 0, EBX, 12, 10, LEAF81D_CACHE_PHYS_PARTITIONS, NA, FALSE) \ FIELD(81D, 0, EBX, 22, 10, LEAF81D_CACHE_WAYS, NA, FALSE) \ FIELD(81D, 0, ECX, 0, 32, LEAF81D_CACHE_NUM_SETS, NA, FALSE) \ FLAG( 81D, 0, EDX, 0, 1, LEAF81D_CACHE_WBINVD, NA, FALSE) \ FLAG( 81D, 0, EDX, 1, 1, LEAF81D_CACHE_INCLUSIVE, NA, FALSE) \ FIELD(81E, 0, EAX, 0, 32, EXTENDED_APICID, NA, FALSE) \ FIELD(81E, 0, EBX, 0, 8, COMPUTE_UNIT_ID, NA, FALSE) \ FIELD(81E, 0, EBX, 8, 2, CORES_PER_COMPUTE_UNIT, NA, FALSE) \ FIELD(81E, 0, ECX, 0, 8, NODEID_VAL, NA, FALSE) \ FIELD(81E, 0, ECX, 8, 3, NODES_PER_PKG, NA, FALSE) #define INTEL_CPUID_FIELD_DATA #define AMD_CPUID_FIELD_DATA #define CPUID_FIELD_DATA \ CPUID_FIELD_DATA_LEVEL_0 \ CPUID_FIELD_DATA_LEVEL_1 \ CPUID_FIELD_DATA_LEVEL_4 \ CPUID_FIELD_DATA_LEVEL_5 \ CPUID_FIELD_DATA_LEVEL_6 \ CPUID_FIELD_DATA_LEVEL_7 \ CPUID_FIELD_DATA_LEVEL_A \ CPUID_FIELD_DATA_LEVEL_B \ CPUID_FIELD_DATA_LEVEL_D \ CPUID_FIELD_DATA_LEVEL_400 \ CPUID_FIELD_DATA_LEVEL_410 \ CPUID_FIELD_DATA_LEVEL_80 \ CPUID_FIELD_DATA_LEVEL_81 \ CPUID_FIELD_DATA_LEVEL_8x \ CPUID_FIELD_DATA_LEVEL_81x \ INTEL_CPUID_FIELD_DATA \ AMD_CPUID_FIELD_DATA /* * Define all field and flag values as an enum. The result is a full * set of values taken from the table above in the form: * * CPUID_FEATURE__ID_ == mask for feature * CPUID__ID__MASK == mask for field * CPUID__ID__SHIFT == offset of field * * e.g. - CPUID_FEATURE_COMMON_ID1EDX_FPU = 0x1 * - CPUID_COMMON_ID88EAX_VIRT_BITS_MASK = 0xff00 * - CPUID_COMMON_ID88EAX_VIRT_BITS_SHIFT = 8 * * Note: The FEATURE/MASK definitions must use some gymnastics to get * around a warning when shifting left by 32. */ #define VMW_BIT_MASK(shift) (((1 << (shift - 1)) << 1) - 1) #define FIELD(lvl, ecxIn, reg, bitpos, size, name, s, c3) \ CPUID_ID##lvl##reg##_##name##_SHIFT = bitpos, \ CPUID_ID##lvl##reg##_##name##_MASK = VMW_BIT_MASK(size) << bitpos, \ CPUID_FEATURE_ID##lvl##reg##_##name = CPUID_ID##lvl##reg##_##name##_MASK, \ CPUID_INTERNAL_SHIFT_##name = bitpos, \ CPUID_INTERNAL_MASK_##name = VMW_BIT_MASK(size) << bitpos, \ CPUID_INTERNAL_REG_##name = CPUID_REG_##reg, \ CPUID_INTERNAL_EAXIN_##name = CPUID_LEVEL_VAL_##lvl, \ CPUID_INTERNAL_ECXIN_##name = ecxIn, #define FLAG FIELD enum { /* Define data for every CPUID field we have */ CPUID_FIELD_DATA }; #undef VMW_BIT_MASK #undef FIELD #undef FLAG /* Level D subleaf 1 eax XSAVEOPT */ #define CPUID_COMMON_IDDsub1EAX_XSAVEOPT 1 /* * Legal CPUID config file mask characters. For a description of the * cpuid masking system, please see: * * http://vmweb.vmware.com/~mts/cgi-bin/view.cgi/Apps/CpuMigrationChecks */ #define CPUID_MASK_HIDE_CHR '0' #define CPUID_MASK_HIDE_STR "0" #define CPUID_MASK_FORCE_CHR '1' #define CPUID_MASK_FORCE_STR "1" #define CPUID_MASK_PASS_CHR '-' #define CPUID_MASK_PASS_STR "-" #define CPUID_MASK_TRUE_CHR 'T' #define CPUID_MASK_TRUE_STR "T" #define CPUID_MASK_FALSE_CHR 'F' #define CPUID_MASK_FALSE_STR "F" #define CPUID_MASK_IGNORE_CHR 'X' #define CPUID_MASK_IGNORE_STR "X" #define CPUID_MASK_HOST_CHR 'H' #define CPUID_MASK_HOST_STR "H" #define CPUID_MASK_RSVD_CHR 'R' #define CPUID_MASK_RSVD_STR "R" #define CPUID_MASK_INSTALL_CHR 'I' #define CPUID_MASK_INSTALL_STR "I" /* * When LM is disabled, we overlay the following masks onto the * guest's default masks. Any level that is not defined below should * be treated as all "-"s */ #define CPT_ID1ECX_LM_DISABLED "----:----:----:----:--0-:----:----:----" #define CPT_ID81EDX_LM_DISABLED "--0-:----:----:----:----:----:----:----" #define CPT_ID81ECX_LM_DISABLED "----:----:----:----:----:----:----:---0" #define CPT_GET_LM_DISABLED_MASK(lvl, reg) \ ((lvl == 1 && reg == CPUID_REG_ECX) ? CPT_ID1ECX_LM_DISABLED : \ (lvl == 0x80000001 && reg == CPUID_REG_ECX) ? CPT_ID81ECX_LM_DISABLED : \ (lvl == 0x80000001 && reg == CPUID_REG_EDX) ? CPT_ID81EDX_LM_DISABLED : \ NULL) /* * CPUID_MASK -- * CPUID_SHIFT -- * CPUID_ISSET -- * CPUID_GET -- * CPUID_SET -- * CPUID_CLEAR -- * CPUID_SETTO -- * * Accessor macros for all CPUID consts/fields/flags. Level and reg are not * required, but are used to force compile-time asserts which help verify that * the flag is being used on the right CPUID input and result register. * * Note: ASSERT_ON_COMPILE is duplicated rather than factored into its own * macro, because token concatenation does not work as expected if an input is * #defined (e.g. APIC) when macros are nested. Also, compound statements * within parenthes is a GCC extension, so we must use runtime asserts with * other compilers. */ #if defined(__GNUC__) && !defined(__clang__) #define CPUID_MASK(eaxIn, reg, flag) \ ({ \ ASSERT_ON_COMPILE(eaxIn == CPUID_INTERNAL_EAXIN_##flag && \ CPUID_REG_##reg == (CpuidReg)CPUID_INTERNAL_REG_##flag); \ CPUID_INTERNAL_MASK_##flag; \ }) #define CPUID_SHIFT(eaxIn, reg, flag) \ ({ \ ASSERT_ON_COMPILE(eaxIn == CPUID_INTERNAL_EAXIN_##flag && \ CPUID_REG_##reg == (CpuidReg)CPUID_INTERNAL_REG_##flag); \ CPUID_INTERNAL_SHIFT_##flag; \ }) #define CPUID_ISSET(eaxIn, reg, flag, data) \ ({ \ ASSERT_ON_COMPILE(eaxIn == CPUID_INTERNAL_EAXIN_##flag && \ CPUID_REG_##reg == (CpuidReg)CPUID_INTERNAL_REG_##flag); \ (((data) & CPUID_INTERNAL_MASK_##flag) != 0); \ }) #define CPUID_GET(eaxIn, reg, field, data) \ ({ \ ASSERT_ON_COMPILE(eaxIn == CPUID_INTERNAL_EAXIN_##field && \ CPUID_REG_##reg == (CpuidReg)CPUID_INTERNAL_REG_##field); \ (((uint32)(data) & CPUID_INTERNAL_MASK_##field) >> \ CPUID_INTERNAL_SHIFT_##field); \ }) #else /* * CPUIDCheck -- * * Return val after verifying parameters. */ static INLINE uint32 CPUIDCheck(uint32 eaxIn, uint32 eaxInCheck, CpuidReg reg, CpuidReg regCheck, uint32 val) { ASSERT(eaxIn == eaxInCheck && reg == regCheck); return val; } #define CPUID_MASK(eaxIn, reg, flag) \ CPUIDCheck((uint32)eaxIn, CPUID_INTERNAL_EAXIN_##flag, \ CPUID_REG_##reg, (CpuidReg)CPUID_INTERNAL_REG_##flag, \ CPUID_INTERNAL_MASK_##flag) #define CPUID_SHIFT(eaxIn, reg, flag) \ CPUIDCheck((uint32)eaxIn, CPUID_INTERNAL_EAXIN_##flag, \ CPUID_REG_##reg, (CpuidReg)CPUID_INTERNAL_REG_##flag, \ CPUID_INTERNAL_SHIFT_##flag) #define CPUID_ISSET(eaxIn, reg, flag, data) \ (CPUIDCheck((uint32)eaxIn, CPUID_INTERNAL_EAXIN_##flag, \ CPUID_REG_##reg, (CpuidReg)CPUID_INTERNAL_REG_##flag, \ CPUID_INTERNAL_MASK_##flag & (data)) != 0) #define CPUID_GET(eaxIn, reg, field, data) \ CPUIDCheck((uint32)eaxIn, CPUID_INTERNAL_EAXIN_##field, \ CPUID_REG_##reg, (CpuidReg)CPUID_INTERNAL_REG_##field, \ ((uint32)(data) & CPUID_INTERNAL_MASK_##field) >> \ CPUID_INTERNAL_SHIFT_##field) #endif #define CPUID_SET(eaxIn, reg, flag, dataPtr) \ do { \ ASSERT_ON_COMPILE( \ (uint32)eaxIn == (uint32)CPUID_INTERNAL_EAXIN_##flag && \ CPUID_REG_##reg == (CpuidReg)CPUID_INTERNAL_REG_##flag); \ *(dataPtr) |= CPUID_INTERNAL_MASK_##flag; \ } while (0) #define CPUID_CLEAR(eaxIn, reg, flag, dataPtr) \ do { \ ASSERT_ON_COMPILE( \ (uint32)eaxIn == (uint32)CPUID_INTERNAL_EAXIN_##flag && \ CPUID_REG_##reg == (CpuidReg)CPUID_INTERNAL_REG_##flag); \ *(dataPtr) &= ~CPUID_INTERNAL_MASK_##flag; \ } while (0) #define CPUID_SETTO(eaxIn, reg, field, dataPtr, val) \ do { \ uint32 _v = val; \ uint32 *_d = dataPtr; \ ASSERT_ON_COMPILE( \ (uint32)eaxIn == (uint32)CPUID_INTERNAL_EAXIN_##field && \ CPUID_REG_##reg == (CpuidReg)CPUID_INTERNAL_REG_##field); \ *_d = (*_d & ~CPUID_INTERNAL_MASK_##field) | \ (_v << CPUID_INTERNAL_SHIFT_##field); \ ASSERT(_v == (*_d & CPUID_INTERNAL_MASK_##field) >> \ CPUID_INTERNAL_SHIFT_##field); \ } while (0) #define CPUID_SETTO_SAFE(eaxIn, reg, field, dataPtr, val) \ do { \ uint32 _v = val & \ (CPUID_INTERNAL_MASK_##field >> CPUID_INTERNAL_SHIFT_##field); \ uint32 *_d = dataPtr; \ ASSERT_ON_COMPILE( \ (uint32)eaxIn == (uint32)CPUID_INTERNAL_EAXIN_##field && \ CPUID_REG_##reg == (CpuidReg)CPUID_INTERNAL_REG_##field); \ *_d = (*_d & ~CPUID_INTERNAL_MASK_##field) | \ (_v << CPUID_INTERNAL_SHIFT_##field); \ } while (0) /* * Definitions of various fields' values and more complicated * macros/functions for reading cpuid fields. */ #define CPUID_FAMILY_EXTENDED 15 /* Effective Intel CPU Families */ #define CPUID_FAMILY_486 4 #define CPUID_FAMILY_P5 5 #define CPUID_FAMILY_P6 6 #define CPUID_FAMILY_P4 15 /* Effective AMD CPU Families */ #define CPUID_FAMILY_5x86 4 #define CPUID_FAMILY_K5 5 #define CPUID_FAMILY_K6 5 #define CPUID_FAMILY_K7 6 #define CPUID_FAMILY_K8 15 #define CPUID_FAMILY_K8L 16 #define CPUID_FAMILY_K8MOBILE 17 #define CPUID_FAMILY_LLANO 18 #define CPUID_FAMILY_BOBCAT 20 #define CPUID_FAMILY_BULLDOZER 21 /* Effective VIA CPU Families */ #define CPUID_FAMILY_C7 6 /* Intel model information */ #define CPUID_MODEL_PPRO 1 #define CPUID_MODEL_PII_03 3 #define CPUID_MODEL_PII_05 5 #define CPUID_MODEL_CELERON_06 6 #define CPUID_MODEL_PM_09 9 #define CPUID_MODEL_PM_0D 13 #define CPUID_MODEL_PM_0E 14 // Yonah / Sossaman #define CPUID_MODEL_CORE_0F 15 // Conroe / Merom #define CPUID_MODEL_CORE_17 0x17 // Penryn #define CPUID_MODEL_NEHALEM_1A 0x1a // Nehalem / Gainestown #define CPUID_MODEL_ATOM_1C 0x1c // Silverthorne / Diamondville #define CPUID_MODEL_CORE_1D 0x1d // Dunnington #define CPUID_MODEL_NEHALEM_1E 0x1e // Lynnfield #define CPUID_MODEL_NEHALEM_1F 0x1f // Havendale #define CPUID_MODEL_NEHALEM_25 0x25 // Westmere / Clarkdale #define CPUID_MODEL_SANDYBRIDGE_2A 0x2a // Sandybridge (desktop/mobile) #define CPUID_MODEL_SANDYBRIDGE_2D 0x2d // Sandybridge-EP #define CPUID_MODEL_NEHALEM_2C 0x2c // Westmere-EP #define CPUID_MODEL_NEHALEM_2E 0x2e // Nehalem-EX #define CPUID_MODEL_NEHALEM_2F 0x2f // Westmere-EX #define CPUID_MODEL_SANDYBRIDGE_3A 0x3a // Ivy Bridge #define CPUID_MODEL_HASWELL_3C 0x3c // Haswell DT #define CPUID_MODEL_HASWELL_45 0x45 // Haswell Ultrathin #define CPUID_MODEL_PIII_07 7 #define CPUID_MODEL_PIII_08 8 #define CPUID_MODEL_PIII_0A 10 /* AMD model information */ #define CPUID_MODEL_BARCELONA_02 0x02 // Barcelona (Opteron & Phenom) #define CPUID_MODEL_SHANGHAI_04 0x04 // Shanghai RB #define CPUID_MODEL_SHANGHAI_05 0x05 // Shanghai BL #define CPUID_MODEL_SHANGHAI_06 0x06 // Shanghai DA #define CPUID_MODEL_ISTANBUL_MAGNY_08 0x08 // Istanbul (6 core) & Magny-cours (12) HY #define CPUID_MODEL_ISTANBUL_MAGNY_09 0x09 // HY - G34 package #define CPUID_MODEL_PHAROAH_HOUND_0A 0x0A // Pharoah Hound #define CPUID_MODEL_OPTERON_REVF_41 0x41 // family == CPUID_FAMILY_K8 /* VIA model information */ #define CPUID_MODEL_NANO 15 // Isaiah /* *---------------------------------------------------------------------- * * CPUID_IsVendor{AMD,Intel,VIA} -- * * Determines if the vendor string in cpuid id0 is from {AMD,Intel,VIA}. * * Results: * True iff vendor string is CPUID_{AMD,INTEL,VIA}_VENDOR_STRING * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE Bool CPUID_IsRawVendor(CPUIDRegs *id0, const char* vendor) { // hard to get strcmp() in some environments, so do it in the raw return (id0->ebx == *(const uint32 *) (vendor + 0) && id0->ecx == *(const uint32 *) (vendor + 4) && id0->edx == *(const uint32 *) (vendor + 8)); } static INLINE Bool CPUID_IsVendorAMD(CPUIDRegs *id0) { return CPUID_IsRawVendor(id0, CPUID_AMD_VENDOR_STRING); } static INLINE Bool CPUID_IsVendorIntel(CPUIDRegs *id0) { return CPUID_IsRawVendor(id0, CPUID_INTEL_VENDOR_STRING); } static INLINE Bool CPUID_IsVendorVIA(CPUIDRegs *id0) { return CPUID_IsRawVendor(id0, CPUID_VIA_VENDOR_STRING); } static INLINE uint32 CPUID_EFFECTIVE_FAMILY(uint32 v) /* %eax from CPUID with %eax=1. */ { uint32 f = CPUID_GET(1, EAX, FAMILY, v); return f != CPUID_FAMILY_EXTENDED ? f : f + CPUID_GET(1, EAX, EXTENDED_FAMILY, v); } /* Normally only used when FAMILY==CPUID_FAMILY_EXTENDED, but Intel is * now using the extended model field for FAMILY==CPUID_FAMILY_P6 to * refer to the newer Core2 CPUs */ static INLINE uint32 CPUID_EFFECTIVE_MODEL(uint32 v) /* %eax from CPUID with %eax=1. */ { uint32 m = CPUID_GET(1, EAX, MODEL, v); uint32 em = CPUID_GET(1, EAX, EXTENDED_MODEL, v); return m + (em << 4); } /* * Notice that CPUID families for Intel and AMD overlap. The following macros * should only be used AFTER the manufacturer has been established (through * the use of CPUID standard function 0). */ static INLINE Bool CPUID_FAMILY_IS_486(uint32 eax) { return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_486; } static INLINE Bool CPUID_FAMILY_IS_P5(uint32 eax) { return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_P5; } static INLINE Bool CPUID_FAMILY_IS_P6(uint32 eax) { return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_P6; } static INLINE Bool CPUID_FAMILY_IS_PENTIUM4(uint32 eax) { return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_P4; } /* * Intel Pentium M processors are Yonah/Sossaman or an older P-M */ static INLINE Bool CPUID_UARCH_IS_PENTIUM_M(uint32 v) // IN: %eax from CPUID with %eax=1. { /* Assumes the CPU manufacturer is Intel. */ return CPUID_FAMILY_IS_P6(v) && (CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_PM_09 || CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_PM_0D || CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_PM_0E); } /* * Intel Core processors are Merom, Conroe, Woodcrest, Clovertown, * Penryn, Dunnington, Kentsfield, Yorktown, Harpertown, ........ */ static INLINE Bool CPUID_UARCH_IS_CORE(uint32 v) // IN: %eax from CPUID with %eax=1. { uint32 model = CPUID_EFFECTIVE_MODEL(v); /* Assumes the CPU manufacturer is Intel. */ return CPUID_FAMILY_IS_P6(v) && model >= CPUID_MODEL_CORE_0F && (model < CPUID_MODEL_NEHALEM_1A || model == CPUID_MODEL_CORE_1D); } /* * Intel Nehalem processors are: Nehalem, Gainestown, Lynnfield, Clarkdale. */ static INLINE Bool CPUID_UARCH_IS_NEHALEM(uint32 v) // IN: %eax from CPUID with %eax=1. { /* Assumes the CPU manufacturer is Intel. */ uint32 effectiveModel = CPUID_EFFECTIVE_MODEL(v); return CPUID_FAMILY_IS_P6(v) && (effectiveModel == CPUID_MODEL_NEHALEM_1A || effectiveModel == CPUID_MODEL_NEHALEM_1E || effectiveModel == CPUID_MODEL_NEHALEM_1F || effectiveModel == CPUID_MODEL_NEHALEM_25 || effectiveModel == CPUID_MODEL_NEHALEM_2C || effectiveModel == CPUID_MODEL_NEHALEM_2E || effectiveModel == CPUID_MODEL_NEHALEM_2F); } static INLINE Bool CPUID_UARCH_IS_SANDYBRIDGE(uint32 v) // IN: %eax from CPUID with %eax=1. { /* Assumes the CPU manufacturer is Intel. */ uint32 effectiveModel = CPUID_EFFECTIVE_MODEL(v); return CPUID_FAMILY_IS_P6(v) && (effectiveModel == CPUID_MODEL_SANDYBRIDGE_2A || effectiveModel == CPUID_MODEL_SANDYBRIDGE_2D || effectiveModel == CPUID_MODEL_SANDYBRIDGE_3A); } static INLINE Bool CPUID_MODEL_IS_CENTERTON(uint32 v) // IN: %eax from CPUID with %eax=1. { /* Assumes the CPU manufacturer is Intel. */ return CPUID_FAMILY_IS_P6(v) && CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_ATOM_1C; } static INLINE Bool CPUID_MODEL_IS_WESTMERE(uint32 v) // IN: %eax from CPUID with %eax=1. { /* Assumes the CPU manufacturer is Intel. */ uint32 effectiveModel = CPUID_EFFECTIVE_MODEL(v); return CPUID_FAMILY_IS_P6(v) && (effectiveModel == CPUID_MODEL_NEHALEM_25 || // Clarkdale effectiveModel == CPUID_MODEL_NEHALEM_2C || // Westmere-EP effectiveModel == CPUID_MODEL_NEHALEM_2F); // Westmere-EX } static INLINE Bool CPUID_MODEL_IS_SANDYBRIDGE(uint32 v) // IN: %eax from CPUID with %eax=1. { /* Assumes the CPU manufacturer is Intel. */ uint32 effectiveModel = CPUID_EFFECTIVE_MODEL(v); return CPUID_FAMILY_IS_P6(v) && (effectiveModel == CPUID_MODEL_SANDYBRIDGE_2A || effectiveModel == CPUID_MODEL_SANDYBRIDGE_2D); } static INLINE Bool CPUID_MODEL_IS_IVYBRIDGE(uint32 v) // IN: %eax from CPUID with %eax=1. { /* Assumes the CPU manufacturer is Intel. */ uint32 effectiveModel = CPUID_EFFECTIVE_MODEL(v); return CPUID_FAMILY_IS_P6(v) && ( effectiveModel == CPUID_MODEL_SANDYBRIDGE_3A); } static INLINE Bool CPUID_FAMILY_IS_K7(uint32 eax) { return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_K7; } static INLINE Bool CPUID_FAMILY_IS_K8(uint32 eax) { return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_K8; } static INLINE Bool CPUID_FAMILY_IS_K8EXT(uint32 eax) { /* * We check for this pattern often enough that it's * worth a separate function, for syntactic sugar. */ return CPUID_FAMILY_IS_K8(eax) && CPUID_GET(1, EAX, EXTENDED_MODEL, eax) != 0; } static INLINE Bool CPUID_FAMILY_IS_K8L(uint32 eax) { return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_K8L || CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_LLANO; } static INLINE Bool CPUID_FAMILY_IS_LLANO(uint32 eax) { return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_LLANO; } static INLINE Bool CPUID_FAMILY_IS_K8MOBILE(uint32 eax) { /* Essentially a K8 (not K8L) part, but with mobile features. */ return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_K8MOBILE; } static INLINE Bool CPUID_FAMILY_IS_K8STAR(uint32 eax) { /* * Read function name as "K8*", as in wildcard. * Matches K8 or K8L or K8MOBILE */ return CPUID_FAMILY_IS_K8(eax) || CPUID_FAMILY_IS_K8L(eax) || CPUID_FAMILY_IS_K8MOBILE(eax); } static INLINE Bool CPUID_FAMILY_IS_BOBCAT(uint32 eax) { return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_BOBCAT; } static INLINE Bool CPUID_FAMILY_IS_BULLDOZER(uint32 eax) { return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_BULLDOZER; } /* * AMD Barcelona (of either Opteron or Phenom kind). */ static INLINE Bool CPUID_MODEL_IS_BARCELONA(uint32 v) // IN: %eax from CPUID with %eax=1. { /* Assumes the CPU manufacturer is AMD. */ return CPUID_EFFECTIVE_FAMILY(v) == CPUID_FAMILY_K8L && CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_BARCELONA_02; } static INLINE Bool CPUID_MODEL_IS_SHANGHAI(uint32 v) // IN: %eax from CPUID with %eax=1. { /* Assumes the CPU manufacturer is AMD. */ return CPUID_EFFECTIVE_FAMILY(v) == CPUID_FAMILY_K8L && (CPUID_MODEL_SHANGHAI_04 <= CPUID_EFFECTIVE_MODEL(v) && CPUID_EFFECTIVE_MODEL(v) <= CPUID_MODEL_SHANGHAI_06); } static INLINE Bool CPUID_MODEL_IS_ISTANBUL_MAGNY(uint32 v) // IN: %eax from CPUID with %eax=1. { /* Assumes the CPU manufacturer is AMD. */ return CPUID_EFFECTIVE_FAMILY(v) == CPUID_FAMILY_K8L && (CPUID_MODEL_ISTANBUL_MAGNY_08 <= CPUID_EFFECTIVE_MODEL(v) && CPUID_EFFECTIVE_MODEL(v) <= CPUID_MODEL_ISTANBUL_MAGNY_09); } static INLINE Bool CPUID_MODEL_IS_PHAROAH_HOUND(uint32 v) // IN: %eax from CPUID with %eax=1. { /* Assumes the CPU manufacturer is AMD. */ return CPUID_EFFECTIVE_FAMILY(v) == CPUID_FAMILY_K8L && CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_PHAROAH_HOUND_0A; } static INLINE Bool CPUID_MODEL_IS_BULLDOZER(uint32 eax) { return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_BULLDOZER; } #define CPUID_TYPE_PRIMARY 0 #define CPUID_TYPE_OVERDRIVE 1 #define CPUID_TYPE_SECONDARY 2 #define CPUID_INTEL_ID4EAX_LEAF4_CACHE_TYPE_NULL 0 #define CPUID_INTEL_ID4EAX_LEAF4_CACHE_TYPE_DATA 1 #define CPUID_INTEL_ID4EAX_LEAF4_CACHE_TYPE_INST 2 #define CPUID_INTEL_ID4EAX_LEAF4_CACHE_TYPE_UNIF 3 #define CPUID_LEAF4_CACHE_TYPE_NULL 0 #define CPUID_LEAF4_CACHE_TYPE_DATA 1 #define CPUID_LEAF4_CACHE_TYPE_INST 2 #define CPUID_LEAF4_CACHE_TYPE_UNIF 3 #define CPUID_LEAF4_CACHE_INDEXING_DIRECT 0 #define CPUID_LEAF4_CACHE_INDEXING_COMPLEX 1 #define CPUID_INTEL_ID4EAX_LEAF4_CACHE_SELF_INIT 0x00000100 #define CPUID_INTEL_ID4EAX_LEAF4_CACHE_FULLY_ASSOC 0x00000200 #define CPUID_LEAF4_CACHE_SELF_INIT 0x00000100 #define CPUID_LEAF4_CACHE_FULLY_ASSOC 0x00000200 #define CPUID_INTEL_IDBECX_LEVEL_TYPE_INVALID 0 #define CPUID_INTEL_IDBECX_LEVEL_TYPE_SMT 1 #define CPUID_INTEL_IDBECX_LEVEL_TYPE_CORE 2 #define CPUID_TOPOLOGY_LEVEL_TYPE_INVALID 0 #define CPUID_TOPOLOGY_LEVEL_TYPE_SMT 1 #define CPUID_TOPOLOGY_LEVEL_TYPE_CORE 2 /* * For certain AMD processors, an lfence instruction is necessary at various * places to ensure ordering. */ static INLINE Bool CPUID_VendorRequiresFence(CpuidVendor vendor) { return vendor == CPUID_VENDOR_AMD; } static INLINE Bool CPUID_VersionRequiresFence(uint32 version) { return CPUID_EFFECTIVE_FAMILY(version) == CPUID_FAMILY_K8 && CPUID_EFFECTIVE_MODEL(version) < 0x40; } static INLINE Bool CPUID_ID0RequiresFence(CPUIDRegs *id0) { if (id0->eax == 0) { return FALSE; } return CPUID_IsVendorAMD(id0); } static INLINE Bool CPUID_ID1RequiresFence(CPUIDRegs *id1) { return CPUID_VersionRequiresFence(id1->eax); } static INLINE Bool CPUID_RequiresFence(CpuidVendor vendor, // IN uint32 version) // IN: %eax from CPUID with %eax=1. { return CPUID_VendorRequiresFence(vendor) && CPUID_VersionRequiresFence(version); } /* * The following low-level functions compute the number of * cores per cpu. They should be used cautiously because * they do not necessarily work on all types of CPUs. * High-level functions that are correct for all CPUs are * available elsewhere: see lib/cpuidInfo/cpuidInfo.c. */ static INLINE uint32 CPUID_IntelCoresPerPackage(uint32 v) /* %eax from CPUID with %eax=4 and %ecx=0. */ { // Note: This is not guaranteed to work on older Intel CPUs. return 1 + CPUID_GET(4, EAX, LEAF4_CORE_COUNT, v); } static INLINE uint32 CPUID_AMDCoresPerPackage(uint32 v) /* %ecx from CPUID with %eax=0x80000008. */ { // Note: This is not guaranteed to work on older AMD CPUs. return 1 + CPUID_GET(0x80000008, ECX, LEAF88_CORE_COUNT, v); } /* * Hypervisor CPUID space is 0x400000XX. */ static INLINE Bool CPUID_IsHypervisorLevel(uint32 level) { return (level & 0xffffff00) == 0x40000000; } /* *---------------------------------------------------------------------- * * CPUID_LevelUsesEcx -- * * Returns TRUE for leaves that support input ECX != 0 (subleaves). * *---------------------------------------------------------------------- */ static INLINE Bool CPUID_LevelUsesEcx(uint32 level) { return level == 4 || level == 7 || level == 0xb || level == 0xd || level == 0x8000001d; } /* *---------------------------------------------------------------------- * * CPUID_IsValid*Subleaf -- * * Functions to determine the last subleaf for the level specified * *---------------------------------------------------------------------- */ static INLINE Bool CPUID_IsValidBSubleaf(uint32 ebx) // IN: %ebx = cpuid.b.sublevel.ebx { return ebx != 0; } static INLINE Bool CPUID_IsValid4Subleaf(uint32 eax) // IN: %eax = cpuid.4.sublevel.eax { return eax != 0; } static INLINE Bool CPUID_IsValid7Subleaf(uint32 eax, uint32 subleaf) // IN: %eax = cpuid.7.0.eax { /* * cpuid.7.0.eax is the max ecx (subleaf) index */ return subleaf <= eax; } /* *---------------------------------------------------------------------- * * CPUID_IsValidDSubleaf -- * * It is the caller's repsonsibility to determine if the processor * supports XSAVE and therefore has D sub-leaves. * *---------------------------------------------------------------------- */ static INLINE Bool CPUID_IsValidDSubleaf(uint32 subleaf) // IN: subleaf to check { return subleaf <= 63; } /* *---------------------------------------------------------------------- * * CPUID_SupportsMsrPlatformInfo -- * * Uses vendor and cpuid.1.0.eax to determine if the processor * supports MSR_PLATFORM_INFO. * *---------------------------------------------------------------------- */ static INLINE Bool CPUID_SupportsMsrPlatformInfo(CpuidVendor vendor, uint32 version) { return vendor == CPUID_VENDOR_INTEL && (CPUID_UARCH_IS_NEHALEM(version) || CPUID_UARCH_IS_SANDYBRIDGE(version)); } #endif open-vm-tools-9.4.0-1280544/lib/include/cpNameLite.h0000644765153500003110000000436512220061556020032 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * cpLiteName.h -- * * Cross-platform "lite" name format used by hgfs. * */ #ifndef __CP_NAME_LITE_H__ #define __CP_NAME_LITE_H__ #if defined __KERNEL__ && defined __linux__ # include "driver-config.h" # include #elif defined _KERNEL && defined __FreeBSD__ # include # define strchr(s,c) index(s,c) #else # include #endif #include "vm_basic_types.h" void CPNameLite_ConvertTo(char *bufIn, // IN/OUT: Input to convert size_t inSize, // IN: Size of input buffer char pathSep); // IN: Path separator void CPNameLite_ConvertFrom(char *bufIn, // IN/OUT: Input to convert size_t inSize, // IN: Size of input buffer char pathSep); // IN: Path separator #endif /* __CP_NAME_LITE_H__ */ open-vm-tools-9.4.0-1280544/lib/include/hgfsTransport.h0000644765153500003110000001547712220061556020663 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * hgfsTransport.h -- * * Transport file shared between guest drivers and host. */ #ifndef _HGFS_TRANSPORT_H_ # define _HGFS_TRANSPORT_H_ #include "vmci_defs.h" /**************************************** * Vsock, Tcp specific data structures * ****************************************/ /* Some fudged values for TCP over sockets. */ #define HGFS_HOST_PORT 2000 /* Socket packet magic. */ #define HGFS_SOCKET_VERSION1 1 /* * Socket status codes. */ typedef enum { HGFS_SOCKET_STATUS_SUCCESS, /* Socket header is good. */ HGFS_SOCKET_STATUS_SIZE_MISMATCH, /* Size and version are incompatible. */ HGFS_SOCKET_STATUS_VERSION_NOT_SUPPORTED, /* Version not handled by remote. */ HGFS_SOCKET_STATUS_INVALID_PACKETLEN, /* Message len exceeds maximum. */ } HgfsSocketStatus; /* * Socket flags. */ typedef uint32 HgfsSocketFlags; /* Used by backdoor proxy socket client to Hgfs server (out of VMX process). */ #define HGFS_SOCKET_SYNC (1 << 0) /* Socket packet header. */ typedef #include "vmware_pack_begin.h" struct HgfsSocketHeader { uint32 version; /* Header version. */ uint32 size; /* Header size, should match for the specified version. */ HgfsSocketStatus status; /* Status: always success when sending (ignored) valid on replies. */ uint32 packetLen; /* The length of the packet to follow. */ HgfsSocketFlags flags; /* The flags to indicate how to deal with the packet. */ } #include "vmware_pack_end.h" HgfsSocketHeader; #define HgfsSocketHeaderInit(hdr, _version, _size, _status, _pktLen, _flags) \ do { \ (hdr)->version = (_version); \ (hdr)->size = (_size); \ (hdr)->status = (_status); \ (hdr)->packetLen = (_pktLen); \ (hdr)->flags = (_flags); \ } while (0) /************************************************ * VMCI specific data structures, macros * ************************************************/ #define HGFS_VMCI_VERSION_1 0x1 typedef enum { HGFS_TS_IO_PENDING, HGFS_TS_IO_COMPLETE, HGFS_TS_IO_FAILED, } HgfsTransportRequestState; typedef enum { HGFS_ASYNC_IOREQ_SHMEM, HGFS_ASYNC_IOREQ_GET_PAGES, HGFS_ASYNC_IOREP, } HgfsAsyncReplyFlags; typedef enum { HGFS_TH_REP_GET_PAGES, HGFS_TH_REQUEST, HGFS_TH_TERMINATE_SESSION, } HgfsTransportPacketType; #define HGFS_VMCI_TRANSPORT_ERROR (VMCI_ERROR_CLIENT_MIN - 1) #define HGFS_VMCI_VERSION_MISMATCH (VMCI_ERROR_CLIENT_MIN - 2) #define HGFS_VMCI_TYPE_NOT_SUPPORTED (VMCI_ERROR_CLIENT_MIN - 3) /* * Used By : Guest and Host * Lives in : Inside HgfsVmciTransportHeader */ typedef #include "vmware_pack_begin.h" struct HgfsIov { uint64 pa; /* Physical addr */ uint32 len; /* length of data; should be <= PAGE_SIZE */ } #include "vmware_pack_end.h" HgfsIov; /* * Used By : Guest and Host * Lives in : Inside HgfsVmciTransportHeader */ typedef #include "vmware_pack_begin.h" struct HgfsAsyncIov { uint64 pa; /* Physical addr */ uint64 va; /* Virtual addr */ uint32 len; /* length of data; should be <= PAGE_SIZE */ uint64 index; /* Guest opaque data; should not be changed by host */ Bool chain; /* Are pages chained ? */ } #include "vmware_pack_end.h" HgfsAsyncIov; /* * Every VMCI request will have this transport Header sent over * in the datagram by the Guest OS. * * Used By : Guest and Host * Lives in : Sent by Guest inside VMCI datagram */ typedef #include "vmware_pack_begin.h" struct HgfsVmciTransportHeader { uint32 version; /* Version number */ HgfsTransportPacketType pktType; /* Type of packet */ uint32 iovCount; /* Number of iovs */ union { HgfsIov iov[1]; /* (PA, len) */ HgfsAsyncIov asyncIov[1]; }; } #include "vmware_pack_end.h" HgfsVmciTransportHeader; /* * Indicates status of VMCI requests. If the requests are processed sync * by the hgfsServer then guest should see IO_COMPLETE otherwise IO_PENDING. * * Used By: Guest and Host * Lives in: Guest Memory */ typedef #include "vmware_pack_begin.h" struct HgfsVmciTransportStatus { HgfsTransportRequestState status; /* IO_PENDING, IO_COMPLETE, IO_FAILED etc */ uint32 size; /* G->H: Size of the packet,H->G: How much more space is needed */ } #include "vmware_pack_end.h" HgfsVmciTransportStatus; typedef #include "vmware_pack_begin.h" struct HgfsVmciAsyncResponse { uint64 id; /* Id corresponding to the guest request */ } #include "vmware_pack_end.h" HgfsVmciAsyncResponse; typedef #include "vmware_pack_begin.h" struct HgfsVmciAsyncShmem { uint32 count; /* Number of iovs */ HgfsAsyncIov iov[1]; } #include "vmware_pack_end.h" HgfsVmciAsyncShmem; typedef #include "vmware_pack_begin.h" struct HgfsVmciAsyncReply { uint32 version; HgfsAsyncReplyFlags pktType; union { HgfsVmciAsyncResponse response; HgfsVmciAsyncShmem shmem; }; } #include "vmware_pack_end.h" HgfsVmciAsyncReply; #endif /* _HGFS_TRANSPORT_H_ */ open-vm-tools-9.4.0-1280544/lib/include/vix.h0000644765153500003110000013502012220061556016610 0ustar dtormts/********************************************************* * Copyright (C) 2004-2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * This is the C interface to the VIX API. * This is platform-independent. */ #ifndef _VIX_H_ #define _VIX_H_ #ifdef __cplusplus extern "C" { #endif /* *----------------------------------------------------------------------------- * * Basic Types -- * *----------------------------------------------------------------------------- */ #include "vm_basic_types.h" typedef int VixHandle; enum { VIX_INVALID_HANDLE = 0, }; /* * These are the types of handles. */ typedef int VixHandleType; enum { VIX_HANDLETYPE_NONE = 0, VIX_HANDLETYPE_HOST = 2, VIX_HANDLETYPE_VM = 3, VIX_HANDLETYPE_NETWORK = 5, VIX_HANDLETYPE_JOB = 6, VIX_HANDLETYPE_SNAPSHOT = 7, VIX_HANDLETYPE_PROPERTY_LIST = 9, VIX_HANDLETYPE_METADATA_CONTAINER = 11 }; /* * The "//{{ Begin VIX_ERROR }}" and "//{{ End VIX_ERROR }}" lines are * to bracket the error code definitions that will be copied over * to vixDiskLib.h during build time. If you modify these two lines, please * make sure you also change bora/lib/distribute/vixDiskLib.h and * bora/support/scripts/replaceVixErrors.py */ // {{ Begin VIX_ERROR }} /* * An error is a 64-bit value. If there is no error, then the value is * set to VIX_OK. If there is an error, then the least significant bits * will be set to one of the integer error codes defined below. The more * significant bits may or may not be set to various values, depending on * the errors. */ typedef uint64 VixError; #define VIX_ERROR_CODE(err) ((err) & 0xFFFF) #define VIX_SUCCEEDED(err) (VIX_OK == (err)) #define VIX_FAILED(err) (VIX_OK != (err)) /* * The error codes are returned by all public VIX routines. */ enum { VIX_OK = 0, /* General errors */ VIX_E_FAIL = 1, VIX_E_OUT_OF_MEMORY = 2, VIX_E_INVALID_ARG = 3, VIX_E_FILE_NOT_FOUND = 4, VIX_E_OBJECT_IS_BUSY = 5, VIX_E_NOT_SUPPORTED = 6, VIX_E_FILE_ERROR = 7, VIX_E_DISK_FULL = 8, VIX_E_INCORRECT_FILE_TYPE = 9, VIX_E_CANCELLED = 10, VIX_E_FILE_READ_ONLY = 11, VIX_E_FILE_ALREADY_EXISTS = 12, VIX_E_FILE_ACCESS_ERROR = 13, VIX_E_REQUIRES_LARGE_FILES = 14, VIX_E_FILE_ALREADY_LOCKED = 15, VIX_E_VMDB = 16, VIX_E_NOT_SUPPORTED_ON_REMOTE_OBJECT = 20, VIX_E_FILE_TOO_BIG = 21, VIX_E_FILE_NAME_INVALID = 22, VIX_E_ALREADY_EXISTS = 23, VIX_E_BUFFER_TOOSMALL = 24, VIX_E_OBJECT_NOT_FOUND = 25, VIX_E_HOST_NOT_CONNECTED = 26, VIX_E_INVALID_UTF8_STRING = 27, VIX_E_OPERATION_ALREADY_IN_PROGRESS = 31, VIX_E_UNFINISHED_JOB = 29, VIX_E_NEED_KEY = 30, VIX_E_LICENSE = 32, VIX_E_VM_HOST_DISCONNECTED = 34, VIX_E_AUTHENTICATION_FAIL = 35, VIX_E_HOST_CONNECTION_LOST = 36, VIX_E_DUPLICATE_NAME = 41, VIX_E_ARGUMENT_TOO_BIG = 44, /* Handle Errors */ VIX_E_INVALID_HANDLE = 1000, VIX_E_NOT_SUPPORTED_ON_HANDLE_TYPE = 1001, VIX_E_TOO_MANY_HANDLES = 1002, /* XML errors */ VIX_E_NOT_FOUND = 2000, VIX_E_TYPE_MISMATCH = 2001, VIX_E_INVALID_XML = 2002, /* VM Control Errors */ VIX_E_TIMEOUT_WAITING_FOR_TOOLS = 3000, VIX_E_UNRECOGNIZED_COMMAND = 3001, VIX_E_OP_NOT_SUPPORTED_ON_GUEST = 3003, VIX_E_PROGRAM_NOT_STARTED = 3004, VIX_E_CANNOT_START_READ_ONLY_VM = 3005, VIX_E_VM_NOT_RUNNING = 3006, VIX_E_VM_IS_RUNNING = 3007, VIX_E_CANNOT_CONNECT_TO_VM = 3008, VIX_E_POWEROP_SCRIPTS_NOT_AVAILABLE = 3009, VIX_E_NO_GUEST_OS_INSTALLED = 3010, VIX_E_VM_INSUFFICIENT_HOST_MEMORY = 3011, VIX_E_SUSPEND_ERROR = 3012, VIX_E_VM_NOT_ENOUGH_CPUS = 3013, VIX_E_HOST_USER_PERMISSIONS = 3014, VIX_E_GUEST_USER_PERMISSIONS = 3015, VIX_E_TOOLS_NOT_RUNNING = 3016, VIX_E_GUEST_OPERATIONS_PROHIBITED = 3017, VIX_E_ANON_GUEST_OPERATIONS_PROHIBITED = 3018, VIX_E_ROOT_GUEST_OPERATIONS_PROHIBITED = 3019, VIX_E_MISSING_ANON_GUEST_ACCOUNT = 3023, VIX_E_CANNOT_AUTHENTICATE_WITH_GUEST = 3024, VIX_E_UNRECOGNIZED_COMMAND_IN_GUEST = 3025, VIX_E_CONSOLE_GUEST_OPERATIONS_PROHIBITED = 3026, VIX_E_MUST_BE_CONSOLE_USER = 3027, VIX_E_VMX_MSG_DIALOG_AND_NO_UI = 3028, /* VIX_E_NOT_ALLOWED_DURING_VM_RECORDING = 3029, Removed in version 1.11 */ /* VIX_E_NOT_ALLOWED_DURING_VM_REPLAY = 3030, Removed in version 1.11 */ VIX_E_OPERATION_NOT_ALLOWED_FOR_LOGIN_TYPE = 3031, VIX_E_LOGIN_TYPE_NOT_SUPPORTED = 3032, VIX_E_EMPTY_PASSWORD_NOT_ALLOWED_IN_GUEST = 3033, VIX_E_INTERACTIVE_SESSION_NOT_PRESENT = 3034, VIX_E_INTERACTIVE_SESSION_USER_MISMATCH = 3035, /* VIX_E_UNABLE_TO_REPLAY_VM = 3039, Removed in version 1.11 */ VIX_E_CANNOT_POWER_ON_VM = 3041, VIX_E_NO_DISPLAY_SERVER = 3043, /* VIX_E_VM_NOT_RECORDING = 3044, Removed in version 1.11 */ /* VIX_E_VM_NOT_REPLAYING = 3045, Removed in version 1.11 */ VIX_E_TOO_MANY_LOGONS = 3046, VIX_E_INVALID_AUTHENTICATION_SESSION = 3047, /* VM Errors */ VIX_E_VM_NOT_FOUND = 4000, VIX_E_NOT_SUPPORTED_FOR_VM_VERSION = 4001, VIX_E_CANNOT_READ_VM_CONFIG = 4002, VIX_E_TEMPLATE_VM = 4003, VIX_E_VM_ALREADY_LOADED = 4004, VIX_E_VM_ALREADY_UP_TO_DATE = 4006, VIX_E_VM_UNSUPPORTED_GUEST = 4011, /* Property Errors */ VIX_E_UNRECOGNIZED_PROPERTY = 6000, VIX_E_INVALID_PROPERTY_VALUE = 6001, VIX_E_READ_ONLY_PROPERTY = 6002, VIX_E_MISSING_REQUIRED_PROPERTY = 6003, VIX_E_INVALID_SERIALIZED_DATA = 6004, VIX_E_PROPERTY_TYPE_MISMATCH = 6005, /* Completion Errors */ VIX_E_BAD_VM_INDEX = 8000, /* Message errors */ VIX_E_INVALID_MESSAGE_HEADER = 10000, VIX_E_INVALID_MESSAGE_BODY = 10001, /* Snapshot errors */ VIX_E_SNAPSHOT_INVAL = 13000, VIX_E_SNAPSHOT_DUMPER = 13001, VIX_E_SNAPSHOT_DISKLIB = 13002, VIX_E_SNAPSHOT_NOTFOUND = 13003, VIX_E_SNAPSHOT_EXISTS = 13004, VIX_E_SNAPSHOT_VERSION = 13005, VIX_E_SNAPSHOT_NOPERM = 13006, VIX_E_SNAPSHOT_CONFIG = 13007, VIX_E_SNAPSHOT_NOCHANGE = 13008, VIX_E_SNAPSHOT_CHECKPOINT = 13009, VIX_E_SNAPSHOT_LOCKED = 13010, VIX_E_SNAPSHOT_INCONSISTENT = 13011, VIX_E_SNAPSHOT_NAMETOOLONG = 13012, VIX_E_SNAPSHOT_VIXFILE = 13013, VIX_E_SNAPSHOT_DISKLOCKED = 13014, VIX_E_SNAPSHOT_DUPLICATEDDISK = 13015, VIX_E_SNAPSHOT_INDEPENDENTDISK = 13016, VIX_E_SNAPSHOT_NONUNIQUE_NAME = 13017, VIX_E_SNAPSHOT_MEMORY_ON_INDEPENDENT_DISK = 13018, VIX_E_SNAPSHOT_MAXSNAPSHOTS = 13019, VIX_E_SNAPSHOT_MIN_FREE_SPACE = 13020, VIX_E_SNAPSHOT_HIERARCHY_TOODEEP = 13021, VIX_E_SNAPSHOT_RRSUSPEND = 13022, VIX_E_SNAPSHOT_NOT_REVERTABLE = 13024, /* Host Errors */ VIX_E_HOST_DISK_INVALID_VALUE = 14003, VIX_E_HOST_DISK_SECTORSIZE = 14004, VIX_E_HOST_FILE_ERROR_EOF = 14005, VIX_E_HOST_NETBLKDEV_HANDSHAKE = 14006, VIX_E_HOST_SOCKET_CREATION_ERROR = 14007, VIX_E_HOST_SERVER_NOT_FOUND = 14008, VIX_E_HOST_NETWORK_CONN_REFUSED = 14009, VIX_E_HOST_TCP_SOCKET_ERROR = 14010, VIX_E_HOST_TCP_CONN_LOST = 14011, VIX_E_HOST_NBD_HASHFILE_VOLUME = 14012, VIX_E_HOST_NBD_HASHFILE_INIT = 14013, /* Disklib errors */ VIX_E_DISK_INVAL = 16000, VIX_E_DISK_NOINIT = 16001, VIX_E_DISK_NOIO = 16002, VIX_E_DISK_PARTIALCHAIN = 16003, VIX_E_DISK_NEEDSREPAIR = 16006, VIX_E_DISK_OUTOFRANGE = 16007, VIX_E_DISK_CID_MISMATCH = 16008, VIX_E_DISK_CANTSHRINK = 16009, VIX_E_DISK_PARTMISMATCH = 16010, VIX_E_DISK_UNSUPPORTEDDISKVERSION = 16011, VIX_E_DISK_OPENPARENT = 16012, VIX_E_DISK_NOTSUPPORTED = 16013, VIX_E_DISK_NEEDKEY = 16014, VIX_E_DISK_NOKEYOVERRIDE = 16015, VIX_E_DISK_NOTENCRYPTED = 16016, VIX_E_DISK_NOKEY = 16017, VIX_E_DISK_INVALIDPARTITIONTABLE = 16018, VIX_E_DISK_NOTNORMAL = 16019, VIX_E_DISK_NOTENCDESC = 16020, VIX_E_DISK_NEEDVMFS = 16022, VIX_E_DISK_RAWTOOBIG = 16024, VIX_E_DISK_TOOMANYOPENFILES = 16027, VIX_E_DISK_TOOMANYREDO = 16028, VIX_E_DISK_RAWTOOSMALL = 16029, VIX_E_DISK_INVALIDCHAIN = 16030, VIX_E_DISK_KEY_NOTFOUND = 16052, // metadata key is not found VIX_E_DISK_SUBSYSTEM_INIT_FAIL = 16053, VIX_E_DISK_INVALID_CONNECTION = 16054, VIX_E_DISK_ENCODING = 16061, VIX_E_DISK_CANTREPAIR = 16062, VIX_E_DISK_INVALIDDISK = 16063, VIX_E_DISK_NOLICENSE = 16064, VIX_E_DISK_NODEVICE = 16065, VIX_E_DISK_UNSUPPORTEDDEVICE = 16066, VIX_E_DISK_CAPACITY_MISMATCH = 16067, VIX_E_DISK_PARENT_NOTALLOWED = 16068, VIX_E_DISK_ATTACH_ROOTLINK = 16069, /* Crypto Library Errors */ VIX_E_CRYPTO_UNKNOWN_ALGORITHM = 17000, VIX_E_CRYPTO_BAD_BUFFER_SIZE = 17001, VIX_E_CRYPTO_INVALID_OPERATION = 17002, VIX_E_CRYPTO_RANDOM_DEVICE = 17003, VIX_E_CRYPTO_NEED_PASSWORD = 17004, VIX_E_CRYPTO_BAD_PASSWORD = 17005, VIX_E_CRYPTO_NOT_IN_DICTIONARY = 17006, VIX_E_CRYPTO_NO_CRYPTO = 17007, VIX_E_CRYPTO_ERROR = 17008, VIX_E_CRYPTO_BAD_FORMAT = 17009, VIX_E_CRYPTO_LOCKED = 17010, VIX_E_CRYPTO_EMPTY = 17011, VIX_E_CRYPTO_KEYSAFE_LOCATOR = 17012, /* Remoting Errors. */ VIX_E_CANNOT_CONNECT_TO_HOST = 18000, VIX_E_NOT_FOR_REMOTE_HOST = 18001, VIX_E_INVALID_HOSTNAME_SPECIFICATION = 18002, /* Screen Capture Errors. */ VIX_E_SCREEN_CAPTURE_ERROR = 19000, VIX_E_SCREEN_CAPTURE_BAD_FORMAT = 19001, VIX_E_SCREEN_CAPTURE_COMPRESSION_FAIL = 19002, VIX_E_SCREEN_CAPTURE_LARGE_DATA = 19003, /* Guest Errors */ VIX_E_GUEST_VOLUMES_NOT_FROZEN = 20000, VIX_E_NOT_A_FILE = 20001, VIX_E_NOT_A_DIRECTORY = 20002, VIX_E_NO_SUCH_PROCESS = 20003, VIX_E_FILE_NAME_TOO_LONG = 20004, VIX_E_OPERATION_DISABLED = 20005, /* Tools install errors */ VIX_E_TOOLS_INSTALL_NO_IMAGE = 21000, VIX_E_TOOLS_INSTALL_IMAGE_INACCESIBLE = 21001, VIX_E_TOOLS_INSTALL_NO_DEVICE = 21002, VIX_E_TOOLS_INSTALL_DEVICE_NOT_CONNECTED = 21003, VIX_E_TOOLS_INSTALL_CANCELLED = 21004, VIX_E_TOOLS_INSTALL_INIT_FAILED = 21005, VIX_E_TOOLS_INSTALL_AUTO_NOT_SUPPORTED = 21006, VIX_E_TOOLS_INSTALL_GUEST_NOT_READY = 21007, VIX_E_TOOLS_INSTALL_SIG_CHECK_FAILED = 21008, VIX_E_TOOLS_INSTALL_ERROR = 21009, VIX_E_TOOLS_INSTALL_ALREADY_UP_TO_DATE = 21010, VIX_E_TOOLS_INSTALL_IN_PROGRESS = 21011, VIX_E_TOOLS_INSTALL_IMAGE_COPY_FAILED = 21012, /* Wrapper Errors */ VIX_E_WRAPPER_WORKSTATION_NOT_INSTALLED = 22001, VIX_E_WRAPPER_VERSION_NOT_FOUND = 22002, VIX_E_WRAPPER_SERVICEPROVIDER_NOT_FOUND = 22003, VIX_E_WRAPPER_PLAYER_NOT_INSTALLED = 22004, VIX_E_WRAPPER_RUNTIME_NOT_INSTALLED = 22005, VIX_E_WRAPPER_MULTIPLE_SERVICEPROVIDERS = 22006, /* FuseMnt errors*/ VIX_E_MNTAPI_MOUNTPT_NOT_FOUND = 24000, VIX_E_MNTAPI_MOUNTPT_IN_USE = 24001, VIX_E_MNTAPI_DISK_NOT_FOUND = 24002, VIX_E_MNTAPI_DISK_NOT_MOUNTED = 24003, VIX_E_MNTAPI_DISK_IS_MOUNTED = 24004, VIX_E_MNTAPI_DISK_NOT_SAFE = 24005, VIX_E_MNTAPI_DISK_CANT_OPEN = 24006, VIX_E_MNTAPI_CANT_READ_PARTS = 24007, VIX_E_MNTAPI_UMOUNT_APP_NOT_FOUND = 24008, VIX_E_MNTAPI_UMOUNT = 24009, VIX_E_MNTAPI_NO_MOUNTABLE_PARTITONS = 24010, VIX_E_MNTAPI_PARTITION_RANGE = 24011, VIX_E_MNTAPI_PERM = 24012, VIX_E_MNTAPI_DICT = 24013, VIX_E_MNTAPI_DICT_LOCKED = 24014, VIX_E_MNTAPI_OPEN_HANDLES = 24015, VIX_E_MNTAPI_CANT_MAKE_VAR_DIR = 24016, VIX_E_MNTAPI_NO_ROOT = 24017, VIX_E_MNTAPI_LOOP_FAILED = 24018, VIX_E_MNTAPI_DAEMON = 24019, VIX_E_MNTAPI_INTERNAL = 24020, VIX_E_MNTAPI_SYSTEM = 24021, VIX_E_MNTAPI_NO_CONNECTION_DETAILS = 24022, /* FuseMnt errors: Do not exceed 24299 */ /* VixMntapi errors*/ VIX_E_MNTAPI_INCOMPATIBLE_VERSION = 24300, VIX_E_MNTAPI_OS_ERROR = 24301, VIX_E_MNTAPI_DRIVE_LETTER_IN_USE = 24302, VIX_E_MNTAPI_DRIVE_LETTER_ALREADY_ASSIGNED = 24303, VIX_E_MNTAPI_VOLUME_NOT_MOUNTED = 24304, VIX_E_MNTAPI_VOLUME_ALREADY_MOUNTED = 24305, VIX_E_MNTAPI_FORMAT_FAILURE = 24306, VIX_E_MNTAPI_NO_DRIVER = 24307, VIX_E_MNTAPI_ALREADY_OPENED = 24308, VIX_E_MNTAPI_ITEM_NOT_FOUND = 24309, VIX_E_MNTAPI_UNSUPPROTED_BOOT_LOADER = 24310, VIX_E_MNTAPI_UNSUPPROTED_OS = 24311, VIX_E_MNTAPI_CODECONVERSION = 24312, VIX_E_MNTAPI_REGWRITE_ERROR = 24313, VIX_E_MNTAPI_UNSUPPORTED_FT_VOLUME = 24314, VIX_E_MNTAPI_PARTITION_NOT_FOUND = 24315, VIX_E_MNTAPI_PUTFILE_ERROR = 24316, VIX_E_MNTAPI_GETFILE_ERROR = 24317, VIX_E_MNTAPI_REG_NOT_OPENED = 24318, VIX_E_MNTAPI_REGDELKEY_ERROR = 24319, VIX_E_MNTAPI_CREATE_PARTITIONTABLE_ERROR = 24320, VIX_E_MNTAPI_OPEN_FAILURE = 24321, VIX_E_MNTAPI_VOLUME_NOT_WRITABLE = 24322, /* Success on operation that completes asynchronously */ VIX_ASYNC = 25000, /* Async errors */ VIX_E_ASYNC_MIXEDMODE_UNSUPPORTED = 26000, /* Network Errors */ VIX_E_NET_HTTP_UNSUPPORTED_PROTOCOL = 30001, VIX_E_NET_HTTP_URL_MALFORMAT = 30003, VIX_E_NET_HTTP_COULDNT_RESOLVE_PROXY = 30005, VIX_E_NET_HTTP_COULDNT_RESOLVE_HOST = 30006, VIX_E_NET_HTTP_COULDNT_CONNECT = 30007, VIX_E_NET_HTTP_HTTP_RETURNED_ERROR = 30022, VIX_E_NET_HTTP_OPERATION_TIMEDOUT = 30028, VIX_E_NET_HTTP_SSL_CONNECT_ERROR = 30035, VIX_E_NET_HTTP_TOO_MANY_REDIRECTS = 30047, VIX_E_NET_HTTP_TRANSFER = 30200, VIX_E_NET_HTTP_SSL_SECURITY = 30201, VIX_E_NET_HTTP_GENERIC = 30202, }; // {{ End VIX_ERROR }} const char *Vix_GetErrorText(VixError err, const char *locale); /* *----------------------------------------------------------------------------- * * VIX Handles -- * * These are common functions that apply to handles of several types. *----------------------------------------------------------------------------- */ /* * VIX Property Type */ typedef int VixPropertyType; enum { VIX_PROPERTYTYPE_ANY = 0, VIX_PROPERTYTYPE_INTEGER = 1, VIX_PROPERTYTYPE_STRING = 2, VIX_PROPERTYTYPE_BOOL = 3, VIX_PROPERTYTYPE_HANDLE = 4, VIX_PROPERTYTYPE_INT64 = 5, VIX_PROPERTYTYPE_BLOB = 6 }; /* * VIX Property ID's */ typedef int VixPropertyID; enum { VIX_PROPERTY_NONE = 0, /* Properties used by several handle types. */ VIX_PROPERTY_META_DATA_CONTAINER = 2, /* VIX_HANDLETYPE_HOST properties */ VIX_PROPERTY_HOST_HOSTTYPE = 50, VIX_PROPERTY_HOST_API_VERSION = 51, VIX_PROPERTY_HOST_SOFTWARE_VERSION = 52, /* VIX_HANDLETYPE_VM properties */ VIX_PROPERTY_VM_NUM_VCPUS = 101, VIX_PROPERTY_VM_VMX_PATHNAME = 103, VIX_PROPERTY_VM_VMTEAM_PATHNAME = 105, VIX_PROPERTY_VM_MEMORY_SIZE = 106, VIX_PROPERTY_VM_READ_ONLY = 107, VIX_PROPERTY_VM_NAME = 108, VIX_PROPERTY_VM_GUESTOS = 109, VIX_PROPERTY_VM_IN_VMTEAM = 128, VIX_PROPERTY_VM_POWER_STATE = 129, VIX_PROPERTY_VM_TOOLS_STATE = 152, VIX_PROPERTY_VM_IS_RUNNING = 196, VIX_PROPERTY_VM_SUPPORTED_FEATURES = 197, /* VIX_PROPERTY_VM_IS_RECORDING = 236, Removed in version 1.11 */ /* VIX_PROPERTY_VM_IS_REPLAYING = 237, Removed in version 1.11 */ VIX_PROPERTY_VM_SSL_ERROR = 293, /* Result properties; these are returned by various procedures */ VIX_PROPERTY_JOB_RESULT_ERROR_CODE = 3000, VIX_PROPERTY_JOB_RESULT_VM_IN_GROUP = 3001, VIX_PROPERTY_JOB_RESULT_USER_MESSAGE = 3002, VIX_PROPERTY_JOB_RESULT_EXIT_CODE = 3004, VIX_PROPERTY_JOB_RESULT_COMMAND_OUTPUT = 3005, VIX_PROPERTY_JOB_RESULT_HANDLE = 3010, VIX_PROPERTY_JOB_RESULT_GUEST_OBJECT_EXISTS = 3011, VIX_PROPERTY_JOB_RESULT_GUEST_PROGRAM_ELAPSED_TIME = 3017, VIX_PROPERTY_JOB_RESULT_GUEST_PROGRAM_EXIT_CODE = 3018, VIX_PROPERTY_JOB_RESULT_ITEM_NAME = 3035, VIX_PROPERTY_JOB_RESULT_FOUND_ITEM_DESCRIPTION = 3036, VIX_PROPERTY_JOB_RESULT_SHARED_FOLDER_COUNT = 3046, VIX_PROPERTY_JOB_RESULT_SHARED_FOLDER_HOST = 3048, VIX_PROPERTY_JOB_RESULT_SHARED_FOLDER_FLAGS = 3049, VIX_PROPERTY_JOB_RESULT_PROCESS_ID = 3051, VIX_PROPERTY_JOB_RESULT_PROCESS_OWNER = 3052, VIX_PROPERTY_JOB_RESULT_PROCESS_COMMAND = 3053, VIX_PROPERTY_JOB_RESULT_FILE_FLAGS = 3054, VIX_PROPERTY_JOB_RESULT_PROCESS_START_TIME = 3055, VIX_PROPERTY_JOB_RESULT_VM_VARIABLE_STRING = 3056, VIX_PROPERTY_JOB_RESULT_PROCESS_BEING_DEBUGGED = 3057, VIX_PROPERTY_JOB_RESULT_SCREEN_IMAGE_SIZE = 3058, VIX_PROPERTY_JOB_RESULT_SCREEN_IMAGE_DATA = 3059, VIX_PROPERTY_JOB_RESULT_FILE_SIZE = 3061, VIX_PROPERTY_JOB_RESULT_FILE_MOD_TIME = 3062, VIX_PROPERTY_JOB_RESULT_EXTRA_ERROR_INFO = 3084, /* Event properties; these are sent in the moreEventInfo for some events. */ VIX_PROPERTY_FOUND_ITEM_LOCATION = 4010, /* VIX_HANDLETYPE_SNAPSHOT properties */ VIX_PROPERTY_SNAPSHOT_DISPLAYNAME = 4200, VIX_PROPERTY_SNAPSHOT_DESCRIPTION = 4201, VIX_PROPERTY_SNAPSHOT_POWERSTATE = 4205, /* VIX_PROPERTY_SNAPSHOT_IS_REPLAYABLE = 4207, Removed in version 1.11 */ VIX_PROPERTY_GUEST_SHAREDFOLDERS_SHARES_PATH = 4525, /* Virtual machine encryption properties */ VIX_PROPERTY_VM_ENCRYPTION_PASSWORD = 7001, }; /* * These are events that may be signalled by calling a procedure * of type VixEventProc. */ typedef int VixEventType; enum { VIX_EVENTTYPE_JOB_COMPLETED = 2, VIX_EVENTTYPE_JOB_PROGRESS = 3, VIX_EVENTTYPE_FIND_ITEM = 8, VIX_EVENTTYPE_CALLBACK_SIGNALLED = 2, // Deprecated - Use VIX_EVENTTYPE_JOB_COMPLETED instead. }; /* * These are the property flags for each file. */ enum { VIX_FILE_ATTRIBUTES_DIRECTORY = 0x0001, VIX_FILE_ATTRIBUTES_SYMLINK = 0x0002, }; /* * Procedures of this type are called when an event happens on a handle. */ typedef void VixEventProc(VixHandle handle, VixEventType eventType, VixHandle moreEventInfo, void *clientData); /* * Handle Property functions */ void Vix_ReleaseHandle(VixHandle handle); void Vix_AddRefHandle(VixHandle handle); VixHandleType Vix_GetHandleType(VixHandle handle); VixError Vix_GetProperties(VixHandle handle, VixPropertyID firstPropertyID, ...); VixError Vix_GetPropertyType(VixHandle handle, VixPropertyID propertyID, VixPropertyType *propertyType); void Vix_FreeBuffer(void *p); /* *----------------------------------------------------------------------------- * * VIX Host -- * *----------------------------------------------------------------------------- */ typedef int VixHostOptions; enum { /* * The following option was removed in version 1.11. VIX_HOSTOPTION_USE_EVENT_PUMP = 0x0008, */ VIX_HOSTOPTION_VERIFY_SSL_CERT = 0x4000, }; typedef int VixServiceProvider; enum { VIX_SERVICEPROVIDER_DEFAULT = 1, VIX_SERVICEPROVIDER_VMWARE_SERVER = 2, VIX_SERVICEPROVIDER_VMWARE_WORKSTATION = 3, VIX_SERVICEPROVIDER_VMWARE_PLAYER = 4, VIX_SERVICEPROVIDER_VMWARE_VI_SERVER = 10, VIX_SERVICEPROVIDER_VMWARE_WORKSTATION_SHARED = 11, }; /* * VIX_API_VERSION tells VixHost_Connect to use the latest API version * that is available for the product specified in the VixServiceProvider * parameter. */ enum { VIX_API_VERSION = -1 }; VixHandle VixHost_Connect(int apiVersion, VixServiceProvider hostType, const char *hostName, int hostPort, const char *userName, const char *password, VixHostOptions options, VixHandle propertyListHandle, VixEventProc *callbackProc, void *clientData); void VixHost_Disconnect(VixHandle hostHandle); /* * VM Registration */ VixHandle VixHost_RegisterVM(VixHandle hostHandle, const char *vmxFilePath, VixEventProc *callbackProc, void *clientData); VixHandle VixHost_UnregisterVM(VixHandle hostHandle, const char *vmxFilePath, VixEventProc *callbackProc, void *clientData); /* * VM Search */ typedef int VixFindItemType; enum { VIX_FIND_RUNNING_VMS = 1, VIX_FIND_REGISTERED_VMS = 4, }; VixHandle VixHost_FindItems(VixHandle hostHandle, VixFindItemType searchType, VixHandle searchCriteria, int32 timeout, VixEventProc *callbackProc, void *clientData); /* * VixHost_OpenVM() supercedes VixVM_Open() since it allows for * the passing of option flags and extra data in the form of a * property list. * It is recommended to use VixHost_OpenVM() instead of VixVM_Open(). */ typedef int VixVMOpenOptions; enum { VIX_VMOPEN_NORMAL = 0x0, }; VixHandle VixHost_OpenVM(VixHandle hostHandle, const char *vmxFilePathName, VixVMOpenOptions options, VixHandle propertyListHandle, VixEventProc *callbackProc, void *clientData); /* * Following functions were removed in version 1.11. * typedef int VixPumpEventsOptions; enum { VIX_PUMPEVENTOPTION_NONE = 0, }; void Vix_PumpEvents(VixHandle hostHandle, VixPumpEventsOptions options); VixHandle VixVM_OpenUrlInGuest(VixHandle vmHandle, const char *url, int windowState, VixHandle propertyListHandle, VixEventProc *callbackProc, void *clientData); */ /* *----------------------------------------------------------------------------- * * PropertyList -- * *----------------------------------------------------------------------------- */ #ifndef VIX_HIDE_FROM_JAVA VixError VixPropertyList_AllocPropertyList(VixHandle hostHandle, VixHandle *resultHandle, int firstPropertyID, ...); #endif /* *----------------------------------------------------------------------------- * * VIX VM -- * * This describes the persistent configuration state of a single VM. The * VM may or may not be running. * *----------------------------------------------------------------------------- */ VixHandle VixVM_Open(VixHandle hostHandle, const char *vmxFilePathName, VixEventProc *callbackProc, void *clientData); typedef int VixVMPowerOpOptions; enum { VIX_VMPOWEROP_NORMAL = 0, VIX_VMPOWEROP_FROM_GUEST = 0x0004, VIX_VMPOWEROP_SUPPRESS_SNAPSHOT_POWERON = 0x0080, VIX_VMPOWEROP_LAUNCH_GUI = 0x0200, VIX_VMPOWEROP_START_VM_PAUSED = 0x1000, }; /* * Power operations */ VixHandle VixVM_PowerOn(VixHandle vmHandle, VixVMPowerOpOptions powerOnOptions, VixHandle propertyListHandle, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_PowerOff(VixHandle vmHandle, VixVMPowerOpOptions powerOffOptions, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_Reset(VixHandle vmHandle, VixVMPowerOpOptions resetOptions, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_Suspend(VixHandle vmHandle, VixVMPowerOpOptions suspendOptions, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_Pause(VixHandle vmHandle, int options, VixHandle propertyList, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_Unpause(VixHandle vmHandle, int options, VixHandle propertyList, VixEventProc *callbackProc, void *clientData); typedef int VixVMDeleteOptions; enum { VIX_VMDELETE_DISK_FILES = 0x0002, }; VixHandle VixVM_Delete(VixHandle vmHandle, VixVMDeleteOptions deleteOptions, VixEventProc *callbackProc, void *clientData); /* * This is the state of an individual VM. These values are bitwise flags. * The actual value returned for may be a bitwise OR of one more of these * flags, along with other reserved values not documented here. */ typedef int VixPowerState; enum { VIX_POWERSTATE_POWERING_OFF = 0x0001, VIX_POWERSTATE_POWERED_OFF = 0x0002, VIX_POWERSTATE_POWERING_ON = 0x0004, VIX_POWERSTATE_POWERED_ON = 0x0008, VIX_POWERSTATE_SUSPENDING = 0x0010, VIX_POWERSTATE_SUSPENDED = 0x0020, VIX_POWERSTATE_TOOLS_RUNNING = 0x0040, VIX_POWERSTATE_RESETTING = 0x0080, VIX_POWERSTATE_BLOCKED_ON_MSG = 0x0100, VIX_POWERSTATE_PAUSED = 0x0200, VIX_POWERSTATE_RESUMING = 0x0800, }; typedef int VixToolsState; enum { VIX_TOOLSSTATE_UNKNOWN = 0x0001, VIX_TOOLSSTATE_RUNNING = 0x0002, VIX_TOOLSSTATE_NOT_INSTALLED = 0x0004, }; /* * These flags describe optional functions supported by different * types of VM. */ enum { VIX_VM_SUPPORT_SHARED_FOLDERS = 0x0001, VIX_VM_SUPPORT_MULTIPLE_SNAPSHOTS = 0x0002, VIX_VM_SUPPORT_TOOLS_INSTALL = 0x0004, VIX_VM_SUPPORT_HARDWARE_UPGRADE = 0x0008, }; /* * VIX_ADMINISTRATOR_USER_NAME and VIX_CONSOLE_USER_NAME are no longer * supported. If your code includes references to these constants please * update your code to use a valid guest username and password when calling * VixVM_LoginInGuest(). */ //#define VIX_ADMINISTRATOR_USER_NAME "__VMware_Vix_Guest_User_Admin__" //#define VIX_CONSOLE_USER_NAME "__VMware_Vix_Guest_Console_User__" /* * Following functions were removed in version 1.11. * VixHandle VixVM_BeginRecording(VixHandle vmHandle, const char *displayName, const char *description, int options, VixHandle propertyList, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_EndRecording(VixHandle vmHandle, int options, VixHandle propertyList, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_BeginReplay(VixHandle vmHandle, VixHandle snapshotHandle, int options, VixHandle propertyList, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_EndReplay(VixHandle vmHandle, int options, VixHandle propertyList, VixEventProc *callbackProc, void *clientData); */ /* * Guest operations */ VixHandle VixVM_WaitForToolsInGuest(VixHandle vmHandle, int timeoutInSeconds, VixEventProc *callbackProc, void *clientData); /* * VixVM_LoginInGuest option flags. */ enum { VIX_LOGIN_IN_GUEST_REQUIRE_INTERACTIVE_ENVIRONMENT = 0x08, }; VixHandle VixVM_LoginInGuest(VixHandle vmHandle, const char *userName, const char *password, int options, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_LogoutFromGuest(VixHandle vmHandle, VixEventProc *callbackProc, void *clientData); /* * Guest Process functions */ typedef int VixRunProgramOptions; enum { VIX_RUNPROGRAM_RETURN_IMMEDIATELY = 0x0001, VIX_RUNPROGRAM_ACTIVATE_WINDOW = 0x0002, }; VixHandle VixVM_RunProgramInGuest(VixHandle vmHandle, const char *guestProgramName, const char *commandLineArgs, VixRunProgramOptions options, VixHandle propertyListHandle, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_ListProcessesInGuest(VixHandle vmHandle, int options, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_KillProcessInGuest(VixHandle vmHandle, uint64 pid, int options, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_RunScriptInGuest(VixHandle vmHandle, const char *interpreter, const char *scriptText, VixRunProgramOptions options, VixHandle propertyListHandle, VixEventProc *callbackProc, void *clientData); /* * Guest File functions */ VixHandle VixVM_CopyFileFromHostToGuest(VixHandle vmHandle, const char *hostPathName, const char *guestPathName, int options, VixHandle propertyListHandle, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_CopyFileFromGuestToHost(VixHandle vmHandle, const char *guestPathName, const char *hostPathName, int options, VixHandle propertyListHandle, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_DeleteFileInGuest(VixHandle vmHandle, const char *guestPathName, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_FileExistsInGuest(VixHandle vmHandle, const char *guestPathName, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_RenameFileInGuest(VixHandle vmHandle, const char *oldName, const char *newName, int options, VixHandle propertyListHandle, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_CreateTempFileInGuest(VixHandle vmHandle, int options, VixHandle propertyListHandle, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_GetFileInfoInGuest(VixHandle vmHandle, const char *pathName, VixEventProc *callbackProc, void *clientData); /* * Guest Directory functions */ VixHandle VixVM_ListDirectoryInGuest(VixHandle vmHandle, const char *pathName, int options, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_CreateDirectoryInGuest(VixHandle vmHandle, const char *pathName, VixHandle propertyListHandle, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_DeleteDirectoryInGuest(VixHandle vmHandle, const char *pathName, int options, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_DirectoryExistsInGuest(VixHandle vmHandle, const char *pathName, VixEventProc *callbackProc, void *clientData); /* * Guest Variable Functions */ enum { VIX_VM_GUEST_VARIABLE = 1, VIX_VM_CONFIG_RUNTIME_ONLY = 2, VIX_GUEST_ENVIRONMENT_VARIABLE = 3, }; VixHandle VixVM_ReadVariable(VixHandle vmHandle, int variableType, const char *name, int options, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_WriteVariable(VixHandle vmHandle, int variableType, const char *valueName, const char *value, int options, VixEventProc *callbackProc, void *clientData); /* * Snapshot functions that operate on a VM */ VixError VixVM_GetNumRootSnapshots(VixHandle vmHandle, int *result); VixError VixVM_GetRootSnapshot(VixHandle vmHandle, int index, VixHandle *snapshotHandle); VixError VixVM_GetCurrentSnapshot(VixHandle vmHandle, VixHandle *snapshotHandle); VixError VixVM_GetNamedSnapshot(VixHandle vmHandle, const char *name, VixHandle *snapshotHandle); typedef int VixRemoveSnapshotOptions; enum { VIX_SNAPSHOT_REMOVE_CHILDREN = 0x0001, }; VixHandle VixVM_RemoveSnapshot(VixHandle vmHandle, VixHandle snapshotHandle, VixRemoveSnapshotOptions options, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_RevertToSnapshot(VixHandle vmHandle, VixHandle snapshotHandle, VixVMPowerOpOptions options, VixHandle propertyListHandle, VixEventProc *callbackProc, void *clientData); typedef int VixCreateSnapshotOptions; enum { VIX_SNAPSHOT_INCLUDE_MEMORY = 0x0002, }; VixHandle VixVM_CreateSnapshot(VixHandle vmHandle, const char *name, const char *description, VixCreateSnapshotOptions options, VixHandle propertyListHandle, VixEventProc *callbackProc, void *clientData); /* * Shared Folders Functions */ /* * These are the flags describing each shared folder. */ typedef int VixMsgSharedFolderOptions; enum { VIX_SHAREDFOLDER_WRITE_ACCESS = 0x04, }; VixHandle VixVM_EnableSharedFolders(VixHandle vmHandle, Bool enabled, int options, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_GetNumSharedFolders(VixHandle vmHandle, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_GetSharedFolderState(VixHandle vmHandle, int index, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_SetSharedFolderState(VixHandle vmHandle, const char *shareName, const char *hostPathName, VixMsgSharedFolderOptions flags, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_AddSharedFolder(VixHandle vmHandle, const char *shareName, const char *hostPathName, VixMsgSharedFolderOptions flags, VixEventProc *callbackProc, void *clientData); VixHandle VixVM_RemoveSharedFolder(VixHandle vmHandle, const char *shareName, int flags, VixEventProc *callbackProc, void *clientData); /* * Screen Capture */ #ifndef VIX_HIDE_FROM_JAVA enum { VIX_CAPTURESCREENFORMAT_PNG = 0x01, VIX_CAPTURESCREENFORMAT_PNG_NOCOMPRESS = 0x02, }; VixHandle VixVM_CaptureScreenImage(VixHandle vmHandle, int captureType, VixHandle additionalProperties, VixEventProc *callbackProc, void *clientdata); #endif // VIX_HIDE_FROM_JAVA /* * VM Cloning -- */ typedef int VixCloneType; enum { VIX_CLONETYPE_FULL = 0, VIX_CLONETYPE_LINKED = 1, }; VixHandle VixVM_Clone(VixHandle vmHandle, VixHandle snapshotHandle, VixCloneType cloneType, const char *destConfigPathName, int options, VixHandle propertyListHandle, VixEventProc *callbackProc, void *clientData); /* * Misc Functions */ VixHandle VixVM_UpgradeVirtualHardware(VixHandle vmHandle, int options, VixEventProc *callbackProc, void *clientData); enum { VIX_INSTALLTOOLS_MOUNT_TOOLS_INSTALLER = 0x00, VIX_INSTALLTOOLS_AUTO_UPGRADE = 0x01, VIX_INSTALLTOOLS_RETURN_IMMEDIATELY = 0x02 }; VixHandle VixVM_InstallTools(VixHandle vmHandle, int options, const char *commandLineArgs, VixEventProc *callbackProc, void *clientData); /* *----------------------------------------------------------------------------- * * VIX Job -- * *----------------------------------------------------------------------------- */ /* * Synchronization functions * (used to detect when an asynch operation completes). */ VixError VixJob_Wait(VixHandle jobHandle, VixPropertyID firstPropertyID, ...); VixError VixJob_CheckCompletion(VixHandle jobHandle, Bool *complete); /* * Accessor functions * (used to get results of a completed asynch operation). */ VixError VixJob_GetError(VixHandle jobHandle); int VixJob_GetNumProperties(VixHandle jobHandle, int resultPropertyID); VixError VixJob_GetNthProperties(VixHandle jobHandle, int index, int propertyID, ...); /* *----------------------------------------------------------------------------- * * VIX Snapshot -- * *----------------------------------------------------------------------------- */ VixError VixSnapshot_GetNumChildren(VixHandle parentSnapshotHandle, int *numChildSnapshots); VixError VixSnapshot_GetChild(VixHandle parentSnapshotHandle, int index, VixHandle *childSnapshotHandle); VixError VixSnapshot_GetParent(VixHandle snapshotHandle, VixHandle *parentSnapshotHandle); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* _VIX_H_ */ open-vm-tools-9.4.0-1280544/lib/include/syncDriverIoc.h0000644765153500003110000000303412220061556020564 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * syncDriverIoc.h -- * * ioctl commands used by the sync driver on Unix systems. * * SYNC_IOC_FREEZE: Freezes the provided paths. * SYNC_IOC_THAW: Thaws frozen block devices after a FREEZE ioctl. * SYNC_IOC_QUERY: Returns the total number of frozen devices (not * specific to the fd used). */ #ifndef _SYNCDRIVERIOC_H_ #define _SYNCDRIVERIOC_H_ #ifdef linux # include # define SYNC_IOC_FREEZE _IOW(0xF5,0x01,const char *) # define SYNC_IOC_THAW _IO(0xF5,0x02) # define SYNC_IOC_QUERY _IOR(0xF5,0x03,int) #else # error "Driver not yet implemented for this OS." #endif #endif /* _SYNCDRIVERIOC_H_ */ open-vm-tools-9.4.0-1280544/lib/include/msgList.h0000644765153500003110000000422012220061556017421 0ustar dtormts/********************************************************* * Copyright (C) 2009-2011 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * msgList.h -- * * Utilities to manipulate (stateless) lists of messages. */ #ifndef _MSGLIST_H_ #define _MSGLIST_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #include #include #include "vm_basic_types.h" #include "msgid.h" #include "msgfmt.h" /* * Data structures, types, and constants */ typedef struct MsgList MsgList; struct MsgList { MsgList *next; char *id; char *format; MsgFmt_Arg *args; int numArgs; }; /* * Functions */ MsgList *MsgList_Create(const char *idFmt, ...) PRINTF_DECL(1, 2); MsgList *MsgList_VCreate(const char *idFmt, va_list args); MsgList *MsgList_CreateStr(const char *id); void MsgList_Append(MsgList **tail, const char *idFmt, ...) PRINTF_DECL(2, 3); void MsgList_VAppend(MsgList **tail, const char *idFmt, va_list args); void MsgList_AppendStr(MsgList **tail, const char *id); void MsgList_AppendMsgList(MsgList **tail, MsgList *messages); void MsgList_Log(const MsgList *messages); char *MsgList_ToString(const MsgList *messages); MsgList *MsgList_Copy(const MsgList *src); void MsgList_Free(MsgList *messages); const char *MsgList_GetMsgID(const MsgList *messages); Bool MsgList_Present(const MsgList *messages); #endif // ifndef _MSGLIST_H_ open-vm-tools-9.4.0-1280544/lib/include/guest_msg_def.h0000644765153500003110000000675512220061556020631 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * guest_msg_def.h -- * * Second layer of the internal communication channel between guest * applications and vmware * */ #ifndef _GUEST_MSG_DEF_H_ #define _GUEST_MSG_DEF_H_ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" /* Basic request types */ typedef enum { MESSAGE_TYPE_OPEN, MESSAGE_TYPE_SENDSIZE, MESSAGE_TYPE_SENDPAYLOAD, MESSAGE_TYPE_RECVSIZE, MESSAGE_TYPE_RECVPAYLOAD, MESSAGE_TYPE_RECVSTATUS, MESSAGE_TYPE_CLOSE, } MessageType; /* Reply statuses */ /* The basic request succeeded */ #define MESSAGE_STATUS_SUCCESS 0x0001 /* vmware has a message available for its party */ #define MESSAGE_STATUS_DORECV 0x0002 /* The channel has been closed */ #define MESSAGE_STATUS_CLOSED 0x0004 /* vmware removed the message before the party fetched it */ #define MESSAGE_STATUS_UNSENT 0x0008 /* A checkpoint occurred */ #define MESSAGE_STATUS_CPT 0x0010 /* An underlying device is powering off */ #define MESSAGE_STATUS_POWEROFF 0x0020 /* vmware has detected a timeout on the channel */ #define MESSAGE_STATUS_TIMEOUT 0x0040 /* vmware supports high-bandwidth for sending and receiving the payload */ #define MESSAGE_STATUS_HB 0x0080 /* * This mask defines the status bits that the guest is allowed to set; * we use this to mask out all other bits when receiving the status * from the guest. Otherwise, the guest can manipulate VMX state by * setting status bits that are only supposed to be changed by the * VMX. See bug 45385. */ #define MESSAGE_STATUS_GUEST_MASK MESSAGE_STATUS_SUCCESS /* * Max number of channels. * Unfortunately this has to be public because the monitor part * of the backdoor needs it for its trivial-case optimization. [greg] */ #define GUESTMSG_MAX_CHANNEL 8 /* Flags to open a channel. --hpreg */ #define GUESTMSG_FLAG_COOKIE 0x80000000 #define GUESTMSG_FLAG_ALL GUESTMSG_FLAG_COOKIE /* * Maximum size of incoming message. This is to prevent denial of host service * attacks from guest applications. */ #define GUESTMSG_MAX_IN_SIZE (64 * 1024) #endif /* _GUEST_MSG_DEF_H_ */ open-vm-tools-9.4.0-1280544/lib/include/loglevel_defs.h0000644765153500003110000000735512220061556020625 0ustar dtormts/********************************************************* * Copyright (C) 1998-2003 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _LOGLEVEL_DEFS_H_ #define _LOGLEVEL_DEFS_H_ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #ifndef LOGLEVEL_MODULE #error "loglevel_defs.h must be included with LOGLEVEL_MODULE defined" #endif #ifndef LOGLEVEL_EXTENSION #error "loglevel_defs.h must be included with LOGLEVEL_EXTENSION defined" #endif #include "vm_basic_types.h" #include "vm_basic_defs.h" /* * CPP variable name hacks */ #define LOGLEVEL_EXTOFFSET(ext) XCONC(_loglevel_offset_, ext) #define LOGLEVEL_EXTNAME(ext) XSTR(ext) #define LOGLEVEL_MODULEVAR(mod) XCONC(_loglevel_mod_, mod) /* * LogLevel declaration */ #define LOGLEVEL_EXTENSION_DECLARE(list) \ VMX86_EXTERN_DATA const int8 *logLevelPtr; \ VMX86_EXTERN_DATA int LOGLEVEL_EXTOFFSET(LOGLEVEL_EXTENSION); \ enum { list(LOGLEVEL_MODULEVAR) } #ifdef VMX86_LOG /* * Cross extension */ #define LOGLEVEL_BYEXTNAME(_ext, _mod) \ (*LogLevel_LookUpVar(XSTR(_ext), XSTR(_mod))) #define LOGLEVEL_BYEXTNAME_SET(_ext, _mod, _val) \ LogLevel_Set(XSTR(_ext), XSTR(_mod), _val) const int8 *LogLevel_LookUpVar(const char *extension, const char *module); int LogLevel_Set(const char *extension, const char *module, int val); #define DOLOG_BYEXTNAME(_ext, _mod, _min) \ UNLIKELY(LOGLEVEL_BYEXTNAME(_ext, _mod) >= (_min)) #define LOG_BYEXTNAME(_ext, _mod, _min, _log) \ (DOLOG_BYEXTNAME(_ext, _mod, _min) ? (Log _log) : (void) 0) /* * Intra extension */ #define LOGLEVEL_BYNAME(_mod) \ logLevelPtr[LOGLEVEL_EXTOFFSET(LOGLEVEL_EXTENSION) + \ LOGLEVEL_MODULEVAR(_mod)] #ifdef VMM #define LOGLEVEL_BYNAME_SET(_mod, _val) do { \ monitorLogLevels[LOGLEVEL_EXTOFFSET(LOGLEVEL_EXTENSION) + \ LOGLEVEL_MODULEVAR(_mod)] = _val; \ } while (0) #endif #define DOLOG_BYNAME(_mod, _min) \ UNLIKELY(LOGLEVEL_BYNAME(_mod) >= (_min)) #define LOG_BYNAME(_mod, _min, _log) \ (DOLOG_BYNAME(_mod, _min) ? (Log _log) : (void) 0) /* * Default */ #define LOGLEVEL() LOGLEVEL_BYNAME(LOGLEVEL_MODULE) #define DOLOG(_min) DOLOG_BYNAME(LOGLEVEL_MODULE, _min) #define LOG(_min, _log) LOG_BYNAME(LOGLEVEL_MODULE, _min, _log) #else /* VMX86_LOG */ #define LOGLEVEL_BYEXTNAME(_ext, _mod) 0 #define LOGLEVEL_BYEXTNAME_SET(_ext, _mod, _val) do {} while (0) #define DOLOG_BYEXTNAME(_ext, _mod, _min) (FALSE) #define LOG_BYEXTNAME(_ext, _mod, _min, _log) do {} while (0) #define LOGLEVEL_BYNAME(_mod) 0 #ifdef VMM #define LOGLEVEL_BYNAME_SET(_mod, _val) do {} while (0) #endif #define DOLOG_BYNAME(_mod, _min) (FALSE) #define LOG_BYNAME(_mod, _min, _log) do {} while (0) #define LOGLEVEL() 0 #define DOLOG(_min) (FALSE) #define LOG(_min, _log) #endif /* VMX86_LOG */ #ifdef VMX86_DEVEL #define LOG_DEVEL(_x) (Log _x) #else #define LOG_DEVEL(_x) #endif #endif /* _LOGLEVEL_DEFS_H_ */ open-vm-tools-9.4.0-1280544/lib/include/vm_basic_math.h0000644765153500003110000000422612220061556020601 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vm_basic_math.h -- * * Standard mathematical macros for VMware source code. */ #ifndef _VM_BASIC_MATH_H_ #define _VM_BASIC_MATH_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_VMKDRIVERS #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_DISTRIBUTE #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMIROM #include "includeCheck.h" #include "vm_basic_types.h" // For INLINE. #include "vm_basic_asm.h" // For Div64... static INLINE uint32 RatioOf(uint32 numer1, uint32 numer2, uint32 denom) { uint64 numer = (uint64)numer1 * numer2; /* Calculate "(numer1 * numer2) / denom" avoiding round-off errors. */ #if defined(VMM) || !(defined(__i386__) || defined(__x86_64__)) return numer / denom; #else uint32 ratio; uint32 unused; Div643232(numer, denom, &ratio, &unused); return ratio; #endif } static INLINE uint32 ExponentialAvg(uint32 avg, uint32 value, uint32 gainNumer, uint32 gainDenom) { uint32 term1 = gainNumer * avg; uint32 term2 = (gainDenom - gainNumer) * value; return (term1 + term2) / gainDenom; } static INLINE Bool IsPowerOfTwo(uint32 x) { /* Does not check for zero. Callers depend on this. */ return !(x & (x - 1)); } #endif // ifndef _VM_BASIC_MATH_H_ open-vm-tools-9.4.0-1280544/lib/include/uuid.h0000644765153500003110000000463312220061556016755 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * uuid.h -- * * UUID generation */ #ifndef _UUID_H_ #define _UUID_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #define UUID_SIZE 16 #define UUID_STRSIZE (2*UUID_SIZE + 1) #define UUID_MAXLEN 48 typedef enum { UUID_WITH_PATH = 0, UUID_RANDOM, UUID_VPX_BIOS, UUID_VPX_INSTANCE, UUID_UNKNOWN } UUIDStyle; Bool UUID_ConvertToBin(uint8 dest_id[UUID_SIZE], const char *text); char *UUID_ConvertToText(const uint8 id[UUID_SIZE]); #define UUID_CREATE_WS4 0 /* the "original", WS4 and earlier scheme */ #define UUID_CREATE_WS5 1 /* the WS5 scheme */ #define UUID_CREATE_WS6 2 /* the WS6 scheme - "native" path */ #define UUID_CREATE_ESX50 3 /* the scheme to allow location generated using host UUID with wrong endianness as reported by pre-ESX 5.0 U2. See PR 861271 for details. */ #define UUID_CREATE_WS65 4 /* the WS65 scheme - UTF-8 path */ #define UUID_CREATE_CURRENT 4 /* the current scheme - always the latest */ char *UUID_Create(const char *configFileFullPath, int schemeControl); char *UUID_CreateRandom(void); char *UUID_CreateRandomVpxStyle(uint8 vpxdId, UUIDStyle); Bool UUID_IsUUIDGeneratedByThatVpxd(const uint8 *id, int vpxdInstanceId); char *UUID_PackText(const char *text, char *pack, int packLen); char *UUID_ProperHostUUID(void); char *UUID_GetHostUUID(void); UUIDStyle UUID_GetStyle(const uint8 *id); /* like UUID_GetHostUUID, except gets actual host UUID */ char *UUID_GetRealHostUUID(void); #endif open-vm-tools-9.4.0-1280544/lib/include/cryptoError.h0000644765153500003110000000566612220061556020350 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * cryptoError.h -- * * Error code for cryptographic infrastructure library. */ #ifndef VMWARE_CRYPTOERROR_H #define VMWARE_CRYPTOERROR_H 1 #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #include "vmware.h" typedef int CryptoError; /* * This set of errors should not be expanded beyond a maximum value of 15 * without also updating the code for AIOMgr errors, which allots only 4 bits * for sub-error codes. * * Adding a lot of error codes to describe particular errors is a bad idea * anyhow, because it can be a security hole in itself; see, for example, the * SSL vulnerability described at . * It is best to distinguish only those types of errors that the caller can * legitimately use to figure out how to fix the problem and try again. */ #define CRYPTO_ERROR_SUCCESS ((CryptoError) 0) #define CRYPTO_ERROR_OPERATION_FAILED ((CryptoError) 1) #define CRYPTO_ERROR_UNKNOWN_ALGORITHM ((CryptoError) 2) #define CRYPTO_ERROR_BAD_BUFFER_SIZE ((CryptoError) 3) #define CRYPTO_ERROR_INVALID_OPERATION ((CryptoError) 4) #define CRYPTO_ERROR_NOMEM ((CryptoError) 5) #define CRYPTO_ERROR_NEED_PASSWORD ((CryptoError) 6) #define CRYPTO_ERROR_BAD_PASSWORD ((CryptoError) 7) #define CRYPTO_ERROR_IO_ERROR ((CryptoError) 8) #define CRYPTO_ERROR_UNKNOWN_ERROR ((CryptoError) 9) #define CRYPTO_ERROR_NAME_NOT_FOUND ((CryptoError) 10) #define CRYPTO_ERROR_NO_CRYPTO ((CryptoError) 11) #define CRYPTO_ERROR_LOCK_FAILURE ((CryptoError) 12) const char * CryptoError_ToString(CryptoError error); const char * CryptoError_ToMsgString(CryptoError error); static INLINE int CryptoError_ToInteger(CryptoError error) { return (int) error; } static INLINE CryptoError CryptoError_FromInteger(int index) { return (CryptoError) index; } static INLINE Bool CryptoError_IsSuccess(CryptoError error) { return (CRYPTO_ERROR_SUCCESS == error); } static INLINE Bool CryptoError_IsFailure(CryptoError error) { return (CRYPTO_ERROR_SUCCESS != error); } #endif /* cryptoError.h */ open-vm-tools-9.4.0-1280544/lib/include/hashTable.h0000644765153500003110000001243212220061556017676 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * hashTable.h -- * * Hash table. */ #ifndef _HASH_TABLE_H_ #define _HASH_TABLE_H_ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #include "vm_atomic.h" typedef struct HashTable HashTable; typedef struct PtrHashTable PtrHashTable; typedef void (*HashTableFreeEntryFn)(void *clientData); typedef int (*HashTableForEachCallback)(const char *key, void *value, void *clientData); #define HASH_STRING_KEY 0 // case-sensitive string key #define HASH_ISTRING_KEY 1 // case-insensitive string key #define HASH_INT_KEY 2 // uintptr_t or pointer key /* * The flag bits are ored into the type field. * Atomic hash tables only support insert, lookup, and replace. */ #define HASH_TYPE_MASK 7 #define HASH_FLAG_MASK (~HASH_TYPE_MASK) #define HASH_FLAG_ATOMIC 0x08 // thread-safe hash table #define HASH_FLAG_COPYKEY 0x10 // copy string key HashTable * HashTable_Alloc(uint32 numEntries, int keyType, HashTableFreeEntryFn fn); HashTable * HashTable_AllocOnce(Atomic_Ptr *var, uint32 numEntries, int keyType, HashTableFreeEntryFn fn); void HashTable_Free(HashTable *hashTable); void HashTable_FreeUnsafe(HashTable *hashTable); Bool HashTable_Insert(HashTable *hashTable, const void *keyStr, void *clientData); Bool HashTable_Lookup(HashTable *hashTable, const void *keyStr, void **clientData); void * HashTable_LookupOrInsert(HashTable *hashTable, const void *keyStr, void *clientData); Bool HashTable_ReplaceOrInsert(HashTable *hashTable, const void *keyStr, void *clientData); Bool HashTable_ReplaceIfEqual(HashTable *hashTable, const void *keyStr, void *oldClientData, void *newClientData); Bool HashTable_Delete(HashTable *hashTable, const void *keyStr); Bool HashTable_LookupAndDelete(HashTable *hashTable, const void *keyStr, void **clientData); void HashTable_Clear(HashTable *ht); void HashTable_ToArray(const HashTable *ht, void ***clientDatas, size_t *size); void HashTable_KeyArray(const HashTable *ht, const void ***keys, size_t *size); size_t HashTable_GetNumElements(const HashTable *ht); int HashTable_ForEach(const HashTable *ht, HashTableForEachCallback cb, void *clientData); /* * Specialize hash table that uses the callers data structure as its * hash entry as well, the hash key being an address that must be unique. */ typedef struct PtrHashEntry { struct PtrHashEntry *next; void *ptr; } PtrHashEntry; /* * PTRHASH_CONTAINER - get the struct for this entry (like PtrHashEntry) * @ptr: the &struct PtrHashEntry pointer. * @type: the type of the struct this is embedded in. * @member: the name of the list struct within the struct. */ #define PTRHASH_CONTAINER(ptr, type, member) \ ((type *)((char *)(ptr) - offsetof(type, member))) typedef int (*PtrHashForEachCallback)(PtrHashEntry *entry, const void *clientData); PtrHashTable *PtrHash_Alloc(uint32 numBuckets); void PtrHash_Free(PtrHashTable *hashTable); size_t PtrHash_AllocSize(PtrHashTable *ht); size_t PtrHash_GetNumElements(const PtrHashTable *ht); int PtrHash_ForEach(const PtrHashTable *ht, PtrHashForEachCallback cb, const void *clientData); PtrHashEntry *PtrHash_Lookup(const PtrHashTable *hashTable, const void *keyPtr); PtrHashEntry *PtrHash_LookupAndDelete(PtrHashTable *hashTable, const void *keyPtr); Bool PtrHash_Insert(PtrHashTable *hashTable, PtrHashEntry *entry); Bool PtrHash_Delete(PtrHashTable *hashTable, const void *keyPtr); #endif open-vm-tools-9.4.0-1280544/lib/include/dynxdr.h0000644765153500003110000000333412220061556017314 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _DYNXDR_H_ #define _DYNXDR_H_ /* * dynxdr.h -- * * Functions for creating and destroying an XDR stream that is backed * by a dynamic memory buffer. Uses DynBuf, so requires code using it to * link lib/misc. * * This stream only does encoding. For decoding, we generally have data * already available in the form of a pre-allocated buffer, in which * case we can use the xdrmem_create() function. * * Note: xdr_destroy() is a no-op for this stream. Use DynXdr_Destroy() * instead. Also, XDR_SETPOS and XDR_INLINE are not supported. */ #include #include #include "vm_basic_types.h" XDR *DynXdr_Create(XDR *in); Bool DynXdr_AppendRaw(XDR *xdrs, const void *buf, size_t len); void *DynXdr_AllocGet(XDR *xdrs); void *DynXdr_Get(XDR *xdrs); void DynXdr_Destroy(XDR *xdrs, Bool release); #endif /* _DYNXDR_H_ */ open-vm-tools-9.4.0-1280544/lib/include/impersonate.h0000644765153500003110000000317512220061556020335 0ustar dtormts/********************************************************* * Copyright (C) 2003 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * impersonate.h -- * * Provides functions to assist in impersonating and unimpersonating * as a given user. */ #ifndef _IMPERSONATE_H_ #define _IMPERSONATE_H_ #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #include "auth.h" extern void Impersonate_Init(void); extern Bool Impersonate_Owner(const char *file); extern Bool Impersonate_Do(const char *user, AuthToken token); extern Bool Impersonate_Undo(void); extern char *Impersonate_Who(void); extern Bool Impersonate_ForceRoot(void); extern Bool Impersonate_UnforceRoot(void); extern Bool Impersonate_Runas(const char *cfg, const char *caller, AuthToken callerToken); #ifdef _WIN32 extern Bool Impersonate_CfgRunasOnly(const char *cfg); #endif #endif // ifndef _IMPERSONATE_H_ open-vm-tools-9.4.0-1280544/lib/include/vm_atomic.h0000644765153500003110000021500512220061556017762 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vm_atomic.h -- * * Atomic power * * Note: Only partially tested on ARM processors: Works for View Open * Client, which shouldn't have threads. * * In ARM, GCC intrinsics (__sync*) compile but might not * work, while MS intrinsics (_Interlocked*) do not compile, * and ARM has no equivalent to the "lock" instruction prior to * ARMv6; the current ARM target is ARMv5. According to glibc * documentation, ARMv5 cannot have atomic code in user space. * Instead a Linux system call to kernel code referenced in * entry-armv.S is used to achieve atomic functions. See bug * 478054 for details. */ #ifndef _ATOMIC_H_ #define _ATOMIC_H_ //#define FAKE_ATOMIC /* defined if true atomic not needed */ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMKDRIVERS #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_DISTRIBUTE #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMIROM #include "includeCheck.h" #include "vm_basic_types.h" /* Basic atomic type: 32 bits */ typedef struct Atomic_uint32 { volatile uint32 value; } Atomic_uint32; /* Basic atomic type: 64 bits */ typedef struct Atomic_uint64 { volatile uint64 value; } Atomic_uint64 ALIGNED(8); /* * Prototypes for msft atomics. These are defined & inlined by the * compiler so no function definition is needed. The prototypes are * needed for c++. Since amd64 compiler doesn't support inline asm we * have to use these. Unfortunately, we still have to use some inline asm * for the 32 bit code since the and/or/xor implementations didn't show up * untill xp or 2k3. * * The declarations for the intrinsic functions were taken from ntddk.h * in the DDK. The declarations must match otherwise the 64-bit c++ * compiler will complain about second linkage of the intrinsic functions. * We define the intrinsic using the basic types corresponding to the * Windows typedefs. This avoids having to include windows header files * to get to the windows types. */ #if defined(_MSC_VER) && _MSC_VER >= 1310 #ifdef __cplusplus extern "C" { #endif long _InterlockedExchange(long volatile*, long); long _InterlockedCompareExchange(long volatile*, long, long); long _InterlockedExchangeAdd(long volatile*, long); long _InterlockedDecrement(long volatile*); long _InterlockedIncrement(long volatile*); void _ReadWriteBarrier(void); #pragma intrinsic(_InterlockedExchange, _InterlockedCompareExchange) #pragma intrinsic(_InterlockedExchangeAdd, _InterlockedDecrement) #pragma intrinsic(_InterlockedIncrement, _ReadWriteBarrier) #if defined(VM_X86_64) long _InterlockedAnd(long volatile*, long); __int64 _InterlockedAnd64(__int64 volatile*, __int64); long _InterlockedOr(long volatile*, long); __int64 _InterlockedOr64(__int64 volatile*, __int64); long _InterlockedXor(long volatile*, long); __int64 _InterlockedXor64(__int64 volatile*, __int64); __int64 _InterlockedExchangeAdd64(__int64 volatile*, __int64); __int64 _InterlockedIncrement64(__int64 volatile*); __int64 _InterlockedDecrement64(__int64 volatile*); __int64 _InterlockedExchange64(__int64 volatile*, __int64); __int64 _InterlockedCompareExchange64(__int64 volatile*, __int64, __int64); #if !defined(_WIN64) #pragma intrinsic(_InterlockedAnd, _InterlockedAnd64) #pragma intrinsic(_InterlockedOr, _InterlockedOr64) #pragma intrinsic(_InterlockedXor, _InterlockedXor64) #pragma intrinsic(_InterlockedExchangeAdd64, _InterlockedIncrement64) #pragma intrinsic(_InterlockedDecrement64, _InterlockedExchange64) #pragma intrinsic(_InterlockedCompareExchange64) #endif /* !_WIN64 */ #endif /* __x86_64__ */ #ifdef __cplusplus } #endif #endif /* _MSC_VER */ #if defined(__arm__) && !defined(FAKE_ATOMIC) /* * LDREX without STREX or CLREX may cause problems in environments where the * context switch may not clear the reference monitor - according ARM manual * the reference monitor should be cleared after a context switch, but some * may not like Linux kernel's non-preemptive context switch path. So use of * ARM routines in kernel code may not be safe. */ # if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \ defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__) # define VM_ARM_V7 # ifdef __KERNEL__ # warning LDREX/STREX may not be safe in linux kernel, since it \ does not issue CLREX on context switch (as of 2011-09-29). # endif # else # error Only ARMv7 extends the synchronization primitives ldrex/strex. \ For the lower ARM version, please implement the atomic functions \ by kernel APIs. # endif #endif /* Data Memory Barrier */ #ifdef VM_ARM_V7 #define dmb() __asm__ __volatile__("dmb" : : : "memory") #endif /* Convert a volatile uint32 to Atomic_uint32. */ static INLINE Atomic_uint32 * Atomic_VolatileToAtomic(volatile uint32 *var) { return (Atomic_uint32 *)var; } /* Convert a volatile uint64 to Atomic_uint64. */ static INLINE Atomic_uint64 * Atomic_VolatileToAtomic64(volatile uint64 *var) { return (Atomic_uint64 *)var; } /* *----------------------------------------------------------------------------- * * Atomic_Init, Atomic_SetFence, AtomicUseFence -- * * Determine whether an lfence intruction is executed after * every locked instruction. * * Certain AMD processors have a bug (see bug 107024) that * requires an lfence after every locked instruction. * * The global variable AtomicUseFence controls whether lfence * is used (see AtomicEpilogue). * * Atomic_SetFence sets AtomicUseFence to the given value. * * Atomic_Init computes and sets AtomicUseFence for x86. * It does not take into account the number of processors. * * The rationale for all this complexity is that Atomic_Init * is the easy-to-use interface. It can be called a number * of times cheaply, and does not depend on other libraries. * However, because the number of CPUs is difficult to compute, * it does without it and always assumes there are more than one. * * For programs that care or have special requirements, * Atomic_SetFence can be called directly, in addition to Atomic_Init. * It overrides the effect of Atomic_Init, and can be called * before, after, or between calls to Atomic_Init. * *----------------------------------------------------------------------------- */ // The freebsd assembler doesn't know the lfence instruction #if defined(__GNUC__) && \ __GNUC__ >= 3 && \ (defined(__VMKERNEL__) || !defined(__FreeBSD__)) && \ (!defined(MODULE) || defined(__VMKERNEL_MODULE__)) && \ !defined(__APPLE__) && \ (defined(__i386__) || defined(__x86_64__)) /* PR136775 */ #define ATOMIC_USE_FENCE #endif #if defined(VMATOMIC_IMPORT_DLLDATA) VMX86_EXTERN_DATA Bool AtomicUseFence; #else EXTERN Bool AtomicUseFence; #endif EXTERN Bool atomicFenceInitialized; void AtomicInitFence(void); static INLINE void Atomic_Init(void) { #ifdef ATOMIC_USE_FENCE if (!atomicFenceInitialized) { AtomicInitFence(); } #endif } static INLINE void Atomic_SetFence(Bool fenceAfterLock) /* IN: TRUE to enable lfence */ /* FALSE to disable. */ { AtomicUseFence = fenceAfterLock; #if defined(__VMKERNEL__) extern void Atomic_SetFenceVMKAPI(Bool fenceAfterLock); Atomic_SetFenceVMKAPI(fenceAfterLock); #endif atomicFenceInitialized = TRUE; } /* Conditionally execute fence after interlocked instruction. */ static INLINE void AtomicEpilogue(void) { #ifdef ATOMIC_USE_FENCE #ifdef VMM /* The monitor conditionally patches out the lfence when not needed.*/ /* Construct a MonitorPatchTextEntry in the .patchtext section. */ asm volatile ("1:\n\t" "lfence\n\t" "2:\n\t" ".pushsection .patchtext\n\t" ".quad 1b\n\t" ".quad 2b\n\t" ".popsection\n\t" ::: "memory"); #else if (UNLIKELY(AtomicUseFence)) { asm volatile ("lfence" ::: "memory"); } #endif #endif } /* * All the assembly code is tricky and written conservatively. * For example, to make sure gcc won't introduce copies, * we force the addressing mode like this: * * "xchgl %0, (%1)" * : "=r" (val) * : "r" (&var->value), * "0" (val) * : "memory" * * - edward * * Actually - turns out that gcc never generates memory aliases (it * still does generate register aliases though), so we can be a bit * more agressive with the memory constraints. The code above can be * modified like this: * * "xchgl %0, %1" * : "=r" (val), * "=m" (var->value), * : "0" (val), * "1" (var->value) * * The advantages are that gcc can use whatever addressing mode it * likes to access the memory value, and that we dont have to use a * way-too-generic "memory" clobber as there is now an explicit * declaration that var->value is modified. * * see also /usr/include/asm/atomic.h to convince yourself this is a * valid optimization. * * - walken */ /* *----------------------------------------------------------------------------- * * Atomic_Read -- * * Read * * Results: * The value of the atomic variable. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE uint32 Atomic_Read(Atomic_uint32 const *var) // IN { return var->value; } #define Atomic_Read32 Atomic_Read /* *----------------------------------------------------------------------------- * * Atomic_Write -- * * Write * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE void Atomic_Write(Atomic_uint32 *var, // IN uint32 val) // IN { var->value = val; } #define Atomic_Write32 Atomic_Write /* *----------------------------------------------------------------------------- * * Atomic_ReadWrite -- * * Read followed by write * * Results: * The value of the atomic variable before the write. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE uint32 Atomic_ReadWrite(Atomic_uint32 *var, // IN uint32 val) // IN { #ifdef FAKE_ATOMIC uint32 retval = var->value; var->value = val; return retval; #elif defined(__GNUC__) #ifdef VM_ARM_V7 register volatile uint32 retVal; register volatile uint32 res; dmb(); __asm__ __volatile__( "1: ldrex %[retVal], [%[var]] \n\t" "strex %[res], %[val], [%[var]] \n\t" "teq %[res], #0 \n\t" "bne 1b" : [retVal] "=&r" (retVal), [res] "=&r" (res) : [var] "r" (&var->value), [val] "r" (val) : "cc" ); dmb(); return retVal; #else // __VM_ARM_V7 (assume x86*) /* Checked against the Intel manual and GCC --walken */ __asm__ __volatile__( "xchgl %0, %1" : "=r" (val), "+m" (var->value) : "0" (val) ); AtomicEpilogue(); return val; #endif // VM_ARM_V7 #elif defined _MSC_VER #if _MSC_VER >= 1310 return _InterlockedExchange((long *)&var->value, (long)val); #else #pragma warning(push) #pragma warning(disable : 4035) // disable no-return warning { __asm mov eax, val __asm mov ebx, var __asm xchg [ebx]Atomic_uint32.value, eax // eax is the return value, this is documented to work - edward } #pragma warning(pop) #endif // _MSC_VER >= 1310 #else #error No compiler defined for Atomic_ReadWrite #endif // __GNUC__ } #define Atomic_ReadWrite32 Atomic_ReadWrite /* *----------------------------------------------------------------------------- * * Atomic_ReadIfEqualWrite -- * * Compare exchange: Read variable, if equal to oldVal, write newVal * * Results: * The value of the atomic variable before the write. * * Side effects: * The variable may be modified. * *----------------------------------------------------------------------------- */ static INLINE uint32 Atomic_ReadIfEqualWrite(Atomic_uint32 *var, // IN uint32 oldVal, // IN uint32 newVal) // IN { #ifdef FAKE_ATOMIC uint32 readVal = var->value; if (oldVal == readVal) { var->value = newVal; } return oldVal; #elif defined(__GNUC__) #ifdef VM_ARM_V7 register uint32 retVal; register uint32 res; dmb(); __asm__ __volatile__( "1: ldrex %[retVal], [%[var]] \n\t" "mov %[res], #0 \n\t" "teq %[retVal], %[oldVal] \n\t" "strexeq %[res], %[newVal], [%[var]] \n\t" "teq %[res], #0 \n\t" "bne 1b" : [retVal] "=&r" (retVal), [res] "=&r" (res) : [var] "r" (&var->value), [oldVal] "r" (oldVal), [newVal] "r" (newVal) : "cc" ); dmb(); return retVal; #else // VM_ARM_V7 (assume x86*) uint32 val; /* Checked against the Intel manual and GCC --walken */ __asm__ __volatile__( "lock; cmpxchgl %2, %1" : "=a" (val), "+m" (var->value) : "r" (newVal), "0" (oldVal) : "cc" ); AtomicEpilogue(); return val; #endif // VM_ARM_V7 #elif defined _MSC_VER #if _MSC_VER >= 1310 return _InterlockedCompareExchange((long *)&var->value, (long)newVal, (long)oldVal); #else #pragma warning(push) #pragma warning(disable : 4035) // disable no-return warning { __asm mov eax, oldVal __asm mov ebx, var __asm mov ecx, newVal __asm lock cmpxchg [ebx]Atomic_uint32.value, ecx // eax is the return value, this is documented to work - edward } #pragma warning(pop) #endif #else #error No compiler defined for Atomic_ReadIfEqualWrite #endif } #define Atomic_ReadIfEqualWrite32 Atomic_ReadIfEqualWrite #if defined(__x86_64__) || defined(VM_ARM_V7) /* *----------------------------------------------------------------------------- * * Atomic_ReadIfEqualWrite64 -- * * Compare exchange: Read variable, if equal to oldVal, write newVal * * Results: * The value of the atomic variable before the write. * * Side effects: * The variable may be modified. * *----------------------------------------------------------------------------- */ static INLINE uint64 Atomic_ReadIfEqualWrite64(Atomic_uint64 *var, // IN uint64 oldVal, // IN uint64 newVal) // IN { #if defined(__GNUC__) #ifdef VM_ARM_V7 register uint64 retVal; register uint32 res; dmb(); __asm__ __volatile__( "1: ldrexd %[retVal], %H[retVal], [%[var]] \n\t" "mov %[res], #0 \n\t" "teq %[retVal], %[oldVal] \n\t" "teqeq %H[retVal], %H[oldVal] \n\t" "strexdeq %[res], %[newVal], %H[newVal], [%[var]] \n\t" "teq %[res], #0 \n\t" "bne 1b" : [retVal] "=&r" (retVal), [res] "=&r" (res) : [var] "r" (&var->value), [oldVal] "r" (oldVal), [newVal] "r" (newVal) : "cc" ); dmb(); return retVal; #else // VM_ARM_V7 (assume x86*) uint64 val; /* Checked against the AMD manual and GCC --hpreg */ __asm__ __volatile__( "lock; cmpxchgq %2, %1" : "=a" (val), "+m" (var->value) : "r" (newVal), "0" (oldVal) : "cc" ); AtomicEpilogue(); return val; #endif //VM_ARM_V7 #elif defined _MSC_VER return _InterlockedCompareExchange64((__int64 *)&var->value, (__int64)newVal, (__int64)oldVal); #else #error No compiler defined for Atomic_ReadIfEqualWrite64 #endif } #endif /* *----------------------------------------------------------------------------- * * Atomic_And -- * * Atomic read, bitwise AND with a value, write. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void Atomic_And(Atomic_uint32 *var, // IN uint32 val) // IN { #ifdef FAKE_ATOMIC var->value &= val; #elif defined(__GNUC__) #ifdef VM_ARM_V7 register volatile uint32 res; register volatile uint32 tmp; dmb(); __asm__ __volatile__( "1: ldrex %[tmp], [%[var]] \n\t" "and %[tmp], %[tmp], %[val] \n\t" "strex %[res], %[tmp], [%[var]] \n\t" "teq %[res], #0 \n\t" "bne 1b" : [res] "=&r" (res), [tmp] "=&r" (tmp) : [var] "r" (&var->value), [val] "r" (val) : "cc" ); dmb(); #else /* VM_ARM_V7 */ /* Checked against the Intel manual and GCC --walken */ __asm__ __volatile__( "lock; andl %1, %0" : "+m" (var->value) : "ri" (val) : "cc" ); AtomicEpilogue(); #endif // VM_ARM_V7 #elif defined _MSC_VER #if defined(__x86_64__) _InterlockedAnd((long *)&var->value, (long)val); #else __asm mov eax, val __asm mov ebx, var __asm lock and [ebx]Atomic_uint32.value, eax #endif #else #error No compiler defined for Atomic_And #endif } #define Atomic_And32 Atomic_And /* *----------------------------------------------------------------------------- * * Atomic_Or -- * * Atomic read, bitwise OR with a value, write. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void Atomic_Or(Atomic_uint32 *var, // IN uint32 val) // IN { #ifdef FAKE_ATOMIC var->value |= val; #elif defined(__GNUC__) #ifdef VM_ARM_V7 register volatile uint32 res; register volatile uint32 tmp; dmb(); __asm__ __volatile__( "1: ldrex %[tmp], [%[var]] \n\t" "orr %[tmp], %[tmp], %[val] \n\t" "strex %[res], %[tmp], [%[var]] \n\t" "teq %[res], #0 \n\t" "bne 1b" : [res] "=&r" (res), [tmp] "=&r" (tmp) : [var] "r" (&var->value), [val] "r" (val) : "cc" ); dmb(); #else // VM_ARM_V7 /* Checked against the Intel manual and GCC --walken */ __asm__ __volatile__( "lock; orl %1, %0" : "+m" (var->value) : "ri" (val) : "cc" ); AtomicEpilogue(); #endif // VM_ARM_V7 #elif defined _MSC_VER #if defined(__x86_64__) _InterlockedOr((long *)&var->value, (long)val); #else __asm mov eax, val __asm mov ebx, var __asm lock or [ebx]Atomic_uint32.value, eax #endif #else #error No compiler defined for Atomic_Or #endif } #define Atomic_Or32 Atomic_Or /* *----------------------------------------------------------------------------- * * Atomic_Xor -- * * Atomic read, bitwise XOR with a value, write. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void Atomic_Xor(Atomic_uint32 *var, // IN uint32 val) // IN { #ifdef FAKE_ATOMIC var->value ^= val; #elif defined(__GNUC__) #ifdef VM_ARM_V7 register volatile uint32 res; register volatile uint32 tmp; dmb(); __asm__ __volatile__( "1: ldrex %[tmp], [%[var]] \n\t" "eor %[tmp], %[tmp], %[val] \n\t" "strex %[res], %[tmp], [%[var]] \n\t" "teq %[res], #0 \n\t" "bne 1b" : [res] "=&r" (res), [tmp] "=&r" (tmp) : [var] "r" (&var->value), [val] "r" (val) : "cc" ); dmb(); #else // VM_ARM_V7 /* Checked against the Intel manual and GCC --walken */ __asm__ __volatile__( "lock; xorl %1, %0" : "+m" (var->value) : "ri" (val) : "cc" ); AtomicEpilogue(); #endif // VM_ARM_V7 #elif defined _MSC_VER #if defined(__x86_64__) _InterlockedXor((long *)&var->value, (long)val); #else __asm mov eax, val __asm mov ebx, var __asm lock xor [ebx]Atomic_uint32.value, eax #endif #else #error No compiler defined for Atomic_Xor #endif } #define Atomic_Xor32 Atomic_Xor #if defined(__x86_64__) /* *----------------------------------------------------------------------------- * * Atomic_Xor64 -- * * Atomic read, bitwise XOR with a value, write. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void Atomic_Xor64(Atomic_uint64 *var, // IN uint64 val) // IN { #if defined(__GNUC__) /* Checked against the AMD manual and GCC --hpreg */ __asm__ __volatile__( "lock; xorq %1, %0" : "+m" (var->value) : "ri" (val) : "cc" ); AtomicEpilogue(); #elif defined _MSC_VER _InterlockedXor64((__int64 *)&var->value, (__int64)val); #else #error No compiler defined for Atomic_Xor64 #endif } #endif /* *----------------------------------------------------------------------------- * * Atomic_Add -- * * Atomic read, add a value, write. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void Atomic_Add(Atomic_uint32 *var, // IN uint32 val) // IN { #ifdef FAKE_ATOMIC var->value += val; #elif defined(__GNUC__) #ifdef VM_ARM_V7 register volatile uint32 res; register volatile uint32 tmp; dmb(); __asm__ __volatile__( "1: ldrex %[tmp], [%[var]] \n\t" "add %[tmp], %[tmp], %[val] \n\t" "strex %[res], %[tmp], [%[var]] \n\t" "teq %[res], #0 \n\t" "bne 1b" : [res] "=&r" (res), [tmp] "=&r" (tmp) : [var] "r" (&var->value), [val] "r" (val) : "cc" ); dmb(); #else // VM_ARM_V7 /* Checked against the Intel manual and GCC --walken */ __asm__ __volatile__( "lock; addl %1, %0" : "+m" (var->value) : "ri" (val) : "cc" ); AtomicEpilogue(); #endif // VM_ARM_V7 #elif defined _MSC_VER #if _MSC_VER >= 1310 _InterlockedExchangeAdd((long *)&var->value, (long)val); #else __asm mov eax, val __asm mov ebx, var __asm lock add [ebx]Atomic_uint32.value, eax #endif #else #error No compiler defined for Atomic_Add #endif } #define Atomic_Add32 Atomic_Add #if defined(__x86_64__) /* *----------------------------------------------------------------------------- * * Atomic_Add64 -- * * Atomic read, add a value, write. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void Atomic_Add64(Atomic_uint64 *var, // IN uint64 val) // IN { #if defined(__GNUC__) /* Checked against the AMD manual and GCC --hpreg */ __asm__ __volatile__( "lock; addq %1, %0" : "+m" (var->value) : "ri" (val) : "cc" ); AtomicEpilogue(); #elif defined _MSC_VER _InterlockedExchangeAdd64((__int64 *)&var->value, (__int64)val); #else #error No compiler defined for Atomic_Add64 #endif } #endif /* *----------------------------------------------------------------------------- * * Atomic_Sub -- * * Atomic read, subtract a value, write. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void Atomic_Sub(Atomic_uint32 *var, // IN uint32 val) // IN { #ifdef FAKE_ATOMIC var->value -= val; #elif defined(__GNUC__) #ifdef VM_ARM_V7 register volatile uint32 res; register volatile uint32 tmp; dmb(); __asm__ __volatile__( "1: ldrex %[tmp], [%[var]] \n\t" "sub %[tmp], %[tmp], %[val] \n\t" "strex %[res], %[tmp], [%[var]] \n\t" "teq %[res], #0 \n\t" "bne 1b" : [res] "=&r" (res), [tmp] "=&r" (tmp) : [var] "r" (&var->value), [val] "r" (val) : "cc" ); dmb(); #else // VM_ARM_V7 /* Checked against the Intel manual and GCC --walken */ __asm__ __volatile__( "lock; subl %1, %0" : "+m" (var->value) : "ri" (val) : "cc" ); AtomicEpilogue(); #endif // VM_ARM_V7 #elif defined _MSC_VER #if _MSC_VER >= 1310 _InterlockedExchangeAdd((long *)&var->value, (long)-val); #else __asm mov eax, val __asm mov ebx, var __asm lock sub [ebx]Atomic_uint32.value, eax #endif #else #error No compiler defined for Atomic_Sub #endif } #define Atomic_Sub32 Atomic_Sub #if defined(__x86_64__) /* *----------------------------------------------------------------------------- * * Atomic_Sub64 -- * * Atomic read, subtract a value, write. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void Atomic_Sub64(Atomic_uint64 *var, // IN uint64 val) // IN { #ifdef __GNUC__ /* Checked against the AMD manual and GCC --hpreg */ __asm__ __volatile__( "lock; subq %1, %0" : "+m" (var->value) : "ri" (val) : "cc" ); AtomicEpilogue(); #elif defined _MSC_VER _InterlockedExchangeAdd64((__int64 *)&var->value, (__int64)-val); #else #error No compiler defined for Atomic_Sub64 #endif } #endif /* *----------------------------------------------------------------------------- * * Atomic_Inc -- * * Atomic read, increment, write. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void Atomic_Inc(Atomic_uint32 *var) // IN { #ifdef __GNUC__ #if defined(VM_ARM_V7) || defined(FAKE_ATOMIC) Atomic_Add(var, 1); #else // VM_ARM_V7 /* Checked against the Intel manual and GCC --walken */ __asm__ __volatile__( "lock; incl %0" : "+m" (var->value) : : "cc" ); AtomicEpilogue(); #endif // VM_ARM_V7 #elif defined _MSC_VER #if _MSC_VER >= 1310 _InterlockedIncrement((long *)&var->value); #else __asm mov ebx, var __asm lock inc [ebx]Atomic_uint32.value #endif #else #error No compiler defined for Atomic_Inc #endif } #define Atomic_Inc32 Atomic_Inc /* *----------------------------------------------------------------------------- * * Atomic_Dec -- * * Atomic read, decrement, write. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void Atomic_Dec(Atomic_uint32 *var) // IN { #ifdef __GNUC__ #if defined(VM_ARM_V7) || defined(FAKE_ATOMIC) Atomic_Sub(var, 1); #else // VM_ARM_V7 /* Checked against the Intel manual and GCC --walken */ __asm__ __volatile__( "lock; decl %0" : "+m" (var->value) : : "cc" ); AtomicEpilogue(); #endif // VM_ARM_V7 #elif defined _MSC_VER #if _MSC_VER >= 1310 _InterlockedDecrement((long *)&var->value); #else __asm mov ebx, var __asm lock dec [ebx]Atomic_uint32.value #endif #else #error No compiler defined for Atomic_Dec #endif } #define Atomic_Dec32 Atomic_Dec /* * Note that the technique below can be used to implement ReadX(), where X is * an arbitrary mathematical function. */ /* *----------------------------------------------------------------------------- * * Atomic_FetchAndOr -- * * Atomic read (returned), bitwise OR with a value, write. * * Results: * The value of the variable before the operation. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE uint32 Atomic_FetchAndOr(Atomic_uint32 *var, // IN uint32 val) // IN { uint32 res; do { res = Atomic_Read(var); } while (res != Atomic_ReadIfEqualWrite(var, res, res | val)); return res; } /* *----------------------------------------------------------------------------- * * Atomic_FetchAndAnd -- * * Atomic read (returned), bitwise And with a value, write. * * Results: * The value of the variable before the operation. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE uint32 Atomic_FetchAndAnd(Atomic_uint32 *var, // IN uint32 val) // IN { uint32 res; do { res = Atomic_Read(var); } while (res != Atomic_ReadIfEqualWrite(var, res, res & val)); return res; } #define Atomic_ReadOr32 Atomic_FetchAndOr #if defined(__x86_64__) /* *----------------------------------------------------------------------------- * * Atomic_ReadOr64 -- * * Atomic read (returned), bitwise OR with a value, write. * * Results: * The value of the variable before the operation. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE uint64 Atomic_ReadOr64(Atomic_uint64 *var, // IN uint64 val) // IN { uint64 res; do { res = var->value; } while (res != Atomic_ReadIfEqualWrite64(var, res, res | val)); return res; } /* *----------------------------------------------------------------------------- * * Atomic_ReadAnd64 -- * * Atomic read (returned), bitwise AND with a value, write. * * Results: * The value of the variable before the operation. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE uint64 Atomic_ReadAnd64(Atomic_uint64 *var, // IN uint64 val) // IN { uint64 res; do { res = var->value; } while (res != Atomic_ReadIfEqualWrite64(var, res, res & val)); return res; } #endif // __x86_64__ /* *----------------------------------------------------------------------------- * * Atomic_FetchAndAddUnfenced -- * * Atomic read (returned), add a value, write. * * If you have to implement FetchAndAdd() on an architecture other than * x86 or x86-64, you might want to consider doing something similar to * Atomic_FetchAndOr(). * * The "Unfenced" version of Atomic_FetchAndInc never executes * "lfence" after the interlocked operation. * * Results: * The value of the variable before the operation. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE uint32 Atomic_FetchAndAddUnfenced(Atomic_uint32 *var, // IN uint32 val) // IN { #ifdef FAKE_ATOMIC uint32 res = var->value; var->value = res + val; return res; #elif defined(__GNUC__) #ifdef VM_ARM_V7 register volatile uint32 res; register volatile uint32 retVal; register volatile uint32 tmp; dmb(); __asm__ __volatile__( "1: ldrex %[retVal], [%[var]] \n\t" "add %[tmp], %[val], %[retVal] \n\t" "strex %[res], %[tmp], [%[var]] \n\t" "teq %[res], #0 \n\t" "bne 1b" : [tmp] "=&r" (tmp), [res] "=&r" (res), [retVal] "=&r" (retVal) : [var] "r" (&var->value), [val] "r" (val) : "cc" ); dmb(); return retVal; #else // VM_ARM_V7 /* Checked against the Intel manual and GCC --walken */ __asm__ __volatile__( "lock; xaddl %0, %1" : "=r" (val), "+m" (var->value) : "0" (val) : "cc" ); return val; #endif // VM_ARM_V7 #elif defined _MSC_VER #if _MSC_VER >= 1310 return _InterlockedExchangeAdd((long *)&var->value, (long)val); #else #pragma warning(push) #pragma warning(disable : 4035) // disable no-return warning { __asm mov eax, val __asm mov ebx, var __asm lock xadd [ebx]Atomic_uint32.value, eax } #pragma warning(pop) #endif #else #error No compiler defined for Atomic_FetchAndAdd #endif } #define Atomic_ReadAdd32 Atomic_FetchAndAdd /* *----------------------------------------------------------------------------- * * Atomic_FetchAndAdd -- * * Atomic read (returned), add a value, write. * * If you have to implement FetchAndAdd() on an architecture other than * x86 or x86-64, you might want to consider doing something similar to * Atomic_FetchAndOr(). * * Unlike "Unfenced" version, this one may execute the "lfence" after * interlocked operation. * * Results: * The value of the variable before the operation. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE uint32 Atomic_FetchAndAdd(Atomic_uint32 *var, // IN uint32 val) // IN { #if defined(__GNUC__) && !defined(VM_ARM_V7) && !defined(FAKE_ATOMIC) val = Atomic_FetchAndAddUnfenced(var, val); AtomicEpilogue(); return val; #else return Atomic_FetchAndAddUnfenced(var, val); #endif } #if defined(__x86_64__) /* *----------------------------------------------------------------------------- * * Atomic_ReadAdd64 -- * * Atomic read (returned), add a value, write. * * Results: * The value of the variable before the operation. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE uint64 Atomic_ReadAdd64(Atomic_uint64 *var, // IN uint64 val) // IN { #if defined(__GNUC__) /* Checked against the AMD manual and GCC --hpreg */ __asm__ __volatile__( "lock; xaddq %0, %1" : "=r" (val), "+m" (var->value) : "0" (val) : "cc" ); AtomicEpilogue(); return val; #elif defined _MSC_VER return _InterlockedExchangeAdd64((__int64 *)&var->value, (__int64)val); #else #error No compiler defined for Atomic_ReadAdd64 #endif } /* *----------------------------------------------------------------------------- * * Atomic_ReadSub64 -- * * Atomic read (returned), sub a value, write. * * Results: * The value of the variable before the operation. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE uint64 Atomic_ReadSub64(Atomic_uint64 *var, // IN uint64 val) // IN { // Do an sub by an add and a overflow return Atomic_ReadAdd64(var, -val); } #endif /* *----------------------------------------------------------------------------- * * Atomic_FetchAndInc -- * * Atomic read (returned), increment, write. * * Results: * The value of the variable before the operation. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE uint32 Atomic_FetchAndInc(Atomic_uint32 *var) // IN { return Atomic_FetchAndAdd(var, 1); } #define Atomic_ReadInc32 Atomic_FetchAndInc #if defined(__x86_64__) /* *----------------------------------------------------------------------------- * * Atomic_ReadInc64 -- * * Atomic read (returned), increment, write. * * Results: * The value of the variable before the operation. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE uint64 Atomic_ReadInc64(Atomic_uint64 *var) // IN { return Atomic_ReadAdd64(var, 1); } #endif /* *----------------------------------------------------------------------------- * * Atomic_FetchAndDec -- * * Atomic read (returned), decrement, write. * * Results: * The value of the variable before the operation. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE uint32 Atomic_FetchAndDec(Atomic_uint32 *var) // IN { return Atomic_FetchAndAdd(var, (uint32)-1); } #define Atomic_ReadDec32 Atomic_FetchAndDec #if defined(__x86_64__) /* *----------------------------------------------------------------------------- * * Atomic_ReadDec64 -- * * Atomic read (returned), decrement, write. * * Results: * The value of the variable before the operation. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE uint64 Atomic_ReadDec64(Atomic_uint64 *var) // IN { return Atomic_ReadAdd64(var, CONST64U(-1)); } #endif #ifdef VMKERNEL /* *----------------------------------------------------------------------------- * * CMPXCHG1B -- * * Compare and exchange a single byte. * * Results: * The value read from ptr. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE uint8 CMPXCHG1B(volatile uint8 *ptr, // IN uint8 oldVal, // IN uint8 newVal) // IN { uint8 val; __asm__ __volatile__("lock; cmpxchgb %b2, %1" : "=a" (val), "+m" (*ptr) : "r" (newVal), "0" (oldVal) : "cc"); return val; } #endif /* * Usage of this helper struct is strictly reserved to the following * function. --hpreg */ typedef struct { uint32 lowValue; uint32 highValue; } S_uint64; /* *----------------------------------------------------------------------------- * * Atomic_CMPXCHG64 -- * * Compare exchange: Read variable, if equal to oldVal, write newVal * * XXX: Ensure that if this function is to be inlined by gcc, it is * compiled with -fno-strict-aliasing. Otherwise it will break. * Unfortunately we know that gcc 2.95.3 (used to build the FreeBSD 3.2 * Tools) does not honor -fno-strict-aliasing. As a workaround, we avoid * inlining the function entirely for versions of gcc under 3.0. * * Results: * TRUE if equal, FALSE if not equal * * Side effects: * None * *----------------------------------------------------------------------------- */ #if defined(__GNUC__) && __GNUC__ < 3 static Bool #else static INLINE Bool #endif Atomic_CMPXCHG64(Atomic_uint64 *var, // IN/OUT uint64 const *oldVal, // IN uint64 const *newVal) // IN { #ifdef FAKE_ATOMIC uint64 readVal = var->value; if (*oldVal == readVal) { var->value = *newVal; } return (*oldVal == readVal); #elif defined(__GNUC__) #if defined(VM_ARM_V7) return (Atomic_ReadIfEqualWrite64(var, *oldVal, *newVal) == *oldVal); #else // VM_ARM_V7 Bool equal; /* Checked against the Intel manual and GCC --walken */ #if defined(__x86_64__) uint64 dummy; __asm__ __volatile__( "lock; cmpxchgq %3, %0" "\n\t" "sete %1" : "+m" (*var), "=qm" (equal), "=a" (dummy) : "r" (*newVal), "2" (*oldVal) : "cc" ); #else /* 32-bit version for non-ARM */ int dummy1, dummy2; # if defined __PIC__ /* * Rules for __asm__ statements in __PIC__ code * -------------------------------------------- * * The compiler uses %ebx for __PIC__ code, so an __asm__ statement cannot * clobber %ebx. The __asm__ statement can temporarily modify %ebx, but _for * each parameter that is used while %ebx is temporarily modified_: * * 1) The constraint cannot be "m", because the memory location the compiler * chooses could then be relative to %ebx. * * 2) The constraint cannot be a register class which contains %ebx (such as * "r" or "q"), because the register the compiler chooses could then be * %ebx. (This happens when compiling the Fusion UI with gcc 4.2.1, Apple * build 5577.) * * 3) Using register classes even for other values is problematic, as gcc * can decide e.g. %ecx == %edi == 0 (as compile-time constants) and * ends up using one register for two things. Which breaks xchg's ability * to temporarily put the PIC pointer somewhere else. PR772455 * * For that reason alone, the __asm__ statement should keep the regions * where it temporarily modifies %ebx as small as possible, and should * prefer specific register assignments. */ # if __GNUC__ < 3 // Part of #188541 - for RHL 6.2 etc. __asm__ __volatile__( "xchg %%ebx, %6" "\n\t" "mov 4(%%ebx), %%ecx" "\n\t" "mov (%%ebx), %%ebx" "\n\t" "lock; cmpxchg8b (%3)" "\n\t" "xchg %%ebx, %6" "\n\t" "sete %0" : "=a" (equal), "=d" (dummy2), "=D" (dummy1) : /* * See the "Rules for __asm__ statements in __PIC__ code" above: %3 * must use a register class which does not contain %ebx. */ "S" (var), "0" (((S_uint64 const *)oldVal)->lowValue), "1" (((S_uint64 const *)oldVal)->highValue), "D" (newVal) : "ecx", "cc", "memory" ); # else __asm__ __volatile__( "xchgl %%ebx, %6" "\n\t" "lock; cmpxchg8b (%3)" "\n\t" "xchgl %%ebx, %6" "\n\t" "sete %0" : "=qm" (equal), "=a" (dummy1), "=d" (dummy2) : /* * See the "Rules for __asm__ statements in __PIC__ code" above: %3 * must use a register class which does not contain %ebx. * "a"/"c"/"d" are already used, so we are left with either "S" or "D". * * Note that this assembly uses ALL GP registers (with %esp reserved for * stack, %ebp reserved for frame, %ebx reserved for PIC). */ "S" (var), "1" (((S_uint64 const *)oldVal)->lowValue), "2" (((S_uint64 const *)oldVal)->highValue), "D" (((S_uint64 const *)newVal)->lowValue), "c" (((S_uint64 const *)newVal)->highValue) : "cc", "memory" ); # endif # else __asm__ __volatile__( "lock; cmpxchg8b %0" "\n\t" "sete %1" : "+m" (*var), "=qm" (equal), "=a" (dummy1), "=d" (dummy2) : "2" (((S_uint64 const *)oldVal)->lowValue), "3" (((S_uint64 const *)oldVal)->highValue), "b" (((S_uint64 const *)newVal)->lowValue), "c" (((S_uint64 const *)newVal)->highValue) : "cc" ); # endif #endif AtomicEpilogue(); return equal; #endif //VM_ARM_V7 #elif defined _MSC_VER #if defined(__x86_64__) return (__int64)*oldVal == _InterlockedCompareExchange64((__int64 *)&var->value, (__int64)*newVal, (__int64)*oldVal); #else #pragma warning(push) #pragma warning(disable : 4035) // disable no-return warning { __asm mov esi, var __asm mov edx, oldVal __asm mov ecx, newVal __asm mov eax, [edx]S_uint64.lowValue __asm mov edx, [edx]S_uint64.highValue __asm mov ebx, [ecx]S_uint64.lowValue __asm mov ecx, [ecx]S_uint64.highValue __asm lock cmpxchg8b [esi] __asm sete al __asm movzx eax, al // eax is the return value, this is documented to work - edward } #pragma warning(pop) #endif #else #error No compiler defined for Atomic_CMPXCHG64 #endif // !GNUC } /* *----------------------------------------------------------------------------- * * Atomic_CMPXCHG32 -- * * Compare exchange: Read variable, if equal to oldVal, write newVal * * Results: * TRUE if equal, FALSE if not equal * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE Bool Atomic_CMPXCHG32(Atomic_uint32 *var, // IN/OUT uint32 oldVal, // IN uint32 newVal) // IN { #ifdef FAKE_ATOMIC uint32 readVal = var->value; if (oldVal == readVal) { var->value = newVal; } return (oldVal == readVal); #elif defined(__GNUC__) #ifdef VM_ARM_V7 return (Atomic_ReadIfEqualWrite(var, oldVal, newVal) == oldVal); #else // VM_ARM_V7 Bool equal; uint32 dummy; __asm__ __volatile__( "lock; cmpxchgl %3, %0" "\n\t" "sete %1" : "+m" (*var), "=qm" (equal), "=a" (dummy) : "r" (newVal), "2" (oldVal) : "cc" ); AtomicEpilogue(); return equal; #endif // VM_ARM_V7 #else // defined(__GNUC__) return (Atomic_ReadIfEqualWrite(var, oldVal, newVal) == oldVal); #endif // !defined(__GNUC__) } /* *----------------------------------------------------------------------------- * * Atomic_Read64 -- * * Read and return. * * Results: * The value of the atomic variable. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE uint64 Atomic_Read64(Atomic_uint64 const *var) // IN { #ifdef FAKE_ATOMIC return var->value; #elif defined(__GNUC__) && defined(__x86_64__) uint64 value; #ifdef VMM ASSERT((uintptr_t)var % 8 == 0); #endif /* * Use asm to ensure we emit a single load. */ __asm__ __volatile__( "movq %1, %0" : "=r" (value) : "m" (var->value) ); return value; #elif defined(__GNUC__) && defined(__i386__) uint64 value; /* * Since cmpxchg8b will replace the contents of EDX:EAX with the * value in memory if there is no match, we need only execute the * instruction once in order to atomically read 64 bits from * memory. The only constraint is that ECX:EBX must have the same * value as EDX:EAX so that if the comparison succeeds. We * intentionally don't tell gcc that we are using ebx and ecx as we * don't modify them and do not care what value they store. */ __asm__ __volatile__( "mov %%ebx, %%eax" "\n\t" "mov %%ecx, %%edx" "\n\t" "lock; cmpxchg8b %1" : "=&A" (value) : "m" (*var) : "cc" ); AtomicEpilogue(); return value; #elif defined (_MSC_VER) && defined(__x86_64__) /* * Microsoft docs guarantee "Simple reads and writes to properly * aligned 64-bit variables are atomic on 64-bit Windows." * http://msdn.microsoft.com/en-us/library/ms684122%28VS.85%29.aspx * * XXX Verify that value is properly aligned. Bug 61315. */ return var->value; #elif defined (_MSC_VER) && defined(__i386__) # pragma warning(push) # pragma warning(disable : 4035) // disable no-return warning { __asm mov ecx, var __asm mov edx, ecx __asm mov eax, ebx __asm lock cmpxchg8b [ecx] // edx:eax is the return value; this is documented to work. --mann } # pragma warning(pop) #elif defined(__GNUC__) && defined (VM_ARM_V7) uint64 value; __asm__ __volatile__( "ldrexd %[value], %H[value], [%[var]] \n\t" : [value] "=&r" (value) : [var] "r" (&var->value) ); return value; #endif } /* *---------------------------------------------------------------------- * * Atomic_ReadUnaligned64 -- * * Atomically read a 64 bit integer, possibly misaligned. * This function can be *very* expensive, costing over 50 kcycles * on Nehalem. * * Note that "var" needs to be writable, even though it will not * be modified. * * Results: * The value of the atomic variable. * * Side effects: * None * *---------------------------------------------------------------------- */ #if defined(__x86_64__) static INLINE uint64 Atomic_ReadUnaligned64(Atomic_uint64 const *var) { return Atomic_ReadIfEqualWrite64((Atomic_uint64*)var, 0, 0); } #endif /* *---------------------------------------------------------------------- * * Atomic_FetchAndAdd64 -- * * Atomically adds a 64-bit integer to another * * Results: * Returns the old value just prior to the addition * * Side effects: * None * *---------------------------------------------------------------------- */ static INLINE uint64 Atomic_FetchAndAdd64(Atomic_uint64 *var, // IN/OUT uint64 addend) // IN { uint64 oldVal; uint64 newVal; do { oldVal = var->value; newVal = oldVal + addend; } while (!Atomic_CMPXCHG64(var, &oldVal, &newVal)); return oldVal; } /* *---------------------------------------------------------------------- * * Atomic_FetchAndInc64 -- * * Atomically increments a 64-bit integer * * Results: * Returns the old value just prior to incrementing * * Side effects: * None * *---------------------------------------------------------------------- */ static INLINE uint64 Atomic_FetchAndInc64(Atomic_uint64 *var) // IN/OUT { return Atomic_FetchAndAdd64(var, 1); } /* *---------------------------------------------------------------------- * * Atomic_FetchAndDec64 -- * * Atomically decrements a 64-bit integer * * Results: * Returns the old value just prior to decrementing * * Side effects: * None * *---------------------------------------------------------------------- */ static INLINE uint64 Atomic_FetchAndDec64(Atomic_uint64 *var) // IN/OUT { uint64 oldVal; uint64 newVal; do { oldVal = var->value; newVal = oldVal - 1; } while (!Atomic_CMPXCHG64(var, &oldVal, &newVal)); return oldVal; } /* *----------------------------------------------------------------------------- * * Atomic_Inc64 -- * * Atomic read, increment, write. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void Atomic_Inc64(Atomic_uint64 *var) // IN { #if !defined(__x86_64__) Atomic_FetchAndInc64(var); #elif defined(__GNUC__) /* Checked against the AMD manual and GCC --hpreg */ __asm__ __volatile__( "lock; incq %0" : "+m" (var->value) : : "cc" ); AtomicEpilogue(); #elif defined _MSC_VER _InterlockedIncrement64((__int64 *)&var->value); #else #error No compiler defined for Atomic_Inc64 #endif } /* *----------------------------------------------------------------------------- * * Atomic_Dec64 -- * * Atomic read, decrement, write. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void Atomic_Dec64(Atomic_uint64 *var) // IN { #if !defined(__x86_64__) Atomic_FetchAndDec64(var); #elif defined(__GNUC__) /* Checked against the AMD manual and GCC --hpreg */ __asm__ __volatile__( "lock; decq %0" : "+m" (var->value) : : "cc" ); AtomicEpilogue(); #elif defined _MSC_VER _InterlockedDecrement64((__int64 *)&var->value); #else #error No compiler defined for Atomic_Dec64 #endif } /* *----------------------------------------------------------------------------- * * Atomic_ReadWrite64 -- * * Read followed by write * * Results: * The value of the atomic variable before the write. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE uint64 Atomic_ReadWrite64(Atomic_uint64 *var, // IN uint64 val) // IN { #if defined(__x86_64__) #if defined(__GNUC__) /* Checked against the AMD manual and GCC --hpreg */ __asm__ __volatile__( "xchgq %0, %1" : "=r" (val), "+m" (var->value) : "0" (val) ); AtomicEpilogue(); return val; #elif defined _MSC_VER return _InterlockedExchange64((__int64 *)&var->value, (__int64)val); #else #error No compiler defined for Atomic_ReadWrite64 #endif #else uint64 oldVal; do { oldVal = var->value; } while (!Atomic_CMPXCHG64(var, &oldVal, &val)); return oldVal; #endif } /* *----------------------------------------------------------------------------- * * Atomic_Write64 -- * * Write * * Results: * None. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void Atomic_Write64(Atomic_uint64 *var, // IN uint64 val) // IN { #if defined(__x86_64__) #if defined(__GNUC__) #ifdef VMM ASSERT((uintptr_t)var % 8 == 0); #endif /* * There is no move instruction for 64-bit immediate to memory, so unless * the immediate value fits in 32-bit (i.e. can be sign-extended), GCC * breaks the assignment into two movl instructions. The code below forces * GCC to load the immediate value into a register first. */ __asm__ __volatile__( "movq %1, %0" : "=m" (var->value) : "r" (val) ); #elif defined _MSC_VER /* * Microsoft docs guarantee "Simple reads and writes to properly aligned * 64-bit variables are atomic on 64-bit Windows." * http://msdn.microsoft.com/en-us/library/ms684122%28VS.85%29.aspx * * XXX Verify that value is properly aligned. Bug 61315. */ var->value = val; #else #error No compiler defined for Atomic_Write64 #endif #else /* defined(__x86_64__) */ (void)Atomic_ReadWrite64(var, val); #endif } /* *----------------------------------------------------------------------------- * * Atomic_Or64 -- * * Atomic read, bitwise OR with a 64-bit value, write. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void Atomic_Or64(Atomic_uint64 *var, // IN uint64 val) // IN { #if defined(__x86_64__) #if defined(__GNUC__) /* Checked against the AMD manual and GCC --hpreg */ __asm__ __volatile__( "lock; orq %1, %0" : "+m" (var->value) : "ri" (val) : "cc" ); AtomicEpilogue(); #elif defined _MSC_VER _InterlockedOr64((__int64 *)&var->value, (__int64)val); #else #error No compiler defined for Atomic_Or64 #endif #else // __x86_64__ uint64 oldVal; uint64 newVal; do { oldVal = var->value; newVal = oldVal | val; } while (!Atomic_CMPXCHG64(var, &oldVal, &newVal)); #endif } /* *----------------------------------------------------------------------------- * * Atomic_And64 -- * * Atomic read, bitwise AND with a 64-bit value, write. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void Atomic_And64(Atomic_uint64 *var, // IN uint64 val) // IN { #if defined(__x86_64__) #if defined(__GNUC__) /* Checked against the AMD manual and GCC --hpreg */ __asm__ __volatile__( "lock; andq %1, %0" : "+m" (var->value) : "ri" (val) : "cc" ); AtomicEpilogue(); #elif defined _MSC_VER _InterlockedAnd64((__int64 *)&var->value, (__int64)val); #else #error No compiler defined for Atomic_And64 #endif #else // __x86_64__ uint64 oldVal; uint64 newVal; do { oldVal = var->value; newVal = oldVal & val; } while (!Atomic_CMPXCHG64(var, &oldVal, &newVal)); #endif } /* *----------------------------------------------------------------------------- * * Atomic_SetBit64 -- * * Atomic read, set bit N, and write. * Be careful: if bit is in a register (not in an immediate), then it * can specify a bit offset above 63 or even a negative offset. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void Atomic_SetBit64(Atomic_uint64 *var, // IN/OUT uint64 bit) // IN { #if defined(__x86_64__) #if defined(__GNUC__) __asm__ __volatile__( "lock; bts %1, %0" : "+m" (var->value) : "ri" (bit) : "cc" ); AtomicEpilogue(); #elif defined _MSC_VER uint64 oldVal; uint64 newVal; do { oldVal = var->value; newVal = oldVal | (CONST64U(1) << bit); } while (!Atomic_CMPXCHG64(var, &oldVal, &newVal)); #else #error No compiler defined for Atomic_SetBit64 #endif #else // __x86_64__ uint64 oldVal; uint64 newVal; do { oldVal = var->value; newVal = oldVal | (CONST64U(1) << bit); } while (!Atomic_CMPXCHG64(var, &oldVal, &newVal)); #endif } /* *----------------------------------------------------------------------------- * * Atomic_ClearBit64 -- * * Atomic read, clear bit N, and write. * Be careful: if bit is in a register (not in an immediate), then it * can specify a bit offset above 63 or even a negative offset. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void Atomic_ClearBit64(Atomic_uint64 *var, // IN/OUT uint64 bit) // IN { #if defined(__x86_64__) #if defined(__GNUC__) __asm__ __volatile__( "lock; btr %1, %0" : "+m" (var->value) : "ri" (bit) : "cc" ); AtomicEpilogue(); #elif defined _MSC_VER uint64 oldVal; uint64 newVal; do { oldVal = var->value; newVal = oldVal & ~(CONST64U(1) << bit); } while (!Atomic_CMPXCHG64(var, &oldVal, &newVal)); #else #error No compiler defined for Atomic_ClearBit64 #endif #else // __x86_64__ uint64 oldVal; uint64 newVal; do { oldVal = var->value; newVal = oldVal & ~(CONST64U(1) << bit); } while (!Atomic_CMPXCHG64(var, &oldVal, &newVal)); #endif } /* *----------------------------------------------------------------------------- * * Atomic_TestBit64 -- * * Read a bit. * Be careful: if bit is in a register (not in an immediate), then it * can specify a bit offset above 63 or even a negative offset. * * Results: * TRUE if the tested bit was set; else FALSE. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE Bool Atomic_TestBit64(Atomic_uint64 *var, // IN uint64 bit) // IN { #if defined(__x86_64__) #if defined(__GNUC__) Bool out = FALSE; __asm__ __volatile__( "bt %2, %1; setc %0" : "=rm"(out) : "m" (var->value), "rJ" (bit) : "cc" ); return out; #elif defined _MSC_VER return (var->value & (CONST64U(1) << bit)) != 0; #else #error No compiler defined for Atomic_TestBit64 #endif #else // __x86_64__ return (var->value & (CONST64U(1) << bit)) != 0; #endif } /* * Template code for the Atomic_ type and its operators. * * The cast argument is an intermediate type cast to make some * compilers stop complaining about casting uint32 <-> void *, * even though we only do it in the 32-bit case so they are always * the same size. So for val of type uint32, instead of * (void *)val, we have (void *)(uintptr_t)val. * The specific problem case is the Windows ddk compiler * (as used by the SVGA driver). -- edward */ #define MAKE_ATOMIC_TYPE(name, size, in, out, cast) \ typedef Atomic_uint ## size Atomic_ ## name; \ \ \ static INLINE void \ AtomicAssertOnCompile ## name(void) \ { \ enum { AssertOnCompileMisused = 8 * sizeof (in) == size \ && 8 * sizeof (out) == size \ && 8 * sizeof (cast) == size \ ? 1 : -1 }; \ typedef char AssertOnCompileFailed[AssertOnCompileMisused]; \ } \ \ \ static INLINE out \ Atomic_Read ## name(Atomic_ ## name const *var) \ { \ return (out)(cast)Atomic_Read ## size(var); \ } \ \ \ static INLINE void \ Atomic_Write ## name(Atomic_ ## name *var, \ in val) \ { \ Atomic_Write ## size(var, (uint ## size)(cast)val); \ } \ \ \ static INLINE out \ Atomic_ReadWrite ## name(Atomic_ ## name *var, \ in val) \ { \ return (out)(cast)Atomic_ReadWrite ## size(var, \ (uint ## size)(cast)val); \ } \ \ \ static INLINE out \ Atomic_ReadIfEqualWrite ## name(Atomic_ ## name *var, \ in oldVal, \ in newVal) \ { \ return (out)(cast)Atomic_ReadIfEqualWrite ## size(var, \ (uint ## size)(cast)oldVal, (uint ## size)(cast)newVal); \ } \ \ \ static INLINE void \ Atomic_And ## name(Atomic_ ## name *var, \ in val) \ { \ Atomic_And ## size(var, (uint ## size)(cast)val); \ } \ \ \ static INLINE void \ Atomic_Or ## name(Atomic_ ## name *var, \ in val) \ { \ Atomic_Or ## size(var, (uint ## size)(cast)val); \ } \ \ \ static INLINE void \ Atomic_Xor ## name(Atomic_ ## name *var, \ in val) \ { \ Atomic_Xor ## size(var, (uint ## size)(cast)val); \ } \ \ \ static INLINE void \ Atomic_Add ## name(Atomic_ ## name *var, \ in val) \ { \ Atomic_Add ## size(var, (uint ## size)(cast)val); \ } \ \ \ static INLINE void \ Atomic_Sub ## name(Atomic_ ## name *var, \ in val) \ { \ Atomic_Sub ## size(var, (uint ## size)(cast)val); \ } \ \ \ static INLINE void \ Atomic_Inc ## name(Atomic_ ## name *var) \ { \ Atomic_Inc ## size(var); \ } \ \ \ static INLINE void \ Atomic_Dec ## name(Atomic_ ## name *var) \ { \ Atomic_Dec ## size(var); \ } \ \ \ static INLINE out \ Atomic_ReadOr ## name(Atomic_ ## name *var, \ in val) \ { \ return (out)(cast)Atomic_ReadOr ## size(var, (uint ## size)(cast)val); \ } \ \ \ static INLINE out \ Atomic_ReadAdd ## name(Atomic_ ## name *var, \ in val) \ { \ return (out)(cast)Atomic_ReadAdd ## size(var, (uint ## size)(cast)val); \ } \ \ \ static INLINE out \ Atomic_ReadInc ## name(Atomic_ ## name *var) \ { \ return (out)(cast)Atomic_ReadInc ## size(var); \ } \ \ \ static INLINE out \ Atomic_ReadDec ## name(Atomic_ ## name *var) \ { \ return (out)(cast)Atomic_ReadDec ## size(var); \ } /* * Since we use a macro to generate these definitions, it is hard to look for * them. So DO NOT REMOVE THIS COMMENT and keep it up-to-date. --hpreg * * Atomic_Ptr * Atomic_ReadPtr -- * Atomic_WritePtr -- * Atomic_ReadWritePtr -- * Atomic_ReadIfEqualWritePtr -- * Atomic_AndPtr -- * Atomic_OrPtr -- * Atomic_XorPtr -- * Atomic_AddPtr -- * Atomic_SubPtr -- * Atomic_IncPtr -- * Atomic_DecPtr -- * Atomic_ReadOrPtr -- * Atomic_ReadAddPtr -- * Atomic_ReadIncPtr -- * Atomic_ReadDecPtr -- * * Atomic_Int * Atomic_ReadInt -- * Atomic_WriteInt -- * Atomic_ReadWriteInt -- * Atomic_ReadIfEqualWriteInt -- * Atomic_AndInt -- * Atomic_OrInt -- * Atomic_XorInt -- * Atomic_AddInt -- * Atomic_SubInt -- * Atomic_IncInt -- * Atomic_DecInt -- * Atomic_ReadOrInt -- * Atomic_ReadAddInt -- * Atomic_ReadIncInt -- * Atomic_ReadDecInt -- */ #if defined(__x86_64__) MAKE_ATOMIC_TYPE(Ptr, 64, void const *, void *, uintptr_t) #else MAKE_ATOMIC_TYPE(Ptr, 32, void const *, void *, uintptr_t) #endif MAKE_ATOMIC_TYPE(Int, 32, int, int, int) /* Prevent the compiler from re-ordering memory references. */ #ifdef __GNUC__ #define ATOMIC_COMPILER_BARRIER() __asm__ __volatile__ ("": : :"memory") #elif defined(_MSC_VER) #define ATOMIC_COMPILER_BARRIER() _ReadWriteBarrier() #else #error No compiler defined for ATOMIC_COMPILER_BARRIER #endif /* *----------------------------------------------------------------------------- * * Atomic_MFence -- * * Implements mfence in terms of a lock xor. The reason for implementing * our own mfence is that not all of our supported cpus have an assembly * mfence (P3, Athlon). We put it here to avoid duplicating code which is * also why it is prefixed with "Atomic_". * * Results: * None. * * Side effects: * Cause loads and stores prior to this to be globally * visible. * *----------------------------------------------------------------------------- */ static INLINE void Atomic_MFence(void) { Atomic_uint32 fence; ATOMIC_COMPILER_BARRIER(); Atomic_Xor(&fence, 0x1); ATOMIC_COMPILER_BARRIER(); } #ifdef ATOMIC_COMPILER_BARRIER #undef ATOMIC_COMPILER_BARRIER #endif #endif // ifndef _ATOMIC_H_ open-vm-tools-9.4.0-1280544/lib/include/vm_product.h0000644765153500003110000005134412220061556020172 0ustar dtormts/********************************************************* * Copyright (C) 2006-2011 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef VM_PRODUCT_H #define VM_PRODUCT_H #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" /**** **** **** PLEASE use the various PRODUCT_* and *_NAME defines as though **** they were variables -- do not embed them in format strings, **** since they could contain a "%" sign or actually be a variable **** someday. **** ****/ /* * This name should be used when referring to the company */ #define COMPANY_NAME "VMware, Inc." /* * This generic name should be used when referring to any product of the * VMware product line, like VMware Workstation, VMware Server, and so * on... */ #define PRODUCT_GENERIC_NAME "VMware" #define PRODUCT_GENERIC_NAME_UPPER "VMWARE" #define PRODUCT_GENERIC_NAME_LOWER "vmware" /* * Brief names are used when the VMware prefix is not wanted. */ #define PRODUCT_SCALABLE_SERVER_BRIEF_NAME "ESX" #define PRODUCT_WORKSTATION_BRIEF_NAME "Workstation" #define PRODUCT_WORKSTATION_ENTERPRISE_BRIEF_NAME \ PRODUCT_WORKSTATION_BRIEF_NAME " " "ACE Edition" #define PRODUCT_WORKSTATION_SERVER_BRIEF_NAME "Workstation Server" #define PRODUCT_PLAYER_BRIEF_NAME "Player" #define PRODUCT_ACE_PLAYER_BRIEF_NAME "ACE " PRODUCT_PLAYER_BRIEF_NAME #define PRODUCT_MAC_DESKTOP_BRIEF_NAME "Fusion" #define PRODUCT_ACE_MANAGEMENT_SERVER_BRIEF_NAME "ACE Management Server" /* * Product names include the formal VMware prefix. */ #define MAKE_NAME(_brief) PRODUCT_GENERIC_NAME " " _brief /* * This name should be used when referring to VMware Tools */ #define VMWARE_TOOLS_SHORT_NAME MAKE_NAME("Tools") #define PRODUCT_SCALABLE_SERVER_NAME MAKE_NAME(PRODUCT_SCALABLE_SERVER_BRIEF_NAME) #define PRODUCT_ESX_SMP_NAME MAKE_NAME("Virtual SMP for ESX Server") #define PRODUCT_WORKSTATION_NAME MAKE_NAME(PRODUCT_WORKSTATION_BRIEF_NAME) #define PRODUCT_WORKSTATION_ENTERPRISE_NAME MAKE_NAME(PRODUCT_WORKSTATION_ENTERPRISE_BRIEF_NAME) #define PRODUCT_WORKSTATION_SERVER_NAME MAKE_NAME(PRODUCT_WORKSTATION_SERVER_BRIEF_NAME) #define PRODUCT_MUI_NAME MAKE_NAME("Management Interface") #define PRODUCT_CONSOLE_NAME MAKE_NAME("Server Console") #define PRODUCT_PLAYER_NAME MAKE_NAME(PRODUCT_PLAYER_BRIEF_NAME) #define PRODUCT_PLAYER_NAME_FOR_LICENSE PRODUCT_PLAYER_NAME #define PRODUCT_ACE_PLAYER_NAME MAKE_NAME(PRODUCT_ACE_PLAYER_BRIEF_NAME) #define PRODUCT_ACE_MANAGEMENT_SERVER_NAME MAKE_NAME(PRODUCT_ACE_MANAGEMENT_SERVER_BRIEF_NAME) #define PRODUCT_MAC_DESKTOP_NAME_FOR_LICENSE "VMware Fusion for Mac OS" #define PRODUCT_VMLS_SHORT_NAME "VMLS" #define PRODUCT_VMLS_NAME MAKE_NAME("License Server") #define PRODUCT_VLICENSE_SHORT_NAME "VLICENSE" #define PRODUCT_VLICENSE_NAME MAKE_NAME("License Infrastructure") #define PRODUCT_P2V_SHORT_NAME "P2V" #define PRODUCT_P2V_NAME MAKE_NAME("P2V Assistant") #define PRODUCT_V2V_SHORT_NAME "V2V" #define PRODUCT_V2V_NAME MAKE_NAME("Virtual Machine Importer") #define PRODUCT_SYSIMAGE_SHORT_NAME "SysImage" #define PRODUCT_SYSIMAGE_NAME MAKE_NAME("System Image Framework") #define PRODUCT_VCB_SHORT_NAME "VCB" #define PRODUCT_VCB_NAME MAKE_NAME("Consolidated Backup") #define PRODUCT_VPX_NAME MAKE_NAME("VirtualCenter") #define PRODUCT_VPXA_NAME PRODUCT_VPX_NAME " Agent" #define PRODUCT_FDM_NAME MAKE_NAME("Fault Domain Manager") #define PRODUCT_HA_NAME MAKE_NAME("High Availability Extension") #define PRODUCT_WBC_NAME MAKE_NAME("WebCenter") #define PRODUCT_SDK_NAME MAKE_NAME("SDK") #define PRODUCT_DDK_NAME MAKE_NAME("ESX DDK") #define PRODUCT_NGCINSTALLER_NAME MAKE_NAME("vSphere Web Client") #define PRODUCT_SSOINSTALLER_NAME MAKE_NAME("Single Sign On") #define PRODUCT_SSOREGMM_NAME MAKE_NAME("vCenter Registration Tool") // XXX I think these are dead and can be removed -clayton // #define PRODUCT_VDM_SHORT_NAME "VDM" // #define PRODUCT_VDM_NAME MAKE_NAME("Virtual Desktop Manager") #define PRODUCT_VDDK_SHORT_NAME "VDDK" #define PRODUCT_VDDK_NAME MAKE_NAME("Virtual Disk Development Kit") #define PRODUCT_VDM_CLIENT_NAME MAKE_NAME("View Client") #define PRODUCT_VDM_CLIENT_NAME_FOR_LICENSE PRODUCT_VDM_CLIENT_NAME #define PRODUCT_XVP_SHORT_NAME "XVP" #define PRODUCT_XVP_NAME MAKE_NAME("vCenter XVP Manager") #define PRODUCT_RMKSCONTAINER_NAME MAKE_NAME("Remote MKS Container") #define PRODUCT_BOOMERANG_NAME MAKE_NAME("Boomerang") #define PRODUCT_HBR_SERVER_NAME MAKE_NAME("vSphere Replication Server") #define PRODUCT_VIEW_SHORT_NAME "View" #define PRODUCT_VIEW_NAME MAKE_NAME("View") #define PRODUCT_VIEW_NAME_FOR_LICENSE PRODUCT_VIEW_NAME #define PRODUCT_VMCF_NAME MAKE_NAME("VMCF") // XXX VMvisor is the underlying technology for possibly several products, // XXX not the product. Fix when names are decided. // #define PRODUCT_VMVISOR_NAME MAKE_NAME("VMvisor") // XXX Only one product for now so just hardcode it. #define PRODUCT_VMVISOR_NAME MAKE_NAME(PRODUCT_SCALABLE_SERVER_BRIEF_NAME "i") #if defined(__linux__) || defined(__FreeBSD__) #define PRODUCT_NETDUMP_NAME PRODUCT_GENERIC_NAME_LOWER "-netdumper" #else #define PRODUCT_NETDUMP_NAME PRODUCT_VMVISOR_NAME " dump collector" #endif /* * VMware Remote Console (VMRC) version definitions */ #define PRODUCT_VMRC_SHORT_NAME "VMRC" #define PRODUCT_VMRC_NAME MAKE_NAME("Remote Console") #define PRODUCT_VMRC_PLUGIN_NAME PRODUCT_VMRC_NAME " Plug-in" #define PRODUCT_VMRC_DESCRIPTION "Enables remote interaction with virtual machines." #ifdef _WIN32 #define PRODUCT_VMRC_EXECUTABLE PRODUCT_GENERIC_NAME_LOWER "-vmrc.exe" #else #define PRODUCT_VMRC_EXECUTABLE PRODUCT_GENERIC_NAME_LOWER "-vmrc" #define PRODUCT_VMRC_DEVICE_EXECUTABLE PRODUCT_GENERIC_NAME_LOWER "-deviceMgr" #endif /* * VMRC ActiveX CLSIDs and ProgIDs * * VMRC is versioned x.y.z - ProgID is intentionally built using only x.y */ #define PRODUCT_VMRC_PLUGIN_GUID_EMBEDDED 4AEA1010-0A0C-405E-9B74-767FC8A998CB #define PRODUCT_VMRC_PLUGIN_GUID_TYPELIB E82F3B76-A628-4486-B197-03780F86063A #define PRODUCT_VMRC_PLUGIN_PROGID_EMBEDDED_BASE "VMware.RemoteConsole" #define PRODUCT_VMRC_PLUGIN_PROGID_EMBEDDED PRODUCT_VMRC_PLUGIN_PROGID_EMBEDDED_BASE "." \ XSTR(VMRC_PLUGIN_VERSION_BASE) /* * VMRC MIME types */ #ifdef _WIN32 #define PRODUCT_VMRC_MIMETYPE_SEPARATOR "|" #define PRODUCT_VMRC_MIMETYPE_TERMINATOR "" #else #define PRODUCT_VMRC_MIMETYPE_SEPARATOR "::" PRODUCT_VMRC_PLUGIN_NAME ";" #define PRODUCT_VMRC_MIMETYPE_TERMINATOR "::" PRODUCT_VMRC_PLUGIN_NAME ";" #endif #define PRODUCT_VMRC_PLUGIN_CURRENT_MIMETYPE \ "application/x-vmware-remote-console-2012" /* * All supported plugin mimetypes * * NB: See above for constraints on the ordering of this list. */ #define PRODUCT_VMRC_PLUGIN_MIMETYPES \ PRODUCT_VMRC_PLUGIN_CURRENT_MIMETYPE PRODUCT_VMRC_MIMETYPE_TERMINATOR /* * VMware USB Arbitration Service version definitions */ #define PRODUCT_USB_ARBITRATOR_SHORT_NAME "vmware-usbarbitrator" #define PRODUCT_USB_ARBITRATOR_NAME MAKE_NAME("USB Arbitration Service") #ifdef _WIN32 #define PRODUCT_USB_ARBITRATOR_EXECUTABLE PRODUCT_GENERIC_NAME_LOWER "-usbarbitrator.exe" #else #define PRODUCT_USB_ARBITRATOR_EXECUTABLE PRODUCT_GENERIC_NAME_LOWER "-usbarbitrator" #endif /* * TODO: This properly lives in productState, but we need it here to * define DEFAULT_LIBDIRECTORY. If that can be moved to productState, * it's no longer needed here. */ #define PRODUCT_MAC_DESKTOP_NAME MAKE_NAME(PRODUCT_MAC_DESKTOP_BRIEF_NAME) #if !( defined(VMX86_SERVER) \ || defined(VMX86_DESKTOP) \ || defined(VMX86_ENTERPRISE_DESKTOP) \ || defined(VMX86_VIEW) \ || defined(VMX86_MUI) \ || defined(VMX86_VPX) \ || defined(VMX86_WBC) \ || defined(VMX86_SDK) \ || defined(VMX86_TOOLS) \ || defined(VMX86_V2V) \ || defined(VMX86_SYSIMAGE) \ || defined(VMX86_VCB) \ || defined(VMX86_VMLS) \ || defined(VMX86_VLICENSE) \ || defined(VMX86_P2V) \ || defined(VMX86_DDK) \ || defined(VMX86_VDDK) \ || defined(VMX86_NETDUMP) \ || defined(VMX86_BOOMERANG) \ || defined(VMX86_HBR_SERVER) \ || defined(VMX86_VMCF)) # if defined(_WIN32) || defined(__APPLE__) /* * XXX Make the product be Workstation by default if none of the defines * XXX above are not defined in defs-globaldefs.mk -- Edward A. Waugh */ # define VMX86_DESKTOP # else # error Unknown product # endif #endif #if defined(VMVISOR) # define PRODUCT_SHORT_NAME PRODUCT_VMVISOR_NAME #elif defined(VMX86_SERVER) # define PRODUCT_SHORT_NAME PRODUCT_SCALABLE_SERVER_NAME #elif defined(VMX86_CONSOLE) # define PRODUCT_SHORT_NAME PRODUCT_CONSOLE_NAME #elif defined(VMX86_MUI) # define PRODUCT_SHORT_NAME PRODUCT_MUI_NAME #elif defined(VMX86_ENTERPRISE_DESKTOP) # define PRODUCT_SHORT_NAME PRODUCT_WORKSTATION_ENTERPRISE_NAME #elif defined(VMX86_DESKTOP) # if defined(__APPLE__) # define PRODUCT_SHORT_NAME PRODUCT_MAC_DESKTOP_NAME # else # define PRODUCT_SHORT_NAME PRODUCT_WORKSTATION_NAME # endif #elif defined(VMX86_TOOLS) # define PRODUCT_SHORT_NAME VMWARE_TOOLS_SHORT_NAME #elif defined(VMX86_VPX) # if defined(CSI_HA) # define PRODUCT_SHORT_NAME PRODUCT_HA_NAME # elif defined(CSI_FDM) # define PRODUCT_SHORT_NAME PRODUCT_FDM_NAME # elif defined(VPXA) # define PRODUCT_SHORT_NAME PRODUCT_VPXA_NAME # elif defined(XVP) # define PRODUCT_SHORT_NAME PRODUCT_XVP_NAME # elif defined(INSTALL_NGC) # define PRODUCT_SHORT_NAME PRODUCT_NGCINSTALLER_NAME # elif defined(INSTALL_SSO) # define PRODUCT_SHORT_NAME PRODUCT_SSOINSTALLER_NAME # elif defined(INSTALL_SSOREGMM) # define PRODUCT_SHORT_NAME PRODUCT_SSOREGMM_NAME # else # define PRODUCT_SHORT_NAME PRODUCT_VPX_NAME # endif #elif defined(VMX86_WBC) # define PRODUCT_SHORT_NAME PRODUCT_WBC_NAME #elif defined(VMX86_SDK) # define PRODUCT_SHORT_NAME PRODUCT_SDK_NAME #elif defined(VMX86_P2V) # define PRODUCT_SHORT_NAME PRODUCT_P2V_NAME #elif defined(VMX86_V2V) # define PRODUCT_SHORT_NAME PRODUCT_V2V_NAME #elif defined(VMX86_SYSIMAGE) # define PRODUCT_SHORT_NAME PRODUCT_SYSIMAGE_NAME #elif defined(VMX86_VCB) # define PRODUCT_SHORT_NAME PRODUCT_VCB_NAME #elif defined(VMX86_VMLS) # define PRODUCT_SHORT_NAME PRODUCT_VMLS_NAME #elif defined(VMX86_VLICENSE) # define PRODUCT_SHORT_NAME PRODUCT_VLICENSE_NAME #elif defined(VMX86_DDK) # define PRODUCT_SHORT_NAME PRODUCT_DDK_NAME #elif defined(VMX86_VDDK) # define PRODUCT_SHORT_NAME PRODUCT_VDDK_NAME #elif defined(VMX86_NETDUMP) # define PRODUCT_SHORT_NAME PRODUCT_NETDUMP_NAME #elif defined(VMX86_BOOMERANG) # define PRODUCT_SHORT_NAME PRODUCT_BOOMERANG_NAME #elif defined(VMX86_HBR_SERVER) # define PRODUCT_SHORT_NAME PRODUCT_HBR_SERVER_NAME #elif defined(VMX86_VIEW) # define PRODUCT_SHORT_NAME PRODUCT_VIEW_NAME #elif defined(VMX86_VMCF) # define PRODUCT_SHORT_NAME PRODUCT_VMCF_NAME #endif /* * Names of programs */ #if defined(VMX86_CONSOLE) #if defined(__linux__) || defined(__FreeBSD__) #define VMWARE_EXECUTABLE PRODUCT_GENERIC_NAME_LOWER "-console" #else #define VMWARE_EXECUTABLE PRODUCT_GENERIC_NAME_LOWER "Console.exe" #endif #else #define VMWARE_EXECUTABLE PRODUCT_GENERIC_NAME_LOWER #endif #define VMWARE_VMX_EXECUTABLE PRODUCT_GENERIC_NAME_LOWER "-vmx" #define CCAGENT_DISPLAY_NAME PRODUCT_VPX_NAME " Agent" #if defined(__linux__) || defined(__FreeBSD__) # define VMAUTHD_EXECUTABLE PRODUCT_GENERIC_NAME_LOWER "-authd" #else # define VMAUTHD_DISPLAY_NAME "VMware Authorization Service" # define VMSERVERD_DISPLAY_NAME "VMware Registration Service" # define VMNAT_DISPLAY_NAME "VMware NAT Service" # define TOOLS_SERVICE_DISPLAY_NAME "VMware Tools Service" # define TOOLS_SERVICE_NAME "VMTools" # define VMAUTHD_SERVICE_NAME "VMAuthdService" #endif /* * Configuration paths */ #ifndef _WIN32 # define PRODUCT_NAME PRODUCT_SHORT_NAME /* * Checked against the ProductID field of licenses. This ensures that * a license intended for one flavor of the product will not allow * another flavor of the product to run. */ # if defined(__APPLE__) # define PRODUCT_OS "Mac OS" # else # define PRODUCT_OS "Linux" # endif /* * Note: changing PRODUCT_NAME_FOR_LICENSE and PRODUCT_LICENSE_VERSION * or macros it cleverly depends on (such as PRODUCT_NAME) requires a * coordinated dormant license file change. Otherwise licensing for * that product may break because the Licensecheck API is being passed * a parameter that no longer match the content of the dormant license * file. */ # if defined(VMX86_SERVER) # define PRODUCT_NAME_FOR_LICENSE "VMware ESX Server" # define PRODUCT_SMP_NAME_FOR_LICENSE PRODUCT_ESX_SMP_NAME # elif defined(VMX86_DESKTOP) # if defined(__APPLE__) # define PRODUCT_NAME_FOR_LICENSE PRODUCT_MAC_DESKTOP_NAME_FOR_LICENSE # else # define PRODUCT_NAME_FOR_LICENSE "VMware Workstation" # endif # define PRODUCT_SMP_NAME_FOR_LICENSE "" // None # elif defined(VMX86_VPX) # define PRODUCT_NAME_FOR_LICENSE PRODUCT_NAME " Server" # define PRODUCT_SMP_NAME_FOR_LICENSE "" // None # elif defined(VMX86_SYSIMAGE) # define PRODUCT_NAME_FOR_LICENSE PRODUCT_NAME # define PRODUCT_SMP_NAME_FOR_LICENSE "" // None # elif defined(VMX86_NETDUMP) # define PRODUCT_NAME_FOR_LICENSE PRODUCT_NETDUMP_NAME # define PRODUCT_SMP_NAME_FOR_LICENSE "" //None # else /* It is a product that doesn't use a license */ # define PRODUCT_NAME_FOR_LICENSE PRODUCT_NAME # define PRODUCT_SMP_NAME_FOR_LICENSE "" // None # endif /* * VMWARE_HOST_DIRECTORY is for host-specific configuration files. * DEFAULT_LIBDIRECTORY is the default for the 'libdir' config variable. * * The remote console checks at run time, and the MUI is not really a separate * product. */ # if defined(__APPLE__) # if defined VMX86_DESKTOP # define VMWARE_HOST_DIRECTORY_PREFIX \ "/Library/Preferences/" PRODUCT_SHORT_NAME # else # define VMWARE_HOST_DIRECTORY_PREFIX \ "/Library/Application Support/" PRODUCT_SHORT_NAME # endif # endif # if defined (VMX86_CONSOLE) # if defined(__APPLE__) # define VMWARE_HOST_DIRECTORY VMWARE_HOST_DIRECTORY_PREFIX " Console" # else # define VMWARE_HOST_DIRECTORY "/etc/" PRODUCT_GENERIC_NAME_LOWER "-console" # define DEFAULT_LIBDIRECTORY "/usr/lib/" PRODUCT_GENERIC_NAME_LOWER "-console" # endif # else # if defined(__APPLE__) # define VMWARE_HOST_DIRECTORY VMWARE_HOST_DIRECTORY_PREFIX # elif defined(__ACESC_LICENSE__) /* * This definition (__ACESC_LICENSE__) is used by the acesc licensing. * The licensing API uses VMWARE_HOST_DIRECTORY definition to save the activated * license (as well as searching). * In our case, the ACESC will use this customized directory, instead of the common * '/etc/vmware'. * The main motivation for this is that the acesc configuration application is * a web application (cgi app). Using the common directory, the apache process * does not have enough permission to write into the directory (/etc/vmware). * Instead of making the /etc/vmware writeable by everybody, we just create another * subdirectory (/etc/vmware/acesc). */ # define VMWARE_HOST_DIRECTORY "/etc/vmware/acesc" # define DEFAULT_LIBDIRECTORY "/usr/lib/" PRODUCT_GENERIC_NAME_LOWER # else # define VMWARE_HOST_DIRECTORY "/etc/" PRODUCT_GENERIC_NAME_LOWER # define DEFAULT_LIBDIRECTORY "/usr/lib/" PRODUCT_GENERIC_NAME_LOWER # endif # endif # if defined(__APPLE__) # if defined VMX86_DESKTOP /* * We will remove this definition soon. Fusion's library directory should not * be hardcoded: it prevents Fusion from being relocated. Use * Location_GetLibrary() instead. */ # define DEFAULT_LIBDIRECTORY \ "/Applications/" PRODUCT_SHORT_NAME ".app/Contents/Library" # else # define DEFAULT_LIBDIRECTORY VMWARE_HOST_DIRECTORY # endif # endif /* For user-specific files. */ # if defined(__APPLE__) # define VMWARE_USER_DIRECTORY "~/Library/Preferences/" PRODUCT_SHORT_NAME # else # define VMWARE_USER_DIRECTORY "~/." PRODUCT_GENERIC_NAME_LOWER # endif # define VMWARE_MODULE_NAME "/dev/vmmon" # define VMWARE_CONFIG PRODUCT_GENERIC_NAME_LOWER "-config.pl" # define VMWARE_CONNECT_SOCKET_DIRECTORY "/var/run/" PRODUCT_GENERIC_NAME_LOWER #else /* PRODUCT_SHORT_NAME and PRODUCT_FULL_NAME are used to display the name depending on how much space we have */ # define PRODUCT_FULL_NAME PRODUCT_SHORT_NAME # define PRODUCT_NAME PRODUCT_FULL_NAME /* Directory name in the registry */ #define PRODUCT_REG_NAME PRODUCT_NAME /* * Checked against the ProductID field of licenses. This ensures that * a license intended for one flavor of the product will not allow * another flavor of the product to run. */ # if defined(VMX86_DESKTOP) # if defined(__APPLE__) # define PRODUCT_NAME_FOR_LICENSE PRODUCT_MAC_DESKTOP_NAME_FOR_LICENSE # else # define PRODUCT_NAME_FOR_LICENSE "VMware Workstation" # endif # define PRODUCT_SMP_NAME_FOR_LICENSE "" // None # elif defined(VMX86_VPX) # define PRODUCT_NAME_FOR_LICENSE PRODUCT_NAME " Server" # define PRODUCT_SMP_NAME_FOR_LICENSE "" // None # else # define PRODUCT_NAME_FOR_LICENSE PRODUCT_REG_NAME # define PRODUCT_SMP_NAME_FOR_LICENSE "" // None # endif #define PRIVATE_REG_KEY "Private" #endif /* * Used when referring to an unspecified member of the VMware product line * ex. "This file was created by an incompatible version of PRODUCT_LINE_NAME" */ #define PRODUCT_LINE_NAME PRODUCT_GENERIC_NAME " software" #define PRODUCT_REG_PATH "SOFTWARE\\" COMPANY_NAME "\\" PRODUCT_REG_NAME #define PRIVATE_REG_PATH PRODUCT_REG_PATH "\\" PRIVATE_REG_KEY /* * Defines used primarily in Tools, but perhaps useful elsewhere. Only error * on unrecognized platform during Tools builds. Note that NetWare must come * before linux below since it uses the Linux gcc which automatically defines * linux; the other platforms don't have this issue. */ #ifdef N_PLAT_NLM # define PRODUCT_NAME_PLATFORM PRODUCT_NAME " for NetWare" #elif defined(linux) # define PRODUCT_NAME_PLATFORM PRODUCT_NAME " for Linux" #elif defined(_WIN32) # define PRODUCT_NAME_PLATFORM PRODUCT_NAME " for Windows" #elif defined(__FreeBSD__) # define PRODUCT_NAME_PLATFORM PRODUCT_NAME " for FreeBSD" #elif defined(sun) # define PRODUCT_NAME_PLATFORM PRODUCT_NAME " for Solaris" #elif defined(__APPLE__) # define PRODUCT_NAME_PLATFORM PRODUCT_NAME " for Mac OS X" #elif defined __ANDROID__ # define PRODUCT_NAME_PLATFORM PRODUCT_NAME " for Android" #else # ifdef VMX86_TOOLS # error "Define a product string for this platform." # endif #endif /* * This is for ACE Management Server * Since there is no separate product defined for Ace Mgmt Server * (i.e. PRODUCT=xxx when running makefile), we can not used the * generic PRODUCT_NAME_STRING_FOR_LICENSE definition. * As a result, the specific ACE_MGMT_SERVER_PRODUCT_NAME_FOR_LICENSE * is used instead. * A similar reason is used also for the PRODUCT_VERSION_STRING_FOR_LICENSE * definition in the vm_version.h */ #define ACE_MGMT_SERVER_PRODUCT_NAME_FOR_LICENSE "VMware ACE Management Server" /* * For Host Agent (hostd) */ #define HOST_AGENT_PRODUCT_NAME PRODUCT_NAME " Host Agent" /* Used by bora/vim/lib/vmgina module. * @todo Use this also in /bora/install/msi/InstUtil/desktop/vmInstUtil.cpp * to guarantee that the service is installed with exactly this name. */ #define HOST_AGENT_SERVICE_NAME "VMwareHostd" // Name of the environment variable that controls which proxy server to use // while opening connections to vCenter and vSphere servers. Currently vCloud // VMRC uses it. #define VMWARE_HTTPSPROXY "VMWARE_HTTPSPROXY" // Name of the environment variable that controls whether MKS traffic should // be tunnelled over HTTPS through the console proxy. Currently vCloud VMRC // uses it. #define VMWARE_HTTPSTUNNEL_MKS "VMWARE_HTTPSTUNNEL_MKS" #endif /* VM_PRODUCT_H */ open-vm-tools-9.4.0-1280544/lib/include/hgfsVirtualDir.h0000644765153500003110000000346712220061556020750 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * hgfsVirtualDir.h -- * * Defines for virtual directory names in hgfs. */ #ifndef _HGFSVIRTUALDIR_H_ # define _HGFSVIRTUALDIR_H_ /* * These are the names of the virtual directories for accessing UNC * names and drives on the host machine. */ # define HGFS_DRIVE_DIR_NAME "drive" # define HGFS_UNC_DIR_NAME "unc" #define HGFS_STR_LEN(str) (sizeof str - 1) #endif /* _HGFSVIRTUALDIR_H_ */ open-vm-tools-9.4.0-1280544/lib/include/posix.h0000644765153500003110000005677512220061556017167 0ustar dtormts/********************************************************* * Copyright (C) 2008-2011 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _POSIX_H_ #define _POSIX_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #include #include #if !defined(_WIN32) #include #include #include #endif #include "vm_basic_types.h" #include "unicodeTypes.h" #include "unicodeBase.h" #include "codeset.h" /* * Force all users of these wrappers to use the LFS (large file) interface * versions of the functions wrapper therein. If we don't do this the * wrappers may be built with the LFS versions and the callers might not * leading to a (potentially undetected) mismatch. */ #if defined(linux) && !defined(__ANDROID__) && \ (!defined(_LARGEFILE64_SOURCE) || _FILE_OFFSET_BITS != 64) #error LFS support is not enabled! #endif struct stat; #if defined(_WIN32) typedef int mode_t; #else struct statfs; struct utimbuf; struct timeval; struct passwd; #if !defined(sun) struct mntent; #else struct mnttab; #endif #endif int Posix_Creat(ConstUnicode pathName, mode_t mode); int Posix_Open(ConstUnicode pathName, int flags, ...); FILE *Posix_Fopen(ConstUnicode pathName, const char *mode); FILE *Posix_Popen(ConstUnicode pathName, const char *mode); int Posix_Rename(ConstUnicode fromPathName, ConstUnicode toPathName); int Posix_Rmdir(ConstUnicode pathName); int Posix_Unlink(ConstUnicode pathName); FILE *Posix_Freopen(ConstUnicode pathName, const char *mode, FILE *stream); int Posix_Access(ConstUnicode pathName, int mode); int Posix_EuidAccess(ConstUnicode pathName, int mode); int Posix_Stat(ConstUnicode pathName, struct stat *statbuf); int Posix_Chmod(ConstUnicode pathName, mode_t mode); void Posix_Perror(ConstUnicode str); int Posix_Printf(ConstUnicode format, ...); int Posix_Fprintf(FILE *stream, ConstUnicode format, ...); int Posix_Mkdir(ConstUnicode pathName, mode_t mode); int Posix_Chdir(ConstUnicode pathName); Unicode Posix_Getenv(ConstUnicode name); long Posix_Pathconf(ConstUnicode pathName, int name); int Posix_Lstat(ConstUnicode pathName, struct stat *statbuf); Unicode Posix_MkTemp(ConstUnicode pathName); #if !defined(_WIN32) /* * These Windows APIs actually work with non-ASCII (MBCS) strings. * Make them NULL wrappers for all other platforms. */ #define Posix_GetHostName gethostname #if defined(__APPLE__) #define Posix_GetHostByName gethostbyname #endif #define Posix_GetAddrInfo getaddrinfo #define Posix_FreeAddrInfo freeaddrinfo #define Posix_GetNameInfo getnameinfo void *Posix_Dlopen(ConstUnicode pathName, int flags); int Posix_Utime(ConstUnicode pathName, const struct utimbuf *times); int Posix_Mknod(ConstUnicode pathName, mode_t mode, dev_t dev); int Posix_Chown(ConstUnicode pathName, uid_t owner, gid_t group); int Posix_Lchown(ConstUnicode pathName, uid_t owner, gid_t group); int Posix_Link(ConstUnicode pathName1, ConstUnicode pathName2); int Posix_Symlink(ConstUnicode pathName1, ConstUnicode pathName2); int Posix_Mkfifo(ConstUnicode pathName, mode_t mode); int Posix_Truncate(ConstUnicode pathName, off_t length); int Posix_Utimes(ConstUnicode pathName, const struct timeval *time); int Posix_Execl(ConstUnicode pathName, ConstUnicode arg0, ...); int Posix_Execlp(ConstUnicode fileName, ConstUnicode arg0, ...); int Posix_Execv(ConstUnicode pathName, Unicode const argVal[]); int Posix_Execve(ConstUnicode pathName, Unicode const argVal[], Unicode const envPtr[]); int Posix_Execvp(ConstUnicode fileName, Unicode const argVal[]); DIR *Posix_OpenDir(ConstUnicode pathName); int Posix_System(ConstUnicode command); int Posix_Putenv(Unicode name); void Posix_Unsetenv(ConstUnicode name); /* * These functions return dynamically allocated stings that have to be * freed by the caller so they must be used in the ESX environment. They * are different than their POSIX "base" functions. */ Unicode Posix_RealPath(ConstUnicode pathName); Unicode Posix_ReadLink(ConstUnicode pathName); struct passwd *Posix_Getpwnam(ConstUnicode name); struct passwd *Posix_Getpwuid(uid_t uid); int Posix_Setenv(ConstUnicode name, ConstUnicode value, int overWrite); int Posix_Getpwnam_r(ConstUnicode name, struct passwd *pw, char *buf, size_t size, struct passwd **ppw); int Posix_Getpwuid_r(uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **ppw); struct passwd *Posix_Getpwent(void); struct group *Posix_Getgrnam(ConstUnicode name); int Posix_Getgrnam_r(ConstUnicode name, struct group *gr, char *buf, size_t size, struct group **pgr); #if !defined(sun) int Posix_Statfs(ConstUnicode pathName, struct statfs *statfsbuf); int Posix_GetGroupList(ConstUnicode user, gid_t group, gid_t *groups, int *ngroups); #if !defined(__APPLE__) && !defined(__FreeBSD__) int Posix_Mount(ConstUnicode source, ConstUnicode target, const char *filesystemtype, unsigned long mountflags, const void *data); int Posix_Umount(ConstUnicode target); FILE *Posix_Setmntent(ConstUnicode pathName, const char *mode); struct mntent *Posix_Getmntent(FILE *fp); struct mntent *Posix_Getmntent_r(FILE *fp, struct mntent *m, char *buf, int size); #endif // !defined(__APPLE__) && !defined(__FreeBSD__) #else // !defined(sun) int Posix_Getmntent(FILE *fp, struct mnttab *mp); #endif // !defined(sun) #if !defined(__APPLE__) /* *---------------------------------------------------------------------- * * Posix_GetHostByName -- * * Wrapper for gethostbyname(). Caller should release memory * allocated for the hostent structure returned by calling * Posix_FreeHostent(). * * Results: * NULL Error * !NULL Pointer to hostent structure * * Side effects: * None * *---------------------------------------------------------------------- */ static INLINE struct hostent* Posix_GetHostByName(ConstUnicode name) // IN { struct hostent *newhostent; int error; struct hostent he; char buffer[1024]; struct hostent *phe = &he; char **p; int i; int naddrs; ASSERT(name); if ((gethostbyname_r(name, &he, buffer, sizeof buffer, #if !defined(sun) && !defined(SOLARIS) && !defined(SOL10) &phe, #endif &error) == 0) && phe) { newhostent = (struct hostent *)Util_SafeMalloc(sizeof *newhostent); newhostent->h_name = Unicode_Alloc(phe->h_name, STRING_ENCODING_DEFAULT); if (phe->h_aliases) { newhostent->h_aliases = Unicode_AllocList(phe->h_aliases, -1, STRING_ENCODING_DEFAULT); } else { newhostent->h_aliases = NULL; } newhostent->h_addrtype = phe->h_addrtype; newhostent->h_length = phe->h_length; naddrs = 1; for (p = phe->h_addr_list; *p; p++) { naddrs++; } newhostent->h_addr_list = (char **)Util_SafeMalloc(naddrs * sizeof(*(phe->h_addr_list))); for (i = 0; i < naddrs - 1; i++) { newhostent->h_addr_list[i] = (char *)Util_SafeMalloc(phe->h_length); memcpy(newhostent->h_addr_list[i], phe->h_addr_list[i], phe->h_length); } newhostent->h_addr_list[naddrs - 1] = NULL; return newhostent; } /* There has been an error */ return NULL; } #endif // !define(__APPLE__) /* *---------------------------------------------------------------------- * * Posix_FreeHostent -- * * Free the memory allocated for an hostent structure returned * by Posix_GetHostByName. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE void Posix_FreeHostent(struct hostent *he) { #if !defined(__APPLE__) char **p; if (he) { Unicode_Free(he->h_name); if (he->h_aliases) { Unicode_FreeList(he->h_aliases, -1); } p = he->h_addr_list; while (*p) { free(*p++); } free(he->h_addr_list); free(he); } #else (void) he; #endif } #else // !define(_WIN32) #if defined(_WINSOCKAPI_) || defined(_WINSOCK2API_) #include #include "vm_atomic.h" /* *---------------------------------------------------------------------- * * Posix_GetHostName -- * * Wrapper for gethostname(). * * Results: * 0 Success * -1 Error * * Side effects: * On error, error code returned by WSAGetLastError() is updated. * *---------------------------------------------------------------------- */ static INLINE int Posix_GetHostName(Unicode name, // OUT int namelen) // IN { char *nameMBCS = (char *)Util_SafeMalloc(namelen); Unicode nameUTF8; int retval; ASSERT(name); retval = gethostname(nameMBCS, namelen); if (retval == 0) { nameUTF8 = Unicode_Alloc(nameMBCS, STRING_ENCODING_DEFAULT); if (!Unicode_CopyBytes(name, nameUTF8, namelen, NULL, STRING_ENCODING_UTF8)) { retval = -1; WSASetLastError(WSAEFAULT); } Unicode_Free(nameUTF8); } free(nameMBCS); return retval; } /* *---------------------------------------------------------------------- * * Posix_GetHostByName -- * * Wrapper for gethostbyname(). Caller should release memory * allocated for the hostent structure returned by calling * Posix_FreeHostent(). * * Results: * NULL Error * !NULL Pointer to hostent structure * * Side effects: * On error, error code returned by WSAGetLastError() is updated. * *---------------------------------------------------------------------- */ static INLINE struct hostent* Posix_GetHostByName(ConstUnicode name) // IN { struct hostent *newhostent; char *nameMBCS; struct hostent *hostentMBCS; struct hostent *ret = NULL; ASSERT(name); nameMBCS = (char *)Unicode_GetAllocBytes(name, STRING_ENCODING_DEFAULT); if (nameMBCS != NULL) { hostentMBCS = gethostbyname(nameMBCS); free(nameMBCS); if (hostentMBCS != NULL) { newhostent = (struct hostent *)Util_SafeMalloc(sizeof *newhostent); newhostent->h_name = Unicode_Alloc(hostentMBCS->h_name, STRING_ENCODING_DEFAULT); if (hostentMBCS->h_aliases) { newhostent->h_aliases = Unicode_AllocList(hostentMBCS->h_aliases, -1, STRING_ENCODING_DEFAULT); } else { newhostent->h_aliases = NULL; } newhostent->h_addrtype = hostentMBCS->h_addrtype; newhostent->h_length = hostentMBCS->h_length; newhostent->h_addr_list = hostentMBCS->h_addr_list; ret = newhostent; } } else { /* There has been an error converting from UTF-8 to local encoding. */ WSASetLastError(WSANO_RECOVERY); } return ret; } /* *---------------------------------------------------------------------- * * Posix_FreeHostent -- * * Free the memory allocated for an hostent structure returned * by Posix_GetHostByName. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static INLINE void Posix_FreeHostent(struct hostent *he) { if (he) { Unicode_Free(he->h_name); if (he->h_aliases) { Unicode_FreeList(he->h_aliases, -1); } free(he); } } #endif // defined(_WINSOCKAPI_) || defined(_WINSOCK2API_) #ifdef _WS2TCPIP_H_ typedef int (WINAPI *GetAddrInfoWFnType)(PCWSTR pNodeName, PCWSTR pServiceName, const struct addrinfo *pHints, struct addrinfoW **ppResult); typedef void (WINAPI *FreeAddrInfoWFnType)(struct addrinfoW *ai); typedef int (WINAPI *GetNameInfoWFnType)(const SOCKADDR *pSockaddr, socklen_t SockAddrLength, PWCHAR pNodeBuffer, DWORD NodeBufferSize, PWCHAR pServiceBuffer, DWORD ServiceBufferSize, INT flags); /* *---------------------------------------------------------------------- * * Posix_GetAddrInfo -- * * Wrapper for getaddrinfo(). * * Results: * 0 Success * != 0 Error * * Side effects: * On error, error code returned by WSAGetLastError() is updated. * *---------------------------------------------------------------------- */ static INLINE int Posix_GetAddrInfo(ConstUnicode nodename, // IN ConstUnicode servname, // IN const struct addrinfo *hints, // IN struct addrinfo **res) // OUT { HMODULE hWs2_32 = GetModuleHandleW(L"ws2_32"); GetAddrInfoWFnType GetAddrInfoWFn = NULL; FreeAddrInfoWFnType FreeAddrInfoWFn = NULL; int retval; char *nodenameMBCS; char *servnameMBCS; struct addrinfo *resA; ASSERT(nodename || servname); ASSERT(res); ASSERT(hWs2_32); if (hWs2_32) { GetAddrInfoWFn = (GetAddrInfoWFnType)GetProcAddress(hWs2_32, "GetAddrInfoW"); FreeAddrInfoWFn = (FreeAddrInfoWFnType)GetProcAddress(hWs2_32, "FreeAddrInfoW"); } /* * If the unicode version of getaddrinfo exists, use it. The string * conversion required is between UTF-8 and UTF-16 encodings. Note * that struct addrinfo and ADDRINFOW are identical except for the * fields ai_canonname (char * vs. PWSTR) and ai_next (obviously). */ if (GetAddrInfoWFn && FreeAddrInfoWFn) { utf16_t *nodenameW = Unicode_GetAllocUTF16(nodename); utf16_t *servnameW = Unicode_GetAllocUTF16(servname); struct addrinfoW *resW; retval = (*GetAddrInfoWFn)(nodenameW, servnameW, hints, &resW); if (retval == 0) { struct addrinfoW *cur; struct addrinfo **pres = res; for (cur = resW; cur != NULL; cur = cur->ai_next) { *pres = (struct addrinfo *)Util_SafeMalloc(sizeof **pres); (*pres)->ai_flags = cur->ai_flags; (*pres)->ai_family = cur->ai_family; (*pres)->ai_socktype = cur->ai_socktype; (*pres)->ai_protocol = cur->ai_protocol; (*pres)->ai_addrlen = cur->ai_addrlen; if (cur->ai_canonname) { (*pres)->ai_canonname = Unicode_AllocWithUTF16(cur->ai_canonname); } else { (*pres)->ai_canonname = NULL; } (*pres)->ai_addr = (struct sockaddr *) Util_SafeMalloc((*pres)->ai_addrlen); memcpy((*pres)->ai_addr, cur->ai_addr, (*pres)->ai_addrlen); pres = &((*pres)->ai_next); } *pres = NULL; FreeAddrInfoWFn(resW); } free(nodenameW); free(servnameW); goto exit; } /* * We did not find the unicode version of getaddrinfo, so we need to * convert strings to and from the local encoding. */ nodenameMBCS = (char *)Unicode_GetAllocBytes(nodename, STRING_ENCODING_DEFAULT); servnameMBCS = (char *)Unicode_GetAllocBytes(servname, STRING_ENCODING_DEFAULT); retval = getaddrinfo(nodenameMBCS, servnameMBCS, hints, &resA); if (retval == 0) { struct addrinfo **pres = res; struct addrinfo *cur; for (cur = resA; cur != NULL; cur = cur->ai_next) { *pres = (struct addrinfo *)Util_SafeMalloc(sizeof **pres); (*pres)->ai_flags = cur->ai_flags; (*pres)->ai_family = cur->ai_family; (*pres)->ai_socktype = cur->ai_socktype; (*pres)->ai_protocol = cur->ai_protocol; (*pres)->ai_addrlen = cur->ai_addrlen; if (cur->ai_canonname) { (*pres)->ai_canonname = Unicode_Alloc(cur->ai_canonname, STRING_ENCODING_DEFAULT); } else { (*pres)->ai_canonname = NULL; } (*pres)->ai_addr = (struct sockaddr *) Util_SafeMalloc((*pres)->ai_addrlen); memcpy((*pres)->ai_addr, cur->ai_addr, (*pres)->ai_addrlen); pres = &((*pres)->ai_next); } *pres = NULL; freeaddrinfo(resA); } free(nodenameMBCS); free(servnameMBCS); exit: return retval; } /* *---------------------------------------------------------------------------- * * Posix_FreeAddrInfo -- * * Free the addrinfo structure allocated by Posix_GetAddrInfo. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static INLINE void Posix_FreeAddrInfo(struct addrinfo *ai) { struct addrinfo *temp; while (ai) { temp = ai; ai = ai->ai_next; free(temp->ai_canonname); free(temp->ai_addr); free(temp); } } /* *---------------------------------------------------------------------- * * Posix_GetNameInfo -- * * Wrapper for getnameinfo(). * * Results: * 0 Success * != 0 Error * * Side effects: * On error, error code returned by WSAGetLastError() is updated. * *---------------------------------------------------------------------- */ static INLINE int Posix_GetNameInfo(const struct sockaddr *sa, // IN socklen_t salen, // IN Unicode host, // OUT DWORD hostlen, // IN Unicode serv, // OUT DWORD servlen, // IN int flags) // IN { HMODULE hWs2_32; int retval; char *hostMBCS = NULL; char *servMBCS = NULL; utf16_t *hostW = NULL; utf16_t *servW = NULL; Unicode hostUTF8 = NULL; Unicode servUTF8 = NULL; GetNameInfoWFnType GetNameInfoWFn; hWs2_32 = LoadLibraryW(L"ws2_32"); if (hWs2_32) { /* * If the unicode version of getnameinfo exists, use it. The string * conversion required is between UTF-8 and UTF-16 encodings. */ GetNameInfoWFn = (GetNameInfoWFnType)GetProcAddress(hWs2_32, "GetNameInfoW"); if (GetNameInfoWFn) { if (host) { hostW = (utf16_t *)Util_SafeMalloc(hostlen * sizeof *hostW); } if (serv) { servW = (utf16_t *)Util_SafeMalloc(servlen * sizeof *servW); } retval = (*GetNameInfoWFn)(sa, salen, hostW, hostlen, servW, servlen, flags); if (retval == 0) { if (host) { hostUTF8 = Unicode_AllocWithUTF16(hostW); if (!Unicode_CopyBytes(host, hostUTF8, hostlen, NULL, STRING_ENCODING_UTF8)) { retval = EAI_MEMORY; WSASetLastError(WSA_NOT_ENOUGH_MEMORY); goto exit; } } if (serv) { servUTF8 = Unicode_AllocWithUTF16(servW); if (!Unicode_CopyBytes(serv, servUTF8, servlen, NULL, STRING_ENCODING_UTF8)) { retval = EAI_MEMORY; WSASetLastError(WSA_NOT_ENOUGH_MEMORY); goto exit; } } } goto exit; } } /* * We did not find the unicode version of getnameinfo, so we need to * convert strings to and from the local encoding. */ if (host) { hostMBCS = (char *)Util_SafeMalloc(hostlen * sizeof *hostMBCS); } if (serv) { servMBCS = (char *)Util_SafeMalloc(servlen * sizeof *servMBCS); } retval = getnameinfo(sa, salen, hostMBCS, hostlen, servMBCS, servlen, flags); if (retval == 0) { if (host) { hostUTF8 = Unicode_Alloc(hostMBCS, STRING_ENCODING_DEFAULT); if (!Unicode_CopyBytes(host, hostUTF8, hostlen, NULL, STRING_ENCODING_UTF8)) { retval = EAI_MEMORY; WSASetLastError(WSA_NOT_ENOUGH_MEMORY); goto exit; } } if (serv) { servUTF8 = Unicode_Alloc(servMBCS, STRING_ENCODING_DEFAULT); if (!Unicode_CopyBytes(serv, servUTF8, servlen, NULL, STRING_ENCODING_UTF8)) { retval = EAI_MEMORY; WSASetLastError(WSA_NOT_ENOUGH_MEMORY); goto exit; } } } exit: if (hWs2_32) { FreeLibrary(hWs2_32); free(hostW); free(servW); } free(hostMBCS); free(servMBCS); free(hostUTF8); free(servUTF8); return retval; } #endif // ifdef _WS2TCPIP_H_ #endif // !define(_WIN32) #if (defined(VMX86_SERVER) || defined(__APPLE__)) && \ !defined(UNICODE_BUILDING_POSIX_WRAPPERS) /* * ESX and Mac OS are UTF-8 environments so these functions can be * "defined away" - the POSIX wrapper call can be directly mapped to the * POSIX function avoiding unneccesary (call and handling) overhead. * * NOTE: PLEASE KEEP THESE IN SORTED ORDER */ #define Posix_Access access #define Posix_Chdir chdir #define Posix_Chmod chmod #define Posix_Chown chown #define Posix_Creat creat #define Posix_Dlopen dlopen #define Posix_Execl execl #define Posix_Execlp execlp #define Posix_Execv execv #define Posix_Execve execve #define Posix_Execvp execvp #define Posix_Fopen fopen #define Posix_Fprintf fprintf #define Posix_Freopen freopen #define Posix_Getenv getenv #define Posix_GetGroupList getgrouplist #define Posix_Getmntent getmntent #define Posix_Getmntent_r getmntent_r #define Posix_Getpwnam getpwnam #define Posix_Getpwnam_r getpwnam_r #define Posix_Getpwuid getpwuid #define Posix_Getpwuid_r getpwuid_r #define Posix_Getgrnam getgrnam #define Posix_Getgrnam_r getgrnam_r #define Posix_Lchown lchown #define Posix_Link link #define Posix_Lstat lstat #define Posix_Mkdir mkdir #define Posix_Mkfifo mkfifo #define Posix_Mknod mknod #define Posix_Mount mount #define Posix_Open open #define Posix_OpenDir opendir #define Posix_Pathconf pathconf #define Posix_Perror perror #define Posix_Popen popen #define Posix_Printf printf #define Posix_Putenv putenv #define Posix_Rename rename #define Posix_Rmdir rmdir #define Posix_Setenv setenv #define Posix_Setmntent setmntent #define Posix_Stat stat #define Posix_Statfs statfs #define Posix_Symlink symlink #define Posix_System system #define Posix_Truncate truncate #define Posix_Umount umount #define Posix_Unlink unlink #define Posix_Unsetenv unsetenv #define Posix_Utime utime #define Posix_Utimes utimes #endif #endif // _POSIX_H_ open-vm-tools-9.4.0-1280544/lib/include/vmblock_user.h0000644765153500003110000001250712220061556020501 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * vmblock_user.h -- * * Provides interfaces that allow user level programs to talk to the * vmblock fs. */ #ifndef _VMBLOCK_USER_H_ #define _VMBLOCK_USER_H_ #include "vm_basic_types.h" #include "vmblock.h" static INLINE int VMBLOCK_CONTROL_FUSE(int fd, // IN char op, // IN const char *path) // IN { /* * buffer needs room for an operation character and a string with max length * PATH_MAX - 1. */ char buffer[PATH_MAX]; size_t pathLength; pathLength = strlen(path); if (pathLength >= PATH_MAX) { errno = ENAMETOOLONG; return -1; } buffer[0] = op; memcpy(buffer + 1, path, pathLength); /* * The lseek is only to prevent the file pointer from overflowing; * vmblock-fuse ignores the file pointer / offset. Overflowing the file * pointer causes write to fail: * http://article.gmane.org/gmane.comp.file-systems.fuse.devel/6648 * There's also a race condition here where many threads all calling * VMBLOCK_CONTROL at the same time could have all their seeks executed one * after the other, followed by all the writes. Again, it's not a problem * unless the file pointer overflows which is very unlikely with 32 bit * offsets and practically impossible with 64 bit offsets. */ if (lseek(fd, 0, SEEK_SET) < 0) { return -1; } if (write(fd, buffer, pathLength + 1) < 0) { return -1; } return 0; } #if defined(vmblock_fuse) #define VMBLOCK_CONTROL(fd, op, path) VMBLOCK_CONTROL_FUSE(fd, op, path) #elif defined(linux) static INLINE int VMBLOCK_CONTROL(int fd, int op, const char *path) { return write(fd, path, op); } #elif defined(__FreeBSD__) static INLINE int VMBLOCK_CONTROL(int fd, int cmd, const char *path) { char tpath[MAXPATHLEN]; size_t pathSize; if (path == NULL) { return -1; } /* * FreeBSD's ioctl data parameters must be of fixed size. Guarantee a safe * buffer of size MAXPATHLEN by copying the user's string to one of our own. */ pathSize = strlcpy(tpath, path, MAXPATHLEN); if (pathSize >= sizeof tpath) { return -1; } return ioctl(fd, cmd, tpath); } #elif defined(sun) static INLINE int VMBLOCK_CONTROL(int fd, int cmd, const char *path) { return ioctl(fd, cmd, path); } #endif #endif // _VMBLOCK_USER_H_ open-vm-tools-9.4.0-1280544/lib/include/vthreadBase.h0000644765153500003110000000726012220061556020236 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vthreadBase.h -- * * Subset of vthread defines that are used by libs that need to make * vthread calls but don't actually do any vthreading. * * May be used without lib/thread or with lib/thread. (But don't try * to do both simultaneously, since lib/thread needs to do more * bookkeeping.) */ #ifndef VTHREAD_BASE_H #define VTHREAD_BASE_H #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #include "vm_atomic.h" #if !defined VMM && !defined WIN32 #define VTHREAD_USE_PTHREAD 1 #include #endif /* * Types */ typedef unsigned VThreadID; #define VTHREAD_INVALID_ID (VThreadID)(~0u) /* XXX Vestigial need as an MXState array size */ #define VTHREAD_MAX_THREADS 160 #ifdef VMM /* *----------------------------------------------------------------------------- * * VThread_CurID -- * VThread_CurName -- * * Get the current thread ID / name. This is only inline for the monitor. * * The extern symbols herein are defined in monitor.c and * initialized by SharedArea_PowerOn. * * Results: * Thread ID / name. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE VThreadID VThread_CurID(void) { extern const VThreadID vthreadCurID; return vthreadCurID; } static INLINE const char * VThread_CurName(void) { extern const char vcpuThreadName[]; return vcpuThreadName; } #else #define VTHREAD_VMX_ID 0 #define VTHREAD_MKS_ID 1 #define VTHREAD_OTHER_ID 2 #define VTHREAD_ALLOCSTART_ID 3 #define VTHREADBASE_MAX_NAME 32 /* Arbitrary */ typedef struct { VThreadID id; char name[VTHREADBASE_MAX_NAME]; #if !defined _WIN32 Atomic_Int signalNestCount; #endif } VThreadBaseData; /* Common VThreadBase functions */ const char *VThreadBase_CurName(void); VThreadID VThreadBase_CurID(void); void VThreadBase_SetName(const char *name); /* For implementing a thread library */ Bool VThreadBase_InitWithTLS(VThreadBaseData *tls); void VThreadBase_ForgetSelf(void); void VThreadBase_SetNoIDFunc(void (*func)(void), void (*destr)(void *)); /* Match up historical VThread_ names with VThreadBase_ names */ static INLINE const char * VThread_CurName(void) { return VThreadBase_CurName(); } static INLINE VThreadID VThread_CurID(void) { return VThreadBase_CurID(); } static INLINE void VThread_SetName(const char *name) { VThreadBase_SetName(name); } #ifdef _WIN32 static INLINE Bool VThreadBase_IsInSignal(void) { /* Win32 does not worry about async-signal-safety. */ return FALSE; } #else Bool VThreadBase_IsInSignal(void); void VThreadBase_SetIsInSignal(VThreadID tid, Bool isInSignal); int VThreadBase_SigMask(int how, const sigset_t *newmask, sigset_t *oldmask); #endif #endif /* VMM */ #endif // VTHREAD_BASE_H open-vm-tools-9.4.0-1280544/lib/include/panic.h0000644765153500003110000000462512220061556017102 0ustar dtormts/********************************************************* * Copyright (C) 2003 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * panic.h -- * * Module to encapsulate common Panic behavior. */ #ifndef _PANIC_H_ #define _PANIC_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" /* * Initialize module to read custom behavior from config files. */ void Panic_Init(void); /* * If you want the Panic module to just handle everything: implement Panic() * as a call to Panic_Panic(). If you want to implement your own Panic(), * you can still use functions below to query whether certain features are * desired and get the default implementation of each feature. */ NORETURN void Panic_Panic(const char *format, va_list args); /* * On panic, post a UI dialog about the panic and how to diagnose it: */ void Panic_SetPanicMsgPost(Bool postMsg); Bool Panic_GetPanicMsgPost(void); void Panic_PostPanicMsg(const char *format, ...); /* * On panic, break into a debugger or enter an infinite loop until a * debugger stops it: */ void Panic_SetBreakOnPanic(Bool breakOnPanic); Bool Panic_GetBreakOnPanic(void); void Panic_BreakOnPanic(void); void Panic_LoopOnPanic(void); /* * On panic, dump core; Panic is also the place where various pieces of * back end stash information about the core dump. */ void Panic_SetCoreDumpOnPanic(Bool dumpCore); Bool Panic_GetCoreDumpOnPanic(void); void Panic_SetCoreDumpFileName(const char *fileName); int Panic_GetCoreDumpFlags(void); void Panic_SetCoreDumpFlags(int flags); /* * Extra debugging information that Panic module knows how to dump. */ void Panic_DumpGuiResources(void); #endif // _PANIC_H_ open-vm-tools-9.4.0-1280544/lib/include/libExport.hh0000644765153500003110000000266212220061556020127 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * libExport.hh -- * * Declares proper decorations for dll-export interface * for all modules in libs. */ #ifndef LIB_EXPORT_HH #define LIB_EXPORT_HH #include "vm_api.h" #ifdef LIB_EXPORT_SOURCE #define LIB_EXPORT VMW_LIB_DYNAMIC #else #define LIB_EXPORT VMW_LIB_CLIENT #endif #ifdef LIB_EXPORT_WUI_SOURCE #define LIB_EXPORT_WUI VMW_LIB_DYNAMIC #else #define LIB_EXPORT_WUI VMW_LIB_CLIENT #endif #ifdef VMSTRING_EXPORT_SOURCE #define VMSTRING_EXPORT VMW_LIB_DYNAMIC #else #define VMSTRING_EXPORT VMW_LIB_CLIENT #endif #endif // LIB_EXPORT_HH open-vm-tools-9.4.0-1280544/lib/include/vmxrpc.h0000644765153500003110000001336712220061556017332 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vmxrpc.h -- * * VMware extensions to XDR types. Wrappers to allow the use of types declared * in vm_basic_types.h in structures. */ #ifndef _VMXRPC_H_ #define _VMXRPC_H_ #include #include #include "vm_basic_types.h" /* * glibc and Solaris headers seem to define functions for unsigned types with * slightly different names than all other platforms. Provide macros to * translate the names to the more common ones. */ #if defined(__GLIBC__) || defined(sun) # define xdr_u_int16_t(x, i) xdr_uint16_t(x, i) # define xdr_u_int32_t(x, i) xdr_uint32_t(x, i) # define xdr_u_int64_t(x, i) xdr_uint64_t(x, i) #endif /* Wrapper around xdr_free that does casting automatically. */ #define VMX_XDR_FREE(func, data) xdr_free((xdrproc_t)(func), (char *)(data)) /* *----------------------------------------------------------------------------- * * xdr_int8 -- * * XDR function for encoding/decoding int8. * * Results: * Whether the call succeeded. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE bool_t xdr_int8(XDR *xdrs, // IN int8 *ip) // IN/OUT { /* XDR doesn't seem to have a "signed char" representation. */ return xdr_char(xdrs, (char*)ip); } /* *----------------------------------------------------------------------------- * * xdr_uint8 -- * * XDR function for encoding/decoding uint8. * * Results: * Whether the call succeeded. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE bool_t xdr_uint8(XDR *xdrs, // IN uint8 *ip) // IN/OUT { return xdr_u_char(xdrs, ip); } /* *----------------------------------------------------------------------------- * * xdr_int16 -- * * XDR function for encoding/decoding int16. * * Results: * Whether the call succeeded. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE bool_t xdr_int16(XDR *xdrs, // IN int16 *ip) // IN/OUT { return xdr_int16_t(xdrs, ip); } /* *----------------------------------------------------------------------------- * * xdr_uint16 -- * * XDR function for encoding/decoding uint16. * * Results: * Whether the call succeeded. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE bool_t xdr_uint16(XDR *xdrs, // IN uint16 *ip) // IN/OUT { return xdr_u_int16_t(xdrs, ip); } /* *----------------------------------------------------------------------------- * * xdr_int32 -- * * XDR function for encoding/decoding int32. * * Results: * Whether the call succeeded. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE bool_t xdr_int32(XDR *xdrs, // IN int32 *ip) // IN/OUT { return xdr_int32_t(xdrs, ip); } /* *----------------------------------------------------------------------------- * * xdr_uint32 -- * * XDR function for encoding/decoding uint32. * * Results: * Whether the call succeeded. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE bool_t xdr_uint32(XDR *xdrs, // IN uint32 *ip) // IN/OUT { return xdr_u_int32_t(xdrs, ip); } /* *----------------------------------------------------------------------------- * * xdr_int64 -- * * XDR function for encoding/decoding int64. * * Results: * Whether the call succeeded. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE bool_t xdr_int64(XDR *xdrs, // IN int64 *ip) // IN/OUT { return xdr_int64_t(xdrs, ip); } /* *----------------------------------------------------------------------------- * * xdr_uint64 -- * * XDR function for encoding/decoding uint64. * * Results: * Whether the call succeeded. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE bool_t xdr_uint64(XDR *xdrs, // IN uint64 *ip) // IN/OUT { return xdr_u_int64_t(xdrs, ip); } /* See vm_basic_types.h. X defines a different Bool. */ #if !defined(__STRICT_ANSI__) || defined(__FreeBSD__) /* *----------------------------------------------------------------------------- * * xdr_Bool -- * * XDR function for encoding/decoding Bool. * * Results: * Whether the call succeeded. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE bool_t xdr_Bool(XDR *xdrs, // IN Bool *ip) // IN/OUT { return xdr_char(xdrs, ip); } #endif #endif /* _VMXRPC_H_ */ open-vm-tools-9.4.0-1280544/lib/include/hgfsDevLinux.h0000644765153500003110000000632112220061556020411 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * hgfsDev.h -- * * Header for code shared between the hgfs linux kernel module driver * and the pserver. */ #ifndef _HGFS_DEV_H_ #define _HGFS_DEV_H_ #include "vm_basic_types.h" #include "hgfs.h" #define HGFS_NAME "vmhgfs" // Name of FS (e.g. "mount -t vmhgfs") #define HGFS_DEVICE_NAME "dev" // Name of our device under /proc/fs/HGFS_NAME/ #define HGFS_SUPER_MAGIC 0xbacbacbc // Superblock magic number #define HGFS_PROTOCOL_VERSION 1 // Incremented when something changes #define HGFS_DEFAULT_TTL 1 // Default TTL for dentries /* * Mount information, passed from pserver process to kernel * at mount time. * * XXX: I'm hijacking this struct. In the future, when the Solaris HGFS driver * loses its pserver, the struct will be used by /sbin/mount.vmhgfs solely. * As is, it is also used by the Solaris pserver. */ typedef struct HgfsMountInfo { uint32 magicNumber; // hgfs magic number uint32 version; // protocol version uint32 fd; // file descriptor of client file #ifndef sun uid_t uid; // desired owner of files Bool uidSet; // is the owner actually set? gid_t gid; // desired group of files Bool gidSet; // is the group actually set? unsigned short fmask; // desired file mask unsigned short dmask; // desired directory mask uint32 ttl; // number of seconds before revalidating dentries #if defined __APPLE__ char shareNameHost[MAXPATHLEN]; // must be ".host" char shareNameDir[MAXPATHLEN]; // desired share name for mounting #else const char *shareNameHost; // must be ".host" const char *shareNameDir; // desired share name for mounting #endif #endif } HgfsMountInfo; #endif //ifndef _HGFS_DEV_H_ open-vm-tools-9.4.0-1280544/lib/include/vixCommands.h0000644765153500003110000023402612220061556020300 0ustar dtormts/********************************************************* * Copyright (C) 2003 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vixCommands.h -- * * Defines used when Vix crosses various IPC boundaries. */ #ifndef _VIX_COMMANDS_H_ #define _VIX_COMMANDS_H_ #include "vm_version.h" #include "vixOpenSource.h" /* * These describe the format of the message objects. * This will change when the client/vmx support different * structures for the message header. Hopefully, that won't * happen. */ #define VIX_COMMAND_MAGIC_WORD 0xd00d0001 #define VIX_COMMAND_MESSAGE_VERSION 5 /* * These give upper bounds for how big any VIX IPC meesage * should be. There are for sanity checks and to ignore maliciously * large messages that may be part of an DoS attack. The may need to * be revised if large messages are added to the protocol. */ #define VIX_COMMAND_MAX_SIZE (16 * 1024 * 1024) #define VIX_COMMAND_MAX_REQUEST_SIZE 65536 /* * We don't want to allow guest ops commands with input size too large. * Limit it to the max request size with enough room for the credentials. * Check bugs 824773, 926819 for more details. */ #define VIX_COMMAND_MAX_USER_INPUT_SIZE (VIX_COMMAND_MAX_REQUEST_SIZE - 5000) /* * The types of credential we can pass with any request. */ #define VIX_USER_CREDENTIAL_NONE 0 #define VIX_USER_CREDENTIAL_NAME_PASSWORD 1 #define VIX_USER_CREDENTIAL_ANONYMOUS 2 #define VIX_USER_CREDENTIAL_ROOT 3 #define VIX_USER_CREDENTIAL_NAME_PASSWORD_OBFUSCATED 4 #define VIX_USER_CREDENTIAL_CONSOLE_USER 5 #define VIX_USER_CREDENTIAL_HOST_CONFIG_SECRET 6 #define VIX_USER_CREDENTIAL_HOST_CONFIG_HASHED_SECRET 7 #define VIX_USER_CREDENTIAL_NAMED_INTERACTIVE_USER 8 #define VIX_USER_CREDENTIAL_TICKETED_SESSION 9 #define VIX_USER_CREDENTIAL_SSPI 10 #define VIX_USER_CREDENTIAL_SAML_BEARER_TOKEN 11 #define VIX_SHARED_SECRET_CONFIG_USER_NAME "__VMware_Vix_Shared_Secret_1__" /* * This is the port for the server side remote Vix component */ #define VIX_SERVER_PORT 61525 #define VIX_TOOLS_SOCKET_PORT 61526 /* * These are the flags set in the commonFlags field. */ enum VixCommonCommandOptionValues { VIX_COMMAND_REQUEST = 0x01, VIX_COMMAND_REPORT_EVENT = 0x02, VIX_COMMAND_FORWARD_TO_GUEST = 0x04, VIX_COMMAND_GUEST_RETURNS_STRING = 0x08, VIX_COMMAND_GUEST_RETURNS_INTEGER_STRING = 0x10, /* DEPRECATED VIX_COMMAND_GUEST_RETURNS_ENCODED_STRING = 0x20, */ VIX_COMMAND_GUEST_RETURNS_PROPERTY_LIST = 0x40, VIX_COMMAND_GUEST_RETURNS_BINARY = 0x80, // We cannot add more constants here. This is stored in a uint8, // so it is full. Use requestFlags or responseFlags. }; /* * These are the flags set in the request Flags field. */ enum { VIX_REQUESTMSG_ONLY_RELOAD_NETWORKS = 0x01, VIX_REQUESTMSG_RETURN_ON_INITIATING_TOOLS_UPGRADE = 0x02, VIX_REQUESTMSG_RUN_IN_ANY_VMX_STATE = 0x04, VIX_REQUESTMSG_REQUIRES_INTERACTIVE_ENVIRONMENT = 0x08, VIX_REQUESTMSG_INCLUDES_AUTH_DATA_V1 = 0x10, VIX_REQUESTMSG_REQUIRES_VMDB_NOTIFICATION = 0x20, VIX_REQUESTMSG_ESCAPE_XML_DATA = 0x40, }; /* * These are the flags set in responseFlags. */ enum VixResponseFlagsValues { VIX_RESPONSE_SOFT_POWER_OP = 0x0001, VIX_RESPONSE_EXTENDED_RESULT_V1 = 0x0002, VIX_RESPONSE_TRUNCATED = 0x0004, VIX_RESPONSE_FSR = 0x0008, VIX_RESPONSE_VMDB_NOTIFICATION_POSTED = 0x0010, }; /* * This is the header for one message, either a request or a * response, and sent either to or from the VMX. * * Every message has 3 regions: * * ------------------------------------- * | Header | Body | Credential | * ------------------------------------- * * The credential and the body may either or both be empty. * The 3 regions always appear in this order. First the header, then a body * if there is one, then a credential if there is one. * There should be no gaps between these regions. New regions are added * to the end. This means the lengths can also be used to compute * offsets to the regions. * * The length of the headers, the credential, and the body are all stored in * the common header. This should allow parsing code to receive complete * messages even if it does not understand them. * * Currently that the credential is only used for a Request. It is * currently empty for a response. * */ typedef #include "vmware_pack_begin.h" struct VixMsgHeader { uint32 magic; uint16 messageVersion; uint32 totalMessageLength; uint32 headerLength; uint32 bodyLength; uint32 credentialLength; uint8 commonFlags; } #include "vmware_pack_end.h" VixMsgHeader; /* * These are the headers for a single request, response, or event. * In theory, either the VMX or the client may issue a request * to the other. In practice, legacy foundry clients can only * accept response messages from the VMX, not requests. Because of * this, an event message is a special kind of response message. */ typedef #include "vmware_pack_begin.h" struct VixCommandRequestHeader { VixMsgHeader commonHeader; uint32 opCode; uint32 requestFlags; uint32 timeOut; uint64 cookie; uint32 clientHandleId; // for remote case uint32 userCredentialType; } #include "vmware_pack_end.h" VixCommandRequestHeader; typedef #include "vmware_pack_begin.h" struct VixCommandResponseHeader { VixMsgHeader commonHeader; uint64 requestCookie; uint32 responseFlags; uint32 duration; uint32 error; uint32 additionalError; uint32 errorDataLength; } #include "vmware_pack_end.h" VixCommandResponseHeader; typedef #include "vmware_pack_begin.h" struct VixMsgEventHeader { VixCommandResponseHeader responseHeader; int32 eventType; } #include "vmware_pack_end.h" VixMsgEventHeader; /* * A trivial request that is just a generic * response header (it has no body). */ typedef #include "vmware_pack_begin.h" struct VixMsgTrivialRequest { VixCommandRequestHeader header; } #include "vmware_pack_end.h" VixMsgTrivialRequest; /* * A trivial event that is just a generic * event header (it has no body). */ typedef #include "vmware_pack_begin.h" struct VixMsgTrivialEvent { VixMsgEventHeader eventHeader; } #include "vmware_pack_end.h" VixMsgTrivialEvent; /* * ********************************************************** * This is a generic progress update from the VMX. * The VMX may send several of these before sending a final response * message. These only report progress, they do not mean the job * has completed. These messages are identified by the * VIX_COMMAND_REPORT_EVENT flag in the commonFlags field and * VIX_EVENTTYPE_JOB_PROGRESS as the eventType. */ typedef #include "vmware_pack_begin.h" struct VixMsgProgressEvent { VixMsgEventHeader eventHeader; int64 workToDo; int64 workDone; } #include "vmware_pack_end.h" VixMsgProgressEvent; /* * This is an event sent from the VMX to all clients when some property changes. * It may be used for any runtime property. */ typedef #include "vmware_pack_begin.h" struct VixMsgPropertyChangedEvent { VixMsgEventHeader eventHeader; int options; uint32 propertyListSize; } #include "vmware_pack_end.h" VixMsgPropertyChangedEvent; /* * ********************************************************** * This is a userName and password pair. */ typedef #include "vmware_pack_begin.h" struct VixCommandNamePassword { uint32 nameLength; uint32 passwordLength; } #include "vmware_pack_end.h" VixCommandNamePassword; /* * ********************************************************** * This is a ticketed session for authentication. */ typedef #include "vmware_pack_begin.h" struct VixCommandTicketedSession { uint32 ticketLength; } #include "vmware_pack_end.h" VixCommandTicketedSession; /* * ********************************************************** * This is a SSPI token for acquiring credentials */ typedef #include "vmware_pack_begin.h" struct VixCommandSSPI { uint32 tokenLength; } #include "vmware_pack_end.h" VixCommandSSPI; /* * ********************************************************** * This is a SAML bearer token with optional userName to specify * an IdProvider store. */ typedef #include "vmware_pack_begin.h" struct VixCommandSAMLToken { uint32 tokenLength; uint32 nameLength; } #include "vmware_pack_end.h" VixCommandSAMLToken; /* * ********************************************************** * Basic power op request. The response is just a generic * response header (it has no body). */ typedef #include "vmware_pack_begin.h" struct VixMsgPowerOpRequest { VixCommandRequestHeader header; VixVMPowerOpOptions powerOpOptions; /* * Starting in Workstation 7.0, a serialized property list buffer * can be appended here. This was originally used for augmenting * poweroff to support revert to snapshot upon poweroff functionality. */ } #include "vmware_pack_end.h" VixMsgPowerOpRequest; /* * ********************************************************** * Get/Set Properties Request */ typedef #include "vmware_pack_begin.h" struct VixMsgGetVMStateResponse { VixCommandResponseHeader header; uint32 bufferSize; // This is followed by the buffer of serialized properties } #include "vmware_pack_end.h" VixMsgGetVMStateResponse; typedef #include "vmware_pack_begin.h" struct VixMsgSetVMStateRequest { VixCommandRequestHeader header; uint32 bufferSize; // This is followed by the buffer of serialized properties } #include "vmware_pack_end.h" VixMsgSetVMStateRequest; typedef #include "vmware_pack_begin.h" struct VixMsgAuthDataV1 { int64 nonce; uint32 sequenceNumber; uint8 hashValue[32]; } #include "vmware_pack_end.h" VixMsgAuthDataV1; /* * ********************************************************** * Basic reload state request. The response is just a generic * response header (it has no body). */ typedef #include "vmware_pack_begin.h" struct VixMsgReloadVMStateRequest { VixCommandRequestHeader header; // This is followed by an array of VixMsgConfigurationObjectType objects } #include "vmware_pack_end.h" VixMsgReloadVMStateRequest; /* * This is a prefix to a configuration object. The current supported * types are defined below in the VixCommonConfigObjectType enum. * Following each object type struct is the specific object. Currently, * we support: * * VIX_NETWORK_SETTING_CONFIG - VixMsgNICBandwidth */ typedef #include "vmware_pack_begin.h" struct VixMsgConfigurationObjectType { int32 configurationType; uint32 objectSize; } #include "vmware_pack_end.h" VixMsgConfigurationObjectType; typedef #include "vmware_pack_begin.h" struct VixMsgNICBandwidth { Bool validNICNum; int32 nicNum; char pvnGUID[64]; uint32 totalBandwidth; uint32 maxSendBandwidth; uint32 maxReceiveBandwidth; uint32 packetLossPattern; uint32 packetLossRate; uint32 packetLossMinBurstDuration; uint32 packetLossMaxBurstDuration; uint32 minLatency; uint32 maxLatency; uint32 options; } #include "vmware_pack_end.h" VixMsgNICBandwidth; typedef #include "vmware_pack_begin.h" struct VixMsgLANSegmentConfiguration { VixMsgConfigurationObjectType configHeader; VixMsgNICBandwidth lanSegment; } #include "vmware_pack_end.h" VixMsgLANSegmentConfiguration; /* * These are options to the bandwidth commands. */ enum VixMsgPacketLossType { // packetLossPattern values VIX_PACKETLOSS_RANDOM = 1, }; /* * These are the types of configuration objects we can send * to a VIX_COMMAND_RELOAD_VM command. */ enum VixMsgConfigObjectType { VIX_LAN_SEGMENT_SETTING_CONFIG = 1, }; /* * ********************************************************** * Wait for tools request. The response is just a generic * response header (it has no body). */ typedef #include "vmware_pack_begin.h" struct VixMsgWaitForToolsRequest { VixCommandRequestHeader header; int32 timeoutInSeconds; int32 minVersion; } #include "vmware_pack_end.h" VixMsgWaitForToolsRequest; /* * ********************************************************** * Run a program on the guest. */ typedef #include "vmware_pack_begin.h" struct VixMsgRunProgramRequest { VixCommandRequestHeader header; int32 runProgramOptions; uint32 programNameLength; uint32 commandLineArgsLength; } #include "vmware_pack_end.h" VixMsgRunProgramRequest; typedef #include "vmware_pack_begin.h" struct VixMsgOldRunProgramResponse { VixCommandResponseHeader header; int32 exitCode; VmTimeType deltaTime; } #include "vmware_pack_end.h" VixMsgOldRunProgramResponse; typedef #include "vmware_pack_begin.h" struct VixMsgRunProgramResponse { VixCommandResponseHeader header; int32 exitCode; VmTimeType deltaTime; int64 pid; uint32 stdOutLength; uint32 stdErrLength; } #include "vmware_pack_end.h" VixMsgRunProgramResponse; /* * ********************************************************** * Install VMware tools. */ typedef #include "vmware_pack_begin.h" struct VixMsgInstallToolsRequest { VixCommandRequestHeader header; int32 installOptions; uint32 commandLineArgsLength; } #include "vmware_pack_end.h" VixMsgInstallToolsRequest; /* * ********************************************************** * Send keystrokes to the guest. */ enum VixKeyStrokeCharType { VIX_KEYSTROKE_SCANCODE = 1, VIX_KEYSTROKE_TEXT_CHAR = 2, }; enum VixKeyStrokeModifiers { VIX_KEYSTROKE_MODIFIER_KEY_DOWN = 0x01, VIX_KEYSTROKE_MODIFIER_KEY_UP = 0x02, VIX_KEYSTROKE_MODIFIER_CONTROL = 0x04, VIX_KEYSTROKE_MODIFIER_SHIFT = 0x08, VIX_KEYSTROKE_MODIFIER_ALT = 0x10, VIX_KEYSTROKE_MODIFIER_KEY_DOWN_ONLY = 0x80, VIX_KEYSTROKE_MODIFIER_KEY_UP_ONLY = 0x100, }; typedef #include "vmware_pack_begin.h" struct VixMsgKeyStroke { int32 modifier; int32 scanCode; int32 duration; int32 delayAfterKeyUp; int32 repeat; } #include "vmware_pack_end.h" VixMsgKeyStroke; typedef #include "vmware_pack_begin.h" struct VixMsgSendKeyStrokesRequest { VixCommandRequestHeader header; int32 keyStrokeType; int32 options; int64 targetPid; int32 numKeyStrokes; uint32 windowNameLength; } #include "vmware_pack_end.h" VixMsgSendKeyStrokesRequest; /* * send a mouse event to the guest */ typedef #include "vmware_pack_begin.h" struct VixMsgSendMouseEventRequest { VixCommandRequestHeader header; int16 x; int16 y; int16 buttons; int32 options; } #include "vmware_pack_end.h" VixMsgSendMouseEventRequest; /* * ********************************************************** * Read or write the registry on the guest. */ typedef #include "vmware_pack_begin.h" struct VixMsgRegistryRequest { VixCommandRequestHeader header; uint32 registryKeyLength; int32 expectedRegistryKeyType; uint32 dataToWriteSize; } #include "vmware_pack_end.h" VixMsgRegistryRequest; /* * ********************************************************** * Copy files between the host and the guest. */ typedef #include "vmware_pack_begin.h" struct VixCommandRenameFileRequest { VixCommandRequestHeader header; int32 copyFileOptions; uint32 oldPathNameLength; uint32 newPathNameLength; uint32 filePropertiesLength; } #include "vmware_pack_end.h" VixCommandRenameFileRequest; typedef #include "vmware_pack_begin.h" struct VixCommandRenameFileRequestEx { VixCommandRequestHeader header; int32 copyFileOptions; uint32 oldPathNameLength; uint32 newPathNameLength; uint32 filePropertiesLength; Bool overwrite; } #include "vmware_pack_end.h" VixCommandRenameFileRequestEx; typedef #include "vmware_pack_begin.h" struct VixCommandHgfsSendPacket { VixCommandRequestHeader header; uint32 hgfsPacketSize; int32 timeout; } #include "vmware_pack_end.h" VixCommandHgfsSendPacket; typedef #include "vmware_pack_begin.h" struct VixMsgSetGuestFileAttributesRequest { VixCommandRequestHeader header; int32 fileOptions; int64 accessTime; int64 modificationTime; int32 ownerId; int32 groupId; int32 permissions; Bool hidden; Bool readOnly; uint32 guestPathNameLength; } #include "vmware_pack_end.h" VixMsgSetGuestFileAttributesRequest; /* * ********************************************************** * Perform a simple operation (like delete or check for existence) * on a file or registry key on the guest. */ typedef #include "vmware_pack_begin.h" struct VixMsgSimpleFileRequest { VixCommandRequestHeader header; int32 fileOptions; uint32 guestPathNameLength; } #include "vmware_pack_end.h" VixMsgSimpleFileRequest; typedef #include "vmware_pack_begin.h" struct VixMsgListDirectoryRequest { VixCommandRequestHeader header; int32 fileOptions; uint32 guestPathNameLength; int64 offset; } #include "vmware_pack_end.h" VixMsgListDirectoryRequest; enum VixListDirectoryOptions { VIX_LIST_DIRECTORY_USE_OFFSET = 0x01 }; typedef #include "vmware_pack_begin.h" struct VixMsgListFilesRequest { VixCommandRequestHeader header; int32 fileOptions; uint32 guestPathNameLength; uint32 patternLength; int32 index; int32 maxResults; uint64 offset; } #include "vmware_pack_end.h" VixMsgListFilesRequest; typedef #include "vmware_pack_begin.h" struct VixCommandInitiateFileTransferToGuestRequest { VixCommandRequestHeader header; int32 options; uint32 guestPathNameLength; Bool overwrite; } #include "vmware_pack_end.h" VixCommandInitiateFileTransferToGuestRequest; /* * This is used to reply to several operations, like testing whether * a file or registry key exists on the client. */ typedef #include "vmware_pack_begin.h" struct VixMsgCheckExistsResponse { VixCommandResponseHeader header; Bool exists; } #include "vmware_pack_end.h" VixMsgCheckExistsResponse; /* * ********************************************************** * Perform a create file operation (like createDir or moveFile) * on a file in the guest. This lets you pass in things like the initial file * properties. */ typedef #include "vmware_pack_begin.h" struct VixMsgCreateFileRequest { VixCommandRequestHeader header; int32 fileOptions; uint32 guestPathNameLength; uint32 filePropertiesLength; } #include "vmware_pack_end.h" VixMsgCreateFileRequest; typedef #include "vmware_pack_begin.h" struct VixMsgCreateFileRequestEx { VixCommandRequestHeader header; int32 fileOptions; uint32 guestPathNameLength; uint32 filePropertiesLength; Bool createParentDirectories; } #include "vmware_pack_end.h" VixMsgCreateFileRequestEx; /* * ********************************************************** * Hot extend a disk in a running VM. */ typedef #include "vmware_pack_begin.h" struct VixMsgHotExtendDiskRequest { VixCommandRequestHeader header; int32 hotDiskOptions; uint32 typeLength; int32 adapterNum; int32 targetNum; uint64 newNumSectors; } #include "vmware_pack_end.h" VixMsgHotExtendDiskRequest; /* * ********************************************************** * Hot plug CPU in a running VM. */ typedef #include "vmware_pack_begin.h" struct VixMsgHotPlugCPURequest { VixCommandRequestHeader header; uint32 newNumCPU; } #include "vmware_pack_end.h" VixMsgHotPlugCPURequest; /* * ********************************************************** * Hot plug memory in a running VM. */ typedef #include "vmware_pack_begin.h" struct VixMsgHotPlugMemoryRequest { VixCommandRequestHeader header; uint32 newSizeMb; } #include "vmware_pack_end.h" VixMsgHotPlugMemoryRequest; /* * ********************************************************** * Hot add device in a running VM. */ typedef #include "vmware_pack_begin.h" struct VixMsgHotAddDeviceRequest { VixCommandRequestHeader header; int32 deviceType; uint32 devicePropsBufferSize; int32 backingType; uint32 backingPropsBufferSize; } #include "vmware_pack_end.h" VixMsgHotAddDeviceRequest; typedef #include "vmware_pack_begin.h" struct VixMsgHotAddDeviceResponse { VixCommandResponseHeader header; int32 adapterNum; int32 targetNum; } #include "vmware_pack_end.h" VixMsgHotAddDeviceResponse; /* * ********************************************************** * Hot remove device in a running VM. */ typedef #include "vmware_pack_begin.h" struct VixMsgHotRemoveDeviceRequest { VixCommandRequestHeader header; int32 deviceType; uint32 devicePropsBufferSize; } #include "vmware_pack_end.h" VixMsgHotRemoveDeviceRequest; /* * ********************************************************** * Change monitor type of a running VM. */ typedef #include "vmware_pack_begin.h" struct VixMsgHotChangeMonitorTypeRequest { VixCommandRequestHeader header; int32 monitorType; } #include "vmware_pack_end.h" VixMsgHotChangeMonitorTypeRequest; /* * ********************************************************** * Hot plug begin batch. */ typedef #include "vmware_pack_begin.h" struct VixMsgHotPlugBeginBatchRequest { VixCommandRequestHeader header; int32 flags; } #include "vmware_pack_end.h" VixMsgHotPlugBeginBatchRequest; /* * ********************************************************** * Hot plug commit batch. */ typedef #include "vmware_pack_begin.h" struct VixMsgHotPlugCommitBatchRequest { VixCommandRequestHeader header; int32 status; } #include "vmware_pack_end.h" VixMsgHotPlugCommitBatchRequest; /* * ********************************************************** * Transfer connection. Besides fields here you are supposed to * receive file descriptor OOB. */ typedef #include "vmware_pack_begin.h" struct VixMsgTransferConnectionRequest { VixCommandRequestHeader header; Bool isPrivileged; uint32 cryptoLength; uint32 fdLength; /* uint8 cryptoData[]; */ /* uint8 fdData[]; */ } #include "vmware_pack_end.h" VixMsgTransferConnectionRequest; /* * ********************************************************** * Pass data. Besides fields here you may receive also * file descriptor. Data is just command which was pending * on original connection already transferred via * TransferConnectionRequest. */ typedef #include "vmware_pack_begin.h" struct VixMsgTransferRequestRequest { VixCommandRequestHeader header; uint32 dataLength; uint32 fdLength; /* uint8 data[]; */ /* uint8 fdData[]; */ } #include "vmware_pack_end.h" VixMsgTransferRequestRequest; /* * ********************************************************** * Pass final data. Besides fields here you may receive also * file descriptor. Data is just what was already received * on the socket passed by TransferConnectionRequest. */ typedef #include "vmware_pack_begin.h" struct VixMsgTransferFinalDataRequest { VixCommandRequestHeader header; uint32 dataLength; uint32 fdLength; /* uint8 data[]; */ /* uint8 fdData[]; */ } #include "vmware_pack_end.h" VixMsgTransferFinalDataRequest; /* * ********************************************************** * Create a snapshot of a running VM. */ typedef #include "vmware_pack_begin.h" struct VixMsgCreateSnapshotRequest { VixCommandRequestHeader header; int32 options; Bool powerOff; Bool saveDeviceState; uint32 nameLength; uint32 descriptionLength; } #include "vmware_pack_end.h" VixMsgCreateSnapshotRequest; typedef #include "vmware_pack_begin.h" struct VixMsgCreateSnapshotResponse { VixCommandResponseHeader header; int32 snapshotUID; } #include "vmware_pack_end.h" VixMsgCreateSnapshotResponse; /* * Several snapshot operations for a running VM. */ typedef #include "vmware_pack_begin.h" struct VixMsgSnapshotRequest { VixCommandRequestHeader header; int32 options; int32 snapshotId; } #include "vmware_pack_end.h" VixMsgSnapshotRequest; typedef #include "vmware_pack_begin.h" struct VixMsgSnapshotUpdateEvent { VixMsgEventHeader eventHeader; int32 options; uint32 propertyListLength; /* * This is followed by a serialized property list. */ } #include "vmware_pack_end.h" VixMsgSnapshotUpdateEvent; typedef #include "vmware_pack_begin.h" struct VixMsgSnapshotMRURequest { VixCommandRequestHeader header; int32 snapshotId; int32 maxMRU; } #include "vmware_pack_end.h" VixMsgSnapshotMRURequest; typedef #include "vmware_pack_begin.h" struct VixMsgSetSnapshotInfoRequest { VixCommandRequestHeader header; int32 snapshotId; int32 clientFlags; int32 numTierUIDs; uint32 displayNameLength; uint32 descriptionLength; uint32 propertyListLength; uint32 tierUIDListLength; /* * Followed by: * displayName string * description string * serialized property list. */ } #include "vmware_pack_end.h" VixMsgSetSnapshotInfoRequest; typedef #include "vmware_pack_begin.h" struct VixMsgSetSnapshotInfoResponse { VixCommandResponseHeader header; uint32 propertyListLength; } #include "vmware_pack_end.h" VixMsgSetSnapshotInfoResponse; typedef #include "vmware_pack_begin.h" struct VixMsgRemoveBulkSnapshotRequest { VixCommandRequestHeader header; int32 options; int32 numSnapshots; /* * This is followed by numSnapshots snapshotIDs. */ } #include "vmware_pack_end.h" VixMsgRemoveBulkSnapshotRequest; /* * Stop recording or playback of a snapshot event log. */ typedef #include "vmware_pack_begin.h" struct VixMsgVMSnapshotLoggingRequest { VixCommandRequestHeader header; int32 options; } #include "vmware_pack_end.h" VixMsgVMSnapshotLoggingRequest; typedef #include "vmware_pack_begin.h" struct VixMsgRecordReplayEvent { VixMsgEventHeader eventHeader; int32 newRecordState; int32 reason; } #include "vmware_pack_end.h" VixMsgRecordReplayEvent; typedef #include "vmware_pack_begin.h" struct VixMsgDebuggerEvent { VixMsgEventHeader eventHeader; int32 blobLength; /* * This is followed by the blob buffer. */ } #include "vmware_pack_end.h" VixMsgDebuggerEvent; /* * Fault Tolerance Automation */ typedef #include "vmware_pack_begin.h" struct VixMsgFaultToleranceControlRequest { VixCommandRequestHeader requestHeader; int32 command; char uuid[48]; uint32 vmxPathLen; char vmxFilePath[1]; } #include "vmware_pack_end.h" VixMsgFaultToleranceControlRequest; typedef #include "vmware_pack_begin.h" struct VixFaultToleranceControlResponse { VixCommandResponseHeader header; uint32 propertyListBufferSize; // Followed by a serialized property list containing error context. } #include "vmware_pack_end.h" VixFaultToleranceControlResponse; /* * ********************************************************** * Shared folder operations. */ typedef #include "vmware_pack_begin.h" struct VixMsgSharedFolderRequest { VixCommandRequestHeader header; int32 options; int32 index; uint32 shareNameLength; uint32 hostPathNameLength; } #include "vmware_pack_end.h" VixMsgSharedFolderRequest; typedef #include "vmware_pack_begin.h" struct VixMsgSharedFolderResponse { VixCommandResponseHeader header; int32 numSharedFolders; } #include "vmware_pack_end.h" VixMsgSharedFolderResponse; typedef #include "vmware_pack_begin.h" struct VixMsgGetSharedFolderInfoResponse { VixCommandResponseHeader header; uint32 shareNameLength; uint32 hostPathNameLength; int32 sharedFolderFlags; } #include "vmware_pack_end.h" VixMsgGetSharedFolderInfoResponse; /* * Add or change a shared folder request. */ typedef #include "vmware_pack_begin.h" struct VixMsgSetSharedFolderRequest { VixCommandRequestHeader header; int32 options; uint32 shareNameLength; uint32 hostPathNameLength; } #include "vmware_pack_end.h" VixMsgSetSharedFolderRequest; /* * ********************************************************** * Capture the screen of a VM */ typedef #include "vmware_pack_begin.h" struct VixMsgCaptureScreenRequest { VixCommandRequestHeader header; int32 format; // Identifies the requested data format. int32 maxSize; // Max data response size in bytes // (-1 is any size) int32 captureScreenOptions; } #include "vmware_pack_end.h" VixMsgCaptureScreenRequest; typedef #include "vmware_pack_begin.h" struct VixMsgCaptureScreenResponse { VixCommandResponseHeader header; int32 format; // Format of the data in the response. uint32 dataOffset; // Relative to the address of this struct. } #include "vmware_pack_end.h" VixMsgCaptureScreenResponse; /* * ********************************************************** * Run a script in the guest. */ typedef #include "vmware_pack_begin.h" struct VixMsgRunScriptRequest { VixCommandRequestHeader header; int32 scriptOptions; uint32 interpreterNameLength; uint32 scriptLength; uint32 propertiesLength; } #include "vmware_pack_end.h" VixMsgRunScriptRequest; /* * ********************************************************** * An unsupported command. This is used to test future versions * of the API sending us commands we don't recognize. */ typedef #include "vmware_pack_begin.h" struct VixUnsupportedCommandRequest { VixCommandRequestHeader header; char junk[2053]; } #include "vmware_pack_end.h" VixUnsupportedCommandRequest; /* * ********************************************************** * Create a session key between the client and the VMX. */ typedef #include "vmware_pack_begin.h" struct VixCommandMakeSessionKeyRequest { VixCommandRequestHeader header; int32 keyOptions; int32 timeout; uint32 responseKeyLength; int32 responseKeyCypherType; int32 cypherType; } #include "vmware_pack_end.h" VixCommandMakeSessionKeyRequest; typedef #include "vmware_pack_begin.h" struct VixCommandMakeSessionKeyResponse { VixCommandResponseHeader header; int32 keyOptions; int32 timeout; uint32 keyLength; int32 cypherType; } #include "vmware_pack_end.h" VixCommandMakeSessionKeyResponse; typedef #include "vmware_pack_begin.h" struct VixCommandGenerateNonceResponse { VixCommandResponseHeader header; int64 nonce; } #include "vmware_pack_end.h" VixCommandGenerateNonceResponse; enum { VIX_CYPHERTYPE_NONE = 0, VIX_CYPHERTYPE_DEFAULT = 1, }; /* * ********************************************************** * Kill a guest process. */ typedef #include "vmware_pack_begin.h" struct VixCommandKillProcessRequest { VixCommandRequestHeader header; uint64 pid; uint32 options; } #include "vmware_pack_end.h" VixCommandKillProcessRequest; /* * ********************************************************** * Read and write variables like guest variables and config values. */ typedef #include "vmware_pack_begin.h" struct VixMsgReadVariableRequest { VixCommandRequestHeader header; int32 variableType; int32 options; uint32 nameLength; } #include "vmware_pack_end.h" VixMsgReadVariableRequest; typedef #include "vmware_pack_begin.h" struct VixMsgReadVariableResponse { VixCommandResponseHeader header; int32 valueType; int32 valueProperties; uint32 valueLength; } #include "vmware_pack_end.h" VixMsgReadVariableResponse; /* * Several snapshot operations for a running VM. */ typedef #include "vmware_pack_begin.h" struct VixMsgWriteVariableRequest { VixCommandRequestHeader header; int32 variableType; int32 options; uint32 nameLength; uint32 valueLength; } #include "vmware_pack_end.h" VixMsgWriteVariableRequest; /* * ********************************************************** * Perform a create file operation (like createDir or moveFile) * on a file in the guest. This lets you pass in things like the initial file * properties. */ typedef #include "vmware_pack_begin.h" struct VixMsgCreateTempFileRequest { VixCommandRequestHeader header; int32 options; uint32 propertyNameLength; uint32 filePrefixLength; uint32 fileSuffixLength; } #include "vmware_pack_end.h" VixMsgCreateTempFileRequest; typedef #include "vmware_pack_begin.h" struct VixMsgCreateTempFileRequestEx { VixCommandRequestHeader header; int32 options; uint32 filePrefixLength; uint32 fileSuffixLength; uint32 directoryPathLength; uint32 propertyListLength; } #include "vmware_pack_end.h" VixMsgCreateTempFileRequestEx; typedef #include "vmware_pack_begin.h" struct { VixCommandRequestHeader header; int32 fileOptions; uint32 guestPathNameLength; uint32 filePropertiesLength; Bool recursive; } #include "vmware_pack_end.h" VixMsgDeleteDirectoryRequest; /* * ********************************************************** * Connect/Disconnect device request. The response is just a generic * response header (it has no body). */ typedef #include "vmware_pack_begin.h" struct VixMsgConnectDeviceRequest { VixCommandRequestHeader header; int32 options; Bool connected; uint32 nameLength; } #include "vmware_pack_end.h" VixMsgConnectDeviceRequest; /* * ********************************************************** * Get the list of VProbes exported by a given VM. The request is * parameterless, and so generic. */ typedef #include "vmware_pack_begin.h" struct VixMsgGetVProbesResponse { VixCommandResponseHeader header; int32 numEntries; } #include "vmware_pack_end.h" VixMsgGetVProbesResponse; /* * ********************************************************** * Load a vprobe script into a given VM. The request is a string * to be loaded. The response is a collection of warning and error * strings; zero errors indicates success. */ typedef #include "vmware_pack_begin.h" struct VixMsgVProbeLoadRequest { VixCommandRequestHeader header; char string[1]; /* variable length */ } #include "vmware_pack_end.h" VixMsgVProbeLoadRequest; typedef #include "vmware_pack_begin.h" struct VixMsgVProbeLoadResponse { VixCommandResponseHeader header; uint32 numWarnings; uint32 numErrors; uint32 instanceID; char warningsAndErrors[1]; /* variable length */ } #include "vmware_pack_end.h" VixMsgVProbeLoadResponse; /* * ********************************************************** * Get the state of a virtual device. */ typedef #include "vmware_pack_begin.h" struct VixMsgGetDeviceStateRequest { VixCommandRequestHeader header; int32 options; uint32 nameLength; } #include "vmware_pack_end.h" VixMsgGetDeviceStateRequest; /* * This is used to reply to IsDeviceConnected operations. */ typedef #include "vmware_pack_begin.h" struct VixMsgGetDeviceStateResponse { VixCommandResponseHeader header; Bool connected; int32 stateFlags; // Maybe capacity and percent allocated? } #include "vmware_pack_end.h" VixMsgGetDeviceStateResponse; /* * ********************************************************** * Enable/disable all shared folders on this VM. The response * is just a generic response header (it has no body). */ typedef #include "vmware_pack_begin.h" struct VixMsgEnableSharedFoldersRequest { VixCommandRequestHeader header; Bool enabled; int32 sharedFolderOptions; } #include "vmware_pack_end.h" VixMsgEnableSharedFoldersRequest; /* * ********************************************************** * Mount volumes in the guest. */ enum VixMountOptions { VIX_MOUNT_ALL = 0x0001, VIX_MOUNT_REMOUNT_FIRST = 0x0002, }; typedef #include "vmware_pack_begin.h" struct VixMsgMountHGFSRequest { VixCommandRequestHeader header; int32 mountOptions; int32 mountType; /* The str path list has the form "host1\0dest1\0host2\0dest2\0host3\0dest3\0\0" */ uint32 pathListLength; } #include "vmware_pack_end.h" VixMsgMountHGFSRequest; /* * Get guest networking config */ typedef #include "vmware_pack_begin.h" struct VixMsgGetGuestNetworkingConfigRequest { VixCommandRequestHeader header; int32 options; } #include "vmware_pack_end.h" VixMsgGetGuestNetworkingConfigRequest; /* * Set guest networking config */ typedef #include "vmware_pack_begin.h" struct VixMsgSetGuestNetworkingConfigRequest { VixCommandRequestHeader header; int32 options; uint32 bufferSize; } #include "vmware_pack_end.h" VixMsgSetGuestNetworkingConfigRequest; /* * Query VMX performance data */ typedef #include "vmware_pack_begin.h" struct VixMsgGetPerformanceDataRequest { VixCommandRequestHeader header; // unused for now, but left for future expansion in case we // get such a large list that we want to pass the desired properties. int32 options; uint32 sizeOfPropertyList; // This is followed by the buffer of properties we wish to fetch } #include "vmware_pack_end.h" VixMsgGetPerformanceDataRequest; typedef #include "vmware_pack_begin.h" struct VixMsgGetPerformanceDataResponse { VixCommandResponseHeader header; uint32 bufferSize; // This is followed by the buffer of serialized properties } #include "vmware_pack_end.h" VixMsgGetPerformanceDataResponse; /* * Run a program in guest with (VI version with more args) */ typedef #include "vmware_pack_begin.h" struct VixMsgStartProgramRequest { VixCommandRequestHeader header; Bool startMinimized; uint32 programPathLength; uint32 argumentsLength; uint32 workingDirLength; uint32 numEnvVars; uint32 envVarLength; // This is followed by the buffer of the args } #include "vmware_pack_end.h" VixMsgStartProgramRequest; typedef #include "vmware_pack_begin.h" struct VixMsgListProcessesExRequest { VixCommandRequestHeader header; // if we need to make multiple trips, this is the key used to identify // the result being processed uint32 key; // if we need to make multiple trips, this is the offset in the reply // from which to send the next chunk uint32 offset; uint32 numPids; // This is followed by the list of uint64s } #include "vmware_pack_end.h" VixMsgListProcessesExRequest; typedef #include "vmware_pack_begin.h" struct VixMsgReadEnvironmentVariablesRequest { VixCommandRequestHeader header; uint32 numNames; uint32 namesLength; // This is followed by the list of NUL-terminated names } #include "vmware_pack_end.h" VixMsgReadEnvironmentVariablesRequest; /* IdProvider support */ typedef #include "vmware_pack_begin.h" struct VixMsgAddAliasRequest { VixCommandRequestHeader header; uint32 options; uint32 userNameLen; uint32 pemCertLen; Bool addMapping; int32 subjectType; // one of VixGuestAuthSubjectType uint32 subjectNameLen; uint32 aliasCommentLen; /* Followed by the NUL-terminated string arguments. */ /* char[] userName; */ /* char[] pemCert; */ /* char[] subjectName; */ /* char[] aliasComment; */ } #include "vmware_pack_end.h" VixMsgAddAuthAliasRequest; typedef #include "vmware_pack_begin.h" struct VixMsgRemoveAuthAliasRequest { VixCommandRequestHeader header; uint32 options; uint32 userNameLen; uint32 pemCertLen; // special case for RemoveAliasByCert: // if subjectType is NONE, then all aliases will be removed. int32 subjectType; // one of VixGuestAuthSubjectType uint32 subjectNameLen; /* Followed by the NUL-terminated string arguments. */ /* char[] userName; */ /* char[] pemCert; */ /* char[] subjectName; */ } #include "vmware_pack_end.h" VixMsgRemoveAuthAliasRequest; typedef #include "vmware_pack_begin.h" struct VixMsgListAuthAliasesRequest { VixCommandRequestHeader header; uint32 options; uint32 userNameLen; /* char[] userName; */ } #include "vmware_pack_end.h" VixMsgListAuthAliasesRequest; typedef #include "vmware_pack_begin.h" struct VixMsgListMappedAliasesRequest { VixCommandRequestHeader header; uint32 options; } #include "vmware_pack_end.h" VixMsgListMappedAliasesRequest; /* * Windows Registry Management Support. */ typedef #include "vmware_pack_begin.h" struct VixMsgCreateRegKeyRequest { VixCommandRequestHeader header; uint32 options; uint32 pathLength; uint32 wowBitness; Bool isVolatile; uint32 classTypeLength; /* * Followed by NUL-terminated string arguments. * char[] path; * char[] classType; */ } #include "vmware_pack_end.h" VixMsgCreateRegKeyRequest; typedef #include "vmware_pack_begin.h" struct VixMsgListRegKeysRequest { VixCommandRequestHeader header; uint32 options; /* * If we need multiple roundtrips, this is the index * used to identify the result being processed. */ uint32 index; /* * If we need multiple roundtrips, this is the offset * in the reply from which to send the next chunk. */ uint32 offset; uint32 pathLength; uint32 wowBitness; Bool recursive; uint32 matchPatternLength; /* * Followed by NUL-terminated string arguments. * char[] path; * char[] matchPattern; */ } #include "vmware_pack_end.h" VixMsgListRegKeysRequest; typedef #include "vmware_pack_begin.h" struct VixMsgDeleteRegKeyRequest { VixCommandRequestHeader header; uint32 options; uint32 pathLength; uint32 wowBitness; Bool recursive; /* * Followed by NUL-terminated string arguments. * char[] path; */ } #include "vmware_pack_end.h" VixMsgDeleteRegKeyRequest; typedef #include "vmware_pack_begin.h" struct VixMsgSetRegValueRequest { VixCommandRequestHeader header; uint32 options; uint32 pathLength; uint32 wowBitness; uint32 nameLength; uint32 dataBlobType; uint32 dataBlobLength; /* * Followed by NUL-terminated string arguments. * char[] path; * char[] name; * * Followed by a data blob of specified length * containing information of specified type. * void *dataBlob; */ } #include "vmware_pack_end.h" VixMsgSetRegValueRequest; typedef #include "vmware_pack_begin.h" struct VixMsgListRegValuesRequest { VixCommandRequestHeader header; uint32 options; /* * If we need multiple roundtrips, this is the index * used to identify the result being processed. */ uint32 index; /* * If we need multiple roundtrips, this is the offset * in the reply from which to send the next chunk. */ uint32 offset; uint32 pathLength; uint32 wowBitness; Bool expandStrings; uint32 matchPatternLength; /* * Followed by NUL-terminated string arguments. * char[] path; * char[] matchPattern; */ } #include "vmware_pack_end.h" VixMsgListRegValuesRequest; typedef #include "vmware_pack_begin.h" struct VixMsgDeleteRegValueRequest { VixCommandRequestHeader header; uint32 options; uint32 pathLength; uint32 wowBitness; uint32 nameLength; /* * Followed by NUL-terminated string arguments. * char[] path; * char[] name; */ } #include "vmware_pack_end.h" VixMsgDeleteRegValueRequest; /* * HOWTO: Adding a new Vix Command. Step 3. * * Add a new struct to pass over the control socket into the VMX. * You only need to do this if your command is manipulating a running * VM, but that is a common situation. If your command only manipulates * non-running VMs, then you can skip this. * * This particular command passes strings as both a param and a * result. This is the most general case, because it means that both * the request and response have a variable-length string on the end. * You can make a simpler request or response if it only passes integers * and so is fixed size. */ /* * ********************************************************** * Sample Command. */ typedef #include "vmware_pack_begin.h" struct VixMsgSampleCommandRequest { VixCommandRequestHeader header; int32 intArg; uint32 strArgLength; } #include "vmware_pack_end.h" VixMsgSampleCommandRequest; typedef #include "vmware_pack_begin.h" struct VixMsgSampleCommandResponse { VixCommandResponseHeader header; int32 intResult; uint32 strResultLength; } #include "vmware_pack_end.h" VixMsgSampleCommandResponse; // End of "HOWTO: Adding a new Vix Command. Step 3." /* * ********************************************************** * Debugger related commands. */ typedef #include "vmware_pack_begin.h" struct VixMsgAttachDebuggerRequest { VixCommandRequestHeader header; int32 options; uint32 propertyListBufferSize; } #include "vmware_pack_end.h" VixMsgAttachDebuggerRequest; typedef #include "vmware_pack_begin.h" struct VixMsgAttachDebuggerResponse { VixCommandResponseHeader header; uint32 propertyListBufferSize; } #include "vmware_pack_end.h" VixMsgAttachDebuggerResponse; typedef #include "vmware_pack_begin.h" struct VixMsgIssueDebuggerCommandRequest { VixCommandRequestHeader header; int32 options; uint32 propertyListBufferSize; uint32 debuggerBlobBufferSize; } #include "vmware_pack_end.h" VixMsgIssueDebuggerCommandRequest; typedef #include "vmware_pack_begin.h" struct VixMsgIssueDebuggerCommandResponse { VixCommandResponseHeader header; uint32 propertyListBufferSize; uint32 debuggerBlobBufferSize; } #include "vmware_pack_end.h" VixMsgIssueDebuggerCommandResponse; typedef #include "vmware_pack_begin.h" struct VixMsgDetachDebuggerRequest { VixCommandRequestHeader header; int32 options; uint32 propertyListBufferSize; } #include "vmware_pack_end.h" VixMsgDetachDebuggerRequest; typedef #include "vmware_pack_begin.h" struct VixMsgDetachDebuggerResponse { VixCommandResponseHeader header; uint32 propertyListBufferSize; } #include "vmware_pack_end.h" VixMsgDetachDebuggerResponse; /* * ********************************************************** * VM Pause state change event format */ typedef #include "vmware_pack_begin.h" struct VixMsgPauseStateChangedEvent { VixMsgEventHeader eventHeader; Bool paused; } #include "vmware_pack_end.h" VixMsgPauseStateChangedEvent; /* * ********************************************************** * Wait for a user action, such as a user logging into the guest. */ /* * Vix_WaitForUserActionInGuest Request * VIX_COMMAND_WAIT_FOR_USER_ACTION_IN_GUEST */ typedef #include "vmware_pack_begin.h" struct VixMsgWaitForUserActionRequest { VixCommandRequestHeader header; int32 userType; int32 userAction; int32 timeoutInSeconds; int32 options; uint32 userNameLength; uint32 propertyBufferSize; // This is followed by: // userName // buffer of serialized properties } #include "vmware_pack_end.h" VixMsgWaitForUserActionRequest; typedef #include "vmware_pack_begin.h" struct VixMsgWaitForUserActionResponse { VixCommandRequestHeader header; Bool actionHappened; uint32 bufferSize; // This is followed by the buffer of serialized properties } #include "vmware_pack_end.h" VixMsgWaitForUserActionResponse; /* * ********************************************************** * List filesystems */ typedef #include "vmware_pack_begin.h" struct VixCommandListFileSystemsRequest { VixCommandRequestHeader header; uint32 options; uint32 propertyListSize; } #include "vmware_pack_end.h" VixCommandListFileSystemsRequest; /* * ********************************************************** * Acquire Credentials. */ typedef #include "vmware_pack_begin.h" struct VixCommandAcquireCredentialsRequest { VixCommandRequestHeader header; int64 sessionID; } #include "vmware_pack_end.h" VixCommandAcquireCredentialsRequest; /* * ********************************************************** * A simple request packet that contains an options field and a * property list. */ typedef #include "vmware_pack_begin.h" struct VixCommandGenericRequest { VixCommandRequestHeader header; uint32 options; uint32 propertyListSize; // This is followed by the buffer of serialized properties } #include "vmware_pack_end.h" VixCommandGenericRequest; /* * These are values we use to discover hosts and guests through SLPv2. */ #define VIX_SLPV2_SERVICE_NAME_TOOLS_SERVICE "VMware_Vix_Tools" #define VIX_SLPV2_PROPERTY_IP_ADDR "IP" #define VIX_SLPV2_PROPERTY_MAC_ADDR "Mac" /* * The security classifications for async op types/op code. Each op code * is given a security category, and the VMX uses that category to determine * whether a client is allowed to perform the given command. */ typedef enum VixCommandSecurityCategory { /* The default for unknown commands */ VIX_COMMAND_CATEGORY_UNKNOWN, /* * A command that should be executed in the guest OS by the VIX Tools. * component. These are allowed for all connection types. */ VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED, /* * A command that only allowed by privileged connections; in the VI * world this is means that only Hostd is allowed to perform these * commands. */ VIX_COMMAND_CATEGORY_PRIVILEGED, /* * A command that may or may not be privileged. Usually, extra inspection * of the payload is required to make the determination. This should be * used sparingly, since must always be accompanied by "deep packet * inspection" code in the VMX (mainDispatch.c). */ VIX_COMMAND_CATEGORY_MIXED, } VixCommandSecurityCategory; /* * This is the list of all Vix commands * * Be really careful with these. These values are passed over the socket * between clients and the VMX process. One client may connect to newer or * older versions of the VMX, so we cannot ever change or recycle values if * if we add or remove command ids. This is why the values are explicitly * assigned, and there may be gaps in the numeric sequence as some commands * are no longer supported. */ typedef int VixAsyncOpType; enum { VIX_COMMAND_UNKNOWN = -1, VIX_COMMAND_VM_POWERON = 0, VIX_COMMAND_VM_POWEROFF = 1, VIX_COMMAND_VM_RESET = 2, VIX_COMMAND_VM_SUSPEND = 3, VIX_COMMAND_RUN_PROGRAM = 4, /* DEPRECATED VIX_COMMAND_GET_PROPERTY = 5, */ /* DEPRECATED VIX_COMMAND_SET_PROPERTY = 6, */ VIX_COMMAND_KEYSTROKES = 7, VIX_COMMAND_READ_REGISTRY = 8, VIX_COMMAND_WRITE_REGISTRY = 10, VIX_COMMAND_COPY_FILE_FROM_GUEST_TO_HOST = 12, VIX_COMMAND_COPY_FILE_FROM_HOST_TO_GUEST = 13, VIX_COMMAND_CREATE_SNAPSHOT = 14, VIX_COMMAND_REMOVE_SNAPSHOT = 15, VIX_COMMAND_REVERT_TO_SNAPSHOT = 16, VIX_COMMAND_VM_CLONE = 17, VIX_COMMAND_DELETE_GUEST_FILE = 18, VIX_COMMAND_GUEST_FILE_EXISTS = 19, VIX_COMMAND_FIND_VM = 20, VIX_COMMAND_CALL_PROCEDURE = 21, VIX_COMMAND_REGISTRY_KEY_EXISTS = 22, VIX_COMMAND_WIN32_WINDOW_MESSAGE = 23, VIX_COMMAND_CONSOLIDATE_SNAPSHOTS = 24, VIX_COMMAND_INSTALL_TOOLS = 25, VIX_COMMAND_CANCEL_INSTALL_TOOLS = 26, VIX_COMMAND_UPGRADE_VIRTUAL_HARDWARE = 27, VIX_COMMAND_SET_NIC_BANDWIDTH = 28, /* DEPRECATED VIX_COMMAND_CREATE_DISK = 29, */ /* DEPRECATED VIX_COMMAND_CREATE_FLOPPY = 30, */ VIX_COMMAND_RELOAD_VM = 31, VIX_COMMAND_DELETE_VM = 32, /* DEPRECATED VIX_COMMAND_SYNCDRIVER_FREEZE = 33, */ /* DEPRECATED VIX_COMMAND_SYNCDRIVER_THAW = 34, */ /* DEPRECATED VIX_COMMAND_HOT_ADD_DISK = 35, */ /* DEPRECATED VIX_COMMAND_HOT_REMOVE_DISK = 36, */ /* DEPRECATED VIX_COMMAND_SET_GUEST_PRINTER = 37, */ VIX_COMMAND_WAIT_FOR_TOOLS = 38, VIX_COMMAND_CREATE_RUNNING_VM_SNAPSHOT = 39, VIX_COMMAND_CONSOLIDATE_RUNNING_VM_SNAPSHOT = 40, VIX_COMMAND_GET_NUM_SHARED_FOLDERS = 41, VIX_COMMAND_GET_SHARED_FOLDER_STATE = 42, VIX_COMMAND_EDIT_SHARED_FOLDER_STATE = 43, VIX_COMMAND_REMOVE_SHARED_FOLDER = 44, VIX_COMMAND_ADD_SHARED_FOLDER = 45, VIX_COMMAND_RUN_SCRIPT_IN_GUEST = 46, VIX_COMMAND_OPEN_VM = 47, /* DEPRECATED VIX_COMMAND_GET_DISK_PROPERTIES = 48, */ /* DEPRECATED VIX_COMMAND_OPEN_URL = 49, */ VIX_COMMAND_GET_HANDLE_STATE = 50, /* DEPRECATED VIX_COMMAND_SET_HANDLE_STATE = 51, */ VIX_COMMAND_CREATE_WORKING_COPY = 55, // DELETE this when we switch remote foundry to VIM VIX_COMMAND_DISCARD_WORKING_COPY = 56, // DELETE this when we switch remote foundry to VIM VIX_COMMAND_SAVE_WORKING_COPY = 57, // DELETE this when we switch remote foundry to VIM VIX_COMMAND_CAPTURE_SCREEN = 58, /* DEPRECATED VIX_COMMAND_GET_VMDB_VALUES = 59, */ /* DEPRECATED VIX_COMMAND_SET_VMDB_VALUES = 60, */ /* DEPRECATED VIX_COMMAND_READ_XML_FILE = 61, */ VIX_COMMAND_GET_TOOLS_STATE = 62, VIX_COMMAND_CHANGE_SCREEN_RESOLUTION = 69, VIX_COMMAND_DIRECTORY_EXISTS = 70, VIX_COMMAND_DELETE_GUEST_REGISTRY_KEY = 71, VIX_COMMAND_DELETE_GUEST_DIRECTORY = 72, VIX_COMMAND_DELETE_GUEST_EMPTY_DIRECTORY = 73, VIX_COMMAND_CREATE_TEMPORARY_FILE = 74, VIX_COMMAND_LIST_PROCESSES = 75, VIX_COMMAND_MOVE_GUEST_FILE = 76, VIX_COMMAND_CREATE_DIRECTORY = 77, VIX_COMMAND_CHECK_USER_ACCOUNT = 78, VIX_COMMAND_LIST_DIRECTORY = 79, VIX_COMMAND_REGISTER_VM = 80, VIX_COMMAND_UNREGISTER_VM = 81, VIX_CREATE_SESSION_KEY_COMMAND = 83, VMXI_HGFS_SEND_PACKET_COMMAND = 84, VIX_COMMAND_KILL_PROCESS = 85, /* DEPRECATED VIX_VM_FORK_COMMAND = 86, */ VIX_COMMAND_LOGOUT_IN_GUEST = 87, VIX_COMMAND_READ_VARIABLE = 88, VIX_COMMAND_WRITE_VARIABLE = 89, VIX_COMMAND_CONNECT_DEVICE = 92, VIX_COMMAND_IS_DEVICE_CONNECTED = 93, VIX_COMMAND_GET_FILE_INFO = 94, VIX_COMMAND_SET_FILE_INFO = 95, VIX_COMMAND_MOUSE_EVENTS = 96, VIX_COMMAND_OPEN_TEAM = 97, /* DEPRECATED VIX_COMMAND_FIND_HOST_DEVICES = 98, */ VIX_COMMAND_ANSWER_MESSAGE = 99, VIX_COMMAND_ENABLE_SHARED_FOLDERS = 100, VIX_COMMAND_MOUNT_HGFS_FOLDERS = 101, VIX_COMMAND_HOT_EXTEND_DISK = 102, VIX_COMMAND_GET_VPROBES_VERSION = 104, VIX_COMMAND_GET_VPROBES = 105, VIX_COMMAND_VPROBE_GET_GLOBALS = 106, VIX_COMMAND_VPROBE_LOAD = 107, VIX_COMMAND_VPROBE_RESET = 108, /* DEPRECATED VIX_COMMAND_LIST_USB_DEVICES = 109, */ VIX_COMMAND_CONNECT_HOST = 110, VIX_COMMAND_CREATE_LINKED_CLONE = 112, VIX_COMMAND_STOP_SNAPSHOT_LOG_RECORDING = 113, VIX_COMMAND_STOP_SNAPSHOT_LOG_PLAYBACK = 114, VIX_COMMAND_SAMPLE_COMMAND = 115, VIX_COMMAND_GET_GUEST_NETWORKING_CONFIG = 116, VIX_COMMAND_SET_GUEST_NETWORKING_CONFIG = 117, VIX_COMMAND_FAULT_TOLERANCE_REGISTER = 118, VIX_COMMAND_FAULT_TOLERANCE_UNREGISTER = 119, VIX_COMMAND_FAULT_TOLERANCE_CONTROL = 120, VIX_COMMAND_FAULT_TOLERANCE_QUERY_SECONDARY = 121, VIX_COMMAND_VM_PAUSE = 122, VIX_COMMAND_VM_UNPAUSE = 123, /* DEPRECATED VIX_COMMAND_GET_SNAPSHOT_LOG_INFO = 124, */ /* DEPRECATED VIX_COMMAND_SET_REPLAY_SPEED = 125, */ /* DEPRECATED VIX_COMMAND_ANSWER_USER_MESSAGE = 126, */ /* DEPRECATED VIX_COMMAND_SET_CLIENT_LOCALE = 127, */ VIX_COMMAND_GET_PERFORMANCE_DATA = 128, /* DEPRECATED VIX_COMMAND_REFRESH_RUNTIME_PROPERTIES = 129, */ VIX_COMMAND_GET_SNAPSHOT_SCREENSHOT = 130, /* DEPRECATED VIX_COMMAND_ADD_TIMEMARKER = 131, */ VIX_COMMAND_WAIT_FOR_USER_ACTION_IN_GUEST = 132, /* DEPRECATED VIX_COMMAND_VMDB_END_TRANSACTION = 133, */ /* DEPRECATED VIX_COMMAND_VMDB_SET = 134, */ VIX_COMMAND_CHANGE_VIRTUAL_HARDWARE = 135, VIX_COMMAND_HOT_PLUG_CPU = 136, VIX_COMMAND_HOT_PLUG_MEMORY = 137, VIX_COMMAND_HOT_ADD_DEVICE = 138, VIX_COMMAND_HOT_REMOVE_DEVICE = 139, VIX_COMMAND_DEBUGGER_ATTACH = 140, VIX_COMMAND_DEBUGGER_DETACH = 141, VIX_COMMAND_DEBUGGER_SEND_COMMAND = 142, /* DEPRECATED VIX_COMMAND_GET_RECORD_STATE = 143, */ /* DEPRECATED VIX_COMMAND_SET_RECORD_STATE = 144, */ /* DEPRECATEDVIX_COMMAND_REMOVE_RECORD_STATE = 145, */ /* VIX_COMMAND_GET_REPLAY_STATE = 146, */ /* VIX_COMMAND_SET_REPLAY_STATE = 147, */ /* VIX_COMMAND_REMOVE_REPLAY_STATE = 148, */ /* DEPRECATED VIX_COMMAND_CANCEL_USER_PROGRESS_MESSAGE = 150, */ VIX_COMMAND_GET_VMX_DEVICE_STATE = 151, /* DEPRECATED VIX_COMMAND_GET_NUM_TIMEMARKERS = 152, */ /* DEPRECATED VIX_COMMAND_GET_TIMEMARKER = 153, */ /* DEPRECATED VIX_COMMAND_REMOVE_TIMEMARKER = 154, */ VIX_COMMAND_SET_SNAPSHOT_INFO = 155, VIX_COMMAND_SNAPSHOT_SET_MRU = 156, VIX_COMMAND_LOGOUT_HOST = 157, VIX_COMMAND_HOT_PLUG_BEGIN_BATCH = 158, VIX_COMMAND_HOT_PLUG_COMMIT_BATCH = 159, VIX_COMMAND_TRANSFER_CONNECTION = 160, VIX_COMMAND_TRANSFER_REQUEST = 161, VIX_COMMAND_TRANSFER_FINAL_DATA = 162, /* DEPRECATED VIX_COMMAND_ADD_ROLLING_SNAPSHOT_TIER = 163, */ /* DEPRECATED VIX_COMMAND_REMOVE_ROLLING_SNAPSHOT_TIER = 164, */ /* DEPRECATED VIX_COMMAND_LIST_ROLLING_SNAPSHOT_TIER = 165, */ /* DEPRECATED VIX_COMMAND_ADD_ROLLING_SNAPSHOT_TIER_VMX = 166, */ /* DEPRECATED VIX_COMMAND_REMOVE_ROLLING_SNAPSHOT_TIER_VMX = 167, */ /* DEPRECATED VIX_COMMAND_LIST_ROLLING_SNAPSHOT_TIER_VMX = 168, */ VIX_COMMAND_LIST_FILESYSTEMS = 169, VIX_COMMAND_CHANGE_DISPLAY_TOPOLOGY = 170, VIX_COMMAND_SUSPEND_AND_RESUME = 171, VIX_COMMAND_REMOVE_BULK_SNAPSHOT = 172, VIX_COMMAND_COPY_FILE_FROM_READER_TO_GUEST = 173, VIX_COMMAND_GENERATE_NONCE = 174, VIX_COMMAND_CHANGE_DISPLAY_TOPOLOGY_MODES = 175, VIX_COMMAND_QUERY_CHILDREN = 176, VIX_COMMAND_LIST_FILES = 177, VIX_COMMAND_CREATE_DIRECTORY_EX = 178, VIX_COMMAND_MOVE_GUEST_FILE_EX = 179, VIX_COMMAND_MOVE_GUEST_DIRECTORY = 180, VIX_COMMAND_CREATE_TEMPORARY_FILE_EX = 181, VIX_COMMAND_CREATE_TEMPORARY_DIRECTORY = 182, VIX_COMMAND_SET_GUEST_FILE_ATTRIBUTES = 183, VIX_COMMAND_COPY_FILE_FROM_GUEST_TO_READER = 184, VIX_COMMAND_START_PROGRAM = 185, VIX_COMMAND_LIST_PROCESSES_EX = 186, VIX_COMMAND_READ_ENV_VARIABLES = 187, VIX_COMMAND_INITIATE_FILE_TRANSFER_FROM_GUEST = 188, VIX_COMMAND_INITIATE_FILE_TRANSFER_TO_GUEST = 189, VIX_COMMAND_ACQUIRE_CREDENTIALS = 190, VIX_COMMAND_RELEASE_CREDENTIALS = 191, VIX_COMMAND_VALIDATE_CREDENTIALS = 192, VIX_COMMAND_TERMINATE_PROCESS = 193, VIX_COMMAND_DELETE_GUEST_FILE_EX = 194, VIX_COMMAND_DELETE_GUEST_DIRECTORY_EX = 195, VIX_COMMAND_HOT_CHANGE_MONITOR_TYPE = 196, VIX_COMMAND_ADD_AUTH_ALIAS = 197, VIX_COMMAND_REMOVE_AUTH_ALIAS = 198, VIX_COMMAND_LIST_AUTH_PROVIDER_ALIASES = 199, VIX_COMMAND_LIST_AUTH_MAPPED_ALIASES = 200, VIX_COMMAND_CREATE_REGISTRY_KEY = 201, VIX_COMMAND_LIST_REGISTRY_KEYS = 202, VIX_COMMAND_DELETE_REGISTRY_KEY = 203, VIX_COMMAND_SET_REGISTRY_VALUE = 204, VIX_COMMAND_LIST_REGISTRY_VALUES = 205, VIX_COMMAND_DELETE_REGISTRY_VALUE = 206, /* * HOWTO: Adding a new Vix Command. Step 2a. * * Add a new ID for your new function prototype here. BE CAREFUL. The * OFFICIAL list of id's is in the bfg-main tree, in bora/lib/public/vixCommands.h. * When people add new command id's in different tree, they may collide and use * the same ID values. This can merge without conflicts, and cause runtime bugs. * Once a new command is added here, a command info field needs to be added * in bora/lib/foundryMsg/foundryMsg.c as well. */ VIX_COMMAND_LAST_NORMAL_COMMAND = 207, VIX_TEST_UNSUPPORTED_TOOLS_OPCODE_COMMAND = 998, VIX_TEST_UNSUPPORTED_VMX_OPCODE_COMMAND = 999, }; /* * These are the command names that are passed through the backdoor from the * VMX to the tools. */ #define VIX_BACKDOOR_COMMAND_VERSION "Vix_1_" #define VIX_BACKDOORCOMMAND_RUN_PROGRAM VIX_BACKDOOR_COMMAND_VERSION"Run_Program" #define VIX_BACKDOORCOMMAND_SYNCDRIVER_FREEZE VIX_BACKDOOR_COMMAND_VERSION"SyncDriver_Freeze" #define VIX_BACKDOORCOMMAND_SYNCDRIVER_THAW VIX_BACKDOOR_COMMAND_VERSION"SyncDriver_Thaw" #define VIX_BACKDOORCOMMAND_GET_PROPERTIES VIX_BACKDOOR_COMMAND_VERSION"Get_ToolsProperties" #define VIX_BACKDOORCOMMAND_SEND_HGFS_PACKET VIX_BACKDOOR_COMMAND_VERSION"Send_Hgfs_Packet" #define VIX_BACKDOORCOMMAND_UNRECOGNIZED_COMMAND VIX_BACKDOOR_COMMAND_VERSION"Unrecognized_Command" #define VIX_BACKDOORCOMMAND_COMMAND VIX_BACKDOOR_COMMAND_VERSION"Relayed_Command" #define VIX_BACKDOORCOMMAND_MOUNT_VOLUME_LIST VIX_BACKDOOR_COMMAND_VERSION"Mount_Volumes" /* * This is the set of features that may be supported by different * versions of the VMX or Vix Tools. */ enum VixToolsFeatures { VIX_TOOLSFEATURE_SUPPORT_GET_HANDLE_STATE = 0x0001, /* VIX_TOOLSFEATURE_SUPPORT_OPEN_URL = 0x0002, Removed in version 1.11*/ }; enum { VIX_TOOLS_READ_FILE_ACCESS = 0x01, VIX_TOOLS_WRITE_FILE_ACCESS = 0x02, }; /* * These are the command names that are passed through the backdoor from the tools * to the VMX. */ #define VIX_BACKDOORCOMMAND_RUN_PROGRAM_DONE "Run_Program_Done" #define VIX_FEATURE_UNKNOWN_VALUE "Unknown" /* * VIX_COMMAND_RUN_PROGRAM returns 2 integer values as an array. These * are the indexes * TODO: Delete this enum */ enum VixRunProgramResultValues { VIX_COMMAND_RUN_PROGRAM_ELAPSED_TIME_RESULT = 0, VIX_COMMAND_RUN_PROGRAM_EXIT_CODE_RESULT = 1, }; /* These are the values of Vix objects. */ #define VIX_VM_OBJECT_TYPE "VixVM" /* VM enumeration */ #ifdef _WIN32 #define VIX_WINDOWSREGISTRY_VMWARE_KEY "Software\\" COMPANY_NAME #define VIX_WINDOWSREGISTRY_RUNNING_VM_LIST "Running VM List" #define VIX_WINDOWSREGISTRY_VMWARE_KEY_RUNNING_VM_LIST VIX_WINDOWSREGISTRY_VMWARE_KEY "\\" VIX_WINDOWSREGISTRY_RUNNING_VM_LIST #endif /* * This is used to denote that the contents of a VIX XML-like response * string has been escaped. Old Tools did not escape the contents. * This tag is only used for existing commands that did not originally perform * escaping. Any new command must always escape any strings passed in XML. * See ListProcessesInGuest as an example. * The protocol works as follows: * 1) A client library that internally knows how to handle escaped XML opts in * by including the VIX_REQUESTMSG_ESCAPE_XML_DATA in relevent requests. * 2) Tools that understands the VIX_REQUESTMSG_ESCAPE_XML_DATA flag sees that * it is set in the request, and then escapes all string data within the * XML response. To indicate to the client that it has understood the * request, it include the VIX_XML_ESCAPED_TAG in the response (at the * begining of the response). * 3) When the client library receives the response, it searches for the * VIX_XML_ESCAPED_TAG. If it is present, it then unescapes all string * data in the response. If the tag is not present, the client library * assumes that the Tools did not understand VIX_REQUESTMSG_ESCAPE_XML_DATA * and that the string data is not escaped. * The following characters are escaped: '<', '>', and '%'. * For new commands (starting with those released in M/N for the vSphere * guest ops project), the escaping is exactly the same, but the * VIX_REQUESTMSG_ESCAPE_XML_DATA flag and the VIX_XML_ESCAPED_TAG are not * used, since both ends expect escaping. */ #define VIX_XML_ESCAPED_TAG "" #define VIX_XML_ESCAPE_CHARACTER '%' /* *----------------------------------------------------------------------------- * * VixMsg -- * * These are the formatting and parsing utilities provided by the VixMsg * library. * *----------------------------------------------------------------------------- */ #ifndef VIX_HIDE_FROM_JAVA struct VixCommandRequestHeader * VixMsg_AllocRequestMsg(size_t msgHeaderAndBodyLength, int opCode, uint64 cookie, int credentialType, const char *userNamePassword); struct VixCommandResponseHeader * VixMsg_AllocResponseMsg(const struct VixCommandRequestHeader *requestHeader, VixError error, uint32 additionalError, size_t responseBodyLength, const void *responseBody, size_t *responseMsgLength); void VixMsg_InitResponseMsg(struct VixCommandResponseHeader *responseHeader, const struct VixCommandRequestHeader *requestHeader, VixError error, uint32 additionalError, size_t totalMessageLength); VixError VixMsg_ValidateMessage(const void *vMsg, size_t msgLength); VixError VixMsg_ValidateRequestMsg(const void *vMsg, size_t msgLength); VixError VixMsg_ValidateResponseMsg(const void *vMsg, size_t msgLength); VixError VixMsg_ParseWriteVariableRequest(VixMsgWriteVariableRequest *msg, char **valueName, char **value); VixError VixMsg_ObfuscateNamePassword(const char *userName, const char *password, char **result); VixError VixMsg_DeObfuscateNamePassword(const char *packagedName, char **userNameResult, char **passwordResult); VixError VixMsg_EncodeString(const char *str, char **result); VixError VixMsg_DecodeString(const char *str, char **result); Bool VixMsg_ValidateCommandInfoTable(void); const char *VixAsyncOp_GetDebugStrForOpCode(int opCode); VixCommandSecurityCategory VixMsg_GetCommandSecurityCategory(int opCode); /* * Vix private internal properties shared between the Vix client * and the VMX. */ enum { VIX_PROPERTY_VM_POWER_OFF_TO_SNAPSHOT_UID = 5102, }; VixError VixMsg_AllocGenericRequestMsg(int opCode, uint64 cookie, int credentialType, const char *userNamePassword, int options, VixPropertyListImpl *propertyList, VixCommandGenericRequest **request); VixError VixMsg_ParseGenericRequestMsg(const VixCommandGenericRequest *request, int *options, VixPropertyListImpl *propertyList); VixError VixMsg_ParseSimpleResponseWithString(const VixCommandResponseHeader *response, const char **result); void *VixMsg_MallocClientData(size_t size); void *VixMsg_ReallocClientData(void *ptr, size_t size); char *VixMsg_StrdupClientData(const char *s, Bool *allocateFailed); /* * Parser state used by VMAutomationMsgParser* group of functions. */ typedef struct { const char *currentPtr; const char *endPtr; } VMAutomationMsgParser; /* Keep the original type name around all the old code can stay the same. */ typedef VMAutomationMsgParser VMAutomationRequestParser; #define VMAutomationRequestParserInit VMAutomationMsgParserInitRequest #define VMAutomationMsgParserInitRequest(state, msg, fixedLength) \ __VMAutomationMsgParserInitRequest(__FUNCTION__, __LINE__, state, msg, fixedLength) VixError __VMAutomationMsgParserInitRequest(const char *caller, unsigned int line, VMAutomationMsgParser *state, const struct VixCommandRequestHeader *msg, size_t fixedLength); #define VMAutomationMsgParserInitResponse(state, msg, fixedLength) \ __VMAutomationMsgParserInitResponse(__FUNCTION__, __LINE__, state, msg, fixedLength) VixError __VMAutomationMsgParserInitResponse(const char *caller, unsigned int line, VMAutomationMsgParser *state, const struct VixCommandResponseHeader *msg, size_t fixedLength); #define VMAutomationRequestParserGetRemainingData \ VMAutomationMsgParserGetRemainingData const void * VMAutomationMsgParserGetRemainingData(VMAutomationMsgParser *state, size_t *length); #define VMAutomationRequestParserGetData VMAutomationMsgParserGetData #define VMAutomationMsgParserGetData(state, length, result) \ __VMAutomationMsgParserGetData(__FUNCTION__, __LINE__, \ state, length, (const char **)result) VixError __VMAutomationMsgParserGetData(const char *caller, unsigned int line, VMAutomationMsgParser *state, size_t length, const char **result); #define VMAutomationRequestParserGetOptionalString \ VMAutomationMsgParserGetOptionalString #define VMAutomationMsgParserGetOptionalString(state, length, result) \ __VMAutomationMsgParserGetOptionalString(__FUNCTION__, __LINE__, \ state, length, result) VixError __VMAutomationMsgParserGetOptionalString(const char *caller, unsigned int line, VMAutomationMsgParser *state, size_t length, const char **result); #define VMAutomationRequestParserGetOptionalStrings \ VMAutomationMsgParserGetOptionalStrings #define VMAutomationMsgParserGetOptionalStrings(state, count, length, \ result) \ __VMAutomationMsgParserGetOptionalStrings(__FUNCTION__, __LINE__, \ state, count, length, result) VixError __VMAutomationMsgParserGetOptionalStrings (const char *caller, unsigned int line, VMAutomationMsgParser *state, uint32 count, size_t length, const char **result); #define VMAutomationRequestParserGetString VMAutomationMsgParserGetString #define VMAutomationMsgParserGetString(state, length, result) \ __VMAutomationMsgParserGetString(__FUNCTION__, __LINE__, \ state, length, result) VixError __VMAutomationMsgParserGetString(const char *caller, unsigned int line, VMAutomationMsgParser *state, size_t length, const char **result); #define VMAutomationRequestParserGetPropertyList \ VMAutomationMsgParserGetPropertyList #define VMAutomationMsgParserGetPropertyList(state, length, propList) \ __VMAutomationMsgParserGetPropertyList(__FUNCTION__, __LINE__, \ state, length, propList) VixError __VMAutomationMsgParserGetPropertyList(const char *caller, unsigned int line, VMAutomationMsgParser *state, size_t length, VixPropertyListImpl *propList); #endif // VIX_HIDE_FROM_JAVA #endif // _VIX_COMMANDS_H_ open-vm-tools-9.4.0-1280544/lib/include/community_source.h0000644765153500003110000000505512220061556021412 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * community_source.h -- * * Macros for excluding source code from community. */ #ifndef _COMMUNITY_SOURCE_H_ #define _COMMUNITY_SOURCE_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_VMKDRIVERS #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_DISTRIBUTE #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMIROM #include "includeCheck.h" /* * Convenience macro for COMMUNITY_SOURCE */ #undef EXCLUDE_COMMUNITY_SOURCE #ifdef COMMUNITY_SOURCE #define EXCLUDE_COMMUNITY_SOURCE(x) #else #define EXCLUDE_COMMUNITY_SOURCE(x) x #endif #undef COMMUNITY_SOURCE_AMD_SECRET #if !defined(COMMUNITY_SOURCE) || defined(AMD_SOURCE) /* * It's ok to include AMD_SECRET source code for non-Community Source, * or for drops directed at AMD. */ #define COMMUNITY_SOURCE_AMD_SECRET #endif #undef COMMUNITY_SOURCE_INTEL_SECRET #if !defined(COMMUNITY_SOURCE) || defined(INTEL_SOURCE) /* * It's ok to include INTEL_SECRET source code for non-Community Source, * or for drops directed at Intel. */ #define COMMUNITY_SOURCE_INTEL_SECRET #endif #endif open-vm-tools-9.4.0-1280544/lib/include/sha1.h0000644765153500003110000000617412220061556016645 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * sha1.h -- * * SHA1 encryption */ #ifndef _SHA1_H_ #define _SHA1_H_ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" /* for uint32 */ #include "vm_basic_types.h" #if defined __APPLE__ && defined USERLEVEL /* * Apple provides basic crypto functions in its system runtime that are * maintained for both speed and security. Use those instead. */ #include #define SHA1_HASH_LEN CC_SHA1_DIGEST_LENGTH #define SHA1_CTX CC_SHA1_CTX #define SHA1Init CC_SHA1_Init #define SHA1Update CC_SHA1_Update #define SHA1Final CC_SHA1_Final #else /* SHA-1 in C By Steve Reid 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 */ /* 12/15/98: JEB: Removed main and moved prototypes to sha1.h Made SHA1Transform a static function */ #define SHA1_HASH_LEN 20 typedef struct { uint32 state[5]; uint32 count[2]; unsigned char buffer[64]; } SHA1_CTX; #define SHA1HANDSOFF /* Copies data before messing with it. */ void SHA1Init(SHA1_CTX* context); #ifdef SHA1HANDSOFF void SHA1Update(SHA1_CTX* context, const unsigned char *data, size_t len); #else void SHA1Update(SHA1_CTX* context, unsigned char *data, size_t len); #endif void SHA1Final(unsigned char digest[SHA1_HASH_LEN], SHA1_CTX* context); #endif // defined __APPLE__ && defined USERLEVEL #endif // ifndef _SHA1_H_ open-vm-tools-9.4.0-1280544/lib/include/mutexRankLib.h0000644765153500003110000001365212220061556020415 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _LIBMUTEXRANK_H #define _LIBMUTEXRANK_H #include "mutexRank.h" /* * MXUser mutex ranks for bora/lib code. * * The ranks define the ordering in which locks are allowed to be acquired. * * Only locks with higher rank numbers (generally more localized) * can be acquired while a lock with a lower rank number is active. * * bora/lib lock rank space is from RANK_libLockBase on up to * RANK_LEAF (see vm_basic_defs).asdf * * (Keep all of the below offsets in hex). */ /* * workerLib default completion lock * * Used for workerLib callers who don't provide their own lock. Held * around arbitrary completion callbacks so it probably makes sense to * be of a low rank. */ #define RANK_workerLibCmplLock RANK_libLockBase /* * hostDeviceInfo HAL lock * * Must be < vmhs locks since this is held around the RANK_vmhsHDILock * callback lock which vmhs passes into that library. */ #define RANK_hdiHALLock (RANK_libLockBase + 0x1005) /* * vmhs locks (must be < vigor) */ #define RANK_vmhsHDILock (RANK_libLockBase + 0x3002) #define RANK_vmhsThrMxLock (RANK_libLockBase + 0x3005) #define RANK_vmhsVmxMxLock (RANK_libLockBase + 0x3005) /* * hgfs locks */ #define RANK_hgfsSessionArrayLock (RANK_libLockBase + 0x4010) #define RANK_hgfsSharedFolders (RANK_libLockBase + 0x4030) #define RANK_hgfsNotifyLock (RANK_libLockBase + 0x4040) #define RANK_hgfsFileIOLock (RANK_libLockBase + 0x4050) #define RANK_hgfsSearchArrayLock (RANK_libLockBase + 0x4060) #define RANK_hgfsNodeArrayLock (RANK_libLockBase + 0x4070) /* * SLPv2 global lock */ #define RANK_slpv2GlobalLock (RANK_libLockBase + 0x4305) /* * vigor (must be < VMDB range and < disklib, see bug 741290) */ #define RANK_vigorClientLock (RANK_libLockBase + 0x4400) #define RANK_vigorOfflineClientLock (RANK_libLockBase + 0x4410) /* * NFC lib lock */ #define RANK_nfcLibLock (RANK_libLockBase + 0x4505) /* * policy ops pending list lock */ #define RANK_popPendingListLock (RANK_libLockBase + 0x4605) /* * disklib and I/O related locks */ #define RANK_diskLibLock (RANK_libLockBase + 0x5001) #define RANK_nasPluginLock (RANK_libLockBase + 0x5007) #define RANK_nasPluginMappingLock (RANK_libLockBase + 0x5008) #define RANK_diskLibPluginLock (RANK_libLockBase + 0x5010) #define RANK_vmioPluginRootLock (RANK_libLockBase + 0x5020) #define RANK_vmioPluginSysLock (RANK_libLockBase + 0x5040) #define RANK_fsCmdLock (RANK_libLockBase + 0x5050) #define RANK_scsiStateLock (RANK_libLockBase + 0x5060) #define RANK_parInitLock (RANK_libLockBase + 0x5070) #define RANK_namespaceLock (RANK_libLockBase + 0x5080) #define RANK_vvolLibLock (RANK_libLockBase + 0x5090) /* * VMDB range: * (RANK_libLockBase + 0x5500, RANK_libLockBase + 0x5600) */ #define RANK_vmuSecPolicyLock (RANK_libLockBase + 0x5505) #define RANK_vmdbCnxRpcLock (RANK_libLockBase + 0x5510) #define RANK_vmdbCnxRpcBarrierLock (RANK_libLockBase + 0x5520) #define RANK_vmdbCnxLock (RANK_libLockBase + 0x5530) #define RANK_vmdbSecureLock (RANK_libLockBase + 0x5540) #define RANK_vmdbDbLock (RANK_libLockBase + 0x5550) #define RANK_vmdbW32HookLock (RANK_libLockBase + 0x5560) #define RANK_vmdbWQPoolLock (RANK_libLockBase + 0x5570) #define RANK_vmdbMemMapLock (RANK_libLockBase + 0x5580) /* * USB range: * (RANK_libLockBase + 0x6500, RANK_libLockBase + 0x6600) */ #define RANK_usbArbLibGlobalLock (RANK_libLockBase + 0x6505) #define RANK_usbEnumGlobalLock (RANK_libLockBase + 0x6506) #define RANK_usbArbLibAsockLock (RANK_libLockBase + 0x6507) #define RANK_usbEnumBackendLock (RANK_libLockBase + 0x6508) /* * misc locks * * Assuming ordering is important here for the listed locks. Other * non-leaf locks are usually defined with RANK_LEAF - 1. * * At least: * impersonate < pollDefault * keyLocator < preference (for checking AESNI) * keyLocator < sslState (bug 743010) * configDb < keyLocator (for unlocking dictionaries) * battery/button < preference * workerLib < something for sure under VThread_Create * licenseCheck < preference * sslState < getSafeTmpDir */ #define RANK_vigorTransportListLock (RANK_libLockBase + 0x7010) #define RANK_batteryLock (RANK_libLockBase + 0x7030) #define RANK_buttonLock (RANK_libLockBase + 0x7040) #define RANK_impersonateLock (RANK_libLockBase + 0x7045) #define RANK_pollDefaultLock (RANK_libLockBase + 0x7050) #define RANK_workerLibLock (RANK_libLockBase + 0x7060) #define RANK_configDbLock (RANK_libLockBase + 0x7070) #define RANK_keyLocatorLock (RANK_libLockBase + 0x7080) #define RANK_sslStateLock (RANK_libLockBase + 0x7085) #define RANK_getSafeTmpDirLock (RANK_libLockBase + 0x7086) #define RANK_licenseCheckLock (RANK_libLockBase + 0x7090) #define RANK_preferenceLock (RANK_libLockBase + 0x7100) #endif /* _LIBMUTEXRANK_H */ open-vm-tools-9.4.0-1280544/lib/include/backdoor_types.h0000644765153500003110000001004212220061556021006 0ustar dtormts/********************************************************* * Copyright (C) 1999 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * backdoor_types.h -- * * Type definitions for backdoor interaction code. */ #ifndef _BACKDOOR_TYPES_H_ #define _BACKDOOR_TYPES_H_ #ifndef VM_I386 #error The backdoor protocol is only supported on x86 architectures. #endif /* * These #defines are intended for defining register structs as part of * existing named unions. If the union should encapsulate the register * (and nothing else), use DECLARE_REG_NAMED_STRUCT defined below. */ #define DECLARE_REG32_STRUCT \ struct { \ uint16 low; \ uint16 high; \ } halfs; \ uint32 word #define DECLARE_REG64_STRUCT \ DECLARE_REG32_STRUCT; \ struct { \ uint32 low; \ uint32 high; \ } words; \ uint64 quad #ifndef VM_X86_64 #define DECLARE_REG_STRUCT DECLARE_REG32_STRUCT #else #define DECLARE_REG_STRUCT DECLARE_REG64_STRUCT #endif #define DECLARE_REG_NAMED_STRUCT(_r) \ union { DECLARE_REG_STRUCT; } _r /* * Some of the registers are expressed by semantic name, because if they were * expressed as register structs declared above, we could only address them * by fixed size (half-word, word, quad, etc.) instead of by varying size * (size_t, uintptr_t). * * To be cleaner, these registers are expressed ONLY by semantic name, * rather than by a union of the semantic name and a register struct. */ typedef union { struct { DECLARE_REG_NAMED_STRUCT(ax); size_t size; /* Register bx. */ DECLARE_REG_NAMED_STRUCT(cx); DECLARE_REG_NAMED_STRUCT(dx); DECLARE_REG_NAMED_STRUCT(si); DECLARE_REG_NAMED_STRUCT(di); } in; struct { DECLARE_REG_NAMED_STRUCT(ax); DECLARE_REG_NAMED_STRUCT(bx); DECLARE_REG_NAMED_STRUCT(cx); DECLARE_REG_NAMED_STRUCT(dx); DECLARE_REG_NAMED_STRUCT(si); DECLARE_REG_NAMED_STRUCT(di); } out; } Backdoor_proto; typedef union { struct { DECLARE_REG_NAMED_STRUCT(ax); DECLARE_REG_NAMED_STRUCT(bx); size_t size; /* Register cx. */ DECLARE_REG_NAMED_STRUCT(dx); uintptr_t srcAddr; /* Register si. */ uintptr_t dstAddr; /* Register di. */ DECLARE_REG_NAMED_STRUCT(bp); } in; struct { DECLARE_REG_NAMED_STRUCT(ax); DECLARE_REG_NAMED_STRUCT(bx); DECLARE_REG_NAMED_STRUCT(cx); DECLARE_REG_NAMED_STRUCT(dx); DECLARE_REG_NAMED_STRUCT(si); DECLARE_REG_NAMED_STRUCT(di); DECLARE_REG_NAMED_STRUCT(bp); } out; } Backdoor_proto_hb; MY_ASSERTS(BACKDOOR_STRUCT_SIZES, ASSERT_ON_COMPILE(sizeof(Backdoor_proto) == 6 * sizeof(uintptr_t)); ASSERT_ON_COMPILE(sizeof(Backdoor_proto_hb) == 7 * sizeof(uintptr_t)); ) #undef DECLARE_REG_STRUCT #endif /* _BACKDOOR_TYPES_H_ */ open-vm-tools-9.4.0-1280544/lib/include/vmcheck.h0000644765153500003110000000237312220061556017426 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vmcheck.h -- * * Utility functions for discovering our virtualization status. */ #ifndef __VMCHECK_H__ # define __VMCHECK_H__ #ifdef __cplusplus extern "C" { #endif # include "vm_basic_types.h" Bool VmCheck_GetVersion(uint32 *version, // OUT uint32 *type); // OUT Bool VmCheck_IsVirtualWorld(void); #ifdef __cplusplus } #endif #endif /* __VMCHECK_H__ */ open-vm-tools-9.4.0-1280544/lib/include/guestStats.h0000644765153500003110000000563312220061556020156 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file guestStats.h * * Common declarations that aid in sending guest statistics to the vmx * and may be further to vmkernel. */ #ifndef _GUEST_STATS_H_ #define _GUEST_STATS_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vm_basic_types.h" typedef #include "vmware_pack_begin.h" struct GuestMemInfo { uint32 version; ///< MemInfo structure version. uint32 flags; ///< Indicates which stats are valid. uint64 memTotal; ///< Total physical memory in Kb. uint64 memFree; ///< Physical memory available in Kb. uint64 memBuff; ///< Physical memory used as buffer cache in Kb. uint64 memCache; ///< Physical memory used as cache in Kb. uint64 memActive; ///< Physical memory actively in use in Kb (working set) uint64 memInactive; ///< Physical memory inactive in Kb (cold pages) uint64 swapInRate; ///< Memory swapped out in Kb / sec. uint64 swapOutRate; ///< Memory swapped out in Kb / sec. uint64 ioInRate; ///< Amount of I/O in Kb / sec. uint64 ioOutRate; ///< Amount of I/O out in Kb / sec. uint64 hugePagesTotal; ///< Total number of huge pages. uint64 hugePagesFree; ///< Available number of huge pages. uint64 memPinned; ///< Unreclaimable physical memory in 4K page size. } #include "vmware_pack_end.h" GuestMemInfo; /* Flags for GuestMemInfo. */ #define MEMINFO_MEMTOTAL (1 << 0) #define MEMINFO_MEMFREE (1 << 1) #define MEMINFO_MEMBUFF (1 << 2) #define MEMINFO_MEMCACHE (1 << 3) #define MEMINFO_MEMACTIVE (1 << 4) #define MEMINFO_MEMINACTIVE (1 << 5) #define MEMINFO_SWAPINRATE (1 << 6) #define MEMINFO_SWAPOUTRATE (1 << 7) #define MEMINFO_IOINRATE (1 << 8) #define MEMINFO_IOOUTRATE (1 << 9) #define MEMINFO_HUGEPAGESTOTAL (1 << 10) #define MEMINFO_HUGEPAGESFREE (1 << 11) #define MEMINFO_MEMPINNED (1 << 12) #endif // _GUEST_STATS_H_ open-vm-tools-9.4.0-1280544/lib/include/vm_ctype.h0000644765153500003110000000467112220061556017637 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vm_ctype.h -- wrappers to calls which are vulnerable on Windows implementation */ #ifndef _VM_CTYPE_H_ #define _VM_CTYPE_H_ #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #include /* * On Windows platform, ctype.h functions are implemented via table lookup, * and a negative index is unsafe. See bug 83950. * Attack the parameter with 0xFF to cast away the signedness. */ #ifdef _WIN32 #define CType_IsAlnum(c) isalnum((c) & 0xFF) #define CType_IsAlpha(c) isalpha((c) & 0xFF) #define CType_IsAscii(c) isascii((c) & 0xFF) static __inline int CType_IsBlank(int c) { return c == ' ' || c == '\t'; } #define CType_IsCntrl(c) iscntrl((c) & 0xFF) #define CType_IsDigit(c) isdigit((c) & 0xFF) #define CType_IsGraph(c) isgraph((c) & 0xFF) #define CType_IsLower(c) islower((c) & 0xFF) #define CType_IsPrint(c) isprint((c) & 0xFF) #define CType_IsPunct(c) ispunct((c) & 0xFF) #define CType_IsSpace(c) isspace((c) & 0xFF) #define CType_IsUpper(c) isupper((c) & 0xFF) #define CType_IsXDigit(c) isxdigit((c) & 0xFF) #else #define CType_IsAlnum(c) isalnum((c)) #define CType_IsAlpha(c) isalpha((c)) #define CType_IsAscii(c) isascii((c)) #define CType_IsBlank(c) isblank((c)) #define CType_IsCntrl(c) iscntrl((c)) #define CType_IsDigit(c) isdigit((c)) #define CType_IsGraph(c) isgraph((c)) #define CType_IsLower(c) islower((c)) #define CType_IsPrint(c) isprint((c)) #define CType_IsPunct(c) ispunct((c)) #define CType_IsSpace(c) isspace((c)) #define CType_IsUpper(c) isupper((c)) #define CType_IsXDigit(c) isxdigit((c)) #endif /* _WIN32 */ #endif open-vm-tools-9.4.0-1280544/lib/include/vmstdio.h0000644765153500003110000000247012220061556017471 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vmstdio.h -- * * Functions that operate on FILE objects --hpreg */ #ifndef __VMSTDIO_H__ # define __VMSTDIO_H__ #include typedef enum { StdIO_Error, StdIO_EOF, StdIO_Success, } StdIO_Status; StdIO_Status StdIO_ReadNextLine(FILE *stream, // IN char **buf, // OUT size_t maxBufLength, // IN size_t *count); // OUT #endif /* __VMSTDIO_H__ */ open-vm-tools-9.4.0-1280544/lib/include/logFixed.h0000644765153500003110000000302512220061556017542 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _LOGFIXED_H_ #define _LOGFIXED_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" /* * LogFixed_Base2 and LogFixed_Base10 provide their values expressed * as a ration of two uint32 numbers with an accuracy of better than 1%. * * Reminder: A log, base x, of zero is undefined. These routines will assert * in development builds when a zero value is passed to them. */ void LogFixed_Base2(uint64 value, uint32 *numerator, uint32 *denominator); void LogFixed_Base10(uint64 value, uint32 *numerator, uint32 *denominator); #endif // _LOGFIXED_H_ open-vm-tools-9.4.0-1280544/lib/include/x86cpuid_asm.h0000644765153500003110000002340212220061556020314 0ustar dtormts/********************************************************* * Copyright (C) 2003-2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * x86cpuid_asm.h * * CPUID-related assembly functions. */ #ifndef _X86CPUID_ASM_H_ #define _X86CPUID_ASM_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_DISTRIBUTE #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #include "vm_basic_asm.h" #include "x86cpuid.h" /* * x86-64 windows doesn't support inline asm so we have to use these * intrinsic functions defined in the compiler. Not all of these are well * documented. There is an array in the compiler dll (c1.dll) which has * an array of the names of all the intrinsics minus the leading * underscore. Searching around in the ntddk.h file can also be helpful. * * The declarations for the intrinsic functions were taken from the DDK. * Our declarations must match the ddk's otherwise the 64-bit c++ compiler * will complain about second linkage of the intrinsic functions. * We define the intrinsic using the basic types corresponding to the * Windows typedefs. This avoids having to include windows header files * to get to the windows types. */ #ifdef _MSC_VER #ifdef __cplusplus extern "C" { #endif #ifdef VM_X86_64 /* * intrinsic functions only supported by x86-64 windows as of 2k3sp1 */ void __cpuid(unsigned int*, unsigned int); #pragma intrinsic(__cpuid) #endif /* VM_X86_64 */ #ifdef __cplusplus } #endif #endif /* _MSC_VER */ #ifdef __GNUC__ // { /* * Checked against the Intel manual and GCC --hpreg * * Need __volatile__ and "memory" since CPUID has a synchronizing effect. * The CPUID may also change at runtime (APIC flag, etc). * */ /* * %ebx is reserved on i386 PIC. Apple's gcc-5493 (gcc 4.0) compiling * for x86_64 incorrectly errors out saying %ebx is reserved. This is * Apple bug 7304232. */ #if vm_x86_64 ? (defined __APPLE_CC__ && __APPLE_CC__ == 5493) : defined __PIC__ #if vm_x86_64 /* * Note that this generates movq %rbx,%rbx; cpuid; xchgq %rbx,%rbx ... * Unfortunately Apple's assembler does not have .ifnes, and I cannot * figure out how to do that with .if. If we ever enable this code * on other 64bit systems, both movq & xchgq should be surrounded by * .ifnes \"%%rbx\", \"%q1\" & .endif */ #define VM_CPUID_BLOCK "movq %%rbx, %q1\n\t" \ "cpuid\n\t" \ "xchgq %%rbx, %q1\n\t" #define VM_EBX_OUT(reg) "=&r"(reg) #else #define VM_CPUID_BLOCK "movl %%ebx, %1\n\t" \ "cpuid\n\t" \ "xchgl %%ebx, %1\n\t" #define VM_EBX_OUT(reg) "=&rm"(reg) #endif #else #define VM_CPUID_BLOCK "cpuid" #define VM_EBX_OUT(reg) "=b"(reg) #endif static INLINE void __GET_CPUID(int eax, // IN CPUIDRegs *regs) // OUT { __asm__ __volatile__( VM_CPUID_BLOCK : "=a" (regs->eax), VM_EBX_OUT(regs->ebx), "=c" (regs->ecx), "=d" (regs->edx) : "a" (eax) : "memory" ); } static INLINE void __GET_CPUID2(int eax, // IN int ecx, // IN CPUIDRegs *regs) // OUT { __asm__ __volatile__( VM_CPUID_BLOCK : "=a" (regs->eax), VM_EBX_OUT(regs->ebx), "=c" (regs->ecx), "=d" (regs->edx) : "a" (eax), "c" (ecx) : "memory" ); } static INLINE uint32 __GET_EAX_FROM_CPUID(int eax) // IN { uint32 ebx; __asm__ __volatile__( VM_CPUID_BLOCK : "=a" (eax), VM_EBX_OUT(ebx) : "a" (eax) : "memory", "%ecx", "%edx" ); return eax; } static INLINE uint32 __GET_EBX_FROM_CPUID(int eax) // IN { uint32 ebx; __asm__ __volatile__( VM_CPUID_BLOCK : "=a" (eax), VM_EBX_OUT(ebx) : "a" (eax) : "memory", "%ecx", "%edx" ); return ebx; } static INLINE uint32 __GET_ECX_FROM_CPUID(int eax) // IN { uint32 ecx; uint32 ebx; __asm__ __volatile__( VM_CPUID_BLOCK : "=a" (eax), VM_EBX_OUT(ebx), "=c" (ecx) : "a" (eax) : "memory", "%edx" ); return ecx; } static INLINE uint32 __GET_EDX_FROM_CPUID(int eax) // IN { uint32 edx; uint32 ebx; __asm__ __volatile__( VM_CPUID_BLOCK : "=a" (eax), VM_EBX_OUT(ebx), "=d" (edx) : "a" (eax) : "memory", "%ecx" ); return edx; } static INLINE uint32 __GET_EAX_FROM_CPUID4(int ecx) // IN { uint32 eax; uint32 ebx; __asm__ __volatile__( VM_CPUID_BLOCK : "=a" (eax), VM_EBX_OUT(ebx), "=c" (ecx) : "a" (4), "c" (ecx) : "memory", "%edx" ); return eax; } #undef VM_CPUID_BLOCK #undef VM_EBX_OUT #elif defined(_MSC_VER) // } { static INLINE void __GET_CPUID(int input, CPUIDRegs *regs) { #ifdef VM_X86_64 __cpuid((unsigned int *)regs, input); #else __asm push esi __asm push ebx __asm push ecx __asm push edx __asm mov eax, input __asm mov esi, regs __asm _emit 0x0f __asm _emit 0xa2 __asm mov 0x0[esi], eax __asm mov 0x4[esi], ebx __asm mov 0x8[esi], ecx __asm mov 0xC[esi], edx __asm pop edx __asm pop ecx __asm pop ebx __asm pop esi #endif } #ifdef VM_X86_64 /* * No inline assembly in Win64. Implemented in bora/lib/misc in * cpuidMasm64.asm. */ extern void __GET_CPUID2(int inputEax, int inputEcx, CPUIDRegs *regs); #else // VM_X86_64 static INLINE void __GET_CPUID2(int inputEax, int inputEcx, CPUIDRegs *regs) { __asm push esi __asm push ebx __asm push ecx __asm push edx __asm mov eax, inputEax __asm mov ecx, inputEcx __asm mov esi, regs __asm _emit 0x0f __asm _emit 0xa2 __asm mov 0x0[esi], eax __asm mov 0x4[esi], ebx __asm mov 0x8[esi], ecx __asm mov 0xC[esi], edx __asm pop edx __asm pop ecx __asm pop ebx __asm pop esi } #endif static INLINE uint32 __GET_EAX_FROM_CPUID(int input) { #ifdef VM_X86_64 CPUIDRegs regs; __cpuid((unsigned int *)®s, input); return regs.eax; #else uint32 output; //NOT_TESTED(); __asm push ebx __asm push ecx __asm push edx __asm mov eax, input __asm _emit 0x0f __asm _emit 0xa2 __asm mov output, eax __asm pop edx __asm pop ecx __asm pop ebx return output; #endif } static INLINE uint32 __GET_EBX_FROM_CPUID(int input) { #ifdef VM_X86_64 CPUIDRegs regs; __cpuid((unsigned int *)®s, input); return regs.ebx; #else uint32 output; //NOT_TESTED(); __asm push ebx __asm push ecx __asm push edx __asm mov eax, input __asm _emit 0x0f __asm _emit 0xa2 __asm mov output, ebx __asm pop edx __asm pop ecx __asm pop ebx return output; #endif } static INLINE uint32 __GET_ECX_FROM_CPUID(int input) { #ifdef VM_X86_64 CPUIDRegs regs; __cpuid((unsigned int *)®s, input); return regs.ecx; #else uint32 output; //NOT_TESTED(); __asm push ebx __asm push ecx __asm push edx __asm mov eax, input __asm _emit 0x0f __asm _emit 0xa2 __asm mov output, ecx __asm pop edx __asm pop ecx __asm pop ebx return output; #endif } static INLINE uint32 __GET_EDX_FROM_CPUID(int input) { #ifdef VM_X86_64 CPUIDRegs regs; __cpuid((unsigned int *)®s, input); return regs.edx; #else uint32 output; //NOT_TESTED(); __asm push ebx __asm push ecx __asm push edx __asm mov eax, input __asm _emit 0x0f __asm _emit 0xa2 __asm mov output, edx __asm pop edx __asm pop ecx __asm pop ebx return output; #endif } #ifdef VM_X86_64 /* * No inline assembly in Win64. Implemented in bora/lib/misc in * cpuidMasm64.asm. */ extern uint32 __GET_EAX_FROM_CPUID4(int inputEcx); #else // VM_X86_64 static INLINE uint32 __GET_EAX_FROM_CPUID4(int inputEcx) { uint32 output; //NOT_TESTED(); __asm push ebx __asm push ecx __asm push edx __asm mov eax, 4 __asm mov ecx, inputEcx __asm _emit 0x0f __asm _emit 0xa2 __asm mov output, eax __asm pop edx __asm pop ecx __asm pop ebx return output; } #endif // VM_X86_64 #else // } #error #endif #define CPUID_FOR_SIDE_EFFECTS() ((void)__GET_EAX_FROM_CPUID(0)) static INLINE void __GET_CPUID4(int inputEcx, CPUIDRegs *regs) { __GET_CPUID2(4, inputEcx, regs); } /* The first parameter is used as an rvalue and then as an lvalue. */ #define GET_CPUID(_ax, _bx, _cx, _dx) { \ CPUIDRegs regs; \ __GET_CPUID(_ax, ®s); \ _ax = regs.eax; \ _bx = regs.ebx; \ _cx = regs.ecx; \ _dx = regs.edx; \ } #endif open-vm-tools-9.4.0-1280544/lib/include/file.h0000644765153500003110000003040312220061556016720 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * file.h -- * * Interface to host file system and related utility functions. */ #ifndef _FILE_H_ #define _FILE_H_ #ifdef __cplusplus extern "C"{ #endif #include #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #include "fileIO.h" #include "unicodeTypes.h" #include "err.h" #if defined(_WIN32) #define FILE_MAXPATH MAX_PATH #else # ifdef __FreeBSD__ # include // For __FreeBSD_version # endif # if defined(__FreeBSD__) # include // PATH_MAX # else # include // PATH_MAX # endif #define FILE_MAXPATH PATH_MAX #endif #define FILE_SEARCHPATHTOKEN ";" /* * Opaque, platform-specific stucture for supporting the directory walking API. */ typedef struct WalkDirContextImpl WalkDirContextImpl; typedef const WalkDirContextImpl *WalkDirContext; /* * When File_MakeTempEx2 is called, it creates a temporary file or a directory * in a specified directory. File_MakeTempEx2 calls a user-specified callback * function to get the filename. Callback function should be of type * File_MakeTempCreateNameFunc. * * 'num' specifies nth time this function is called. * * 'data' specifies the payload that the user specified when executing * File_MakeTempEx2 function. * * If successful, this function should return a dynamically allocated string * with the filename. * * File_MakeTempEx2 frees the pathName after a successful call to this * function. * */ typedef Unicode File_MakeTempCreateNameFunc(uint32 num, void *data); #if defined(__APPLE__) typedef enum { FILEMACOS_UNMOUNT_SUCCESS, FILEMACOS_UNMOUNT_SUCCESS_ALREADY, FILEMACOS_UNMOUNT_ERROR, } FileMacosUnmountStatus; FileMacosUnmountStatus FileMacos_UnmountDev(char const *bsdDev, Bool wholeDev, Bool eject, Bool su); void FileMacos_MountDevAsyncNoResult(char const *bsdDev, Bool su); Bool FileMacos_IsOnExternalDevice(int fd); Bool FileMacos_IsOnSparseDmg(int fd); Bool FileMacos_IsSliceDevice(char const *bsdDev); char *FileMacos_DiskDevToUserFriendlyName(char const *bsdDiskDev); char *FileMacos_DiskDevToVolumeName(char const *bsdDiskDev); char *FileMacos_DiskDeviceToUniqueID(char const *bsdPath); char *FileMacos_UniqueIDToDiskDevice(char const *identifier); Bool FileMacOS_MakeSecureLibraryCopies(const char *inDir, const char **dylibName, unsigned numDylibs, char **outDir); #elif defined VMX86_SERVER struct FS_PartitionListResult; int File_GetVMFSAttributes(ConstUnicode pathName, struct FS_PartitionListResult **fsAttrs); int File_GetVMFSVersion(ConstUnicode pathName, uint32 *versionNum); int File_GetVMFSBlockSize(ConstUnicode pathName, uint32 *blockSize); int File_GetVMFSMountInfo(ConstUnicode pathName, char **fsType, uint32 *version, char **remoteIP, char **remoteMountPoint, char **localMountPoint); #endif Bool File_SupportsZeroedThick(ConstUnicode pathName); Bool File_SupportsMultiWriter(ConstUnicode pathName); Bool File_SupportsMandatoryLock(ConstUnicode pathName); Bool File_Exists(ConstUnicode pathName); int File_Unlink(ConstUnicode pathName); int File_UnlinkIfExists(ConstUnicode pathName); int File_UnlinkDelayed(ConstUnicode pathName); int File_UnlinkNoFollow(ConstUnicode pathName); void File_SplitName(ConstUnicode pathName, Unicode *volume, Unicode *dir, Unicode *base); void File_GetPathName(ConstUnicode fullPath, Unicode *pathName, Unicode *base); Unicode File_StripSlashes(ConstUnicode path); Unicode File_PathJoin(ConstUnicode dirName, ConstUnicode baseName); Bool File_CreateDirectory(ConstUnicode pathName); Bool File_CreateDirectoryEx(ConstUnicode pathName, int mask); Bool File_EnsureDirectory(ConstUnicode pathName); Bool File_DeleteEmptyDirectory(ConstUnicode pathName); Bool File_CreateDirectoryHierarchy(ConstUnicode pathName, Unicode *topmostCreated); Bool File_CreateDirectoryHierarchyEx(ConstUnicode pathName, int mask, Unicode *topmostCreated); Bool File_DeleteDirectoryTree(ConstUnicode pathName); int File_ListDirectory(ConstUnicode pathName, Unicode **ids); /* * Simple file-system walk. */ WalkDirContext File_WalkDirectoryStart(ConstUnicode parentPath); Bool File_WalkDirectoryNext(WalkDirContext context, Unicode *path); void File_WalkDirectoryEnd(WalkDirContext context); Bool File_IsDirectory(ConstUnicode pathName); Bool File_IsFile(ConstUnicode pathName); Bool File_IsSymLink(ConstUnicode pathName); Bool File_IsCharDevice(ConstUnicode pathName); Bool File_IsRemote(ConstUnicode pathName); Bool File_IsEmptyDirectory(ConstUnicode pathName); Unicode File_Cwd(ConstUnicode drive); // XXX belongs to `process' module Unicode File_FullPath(ConstUnicode pathName); Bool File_IsFullPath(ConstUnicode pathName); uint64 File_GetFreeSpace(ConstUnicode pathName, Bool doNotAscend); uint64 File_GetCapacity(ConstUnicode pathName); int File_MakeTempEx(ConstUnicode dir, ConstUnicode pathName, Unicode *presult); int File_MakeTempEx2(ConstUnicode dir, Bool createTempFile, File_MakeTempCreateNameFunc *createNameFunc, void *createFuncData, Unicode *presult); int64 File_GetModTime(ConstUnicode pathName); char *File_GetModTimeString(ConstUnicode pathName); char *File_GetUniqueFileSystemID(const char *pathName); Bool File_GetTimes(ConstUnicode pathName, VmTimeType *createTime, VmTimeType *accessTime, VmTimeType *writeTime, VmTimeType *attrChangeTime); Bool File_SetTimes(ConstUnicode pathName, VmTimeType createTime, VmTimeType accessTime, VmTimeType writeTime, VmTimeType attrChangeTime); Bool File_GetFilePermissions(ConstUnicode pathName, int *mode); Bool File_SetFilePermissions(ConstUnicode pathName, int mode); Bool File_SupportsFileSize(ConstUnicode pathName, uint64 fileSize); Bool File_GetMaxFileSize(ConstUnicode pathName, uint64 *maxFileSize); #ifdef VMX86_SERVER Bool File_Is2TiBEnabled(void); #endif Bool File_SupportsLargeFiles(ConstUnicode pathName); char *File_MapPathPrefix(const char *oldPath, const char **oldPrefixes, const char **newPrefixes, size_t numPrefixes); Bool File_CopyFromFdToFd(FileIODescriptor src, FileIODescriptor dst); FileIOResult File_CreatePrompt(FileIODescriptor *file, ConstUnicode pathName, int access, int prompt); Bool File_CopyFromFd(FileIODescriptor src, ConstUnicode dstName, Bool overwriteExisting); Bool File_Copy(ConstUnicode srcName, ConstUnicode dstName, Bool overwriteExisting); Bool File_CopyFromFdToName(FileIODescriptor src, ConstUnicode dstName, int dstDispose); Bool File_CopyFromNameToName(ConstUnicode srcName, ConstUnicode dstName, int dstDispose); Bool File_MoveTree(ConstUnicode srcName, ConstUnicode dstName, Bool overwriteExisting); Bool File_CopyTree(ConstUnicode srcName, ConstUnicode dstName, Bool overwriteExisting, Bool followSymlinks); Bool File_Replace(ConstUnicode oldFile, ConstUnicode newFile); int File_Rename(ConstUnicode oldFile, ConstUnicode newFile); int File_RenameRetry(ConstUnicode oldFile, ConstUnicode newFile, uint32 msecMaxWaitTime); Bool File_Move(ConstUnicode oldFile, ConstUnicode newFile, Bool *asRename); void File_Rotate(const char *pathName, int n, Bool noRename, char **newFileName); int File_GetFSMountInfo(ConstUnicode pathName, char **fsType, uint32 *version, char **remoteIP, char **remoteMountPoint, char **localMountPoint); /* Get size only for regular file. */ int64 File_GetSize(ConstUnicode pathName); /* Get size for file or directory. */ int64 File_GetSizeEx(ConstUnicode pathName); int64 File_GetSizeByPath(ConstUnicode pathName); int64 File_GetSizeAlternate(ConstUnicode pathName); /* file change notification module */ typedef void (*CbFunction)(void *clientData); typedef void (*NotifyCallback)(ConstUnicode pathName, int err, void *data); typedef void (*PollTimeout) (CbFunction f, void *clientData, int delay); typedef void (*PollRemoveTimeout) (CbFunction f, void *clientData); void File_PollInit(PollTimeout pt, PollRemoveTimeout prt); void File_PollExit(void); void File_PollImpersonateOnCheck(Bool check); Bool File_PollAddFile(ConstUnicode pathName, uint32 pollPeriod, NotifyCallback callback, void *data, Bool fPeriodic); Bool File_PollAddDirFile(ConstUnicode pathName, uint32 pollPeriod, NotifyCallback callback, void *data, Bool fPeriodic); Bool File_PollRemoveFile(ConstUnicode pathName, uint32 pollPeriod, NotifyCallback callback); Bool File_IsSameFile(ConstUnicode path1, ConstUnicode path2); char *File_PrependToPath(const char *searchPath, const char *elem); Bool File_FindFileInSearchPath(const char *file, const char *searchPath, const char *cwd, char **result); Unicode File_ReplaceExtension(ConstUnicode pathName, ConstUnicode newExtension, uint32 numExtensions, ...); Unicode File_RemoveExtension(ConstUnicode pathName); Bool File_MakeCfgFileExecutable(ConstUnicode pathName); char *File_ExpandAndCheckDir(const char *dirName); char *File_GetSafeTmpDir(Bool useConf); int File_MakeSafeTemp(ConstUnicode tag, Unicode *presult); Bool File_DoesVolumeSupportAcls(ConstUnicode pathName); #ifdef __cplusplus } // extern "C" { #endif #endif // ifndef _FILE_H_ open-vm-tools-9.4.0-1280544/lib/include/vixOpenSource.h0000644765153500003110000006460412220061556020624 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * This header file is given out as part of the open source * tools. Things in this file are public, but they may not have * been tested or documented, and that may change in future releases. * The public Vix API is defined in vix.h * * These definitions are used by the implementation of the vix * client, the VMX process, and the tols. * */ #ifndef _VIXOpenSource_h_ #define _VIXOpenSource_h_ #ifdef __cplusplus extern "C"{ #endif /* * VIX_HIDE_BORA_DEPENDENCIES: * * This flag allows some mini-applications to use parts of Vix that will * someday make it into the public API, without including all of the include * directories in bora. Specifically, some VMware apps will want to use a * separate, more public, build tree, but still make use API that have not been * publicly released yet. */ /* * VIX_HIDE_FROM_JAVA * * Setting this flag minizes the functions exposed here. The java * binding is generated by processing this header, resulting in a * large number of currently unused functions. To keep the number * of functions that need to be exposed via vixWrapper, we hide all * but the needed functions to java. */ /* * If we're hiding functions from java, also hide the bora dependencies. */ #ifdef VIX_HIDE_FROM_JAVA #define VIX_HIDE_BORA_DEPENDENCIES #endif #include "vm_basic_types.h" #ifndef VIX_HIDE_BORA_DEPENDENCIES #include "cryptoError.h" #endif // VIX_HIDE_BORA_DEPENDENCIES #include "vix.h" // Vix Public API /* *----------------------------------------------------------------------------- * * Vix Errors -- * *----------------------------------------------------------------------------- */ #ifndef VIX_HIDE_BORA_DEPENDENCIES VixError Vix_TranslateSystemError(int systemError); VixError Vix_TranslateCryptoError(CryptoError cryptoError); VixError Vix_TranslateErrno(int systemError); #ifdef _WIN32 VixError Vix_TranslateCOMError(HRESULT comError); VixError Vix_TranslateGuestRegistryError(int systemError); #endif #endif // VIX_HIDE_BORA_DEPENDENCIES /* * This is an expanded view of a VixError * Every VixError is a 64-bit int, so it can fit into this struct. * * The flags, extraErrorType, and extraError are all optional. They * do not have to be set for any error. In fact, these are guaranteed * to be all 0 when the error is VIX_OK. This means that any program * that checks (VIX_OK == err) or (VIX_OK != err) will always work. * * The basic error field is a Vix error value, and it's the lsb * of the new struct. This means that a 64-bit error can be assigned * enum constant, like an integer. For example, err = VIX_E_FAIL; works. * This just leaves the flags and extraError fields as 0. */ typedef #include "vmware_pack_begin.h" struct VixErrorFields { uint16 error; uint8 flags; uint8 extraErrorType; uint32 extraError; } #include "vmware_pack_end.h" VixErrorFields; /* * These are the flags for a Vix error. */ enum { VIX_ERRORFLAG_GUEST = 0x0001, VIX_ERRORFLAG_REMOTE = 0x0002, }; /* * These are the types of extra error in a Vix error. */ enum { VIX_ERROREXTRATYPE_NONE = 0, VIX_ERROREXTRATYPE_SNAPSHOT = 1, VIX_ERROREXTRATYPE_DISKLIB = 2, VIX_ERROREXTRATYPE_WINDOWS = 3, VIX_ERROREXTRATYPE_LINUX = 4, VIX_ERROREXTRATYPE_FILE = 5, VIX_ERROREXTRATYPE_VMDB = 6, VIX_ERROREXTRATYPE_AIO = 7, VIX_ERROREXTRATYPE_CRYPTO = 8, VIX_ERROREXTRATYPE_KEYSAFE = 9, VIX_ERROREXTRATYPE_BLOCKLIST = 10, VIX_ERROREXTRATYPE_V2I = 11, VIX_ERROREXTRATYPE_MSGPOST = 12, }; /* * These are the types of extra error in a Vix error. */ #define VIX_ERROR_BASE_ERROR(err) ((VixErrorFields *) &err)->error #define VIX_ERROR_EXTRA_ERROR(err) ((VixErrorFields *) &err)->extraError #define VIX_ERROR_EXTRA_ERROR_TYPE(err) ((VixErrorFields *) &err)->extraErrorType #define VIX_ERROR_FROM_GUEST(err) (((VixErrorFields *) &err)->flags & VIX_ERRORFLAG_GUEST) #define VIX_ERROR_FROM_REMOTE(err) (((VixErrorFields *) &err)->flags & VIX_ERRORFLAG_REMOTE) #define VIX_ERROR_SET_FROM_GUEST(err) (((VixErrorFields *) &err)->flags |= VIX_ERRORFLAG_GUEST) #define VIX_ERROR_SET_FROM_REMOTE(err) (((VixErrorFields *) &err)->flags |= VIX_ERRORFLAG_REMOTE) #define VIX_SET_GUEST_WINDOWS_ERROR(err, vixError, winError) \ do { \ err = 0; \ VIX_ERROR_BASE_ERROR(err) = vixError; \ VIX_ERROR_EXTRA_ERROR(err) = winError; \ VIX_ERROR_EXTRA_ERROR_TYPE(err) = VIX_ERROREXTRATYPE_WINDOWS; \ VIX_ERROR_SET_FROM_GUEST(err); \ } while (0) #define VIX_ERROR_SET_ADDITIONAL_ERROR(err, vixError, additionalError) \ do { \ err = additionalError; \ err = (err << 32) | vixError; \ } while (0) /* * This defines additional error codes. * The public error codes are defined in vix.h * These error codes are in addition to those. */ enum { VIX_E_OP_NOT_SUPPORTED_ON_NON_VMWARE_VM = 3038, VIX_E_VI_OP_NOT_SUPPORTED_ON_GUEST = 3048, VIX_E_INVALID_LOGIN_CREDENTIALS = 3050, /* File Errors */ VIX_E_DIRECTORY_NOT_EMPTY = 20006, VIX_E_GUEST_AUTH_MULIPLE_MAPPINGS = 20007, /* Guest Reg Errors */ VIX_E_REG_KEY_INVALID = 20008, VIX_E_REG_KEY_HAS_SUBKEYS = 20009, VIX_E_REG_VALUE_NOT_FOUND = 20010, VIX_E_REG_KEY_ALREADY_EXISTS = 20011, /* Generic Guest Errors */ VIX_E_HGFS_MOUNT_FAIL = 20050, /* Reg Errors*/ VIX_E_REG_INCORRECT_VALUE_TYPE = 25000 /* WARNING. Do not exceed 2**16 */ }; /* *----------------------------------------------------------------------------- * * VIX Handles -- * * These are common functions that apply to handles of several types. *----------------------------------------------------------------------------- */ /* * VIX Property ID's * * These are used in the tools, but they are not (yet) part of the public * API. They may be promoted, but for now they are not tested or documented. */ enum { VIX_PROPERTY_VM_GUEST_TEMP_DIR_PROPERTY = 203, /* VMX properties. */ VIX_PROPERTY_VMX_VERSION = 4400, VIX_PROPERTY_VMX_PRODUCT_NAME = 4401, /* DEPRECTATED VIX_PROPERTY_VMX_VIX_FEATURES = 4402, */ /* GuestOS and Tools properties. */ VIX_PROPERTY_GUEST_TOOLS_VERSION = 4500, VIX_PROPERTY_GUEST_TOOLS_API_OPTIONS = 4501, VIX_PROPERTY_GUEST_OS_FAMILY = 4502, VIX_PROPERTY_GUEST_OS_VERSION = 4503, VIX_PROPERTY_GUEST_OS_PACKAGE_LIST = 4504, VIX_PROPERTY_GUEST_NAME = 4505, VIX_PROPERTY_GUEST_POWER_OFF_SCRIPT = 4506, VIX_PROPERTY_GUEST_POWER_ON_SCRIPT = 4507, VIX_PROPERTY_GUEST_RESUME_SCRIPT = 4508, VIX_PROPERTY_GUEST_SUSPEND_SCRIPT = 4509, VIX_PROPERTY_GUEST_TOOLS_PRODUCT_NAM = 4511, VIX_PROPERTY_FOREIGN_VM_TOOLS_VERSION = 4512, VIX_PROPERTY_VM_DHCP_ENABLED = 4513, VIX_PROPERTY_VM_IP_ADDRESS = 4514, VIX_PROPERTY_VM_SUBNET_MASK = 4515, VIX_PROPERTY_VM_DEFAULT_GATEWAY = 4516, VIX_PROPERTY_VM_DNS_SERVER_DHCP_ENABLED = 4517, VIX_PROPERTY_VM_DNS_SERVER = 4518, VIX_PROPERTY_GUEST_TOOLS_WORD_SIZE = 4519, VIX_PROPERTY_GUEST_OS_VERSION_SHORT = 4520, VIX_PROPERTY_GUEST_AUTH_SSPI_TOKEN = 4531, VIX_PROPERTY_GUEST_AUTH_SSPI_SESSION_ID = 4532, VIX_PROPERTY_GUEST_AUTH_SESSION_TICKET = 4533, /* VI guest operation status */ VIX_PROPERTY_GUEST_START_PROGRAM_ENABLED = 4540, VIX_PROPERTY_GUEST_LIST_PROCESSES_ENABLED = 4541, VIX_PROPERTY_GUEST_TERMINATE_PROCESS_ENABLED = 4542, VIX_PROPERTY_GUEST_READ_ENVIRONMENT_VARIABLE_ENABLED = 4543, VIX_PROPERTY_GUEST_VALIDATE_CREDENTIALS_ENABLED = 4544, VIX_PROPERTY_GUEST_ACQUIRE_CREDENTIALS_ENABLED = 4545, VIX_PROPERTY_GUEST_RELEASE_CREDENTIALS_ENABLED = 4546, VIX_PROPERTY_GUEST_MAKE_DIRECTORY_ENABLED = 4547, VIX_PROPERTY_GUEST_DELETE_FILE_ENABLED = 4548, VIX_PROPERTY_GUEST_DELETE_DIRECTORY_ENABLED = 4549, VIX_PROPERTY_GUEST_MOVE_DIRECTORY_ENABLED = 4550, VIX_PROPERTY_GUEST_MOVE_FILE_ENABLED = 4551, VIX_PROPERTY_GUEST_CREATE_TEMP_FILE_ENABLED = 4552, VIX_PROPERTY_GUEST_CREATE_TEMP_DIRECTORY_ENABLED = 4553, VIX_PROPERTY_GUEST_LIST_FILES_ENABLED = 4554, VIX_PROPERTY_GUEST_CHANGE_FILE_ATTRIBUTES_ENABLED = 4555, VIX_PROPERTY_GUEST_INITIATE_FILE_TRANSFER_FROM_GUEST_ENABLED = 4556, VIX_PROPERTY_GUEST_INITIATE_FILE_TRANSFER_TO_GUEST_ENABLED = 4557, VIX_PROPERTY_GUEST_ADD_AUTH_ALIAS_ENABLED = 4558, VIX_PROPERTY_GUEST_REMOVE_AUTH_ALIAS_ENABLED = 4559, VIX_PROPERTY_GUEST_LIST_AUTH_ALIASES_ENABLED = 4560, VIX_PROPERTY_GUEST_LIST_MAPPED_ALIASES_ENABLED = 4561, VIX_PROPERTY_GUEST_CREATE_REGISTRY_KEY_ENABLED = 4562, VIX_PROPERTY_GUEST_LIST_REGISTRY_KEYS_ENABLED = 4563, VIX_PROPERTY_GUEST_DELETE_REGISTRY_KEY_ENABLED = 4564, VIX_PROPERTY_GUEST_SET_REGISTRY_VALUE_ENABLED = 4565, VIX_PROPERTY_GUEST_LIST_REGISTRY_VALUES_ENABLED = 4566, VIX_PROPERTY_GUEST_DELETE_REGISTRY_VALUE_ENABLED = 4567, }; /* *----------------------------------------------------------------------------- * * PropertyList -- * *----------------------------------------------------------------------------- */ /* * VIX Property Type */ enum { //VIX_PROPERTYTYPE_ANY = 0, //VIX_PROPERTYTYPE_INTEGER = 1, //VIX_PROPERTYTYPE_STRING = 2, //VIX_PROPERTYTYPE_BOOL = 3, //VIX_PROPERTYTYPE_HANDLE = 4, //VIX_PROPERTYTYPE_INT64 = 5, //VIX_PROPERTYTYPE_BLOB = 6, VIX_PROPERTYTYPE_POINTER = 7 }; #ifndef VIX_HIDE_FROM_JAVA /* * This is a single name/value pair. */ typedef struct VixPropertyValue { int propertyID; VixPropertyType type; union { Bool boolValue; char *strValue; int intValue; int64 int64Value; VixHandle handleValue; struct { unsigned char *blobContents; int blobSize; } blobValue; void *ptrValue; } value; Bool isDirty; Bool isSensitive; struct VixPropertyValue *next; } VixPropertyValue; /* * This is the entire list. */ typedef struct VixPropertyListImpl { VixPropertyValue *properties; } VixPropertyListImpl; /* * This defines what action Deserialize should take when it encounters * a string that is not UTF-8. */ typedef enum VixPropertyListBadEncodingAction { /* * Abort the deserialization and return an error. This is the recommended * value since it is the strictest; you don't have to think about how * any clients or library code will handle escaped values. * This should always be used when parsing property lists passing arguments * to RPCs since we should be very strict in terms of actions we take * based on arguments. */ VIX_PROPERTY_LIST_BAD_ENCODING_ERROR, /* * Escape any non-UTF-8 characters in the string, add the result to the * property list, and continue deserializing. This should only be used * when there are likely to be applications generated non-ASCII values * for the property list in question (e.g., the Tools properties sent by * pre-i18n Tools) and the properties are more informative then * actionable (something like the hostname of a guest, maybe). */ VIX_PROPERTY_LIST_BAD_ENCODING_ESCAPE, } VixPropertyListBadEncodingAction; void VixPropertyList_Initialize(VixPropertyListImpl *propList); void VixPropertyList_RemoveAllWithoutHandles(VixPropertyListImpl *propList); VixError VixPropertyList_Serialize(VixPropertyListImpl *propListImpl, Bool dirtyOnly, size_t *resultSize, char **resultBuffer); VixError VixPropertyList_Deserialize(VixPropertyListImpl *propListImpl, const char *buffer, size_t bufferSize, VixPropertyListBadEncodingAction action); VixError VixPropertyList_DeserializeNoClobber(VixPropertyListImpl *propListImpl, const char *buffer, size_t bufferSize, VixPropertyListBadEncodingAction action); VixError VixPropertyList_GetString(struct VixPropertyListImpl *propList, int propertyID, int index, char **resultValue); VixError VixPropertyList_SetString(struct VixPropertyListImpl *propList, int propertyID, const char *value); VixError VixPropertyList_GetInteger(struct VixPropertyListImpl *propList, int propertyID, int index, int *resultValue); VixError VixPropertyList_SetInteger(struct VixPropertyListImpl *propList, int propertyID, int value); VixError VixPropertyList_GetBool(struct VixPropertyListImpl *propList, int propertyID, int index, Bool *resultValue); VixError VixPropertyList_SetBool(struct VixPropertyListImpl *propList, int propertyID, Bool value); VixError VixPropertyList_GetHandle(struct VixPropertyListImpl *propList, int propertyID, int index, VixHandle *resultValue); VixError VixPropertyList_SetHandle(struct VixPropertyListImpl *propList, int propertyID, VixHandle value); VixError VixPropertyList_GetInt64(struct VixPropertyListImpl *propList, int propertyID, int index, int64 *resultValue); VixError VixPropertyList_SetInt64(struct VixPropertyListImpl *propList, int propertyID, int64 value); VixError VixPropertyList_GetBlob(struct VixPropertyListImpl *propList, int propertyID, int index, int *resultSize, unsigned char **resultValue); VixError VixPropertyList_SetBlob(struct VixPropertyListImpl *propList, int propertyID, int blobSize, const unsigned char *value); VixError VixPropertyList_RemoveAll(VixHandle propertyListHandle); VixError VixPropertyList_Remove(VixHandle propertyListHandle, int propertyID); VixError VixPropertyList_RemoveFromImpl(VixPropertyListImpl *propList, int propertyID); VixError VixPropertyList_AppendProperties(VixHandle handle, int firstPropertyID, ...); VixError VixPropertyList_FindProperty(VixPropertyListImpl *propList, int propertyID, VixPropertyType type, int index, Bool createIfMissing, VixPropertyValue **resultEntry); Bool VixPropertyList_PropertyExists(VixPropertyListImpl *propList, int propertyID, VixPropertyType type); VixError VixPropertyListAppendProperty(VixPropertyListImpl *propList, int propertyID, VixPropertyType type, VixPropertyValue **resultEntry); int VixPropertyList_GetNumProperties(VixHandle propertyListHandle, int propertyID); VixError VixPropertyList_GetOptionalProperties(VixHandle propertyListHandle, int firstPropertyID, ...); VixError VixPropertyList_GetIndexedProperties(VixHandle propertyListHandle, Bool ignoreMissingProperties, int firstPropertyID, int firstPropertyIndex, ...); VixError VixPropertyList_GetPtr(VixPropertyListImpl *propList, int propertyID, int index, void **resultValue); VixError VixPropertyList_SetPtr(VixPropertyListImpl *propList, int propertyID, void *value); int VixPropertyList_NumItems(VixPropertyListImpl *propList); Bool VixPropertyList_Empty(VixPropertyListImpl *propList); #endif // VIX_HIDE_FROM_JAVA /* *----------------------------------------------------------------------------- * * VixVM -- * * This describes the persistent configuration state of a single VM. The * VM may or may not be running. * *----------------------------------------------------------------------------- */ #define VIX_FOREIGN_VM_TOOLS_VMX_VERSION_STRING "Foreign VM Tools" /* * These are the types of variable strings we can read in the VM. */ enum { //VIX_VM_GUEST_VARIABLE = 1, //VIX_VM_CONFIG_RUNTIME_ONLY = 2, //VIX_GUEST_ENVIRONMENT_VARIABLE = 3, VIX_GUEST_CONFIG = 4, VIX_VMDB_VARIABLE = 5, }; /* * Options for RunProgramInGuest(). */ enum { //VIX_RUNPROGRAM_RETURN_IMMEDIATELY = 0x0001, //VIX_RUNPROGRAM_ACTIVATE_WINDOW = 0x0002, /* DEPRECATED VIX_RUNPROGRAM_USE_INTERACTIVE_SESSION = 0x0004, */ VIX_RUNPROGRAM_RUN_AS_LOCAL_SYSTEM = 0x0008, }; /* * Options for VixVM_ListFileSystemsInGuest() */ enum { VIX_FILESYSTEMS_SHOW_ALL = 0x000, }; /* * These are the property flags for each file. This is a superset * of the values defined in the public header. */ enum { //VIX_FILE_ATTRIBUTES_DIRECTORY = 0x0001, //VIX_FILE_ATTRIBUTES_SYMLINK = 0x0002, VIX_FILE_ATTRIBUTES_HIDDEN = 0x0004, VIX_FILE_ATTRIBUTES_READONLY = 0x0008, }; /* * These are the propery flags for SetGuestFileAttributes request. */ enum { VIX_FILE_ATTRIBUTE_SET_ACCESS_DATE = 0x0001, VIX_FILE_ATTRIBUTE_SET_MODIFY_DATE = 0x0002, VIX_FILE_ATTRIBUTE_SET_READONLY = 0x0004, VIX_FILE_ATTRIBUTE_SET_HIDDEN = 0x0008, VIX_FILE_ATTRIBUTE_SET_UNIX_OWNERID = 0x0010, VIX_FILE_ATTRIBUTE_SET_UNIX_GROUPID = 0x0020, VIX_FILE_ATTRIBUTE_SET_UNIX_PERMISSIONS = 0x0040, }; /* * Subject types for Alias management. */ typedef enum VixGuestAuthSubjectType { VIX_GUEST_AUTH_SUBJECT_TYPE_NONE = 0, VIX_GUEST_AUTH_SUBJECT_TYPE_NAMED = 1, VIX_GUEST_AUTH_SUBJECT_TYPE_ANY = 2, } VixGuestAuthSubjectType; /* * Types for Windows Registry Management. */ /* * In a 64 bit Windows OS, the registry has two views: 32 bit and 64 bit. * Normally using "registry redirection", 32 bit applications automatically * access the 32 bit view, while 64 bit applications access 64 bit view. * However, applications can pass a flag to specifically access either 32 * or 64 bit registry view, irrespective of their own bitness. * * NOTE: 32 bit windows will ignore these flags if passed. * * Based on the above, and on the fact that in our case 32 bit tools run only * on 32 bit windows and 64 bit tools run only on 64 bit windows, we get the * following registry view access matrix: * Application wowNative wow32 wow64 * ----------- -------- ----- ----- * 32 bit tools 32 bit view 32 bit view 32 bit view * 64 bit tools 64 bit view 32 bit view 64 bit view * So in essence, we always access 32 bit view UNLESS its 64 bit tools and user * has specified either wowNative or wow64 as the registry access flag. */ typedef enum VixRegKeyWowBitness { VIX_REGISTRY_KEY_WOW_NATIVE = 0, VIX_REGISTRY_KEY_WOW_32 = 1, VIX_REGISTRY_KEY_WOW_64 = 2, } VixRegKeyWowBitness; typedef enum VixRegValueDataType { VIX_REGISTRY_VALUE_DWORD = 0, VIX_REGISTRY_VALUE_QWORD = 1, VIX_REGISTRY_VALUE_STRING = 2, VIX_REGISTRY_VALUE_EXPAND_STRING = 3, VIX_REGISTRY_VALUE_MULTI_STRING = 4, VIX_REGISTRY_VALUE_BINARY = 5, } VixRegValueDataType; /* *----------------------------------------------------------------------------- * * VixDebug -- * * Vix debug macros, to allow conditional printf debugging with file/line * information. * * Use as: * * VIX_DEBUG(("test debug message: %s %d\n", stringArg, intArg)); * * Output will go to logfile if VIX_DEBUG_PREFERENCE_NAME is non-zero * * VIX_DEBUG_LEVEL(3, ("test debug message: %s %d\n", stringArg, intArg)); * * Output will go to logfile if VIX_DEBUG_PREFERENCE_NAME is >= * the first argument to the macro. * *----------------------------------------------------------------------------- */ #ifndef VIX_HIDE_FROM_JAVA extern int vixDebugGlobalSpewLevel; extern int vixApiTraceGlobalSpewLevel; extern char *VixAllocDebugString(char *fmt, ...) PRINTF_DECL(1,2); extern void VixDebugInit(int debugLevel, int apiTraceLevel, Bool panicOnVixAssert); extern const char *VixDebug_GetFileBaseName(const char *path); extern void VixAssert(const char *cond, const char *file, int lineNum); extern VixError VixLogError(VixError err, const char *function, int line, const char *fileName, unsigned long threadId, const char *fmt, ...) PRINTF_DECL(6, 7); /* * preference name for client and vmx */ #define VIX_DEBUG_PREFERENCE_NAME "vix.debugLevel" #define VIX_ASSERT_PREFERENCE_NAME "vix.doAssert" #define VIX_API_TRACE_PREFERENCE_NAME "vix.apiTraceLevel" /* * Assertions. Normally we'd just use ASSERT(), but we've hit many cases * where ASSERT() is desired by foundry developers, but not by foundry users. * So we have our own VIX_ASSERT(), which is configured via a preference, * vix.doAssert, off by default. */ #ifdef VMX86_DEBUG # ifdef __cplusplus # define VIX_ASSERT(cond) (UNLIKELY(!(cond)) ? VixAssert(#cond, __FILE__, __LINE__) : (void) 0) # else # define VIX_ASSERT(cond) (UNLIKELY(!(cond)) ? VixAssert(#cond, __FILE__, __LINE__) : 0) # endif #else #define VIX_ASSERT(cond) #endif #define DEFAULT_VIX_LOG_LEVEL 0 #define DEFAULT_VIX_API_TRACE_LEVEL 0 #define VIX_DEBUG_LEVEL(logLevel, s) if (logLevel <= vixDebugGlobalSpewLevel) \ { char *debugString = VixAllocDebugString s; \ Log("Vix: [%lu %s:%d]: %s", (unsigned long)Util_GetCurrentThreadId(), \ VixDebug_GetFileBaseName(__FILE__), __LINE__, debugString); \ free(debugString); } #define VIX_DEBUG(s) if (0 != vixDebugGlobalSpewLevel) \ { char *debugString = VixAllocDebugString s; \ Log("Vix: [%lu %s:%d]: %s", (unsigned long)Util_GetCurrentThreadId(), \ VixDebug_GetFileBaseName(__FILE__), __LINE__, debugString); \ free(debugString); } #define VIX_DEBUG_ALWAYS(s) { char *debugString = VixAllocDebugString s; \ Log("Vix: [%lu %s:%d]: %s", (unsigned long) Util_GetCurrentThreadId(), \ VixDebug_GetFileBaseName(__FILE__), __LINE__, debugString); \ free(debugString); } #define VIX_API_TRACE_ON() (vixApiTraceGlobalSpewLevel > 0) #define VIX_API_LOG(s) if (VIX_API_TRACE_ON()) \ { char *debugString = VixAllocDebugString s; \ Log("VixApiLog: %lu %s %s\n", (unsigned long) Util_GetCurrentThreadId(),\ __FUNCTION__, debugString); \ free(debugString); } // If no MSG is given, a description of err is suplemented. #define VIX_ERROR(err) (VIX_ERROR_MSG(err, NULL)) #define VIX_ERROR_MSG(err, ...) (VixLogError(err, __FUNCTION__, __LINE__, \ VixDebug_GetFileBaseName(__FILE__), \ (unsigned long)Util_GetCurrentThreadId(), __VA_ARGS__)) #endif // VIX_HIDE_FROM_JAVA #ifdef __cplusplus } // extern "C" { #endif #endif // _VIXOpenSource_h_ open-vm-tools-9.4.0-1280544/lib/include/rpcout.h0000644765153500003110000000526212220061556017322 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * rpcout.h -- * * Remote Procedure Call between VMware and guest applications * C declarations */ #ifndef __RPCOUT_H__ # define __RPCOUT_H__ #include "vm_basic_types.h" #define RPCI_PROTOCOL_NUM 0x49435052 /* 'RPCI' ;-) */ typedef struct RpcOut RpcOut; RpcOut *RpcOut_Construct(void); void RpcOut_Destruct(RpcOut *out); Bool RpcOut_start(RpcOut *out); Bool RpcOut_send(RpcOut *out, char const *request, size_t reqLen, char const **reply, size_t *repLen); Bool RpcOut_stop(RpcOut *out); /* * This is the only method needed to send a message to vmware for * 99% of uses. I'm leaving the others defined here so people know * they can be exported again if the need arises. [greg] */ Bool RpcOut_sendOne(char **reply, size_t *repLen, char const *reqFmt, ...); /* * A new version of the above function that works with UTF-8 strings * and other data that would be corrupted by Win32's FormatMessage * function (which is used by RpcOut_sendOne()). */ Bool RpcOut_SendOneRaw(void *request, size_t reqLen, char **reply, size_t *repLen); /* * As the above but must be run by admin/root to make the privileged RPC call successfully. */ Bool RpcOut_SendOneRawPriv(void *request, size_t reqLen, char **reply, size_t *repLen); #endif /* __RPCOUT_H__ */ open-vm-tools-9.4.0-1280544/lib/include/vmware_pack_end.h0000644765153500003110000000360312220061556021130 0ustar dtormts/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * vmware_pack_end.h -- * * End of structure packing. See vmware_pack_init.h for details. * * Note that we do not use the following construct in this include file, * because we want to emit the code every time the file is included --hpreg * * #ifndef foo * # define foo * ... * #endif * */ #include "vmware_pack_init.h" #ifdef _MSC_VER # pragma pack(pop) #elif __GNUC__ __attribute__((__packed__)) #else # error Compiler packing... #endif open-vm-tools-9.4.0-1280544/lib/include/util.h0000644765153500003110000004036712220061556016770 0ustar dtormts/********************************************************* * Copyright (C) 1998-2012 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * util.h -- * * misc util functions */ #ifndef UTIL_H #define UTIL_H #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #include #include #include #ifdef _WIN32 #ifdef USERLEVEL #include /* Needed for MBCS string functions */ #include /* for definition of HANDLE */ #endif #else #include #include "errno.h" #endif #include "vm_assert.h" #include "unicodeTypes.h" /* * Define the Util_ThreadID type, and assorted standard bits. */ #if defined(_WIN32) typedef DWORD Util_ThreadID; #else #include #if defined(__APPLE__) || defined(__FreeBSD__) #include typedef pthread_t Util_ThreadID; #else // Linux et al typedef pid_t Util_ThreadID; #endif #endif uint32 CRC_Compute(const uint8 *buf, int len); uint32 Util_Checksum32(const uint32 *buf, int len); uint32 Util_Checksum(const uint8 *buf, int len); uint32 Util_Checksumv(void *iov, int numEntries); uint32 Util_HashString(const char *str); Unicode Util_ExpandString(ConstUnicode fileName); void Util_ExitThread(int); NORETURN void Util_ExitProcessAbruptly(int); int Util_HasAdminPriv(void); #if defined _WIN32 && defined USERLEVEL int Util_TokenHasAdminPriv(HANDLE token); int Util_TokenHasInteractPriv(HANDLE token); #endif Bool Util_Data2Buffer(char *buf, size_t bufSize, const void *data0, size_t dataSize); char *Util_GetCanonicalPath(const char *path); #ifdef _WIN32 char *Util_CompatGetCanonicalPath(const char *path); char *Util_GetCanonicalPathForHash(const char *path); char *Util_CompatGetLowerCaseCanonicalPath(const char* path); #endif int Util_BumpNoFds(uint32 *cur, uint32 *wanted); Bool Util_CanonicalPathsIdentical(const char *path1, const char *path2); Bool Util_IsAbsolutePath(const char *path); unsigned Util_GetPrime(unsigned n0); Util_ThreadID Util_GetCurrentThreadId(void); char *Util_DeriveFileName(const char *source, const char *name, const char *ext); char *Util_CombineStrings(char **sources, int count); char **Util_SeparateStrings(char *source, int *count); typedef struct UtilSingleUseResource UtilSingleUseResource; UtilSingleUseResource *Util_SingleUseAcquire(const char *name); void Util_SingleUseRelease(UtilSingleUseResource *res); #if defined(__linux__) || defined(__FreeBSD__) || defined(sun) Bool Util_GetProcessName(pid_t pid, char *bufOut, size_t bufOutSize); #endif // backtrace functions and utilities #define UTIL_BACKTRACE_LINE_LEN (511) typedef void (*Util_OutputFunc)(void *data, const char *fmt, ...); void Util_Backtrace(int bugNr); void Util_BacktraceFromPointer(uintptr_t *basePtr); void Util_BacktraceFromPointerWithFunc(uintptr_t *basePtr, Util_OutputFunc outFunc, void *outFuncData); void Util_BacktraceWithFunc(int bugNr, Util_OutputFunc outFunc, void *outFuncData); void Util_BacktraceToBuffer(uintptr_t *basePtr, uintptr_t *buffer, int len); // sleep functions void Util_Usleep(long usec); void Util_Sleep(unsigned int sec); int Util_CompareDotted(const char *s1, const char *s2); /* * This enum defines how Util_GetOpt should handle non-option arguments: * * UTIL_NONOPT_PERMUTE: Permute argv so that all non-options are at the end. * UTIL_NONOPT_STOP: Stop when first non-option argument is seen. * UTIL_NONOPT_ALL: Return each non-option argument as if it were * an option with character code 1. */ typedef enum { UTIL_NONOPT_PERMUTE, UTIL_NONOPT_STOP, UTIL_NONOPT_ALL } Util_NonOptMode; struct option; int Util_GetOpt(int argc, char * const *argv, const struct option *opts, Util_NonOptMode mode); #if defined(VMX86_STATS) Bool Util_QueryCStResidency(uint32 *numCpus, uint32 *numCStates, uint64 **transitns, uint64 **residency, uint64 **transTime, uint64 **residTime); #endif /* * In util_shared.h */ Bool Util_Throttle(uint32 count); uint32 Util_FastRand(uint32 seed); // Not thread safe! void Util_OverrideHomeDir(const char *path); /* *----------------------------------------------------------------------------- * * Util_ValidateBytes -- * * Check that memory is filled with the specified value. * * Results: * NULL No error * !NULL First address that doesn't have the proper value * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE void * Util_ValidateBytes(const void *ptr, // IN: ptr to check size_t size, // IN: size of ptr uint8 byteValue) // IN: memory must be filled with this { uint8 *p; uint8 *end; uint64 bigValue; ASSERT(ptr); if (size == 0) { return NULL; } p = (uint8 *) ptr; end = p + size; /* Compare bytes until a "nice" boundary is achieved. */ while ((uintptr_t) p % sizeof bigValue) { if (*p != byteValue) { return p; } p++; if (p == end) { return NULL; } } /* Compare using a "nice sized" chunk for a long as possible. */ memset(&bigValue, (int) byteValue, sizeof bigValue); while (p + sizeof bigValue <= end) { if (*((uint64 *) p) != bigValue) { /* That's not right... let the loop below report the exact address. */ break; } size -= sizeof bigValue; p += sizeof bigValue; } /* Handle any trailing bytes. */ while (p < end) { if (*p != byteValue) { return p; } p++; } return NULL; } /* *---------------------------------------------------------------------- * * Util_BufferIsEmpty -- * * Determine if the specified buffer of 'len' bytes starting at 'base' * is empty (i.e. full of zeroes). * * Results: * TRUE Yes * FALSE No * * Side effects: * None * *---------------------------------------------------------------------- */ static INLINE Bool Util_BufferIsEmpty(void const *base, // IN: size_t len) // IN: { return Util_ValidateBytes(base, len, '\0') == NULL; } Bool Util_MakeSureDirExistsAndAccessible(char const *path, unsigned int mode); #if _WIN32 # define DIRSEPS "\\" # define DIRSEPS_W L"\\" # define DIRSEPC '\\' # define DIRSEPC_W L'\\' # define VALID_DIRSEPS "\\/" # define VALID_DIRSEPS_W L"\\/" #else # define DIRSEPS "/" # define DIRSEPC '/' # define VALID_DIRSEPS DIRSEPS #endif /* *----------------------------------------------------------------------- * * Util_Safe[Malloc, Realloc, Calloc, Strdup] and * Util_Safe[Malloc, Realloc, Calloc, Strdup]Bug -- * * These functions work just like the standard C library functions * (except Util_SafeStrdup[,Bug]() accept NULL, see below), * but will not fail. Instead they Panic(), printing the file and * line number of the caller, if the underlying library function * fails. The Util_SafeFnBug functions print bugNumber in the * Panic() message. * * These functions should only be used when there is no way to * gracefully recover from the error condition. * * The internal versions of these functions expect a bug number * as the first argument. If that bug number is something other * than -1, the panic message will include the bug number. * * Since Util_SafeStrdup[,Bug]() do not need to return NULL * on error, they have been extended to accept the null pointer * (and return it). The competing view is that they should * panic on NULL. This is a convenience vs. strictness argument. * Convenience wins. -- edward * * Results: * The freshly allocated memory. * * Side effects: * Panic() if the library function fails. * *-------------------------------------------------------------------------- */ void *UtilSafeMalloc0(size_t size); void *UtilSafeMalloc1(size_t size, int bugNumber, const char *file, int lineno); void *UtilSafeRealloc0(void *ptr, size_t size); void *UtilSafeRealloc1(void *ptr, size_t size, int bugNumber, const char *file, int lineno); void *UtilSafeCalloc0(size_t nmemb, size_t size); void *UtilSafeCalloc1(size_t nmemb, size_t size, int bugNumber, const char *file, int lineno); char *UtilSafeStrdup0(const char *s); char *UtilSafeStrdup1(const char *s, int bugNumber, const char *file, int lineno); char *UtilSafeStrndup0(const char *s, size_t n); char *UtilSafeStrndup1(const char *s, size_t n, int bugNumber, const char *file, int lineno); /* * Debug builds carry extra arguments into the allocation functions for * better error reporting. Non-debug builds don't pay this extra overhead. */ #ifdef VMX86_DEBUG #define Util_SafeMalloc(_size) \ UtilSafeMalloc1((_size), -1, __FILE__, __LINE__) #define Util_SafeMallocBug(_bugNr, _size) \ UtilSafeMalloc1((_size),(_bugNr), __FILE__, __LINE__) #define Util_SafeRealloc(_ptr, _size) \ UtilSafeRealloc1((_ptr), (_size), -1, __FILE__, __LINE__) #define Util_SafeReallocBug(_bugNr, _ptr, _size) \ UtilSafeRealloc1((_ptr), (_size), (_bugNr), __FILE__, __LINE__) #define Util_SafeCalloc(_nmemb, _size) \ UtilSafeCalloc1((_nmemb), (_size), -1, __FILE__, __LINE__) #define Util_SafeCallocBug(_bugNr, _nmemb, _size) \ UtilSafeCalloc1((_nmemb), (_size), (_bugNr), __FILE__, __LINE__) #define Util_SafeStrndup(_str, _size) \ UtilSafeStrndup1((_str), (_size), -1, __FILE__, __LINE__) #define Util_SafeStrndupBug(_bugNr, _str, _size) \ UtilSafeStrndup1((_str), (_size), (_bugNr), __FILE__, __LINE__) #define Util_SafeStrdup(_str) \ UtilSafeStrdup1((_str), -1, __FILE__, __LINE__) #define Util_SafeStrdupBug(_bugNr, _str) \ UtilSafeStrdup1((_str), (_bugNr), __FILE__, __LINE__) #else /* VMX86_DEBUG */ #define Util_SafeMalloc(_size) \ UtilSafeMalloc0((_size)) #define Util_SafeMallocBug(_bugNr, _size) \ UtilSafeMalloc0((_size)) #define Util_SafeRealloc(_ptr, _size) \ UtilSafeRealloc0((_ptr), (_size)) #define Util_SafeReallocBug(_ptr, _size) \ UtilSafeRealloc0((_ptr), (_size)) #define Util_SafeCalloc(_nmemb, _size) \ UtilSafeCalloc0((_nmemb), (_size)) #define Util_SafeCallocBug(_bugNr, _nmemb, _size) \ UtilSafeCalloc0((_nmemb), (_size)) #define Util_SafeStrndup(_str, _size) \ UtilSafeStrndup0((_str), (_size)) #define Util_SafeStrndupBug(_bugNr, _str, _size) \ UtilSafeStrndup0((_str), (_size)) #define Util_SafeStrdup(_str) \ UtilSafeStrdup0((_str)) #define Util_SafeStrdupBug(_bugNr, _str) \ UtilSafeStrdup0((_str)) #endif /* VMX86_DEBUG */ void *Util_Memcpy(void *dest, const void *src, size_t count); /* *----------------------------------------------------------------------------- * * Util_Zero -- * * Zeros out bufSize bytes of buf. NULL is legal. * * Results: * None. * * Side effects: * See above. * *----------------------------------------------------------------------------- */ static INLINE void Util_Zero(void *buf, // OUT size_t bufSize) // IN { if (buf != NULL) { #if defined _WIN32 && defined USERLEVEL /* * Simple memset calls might be optimized out. See CERT advisory * MSC06-C. */ SecureZeroMemory(buf, bufSize); #else memset(buf, 0, bufSize); #endif } } /* *----------------------------------------------------------------------------- * * Util_ZeroString -- * * Zeros out a NULL-terminated string. NULL is legal. * * Results: * None. * * Side effects: * See above. * *----------------------------------------------------------------------------- */ static INLINE void Util_ZeroString(char *str) // IN/OUT { if (str != NULL) { Util_Zero(str, strlen(str)); } } /* *----------------------------------------------------------------------------- * * Util_ZeroFree -- * * Zeros out bufSize bytes of buf, and then frees it. NULL is * legal. * * Results: * None. * * Side effects: * buf is zeroed, and then free() is called on it. * *----------------------------------------------------------------------------- */ static INLINE void Util_ZeroFree(void *buf, // OUT size_t bufSize) // IN { if (buf != NULL) { Util_Zero(buf, bufSize); free(buf); } } /* *----------------------------------------------------------------------------- * * Util_ZeroFreeString -- * * Zeros out a NULL-terminated string, and then frees it. NULL is * legal. * * Results: * None. * * Side effects: * str is zeroed, and then free() is called on it. * *----------------------------------------------------------------------------- */ static INLINE void Util_ZeroFreeString(char *str) // IN { if (str != NULL) { Util_ZeroString(str); free(str); } } #ifdef _WIN32 /* *----------------------------------------------------------------------------- * * Util_ZeroFreeStringW -- * * Zeros out a NUL-terminated wide-character string, and then frees it. * NULL is legal. * * Results: * None. * * Side effects: * str is zeroed, and then free() is called on it. * *----------------------------------------------------------------------------- */ static INLINE void Util_ZeroFreeStringW(wchar_t *str) // IN { if (str != NULL) { Util_Zero(str, wcslen(str) * sizeof *str); free(str); } } #endif // _WIN32 /* *----------------------------------------------------------------------------- * * Util_FreeList -- * Util_FreeStringList -- * * Free a list (actually a vector) of allocated objects. * The list (vector) itself is also freed. * * The list either has a specified length or is * argv-style NULL terminated (if length is negative). * * The list can be NULL, in which case no operation is performed. * * Results: * None * * Side effects: * errno or Windows last error is preserved. * *----------------------------------------------------------------------------- */ static INLINE void Util_FreeList(void **list, // IN/OUT: the list to free ssize_t length) // IN: the length { if (list == NULL) { ASSERT(length <= 0); return; } if (length >= 0) { ssize_t i; for (i = 0; i < length; i++) { free(list[i]); DEBUG_ONLY(list[i] = NULL); } } else { void **s; for (s = list; *s != NULL; s++) { free(*s); DEBUG_ONLY(*s = NULL); } } free(list); } static INLINE void Util_FreeStringList(char **list, // IN/OUT: the list to free ssize_t length) // IN: the length { Util_FreeList((void **) list, length); } #ifndef _WIN32 /* *----------------------------------------------------------------------------- * * Util_IsFileDescriptorOpen -- * * Check if given file descriptor is open. * * Results: * TRUE if fd is open. * * Side effects: * Clobbers errno. * *----------------------------------------------------------------------------- */ static INLINE Bool Util_IsFileDescriptorOpen(int fd) // IN { lseek(fd, 0L, SEEK_CUR); return errno != EBADF; } #endif /* !_WIN32 */ #endif /* UTIL_H */ open-vm-tools-9.4.0-1280544/lib/include/unicodeOperations.h0000644765153500003110000005312312220061556021477 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * unicodeOperations.h -- * * Basic Unicode string operations. * * UnicodeIndex index and length arguments are in terms of code * units, not characters. The size of a code unit depends on the * implementation (one byte for UTF-8, one 16-bit word for * UTF-16). Do not store these values on disk, modify them, or * do arithmetic operations on them. * * Instead of iterating over the code units in a string to do * character operations, use the library functions provided to * search and transform strings. * * If the functionality you need is not present, email the * i18n-dev mailing list. */ #ifndef _UNICODE_OPERATIONS_H_ #define _UNICODE_OPERATIONS_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include #include "unicodeBase.h" #include "vm_assert.h" #ifdef __cplusplus extern "C" { #endif /* * Primitive operations. All other Unicode operations are implemented * in terms of these. * * Pass -1 for any length parameter to indicate "from start until end * of string". */ int Unicode_CompareRange(ConstUnicode str1, UnicodeIndex str1Start, UnicodeIndex str1Length, ConstUnicode str2, UnicodeIndex str2Start, UnicodeIndex str2Length, Bool ignoreCase); UnicodeIndex Unicode_FindSubstrInRange(ConstUnicode str, UnicodeIndex strStart, UnicodeIndex strLength, ConstUnicode strToFind, UnicodeIndex strToFindStart, UnicodeIndex strToFindLength); UnicodeIndex Unicode_FindLastSubstrInRange(ConstUnicode str, UnicodeIndex strStart, UnicodeIndex strLength, ConstUnicode strToFind, UnicodeIndex strToFindStart, UnicodeIndex strToFindLength); Unicode Unicode_Substr(ConstUnicode str, UnicodeIndex start, UnicodeIndex length); Unicode Unicode_ReplaceRange(ConstUnicode destination, UnicodeIndex destinationStart, UnicodeIndex destinationLength, ConstUnicode source, UnicodeIndex sourceStart, UnicodeIndex sourceLength); Unicode Unicode_Join(ConstUnicode first, ...); Unicode Unicode_Format(const char *fmt, ...); UnicodeIndex Unicode_LengthInCodePoints(ConstUnicode str); /* * Simple in-line functions that may be used below. */ /* *----------------------------------------------------------------------------- * * Unicode_IsIndexAtCodePointBoundary -- * * Check a string index (in bytes) for code point boundary. * * The index must be valid (>= 0 and <= string length). * The end of the string is considered a valid boundary. * * Results: * TRUE if index is at a code point boundary. * * Side effects: * Panic if index is not valid. * *----------------------------------------------------------------------------- */ static INLINE Bool Unicode_IsIndexAtCodePointBoundary(ConstUnicode str, // IN: UnicodeIndex index) // IN: { ASSERT(index >= 0 && index <= Unicode_LengthInCodeUnits(str)); #ifdef SUPPORT_UNICODE_OPAQUE NOT_IMPLEMENTED(); #else return (str[index] & 0xc0) != 0x80; #endif } /* * Other operations, each based upon calls to primitives. */ /* *----------------------------------------------------------------------------- * * Unicode_Append -- * * Allocates and returns a new string containing 'destination' * followed by 'source'. * * Results: * The newly-allocated string. Caller must free with Unicode_Free. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE Unicode Unicode_Append(ConstUnicode destination, // IN ConstUnicode source) // IN { return Unicode_ReplaceRange(destination, -1, 0, source, 0, -1); } /* *----------------------------------------------------------------------------- * * Unicode_AppendRange -- * * Allocates and returns a new string containing 'destination' * followed by the specified range of 'source'. * * Results: * The newly-allocated string. Caller must free with Unicode_Free. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE Unicode Unicode_AppendRange(ConstUnicode dest, // IN: ConstUnicode src, // IN: UnicodeIndex srcStart, // IN: UnicodeIndex srcLength) // IN: { return Unicode_ReplaceRange(dest, Unicode_LengthInCodePoints(dest), 0, src, srcStart, srcLength); } /* *----------------------------------------------------------------------------- * * Unicode_Compare -- * * Compares two Unicode strings for canonical equivalence in code * point order. * * If the result is to be visible in a user interface, use * Unicode_CompareWithLocale to support language and * culture-specific comparison and sorting rules. * * Results: * -1 if str1 < str2, 0 if str1 == str2, 1 if str1 > str2. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE int Unicode_Compare(ConstUnicode str1, // IN ConstUnicode str2) // IN { return Unicode_CompareRange(str1, 0, -1, str2, 0, -1, FALSE); } /* *----------------------------------------------------------------------------- * * Unicode_CompareIgnoreCase -- * * Compares two Unicode strings for case-insensitive canonical * equivalence in code point order. * * If the result is to be visible in a user interface, use * Unicode_CompareWithLocale to support language and * culture-specific comparison and sorting rules. * * Results: * -1 if str1 < str2, 0 if str1 == str2, 1 if str1 > str2. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE int Unicode_CompareIgnoreCase(ConstUnicode str1, // IN ConstUnicode str2) // IN { return Unicode_CompareRange(str1, 0, -1, str2, 0, -1, TRUE); } /* *----------------------------------------------------------------------------- * * UnicodeEndsWith -- * Unicode_EndsWith -- * Unicode_EndsWithIgnoreCase -- * * Tests if 'str' ends with 'suffix'. * * Results: * TRUE if 'str' ends with 'suffix', FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE Bool UnicodeEndsWith(ConstUnicode str, // IN: ConstUnicode suffix, // IN: Bool ignoreCase) // IN: { UnicodeIndex strLength = Unicode_LengthInCodePoints(str); UnicodeIndex suffixLength = Unicode_LengthInCodePoints(suffix); UnicodeIndex offset = strLength - suffixLength; if (suffixLength > strLength) { return FALSE; } return Unicode_CompareRange(str, offset, suffixLength, suffix, 0, suffixLength, ignoreCase) == 0; } static INLINE Bool Unicode_EndsWith(ConstUnicode str, // IN ConstUnicode suffix) // IN { return UnicodeEndsWith(str, suffix, FALSE); } static INLINE Bool Unicode_EndsWithIgnoreCase(ConstUnicode str, // IN ConstUnicode suffix) // IN { return UnicodeEndsWith(str, suffix, TRUE); } /* *----------------------------------------------------------------------------- * * Unicode_Find -- * * Finds the first occurrence of 'strToFind' inside 'str'. * * Results: * If 'strToFind' exists inside 'str', returns the first starting * index of 'strToFind' in that range. * * Otherwise, returns UNICODE_INDEX_NOT_FOUND. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE UnicodeIndex Unicode_Find(ConstUnicode str, // IN ConstUnicode strToFind) // IN { return Unicode_FindSubstrInRange(str, 0, -1, strToFind, 0, -1); } /* *----------------------------------------------------------------------------- * * Unicode_FindFromIndex -- * * Finds the first occurrence of 'strToFind' inside 'str' in the range * [fromIndex, lengthOfStr). * * Results: * If 'strToFind' exists inside 'str' in the specified range, * returns the first starting index of 'strToFind' in that range. * * Otherwise, returns UNICODE_INDEX_NOT_FOUND. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE UnicodeIndex Unicode_FindFromIndex(ConstUnicode str, // IN ConstUnicode strToFind, // IN UnicodeIndex fromIndex) // IN { return Unicode_FindSubstrInRange(str, fromIndex, -1, strToFind, 0, -1); } /* *----------------------------------------------------------------------------- * * Unicode_FindInRange -- * * Finds the first occurrence of 'strToFind' inside 'str' in the range * [start, start+length). * * Results: * If 'strToFind' exists inside 'str' in the specified range, * returns the first starting index of 'strToFind' in that range. * * Otherwise, returns UNICODE_INDEX_NOT_FOUND. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE UnicodeIndex Unicode_FindInRange(ConstUnicode str, // IN ConstUnicode strToFind, // IN UnicodeIndex start, // IN UnicodeIndex length) // IN { return Unicode_FindSubstrInRange(str, start, length, strToFind, 0, -1); } /* *----------------------------------------------------------------------------- * * Unicode_FindLast -- * * Finds the last occurrence of 'strToFind' inside 'str'. * * Results: * If 'strToFind' exists inside 'str', returns the last starting * index of 'strToFind' in that range. * * Otherwise, returns UNICODE_INDEX_NOT_FOUND. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE UnicodeIndex Unicode_FindLast(ConstUnicode str, // IN ConstUnicode strToFind) // IN { return Unicode_FindLastSubstrInRange(str, 0, -1, strToFind, 0, -1); } /* *----------------------------------------------------------------------------- * * Unicode_FindLastFromIndex -- * * Finds the last occurrence of 'strToFind' inside 'str' in the range * [fromIndex, lengthOfStr). * * Results: * If 'strToFind' exists inside 'str' in the specified range, * returns the last starting index of 'strToFind' in that range. * * Otherwise, returns UNICODE_INDEX_NOT_FOUND. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE UnicodeIndex Unicode_FindLastFromIndex(ConstUnicode str, // IN ConstUnicode strToFind, // IN UnicodeIndex fromIndex) // IN { return Unicode_FindLastSubstrInRange(str, fromIndex, -1, strToFind, 0, -1); } /* *----------------------------------------------------------------------------- * * Unicode_FindLastInRange -- * * Finds the last occurrence of 'strToFind' inside 'str' in the range * [start, start+length). * * Results: * If 'strToFind' exists inside 'str' in the specified range, * returns the last starting index of 'strToFind' in that range. * * Otherwise, returns UNICODE_INDEX_NOT_FOUND. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE UnicodeIndex Unicode_FindLastInRange(ConstUnicode str, // IN ConstUnicode strToFind, // IN UnicodeIndex start, // IN UnicodeIndex length) // IN { return Unicode_FindLastSubstrInRange(str, start, length, strToFind, 0, -1); } /* *----------------------------------------------------------------------------- * * Unicode_Insert -- * * Allocates and returns a new copy of 'destination', with the * string 'source' inserted at the index 'destinationStart'. * * Results: * The newly-allocated string. Caller must free with Unicode_Free. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE Unicode Unicode_Insert(ConstUnicode destination, // IN UnicodeIndex destinationStart, // IN ConstUnicode source) // IN { return Unicode_ReplaceRange(destination, destinationStart, 0, source, 0, -1); } /* *----------------------------------------------------------------------------- * * Unicode_InsertRange -- * * Allocates and returns a new copy of 'destination', with the * specified range of the string 'source' inserted at the index * 'destinationStart'. * * Results: * The newly-allocated string. Caller must free with Unicode_Free. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE Unicode Unicode_InsertRange(ConstUnicode destination, UnicodeIndex destinationStart, ConstUnicode source, UnicodeIndex sourceStart, UnicodeIndex sourceLength) { return Unicode_ReplaceRange(destination, destinationStart, 0, source, sourceStart, sourceLength); } /* *----------------------------------------------------------------------------- * * Unicode_IsEqual -- * * Tests two strings for canonical equivalence. * * Results: * TRUE if the two strings are canonically equivalent, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE Bool Unicode_IsEqual(ConstUnicode str1, // IN ConstUnicode str2) // IN { return Unicode_CompareRange(str1, 0, -1, str2, 0, -1, FALSE) == 0; } /* *----------------------------------------------------------------------------- * * Unicode_RemoveRange -- * * Allocates and returns a new string that contains a copy of * 'destination' with the code units in the range [start, start + length) * removed. * * Results: * The newly-allocated string. Caller must free with Unicode_Free. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE Unicode Unicode_RemoveRange(ConstUnicode destination, UnicodeIndex start, UnicodeIndex length) { return Unicode_ReplaceRange(destination, start, length, "", 0, 0); } /* *----------------------------------------------------------------------------- * * Unicode_Replace -- * * Allocates and returns a new string that contains a copy of * 'destination' with the code units in the range * [destinationStart, destinarionStart + destinationLength) replaced * with 'source'. * * Results: * The newly-allocated string. Caller must free with Unicode_Free. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE Unicode Unicode_Replace(ConstUnicode destination, UnicodeIndex destinationStart, UnicodeIndex destinationLength, ConstUnicode source) { return Unicode_ReplaceRange(destination, destinationStart, destinationLength, source, 0, -1); } /* *----------------------------------------------------------------------------- * * UnicodeStartsWith -- * Unicode_StartsWith -- * Unicode_StartsWithIgnoreCase -- * * Tests if 'str' starts with 'prefix'. * * Results: * TRUE if 'str' starts with 'prefix', FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE Bool UnicodeStartsWith(ConstUnicode str, // IN: ConstUnicode prefix, // IN: Bool ignoreCase) // IN: { UnicodeIndex strLength = Unicode_LengthInCodePoints(str); UnicodeIndex prefixLength = Unicode_LengthInCodePoints(prefix); if (prefixLength > strLength) { return FALSE; } return Unicode_CompareRange(str, 0, prefixLength, prefix, 0, prefixLength, ignoreCase) == 0; } static INLINE Bool Unicode_StartsWith(ConstUnicode str, // IN ConstUnicode prefix) // IN { return UnicodeStartsWith(str, prefix, FALSE); } static INLINE Bool Unicode_StartsWithIgnoreCase(ConstUnicode str, // IN ConstUnicode prefix) // IN { return UnicodeStartsWith(str, prefix, TRUE); } /* *----------------------------------------------------------------------------- * * Unicode_Truncate -- * * Allocates and returns a new copy of 'str' truncated to the * specified length in code units. * * Results: * The newly-allocated truncated copy of 'str'. Caller must free * with Unicode_Free. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE Unicode Unicode_Truncate(ConstUnicode str, // IN UnicodeIndex length) // IN { return Unicode_Substr(str, 0, length); } #ifdef __cplusplus } #endif #endif // _UNICODE_OPERATIONS_H_ open-vm-tools-9.4.0-1280544/lib/include/iovector.h0000644765153500003110000001043012220061556017631 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * iovector.h -- * * iov management code API. */ #ifndef _IOVECTOR_H_ #define _IOVECTOR_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" /* * Ugly definition of struct iovec. */ #if defined(__linux__) || defined(sun) || defined(__APPLE__) || defined(__FreeBSD__) #include // for struct iovec #else #ifndef HAS_IOVEC struct iovec { void *iov_base; /* Starting address. */ size_t iov_len; /* Length in bytes. */ }; #endif // HAS_IOVEC #endif /* * An I/O Vector. */ typedef struct VMIOVec { SectorType startSector; SectorType numSectors; uint64 numBytes; /* Total bytes from all of the entries */ uint32 numEntries; /* Total number of entries */ Bool read; /* is it a readv operation? else it's write */ struct iovec *entries; /* Array of entries (dynamically allocated) */ struct iovec *allocEntries; /* The original array that can be passed to free(). * NULL if entries is on a stack. */ } VMIOVec; #define LAZY_ALLOC_MAGIC ((void*)0xF0F0) VMIOVec* IOV_Split(VMIOVec *regionV, SectorType numSectors, uint32 sectorSize); void IOV_Log(const VMIOVec *iov); void IOV_Zero(VMIOVec *iov); Bool IOV_IsZero(VMIOVec* iov); VMIOVec* IOV_Duplicate(VMIOVec* iovIn); VMIOVec* IOV_Allocate(int numEntries); void IOV_Free(VMIOVec* iov); void IOV_DuplicateStatic(VMIOVec *iovIn, int numStaticEntries, struct iovec *staticEntries, VMIOVec *iovOut); void IOV_MakeSingleIOV(VMIOVec* v, struct iovec* iov, SectorType startSector, SectorType dataLen, uint32 sectorSize, uint8* buffer, Bool read); void IOV_WriteIovToBuf(struct iovec* entries, int numEntries, uint8* bufOut, size_t bufSize); void IOV_WriteBufToIov(const uint8* bufIn, size_t bufSize, struct iovec* entries, int numEntries); size_t IOV_WriteIovToBufPlus(struct iovec* entries, int numEntries, uint8* bufOut, size_t bufSize, size_t iovOffset); size_t IOV_WriteBufToIovPlus(uint8* bufIn, size_t bufSize, struct iovec* entries, int numEntries, size_t iovOffset); size_t IOV_WriteIovToIov(VMIOVec *srcIov, VMIOVec *dstIov, uint32 sectorSizeShift); /* *----------------------------------------------------------------------------- * * IOV_ASSERT, IOV_Assert -- * * Checks that the 'numEntries' iovecs in 'iov' are non-null and have * nonzero lengths. * * Results: * None. * * Side effects: * Assert-fails if the iovec is invalid. * *----------------------------------------------------------------------------- */ #if VMX86_DEBUG #define IOV_ASSERT(IOVEC, NUM_ENTRIES) IOV_Assert(IOVEC, NUM_ENTRIES) void IOV_Assert(struct iovec *iov, // IN: iovector uint32 numEntries); // IN: # of entries in 'iov' #else #define IOV_ASSERT(IOVEC, NUM_ENTRIES) ((void) 0) #endif #endif /* #ifndef _IOVECTOR_H_ */ open-vm-tools-9.4.0-1280544/lib/include/vm_basic_asm_x86.h0000644765153500003110000004543412220061556021143 0ustar dtormts/********************************************************* * Copyright (C) 1998-2003 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * vm_basic_asm_x86.h * * Basic IA32 asm macros */ #ifndef _VM_BASIC_ASM_X86_H_ #define _VM_BASIC_ASM_X86_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_DISTRIBUTE #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMIROM #include "includeCheck.h" #ifdef VM_X86_64 /* * The gcc inline asm uses the "A" constraint which differs in 32 & 64 * bit mode. 32 bit means eax and edx, 64 means rax or rdx. */ #error "x86-64 not supported" #endif /* * XTEST * Return TRUE if processor is in transaction region. * */ #if defined(__GNUC__) && (defined(VMM) || defined(VMKERNEL) || defined(FROBOS)) static INLINE Bool xtest(void) { uint8 al; __asm__ __volatile__(".byte 0x0f, 0x01, 0xd6 # xtest \n" "setnz %%al\n" : "=a"(al) : : "cc"); return al; } #endif /* __GNUC__ */ /* * FXSAVE/FXRSTOR * save/restore SIMD/MMX fpu state * * The pointer passed in must be 16-byte aligned. * * Intel and AMD processors behave differently w.r.t. fxsave/fxrstor. Intel * processors unconditionally save the exception pointer state (instruction * ptr., data ptr., and error instruction opcode). FXSAVE_ES1 and FXRSTOR_ES1 * work correctly for Intel processors. * * AMD processors only save the exception pointer state if ES=1. This leads to a * security hole whereby one process/VM can inspect the state of another process * VM. The AMD recommended workaround involves clobbering the exception pointer * state unconditionally, and this is implemented in FXRSTOR_AMD_ES0. Note that * FXSAVE_ES1 will only save the exception pointer state for AMD processors if * ES=1. * * The workaround (FXRSTOR_AMD_ES0) only costs 1 cycle more than just doing an * fxrstor, on both AMD Opteron and Intel Core CPUs. */ #if defined(__GNUC__) static INLINE void FXSAVE_ES1(void *save) { __asm__ __volatile__ ("fxsave %0\n" : "=m" (*(uint8 *)save) : : "memory"); } static INLINE void FXRSTOR_ES1(const void *load) { __asm__ __volatile__ ("fxrstor %0\n" : : "m" (*(const uint8 *)load) : "memory"); } static INLINE void FXRSTOR_AMD_ES0(const void *load) { uint64 dummy = 0; __asm__ __volatile__ ("fnstsw %%ax \n" // Grab x87 ES bit "bt $7,%%ax \n" // Test ES bit "jnc 1f \n" // Jump if ES=0 "fnclex \n" // ES=1. Clear it so fild doesn't trap "1: \n" "ffree %%st(7) \n" // Clear tag bit - avoid poss. stack overflow "fildl %0 \n" // Dummy Load from "safe address" changes all // x87 exception pointers. "fxrstor %1 \n" : : "m" (dummy), "m" (*(const uint8 *)load) : "ax", "memory"); } #endif /* __GNUC__ */ /* * XSAVE/XRSTOR * save/restore GSSE/SIMD/MMX fpu state * * The pointer passed in must be 64-byte aligned. * See above comment for more information. */ #if defined(__GNUC__) && (defined(VMM) || defined(VMKERNEL) || defined(FROBOS)) static INLINE void XSAVE_ES1(void *save, uint64 mask) { #if __GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ == 1 __asm__ __volatile__ ( ".byte 0x0f, 0xae, 0x21 \n" : : "c" ((uint8 *)save), "a" ((uint32)mask), "d" ((uint32)(mask >> 32)) : "memory"); #else __asm__ __volatile__ ( "xsave %0 \n" : "=m" (*(uint8 *)save) : "a" ((uint32)mask), "d" ((uint32)(mask >> 32)) : "memory"); #endif } static INLINE void XSAVEOPT_ES1(void *save, uint64 mask) { __asm__ __volatile__ ( ".byte 0x0f, 0xae, 0x31 \n" : : "c" ((uint8 *)save), "a" ((uint32)mask), "d" ((uint32)(mask >> 32)) : "memory"); } static INLINE void XRSTOR_ES1(const void *load, uint64 mask) { #if __GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ == 1 __asm__ __volatile__ ( ".byte 0x0f, 0xae, 0x29 \n" : : "c" ((const uint8 *)load), "a" ((uint32)mask), "d" ((uint32)(mask >> 32)) : "memory"); #else __asm__ __volatile__ ( "xrstor %0 \n" : : "m" (*(const uint8 *)load), "a" ((uint32)mask), "d" ((uint32)(mask >> 32)) : "memory"); #endif } static INLINE void XRSTOR_AMD_ES0(const void *load, uint64 mask) { uint64 dummy = 0; __asm__ __volatile__ ("fnstsw %%ax \n" // Grab x87 ES bit "bt $7,%%ax \n" // Test ES bit "jnc 1f \n" // Jump if ES=0 "fnclex \n" // ES=1. Clear it so fild doesn't trap "1: \n" "ffree %%st(7) \n" // Clear tag bit - avoid poss. stack overflow "fildl %0 \n" // Dummy Load from "safe address" changes all // x87 exception pointers. "mov %%ebx, %%eax \n" #if __GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ == 1 ".byte 0x0f, 0xae, 0x29 \n" : : "m" (dummy), "c" ((const uint8 *)load), "b" ((uint32)mask), "d" ((uint32)(mask >> 32)) #else "xrstor %1 \n" : : "m" (dummy), "m" (*(const uint8 *)load), "b" ((uint32)mask), "d" ((uint32)(mask >> 32)) #endif : "eax", "memory"); } #endif /* __GNUC__ */ /* *----------------------------------------------------------------------------- * * Div643232 -- * * Unsigned integer division: * The dividend is 64-bit wide * The divisor is 32-bit wide * The quotient is 32-bit wide * * Use this function if you are certain that: * o Either the quotient will fit in 32 bits, * o Or your code is ready to handle a #DE exception indicating overflow. * If that is not the case, then use Div643264(). --hpreg * * Results: * Quotient and remainder * * Side effects: * None * *----------------------------------------------------------------------------- */ #if defined(__GNUC__) static INLINE void Div643232(uint64 dividend, // IN uint32 divisor, // IN uint32 *quotient, // OUT uint32 *remainder) // OUT { /* Checked against the Intel manual and GCC --hpreg */ __asm__( "divl %4" : "=a" (*quotient), "=d" (*remainder) : "0" ((uint32)dividend), "1" ((uint32)(dividend >> 32)), "rm" (divisor) : "cc" ); } #elif defined _MSC_VER static INLINE void Div643232(uint64 dividend, // IN uint32 divisor, // IN uint32 *quotient, // OUT uint32 *remainder) // OUT { /* Written and tested by mann, checked by dbudko and hpreg */ __asm { mov eax, DWORD PTR [dividend] mov edx, DWORD PTR [dividend+4] div DWORD PTR [divisor] mov edi, DWORD PTR [quotient] mov [edi], eax mov edi, DWORD PTR [remainder] mov [edi], edx } } #else #error No compiler defined for Div643232 #endif #if defined(__GNUC__) /* *----------------------------------------------------------------------------- * * Div643264 -- * * Unsigned integer division: * The dividend is 64-bit wide * The divisor is 32-bit wide * The quotient is 64-bit wide --hpreg * * Results: * Quotient and remainder * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE void Div643264(uint64 dividend, // IN uint32 divisor, // IN uint64 *quotient, // OUT uint32 *remainder) // OUT { uint32 hQuotient; uint32 lQuotient; /* Checked against the Intel manual and GCC --hpreg */ __asm__( "divl %5" "\n\t" "movl %%eax, %0" "\n\t" "movl %4, %%eax" "\n\t" "divl %5" : "=&rm" (hQuotient), "=a" (lQuotient), "=d" (*remainder) : "1" ((uint32)(dividend >> 32)), "g" ((uint32)dividend), "rm" (divisor), "2" (0) : "cc" ); *quotient = (uint64)hQuotient << 32 | lQuotient; } #endif /* *----------------------------------------------------------------------------- * * Mul64x3264 -- * * Unsigned integer by fixed point multiplication: * Unsigned 64-bit integer multiplicand. * Unsigned 32-bit fixed point multiplier, represented as * multiplier >> shift, where shift < 64. * Unsigned 64-bit integer product. * * Implementation: * Multiply 64x32 bits to yield a full 96-bit product. * Shift right by shift. * Return the low-order 64 bits of the result. * * Result: * Product * * Side effects: * None * *----------------------------------------------------------------------------- */ #if defined(__GNUC__) static INLINE uint64 Mul64x3264(uint64 multiplicand, uint32 multiplier, uint32 shift) { uint64 result; uint32 tmp1, tmp2; // ASSERT(shift >= 0 && shift < 64); /* * Written and tested by mann, improved with suggestions by hpreg. * * The main improvement over the previous version is that the test * of shift against 32 is moved out of the asm and into C code. * This lets the compiler delete the test and one of the * alternative code sequences in the case where shift is a * constant. It also lets us use the best code sequence in each * alternative, rather than a compromise. The downside is that in * the non-constant case, this version takes slightly more code * space. * * Note on the constraints: We don't really want multiplicand to * start in %edx:%eax as the =A constraint dictates; in fact, we'd * prefer any *other* two registers. But gcc doesn't have * constraint syntax for any other register pair, and trying to * constrain ((uint32) multiplicand) to one place and (multiplicand * >> 32) to another generates *really* bad code -- gcc is just not * smart enough, at least in the version we are currently using. */ if (shift < 32) { __asm__("mov %%eax, %2 \n\t" // Save lo(multiplicand) in tmp2 "mov %%edx, %%eax \n\t" // Get hi(multiplicand) "mull %4 \n\t" // p2 = hi(multiplicand) * multiplier "xchg %%eax, %2 \n\t" // Save lo(p2) in tmp2, get lo(multiplicand) "mov %%edx, %1 \n\t" // Save hi(p2) in tmp1 "mull %4 \n\t" // p1 = lo(multiplicand) * multiplier "addl %2, %%edx \n\t" // hi(p1) += lo(p2) "adcl $0, %1 \n\t" // hi(p2) += carry from previous step "shrdl %%edx, %%eax \n\t" // result = hi(p2):hi(p1):lo(p1) >> shift "shrdl %1, %%edx" : "=A" (result), "=&r" (tmp1), // use in shrdl requires it to be a register "=&r" (tmp2) // could be "=&rm" but "m" is slower : "0" (multiplicand), "rm" (multiplier), "c" (shift) : "cc" ); } else { __asm__("mov %%edx, %2 \n\t" // Save hi(multiplicand) in tmp2 "mull %4 \n\t" // p1 = lo(multiplicand) * multiplier "mov %%edx, %1 \n\t" // Save hi(p1) in tmp1 "mov %2, %%eax \n\t" // Discard lo(p1), get hi(multiplicand) "mull %4 \n\t" // p2 = hi(multiplicand) * multiplier "addl %1, %%eax \n\t" // lo(p2) += hi(p1) "adcl $0, %%edx \n\t" // hi(p2) += carry from previous step "shrdl %%edx, %%eax \n\t" // result = p2 >> (shift & 31) "shrl %%cl, %%edx" : "=A" (result), "=&r" (tmp1), // could be "=&rm" but "m" is slower "=&r" (tmp2) // could be "=&rm" but "m" is slower : "0" (multiplicand), "rm" (multiplier), "c" (shift) : "cc" ); } return result; } #elif defined _MSC_VER #pragma warning(disable: 4035) static INLINE uint64 Mul64x3264(uint64 multiplicand, uint32 multiplier, uint32 shift) { // ASSERT(shift >= 0 && shift < 64); /* Written and tested by mann, checked by dbudko and hpreg */ __asm { mov eax, DWORD PTR [multiplicand+4] // Get hi(multiplicand) mul DWORD PTR [multiplier] // p2 = hi(multiplicand) * multiplier mov ecx, eax // Save lo(p2) mov ebx, edx // Save hi(p2) mov eax, DWORD PTR [multiplicand] // Get lo(multiplicand) mul DWORD PTR [multiplier+0] // p1 = lo(multiplicand) * multiplier add edx, ecx // hi(p1) += lo(p2) adc ebx, 0 // hi(p2) += carry from previous step mov ecx, DWORD PTR [shift] // Get shift cmp ecx, 32 // shift < 32? jl SHORT l2 // Go if so mov eax, edx // result = hi(p2):hi(p1) >> (shift & 31) mov edx, ebx shrd eax, edx, cl shr edx, cl jmp SHORT l3 l2: shrd eax, edx, cl // result = hi(p2):hi(p1):lo(p1) >> shift shrd edx, ebx, cl l3: } // return with result in edx:eax } #pragma warning(default: 4035) #else #error No compiler defined for Mul64x3264 #endif /* *----------------------------------------------------------------------------- * * Muls64x32s64 -- * * Signed integer by fixed point multiplication: * Signed 64-bit integer multiplicand. * Unsigned 32-bit fixed point multiplier, represented as * multiplier >> shift, where shift < 64. * Signed 64-bit integer product. * * Implementation: * Multiply 64x32 bits to yield a full 96-bit product. * Shift right by the location of the binary point. * Return the low-order 64 bits of the result. * * Result: * Product * * Side effects: * None * *----------------------------------------------------------------------------- */ #if defined(__GNUC__) static INLINE int64 Muls64x32s64(int64 multiplicand, uint32 multiplier, uint32 shift) { int64 result; uint32 tmp1, tmp2; // ASSERT(shift >= 0 && shift < 64); /* Written and tested by mann, checked by dbudko and hpreg */ /* XXX hpreg suggested some improvements that we haven't converged on yet */ __asm__("mov %%eax, %2\n\t" // Save lo(multiplicand) "mov %%edx, %%eax\n\t" // Get hi(multiplicand) "test %%eax, %%eax\n\t" // Check sign of multiplicand "jl 0f\n\t" // Go if negative "mull %4\n\t" // p2 = hi(multiplicand) * multiplier "jmp 1f\n" "0:\n\t" "mull %4\n\t" // p2 = hi(multiplicand) * multiplier "sub %4, %%edx\n" // hi(p2) += -1 * multiplier "1:\n\t" "xchg %%eax, %2\n\t" // Save lo(p2), get lo(multiplicand) "mov %%edx, %1\n\t" // Save hi(p2) "mull %4\n\t" // p1 = lo(multiplicand) * multiplier "addl %2, %%edx\n\t" // hi(p1) += lo(p2) "adcl $0, %1\n\t" // hi(p2) += carry from previous step "cmpl $32, %%ecx\n\t" // shift < 32? "jl 2f\n\t" // Go if so "mov %%edx, %%eax\n\t" // result = hi(p2):hi(p1) >> (shift & 31) "mov %1, %%edx\n\t" "shrdl %%edx, %%eax\n\t" "sarl %%cl, %%edx\n\t" "jmp 3f\n" "2:\n\t" "shrdl %%edx, %%eax\n\t" // result = hi(p2):hi(p1):lo(p1) >> shift "shrdl %1, %%edx\n" "3:\n\t" : "=A" (result), "=&r" (tmp1), "=&rm" (tmp2) : "0" (multiplicand), "rm" (multiplier), "c" (shift) : "cc"); return result; } #elif defined _MSC_VER #pragma warning(disable: 4035) static INLINE int64 Muls64x32s64(int64 multiplicand, uint32 multiplier, uint32 shift) { //ASSERT(shift >= 0 && shift < 64); /* Written and tested by mann, checked by dbudko and hpreg */ __asm { mov eax, DWORD PTR [multiplicand+4] // Get hi(multiplicand) test eax, eax // Check sign of multiplicand jl SHORT l0 // Go if negative mul DWORD PTR [multiplier] // p2 = hi(multiplicand) * multiplier jmp SHORT l1 l0: mul DWORD PTR [multiplier] // p2 = hi(multiplicand) * multiplier sub edx, DWORD PTR [multiplier] // hi(p2) += -1 * multiplier l1: mov ecx, eax // Save lo(p2) mov ebx, edx // Save hi(p2) mov eax, DWORD PTR [multiplicand] // Get lo(multiplicand) mul DWORD PTR [multiplier] // p1 = lo(multiplicand) * multiplier add edx, ecx // hi(p1) += lo(p2) adc ebx, 0 // hi(p2) += carry from previous step mov ecx, DWORD PTR [shift] // Get shift cmp ecx, 32 // shift < 32? jl SHORT l2 // Go if so mov eax, edx // result = hi(p2):hi(p1) >> (shift & 31) mov edx, ebx shrd eax, edx, cl sar edx, cl jmp SHORT l3 l2: shrd eax, edx, cl // result = hi(p2):hi(p1):lo(p1) << shift shrd edx, ebx, cl l3: } // return with result in edx:eax } #pragma warning(default: 4035) #else #error No compiler defined for Muls64x32s64 #endif #endif open-vm-tools-9.4.0-1280544/lib/include/vmtoolsd_version.h0000644765153500003110000000214712220061556021421 0ustar dtormts/********************************************************* * Copyright (C) 2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _VMTOOLSD_VERSION_H_ #define _VMTOOLSD_VERSION_H_ #include "vm_tools_version.h" #define VMTOOLSD_VERSION_COMMAS TOOLS_VERSION_EXT_CURRENT_CSV #define VMTOOLSD_VERSION_STRING TOOLS_VERSION_EXT_CURRENT_STR #endif /* _VMTOOLS_VERSION_H_ */ open-vm-tools-9.4.0-1280544/lib/include/random.h0000644765153500003110000000277312220061556017272 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * random.h -- * * Random bits generation. Please use CryptoRandom_GetBytes if * you require a FIPS-compliant source of random data. */ #ifndef __RANDOM_H__ # define __RANDOM_H__ #include "vm_basic_types.h" Bool Random_Crypto(size_t size, void *buffer); /* * High quality - research grade - random number generator. * * Despite its apparent complexity this RNG is extremely fast. */ typedef struct rqContext rqContext; rqContext *Random_QuickSeed(uint32 seed); uint32 Random_Quick(rqContext *context); /* * Simple multiplicative congruential RNG. */ int Random_Simple(int seed); #endif /* __RANDOM_H__ */ open-vm-tools-9.4.0-1280544/lib/include/capsProvider.h0000644765153500003110000000264012220061556020444 0ustar dtormts/********************************************************* * Copyright (C) 2010 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * capsProvider.h -- * * Interface implemented by dnd manager objects to obtain their * capabilities. Mainly needed by Windows host and guest code. */ #ifndef __CAPS_PROVIDER_H__ #define __CAPS_PROVIDER_H__ #if defined VMX86_TOOLS || COMPILE_WITHOUT_CUI # ifdef LIB_EXPORT # undef LIB_EXPORT # endif #define LIB_EXPORT #else #include "libExport.hh" #endif #if defined(SWIG) class CapsProvider #else class LIB_EXPORT CapsProvider #endif { public: virtual ~CapsProvider() {}; virtual Bool CheckCapability(uint32 caps) = 0; }; #endif open-vm-tools-9.4.0-1280544/lib/include/unicode.h0000644765153500003110000000301312220061556017424 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * unicode.h -- * * Unicode-aware string library. */ #ifndef _UNICODE_H_ #define _UNICODE_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" // Start here: string creation, destruction, and encoding conversion. #include "unicodeBase.h" // Basic string operations: length, append, find, insert, replace. #include "unicodeOperations.h" // Character transformations: upper/lower/title case, case folding, etc. #include "unicodeTransforms.h" #ifdef USE_ICU // Unicode functionality depending on the third-party ICU library. #include "unicodeICU.h" #endif // USE_ICU #endif // _UNICODE_H_ open-vm-tools-9.4.0-1280544/lib/include/netutil.h0000644765153500003110000000733512220061556017475 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * netutil.h -- * * Utility network functions. * */ #ifndef __NETUTIL_H__ #define __NETUTIL_H__ #ifdef _WIN32 # include # include # include "vmware/iphlpapi_packed.h" # include # include #else # include #endif #include "vm_basic_types.h" #include "guestInfo.h" /* * Interface types as assigned by IANA. * See http://www.iana.org/assignments/ianaiftype-mib for more details. */ typedef enum { IANA_IFTYPE_OTHER = 1, IANA_IFTYPE_ETHERNETCSMACD = 6, } IanaIfType; /* * Modified from iptypes.h... */ char *NetUtil_GetPrimaryIP(void); GuestNic *NetUtil_GetPrimaryNic(void); #ifdef _WIN32 /* * Brute-force this. Trying to do it "properly" with * WINVER/NTDDI_VERSION checks/manips in a way that compiles for both * VC8 and VC9 didn't work. */ #ifndef FIXED_INFO typedef FIXED_INFO_W2KSP1 FIXED_INFO; typedef FIXED_INFO_W2KSP1 *PFIXED_INFO; #endif DWORD NetUtil_LoadIpHlpApiDll(void); DWORD NetUtil_FreeIpHlpApiDll(void); /* Wrappers for functions in iphlpapi.dll */ PFIXED_INFO NetUtil_GetNetworkParams(void); PIP_ADAPTER_INFO NetUtil_GetAdaptersInfo(void); ULONG NetUtil_GetAdaptersAddresses(ULONG Family, ULONG Flags, PVOID rsvd, PIP_ADAPTER_ADDRESSES adap_addresses, PULONG SizePointer); PMIB_IPFORWARDTABLE NetUtilWin32_GetIpForwardTable(void); PMIB_IPFORWARD_TABLE2 NetUtilWin32_GetIpForwardTable2(void); void NetUtilWin32_FreeMibTable(PMIB_IPFORWARD_TABLE2); #endif #ifdef WIN32 int NetUtil_InetPToN(int af, const char *src, void *dst); const char *NetUtil_InetNToP(int af, const void *src, char *dst, socklen_t size); #else // ifdef WIN32 # define NetUtil_InetPToN inet_pton # define NetUtil_InetNToP inet_ntop #endif #if defined(linux) # ifdef DUMMY_NETUTIL /* * Dummy interface table to enable other tools'/libraries' unit tests. */ typedef struct { int ifIndex; const char *ifName; } NetUtilIfTableEntry; /* * {-1, NULL}-terminated array of NetUtilIfTableEntry pointers. * * (Test) applications wishing to use the dummy NetUtil_GetIf{Index,Name} * functions must define this variable somewhere. It allows said apps * to work with a priori knowledge of interface name <=> index mappings * returned by said APIs. */ EXTERN NetUtilIfTableEntry netUtilIfTable[]; # endif // ifdef DUMMY_NETUTIL int NetUtil_GetIfIndex(const char *ifName); char *NetUtil_GetIfName(int ifIndex); #endif // if defined(linux) size_t NetUtil_GetHardwareAddress(int ifIndex, // IN char *hwAddr, // OUT size_t hwAddrSize, // IN IanaIfType *ifType); // OUT #endif // ifndef _NETUTIL_H_ open-vm-tools-9.4.0-1280544/lib/include/unicodeBase.h0000644765153500003110000002517212220061556020231 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * unicodeBase.h -- * * Basic Unicode string creation and encoding conversion. */ #ifndef _UNICODE_BASE_H_ #define _UNICODE_BASE_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #ifdef __cplusplus extern "C" { #endif #include #include #include "util.h" #include "unicodeTypes.h" #define UNICODE_SUBSTITUTION_CHAR "\xEF\xBF\xBD" /* * Unescapes \\uABCD in string literals to Unicode code point * U+ABCD, and \\U001FABCD to Unicode code point U+1FABCD. * * The resulting string is never freed, so this is not to be used for * general runtime Unicode string creation. * * Use to replace: * * const char *utf8Copyright = "Copyright \302\251 COMPANY_NAME"; * * with: * * ConstUnicode copyright = U_UNESCAPE("Copyright \\u00A9 COMPANY_NAME"); */ #define U_UNESCAPE(x) Unicode_GetStatic(x, TRUE) /* * In contexts where an errno makes sense, use this * to report conversion failure. */ #ifndef _WIN32 #define UNICODE_CONVERSION_ERRNO EINVAL #endif /* * Allocates a Unicode string given a buffer of the specified length * (not necessarily NUL-terminated) in the specified encoding. * * Returns NULL if the buffer was invalid or memory could not be * allocated. */ Unicode Unicode_AllocWithLength(const void *buffer, ssize_t lengthInBytes, StringEncoding encoding); /* *----------------------------------------------------------------------------- * * Unicode_Alloc -- * * Allocates a new Unicode string given a NUL-terminated buffer * of bytes in the specified string encoding. * * If buffer is NULL, then NULL is returned. * * Note that regardless of the encoding of the buffer passed to this * function, the returned string can hold any Unicode characters. * * Results: * An allocated Unicode string containing the decoded characters * in buffer, or NULL if input is NULL. Caller must pass to * Unicode_Free to free. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE Unicode Unicode_Alloc(const void *buffer, // IN StringEncoding encoding) // IN { return Unicode_AllocWithLength(buffer, -1, encoding); } /* *----------------------------------------------------------------------------- * * Unicode_AllocWithUTF8 -- * * Allocates a new Unicode string given a NUL-terminated UTF-8 string. * * If utf8String is NULL, then NULL is returned. * * Results: * An allocated Unicode string containing the characters in * utf8String, or NULL if utf8String is NULL. Caller must pass to * Unicode_Free to free. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE Unicode Unicode_AllocWithUTF8(const char *utf8String) // IN { return Unicode_AllocWithLength(utf8String, -1, STRING_ENCODING_UTF8); } /* *----------------------------------------------------------------------------- * * Unicode_AllocWithUTF16 -- * * Allocates a new Unicode string given a NUL-terminated UTF-16 * string in host-endian order. * * If utf16String is NULL, then NULL is returned. * * Results: * An allocated Unicode string containing the characters in * utf16String, or NULL if utf16String is NULL. Caller must pass to * Unicode_Free to free. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE Unicode Unicode_AllocWithUTF16(const utf16_t *utf16String) // IN { return Unicode_AllocWithLength(utf16String, -1, STRING_ENCODING_UTF16); } Unicode Unicode_Duplicate(ConstUnicode str); void Unicode_Free(Unicode str); Unicode *Unicode_AllocList(char **srcList, ssize_t length, StringEncoding encoding); char **Unicode_GetAllocList(Unicode const srcList[], ssize_t length, StringEncoding encoding); /* *----------------------------------------------------------------------------- * * Unicode_AllocListWithUTF16 -- * * Allocates a list (actually a vector) of Unicode strings from a list * (vector) of UTF-16 strings. The input list has a specified length or * can be an argv-style NULL-terminated list (if length is negative). * * Results: * An allocated list (vector) of Unicode strings. * The result must be freed with Unicode_FreeList. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE Unicode * Unicode_AllocListWithUTF16(utf16_t **utf16list, // IN: ssize_t length) // IN: { return Unicode_AllocList((char **) utf16list, length, STRING_ENCODING_UTF16); } void Unicode_FreeList(Unicode *list, ssize_t length); /* * Accessor for the NUL-terminated UTF-8 representation of this * Unicode string. * * Memory is managed inside this string, so callers do not need to * free. */ const char *Unicode_GetUTF8(ConstUnicode str); /* * Convenience wrapper with a short name for this often-used function. */ static INLINE const char * UTF8(ConstUnicode str) { return Unicode_GetUTF8(str); } /* * Compute the number of bytes in a string. */ ssize_t Unicode_LengthInBytes(const void *buffer, StringEncoding encoding); /* * Gets the number of UTF-16 code units in the NUL-terminated UTF-16 array. */ ssize_t Unicode_UTF16Strlen(const utf16_t *utf16); /* * Duplicates a UTF-16 string. */ utf16_t *Unicode_UTF16Strdup(const utf16_t *utf16); /* * Tests if the buffer's bytes are valid in the specified encoding. */ Bool Unicode_IsBufferValid(const void *buffer, ssize_t lengthInBytes, StringEncoding encoding); /* * Tests if the buffer's unicode contents can be converted to the * specified encoding. */ Bool Unicode_CanGetBytesWithEncoding(ConstUnicode ustr, StringEncoding encoding); /* * Escape non-printable bytes of the buffer with \xAB, where 0xAB * is the non-printable byte value. */ char *Unicode_EscapeBuffer(const void *buffer, ssize_t lengthInBytes, StringEncoding encoding); /* * Returns the length in number of native code units (UTF-8 bytes or * UTF-16 words) of the string. */ UnicodeIndex Unicode_LengthInCodeUnits(ConstUnicode str); /* *----------------------------------------------------------------------------- * * Unicode_IsEmpty -- * * Test if the Unicode string is empty. * * Results: * TRUE if the string has length 0, FALSE otherwise. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE Bool Unicode_IsEmpty(ConstUnicode str) // IN: { #ifdef SUPPORT_UNICODE_OPAQUE NOT_IMPLEMENTED(); #else ASSERT(str != NULL); return str[0] == '\0'; #endif } /* * Efficiently returns the upper bound on the number of bytes required * to encode the Unicode string in the specified encoding, including * NUL termination. */ size_t Unicode_BytesRequired(ConstUnicode str, StringEncoding encoding); /* * Extracts the contents of the Unicode string into a NUL-terminated * buffer using the specified encoding. Copies at most * maxLengthInBytes including NUL termination. Returns FALSE if * truncation occurred, TRUE otherwise. If retLength is not NULL, * *retLength holds the number of bytes actually copied, not including * the NUL termination, upon return. */ Bool Unicode_CopyBytes(void *destBuffer, ConstUnicode srcBuffer, size_t maxLengthInBytes, size_t *retLength, StringEncoding encoding); void *Unicode_GetAllocBytes(ConstUnicode str, StringEncoding encoding); void *Unicode_GetAllocBytesWithLength(ConstUnicode str, StringEncoding encoding, ssize_t lengthInBytes); /* *----------------------------------------------------------------------------- * * Unicode_GetAllocUTF16 -- * * Allocates and returns a NUL terminated buffer into which the contents * of the unicode string are extracted using the (host native) UTF-16 * encoding. (Note that UTF-16 NUL is two bytes: "\0\0".) * * NULL is returned for NULL argument. * * Results: * Pointer to the dynamically allocated memory, * or NULL on NULL argument. * * Caller is responsible to free the memory allocated by this routine. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE utf16_t * Unicode_GetAllocUTF16(ConstUnicode str) // IN: { /* Cast for compatibility with C++ compilers. */ return (utf16_t *) Unicode_GetAllocBytes(str, STRING_ENCODING_UTF16); } /* * Helper function for Unicode string literal macros. */ ConstUnicode Unicode_GetStatic(const char *asciiBytes, Bool unescape); /* * Helper macros for Win32 Unicode string transition. * * Eventually, when the Unicode type becomes opaque * (SUPPORT_UNICODE_OPAQUE), we can store UTF-16 directly inside * it, which is a huge optimization for Win32 programmers. * * At that point, UNICODE_GET_UTF16/UNICODE_RELEASE_UTF16 can become * constant-time operations. * * Until then, Win32 programmers need to alloc and free the UTF-16 * representation of the Unicode string. */ #if defined(_WIN32) #define UNICODE_GET_UTF16(s) Unicode_GetAllocUTF16(s) #define UNICODE_RELEASE_UTF16(s) free((utf16_t *)s) #endif #ifdef __cplusplus } #endif #endif // _UNICODE_BASE_H_ open-vm-tools-9.4.0-1280544/lib/include/ioplGet.h0000644765153500003110000000225512220061556017410 0ustar dtormts/********************************************************* * Copyright (C) 2012 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * ioplGet.h -- * * A utility function to retrieve the IOPL level of the current thread * Compiles on x86, x64 of Linux and Windows */ #ifndef _IOPL_GET_H_ #define _IOPL_GET_H_ #include "x86_basic_defs.h" #include "vm_basic_asm.h" #define Iopl_Get() ((GetCallerEFlags() >> EFLAGS_IOPL_SHIFT) && 0x3) #endif open-vm-tools-9.4.0-1280544/lib/include/vm_legal.h0000644765153500003110000000517612220061556017600 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * All the legalese that we display in About boxes and similar places. */ #ifndef VM_LEGAL_H #define VM_LEGAL_H /* * COMPANY_NAME comes from vm_version.h */ #include "vm_version.h" #ifndef WSTR #define WSTR_(x) L ## x #define WSTR(x) WSTR_(x) #endif #define COPYRIGHT_YEARS "1998-2013" #define COPYRIGHT_STRING "Copyright (C) " COPYRIGHT_YEARS " " COMPANY_NAME #define RIGHT_RESERVED "All rights reserved." /* * Use UTF8_COPYRIGHT_STRING_BASE when the COMPANY_NAME must be separated out * to create a hyperlink. */ #define UTF8_COPYRIGHT_STRING_BASE "Copyright \302\251 " COPYRIGHT_YEARS #define UTF8_COPYRIGHT_STRING UTF8_COPYRIGHT_STRING_BASE " " COMPANY_NAME /* * A UTF-16 version of the copyright string. wchar_t is an * implementation-defined type, but we can expect it to be UTF-16 on * Windows. (Only Windows cares about UTF-16 anyway.) */ #ifdef _WIN32 #define UTF16_COPYRIGHT_STRING L"Copyright \x00A9 " WSTR(COPYRIGHT_YEARS) L" " WSTR(COMPANY_NAME) #endif /* * Use PATENTS_STRING for showing the patents string in plaintext form. * PATENTS_FMT_STRING can be used with PATENTS_URL for creating hyperlinks. */ #define PATENTS_STRING_BASE "This product is protected by U.S. and international copyright and\nintellectual property laws. VMware products are covered by one or\nmore patents listed at " #define PATENTS_STRING PATENTS_STRING_BASE "<" PATENTS_URL ">." #define PATENTS_FMT_STRING PATENTS_STRING_BASE "%s." #define PATENTS_URL "http://www.vmware.com/go/patents" #define TRADEMARK_STRING "VMware is a registered trademark or trademark of VMware, Inc. in the\nUnited States and/or other jurisdictions." #define GENERIC_TRADEMARK_STRING "All other marks and names mentioned herein may be trademarks of their\nrespective companies." #endif /* VM_LEGAL_H */ open-vm-tools-9.4.0-1280544/lib/include/hgfsBd.h0000644765153500003110000000402612220061556017200 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ #ifndef _HGFS_BD_H_ # define _HGFS_BD_H_ /* * hgfsBd.h -- * * Backdoor calls used by hgfs clients. */ #include "rpcout.h" char *HgfsBd_GetBuf(void); char *HgfsBd_GetLargeBuf(void); void HgfsBd_PutBuf(char *); RpcOut *HgfsBd_GetChannel(void); Bool HgfsBd_CloseChannel(RpcOut *out); int HgfsBd_Dispatch(RpcOut *out, char *packetIn, size_t *packetSize, char const **packetOut); Bool HgfsBd_Enabled(RpcOut *out, char *requestPacket); Bool HgfsBd_OpenBackdoor(RpcOut **out); Bool HgfsBd_CloseBackdoor(RpcOut **out); #endif // _HGFS_BD_H_ open-vm-tools-9.4.0-1280544/lib/include/cpNameUtil.h0000644765153500003110000000643012220061556020045 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * cpNameUtil.h * * Utility functions for cross-platform name format. * */ #ifndef __CP_NAME_UTIL_H__ #define __CP_NAME_UTIL_H__ #include "vm_basic_types.h" #include "cpName.h" char *CPNameUtil_Strrchr(char const *cpNameIn, size_t cpNameInSize, char searchChar); int CPNameUtil_ConvertToRoot(char const *nameIn, size_t bufOutSize, char *bufOut); int CPNameUtil_LinuxConvertToRoot(char const *nameIn, size_t bufOutSize, char *bufOut); int CPNameUtil_WindowsConvertToRoot(char const *nameIn, size_t bufOutSize, char *bufOut); /* * Convert a set of files or directories CP names from current to form C. * In/out name lengths include a final nul-terminator to ensure * all the final name component is converted. */ Bool CPNameUtil_Utf8FormHostToUtf8FormC(const char *cpNameToConvert, size_t cpNameToConvertLen, char **cpUtf8FormCName, size_t *cpUtf8FormCNameLen); /* * Convert a set of files or directories CP names from current from form C. * In/out name lengths include a final nul-terminator to ensure * all the final name component is converted. */ Bool CPNameUtil_Utf8FormCToUtf8FormHost(const char *cpUtf8FormCName, size_t cpUtf8FormCNameLen, char **cpConvertedName, size_t *cpConvertedNameLen); void CPNameUtil_CharReplace(char *buf, size_t bufSize, char oldChar, char newChar); #endif /* __CP_NAME_UTIL_H__ */ open-vm-tools-9.4.0-1280544/lib/include/x86vendor.h0000644765153500003110000000325412220061556017650 0ustar dtormts /********************************************************* * Copyright (C) 1998-2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ #ifndef _X86VENDOR_H_ #define _X86VENDOR_H_ /* * CPU vendors */ typedef enum { CPUID_VENDOR_UNKNOWN, CPUID_VENDOR_COMMON, CPUID_VENDOR_INTEL, CPUID_VENDOR_AMD, CPUID_VENDOR_CYRIX, CPUID_VENDOR_VIA, CPUID_NUM_VENDORS } CpuidVendor; #endif open-vm-tools-9.4.0-1280544/lib/include/rpcin.h0000644765153500003110000000535712220061556017126 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * rpcin.h -- * * Remote Procedure Call between VMware and guest applications * C declarations */ #ifndef __RPCIN_H__ # define __RPCIN_H__ #ifdef __cplusplus extern "C" { #endif typedef void RpcIn_ErrorFunc(void *clientData, char const *status); typedef struct RpcIn RpcIn; #if defined(VMTOOLS_USE_GLIB) /* { */ #include "vmware/tools/guestrpc.h" RpcIn *RpcIn_Construct(GMainContext *mainCtx, RpcIn_Callback dispatch, gpointer clientData); Bool RpcIn_start(RpcIn *in, unsigned int delay, RpcIn_ErrorFunc *errorFunc, void *errorData); #else /* } { */ #include "dbllnklst.h" /* * Type for old RpcIn callbacks. Don't use this anymore - this is here * for backwards compatibility. */ typedef Bool (*RpcIn_Callback)(char const **result, // OUT size_t *resultLen, // OUT const char *name, // IN const char *args, // IN size_t argsSize, // IN void *clientData); // IN RpcIn *RpcIn_Construct(DblLnkLst_Links *eventQueue); Bool RpcIn_start(RpcIn *in, unsigned int delay, RpcIn_Callback resetCallback, void *resetClientData, RpcIn_ErrorFunc *errorFunc, void *errorData); /* * Don't use this function anymore - it's here only for backwards compatibility. * Use RpcIn_RegisterCallbackEx() instead. */ void RpcIn_RegisterCallback(RpcIn *in, const char *name, RpcIn_Callback callback, void *clientData); void RpcIn_UnregisterCallback(RpcIn *in, const char *name); unsigned int RpcIn_SetRetVals(char const **result, size_t *resultLen, const char *resultVal, Bool retVal); #endif /* } */ void RpcIn_Destruct(RpcIn *in); void RpcIn_stop(RpcIn *in); #ifdef __cplusplus } // extern "C" #endif #endif /* __RPCIN_H__ */ open-vm-tools-9.4.0-1280544/lib/include/vm_assert.h0000644765153500003110000003154412220061556020013 0ustar dtormts/********************************************************* * Copyright (C) 1998-2004 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * vm_assert.h -- * * The basic assertion facility for all VMware code. * * For proper use, see * http://vmweb.vmware.com/~mts/WebSite/guide/programming/asserts.html */ #ifndef _VM_ASSERT_H_ #define _VM_ASSERT_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_VMKDRIVERS #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_DISTRIBUTE #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMIROM #include "includeCheck.h" // XXX not necessary except some places include vm_assert.h improperly #include "vm_basic_types.h" #include "vm_basic_defs.h" #ifdef __cplusplus extern "C" { #endif /* * Some bits of vmcore are used in VMKernel code and cannot have * the VMKERNEL define due to other header dependencies. */ #if defined(VMKERNEL) && !defined(VMKPANIC) #define VMKPANIC 1 #endif /* * Internal macros, functions, and strings * * The monitor wants to save space at call sites, so it has specialized * functions for each situation. User level wants to save on implementation * so it uses generic functions. */ #if !defined VMM || defined MONITOR_APP // { #if defined VMKPANIC // vmkernel Panic() function does not want a trailing newline. #define _ASSERT_PANIC(name) \ Panic(_##name##Fmt, __FILE__, __LINE__) #define _ASSERT_PANIC_BUG(bug, name) \ Panic(_##name##Fmt " bugNr=%d", __FILE__, __LINE__, bug) #define _ASSERT_PANIC_NORETURN(name) \ Panic_NoReturn(_##name##Fmt, __FILE__, __LINE__) #else /* !VMKPANIC */ #define _ASSERT_PANIC(name) \ Panic(_##name##Fmt "\n", __FILE__, __LINE__) #define _ASSERT_PANIC_BUG(bug, name) \ Panic(_##name##Fmt " bugNr=%d\n", __FILE__, __LINE__, bug) #endif /* VMKPANIC */ #ifdef VMX86_DEVEL # define _ASSERT_WARNING(name) \ Warning(_##name##Fmt "\n", __FILE__, __LINE__) #else # define _ASSERT_WARNING(name) \ Log(_##name##Fmt "\n", __FILE__, __LINE__) #endif #endif // } // these don't have newline so a bug can be tacked on #define _AssertPanicFmt "PANIC %s:%d" #define _AssertAssertFmt "ASSERT %s:%d" #define _AssertNotImplementedFmt "NOT_IMPLEMENTED %s:%d" #define _AssertNotReachedFmt "NOT_REACHED %s:%d" #define _AssertMemAllocFmt "MEM_ALLOC %s:%d" #define _AssertNotTestedFmt "NOT_TESTED %s:%d" /* * Panic and log functions */ void Log(const char *fmt, ...) PRINTF_DECL(1, 2); void Warning(const char *fmt, ...) PRINTF_DECL(1, 2); #if defined VMKPANIC void Panic_SaveRegs(void); #ifdef VMX86_DEBUG void Panic_NoSave(const char *fmt, ...) PRINTF_DECL(1, 2); #else NORETURN void Panic_NoSave(const char *fmt, ...) PRINTF_DECL(1, 2); #endif NORETURN void Panic_NoSaveNoReturn(const char *fmt, ...) PRINTF_DECL(1, 2); #define Panic(fmt...) do { \ Panic_SaveRegs(); \ Panic_NoSave(fmt); \ } while(0) #define Panic_NoReturn(fmt...) do { \ Panic_SaveRegs(); \ Panic_NoSaveNoReturn(fmt); \ } while(0) #else NORETURN void Panic(const char *fmt, ...) PRINTF_DECL(1, 2); #endif void LogThrottled(uint32 *count, const char *fmt, ...) PRINTF_DECL(2, 3); void WarningThrottled(uint32 *count, const char *fmt, ...) PRINTF_DECL(2, 3); /* * Stress testing: redefine ASSERT_IFNOT() to taste */ #ifndef ASSERT_IFNOT /* * PR 271512: When compiling with gcc, catch assignments inside an ASSERT. * * 'UNLIKELY' is defined with __builtin_expect, which does not warn when * passed an assignment (gcc bug 36050). To get around this, we put 'cond' * in an 'if' statement and make sure it never gets executed by putting * that inside of 'if (0)'. We use gcc's statement expression syntax to * make ASSERT an expression because some code uses it that way. * * Since statement expression syntax is a gcc extension and since it's * not clear if this is a problem with other compilers, the ASSERT * definition was not changed for them. Using a bare 'cond' with the * ternary operator may provide a solution. */ #ifdef __GNUC__ #define ASSERT_IFNOT(cond, panic) \ ({if (UNLIKELY(!(cond))) { panic; if (0) { if (cond) { ; } } } (void)0;}) #else #define ASSERT_IFNOT(cond, panic) \ (UNLIKELY(!(cond)) ? (panic) : (void)0) #endif #endif /* * Assert, panic, and log macros * * Some of these are redefined below undef !VMX86_DEBUG. * ASSERT() is special cased because of interaction with Windows DDK. */ #if defined VMX86_DEBUG || defined ASSERT_ALWAYS_AVAILABLE #undef ASSERT #define ASSERT(cond) \ ASSERT_IFNOT(cond, _ASSERT_PANIC(AssertAssert)) #endif #define ASSERT_BUG(bug, cond) \ ASSERT_IFNOT(cond, _ASSERT_PANIC_BUG(bug, AssertAssert)) #define ASSERT_BUG_DEBUGONLY(bug, cond) ASSERT_BUG(bug, cond) #define PANIC() _ASSERT_PANIC(AssertPanic) #define PANIC_BUG(bug) _ASSERT_PANIC_BUG(bug, AssertPanic) #ifdef VMKPANIC #define ASSERT_OR_IN_PANIC(cond) ASSERT((cond) || Panic_IsSystemInPanic()) #endif #define ASSERT_NOT_IMPLEMENTED(cond) \ ASSERT_IFNOT(cond, NOT_IMPLEMENTED()) #define ASSERT_NOT_IMPLEMENTED_BUG(bug, cond) \ ASSERT_IFNOT(cond, NOT_IMPLEMENTED_BUG(bug)) #if defined VMKPANIC && defined VMX86_DEBUG #define NOT_IMPLEMENTED() _ASSERT_PANIC_NORETURN(AssertNotImplemented) #else #define NOT_IMPLEMENTED() _ASSERT_PANIC(AssertNotImplemented) #endif #define NOT_IMPLEMENTED_BUG(bug) _ASSERT_PANIC_BUG(bug, AssertNotImplemented) #if defined VMKPANIC && defined VMX86_DEBUG #define NOT_REACHED() _ASSERT_PANIC_NORETURN(AssertNotReached) #else #define NOT_REACHED() _ASSERT_PANIC(AssertNotReached) #endif #define NOT_REACHED_BUG(bug) _ASSERT_PANIC_BUG(bug, AssertNotReached) #define ASSERT_MEM_ALLOC(cond) \ ASSERT_IFNOT(cond, _ASSERT_PANIC(AssertMemAlloc)) #ifdef VMX86_DEVEL #define ASSERT_DEVEL(cond) ASSERT(cond) #else #define ASSERT_DEVEL(cond) ((void) 0) #endif #define ASSERT_NO_INTERRUPTS() ASSERT(!INTERRUPTS_ENABLED()) #define ASSERT_HAS_INTERRUPTS() ASSERT(INTERRUPTS_ENABLED()) #define NOT_TESTED() _ASSERT_WARNING(AssertNotTested) #define ASSERT_NOT_TESTED(cond) (UNLIKELY(!(cond)) ? NOT_TESTED() : (void)0) #define NOT_TESTED_ONCE() DO_ONCE(NOT_TESTED()) #define NOT_TESTED_1024() \ do { \ static uint16 count = 0; \ if (UNLIKELY(count == 0)) { NOT_TESTED(); } \ count = (count + 1) & 1023; \ } while (0) #define LOG_ONCE(_s) DO_ONCE(Log _s) #ifdef VMX86_DEVEL #define DEPRECATED(_fix) DO_ONCE( \ Warning("%s:%d: %s is DEPRECATED; %s\n", \ __FILE__, __LINE__, __FUNCTION__, \ _fix)) #else #define DEPRECATED(_fix) do {} while (0) #endif /* * Redefine macros that are only in debug versions */ #if !defined VMX86_DEBUG && !defined ASSERT_ALWAYS_AVAILABLE // { #undef ASSERT #define ASSERT(cond) ((void) 0) #undef ASSERT_BUG_DEBUGONLY #define ASSERT_BUG_DEBUGONLY(bug, cond) ((void) 0) #undef ASSERT_LENGTH #define ASSERT_LENGTH(real, expected) ((void) 0) /* * Expand NOT_REACHED() as appropriate for each situation. * * Mainly, we want the compiler to infer the same control-flow * information as it would from Panic(). Otherwise, different * compilation options will lead to different control-flow-derived * errors, causing some make targets to fail while others succeed. * * VC++ has the __assume() built-in function which we don't trust * (see bug 43485); gcc has no such construct; we just panic in * userlevel code. The monitor doesn't want to pay the size penalty * (measured at 212 bytes for the release vmm for a minimal infinite * loop; panic would cost even more) so it does without and lives * with the inconsistency. */ #ifdef VMM #undef NOT_REACHED #define NOT_REACHED() ((void) 0) #else // keep debug definition #endif #undef ASSERT_LOG_UNEXPECTED #define ASSERT_LOG_UNEXPECTED(bug, cond) ((void) 0) #undef LOG_UNEXPECTED #define LOG_UNEXPECTED(bug) ((void) 0) #undef ASSERT_NOT_TESTED #define ASSERT_NOT_TESTED(cond) ((void) 0) #undef NOT_TESTED #define NOT_TESTED() ((void) 0) #undef NOT_TESTED_ONCE #define NOT_TESTED_ONCE() ((void) 0) #undef NOT_TESTED_1024 #define NOT_TESTED_1024() ((void) 0) #endif // !VMX86_DEBUG } /* * Compile-time assertions. * * ASSERT_ON_COMPILE does not use the common * switch (0) { case 0: case (e): ; } trick because some compilers (e.g. MSVC) * generate code for it. * * The implementation uses both enum and typedef because the typedef alone is * insufficient; gcc allows arrays to be declared with non-constant expressions * (even in typedefs, where it makes no sense). */ #define ASSERT_ON_COMPILE(e) \ do { \ enum { AssertOnCompileMisused = ((e) ? 1 : -1) }; \ typedef char AssertOnCompileFailed[AssertOnCompileMisused]; \ } while (0) /* * To put an ASSERT_ON_COMPILE() outside a function, wrap it * in MY_ASSERTS(). The first parameter must be unique in * each .c file where it appears. For example, * * MY_ASSERTS(FS3_INT, * ASSERT_ON_COMPILE(sizeof(FS3_DiskLock) == 128); * ASSERT_ON_COMPILE(sizeof(FS3_DiskLockReserved) == DISK_BLOCK_SIZE); * ASSERT_ON_COMPILE(sizeof(FS3_DiskBlock) == DISK_BLOCK_SIZE); * ASSERT_ON_COMPILE(sizeof(Hardware_DMIUUID) == 16); * ) * * Caution: ASSERT() within MY_ASSERTS() is silently ignored. * The same goes for anything else not evaluated at compile time. */ #define MY_ASSERTS(name, assertions) \ static INLINE void name(void) { \ assertions \ } #ifdef __cplusplus } /* extern "C" */ #endif #endif /* ifndef _VM_ASSERT_H_ */ open-vm-tools-9.4.0-1280544/lib/include/x86_basic_defs.h0000644765153500003110000001661012220061556020574 0ustar dtormts/********************************************************* * Copyright (C) 2006-2013 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * x86_basic_defs.h -- * * Basic macros describing the x86 architecture. */ #ifndef _X86_BASIC_DEFS_H_ #define _X86_BASIC_DEFS_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_DISTRIBUTE #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMIROM #include "includeCheck.h" #define SIZE_8BIT 1 #define SIZE_16BIT 2 #define SIZE_24BIT 3 #define SIZE_32BIT 4 #define SIZE_48BIT 6 #define SIZE_64BIT 8 #define SIZE_80BIT 10 #define SIZE_128BIT 16 #define SIZE_256BIT 32 #define X86_MAX_INSTR_LEN 15 /* Max byte length of an x86 instruction. */ #define NUM_IDT_VECTORS 256 /* * control registers */ #define CR0_PE 0x00000001 #define CR0_MP 0x00000002 #define CR0_EM 0x00000004 #define CR0_TS 0x00000008 #define CR0_ET 0x00000010 #define CR0_NE 0x00000020 #define CR0_WP 0x00010000 #define CR0_AM 0x00040000 #define CR0_NW 0x20000000 #define CR0_CD 0x40000000 #define CR0_PG 0x80000000 #define CR0_RESERVED CONST64U(0xffffffff1ffaffc0) #define CR3_PWT 0x00000008 #define CR3_PCD 0x00000010 #define CR3_PDB_SHIFT 12 #define CR3_PDB_MASK 0xfffff000 #define CR3_IGNORE 0xFFF #define PAE_CR3_IGNORE 0x1F #define CR3_PCID_MASK 0xFFF #define CR3_NO_FLUSH (1ULL << 63) #define CR4_VME 0x00000001 #define CR4_PVI 0x00000002 #define CR4_TSD 0x00000004 #define CR4_DE 0x00000008 #define CR4_PSE 0x00000010 #define CR4_PAE 0x00000020 #define CR4_MCE 0x00000040 #define CR4_PGE 0x00000080 #define CR4_PCE 0x00000100 #define CR4_OSFXSR 0x00000200 // CPU/OS supports SIMD insts #define CR4_OSXMMEXCPT 0x00000400 // #XF exception enable PIII only #define CR4_VMXE 0x00002000 #define CR4_SMXE 0x00004000 #define CR4_FSGSBASE 0x00010000 #define CR4_PCIDE 0x00020000 #define CR4_OSXSAVE 0x00040000 #define CR4_SMEP 0x00100000 /* Removing a bit from CR4_RESERVED causes Task_Switch to leave the bit set. */ #define CR4_RESERVED CONST64U(0xffffffffffe89800) #define CR8_RESERVED CONST64U(0xfffffffffffffff0) #define DR6_B0 0x00000001 #define DR6_B1 0x00000002 #define DR6_B2 0x00000004 #define DR6_B3 0x00000008 #define DR6_B0123 (DR6_B0 | DR6_B1 | DR6_B2 | DR6_B3) #define DR6_B(_n) (1 << (_n)) #define DR6_BD 0x00002000 #define DR6_BS 0x00004000 #define DR6_BT 0x00008000 #define DR6_ONES 0xffff0ff0 #define DR6_STICKY (~DR6_B0123) #define DR6_RESERVED_MASK 0xffff1ff0 /* * Debug registers. */ #define DR7_L_MASK(_n) (1 << ((_n) * 2)) #define DR7_G_MASK(_n) (1 << ((_n) * 2 + 1)) #define DR7_LG_MASK(_n) (3 << ((_n) * 2)) #define DR7_RW_MASK(_n) (3 << (16 + (_n) * 4)) #define DR7_LEN_MASK(_n) (3 << (18 + (_n) * 4)) #define DR7_L0 DR7_L_MASK(0) #define DR7_G0 DR7_G_MASK(0) #define DR7_L1 DR7_L_MASK(1) #define DR7_G1 DR7_G_MASK(1) #define DR7_L2 DR7_L_MASK(2) #define DR7_G2 DR7_G_MASK(2) #define DR7_L3 DR7_L_MASK(3) #define DR7_G3 DR7_G_MASK(3) #define DR7_ENABLED 0x000000ff #define DR7_LE 0x00000100 // Deprecated in modern hardware #define DR7_GE 0x00000200 // Deprecated in modern hardware #define DR7_GD 0x00002000 #define DR7_ONES 0x00000400 #define DR7_RESERVED CONST64U(0xffffffff0000dc00) #define DR7_DEFUNCT (DR7_LE | DR7_GE) #define DR7_DEFAULT DR7_ONES #define DR7_LX_MASK (DR7_L0 | DR7_L1 | DR7_L2 | DR7_L3 | DR7_LE) #define DR7_GX_MASK (DR7_G0 | DR7_G1 | DR7_G2 | DR7_G3 | DR7_GE) #define DR7_LGX_MASK (DR7_LX_MASK | DR7_GX_MASK) #define DR7_RW(_r,_n) (((_r) >> (16+(_n)*4)) & 0x3) #define DR7_L(_r,_n) (((_r) >> ((_n)*2)) & 1) #define DR7_G(_r,_n) (((_r) >> (1 + (_n)*2)) & 1) #define DR7_LEN(_r,_n) (((_r) >> (18+(_n)*4)) & 0x3) #define DR7_RW_BITS(_n,_rw) ((_rw) << (16 + (_n) * 4)) #define DR7_LEN_BITS(_n,_len) ((_len) << (18 + (_n) * 4)) #define DR7_RW_INST 0x0 #define DR7_RW_WRITES 0x1 #define DR7_RW_IO 0x2 #define DR7_RW_ACCESS 0x3 #define DR7_LENGTH_1 0x0 #define DR7_LENGTH_2 0x1 #define DR7_LENGTH_8 0x2 #define DR7_LENGTH_4 0x3 #define DEBUG_STATUS_B0 (1<<0) #define DEBUG_STATUS_B1 (1<<1) #define DEBUG_STATUS_B2 (1<<2) #define DEBUG_STATUS_B3 (1<<3) #define DEBUG_STATUS_DB (1<<13) #define DEBUG_STATUS_BS (1<<14) #define DEBUG_STATUS_BT (1<<15) /* * exception error codes */ #define EXC_DE 0 #define EXC_DB 1 #define EXC_NMI 2 #define EXC_BP 3 #define EXC_OF 4 #define EXC_BR 5 #define EXC_UD 6 #define EXC_NM 7 #define EXC_DF 8 #define EXC_TS 10 #define EXC_NP 11 #define EXC_SS 12 #define EXC_GP 13 #define EXC_PF 14 #define EXC_MF 16 #define EXC_AC 17 #define EXC_MC 18 #define EXC_XF 19 /* SIMD exception. */ #define EXC_SX 30 /* Security exception (SVM only). */ /* * eflag/rflag definitions. */ #define EFLAGS_IOPL_SHIFT 12 typedef enum x86_FLAGS { EFLAGS_NONE = 0, EFLAGS_CF = (1 << 0), /* User */ EFLAGS_SET = (1 << 1), EFLAGS_PF = (1 << 2), /* User */ EFLAGS_AF = (1 << 4), /* User */ EFLAGS_ZF = (1 << 6), /* User */ EFLAGS_SF = (1 << 7), /* User */ EFLAGS_TF = (1 << 8), /* Priv */ EFLAGS_IF = (1 << 9), /* Priv */ EFLAGS_DF = (1 << 10), /* User */ EFLAGS_OF = (1 << 11), /* User */ EFLAGS_NT = (1 << 14), /* Priv */ EFLAGS_RF = (1 << 16), /* Priv */ EFLAGS_VM = (1 << 17), /* Priv */ EFLAGS_AC = (1 << 18), /* Priv */ EFLAGS_VIF = (1 << 19), /* Priv */ EFLAGS_VIP = (1 << 20), /* Priv */ EFLAGS_ID = (1 << 21), /* Priv */ EFLAGS_IOPL = 3 << EFLAGS_IOPL_SHIFT, EFLAGS_ARITH = (EFLAGS_CF | EFLAGS_PF | EFLAGS_AF | EFLAGS_ZF | EFLAGS_SF | EFLAGS_OF), EFLAGS_ALL = (EFLAGS_CF | EFLAGS_PF | EFLAGS_AF | EFLAGS_ZF | EFLAGS_SF | EFLAGS_DF | EFLAGS_OF | EFLAGS_TF | EFLAGS_IF | EFLAGS_IOPL | EFLAGS_NT | EFLAGS_RF | EFLAGS_VM | EFLAGS_AC | EFLAGS_VIF | EFLAGS_VIP | EFLAGS_ID), EFLAGS__4 = 0x7fffffff /* ensure 4 byte encoding */ } x86_FLAGS; #endif // ifndef _VM_BASIC_DEFS_H_ open-vm-tools-9.4.0-1280544/lib/include/localconfig.h0000644765153500003110000000242412220061556020263 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _LOCALCONFIG_H_ #define _LOCALCONFIG_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #include "preference.h" #define LocalConfig_GetBool Preference_GetBool #define LocalConfig_GetTriState Preference_GetTriState #define LocalConfig_GetLong Preference_GetLong #define LocalConfig_GetString Preference_GetString #define LocalConfig_GetPathName Preference_GetPathName #endif open-vm-tools-9.4.0-1280544/lib/include/log.h0000644765153500003110000002132112220061556016561 0ustar dtormts/********************************************************* * Copyright (C) 1998-2012 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef VMWARE_LOG_H #define VMWARE_LOG_H #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #include /* * The bora/lib Log Facility log level model. * This the same as the vmacore/hostd Log Facility. * * The VMW_LOG_BASE is chosen to ensure that on all platforms commonly * used system logger values will be invalid and the errant usage caught. */ #define VMW_LOG_BASE 100 #define VMW_LOG_PANIC (VMW_LOG_BASE + 0) // highest priority #define VMW_LOG_ERROR (VMW_LOG_BASE + 5) #define VMW_LOG_WARNING (VMW_LOG_BASE + 10) // <= goes to stderr by default #define VMW_LOG_AUDIT (VMW_LOG_BASE + 15) // *ALWAYS* output to the log #define VMW_LOG_INFO (VMW_LOG_BASE + 20) // <= goes to log by default #define VMW_LOG_VERBOSE (VMW_LOG_BASE + 25) #define VMW_LOG_TRIVIA (VMW_LOG_BASE + 30) #define VMW_LOG_DEBUG_00 (VMW_LOG_BASE + 35) // noisiest level of debugging #define VMW_LOG_DEBUG_01 (VMW_LOG_DEBUG_00 + 1) #define VMW_LOG_DEBUG_02 (VMW_LOG_DEBUG_00 + 2) #define VMW_LOG_DEBUG_03 (VMW_LOG_DEBUG_00 + 3) #define VMW_LOG_DEBUG_04 (VMW_LOG_DEBUG_00 + 4) #define VMW_LOG_DEBUG_05 (VMW_LOG_DEBUG_00 + 5) #define VMW_LOG_DEBUG_06 (VMW_LOG_DEBUG_00 + 6) #define VMW_LOG_DEBUG_07 (VMW_LOG_DEBUG_00 + 7) #define VMW_LOG_DEBUG_08 (VMW_LOG_DEBUG_00 + 8) #define VMW_LOG_DEBUG_09 (VMW_LOG_DEBUG_00 + 9) #define VMW_LOG_DEBUG_10 (VMW_LOG_DEBUG_00 + 10) // lowest priority; least noisy #define VMW_LOG_NO_ROUTE 0x80000000 // Force routing to Log #define VMW_LOG_NO_ROUTE_STDERR 0x40000000 // Allow stderr on suitable msgs void LogV(uint32 routing, const char *fmt, va_list args); void Log_Level(uint32 routing, const char *fmt, ...) PRINTF_DECL(2, 3); /* * Handy wrapper functions. * * Log -> VMW_LOG_INFO * Warning -> VMW_LOG_WARNING * * TODO: even Log and Warning become wrapper functions around LogV. */ static INLINE void PRINTF_DECL(1, 2) Log_Panic(const char *fmt, ...) { va_list ap; va_start(ap, fmt); LogV(VMW_LOG_PANIC, fmt, ap); va_end(ap); } static INLINE void PRINTF_DECL(1, 2) Log_Audit(const char *fmt, ...) { va_list ap; va_start(ap, fmt); LogV(VMW_LOG_AUDIT, fmt, ap); va_end(ap); } static INLINE void PRINTF_DECL(1, 2) Log_Error(const char *fmt, ...) { va_list ap; va_start(ap, fmt); LogV(VMW_LOG_ERROR, fmt, ap); va_end(ap); } static INLINE void PRINTF_DECL(1, 2) Log_Verbose(const char *fmt, ...) { va_list ap; va_start(ap, fmt); LogV(VMW_LOG_VERBOSE, fmt, ap); va_end(ap); } static INLINE void PRINTF_DECL(1, 2) Log_Trivia(const char *fmt, ...) { va_list ap; va_start(ap, fmt); LogV(VMW_LOG_TRIVIA, fmt, ap); va_end(ap); } #if !defined(VMM) /* Forward decl */ struct MsgList; typedef void (LogOverrideFunc)(int level, const char *msg); typedef enum { LOG_SYSTEM_LOGGER_NONE, LOG_SYSTEM_LOGGER_ADJUNCT, LOG_SYSTEM_LOGGER_ONLY } SysLogger; typedef struct { uint32 signature; // initialization signature const char *fileName; // File name, if known const char *config; // Config variable to look up const char *suffix; // Suffix to generate log file name const char *appName; // App name for log header const char *appVersion; // App version for log header Bool append; // Append to log file Bool switchFile; // Switch the initial log file Bool useThreadName; // Thread name on log line Bool useTimeStamp; // Use a log line time stamp Bool useMilliseconds; // Show milliseconds in time stamp Bool useLevelDesignator; // Show level designator Bool fastRotation; // ESX log rotation optimization Bool preventRemove; // prevent Log_RemoveFile(FALSE) Bool syncAfterWrite; // Sync after a write. Expensive! Bool systemAreaTemp; // temp logs to system/user area int32 stderrMinLevel; // This level and above to stderr int32 logMinLevel; // This level and above to log int permissions; // Permissions for log files uint32 keepOld; // Number of old logs to keep uint32 throttleThreshold; // Threshold for throttling uint32 throttleBPS; // BPS for throttle uint32 rotateSize; // Size at which log should be rotated SysLogger systemLoggerUse; // System logger options char systemLoggerID[128]; // Identifier for system logger } LogInitParams; void Log_GetStaticDefaults(LogInitParams *params); void Log_ApplyConfigValues(const char *appPrefix, LogInitParams *params); Bool Log_InitEx(const LogInitParams *params); Bool Log_InitWithFile(const char *fileName, const char *appPrefix); Bool Log_InitWithConfig(const char *appPrefix); void Log_UpdateFilePermissions(int permissions); void Log_UpdateFileControl(Bool append, unsigned keepOld, size_t rotateSize, Bool fastRotation, uint32 throttleThreshold, uint32 throttleBPS); void Log_UpdatePerLine(Bool perLineTimeStamps, Bool perLineMilliseconds, Bool perLineThreadNames); void Log_Exit(void); Bool Log_Outputting(void); const char *Log_GetFileName(void); void Log_SkipLocking(Bool skipLocking); void Log_SetAlwaysKeep(Bool alwaysKeep); Bool Log_RemoveFile(Bool alwaysRemove); void Log_DisableThrottling(void); void Log_EnableStderrWarnings(Bool stderrOutput); void Log_BackupOldFiles(const char *fileName, Bool noRename); Bool Log_CopyFile(const char *fileName, struct MsgList **errs); uint32 Log_MaxLineLength(void); void Log_OverrideFunction(LogOverrideFunc *func); Bool Log_SetOutput(const char *fileName, const char *config, Bool copy, uint32 systemLoggerUse, char *systemLoggerID, struct MsgList **errs); size_t Log_MakeTimeString(Bool millisec, char *buf, size_t max); typedef Bool (LogOwnerFunc)(void *userData, const char *fileName); Bool Log_BoundNumFiles(LogOwnerFunc *func, void *userData); /* Logging that uses the custom guest throttling configuration. */ void GuestLog_Init(void); void GuestLog_Log(const char *fmt, ...) PRINTF_DECL(1, 2); /* * Default values for the log are obtained via Log_GetStaticDefaults. * * These values represent commonly used override values. */ #if defined(VMX86_SERVER) #define LOG_KEEPOLD 6 // Old log files to keep around; ESX value #else #define LOG_KEEPOLD 3 // Old log files to keep around; non-ESX value #endif #define LOG_NO_KEEPOLD 0 // Keep no old log files #define LOG_NO_ROTATION_SIZE 0 // Do not rotate based on file size #define LOG_NO_THROTTLE_THRESHOLD 0 // No threshold before throttling #define LOG_NO_BPS_LIMIT 0xFFFFFFFF // unlimited input rate /* * Debugging */ void Log_HexDump(const char *prefix, const void *data, size_t size); void Log_Time(VmTimeType *time, int count, const char *message); void Log_Histogram(uint32 n, uint32 histo[], int nbuckets, const char *message, int *count, int limit); #endif /* !VMM */ #endif /* VMWARE_LOG_H */ open-vm-tools-9.4.0-1280544/lib/include/codeset.h0000644765153500003110000004153612220061556017440 0ustar dtormts/* ********************************************************** * Copyright 2007 VMware, Inc. All rights reserved. * **********************************************************/ /* * codeset.h -- * * UTF-16 handling macros. Based on utf16.h from ICU 1.8.1. * * ICU 1.8.1 license follows: * * ICU License - ICU 1.8.1 and later * * COPYRIGHT AND PERMISSION NOTICE * * Copyright (c) 1995-2006 International Business Machines Corporation * and others * * All rights reserved. * * 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, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, provided that the above * copyright notice(s) and this permission notice appear in all * copies of the Software and that both the above copyright * notice(s) and this permission notice appear in supporting * documentation. * * 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 OF THIRD PARTY RIGHTS. IN NO EVENT * SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE * BE LIABLE FOR ANY CLAIM, OR 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. * * Except as contained in this notice, the name of a * copyright holder shall not be used in advertising or otherwise * to promote the sale, use or other dealings in this Software * without prior written authorization of the copyright holder. */ #ifndef __CODESET_H__ # define __CODESET_H__ #include "vm_basic_types.h" #include "vm_assert.h" #include "dynbuf.h" /* * These platforms use UTF-8 (or pretend to): * FreeBSD: really UTF-8 * ESX: UTF-8 by policy decree * Mac: really UTF-8 */ #if defined(__FreeBSD__) || \ defined(VMX86_SERVER) || \ defined(__APPLE__) || \ defined __ANDROID__ #define CURRENT_IS_UTF8 #endif /* * Guard these defines, borrowed from ICU's utf16.h, so that source files * can include both. */ #ifndef __UTF16_H__ /** * Is this code point a surrogate (U+d800..U+dfff)? * @param c 32-bit code point * @return TRUE or FALSE * @stable ICU 2.4 */ #define U_IS_SURROGATE(c) (((c)&0xfffff800)==0xd800) /** * Does this code unit alone encode a code point (BMP, not a surrogate)? * @param c 16-bit code unit * @return TRUE or FALSE * @stable ICU 2.4 */ #define U16_IS_SINGLE(c) (!U_IS_SURROGATE(c)) /** * Is this code unit a lead surrogate (U+d800..U+dbff)? * @param c 16-bit code unit * @return TRUE or FALSE * @stable ICU 2.4 */ #define U16_IS_LEAD(c) (((c)&0xfffffc00)==0xd800) /** * Is this code unit a trail surrogate (U+dc00..U+dfff)? * @param c 16-bit code unit * @return TRUE or FALSE * @stable ICU 2.4 */ #define U16_IS_TRAIL(c) (((c)&0xfffffc00)==0xdc00) /** * Is this code unit a surrogate (U+d800..U+dfff)? * @param c 16-bit code unit * @return TRUE or FALSE * @stable ICU 2.4 */ #define U16_IS_SURROGATE(c) U_IS_SURROGATE(c) /** * Assuming c is a surrogate code point (U16_IS_SURROGATE(c)), * is it a lead surrogate? * @param c 16-bit code unit * @return TRUE or FALSE * @stable ICU 2.4 */ #define U16_IS_SURROGATE_LEAD(c) (((c)&0x400)==0) /** * Helper constant for U16_GET_SUPPLEMENTARY. * @internal */ #define U16_SURROGATE_OFFSET ((0xd800<<10UL)+0xdc00-0x10000) /** * Get a supplementary code point value (U+10000..U+10ffff) * from its lead and trail surrogates. * The result is undefined if the input values are not * lead and trail surrogates. * * @param lead lead surrogate (U+d800..U+dbff) * @param trail trail surrogate (U+dc00..U+dfff) * @return supplementary code point (U+10000..U+10ffff) * @stable ICU 2.4 */ #define U16_GET_SUPPLEMENTARY(lead, trail) \ (((uint32)(lead)<<10UL)+(uint32)(trail)-U16_SURROGATE_OFFSET) /** * Get the lead surrogate (0xd800..0xdbff) for a * supplementary code point (0x10000..0x10ffff). * @param supplementary 32-bit code point (U+10000..U+10ffff) * @return lead surrogate (U+d800..U+dbff) for supplementary * @stable ICU 2.4 */ #define U16_LEAD(supplementary) ((utf16_t)(((supplementary)>>10)+0xd7c0)) /** * Get the trail surrogate (0xdc00..0xdfff) for a * supplementary code point (0x10000..0x10ffff). * @param supplementary 32-bit code point (U+10000..U+10ffff) * @return trail surrogate (U+dc00..U+dfff) for supplementary * @stable ICU 2.4 */ #define U16_TRAIL(supplementary) ((utf16_t)(((supplementary)&0x3ff)|0xdc00)) /** * How many 16-bit code units are used to encode this Unicode code point? (1 or 2) * The result is not defined if c is not a Unicode code point (U+0000..U+10ffff). * @param c 32-bit code point * @return 1 or 2 * @stable ICU 2.4 */ #define U16_LENGTH(c) ((uint32)(c)<=0xffff ? 1 : 2) /** * The maximum number of 16-bit code units per Unicode code point (U+0000..U+10ffff). * @return 2 * @stable ICU 2.4 */ #define U16_MAX_LENGTH 2 /** * Get a code point from a string at a code point boundary offset, * and advance the offset to the next code point boundary. * (Post-incrementing forward iteration.) * "Safe" macro, handles unpaired surrogates and checks for string boundaries. * * The offset may point to the lead surrogate unit * for a supplementary code point, in which case the macro will read * the following trail surrogate as well. * If the offset points to a trail surrogate or * to a single, unpaired lead surrogate, then that itself * will be returned as the code point. * * @param s const utf16_t * string * @param i string offset, must be i(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \ --(i); \ (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \ } \ } \ } #endif // __UTF16_H__ /* * Use this instead of "UTF-16" to specify UTF-16 in native byte order. */ #define CODESET_NATIVE_UTF16 "UTF-16LE" /* * Flags for conversion functions */ #define CSGTG_NORMAL 0x0000 /* Without any information loss. */ #define CSGTG_TRANSLIT 0x0001 /* Transliterate unknown characters. */ #define CSGTG_IGNORE 0x0002 /* Skip over untranslatable characters. */ /* * XXX -- this function is a temporary fix. It should be removed once we fix * the 3rd party library pathname issue. */ char * CodeSet_GetAltPathName(const utf16_t *pathW); // IN Bool CodeSet_Init(const char *icuDataDir); // IN: ICU datafile directory in current page, // can be NULL. void CodeSet_DontUseIcu(void); Bool CodeSet_GenericToGenericDb(const char *codeIn, // IN const char *bufIn, // IN size_t sizeIn, // IN const char *codeOut, // IN unsigned int flags, // IN DynBuf *db); // IN/OUT Bool CodeSet_GenericToGeneric(const char *codeIn, // IN const char *bufIn, // IN size_t sizeIn, // IN const char *codeOut, // IN unsigned int flags, // IN char **bufOut, // IN/OUT size_t *sizeOut); // IN/OUT Bool CodeSet_Utf8ToCurrent(const char *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSet_CurrentToUtf8(const char *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSet_Utf16leToUtf8Db(const char *bufIn, // IN size_t sizeIn, // IN DynBuf *db); // IN Bool CodeSet_Utf16leToUtf8(const char *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSet_Utf8ToUtf16le(const char *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSet_CurrentToUtf16le(const char *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSet_Utf16leToCurrent(const char *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSet_Utf16beToCurrent(const char *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSetOld_Utf8Normalize(const char *bufIn, // IN size_t sizeIn, // IN Bool precomposed, // IN DynBuf *db); // OUT Bool CodeSet_Utf8FormDToUtf8FormC(const char *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut); // OUT Bool CodeSet_Utf8FormCToUtf8FormD(const char *bufIn, // IN size_t sizeIn, // IN char **bufOut, // OUT size_t *sizeOut); // OUT const char * CodeSet_GetCurrentCodeSet(void); Bool CodeSet_IsEncodingSupported(const char *name); Bool CodeSet_Validate(const char *buf, // IN: the string size_t size, // IN: length of string const char *code); // IN: encoding Bool CodeSet_UTF8ToUTF32(const char *utf8, char **utf32); Bool CodeSet_UTF32ToUTF8(const char *utf32, char **utf8); int CodeSet_LengthInCodePoints(const char *utf8); int CodeSet_GetUtf8(const char *string, const char *end, uint32 *uchar); /* *----------------------------------------------------------------------------- * * CodeSet_Utf8ToUtf16 -- * * A convenience wrapper that accepts a NUL-terminated UTF-8 string * and returns an allocated UTF-16 (LE) string. ASSERTs on failure. * * Results: * The allocted UTF-16 (LE) string, free with free(). * * Side effects: * None. * *----------------------------------------------------------------------------- */ static INLINE utf16_t * CodeSet_Utf8ToUtf16(const char *str) // IN: { utf16_t *strW; if (!CodeSet_Utf8ToUtf16le(str, strlen(str), (char **) &strW, NULL)) { ASSERT_MEM_ALLOC(FALSE); } return strW; } /* *----------------------------------------------------------------------------- * * CodeSet_Utf16ToUtf8 -- * * A convenience wrapper that accepts a NUL-terminated UTF-16 (LE) * string and returns an allocated UTF-8 string. ASSERTs on failure. * * Results: * The allocted UTF-8 string, free with free(). * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE char * CodeSet_Utf16ToUtf8(const utf16_t *strW) // IN: { char *str; size_t len; for (len = 0; strW[len]; len++) ; if (!CodeSet_Utf16leToUtf8((const char *) strW, len * sizeof strW[0], (char **) &str, NULL)) { ASSERT_NOT_IMPLEMENTED(0); } return str; } /* *----------------------------------------------------------------------------- * * CodeSet_Utf8FindCodePointBoundary * * Determine if buf[offset] is a valid UTF-8 code point boundary * and find the previous boundary if it is not. The contents of * buf[offset] need not be defined, only data prior to this * location is examined. Useful for finding a suitable place to * put a NUL terminator. * * Results: * * Returns the offset of the byte immediately following the last * complete UTF-8 code point in buf that is entirely within the * range [0, offset-1]. Note that if the final UTF-8 code point * is complete, the input offset will be returned unchanged. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE size_t CodeSet_Utf8FindCodePointBoundary(const char *buf, // IN size_t offset) // IN { size_t origOffset = offset; signed char c; if (offset > 0) { /* * Back up 1 byte and then find the start of the UTF-8 code * point occupying that location. */ offset--; while (offset > 0 && (buf[offset] & 0xc0) == 0x80) { offset--; } /* * Maximum UTF-8 code point length is 4 */ ASSERT(origOffset - offset <= 4); c = buf[offset]; /* * The first byte of a UTF-8 code point needs to be one of * 0b0XXXXXXX, 0b110XXXXX, 0b1110XXXX, 0b11110XXX */ ASSERT(c >= 0 || (c >> 5) == -2 || (c >> 4) == -2 || (c >> 3) == -2); /* * offset now points to the start of a UTF-8 code point. If it * is a single byte or if the length, as encoded in the first * byte, matches the number of bytes we have backed up, then the * entire code point is present, so the original offset is a * valid code point starting offset. * * Length is encoded as * 2 bytes: 0b110XXXXX * 3 bytes: 0b1110XXXX * 4 bytes: 0b11110XXX * Thus the first byte is -2 when shifted right (signed) by * (7 - length). */ if (c >= 0 || (c >> (7 - origOffset + offset)) == -2) { return origOffset; } /* * Else we truncated a code point. Return its starting point. */ } return offset; } /* *----------------------------------------------------------------------------- * * CodeSet_Utf16FindCodePointBoundary * * Determine if buf[offset] is a valid UTF-16 code point boundary * and find the previous boundary if it is not. The contents of * buf[offset] need not be defined, only data prior to this * location is examined. Useful for finding a suitable place to * put a NUL terminator. * * Results: * * Returns the offset of the byte immediately following the last * complete UTF-16 code point in buf that is entirely within the * range [0, offset-1]. Note that if the final UTF-16 code point * is complete, the input offset will be returned unchanged. * * Side effects: * None * *----------------------------------------------------------------------------- */ static INLINE size_t CodeSet_Utf16FindCodePointBoundary(const char *buf, // IN size_t offset) // IN { size_t origOffset; const utf16_t *utf16Buf = (const utf16_t *)buf; origOffset = offset / 2; offset = origOffset - 1; if (origOffset > 0 && U16_IS_LEAD(utf16Buf[offset])) { return offset * 2; } return origOffset * 2; } #endif /* __CODESET_H__ */ open-vm-tools-9.4.0-1280544/lib/include/bsdfmt.h0000644765153500003110000001357112220061556017267 0ustar dtormts/* ********************************************************** * Copyright 2008 VMware, Inc. All rights reserved. * **********************************************************/ /* * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * 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. */ /* * bsdfmt.h -- * * BSD-derived formatter (sprintf, etc.) support. * * Most of this code came from bsd_vsnprintf.c and bsd_output_int.h, * which in turn came from vfprintf.c in the FreeBSD distribution. * See bsd_vsnprintf.c for more details. */ #ifndef _BSDFMT_H_ #define _BSDFMT_H_ #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #ifdef _WIN32 // { #pragma warning(disable : 4018 4047 4101 4102 4146 4244 4267) #define INTMAX_MAX MAX_INT64 typedef unsigned int u_int; typedef unsigned long u_long; typedef unsigned short u_short; typedef unsigned char u_char; typedef __int64 intmax_t; typedef unsigned __int64 uintmax_t; typedef intptr_t ptrdiff_t; #else // } { /* For u_int and u_long, and other types we might want. */ #include #include #include #include #if defined(__FreeBSD__) && __FreeBSD_version < 500029 #define INTMAX_MAX 9223372036854775807LL #define UINTMAX_MAX 18446744073709551615ULL typedef int64 intmax_t; typedef uint64 uintmax_t; typedef int32 wint_t; #endif #endif // } /* * I/O descriptors for BSDFmt_sfvwrite(). */ typedef struct BSDFmt_IOV { void *iov_base; size_t iov_len; } BSDFmt_IOV; typedef struct BSDFmt_UIO { BSDFmt_IOV *uio_iov; int uio_iovcnt; int uio_resid; } BSDFmt_UIO; #define BSDFMT_NIOV 8 typedef struct BSDFmt_StrBuf { Bool alloc; Bool error; char *buf; size_t size; size_t index; } BSDFmt_StrBuf; int BSDFmt_SFVWrite(BSDFmt_StrBuf *sbuf, BSDFmt_UIO *uio); int BSDFmt_SPrint(BSDFmt_StrBuf *sbuf, BSDFmt_UIO *uio); /* * Conversion functions */ char *BSDFmt_WCharToUTF8(wchar_t *, int); char *BSDFmt_UJToA(uintmax_t, char *, int, int, const char *, int, char, const char *); /* * Don't use typedef for mbstate_t because it's actually defined * in VS2003/VC7/include/wchar.h -- edward */ #ifdef _WIN32 #define mbstate_t int #endif /* * Macros for converting digits to letters and vice versa */ #define to_digit(c) ((c) - '0') #define is_digit(c) ((unsigned)to_digit(c) <= 9) #define to_char(n) ((n) + '0') /* * Floating point */ #ifndef NO_FLOATING_POINT // { #include #include #define MAXEXPDIG 6 #define DEFPREC 6 int BSDFmt_Exponent(char *, int, int); extern char *dtoa(double d, int mode, int prec, int *expOut, int *sign, char **strEnd); extern char *ldtoa(long double *ld, int mode, int prec, int *expOut, int *sign, char **strEnd); extern void freedtoa(void *mem); #endif // } /* * The size of the buffer we use as scratch space for integer * conversions, among other things. Technically, we would need the * most space for base 10 conversions with thousands' grouping * characters between each pair of digits. 100 bytes is a * conservative overestimate even for a 128-bit uintmax_t. */ #define INT_CONV_BUF 100 #define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */ /* * Flags used during conversion. */ #define ALT 0x001 /* alternate form */ #define LADJUST 0x004 /* left adjustment */ #define LONGINT 0x010 /* long integer */ #define LLONGINT 0x020 /* long long integer */ #define SHORTINT 0x040 /* short integer */ #define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ #define FPT 0x100 /* Floating point number */ #define GROUPING 0x200 /* use grouping ("'" flag) */ /* C99 additional size modifiers: */ #define SIZET 0x400 /* size_t */ #define PTRDIFFT 0x800 /* ptrdiff_t */ #define INTMAXT 0x1000 /* intmax_t */ #define CHARINT 0x2000 /* print char using int format */ #define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT) /* * Choose PADSIZE to trade efficiency vs. size. If larger printf * fields occur frequently, increase PADSIZE and make the initialisers * below longer. */ #define PADSIZE 16 /* pad chunk size */ extern char blanks[PADSIZE]; extern char zeroes[PADSIZE]; extern const char xdigs_lower[17]; extern const char xdigs_upper[17]; #endif // ifndef _BSDFMT_H_ open-vm-tools-9.4.0-1280544/lib/include/vmSessionId.h0000644765153500003110000000210412220061556020241 0ustar dtormts/********************************************************* * Copyright (C) 2006-2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _VM_SESSION_ID_H_ #define _VM_SESSION_ID_H_ #include "vm_basic_types.h" #ifdef __cplusplus extern "C" { #endif typedef uint64 VMSessionId; #ifdef __cplusplus } #endif #endif /* _VM_SESSION_ID_H_ */ open-vm-tools-9.4.0-1280544/lib/include/safetime.h0000644765153500003110000001147412220061556017605 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * safetime.h -- * * This header file defines wrappers so that we use the * 64-bit versions of the C time calls. This file is * temporary until we switch to a newer version of * Visual Studio that uses the 64-bit verisions by default. * * In Windows, the user is allowed to set the time past the * 32-bit overflow date (in 2038), which can cause crashes * and security problems. In Linux, the time can't be set * to overflow, so we do nothing. * * NB: We do not know if one can set the time past 2038 in * 64-bit versions of Linux, and, if so, what happens when * one does. This requires further investigation sometime * in the future. * * The stat types and functions must be defined manually, * since they contain time_ts, and we can't use the macro * trick, since the struct stat and the function stat have * the same 32 bit name (but different 64 bit names). * */ #ifndef _SAFETIME_H_ #define _SAFETIME_H_ #ifdef _WIN32 #if (defined(_STAT_DEFINED) || defined(_INC_TIME) || defined(_INC_TYPES)) #error Use safetime.h instead of time.h, stat.h, and types.h #endif #undef FMTTIME #define FMTTIME FMT64"d" #if (_MSC_VER < 1400) #define _STAT_DEFINED #include #include #include #define time_t __time64_t #define time(a) _time64(a) #define localtime(a) _localtime64((a)) #define _ctime(a) _ctime64((a)) #define ctime(a) _ctime64((a)) #define _ftime(a) _ftime64((a)) #define ftime(a) _ftime64((a)) #define _timeb __timeb64 #define _gmtime(a) _gmtime64((a)) #define gmtime(a) _gmtime64((a)) #define _mktime(a) _mktime64((a)) #define mktime(a) _mktime64((a)) #define _utime(a,b) _utime64((a),(b)) #define utime(a,b) _utime64((a),(b)) #define _utimbuf __utimbuf64 #define utimbuf __utimbuf64 #define _wctime(a) _wctime64((a),(b)) #define wctime(a) _wctime64((a),(b)) #define _futime(a,b) _futime64((a),(b)) #define futime(a,b) _futime64((a),(b)) #define _wutime(a,b) _wutime64((a),(b)) #define wutime(a,b) _wutime64((a),(b)) #include #ifdef _MSC_VER #pragma pack(push,8) #endif struct _stat { _dev_t st_dev; _ino_t st_ino; unsigned short st_mode; short st_nlink; short st_uid; short st_gid; _dev_t st_rdev; __int64 st_size; __time64_t st_atime; __time64_t st_mtime; __time64_t st_ctime; }; struct stat { _dev_t st_dev; _ino_t st_ino; unsigned short st_mode; short st_nlink; short st_uid; short st_gid; _dev_t st_rdev; __int64 st_size; __time64_t st_atime; __time64_t st_mtime; __time64_t st_ctime; }; struct __stat64 { _dev_t st_dev; _ino_t st_ino; unsigned short st_mode; short st_nlink; short st_uid; short st_gid; _dev_t st_rdev; __int64 st_size; __time64_t st_atime; __time64_t st_mtime; __time64_t st_ctime; }; #ifdef _MSC_VER #pragma pack(pop) #endif #include #define stat(a,b) _stat64((a),(struct __stat64*)(b)) #define _stat(a,b) _stat64((a),(struct __stat64*)(b)) #define fstat(a,b) _fstat64((a),(struct __stat64*)(b)) #define _fstat(a,b) _fstat64((a),(struct __stat64*)(b)) #define wstat(a,b) _wstat64((a),(struct __stat64*)(b)) #define _wstat(a,b) _wstat64((a),(struct __stat64*)(b)) #else /* (_MSC_VER < 1400) */ /* * Starting with VC80, we can pick between 32-bit and 64-bit time_t * by defining or not defining _USE_32BIT_TIME_T. Don't define it. */ #include #include #include #include #include /* Make sure that the headers didn't revert to 32-bit. */ #ifdef _USE_32BIT_TIME_T #error Refusing to use 32-bit time_t in safetime.h #endif #endif /* (_MSC_VER < 1400) */ #else #include #include #include #include #endif #endif open-vm-tools-9.4.0-1280544/lib/include/vmGuestLib.h0000644765153500003110000004033512220061556020067 0ustar dtormts/********************************************************* * Copyright (C) 2003-2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _VM_GUEST_LIB_H_ #define _VM_GUEST_LIB_H_ #include "vm_basic_types.h" #include "vmSessionId.h" #ifdef __cplusplus extern "C" { #endif /* * This is the VMware GuestLib, an API used for accessing various * performance statistics pertaining to the VMware virtual environment * from within a VMware Virtual Machine. */ /* * Error codes returned by GuestLib functions. * * XXX These should be unified with Foundry's error codes. */ typedef enum { VMGUESTLIB_ERROR_SUCCESS = 0, // No error VMGUESTLIB_ERROR_OTHER, // Other error VMGUESTLIB_ERROR_NOT_RUNNING_IN_VM, // Not running in a VM VMGUESTLIB_ERROR_NOT_ENABLED, // GuestLib not enabled on the host. VMGUESTLIB_ERROR_NOT_AVAILABLE, // This stat not available on this host. VMGUESTLIB_ERROR_NO_INFO, // UpdateInfo() has never been called. VMGUESTLIB_ERROR_MEMORY, // Not enough memory VMGUESTLIB_ERROR_BUFFER_TOO_SMALL, // Buffer too small VMGUESTLIB_ERROR_INVALID_HANDLE, // Handle is invalid VMGUESTLIB_ERROR_INVALID_ARG, // One or more arguments were invalid VMGUESTLIB_ERROR_UNSUPPORTED_VERSION // The host doesn't support this request } VMGuestLibError; char const * VMGuestLib_GetErrorText(VMGuestLibError error); // IN /* * GuestLib handle. * * This handle provides a context for accessing all GuestLib * state. Use VMGuestLib_OpenHandle to get a handle for use with other * GuestLib functions, and use VMGuestLib_CloseHandle to release a * handle previously acquired with VMGuestLib_OpenHandle. * * All of the statistics and session state are maintained per GuestLib * handle, so operating on one GuestLib handle will not affect the * state of another handle. */ struct _VMGuestLibHandle; typedef struct _VMGuestLibHandle* VMGuestLibHandle; VMGuestLibError VMGuestLib_OpenHandle(VMGuestLibHandle *handle); // OUT VMGuestLibError VMGuestLib_CloseHandle(VMGuestLibHandle handle); // IN /* * Update the info and session state for the given handle. * * Concurrency/thread safety: No locking is done internally around the * access of a handle. If a calling program uses multiple threads then * the caller must either ensure that each thread of execution is * using a separate handle, or the caller must implement locking * around calls to VMGuestLib_UpdateInfo() on a given handle to ensure * that two threads do not update the handle concurrently. * * Because the state is maintained per handle and no two handles can * be updated exactly simultaneously, the state of two handles may * differ even if they are updated one immediately after the other. * * VMGuestLib_UpdateInfo() is a fairly heavyweight function; it should * be viewed similar to a system call in terms of the computational * cost and performance hit. For this reason, a user of the API who * is concerned about performance will get best results by minimizing * the number of calls to VMGuestLib_UpdateInfo(). */ VMGuestLibError VMGuestLib_UpdateInfo(VMGuestLibHandle handle); // IN /* * Session ID * * This is used to detect changes in the "session" of a virtual * machine. "Session" in this context refers to the particular running * instance of this virtual machine on a given host. Moving a virtual * machine to another host using VMotion will cause a change in * session ID, as will suspending and resuming a virtual machine or * reverting to a snapshot. * * Any of the events above (VMotion, suspend/resume, snapshot revert) * are likely to render invalid any information previously retrieved * through this API, so the intention of the session ID is to provide * applications with a mechanism to detect those events and react * accordingly, e.g. by refreshing and resetting any state that relies * on validity of previously retrieved information. * * Use VMGuestLib_GetSessionId() to retrieve the ID for the current * session after calling VMGuestLib_UpdateInfo(). After a VMotion or * similar event, VMGuestLib_GetSessionId() will return a new value. * See code example below for an example of how to use this. * * If VMGuestLib_UpdateInfo() has never been called, * VMGUESTLIB_ERROR_NO_INFO is returned. * * The session ID should be considered opaque and cannot be compared * in any meaningful way with the session IDs from any other virtual * machine (e.g. to determine if two virtual machines are on the same * host). * * Here is simple pseudo-code (with no error checking) showing a naive * implementation of detecting stale information using the session ID. * * ----- * * VMSessionId sid = 0; * Bool done = FALSE; * * while (!done) { * VMSessionId tmp; * * VMGuestLib_UpdateInfo(); * VMGuestLib_GetSessionId(&tmp); * if (tmp != sid) { * ResetStats(); * sid = tmp; * } * } * * ----- */ VMGuestLibError VMGuestLib_GetSessionId(VMGuestLibHandle handle, // IN VMSessionId *id); // OUT /* * Specific Stat accessors. The values returned by these accessor * functions are up to date as of the last call to VMGuestLib_UpdateInfo(). * * If VMGuestLib_UpdateInfo() has never been called, * VMGUESTLIB_ERROR_NO_INFO is returned. */ /* CPU */ /* * Retrieves the minimum processing power in MHz available to the virtual * machine. Assigning a cpuReservationMhz ensures that even as other virtual * machines on a single host consume shared processing power, there is * still a certain minimum amount for this virtual machine. */ VMGuestLibError VMGuestLib_GetCpuReservationMHz(VMGuestLibHandle handle, // IN uint32 *cpuReservationMHz); // OUT /* * Retrieves the maximum processing power in MHz available to the virtual * machine. Assigning a cpuLimitMHz ensures that this virtual machine never * consumes more than a certain amount of the available processor power. By * limiting the amount of processing power consumed, a portion of this * shared resource is available to other virtual machines. */ VMGuestLibError VMGuestLib_GetCpuLimitMHz(VMGuestLibHandle handle, // IN uint32 *cpuLimitMHz); // OUT /* * Retrieves the number of CPU shares allocated to the virtual machine. */ VMGuestLibError VMGuestLib_GetCpuShares(VMGuestLibHandle handle, // IN uint32 *cpuShares); // OUT /* * Retrieves the number of milliseconds during which the virtual machine * has been using the CPU. This value is always less than or equal to * elapsedMS. This value, in conjunction with elapsedMS, can be used to * estimate efective virtual machine CPU speed. */ VMGuestLibError VMGuestLib_GetCpuUsedMs(VMGuestLibHandle handle, // IN uint64 *cpuUsedMs); // OUT /* * Host Processor speed. This can be used along with CpuUsedMs and * elapsed time to estimate approximate effective VM CPU speed * over a time interval. The following pseudocode illustrates how * to make this calculation: * * ------------------------------------ * * uint32 effectiveVMSpeed; * uint32 hostMhz; * uint64 elapsed1; * uint64 elapsed2; * uint64 used1; * uint64 used2; * * * VMGuestLib_UpdateInfo(handle); * VMGuestLib_GetHostProcessorSpeed(handle, &hostMhz); * VMGuestLib_GetElapsedMs(handle, &elapsed1); * VMGuestLib_GetUsedMs(handle, &used1); * .... * VMGuestLib_UpdateInfo(handle); * VMGuestLib_GetElapsedMs(handle, &elapsed2); * VMGuestLib_GetUsedMs(handle, &used2); * * effectiveVMSpeed = hostMhz * ((used2 - used1) / (elapsed2 - elapsed1)); * * * ------------------------------------ * * After this code executes, effectiveVMSpeed will be the approximate * average effective speed of the VM's virtual CPU over the time period * between the two calls to VMGuestLib_UpdateInfo(). * */ VMGuestLibError VMGuestLib_GetHostProcessorSpeed(VMGuestLibHandle handle, // IN uint32 *mhz); // OUT /* Memory */ /* * Retrieves the minimum amount of memory that is available to the virtual * machine. Assigning a cpuReservationMB ensures that even as other virtual * machines on a single host consume memory, there is still a certain * minimum amount for this virtual machine. */ VMGuestLibError VMGuestLib_GetMemReservationMB(VMGuestLibHandle handle, // IN uint32 *memReservationMB); // OUT /* * Retrieves the maximum amount of memory that is available to the virtual * machine. Assigning a cpuLimitMB ensures that this virtual machine never * consumes more than a certain amount of the available processor power. By * limiting the amount of processing power consumed, a portion of this * shared resource is available to other virtual machines. */ VMGuestLibError VMGuestLib_GetMemLimitMB(VMGuestLibHandle handle, // IN uint32 *memLimitMB); // OUT /* * Retrieves the number of memory shares allocated to the virtual machine. */ VMGuestLibError VMGuestLib_GetMemShares(VMGuestLibHandle handle, // IN uint32 *memShares); // OUT /* * Retrieves the mapped memory size of this virtual machine. This * is the current total amount of guest memory that is backed by * physical memory. Note that this number may include pages of * memory shared between multiple virtual machines and thus may be * an overestimate of the amount of physical host memory "consumed" * by this virtual machine. */ VMGuestLibError VMGuestLib_GetMemMappedMB(VMGuestLibHandle handle, // IN uint32 *memMappedSizeMB); // OUT /* * Retrieves the estimated amount of memory the virtual machine is actively * using. This method returns an estimated working set size for the virtual * machine. */ VMGuestLibError VMGuestLib_GetMemActiveMB(VMGuestLibHandle handle, // IN uint32 *memActiveMB); // OUT /* * Retrieves the amount of overhead memory associated with this virtual * machine consumed on the host system. */ VMGuestLibError VMGuestLib_GetMemOverheadMB(VMGuestLibHandle handle, // IN uint32 *memOverheadMB); // OUT /* * Retrieves the amount of memory that has been reclaimed from this virtual * machine via the VMware Memory Balloon mechanism. */ VMGuestLibError VMGuestLib_GetMemBalloonedMB(VMGuestLibHandle handle, // IN uint32 *memBalloonedMB); // OUT /* * Retrieves the amount of memory associated with this virtual machine that * has been swapped by the host system. */ VMGuestLibError VMGuestLib_GetMemSwappedMB(VMGuestLibHandle handle, // IN uint32 *memSwappedMB); // OUT /* * Retrieves the amount of physical memory associated with this virtual * machine that is copy-on-write (COW) shared on the host. */ VMGuestLibError VMGuestLib_GetMemSharedMB(VMGuestLibHandle handle, // IN uint32 *memSharedMB); // OUT /* * Retrieves the estimated amount of physical memory on the host saved * from copy-on-write (COW) shared guest physical memory. */ VMGuestLibError VMGuestLib_GetMemSharedSavedMB(VMGuestLibHandle handle, // IN uint32 *memSharedSavedMB); // OUT /* * Retrieves the estimated amount of physical host memory currently * consumed for this virtual machine's physical memory. This is the * same as (mapped memory) - (sharedSaved memory). */ VMGuestLibError VMGuestLib_GetMemUsedMB(VMGuestLibHandle handle, // IN uint32 *memUsedMB); // OUT /* Elapsed Time */ /* * Retrieves the number of milliseconds that have passed in real time since * the virtual machine started running on the current host system. The * elapsed time counter is reset any time the virtual machine is powered * on, resumed, or migrated via VMotion. This value, in conjunction with * cpuUsedMS, can be used to estimate effective virtual machine CPU speed. * The cpuUsedMS value is always less than or equal to this value. */ VMGuestLibError VMGuestLib_GetElapsedMs(VMGuestLibHandle handle, // IN uint64 *elapsedMs); // OUT /* * Resource Pool Path. * * Retrieves a string representation of the path to this virtual machine in * the resource pool namespace of the host system. * * pathBuffer is a pointer to a buffer that will receive the resource * pool path string. bufferSize is a pointer to the size of the * pathBuffer in bytes. If bufferSize is not large enough to * accomodate the path and NUL terminator, then * VMGUESTLIB_ERROR_BUFFER_TOO_SMALL is returned and bufferSize * contains the amount of memory needed (in bytes). */ VMGuestLibError VMGuestLib_GetResourcePoolPath(VMGuestLibHandle handle, // IN size_t *bufferSize, // IN/OUT char *pathBuffer); // OUT /* * CPU stolen time. The time (in ms) that the VM was runnable but not scheduled * to run. */ VMGuestLibError VMGuestLib_GetCpuStolenMs(VMGuestLibHandle handle, // IN uint64 *cpuStolenMs); // OUT /* * Memory Target Size. */ VMGuestLibError VMGuestLib_GetMemTargetSizeMB(VMGuestLibHandle handle, // IN uint64 *memTargetSizeMB); // OUT /* * Number of physical CPU cores on the host machine. */ VMGuestLibError VMGuestLib_GetHostNumCpuCores(VMGuestLibHandle handle, // IN uint32 *hostNumCpuCores); // OUT /* * Total CPU time used by host. */ VMGuestLibError VMGuestLib_GetHostCpuUsedMs(VMGuestLibHandle handle, // IN uint64 *hostCpuUsedMs); // OUT /* * Total memory swapped out on the host. */ VMGuestLibError VMGuestLib_GetHostMemSwappedMB(VMGuestLibHandle handle, // IN uint64 *hostMemSwappedMB); // OUT /* * Total COW (Copy-On-Write) memory on host. */ VMGuestLibError VMGuestLib_GetHostMemSharedMB(VMGuestLibHandle handle, // IN uint64 *hostMemSharedMB); // OUT /* * Total consumed memory on host. */ VMGuestLibError VMGuestLib_GetHostMemUsedMB(VMGuestLibHandle handle, // IN uint64 *hostMemUsedMB); // OUT /* * Total memory available to host OS kernel. */ VMGuestLibError VMGuestLib_GetHostMemPhysMB(VMGuestLibHandle handle, // IN uint64 *hostMemPhysMB); // OUT /* * Total physical memory free on host. */ VMGuestLibError VMGuestLib_GetHostMemPhysFreeMB(VMGuestLibHandle handle, // IN uint64 *hostMemPhysFreeMB); // OUT /* * Total host kernel memory overhead. */ VMGuestLibError VMGuestLib_GetHostMemKernOvhdMB(VMGuestLibHandle handle, // IN uint64 *hostMemKernOvhdMB); // OUT /* * Total mapped memory on host. */ VMGuestLibError VMGuestLib_GetHostMemMappedMB(VMGuestLibHandle handle, // IN uint64 *hostMemMappedMB); // OUT /* * Total unmapped memory on host. */ VMGuestLibError VMGuestLib_GetHostMemUnmappedMB(VMGuestLibHandle handle, // IN uint64 *hostMemUnmappedMB); // OUT #ifdef __cplusplus } #endif #endif /* _VM_GUEST_LIB_H_ */ open-vm-tools-9.4.0-1280544/lib/include/preference.h0000644765153500003110000000406712220061556020126 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _PREFERENCE_H_ #define _PREFERENCE_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #include "vm_basic_types.h" struct KeyLocatorState; void Preference_DisableUserPreferences(void); Bool Preference_Init(void); Bool Preference_InitEx(struct KeyLocatorState *klState); void Preference_Exit(void); Bool Preference_GetBool(Bool defaultValue, const char *fmt); int32 Preference_GetTriState(int32 defaultValue, const char *fmt); int32 Preference_GetLong(int32 defaultValue, const char *fmt); int64 Preference_GetInt64(int64 defaultvalue, const char *fmt); double Preference_GetDouble(double defaultValue, const char *fmt); char *Preference_GetString(const char *defaultValue, const char *fmt); char *Preference_GetStringPlain(const char *defaultValue, const char *fmt); char *Preference_GetStringEnum(const void *defaultValue, const char **choices, const char *name); int32 Preference_Generation(void); void Preference_Log(void); char *Preference_GetPathName(const char *defaultValue, const char *fmt); void Preference_SetFromString(const char *string, Bool overwrite); Bool Preference_NotSet(const char *fmt); #endif open-vm-tools-9.4.0-1280544/lib/include/fileLock.h0000644765153500003110000000502412220061556017532 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * fileLock.h -- * * Interface to file locking functions */ #ifndef _FILELOCK_H_ #define _FILELOCK_H_ #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #include "unicodeTypes.h" #include "msgList.h" // The default time, in msec, to wait for a lock before giving up #define FILELOCK_DEFAULT_WAIT 2500 // The wait time that provides "try lock" functionality #define FILELOCK_TRYLOCK_WAIT 0 // Wait "forever" to acquire the lock (maximum uint32) #define FILELOCK_INFINITE_WAIT 0xFFFFFFFF /* * This is the maximum path length overhead that the file locking code * may introduce via all of its components. */ #define FILELOCK_OVERHEAD 15 // File locking functions typedef struct FileLockToken FileLockToken; Unicode FileLock_TokenPathName(const FileLockToken *fileLockToken); FileLockToken *FileLock_Lock(ConstUnicode filePath, const Bool readOnly, const uint32 msecMaxWaitTime, int *err, MsgList **msgs); Bool FileLock_Unlock(const FileLockToken *lockToken, int *err, MsgList **msgs); Bool FileLock_IsLocked(ConstUnicode filePath, int *err, MsgList **msgs); Bool FileLock_Remove(ConstUnicode filePath, int *err, MsgList **msgs); Bool FileLock_CleanupVM(ConstUnicode cfgfilePath, int *err, MsgList **msgs); // Device locking functions, for compatibility int FileLock_LockDevice(const char *device); Bool FileLock_UnlockDevice(const char *device); #endif // ifndef _FILELOCK_H_ open-vm-tools-9.4.0-1280544/lib/include/compat/0000755765153500003110000000000012220061556017113 5ustar dtormtsopen-vm-tools-9.4.0-1280544/lib/include/compat/compat_stdarg.h0000644765153500003110000000455212220061556022121 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * compat_stdarg.h -- * * Compatibility defines for systems that need the stdarg features. If your program * needs va_init, va_copy, va_end, etc. then include this file instead of including * stdarg.h directly. */ #ifndef _COMPAT_STDARG_H #define _COMPAT_STDARG_H 1 #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_VMKDRIVERS #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_DISTRIBUTE #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMIROM #include "includeCheck.h" #include #if !defined(va_copy) # if defined(__va_copy) # define va_copy __va_copy # elif defined(_WIN32) # define va_copy(ap1, ap2) (*(ap1) = *(ap2)) # elif defined(VA_LIST_IS_ARRAY) # define va_copy(ap1, ap2) memcpy(ap1, ap2, sizeof(va_list)) # else # define va_copy(ap1, ap2) ((ap1) = (ap2)) # endif #endif #endif /* _COMPAT_STDARG_H */ open-vm-tools-9.4.0-1280544/lib/include/userlock.h0000644765153500003110000002034412220061556017633 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _USERLOCK_H_ #define _USERLOCK_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #include #include "vm_atomic.h" #include "vm_basic_types.h" #include "vm_basic_defs.h" #include "mutexRank.h" #include "vthreadBase.h" typedef struct MXUserExclLock MXUserExclLock; typedef struct MXUserRecLock MXUserRecLock; typedef struct MXUserRWLock MXUserRWLock; typedef struct MXUserRankLock MXUserRankLock; typedef struct MXUserCondVar MXUserCondVar; typedef struct MXUserSemaphore MXUserSemaphore; typedef struct MXUserBarrier MXUserBarrier; /* * Exclusive ownership lock */ MXUserExclLock *MXUser_CreateExclLock(const char *name, MX_Rank rank); void MXUser_AcquireExclLock(MXUserExclLock *lock); Bool MXUser_TryAcquireExclLock(MXUserExclLock *lock); void MXUser_ReleaseExclLock(MXUserExclLock *lock); void MXUser_DestroyExclLock(MXUserExclLock *lock); Bool MXUser_IsCurThreadHoldingExclLock(MXUserExclLock *lock); MXUserExclLock *MXUser_CreateSingletonExclLock(Atomic_Ptr *lockStorage, const char *name, MX_Rank rank); Bool MXUser_ControlExclLock(MXUserExclLock *lock, uint32 command, ...); MXUserCondVar *MXUser_CreateCondVarExclLock(MXUserExclLock *lock); void MXUser_WaitCondVarExclLock(MXUserExclLock *lock, MXUserCondVar *condVar); void MXUser_TimedWaitCondVarExclLock(MXUserExclLock *lock, MXUserCondVar *condVar, uint32 msecWait); /* * Recursive lock. */ MXUserRecLock *MXUser_CreateRecLock(const char *name, MX_Rank rank); MXUserRecLock *MXUser_CreateRecLockSilent(const char *name, MX_Rank rank); void MXUser_AcquireRecLock(MXUserRecLock *lock); Bool MXUser_TryAcquireRecLock(MXUserRecLock *lock); void MXUser_ReleaseRecLock(MXUserRecLock *lock); void MXUser_DestroyRecLock(MXUserRecLock *lock); Bool MXUser_IsCurThreadHoldingRecLock(MXUserRecLock *lock); MXUserRecLock *MXUser_CreateSingletonRecLock(Atomic_Ptr *lockStorage, const char *name, MX_Rank rank); Bool MXUser_ControlRecLock(MXUserRecLock *lock, uint32 command, ...); void MXUser_DumpRecLock(MXUserRecLock *lock); MXUserCondVar *MXUser_CreateCondVarRecLock(MXUserRecLock *lock); void MXUser_WaitCondVarRecLock(MXUserRecLock *lock, MXUserCondVar *condVar); void MXUser_TimedWaitCondVarRecLock(MXUserRecLock *lock, MXUserCondVar *condVar, uint32 msecWait); void MXUser_IncRefRecLock(MXUserRecLock *lock); void MXUser_DecRefRecLock(MXUserRecLock *lock); /* * Read-write lock */ MXUserRWLock *MXUser_CreateRWLock(const char *name, MX_Rank rank); void MXUser_AcquireForRead(MXUserRWLock *lock); void MXUser_AcquireForWrite(MXUserRWLock *lock); void MXUser_ReleaseRWLock(MXUserRWLock *lock); void MXUser_DestroyRWLock(MXUserRWLock *lock); #define MXUSER_RW_FOR_READ 0 #define MXUSER_RW_FOR_WRITE 1 #define MXUSER_RW_LOCKED 2 Bool MXUser_IsCurThreadHoldingRWLock(MXUserRWLock *lock, uint32 queryType); MXUserRWLock *MXUser_CreateSingletonRWLock(Atomic_Ptr *lockStorage, const char *name, MX_Rank rank); Bool MXUser_ControlRWLock(MXUserRWLock *lock, uint32 command, ...); /* * Computational barrier */ MXUserBarrier *MXUser_CreateBarrier(const char *name, MX_Rank rank, uint32 count); void MXUser_DestroyBarrier(MXUserBarrier *barrier); void MXUser_EnterBarrier(MXUserBarrier *barrier); MXUserBarrier *MXUser_CreateSingletonBarrier(Atomic_Ptr *barrierStorage, const char *name, MX_Rank rank, uint32 count); /* * Counting semaphore */ MXUserSemaphore *MXUser_CreateSemaphore(const char *name, MX_Rank rank); void MXUser_DestroySemaphore(MXUserSemaphore *sema); void MXUser_UpSemaphore(MXUserSemaphore *sema); void MXUser_DownSemaphore(MXUserSemaphore *sema); Bool MXUser_TryDownSemaphore(MXUserSemaphore *sema); Bool MXUser_TimedDownSemaphore(MXUserSemaphore *sema, uint32 msecWait); MXUserSemaphore *MXUser_CreateSingletonSemaphore(Atomic_Ptr *semaStorage, const char *name, MX_Rank rank); /* * Rank lock * * Rank "locks" are entities that perform rank checking but do not provide * any form of mutual exclusion. Their main use is for protecting certain * situations involving Poll and friends/enemies. */ MXUserRankLock *MXUser_CreateRankLock(const char *name, MX_Rank rank); void MXUser_AcquireRankLock(MXUserRankLock *lock); void MXUser_ReleaseRankLock(MXUserRankLock *lock); void MXUser_DestroyRankLock(MXUserRankLock *lock); /* * Generic conditional variable functions. */ #define MXUSER_WAIT_INFINITE 0xFFFFFFFF void MXUser_SignalCondVar(MXUserCondVar *condVar); void MXUser_BroadcastCondVar(MXUserCondVar *condVar); void MXUser_DestroyCondVar(MXUserCondVar *condVar); /* * MXUser_Control[Excl, Rec, RW] commands */ #define MXUSER_CONTROL_ACQUISITION_HISTO 0 // minValue, decades #define MXUSER_CONTROL_HELD_HISTO 1 // minValue, decades #define MXUSER_CONTROL_ENABLE_STATS 2 // no arguments #define MXUSER_DEFAULT_HISTO_MIN_VALUE_NS 1000 // 1 usec #define MXUSER_DEFAULT_HISTO_DECADES 7 // 1 usec to 10 seconds struct MX_MutexRec; #if defined(VMX86_VMX) MXUserRecLock *MXUser_InitFromMXRec(const char *name, struct MX_MutexRec *mutex, MX_Rank rank, Bool isBelowBull); #endif #if defined(VMX86_DEBUG) && !defined(DISABLE_MXUSER_DEBUG) #define MXUSER_DEBUG // debugging "everywhere" when requested #endif #if defined(MXUSER_DEBUG) void MXUser_TryAcquireFailureControl(Bool (*func)(const char *lockName)); Bool MXUser_IsCurThreadHoldingLocks(void); #endif void MXUser_StatisticsControl(double contentionRatio, uint64 minCount); void MXUser_PerLockData(void); void MXUser_SetStatsFunc(void *context, uint32 maxLineLength, Bool trackHeldTime, void (*statsFunc)(void *context, const char *fmt, va_list ap)); void MXUser_SetInPanic(void); Bool MXUser_InPanic(void); MXUserRecLock *MXUser_BindMXMutexRec(struct MX_MutexRec *mutex, MX_Rank rank); struct MX_MutexRec *MXUser_GetRecLockVmm(MXUserRecLock *lock); MX_Rank MXUser_GetRecLockRank(MXUserRecLock *lock); #endif // _USERLOCK_H_ open-vm-tools-9.4.0-1280544/lib/include/vmware.h0000644765153500003110000000774412220061556017316 0ustar dtormts/********************************************************* * Copyright (C) 2003 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * 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 VMware Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission of VMware Inc. * * 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. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * vmware.h -- * * Standard include file for VMware source code. */ #ifndef _VMWARE_H_ #define _VMWARE_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_DISTRIBUTE #include "includeCheck.h" #include "vm_basic_types.h" #include "vm_basic_defs.h" #include "vm_assert.h" /* * Global error codes. Currently used internally, but may be exported * to customers one day, like VM_E_XXX in vmcontrol_constants.h */ typedef enum VMwareStatus { VMWARE_STATUS_SUCCESS, /* success */ VMWARE_STATUS_ERROR, /* generic error */ VMWARE_STATUS_NOMEM, /* generic memory allocation error */ VMWARE_STATUS_INSUFFICIENT_RESOURCES, /* internal or system resource limit exceeded */ VMWARE_STATUS_INVALID_ARGS /* invalid arguments */ } VMwareStatus; #define VMWARE_SUCCESS(s) ((s) == VMWARE_STATUS_SUCCESS) #endif // ifndef _VMWARE_H_ open-vm-tools-9.4.0-1280544/lib/include/syncDriver.h0000644765153500003110000000331312220061556020131 0ustar dtormts/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * syncDriver.h -- * * Interface to the Sync Driver. */ #ifndef _SYNC_DRIVER_H_ #define _SYNC_DRIVER_H_ #include "vm_basic_types.h" #ifdef _WIN32 /* { */ # include # define SYNCDRIVER_INVALID_HANDLE INVALID_HANDLE_VALUE typedef HANDLE SyncDriverHandle; #else /* }{ POSIX */ # define INFINITE -1 # define SYNCDRIVER_INVALID_HANDLE NULL typedef struct SyncHandle * SyncDriverHandle; #endif /* } */ typedef enum { SYNCDRIVER_IDLE, SYNCDRIVER_BUSY, SYNCDRIVER_ERROR } SyncDriverStatus; Bool SyncDriver_Init(void); Bool SyncDriver_Freeze(const char *drives, SyncDriverHandle *handle); Bool SyncDriver_Thaw(const SyncDriverHandle handle); SyncDriverStatus SyncDriver_QueryStatus(const SyncDriverHandle handle, int32 timeout); void SyncDriver_CloseHandle(SyncDriverHandle *handle); #endif open-vm-tools-9.4.0-1280544/lib/include/msgidDefs.h0000644765153500003110000000353412220061556017713 0ustar dtormts/********************************************************* * Copyright (C) 2011 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * msgidDefs.h -- * * Message ID magic definitions */ #ifndef _MSGID_DEFS_H_ #define _MSGID_DEFS_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" /* * Message ID macros * * Use as in * Msg_Append(MSGID(file.openFailed) "Failed to open file %s: %s.\n" * fileName, Msg_ErrString()) * Msg_Append(MSGID(mks.powerOnFailed) "Power on failed.\n") * or * Msg_Hint(TRUE, HINT_OK, * MSGID(mks.noDGA) "No full screen mode.\n"). * * Don't make MSG_MAGIC_LEN (sizeof MSG_MAGIC - 1), since * that may cause the string to be in the object file, even * when it's not used at run time. And we are trying * to avoid littering the output with the magic string. * * -- edward */ #define MSG_MAGIC "@&!*@*@" #define MSG_MAGIC_LEN 7 #define MSGID(id) MSG_MAGIC "(msg." #id ")" #define MSG_BUTTON_ID "(button." #define MSG_BUTTON_ID_LEN 8 #define BUTTONID(id) MSG_MAGIC MSG_BUTTON_ID #id ")" #endif // ifndef _MSGID_DEFS_H_ open-vm-tools-9.4.0-1280544/lib/include/escBitvector.h0000644765153500003110000001047512220061556020444 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ #ifndef _ESC_BITVECTOR_H_ #define _ESC_BITVECTOR_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_DISTRIBUTE // XXX is this true? #include "includeCheck.h" #ifdef __KERNEL__ #include "driver-config.h" #include /* Don't include these if compiling for the Solaris or Apple kernels. */ #elif !defined _KERNEL && !defined KERNEL #include #include #endif #if defined _KERNEL && defined __FreeBSD__ # include #elif defined KERNEL && defined __APPLE__ # include #endif #include "vm_assert.h" #define ESC_BITVECTOR_INDEX(_x) ((_x)>>5) #define ESC_BITVECTOR_MASK(_x) (1<<((_x)&31)) #define ESC_BITVECTOR_SIZE 256 // hardwired size of the bitvector /* *---------------------------------------------------------------------- * * EscBitVector -- * * Taken from bitvector.h, but hard wired for use with the Escape * routines, which always need a bitvector of 256 bits, are never * used in the monitor, and need to work in the linux kernel. [bac] * * *---------------------------------------------------------------------- */ typedef struct EscBitVector { uint32 vector[ESC_BITVECTOR_SIZE/32]; } EscBitVector; /* *---------------------------------------------------------------------- * * EscBitVector_Init -- * * Clear all the bits in this vector. * * Results: * All bits are cleared * *---------------------------------------------------------------------- */ static INLINE void EscBitVector_Init(EscBitVector *bv) { memset(bv, 0, sizeof(EscBitVector)); } /* *---------------------------------------------------------------------- * * EscBitVector_Set, EscBitVector_Clear, EscBitVector_Test -- * * basic operations * * Results: * insertion/deletion/presence to/from/in the set * * EscBitVector_Test returns non-zero if present, 0 otherwise * * *---------------------------------------------------------------------- */ static INLINE void EscBitVector_Set(EscBitVector *bv,int n) { ASSERT(n>=0 && nvector[0]) :"Ir" (n)); #else bv->vector[ESC_BITVECTOR_INDEX(n)] |= ESC_BITVECTOR_MASK(n); #endif } static INLINE void EscBitVector_Clear(EscBitVector *bv,int n) { ASSERT(n>=0 && nvector[0]) :"Ir" (n)); #else bv->vector[ESC_BITVECTOR_INDEX(n)] &= ~ESC_BITVECTOR_MASK(n); #endif } static INLINE int EscBitVector_Test(EscBitVector const *bv, int n) { ASSERT(n>=0 && nvector[0]),"Ir" (n)); return tmp; } #else return ((bv->vector[ESC_BITVECTOR_INDEX(n)] & ESC_BITVECTOR_MASK(n)) != 0); #endif } #endif /* _ESC_BITVECTOR_H_ */ open-vm-tools-9.4.0-1280544/lib/include/hgfsServerPolicy.h0000644765153500003110000001246012220061556021302 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _HGFS_SERVER_POLICY_H_ #define _HGFS_SERVER_POLICY_H_ #include "vm_basic_types.h" #include "hgfs.h" #include "dbllnklst.h" #include "cpName.h" #include "hgfsServer.h" /* * Name of share that corresponds to the root of the server's * filesystem. */ #define HGFS_SERVER_POLICY_ROOT_SHARE_NAME "root" Bool HgfsServerPolicy_Init(HgfsInvalidateObjectsFunc *invalidateObjects, HgfsRegisterSharedFolderFunc *registerFolder); Bool HgfsServerPolicy_Cleanup(void); typedef uint32 HgfsShareOptions; /* * Structure representing one shared folder. We maintain a list of * these to check accesses against. */ typedef struct HgfsSharedFolder { DblLnkLst_Links links; char *name; /* Name of share */ char *path; /* * Path of share in server's filesystem. Should * not include final path separator. */ char *shareTags; /* Tags associated with this share (comma delimited). */ size_t shareTagsLen; /* Length of shareTag string */ size_t nameLen; /* Length of name string */ size_t pathLen; /* Length of path string */ Bool readAccess; /* Read permission for this share */ Bool writeAccess; /* Write permission for this share */ HgfsShareOptions configOptions; /* User-config options. */ HgfsSharedFolderHandle handle; /* Handle assigned by HGFS server * when the folder was registered with it. * Policy package keeps the context and returns * it along with other shared folder properties. * Keeping it here ensures consistent lookup all * properties of the shared folder which takes into * account such details like case sensitive/case * insensitive name lookup. */ } HgfsSharedFolder; /* Per share user configurable options. */ #define HGFS_SHARE_HOST_DEFAULT_CASE (1 << 0) #define HGFS_SHARE_FOLLOW_SYMLINKS (1 << 1) typedef struct HgfsServerPolicy_ShareList { size_t count; char **shareNames; } HgfsServerPolicy_ShareList; /* Defined in hgfsServerInt.h */ HgfsGetNameFunc HgfsServerPolicy_GetShares; HgfsInitFunc HgfsServerPolicy_GetSharesInit; HgfsCleanupFunc HgfsServerPolicy_GetSharesCleanup; HgfsNameStatus HgfsServerPolicy_GetSharePath(char const *nameIn, // IN: size_t nameInLen, // IN: HgfsOpenMode mode, // IN: size_t *sharePathLen, // OUT: char const **sharePath); // OUT: HgfsNameStatus HgfsServerPolicy_GetShareMode(char const *nameIn, // IN: Share name to retrieve size_t nameInLen, // IN: Length of Share name HgfsOpenMode *mode); // OUT: Share's access mode HgfsNameStatus HgfsServerPolicy_GetShareOptions(char const *nameIn, // IN: Share name size_t nameInLen, // IN: Share name length HgfsShareOptions *configOptions); // OUT: Share config options Bool HgfsServerPolicy_IsShareOptionSet(HgfsShareOptions shareOptions, // IN: Config options uint32 option); // IN: Option to check HgfsNameStatus HgfsServerPolicy_ProcessCPName(char const *nameIn, // IN: name in CPName form size_t nameInLen, // IN: length of the name Bool *readAccess, // OUT: Read permissions Bool *writeAccess, // OUT: Write permissions HgfsSharedFolderHandle *handle,// OUT: folder handle char const **shareBaseDir); // OUT: Shared directory void HgfsServerPolicy_FreeShareList(HgfsServerPolicy_ShareList *shareList); // IN: list to free HgfsServerPolicy_ShareList * HgfsServerPolicy_GetSharesWithTag(const char *tag); // IN: tag to search for Bool HgfsServerPolicy_CheckMode(HgfsOpenMode mode, // IN: mode to check Bool writePermissions, // IN: callers write permissions Bool readPermissions); // IN: callers read permissions #endif // _HGFS_SERVER_POLICY_H_ open-vm-tools-9.4.0-1280544/lib/include/vmware_pack_begin.h0000644765153500003110000000355712220061556021456 0ustar dtormts/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * vmware_pack_begin.h -- * * Begin of structure packing. See vmware_pack_init.h for details. * * Note that we do not use the following construct in this include file, * because we want to emit the code every time the file is included --hpreg * * #ifndef foo * # define foo * ... * #endif * */ #include "vmware_pack_init.h" #ifdef _MSC_VER # pragma pack(push, 1) #elif __GNUC__ #else # error Compiler packing... #endif open-vm-tools-9.4.0-1280544/lib/include/guest_os_tables.h0000644765153500003110000004116312220061556021170 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _GUEST_OS_TABLES_H_ #define _GUEST_OS_TABLES_H_ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #define GUEST_OS_TYPE_GEN \ GOT(GUEST_OS_ANY) \ GOT(GUEST_OS_DOS) \ GOT(GUEST_OS_WIN31) \ GOT(GUEST_OS_WIN95) \ GOT(GUEST_OS_WIN98) \ GOT(GUEST_OS_WINME) \ GOT(GUEST_OS_WINNT) \ GOT(GUEST_OS_WIN2000) \ GOT(GUEST_OS_WINXP) \ GOT(GUEST_OS_WINXPPRO_64) \ GOT(GUEST_OS_WINNET) \ GOT(GUEST_OS_WINNET_64) \ GOT(GUEST_OS_LONGHORN) \ GOT(GUEST_OS_LONGHORN_64) \ GOT(GUEST_OS_WINVISTA) \ GOT(GUEST_OS_WINVISTA_64) \ GOT(GUEST_OS_WINSEVEN) /* Windows 7 */ \ GOT(GUEST_OS_WINSEVEN_64) /* Windows 7 */ \ GOT(GUEST_OS_WIN2008R2_64) /* Server 2008 R2 */ \ GOT(GUEST_OS_WINEIGHT) /* Windows 8 */ \ GOT(GUEST_OS_WINEIGHT_64) /* Windows 8 x64 */ \ GOT(GUEST_OS_WINEIGHTSERVER_64) /* Windows 8 Server X64 */ \ GOT(GUEST_OS_HYPER_V) /* Microsoft Hyper-V */ \ GOT(GUEST_OS_OS2) \ GOT(GUEST_OS_ECOMSTATION) /* OS/2 variant; 1.x */ \ GOT(GUEST_OS_ECOMSTATION2) /* OS/2 variant; 2.x */ \ GOT(GUEST_OS_OTHER24XLINUX) \ GOT(GUEST_OS_OTHER24XLINUX_64) \ GOT(GUEST_OS_OTHER26XLINUX) \ GOT(GUEST_OS_OTHER26XLINUX_64) \ GOT(GUEST_OS_OTHER3XLINUX) \ GOT(GUEST_OS_OTHER3XLINUX_64) \ GOT(GUEST_OS_OTHERLINUX) \ GOT(GUEST_OS_OTHERLINUX_64) \ GOT(GUEST_OS_OTHER) \ GOT(GUEST_OS_OTHER_64) \ GOT(GUEST_OS_UBUNTU) \ GOT(GUEST_OS_DEBIAN45) \ GOT(GUEST_OS_DEBIAN45_64) \ GOT(GUEST_OS_RHEL) \ GOT(GUEST_OS_RHEL_64) \ GOT(GUEST_OS_FREEBSD) \ GOT(GUEST_OS_FREEBSD_64) \ GOT(GUEST_OS_SOLARIS_6_AND_7) \ GOT(GUEST_OS_SOLARIS8) \ GOT(GUEST_OS_SOLARIS9) \ GOT(GUEST_OS_SOLARIS10) \ GOT(GUEST_OS_SOLARIS10_64) \ GOT(GUEST_OS_DARWIN9) /* Mac OS 10.5 */ \ GOT(GUEST_OS_DARWIN9_64) \ GOT(GUEST_OS_DARWIN10) /* Mac OS 10.6 */ \ GOT(GUEST_OS_DARWIN10_64) \ GOT(GUEST_OS_DARWIN11) /* Mac OS 10.7 */ \ GOT(GUEST_OS_DARWIN11_64) \ GOT(GUEST_OS_DARWIN12_64) /* Mac OS 10.8 */ \ GOT(GUEST_OS_DARWIN13_64) /* Mac OS 10.9 */ \ GOT(GUEST_OS_OPENSERVER_5_AND_6) \ GOT(GUEST_OS_UNIXWARE7) \ GOT(GUEST_OS_NETWARE4) \ GOT(GUEST_OS_NETWARE5) \ GOT(GUEST_OS_NETWARE6) \ GOT(GUEST_OS_VMKERNEL) /* ESX 4.x */ \ GOT(GUEST_OS_VMKERNEL5) /* ESX 5.x and later */ \ #define GUEST_OS_LIST_GEN \ GOSL("dos", GUEST_OS_DOS) \ GOSL(STR_OS_WIN_31, GUEST_OS_WIN31) \ GOSL(STR_OS_WIN_95, GUEST_OS_WIN95) \ GOSL(STR_OS_WIN_98, GUEST_OS_WIN98) \ GOSL(STR_OS_WIN_ME, GUEST_OS_WINME ) \ GOSL(STR_OS_WIN_NT, GUEST_OS_WINNT) \ GOSL("nt4", GUEST_OS_WINNT) /* old */ \ GOSL(STR_OS_WIN_2000_PRO, GUEST_OS_WIN2000) \ GOSL("win2000", GUEST_OS_WIN2000) /* old */ \ GOSL(STR_OS_WIN_2000_SERV, GUEST_OS_WIN2000) \ GOSL(STR_OS_WIN_2000_ADV_SERV, GUEST_OS_WIN2000) \ GOSL(STR_OS_WIN_XP_HOME, GUEST_OS_WINXP) \ GOSL("whistler", GUEST_OS_WINXP) /* old */ \ GOSL(STR_OS_WIN_XP_PRO, GUEST_OS_WINXP) \ GOSL(STR_OS_WIN_XP_PRO_X64, GUEST_OS_WINXPPRO_64) \ GOSL(STR_OS_WIN_NET_WEB, GUEST_OS_WINNET) \ GOSL(STR_OS_WIN_NET_ST, GUEST_OS_WINNET) \ GOSL(STR_OS_WIN_NET_EN, GUEST_OS_WINNET) \ GOSL("winNetDatacenter", GUEST_OS_WINNET) \ GOSL(STR_OS_WIN_NET_BUS, GUEST_OS_WINNET) \ GOSL("winNetStandard-64", GUEST_OS_WINNET_64) \ GOSL("winNetEnterprise-64", GUEST_OS_WINNET_64) \ GOSL("winNetDatacenter-64", GUEST_OS_WINNET_64) \ GOSL(STR_OS_WIN_LONG, GUEST_OS_LONGHORN) \ GOSL(STR_OS_WIN_2008_CLUSTER, GUEST_OS_LONGHORN) \ GOSL(STR_OS_WIN_2008_DATACENTER, GUEST_OS_LONGHORN) \ GOSL(STR_OS_WIN_2008_DATACENTER_CORE, GUEST_OS_LONGHORN) \ GOSL(STR_OS_WIN_2008_ENTERPRISE, GUEST_OS_LONGHORN) \ GOSL(STR_OS_WIN_2008_ENTERPRISE_CORE, GUEST_OS_LONGHORN) \ GOSL(STR_OS_WIN_2008_SMALL_BUSINESS, GUEST_OS_LONGHORN) \ GOSL(STR_OS_WIN_2008_SMALL_BUSINESS_PREMIUM, GUEST_OS_LONGHORN) \ GOSL(STR_OS_WIN_2008_STANDARD, GUEST_OS_LONGHORN) \ GOSL(STR_OS_WIN_2008_STANDARD_CORE, GUEST_OS_LONGHORN) \ GOSL(STR_OS_WIN_2008_WEB_SERVER, GUEST_OS_LONGHORN) \ GOSL("winLonghornGuest", GUEST_OS_LONGHORN) \ GOSL("longhorn-64", GUEST_OS_LONGHORN_64) \ GOSL(STR_OS_WIN_2008_CLUSTER_X64, GUEST_OS_LONGHORN_64) \ GOSL(STR_OS_WIN_2008_DATACENTER_X64, GUEST_OS_LONGHORN_64) \ GOSL(STR_OS_WIN_2008_DATACENTER_CORE_X64, GUEST_OS_LONGHORN_64) \ GOSL(STR_OS_WIN_2008_ENTERPRISE_X64, GUEST_OS_LONGHORN_64) \ GOSL(STR_OS_WIN_2008_ENTERPRISE_CORE_X64, GUEST_OS_LONGHORN_64) \ GOSL(STR_OS_WIN_2008_SMALL_BUSINESS_X64, GUEST_OS_LONGHORN_64) \ GOSL(STR_OS_WIN_2008_SMALL_BUSINESS_PREMIUM_X64, GUEST_OS_LONGHORN_64) \ GOSL(STR_OS_WIN_2008_STANDARD_X64, GUEST_OS_LONGHORN_64) \ GOSL(STR_OS_WIN_2008_STANDARD_CORE_X64, GUEST_OS_LONGHORN_64) \ GOSL(STR_OS_WIN_2008_WEB_SERVER_X64, GUEST_OS_LONGHORN_64) \ GOSL("winLonghorn64Guest", GUEST_OS_LONGHORN_64) \ GOSL(STR_OS_WIN_VISTA, GUEST_OS_WINVISTA) \ GOSL(STR_OS_WIN_VISTA_X64, GUEST_OS_WINVISTA_64) \ GOSL(STR_OS_WIN_SEVEN, GUEST_OS_WINSEVEN) \ GOSL(STR_OS_WIN_SEVEN_X64, GUEST_OS_WINSEVEN_64) \ GOSL(STR_OS_WIN_2008R2_X64, GUEST_OS_WIN2008R2_64) \ GOSL("windows7Server64Guest", GUEST_OS_WIN2008R2_64) \ GOSL(STR_OS_RED_HAT, GUEST_OS_OTHER26XLINUX) \ GOSL(STR_OS_RED_HAT_EN "2", GUEST_OS_OTHER24XLINUX) \ GOSL(STR_OS_RED_HAT_EN "3", GUEST_OS_OTHER24XLINUX) \ GOSL(STR_OS_RED_HAT_EN "3-64", GUEST_OS_OTHER24XLINUX_64) \ GOSL(STR_OS_RED_HAT_EN "4", GUEST_OS_OTHER26XLINUX) \ GOSL(STR_OS_RED_HAT_EN "4-64", GUEST_OS_OTHER26XLINUX_64) \ GOSL(STR_OS_RED_HAT_EN "5", GUEST_OS_OTHER26XLINUX) \ GOSL(STR_OS_RED_HAT_EN "5-64", GUEST_OS_OTHER26XLINUX_64) \ GOSL(STR_OS_RED_HAT_EN "6", GUEST_OS_RHEL) \ GOSL(STR_OS_RED_HAT_EN "6-64", GUEST_OS_RHEL_64) \ GOSL(STR_OS_RED_HAT_EN "7", GUEST_OS_RHEL) \ GOSL(STR_OS_RED_HAT_EN "7-64", GUEST_OS_RHEL_64) \ GOSL(STR_OS_CENTOS, GUEST_OS_OTHER26XLINUX) \ GOSL(STR_OS_CENTOS "-64", GUEST_OS_OTHER26XLINUX_64) \ GOSL(STR_OS_ORACLE, GUEST_OS_OTHER26XLINUX) \ GOSL(STR_OS_ORACLE "-64", GUEST_OS_OTHER26XLINUX_64) \ GOSL(STR_OS_OPENSUSE, GUEST_OS_OTHER26XLINUX) \ GOSL(STR_OS_OPENSUSE "-64", GUEST_OS_OTHER26XLINUX_64) \ GOSL(STR_OS_SUSE, GUEST_OS_OTHER26XLINUX) \ GOSL(STR_OS_SUSE "-64", GUEST_OS_OTHER26XLINUX_64) \ GOSL(STR_OS_SLES, GUEST_OS_OTHER26XLINUX) \ GOSL(STR_OS_SLES "-64", GUEST_OS_OTHER26XLINUX_64) \ GOSL(STR_OS_SLES "10", GUEST_OS_OTHER26XLINUX) \ GOSL(STR_OS_SLES "10-64", GUEST_OS_OTHER26XLINUX_64) \ GOSL(STR_OS_SLES "11", GUEST_OS_OTHER26XLINUX) \ GOSL(STR_OS_SLES "11-64", GUEST_OS_OTHER26XLINUX_64) \ GOSL(STR_OS_SLES "12", GUEST_OS_OTHER26XLINUX) \ GOSL(STR_OS_SLES "12-64", GUEST_OS_OTHER26XLINUX_64) \ GOSL(STR_OS_NOVELL, GUEST_OS_OTHER26XLINUX) \ GOSL(STR_OS_SUN_DESK, GUEST_OS_OTHER24XLINUX) \ GOSL(STR_OS_MANDRAKE, GUEST_OS_OTHER26XLINUX) \ GOSL(STR_OS_MANDRAKE "-64", GUEST_OS_OTHER26XLINUX_64) \ GOSL(STR_OS_MANDRIVA, GUEST_OS_OTHER26XLINUX) \ GOSL(STR_OS_MANDRIVA "-64", GUEST_OS_OTHER26XLINUX_64) \ GOSL(STR_OS_TURBO, GUEST_OS_OTHER26XLINUX) \ GOSL(STR_OS_TURBO "-64", GUEST_OS_OTHER26XLINUX_64) \ GOSL(STR_OS_ASIANUX_3, GUEST_OS_OTHER26XLINUX) \ GOSL(STR_OS_ASIANUX_3 "-64", GUEST_OS_OTHER26XLINUX_64) \ GOSL(STR_OS_ASIANUX_4, GUEST_OS_OTHER26XLINUX) \ GOSL(STR_OS_ASIANUX_4 "-64", GUEST_OS_OTHER26XLINUX_64) \ GOSL("fedora", GUEST_OS_OTHER26XLINUX) \ GOSL("fedora-64", GUEST_OS_OTHER26XLINUX_64) \ GOSL(STR_OS_OTHER_24, GUEST_OS_OTHER24XLINUX) \ GOSL(STR_OS_OTHER_24 "-64", GUEST_OS_OTHER24XLINUX_64) \ GOSL(STR_OS_OTHER_26, GUEST_OS_OTHER26XLINUX) \ GOSL(STR_OS_OTHER_26 "-64", GUEST_OS_OTHER26XLINUX_64) \ GOSL(STR_OS_OTHER_3X, GUEST_OS_OTHER3XLINUX) \ GOSL(STR_OS_OTHER_3X "-64", GUEST_OS_OTHER3XLINUX_64) \ GOSL(STR_OS_OTHER, GUEST_OS_OTHERLINUX) \ GOSL(STR_OS_OTHER "-64", GUEST_OS_OTHERLINUX_64) \ GOSL(STR_OS_DEBIAN_4, GUEST_OS_DEBIAN45) \ GOSL(STR_OS_DEBIAN_4 "-64", GUEST_OS_DEBIAN45_64) \ GOSL(STR_OS_DEBIAN_5, GUEST_OS_DEBIAN45) \ GOSL(STR_OS_DEBIAN_5 "-64", GUEST_OS_DEBIAN45_64) \ GOSL(STR_OS_DEBIAN_6, GUEST_OS_DEBIAN45) \ GOSL(STR_OS_DEBIAN_6 "-64", GUEST_OS_DEBIAN45_64) \ GOSL(STR_OS_DEBIAN_7, GUEST_OS_DEBIAN45) \ GOSL(STR_OS_DEBIAN_7 "-64", GUEST_OS_DEBIAN45_64) \ GOSL(STR_OS_SOLARIS "6", GUEST_OS_SOLARIS_6_AND_7) \ GOSL(STR_OS_SOLARIS "7", GUEST_OS_SOLARIS_6_AND_7) \ GOSL(STR_OS_SOLARIS "8", GUEST_OS_SOLARIS8) \ GOSL(STR_OS_SOLARIS "9", GUEST_OS_SOLARIS9) \ GOSL(STR_OS_SOLARIS "10", GUEST_OS_SOLARIS10) \ GOSL(STR_OS_SOLARIS "10-64", GUEST_OS_SOLARIS10_64) \ GOSL(STR_OS_SOLARIS "11", GUEST_OS_SOLARIS10) \ GOSL(STR_OS_SOLARIS "11-64", GUEST_OS_SOLARIS10_64) \ GOSL("linux", GUEST_OS_OTHERLINUX) /* old */ \ GOSL("freeBSD", GUEST_OS_FREEBSD) \ GOSL("freeBSD-64", GUEST_OS_FREEBSD_64) \ GOSL(STR_OS_UBUNTU, GUEST_OS_UBUNTU) \ GOSL(STR_OS_UBUNTU "-64", GUEST_OS_OTHER26XLINUX_64) \ GOSL("oes", GUEST_OS_OTHER26XLINUX) \ GOSL("os2", GUEST_OS_OS2) \ GOSL("os2experimental", GUEST_OS_OS2) \ GOSL("netware4", GUEST_OS_NETWARE4) \ GOSL("netware5", GUEST_OS_NETWARE5) \ GOSL("netware6", GUEST_OS_NETWARE6) \ GOSL(STR_OS_MACOS, GUEST_OS_DARWIN9) \ GOSL(STR_OS_MACOS "-64", GUEST_OS_DARWIN9_64) \ GOSL(STR_OS_MACOS "10", GUEST_OS_DARWIN10) \ GOSL(STR_OS_MACOS "10-64", GUEST_OS_DARWIN10_64) \ GOSL(STR_OS_MACOS "11", GUEST_OS_DARWIN11) \ GOSL(STR_OS_MACOS "11-64", GUEST_OS_DARWIN11_64) \ GOSL(STR_OS_MACOS "12-64", GUEST_OS_DARWIN12_64) \ GOSL(STR_OS_MACOS "13-64", GUEST_OS_DARWIN13_64) \ GOSL("other", GUEST_OS_OTHER) \ GOSL("other-64", GUEST_OS_OTHER_64) \ GOSL("vmkernel", GUEST_OS_VMKERNEL) \ GOSL("vmkernel5", GUEST_OS_VMKERNEL5) \ GOSL("openserver5", GUEST_OS_OPENSERVER_5_AND_6) \ GOSL("openserver6", GUEST_OS_OPENSERVER_5_AND_6) \ GOSL("unixware7", GUEST_OS_UNIXWARE7) \ GOSL(STR_OS_ECOMSTATION, GUEST_OS_ECOMSTATION) \ GOSL(STR_OS_ECOMSTATION "2", GUEST_OS_ECOMSTATION2) \ GOSL(STR_OS_WIN_EIGHT, GUEST_OS_WINEIGHT) \ GOSL(STR_OS_WIN_EIGHT_X64, GUEST_OS_WINEIGHT_64) \ GOSL(STR_OS_WIN_EIGHTSERVER_X64, GUEST_OS_WINEIGHTSERVER_64) \ GOSL(STR_OS_HYPER_V, GUEST_OS_HYPER_V) \ #endif open-vm-tools-9.4.0-1280544/lib/include/loglevel_user.h0000644765153500003110000001774312220061556020664 0ustar dtormts/********************************************************* * Copyright (C) 1998-2003 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ #ifndef _LOGLEVEL_USER_H_ #define _LOGLEVEL_USER_H_ #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #define LOGLEVEL_EXTENSION user #include "loglevel_defs.h" #define LOGLEVEL_USER(LOGLEVEL_VAR) \ /* user/main*/ \ /* main has to be first. */ \ LOGLEVEL_VAR(main), \ LOGLEVEL_VAR(aio), \ LOGLEVEL_VAR(passthrough), \ LOGLEVEL_VAR(tools), \ LOGLEVEL_VAR(license), \ LOGLEVEL_VAR(vui), \ LOGLEVEL_VAR(stats), \ LOGLEVEL_VAR(cpucount), \ LOGLEVEL_VAR(ovhdmem), \ LOGLEVEL_VAR(vigor), \ \ /* user/io */ \ LOGLEVEL_VAR(disk), \ LOGLEVEL_VAR(keyboard), \ LOGLEVEL_VAR(vmmouse), \ LOGLEVEL_VAR(timer), \ LOGLEVEL_VAR(vga), \ LOGLEVEL_VAR(svga), \ LOGLEVEL_VAR(svga_rect), \ LOGLEVEL_VAR(enableDetTimer), \ LOGLEVEL_VAR(dma), \ LOGLEVEL_VAR(floppy), \ LOGLEVEL_VAR(cmos), \ LOGLEVEL_VAR(vlance), \ LOGLEVEL_VAR(e1000), \ LOGLEVEL_VAR(serial), \ LOGLEVEL_VAR(parallel), \ LOGLEVEL_VAR(chipset), \ LOGLEVEL_VAR(smc), \ LOGLEVEL_VAR(ich7m), \ LOGLEVEL_VAR(hpet), \ LOGLEVEL_VAR(extcfgdevice), \ LOGLEVEL_VAR(flashram), \ LOGLEVEL_VAR(efinv), \ LOGLEVEL_VAR(pvnvram), \ LOGLEVEL_VAR(pci), \ LOGLEVEL_VAR(pci_vide), \ LOGLEVEL_VAR(pci_uhci), \ LOGLEVEL_VAR(uhci), \ LOGLEVEL_VAR(pci_ehci), \ LOGLEVEL_VAR(ehci), \ LOGLEVEL_VAR(pci_xhci), \ LOGLEVEL_VAR(usb_xhci), \ LOGLEVEL_VAR(usb), \ LOGLEVEL_VAR(vusbmouse), \ LOGLEVEL_VAR(vusbkeyboard), \ LOGLEVEL_VAR(vusbhid), \ LOGLEVEL_VAR(vusbtablet), \ LOGLEVEL_VAR(vusbaudio), \ LOGLEVEL_VAR(hidQueue), \ LOGLEVEL_VAR(pci_1394), \ LOGLEVEL_VAR(1394), \ LOGLEVEL_VAR(pci_vlance), \ LOGLEVEL_VAR(pci_svga), \ LOGLEVEL_VAR(pci_e1000), \ LOGLEVEL_VAR(pci_hyper), \ LOGLEVEL_VAR(pcibridge), \ LOGLEVEL_VAR(vide), \ LOGLEVEL_VAR(atapiCdrom), \ LOGLEVEL_VAR(hostonly), \ LOGLEVEL_VAR(oprom), \ LOGLEVEL_VAR(http), \ LOGLEVEL_VAR(vmci), \ LOGLEVEL_VAR(pci_vmci), \ LOGLEVEL_VAR(vmxnet3), \ LOGLEVEL_VAR(pci_vmxnet3), \ LOGLEVEL_VAR(vcpuhotplug), \ LOGLEVEL_VAR(vcpuNUMA), \ LOGLEVEL_VAR(heci), \ LOGLEVEL_VAR(vmiopluginlib), \ \ /* user/disk */ \ LOGLEVEL_VAR(aioMgr), \ LOGLEVEL_VAR(aioWin32), \ LOGLEVEL_VAR(aioWin32Completion), \ LOGLEVEL_VAR(aioLinux), \ LOGLEVEL_VAR(aioHttp), \ LOGLEVEL_VAR(aioGeneric), \ LOGLEVEL_VAR(cdrom), \ LOGLEVEL_VAR(checksum), \ \ /* user/checkpoint */ \ LOGLEVEL_VAR(checkpoint), \ LOGLEVEL_VAR(dumper), \ LOGLEVEL_VAR(migrate), \ LOGLEVEL_VAR(fsresx), \ \ /* user/gui */ \ LOGLEVEL_VAR(gui), \ LOGLEVEL_VAR(guiWin32), \ LOGLEVEL_VAR(mks), \ LOGLEVEL_VAR(mksSWB), \ LOGLEVEL_VAR(mksClient), \ LOGLEVEL_VAR(mksServer), \ LOGLEVEL_VAR(mksKeyboard), \ LOGLEVEL_VAR(keymap), \ LOGLEVEL_VAR(mksMouse), \ LOGLEVEL_VAR(mksHostCursor), \ LOGLEVEL_VAR(mksCursorPosition), \ LOGLEVEL_VAR(mksHostOps), \ LOGLEVEL_VAR(mksGLManager), \ LOGLEVEL_VAR(mksGLFBO), \ LOGLEVEL_VAR(mksGLShader), \ LOGLEVEL_VAR(mksGLState), \ LOGLEVEL_VAR(mksGLWindow), \ LOGLEVEL_VAR(vdpPlugin), \ \ /* user/sound */ \ LOGLEVEL_VAR(sound), \ LOGLEVEL_VAR(hdaudio), \ LOGLEVEL_VAR(pci_hdaudio), \ LOGLEVEL_VAR(hdaudio_alsa), \ \ /* user/disklib */ \ LOGLEVEL_VAR(disklib), \ LOGLEVEL_VAR(dmg), \ LOGLEVEL_VAR(sparseChecker), \ LOGLEVEL_VAR(dataCache), \ /* more */ \ LOGLEVEL_VAR(dict), \ LOGLEVEL_VAR(pci_scsi), \ LOGLEVEL_VAR(scsi), \ LOGLEVEL_VAR(grm), \ LOGLEVEL_VAR(vmxnet), \ LOGLEVEL_VAR(pciPassthru), \ LOGLEVEL_VAR(vnet), \ LOGLEVEL_VAR(netPkt), \ LOGLEVEL_VAR(macfilter), \ LOGLEVEL_VAR(macbw), \ LOGLEVEL_VAR(macfi), \ LOGLEVEL_VAR(vmkcfg), \ LOGLEVEL_VAR(poll), \ LOGLEVEL_VAR(barrier), \ LOGLEVEL_VAR(mstat), \ LOGLEVEL_VAR(vmLock), \ LOGLEVEL_VAR(buslogic), \ LOGLEVEL_VAR(lsilogic), \ LOGLEVEL_VAR(pvscsi), \ LOGLEVEL_VAR(ahci), \ LOGLEVEL_VAR(diskVmnix), \ LOGLEVEL_VAR(hbaCommon), \ LOGLEVEL_VAR(backdoor), \ LOGLEVEL_VAR(buslogicMdev), \ LOGLEVEL_VAR(hgfs), \ LOGLEVEL_VAR(memspace), \ LOGLEVEL_VAR(dnd), \ LOGLEVEL_VAR(appstate), \ LOGLEVEL_VAR(vthread), \ LOGLEVEL_VAR(vmhs), \ LOGLEVEL_VAR(undopoint), \ LOGLEVEL_VAR(ipc), \ LOGLEVEL_VAR(smbios), \ LOGLEVEL_VAR(acpi), \ LOGLEVEL_VAR(acpiGPE), \ LOGLEVEL_VAR(vmgenc), \ LOGLEVEL_VAR(xpmode), \ LOGLEVEL_VAR(snapshot), \ LOGLEVEL_VAR(asyncsocket), \ LOGLEVEL_VAR(mainMem), \ LOGLEVEL_VAR(mainMemReplayCheck), \ LOGLEVEL_VAR(memoryHotplug), \ LOGLEVEL_VAR(numa), \ LOGLEVEL_VAR(numaHost), \ LOGLEVEL_VAR(remoteDevice), \ LOGLEVEL_VAR(vncDecode), \ LOGLEVEL_VAR(vncEncode), \ LOGLEVEL_VAR(libconnect), \ LOGLEVEL_VAR(state3d), \ LOGLEVEL_VAR(vmGL), \ LOGLEVEL_VAR(guest_msg), \ LOGLEVEL_VAR(guest_rpc), \ LOGLEVEL_VAR(guestVars), \ LOGLEVEL_VAR(vmkEvent), \ LOGLEVEL_VAR(battery), \ LOGLEVEL_VAR(fakeDma), \ LOGLEVEL_VAR(shader), \ LOGLEVEL_VAR(machPoll), \ LOGLEVEL_VAR(replayVMX), \ LOGLEVEL_VAR(vmWindowController), \ LOGLEVEL_VAR(dui), \ LOGLEVEL_VAR(duiMKS), \ LOGLEVEL_VAR(worker), \ LOGLEVEL_VAR(duiDevices), \ LOGLEVEL_VAR(duiLocalization), \ LOGLEVEL_VAR(duiProxyApps), \ LOGLEVEL_VAR(docker), \ LOGLEVEL_VAR(vmIPC), \ LOGLEVEL_VAR(uwt), /* lib/unityWindowTracker */ \ LOGLEVEL_VAR(cui), \ LOGLEVEL_VAR(automation), \ LOGLEVEL_VAR(oemDevice), \ LOGLEVEL_VAR(cptOps), \ LOGLEVEL_VAR(VProbeExec), \ LOGLEVEL_VAR(VP), \ LOGLEVEL_VAR(device), \ LOGLEVEL_VAR(devicePowerOn), \ LOGLEVEL_VAR(vmxvmdbCallbacks), \ LOGLEVEL_VAR(guestInstall), \ LOGLEVEL_VAR(migrateVM), \ LOGLEVEL_VAR(vmUpsellController), \ LOGLEVEL_VAR(objc), /* lib/objc */ \ LOGLEVEL_VAR(blit), /* lib/blit */ \ LOGLEVEL_VAR(vmnetBridge), \ LOGLEVEL_VAR(wifi), /* macWireless and wpa_supplicant */ \ LOGLEVEL_VAR(pvfslib), \ LOGLEVEL_VAR(brtalk), \ LOGLEVEL_VAR(button), \ LOGLEVEL_VAR(util), \ LOGLEVEL_VAR(vmcf), \ LOGLEVEL_VAR(win32util), \ LOGLEVEL_VAR(largepage), \ LOGLEVEL_VAR(guestAppMonitor), \ LOGLEVEL_VAR(syncWaitQ), \ LOGLEVEL_VAR(sg), /* lib/sg */ \ LOGLEVEL_VAR(ftcpt), \ LOGLEVEL_VAR(wrapLib), \ LOGLEVEL_VAR(digestlib), \ LOGLEVEL_VAR(inputdevtap), \ LOGLEVEL_VAR(objlib), \ LOGLEVEL_VAR(vsanobj), \ LOGLEVEL_VAR(svgadevtap), \ LOGLEVEL_VAR(masReceipt), /* lib/masReceipt */ \ LOGLEVEL_VAR(serviceImpl), /* lib/serviceImpl */ \ LOGLEVEL_VAR(serviceUser), /* lib/serviceUser */ \ LOGLEVEL_VAR(ssl), \ LOGLEVEL_VAR(vmrc), \ LOGLEVEL_VAR(namespaceDb), \ LOGLEVEL_VAR(namespaceMgr), \ LOGLEVEL_VAR(blobMgr), \ LOGLEVEL_VAR(vblobbe), \ LOGLEVEL_VAR(blobFileBE), \ LOGLEVEL_VAR(blobPythonBE), \ LOGLEVEL_VAR(grainTrack), \ LOGLEVEL_VAR(shim3D), \ LOGLEVEL_VAR(crc32), \ LOGLEVEL_VAR(vmkmgmtlib), \ LOGLEVEL_VAR(vflash), \ LOGLEVEL_VAR(vva), /* apps/rde/vva */ \ LOGLEVEL_VAR(ftConfig), /*lib/ftConfig */ \ LOGLEVEL_VAR(vmname), /* lib/vmname */ \ /* end of list */ LOGLEVEL_EXTENSION_DECLARE(LOGLEVEL_USER); #endif /* _LOGLEVEL_USER_H_ */ open-vm-tools-9.4.0-1280544/lib/include/vmci_sockets.h0000644765153500003110000005645312220061556020507 0ustar dtormts/********************************************************* * Copyright (C) 2007-2012 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vmci_sockets.h -- * * VMCI sockets public constants and types. */ #ifndef _VMCI_SOCKETS_H_ #define _VMCI_SOCKETS_H_ #if defined(_WIN32) # if !defined(NT_INCLUDED) # include # endif // !NT_INCLUDED #else // _WIN32 #if defined(linux) && !defined(VMKERNEL) # if !defined(__KERNEL__) # include # endif // __KERNEL__ #else // linux && !VMKERNEL # if defined(__APPLE__) # include # include # endif // __APPLE__ #endif // linux && !VMKERNEL #endif /** * \brief Option name for STREAM socket buffer size. * * Use as the option name in \c setsockopt(3) or \c getsockopt(3) to set * or get an \c unsigned \c long \c long that specifies the size of the * buffer underlying a vSockets STREAM socket. * * \note Value is clamped to the MIN and MAX. * * \see VMCISock_GetAFValueFd() * \see SO_VMCI_BUFFER_MIN_SIZE * \see SO_VMCI_BUFFER_MAX_SIZE * * An example is given below. * * \code * int vmciFd; * int af = VMCISock_GetAFValueFd(&vmciFd); * unsigned long long val = 0x1000; * int fd = socket(af, SOCK_STREAM, 0); * setsockopt(fd, af, SO_VMCI_BUFFER_SIZE, &val, sizeof val); * ... * close(fd); * VMCISock_ReleaseAFValueFd(vmciFd); * \endcode */ #define SO_VMCI_BUFFER_SIZE 0 /** * \brief Option name for STREAM socket minimum buffer size. * * Use as the option name in \c setsockopt(3) or \c getsockopt(3) to set * or get an \c unsigned \c long \c long that specifies the minimum size * allowed for the buffer underlying a vSockets STREAM socket. * * \see VMCISock_GetAFValueFd() * \see SO_VMCI_BUFFER_SIZE * \see SO_VMCI_BUFFER_MAX_SIZE * * An example is given below. * * \code * int vmciFd; * int af = VMCISock_GetAFValueFd(&vmciFd); * unsigned long long val = 0x500; * int fd = socket(af, SOCK_STREAM, 0); * setsockopt(fd, af, SO_VMCI_BUFFER_MIN_SIZE, &val, sizeof val); * ... * close(fd); * VMCISock_ReleaseAFValueFd(vmciFd); * \endcode */ #define SO_VMCI_BUFFER_MIN_SIZE 1 /** * \brief Option name for STREAM socket maximum buffer size. * * Use as the option name in \c setsockopt(3) or \c getsockopt(3) to set or * get an unsigned long long that specifies the maximum size allowed for the * buffer underlying a vSockets STREAM socket. * * \see VMCISock_GetAFValueFd() * \see SO_VMCI_BUFFER_SIZE * \see SO_VMCI_BUFFER_MIN_SIZE * * An example is given below. * * \code * int vmciFd; * int af = VMCISock_GetAFValueFd(&vmciFd); * unsigned long long val = 0x4000; * int fd = socket(af, SOCK_STREAM, 0); * setsockopt(fd, af, SO_VMCI_BUFFER_MAX_SIZE, &val, sizeof val); * ... * close(fd); * VMCISock_ReleaseAFValueFd(vmciFd); * \endcode */ #define SO_VMCI_BUFFER_MAX_SIZE 2 /** * \brief Option name for socket peer's host-specific VM ID. * * Use as the option name in \c getsockopt(3) to get a host-specific identifier * for the peer endpoint's VM. The identifier is a signed integer. * * \note Only available for ESX (VMKernel/userworld) endpoints. * * An example is given below. * * \code * int vmciFd; * int af = VMCISock_GetAFValueFd(&vmciFd); * int id; * socklen_t len = sizeof id; * int fd = socket(af, SOCK_DGRAM, 0); * getsockopt(fd, af, SO_VMCI_PEER_HOST_VM_ID, &id, &len); * ... * close(fd); * VMCISock_ReleaseAFValueFd(vmciFd); * \endcode */ #define SO_VMCI_PEER_HOST_VM_ID 3 /** * \brief Option name for socket's service label. * * Use as the option name in \c setsockopt(3) or \c getsockopt(3) to set or * get the service label for a socket. The service label is a C-style * NUL-terminated string. * * \note Only available for ESX (VMkernel/userworld) endpoints. */ #define SO_VMCI_SERVICE_LABEL 4 /** * \brief Option name for determining if a socket is trusted. * * Use as the option name in \c getsockopt(3) to determine if a socket is * trusted. The value is a signed integer. * * An example is given below. * * \code * int vmciFd; * int af = VMCISock_GetAFValueFd(&vmciFd); * int trusted; * socklen_t len = sizeof trusted; * int fd = socket(af, SOCK_DGRAM, 0); * getsockopt(fd, af, SO_VMCI_TRUSTED, &trusted, &len); * ... * close(fd); * VMCISock_ReleaseAFValueFd(vmciFd); * \endcode */ #define SO_VMCI_TRUSTED 5 /** * \brief Option name for STREAM socket connection timeout. * * Use as the option name in \c setsockopt(3) or \c getsockopt(3) to set or * get the connection timeout for a STREAM socket. The value is platform * dependent. On ESX, Linux and Mac OS, it is a \c struct \c timeval. * On Windows, it is a \c DWORD. * * An example is given below. * * \code * int vmciFd; * int af = VMCISock_GetAFValueFd(&vmciFd); * struct timeval t = { 5, 100000 }; // 5.1 seconds * int fd = socket(af, SOCK_STREAM, 0); * setsockopt(fd, af, SO_VMCI_CONNECT_TIMEOUT, &t, sizeof t); * ... * close(fd); * VMCISock_ReleaseAFValueFd(vmciFd); * \endcode */ #define SO_VMCI_CONNECT_TIMEOUT 6 /** * \brief Option name for using non-blocking send/receive. * * Use as the option name for \c setsockopt(3) or \c getsockopt(3) to set or * get the non-blocking transmit/receive flag for a STREAM socket. This flag * determines whether \c send() and \c recv() can be called in non-blocking * contexts for the given socket. The value is a signed integer. * * This option is only relevant to kernel endpoints, where descheduling * the thread of execution is not allowed, for example, while holding a * spinlock. It is not to be confused with conventional non-blocking socket * operations. * * \note Only available for VMKernel endpoints. * * An example is given below. * * \code * int vmciFd; * int af = VMCISock_GetAFValueFd(&vmciFd); * int nonblock; * socklen_t len = sizeof nonblock; * int fd = socket(af, SOCK_STREAM, 0); * getsockopt(fd, af, SO_VMCI_NONBLOCK_TXRX, &nonblock, &len); * ... * close(fd); * VMCISock_ReleaseAFValueFd(vmciFd); * \endcode */ #define SO_VMCI_NONBLOCK_TXRX 7 /** * \brief The vSocket equivalent of INADDR_ANY. * * This works for the \c svm_cid field of sockaddr_vm and indicates the * context ID of the current endpoint. * * \see sockaddr_vm * * An example is given below. * * \code * int vmciFd; * int af = VMCISock_GetAFValueFd(&vmciFd); * struct sockaddr_vm addr; * int fd = socket(af, SOCK_DGRAM, 0); * addr.svm_family = af; * addr.svm_cid = VMADDR_CID_ANY; * addr.svm_port = 2000; * bind(fd, &addr, sizeof addr); * ... * close(fd); * VMCISock_ReleaseAFValueFd(vmciFd); * \endcode */ #define VMADDR_CID_ANY ((unsigned int)-1) /** * \brief Bind to any available port. * * Works for the \c svm_port field of sockaddr_vm. * * \see sockaddr_vm * * An example is given below. * * \code * int vmciFd; * int af = VMCISock_GetAFValueFd(&vmciFd); * struct sockaddr_vm addr; * int fd = socket(af, SOCK_DGRAM, 0); * addr.svm_family = af; * addr.svm_cid = VMADDR_CID_ANY; * addr.svm_port = VMADDR_PORT_ANY; * bind(fd, &addr, sizeof addr); * ... * close(fd); * VMCISock_ReleaseAFValueFd(vmciFd); * \endcode */ #define VMADDR_PORT_ANY ((unsigned int)-1) /** * \brief Invalid vSockets version. * * \see VMCISock_Version() */ #define VMCI_SOCKETS_INVALID_VERSION ((unsigned int)-1) /** * \brief The epoch (first) component of the vSockets version. * * A single byte representing the epoch component of the vSockets version. * * \see VMCISock_Version() * * An example is given below. * * \code * unsigned int ver = VMCISock_Version(); * unsigned char epoch = VMCI_SOCKETS_VERSION_EPOCH(ver); * \endcode */ #define VMCI_SOCKETS_VERSION_EPOCH(_v) (((_v) & 0xFF000000) >> 24) /** * \brief The major (second) component of the vSockets version. * * A single byte representing the major component of the vSockets version. * Typically changes for every major release of a product. * * \see VMCISock_Version() * * An example is given below. * * \code * unsigned int ver = VMCISock_Version(); * unsigned char major = VMCI_SOCKETS_VERSION_MAJOR(ver); * \endcode */ #define VMCI_SOCKETS_VERSION_MAJOR(_v) (((_v) & 0x00FF0000) >> 16) /** * \brief The minor (third) component of the vSockets version. * * Two bytes representing the minor component of the vSockets version. * * \see VMCISock_Version() * * An example is given below. * * \code * unsigned int ver = VMCISock_Version(); * unsigned short minor = VMCI_SOCKETS_VERSION_MINOR(ver); * \endcode */ #define VMCI_SOCKETS_VERSION_MINOR(_v) (((_v) & 0x0000FFFF)) /** \cond PRIVATE */ #if defined(_WIN32) || defined(VMKERNEL) typedef unsigned short sa_family_t; #endif // _WIN32 #if defined(VMKERNEL) struct sockaddr { sa_family_t sa_family; char sa_data[14]; }; #endif /** \endcond */ /** * \brief Address structure for vSockets. * * The address family should be set to whatever VMCISock_GetAFValueFd() * returns. The structure members should all align on their natural * boundaries without resorting to compiler packing directives. The total * size of this structure should be exactly the same as that of \c struct * \c sockaddr. * * \see VMCISock_GetAFValueFd() */ struct sockaddr_vm { #if defined(__APPLE__) unsigned char svm_len; #endif // __APPLE__ /** \brief Address family. \see VMCISock_GetAFValueFd() */ sa_family_t svm_family; /** \cond PRIVATE */ unsigned short svm_reserved1; /** \endcond */ /** \brief Port. \see VMADDR_PORT_ANY */ unsigned int svm_port; /** \brief Context ID. \see VMADDR_CID_ANY */ unsigned int svm_cid; /** \cond PRIVATE */ unsigned char svm_zero[sizeof(struct sockaddr) - #if defined(__APPLE__) sizeof(unsigned char) - #endif // __APPLE__ sizeof(sa_family_t) - sizeof(unsigned short) - sizeof(unsigned int) - sizeof(unsigned int)]; /** \endcond */ }; /** \cond PRIVATE */ struct uuid_2_cid { unsigned int u2c_context_id; unsigned int u2c_pad; char u2c_uuid_string[128]; }; /** \endcond */ #if defined(_WIN32) # if !defined(NT_INCLUDED) # include # define VMCI_SOCKETS_DEVICE L"\\\\.\\VMCI" # define VMCI_SOCKETS_VERSION 0x81032058 # define VMCI_SOCKETS_GET_AF_VALUE 0x81032068 # define VMCI_SOCKETS_GET_LOCAL_CID 0x8103206c # define VMCI_SOCKETS_UUID_2_CID 0x810320a4 static __inline unsigned int __VMCISock_DeviceIoControl(DWORD cmd) { unsigned int val = (unsigned int)-1; HANDLE device = CreateFileW(VMCI_SOCKETS_DEVICE, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (INVALID_HANDLE_VALUE != device) { DWORD ioReturn; DeviceIoControl(device, cmd, &val, sizeof val, &val, sizeof val, &ioReturn, NULL); CloseHandle(device); device = INVALID_HANDLE_VALUE; } return val; } static __inline unsigned int VMCISock_Version(void) { return __VMCISock_DeviceIoControl(VMCI_SOCKETS_VERSION); } static __inline int VMCISock_GetAFValue(void) { return (int)__VMCISock_DeviceIoControl(VMCI_SOCKETS_GET_AF_VALUE); } static __inline int VMCISock_GetAFValueFd(int *outFd) { (void)outFd; /* Unused parameter. */ return VMCISock_GetAFValue(); } static __inline void VMCISock_ReleaseAFValueFd(int fd) { (void)fd; /* Unused parameter. */ } static __inline unsigned int VMCISock_GetLocalCID(void) { return __VMCISock_DeviceIoControl(VMCI_SOCKETS_GET_LOCAL_CID); } static __inline unsigned int VMCISock_Uuid2ContextId(const char *uuidString) { struct uuid_2_cid io; HANDLE device = CreateFileW(VMCI_SOCKETS_DEVICE, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); io.u2c_context_id = VMADDR_CID_ANY; if (INVALID_HANDLE_VALUE != device) { DWORD ioReturn; strncpy_s(io.u2c_uuid_string, sizeof io.u2c_uuid_string, uuidString, _TRUNCATE); DeviceIoControl(device, VMCI_SOCKETS_UUID_2_CID, &io, sizeof io, &io, sizeof io, &ioReturn, NULL); CloseHandle(device); device = INVALID_HANDLE_VALUE; } return io.u2c_context_id; } # endif // !NT_INCLUDED #else // _WIN32 #if (defined(linux) && !defined(VMKERNEL)) || (defined(__APPLE__)) # if defined(linux) && defined(__KERNEL__) void VMCISock_KernelRegister(void); void VMCISock_KernelDeregister(void); int VMCISock_GetAFValue(void); int VMCISock_GetLocalCID(void); # elif defined(__APPLE__) && (KERNEL) /* Nothing to define here. */ # else // __KERNEL__ # include # include # include # include # include # include # include /** \cond PRIVATE */ # define VMCI_SOCKETS_DEFAULT_DEVICE "/dev/vsock" # define VMCI_SOCKETS_CLASSIC_ESX_DEVICE "/vmfs/devices/char/vsock/vsock" # if defined(linux) # define VMCI_SOCKETS_VERSION 1972 # define VMCI_SOCKETS_GET_AF_VALUE 1976 # define VMCI_SOCKETS_GET_LOCAL_CID 1977 # define VMCI_SOCKETS_UUID_2_CID 1991 # elif defined(__APPLE__) # include # define VMCI_SOCKETS_VERSION _IOR( 'V', 21, unsigned) # define VMCI_SOCKETS_GET_AF_VALUE _IOR( 'V', 25, int) # define VMCI_SOCKETS_GET_LOCAL_CID _IOR( 'V', 26, unsigned) # define VMCI_SOCKETS_UUID_2_CID _IOWR('V', 40, struct uuid_2_cid) #endif /** \endcond */ /* *********************************************************************** * VMCISock_Version */ /** * * \brief Retrieve the vSockets version. * * Returns the current version of vSockets. The version is a 32-bit * unsigned integer that consist of three components: the epoch, the * major version, and the minor version. Use the \c VMCI_SOCKETS_VERSION * macros to extract the components. * * \see VMCI_SOCKETS_VERSION_EPOCH() * \see VMCI_SOCKETS_VERSION_MAJOR() * \see VMCI_SOCKETS_VERSION_MINOR() * * \retval VMCI_SOCKETS_INVALID_VERSION Not available. * \retval other The current version. * * An example is given below. * * \code * unsigned int ver = VMCISock_Version(); * if (ver != VMCI_SOCKETS_INVALID_VERSION) { * printf("vSockets version=%d.%d.%d\n", * VMCI_SOCKETS_VERSION_EPOCH(ver), * VMCI_SOCKETS_VERSION_MAJOR(ver), * VMCI_SOCKETS_VERSION_MINOR(ver)); * } * \endcode * *********************************************************************** */ static inline unsigned int VMCISock_Version(void) { int fd; unsigned int version; fd = open(VMCI_SOCKETS_DEFAULT_DEVICE, O_RDWR); if (fd < 0) { fd = open(VMCI_SOCKETS_CLASSIC_ESX_DEVICE, O_RDWR); if (fd < 0) { return VMCI_SOCKETS_INVALID_VERSION; } } if (ioctl(fd, VMCI_SOCKETS_VERSION, &version) < 0) { version = VMCI_SOCKETS_INVALID_VERSION; } close(fd); return version; } /* *********************************************************************** * VMCISock_GetAFValueFd */ /** * * \brief Retrieve the address family value for vSockets. * * Returns the value to be used for the VMCI Sockets address family. * This value should be used as the domain argument to \c socket(2) (when * you might otherwise use \c AF_INET). For VMCI Socket-specific options, * this value should also be used for the level argument to * \c setsockopt(2) (when you might otherwise use \c SOL_TCP). * * \see VMCISock_ReleaseAFValueFd() * \see sockaddr_vm * * \param[out] outFd File descriptor to the VMCI device. The * address family value is valid until this * descriptor is closed. This parameter is * only valid if the return value is not -1. * Call VMCISock_ReleaseAFValueFd() to close * this descriptor. * * \retval -1 Not available. * \retval other The address family value. * * An example is given below. * * \code * int vmciFd; * int af = VMCISock_GetAFValueFd(&vmciFd); * if (af != -1) { * int fd = socket(af, SOCK_STREAM, 0); * ... * close(fd); * close(vmciFd); * } * \endcode * *********************************************************************** */ static inline int VMCISock_GetAFValueFd(int *outFd) { int fd; int family; fd = open(VMCI_SOCKETS_DEFAULT_DEVICE, O_RDWR); if (fd < 0) { fd = open(VMCI_SOCKETS_CLASSIC_ESX_DEVICE, O_RDWR); if (fd < 0) { return -1; } } if (ioctl(fd, VMCI_SOCKETS_GET_AF_VALUE, &family) < 0) { family = -1; } if (family < 0) { close(fd); } else if (outFd) { *outFd = fd; } return family; } /** \cond PRIVATE */ /* *********************************************************************** * VMCISock_GetAFValue */ /** * * \brief Retrieve the address family value for vSockets. * * Returns the value to be used for the VMCI Sockets address family. * This value should be used as the domain argument to \c socket(2) (when * you might otherwise use \c AF_INET). For VMCI Socket-specific options, * this value should also be used for the level argument to * \c setsockopt(2) (when you might otherwise use \c SOL_TCP). * * \note This function leaves its descriptor to the vsock device open so * that the socket implementation knows that the socket family is still in * use. This is done because the address family is registered with the * kernel on-demand and a notification is needed to unregister the address * family. Use of this function is thus discouraged; please use * VMCISock_GetAFValueFd() instead. * * \see VMCISock_GetAFValueFd() * \see sockaddr_vm * * \retval -1 Not available. * \retval other The address family value. * * An example is given below. * * \code * int af = VMCISock_GetAFValue(); * if (af != -1) { * int fd = socket(af, SOCK_STREAM, 0); * ... * close(fd); * } * \endcode * *********************************************************************** */ static inline int VMCISock_GetAFValue(void) { return VMCISock_GetAFValueFd(NULL); } /** \endcond PRIVATE */ /* *********************************************************************** * VMCISock_ReleaseAFValueFd */ /** * * \brief Release the file descriptor obtained when retrieving the * address family value. * * Use this to release the file descriptor obtained by calling * VMCISock_GetAFValueFd(). * * \see VMCISock_GetAFValueFd() * * \param[in] fd File descriptor to the VMCI device. * *********************************************************************** */ static inline void VMCISock_ReleaseAFValueFd(int fd) { if (fd >= 0) { close(fd); } } /* *********************************************************************** * VMCISock_GetLocalCID */ /** * * \brief Retrieve the current context ID. * * \see VMADDR_CID_ANY * * \retval VMADDR_CID_ANY Not available. * \retval other The current context ID. * * An example is given below. * * \code * int vmciFd; * int af = VMCISock_GetAFValueFd(&vmciFd); * struct sockaddr_vm addr; * addr.svm_family = af; * addr.svm_cid = VMCISock_GetLocalCID(); * VMCISock_ReleaseAFValueFd(vmciFd); * \endcode * *********************************************************************** */ static inline unsigned int VMCISock_GetLocalCID(void) { int fd; unsigned int contextId; fd = open(VMCI_SOCKETS_DEFAULT_DEVICE, O_RDWR); if (fd < 0) { fd = open(VMCI_SOCKETS_CLASSIC_ESX_DEVICE, O_RDWR); if (fd < 0) { return VMADDR_CID_ANY; } } if (ioctl(fd, VMCI_SOCKETS_GET_LOCAL_CID, &contextId) < 0) { contextId = VMADDR_CID_ANY; } close(fd); return contextId; } /* *********************************************************************** * VMCISock_Uuid2ContextId */ /** * * \brief Retrieve the context ID of a running VM, given a VM's UUID. * * Retrieves the context ID of a running virtual machine given that virtual * machines's unique identifier. The identifier is local to the host and * its meaning is platform-specific. On ESX, which is currently the only * supported platform, it is the "bios.uuid" field as specified in the VM's * VMX file. * * \see VMADDR_CID_ANY * * \retval VMADDR_CID_ANY Not available. * \retval other The VM's context ID. * * \note Only available for ESX (userworld) endpoints. * * An example is given below. * * \code * int vmciFd; * int af = VMCISock_GetAFValueFd(&vmciFd); * unsigned int cid = VMCISock_Uuid2ContextId( * "56 4d 07 d8 cc d5 c4 0d-98 44 dc 1e 8f e0 da f3"); * VMCISock_ReleaseAFValueFd(vmciFd); * \endcode * *********************************************************************** */ static inline unsigned int VMCISock_Uuid2ContextId(const char *uuidString) { int fd; struct uuid_2_cid io; fd = open(VMCI_SOCKETS_DEFAULT_DEVICE, O_RDWR); if (fd < 0) { fd = open(VMCI_SOCKETS_CLASSIC_ESX_DEVICE, O_RDWR); if (fd < 0) { return VMADDR_CID_ANY; } } strncpy(io.u2c_uuid_string, uuidString, sizeof io.u2c_uuid_string); if (ioctl(fd, VMCI_SOCKETS_UUID_2_CID, &io) < 0) { io.u2c_context_id = VMADDR_CID_ANY; } close(fd); return io.u2c_context_id; } # endif // __KERNEL__ #endif // linux && !VMKERNEL #endif // _WIN32 #endif // _VMCI_SOCKETS_H_ open-vm-tools-9.4.0-1280544/lib/include/mntinfo.h0000644765153500003110000001652612220061556017465 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * mntinfo.h -- * * Macros to abstract differences between structures and functions used in * accessing information about mounted file systems. * */ #ifndef __MNTINFO_H__ #define __MNTINFO_H__ #ifdef sun # include # include # include #elif defined(__linux__) # include #elif defined(__FreeBSD__) # include #endif #include "posix.h" /* *---------------------------------------------------------------------------- * * DECLARE_MNTINFO, MNTINFO * OPEN_MNTFILE, GETNEXT_MNTINFO, CLOSE_MNTFILE, * MNTINFO_NAME, MNTINFO_FSTYPE, MNTINFO_MNTPT -- * * Cross-platform macros for accessing information about the mounted file * systems. This is necessary since the interfaces for getmntent(3) are * slightly different on Linux and Solaris. * * DECLARE_MNTINFO() is used to declare the variable used when invoking * GETNEXT_MNTINFO(). MNTINFO is the type that can be used when passing * between functions. * * OPEN_MNTFILE() and CLOSE_MNTFILE() must be called before and after * a series of GETNEXT_MNTINFO() calls, respectively. GETNEXT_MNTINFO() is * called successively to retrieve information about the next mounted file * system. * * MNTINFO_NAME, MNTINFO_FSTYPE, and MNTINFO_MNTPT retrieve the name, file * system type, and mount point of the provided MNTINFO, respectively. * * MNTFILE is a string with the name of the file containing mount * information. * * Results: * OPEN_MNTFILE: MNTHANDLE on success, NULL on failure * GETNEXT_MNTINFO: on success, TRUE and mnt is filled with file system's * information; FALSE when no mounts left or on failure * CLOSE_MNTFILE: TRUE on success, FALSE on failure * * MNTINFO_NAME: mount's name on success, NULL on failure * MNTINFO_FSTYPE: mount's file system type on success, NULL on failure * MNTINFO_MNTPT: mount's mount point on success, NULL on failure * * Side effects: * None. * *---------------------------------------------------------------------------- */ #ifdef sun # define MNTFILE MNTTAB # define MNTHANDLE FILE * # define MNTINFO struct mnttab # define DECLARE_MNTINFO(name) struct mnttab __ ## name; \ struct mnttab *name = &__ ## name # define OPEN_MNTFILE(mode) Posix_Fopen(MNTFILE, mode) # define GETNEXT_MNTINFO(fp, mnt) (Posix_Getmntent(fp, mnt) == 0) # define CLOSE_MNTFILE(fp) (fclose(fp) == 0) # define MNTINFO_NAME(mnt) mnt->mnt_special # define MNTINFO_FSTYPE(mnt) mnt->mnt_fstype # define MNTINFO_MNTPT(mnt) mnt->mnt_mountp # define MNTINFO_MNT_IS_RO(mnt) (hasmntopt((mnt), "rw") == NULL) #elif defined(__linux__) # define MNTFILE MOUNTED # define MNTHANDLE FILE * # define MNTINFO struct mntent # define DECLARE_MNTINFO(name) struct mntent *name # define OPEN_MNTFILE(mode) Posix_Setmntent(MNTFILE, mode) # define GETNEXT_MNTINFO(fp, mnt) ((mnt = Posix_Getmntent(fp)) != NULL) # define CLOSE_MNTFILE(fp) (endmntent(fp) == 1) # define MNTINFO_NAME(mnt) mnt->mnt_fsname # define MNTINFO_FSTYPE(mnt) mnt->mnt_type # define MNTINFO_MNTPT(mnt) mnt->mnt_dir # define MNTINFO_MNT_IS_RO(mnt) (hasmntopt((mnt), "rw") == NULL) #elif defined(__FreeBSD__) || defined(__APPLE__) struct mntHandle { struct statfs *mountPoints; // array of mountpoints per getmntinfo(3) int numMountPoints; // number of elements in mntArray int mountIndex; // current location within mountPoints array }; # define MNTFILE _PATH_FSTAB # define MNTHANDLE struct mntHandle * # define MNTINFO struct statfs # define DECLARE_MNTINFO(name) struct statfs __ ## name; \ struct statfs *name = &__ ## name # define OPEN_MNTFILE(mode) \ ({ \ MNTHANDLE mntHandle; \ mntHandle = malloc(sizeof *mntHandle); \ if (mntHandle != NULL) { \ mntHandle->numMountPoints = getmntinfo(&mntHandle->mountPoints, \ MNT_NOWAIT); \ mntHandle->mountIndex = 0; \ } \ mntHandle; \ }) # define GETNEXT_MNTINFO(mntHandle, mnt) \ ({ \ /* Avoid multiple evaluations/expansions. */ \ MNTHANDLE thisHandle = (mntHandle); \ MNTINFO *thisMnt = (mnt); \ Bool boolVal = FALSE; \ ASSERT(thisHandle); \ if (thisHandle->mountIndex < thisHandle->numMountPoints) { \ memcpy(thisMnt, \ &thisHandle->mountPoints[thisHandle->mountIndex], \ sizeof *thisMnt); \ ++thisHandle->mountIndex; \ boolVal = TRUE; \ } \ boolVal; \ }) # define CLOSE_MNTFILE(mntHandle) \ ({ \ free(mntHandle); \ TRUE; \ }) # define MNTINFO_NAME(mnt) mnt->f_mntfromname # define MNTINFO_FSTYPE(mnt) mnt->f_fstypename # define MNTINFO_MNTPT(mnt) mnt->f_mntonname # define MNTINFO_MNT_IS_RO(mnt) ((mnt)->f_flags & MNT_RDONLY) #else # error "Define mount information macros for your OS type" #endif #endif /* __MNTINFO_H__ */ open-vm-tools-9.4.0-1280544/lib/include/hgfsProto.h0000644765153500003110000025363412220061556017771 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * hgfsProto.h -- * * Header file for data types and message formats used in the * Host/Guest File System (hgfs) protocol. */ #ifndef _HGFS_PROTO_H_ # define _HGFS_PROTO_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_DISTRIBUTE #include "includeCheck.h" #include "vm_basic_types.h" #include "hgfs.h" /* * Handle used by the server to identify files and searches. Used * by the driver to match server replies with pending requests. */ typedef uint32 HgfsHandle; #define HGFS_INVALID_HANDLE ((HgfsHandle)~((HgfsHandle)0)) /* * Opcodes for server operations. * * Changing the ordering of this enum will break the protocol; new ops * should be added at the end (but before HGFS_OP_MAX). */ typedef enum { HGFS_OP_OPEN, /* Open file */ HGFS_OP_READ, /* Read from file */ HGFS_OP_WRITE, /* Write to file */ HGFS_OP_CLOSE, /* Close file */ HGFS_OP_SEARCH_OPEN, /* Start new search */ HGFS_OP_SEARCH_READ, /* Get next search response */ HGFS_OP_SEARCH_CLOSE, /* End a search */ HGFS_OP_GETATTR, /* Get file attributes */ HGFS_OP_SETATTR, /* Set file attributes */ HGFS_OP_CREATE_DIR, /* Create new directory */ HGFS_OP_DELETE_FILE, /* Delete a file */ HGFS_OP_DELETE_DIR, /* Delete a directory */ HGFS_OP_RENAME, /* Rename a file or directory */ HGFS_OP_QUERY_VOLUME_INFO, /* Query volume information */ /* * The following operations are only available in version 2 of the hgfs * protocol. The corresponding version 1 opcodes above are deprecated. */ HGFS_OP_OPEN_V2, /* Open file */ HGFS_OP_GETATTR_V2, /* Get file attributes */ HGFS_OP_SETATTR_V2, /* Set file attributes */ HGFS_OP_SEARCH_READ_V2, /* Get next search response */ HGFS_OP_CREATE_SYMLINK, /* Create a symlink */ HGFS_OP_SERVER_LOCK_CHANGE, /* Change the oplock on a file */ HGFS_OP_CREATE_DIR_V2, /* Create a directory */ HGFS_OP_DELETE_FILE_V2, /* Delete a file */ HGFS_OP_DELETE_DIR_V2, /* Delete a directory */ HGFS_OP_RENAME_V2, /* Rename a file or directory */ /* * Operations for version 3, deprecating version 2 operations. */ HGFS_OP_OPEN_V3, /* Open file */ HGFS_OP_READ_V3, /* Read from file */ HGFS_OP_WRITE_V3, /* Write to file */ HGFS_OP_CLOSE_V3, /* Close file */ HGFS_OP_SEARCH_OPEN_V3, /* Start new search */ HGFS_OP_SEARCH_READ_V3, /* Read V3 directory entries */ HGFS_OP_SEARCH_CLOSE_V3, /* End a search */ HGFS_OP_GETATTR_V3, /* Get file attributes */ HGFS_OP_SETATTR_V3, /* Set file attributes */ HGFS_OP_CREATE_DIR_V3, /* Create new directory */ HGFS_OP_DELETE_FILE_V3, /* Delete a file */ HGFS_OP_DELETE_DIR_V3, /* Delete a directory */ HGFS_OP_RENAME_V3, /* Rename a file or directory */ HGFS_OP_QUERY_VOLUME_INFO_V3, /* Query volume information */ HGFS_OP_CREATE_SYMLINK_V3, /* Create a symlink */ HGFS_OP_SERVER_LOCK_CHANGE_V3, /* Change the oplock on a file */ HGFS_OP_WRITE_WIN32_STREAM_V3, /* Write WIN32_STREAM_ID format data to file */ /* * Operations for version 4, deprecating version 3 operations. */ HGFS_OP_CREATE_SESSION_V4, /* Create a session and return host capabilities. */ HGFS_OP_DESTROY_SESSION_V4, /* Destroy/close session. */ HGFS_OP_READ_FAST_V4, /* Read */ HGFS_OP_WRITE_FAST_V4, /* Write */ HGFS_OP_SET_WATCH_V4, /* Start monitoring directory changes. */ HGFS_OP_REMOVE_WATCH_V4, /* Stop monitoring directory changes. */ HGFS_OP_NOTIFY_V4, /* Notification for a directory change event. */ HGFS_OP_SEARCH_READ_V4, /* Read V4 directory entries. */ HGFS_OP_OPEN_V4, /* Open file */ HGFS_OP_ENUMERATE_STREAMS_V4, /* Enumerate alternative named streams for a file. */ HGFS_OP_GETATTR_V4, /* Get file attributes */ HGFS_OP_SETATTR_V4, /* Set file attributes */ HGFS_OP_DELETE_V4, /* Delete a file or a directory */ HGFS_OP_LINKMOVE_V4, /* Rename/move/create hard link. */ HGFS_OP_FSCTL_V4, /* Sending FS control requests. */ HGFS_OP_ACCESS_CHECK_V4, /* Flush all cached data to the disk. */ HGFS_OP_FSYNC_V4, /* Access check. */ HGFS_OP_QUERY_VOLUME_INFO_V4, /* Query volume information. */ HGFS_OP_OPLOCK_ACQUIRE_V4, /* Acquire OPLOCK. */ HGFS_OP_OPLOCK_BREAK_V4, /* Break or downgrade OPLOCK. */ HGFS_OP_LOCK_BYTE_RANGE_V4, /* Acquire byte range lock. */ HGFS_OP_UNLOCK_BYTE_RANGE_V4, /* Release byte range lock. */ HGFS_OP_QUERY_EAS_V4, /* Query extended attributes. */ HGFS_OP_SET_EAS_V4, /* Add or modify extended attributes. */ HGFS_OP_MAX, /* Dummy op, must be last in enum */ } HgfsOp; /* HGFS protocol versions. */ #define HGFS_VERSION_OLD (1 << 0) #define HGFS_VERSION_3 (1 << 1) /* If a V4 packet is being processed as a legacy packet it will have this opcode. */ #define HGFS_V4_LEGACY_OPCODE 0xff /* XXX: Needs change when VMCI is supported. */ #define HGFS_REQ_PAYLOAD_SIZE_V3(hgfsReq) (sizeof *hgfsReq + sizeof(HgfsRequest)) #define HGFS_REP_PAYLOAD_SIZE_V3(hgfsRep) (sizeof *hgfsRep + sizeof(HgfsReply)) /* XXX: Needs change when VMCI is supported. */ #define HGFS_REQ_GET_PAYLOAD_V3(hgfsReq) ((char *)(hgfsReq) + sizeof(HgfsRequest)) #define HGFS_REP_GET_PAYLOAD_V3(hgfsRep) ((char *)(hgfsRep) + sizeof(HgfsReply)) /* * File types, used in HgfsAttr. We support regular files, * directories, and symlinks. * * Changing the order of this enum will break the protocol; new types * should be added at the end. */ typedef enum { HGFS_FILE_TYPE_REGULAR, HGFS_FILE_TYPE_DIRECTORY, HGFS_FILE_TYPE_SYMLINK, } HgfsFileType; /* * Open flags. * * Changing the order of this enum will break stuff. Do not add any flags to * this enum: it has been frozen and all new flags should be added to * HgfsOpenMode. This was done because HgfsOpenMode could still be converted * to a bitmask (so that it's easier to add flags to) whereas this enum was * already too large. */ typedef enum { // File doesn't exist File exists HGFS_OPEN, // error HGFS_OPEN_EMPTY, // error size = 0 HGFS_OPEN_CREATE, // create HGFS_OPEN_CREATE_SAFE, // create error HGFS_OPEN_CREATE_EMPTY, // create size = 0 } HgfsOpenFlags; /* * Write flags. */ typedef uint8 HgfsWriteFlags; #define HGFS_WRITE_APPEND 1 /* * Permissions bits. * * These are intentionally similar to Unix permissions bits, and we * convert to/from Unix permissions using simple shift operations, so * don't change these or you will break things. */ typedef uint8 HgfsPermissions; #define HGFS_PERM_READ 4 #define HGFS_PERM_WRITE 2 #define HGFS_PERM_EXEC 1 /* * Access mode bits. * * Different operating systems have different set of file access mode. * Here are constants that are rich enough to describe all access modes in an OS * independent way. */ typedef uint32 HgfsAccessMode; /* * Generic access rights control coarse grain access for the file. * A particular generic rigth can be expanded into different set of specific rights * on different OS. */ /* * HGFS_MODE_GENERIC_READ means ability to read file data and read various file * attributes and properties. */ #define HGFS_MODE_GENERIC_READ (1 << 0) /* * HGFS_MODE_GENERIC_WRITE means ability to write file data and updaate various file * attributes and properties. */ #define HGFS_MODE_GENERIC_WRITE (1 << 1) /* * HGFS_MODE_GENERIC_EXECUE means ability to execute file. For network redirectors * ability to execute usualy implies ability to read data; for local file systems * HGFS_MODE_GENERIC_EXECUTE does not imply ability to read data. */ #define HGFS_MODE_GENERIC_EXECUTE (1 << 2) /* Specific rights define fine grain access modes. */ #define HGFS_MODE_READ_DATA (1 << 3) // Ability to read file data #define HGFS_MODE_WRITE_DATA (1 << 4) // Ability to writge file data #define HGFS_MODE_APPEND_DATA (1 << 5) // Appending data to the end of file #define HGFS_MODE_DELETE (1 << 6) // Ability to delete the file #define HGFS_MODE_TRAVERSE_DIRECTORY (1 << 7) // Ability to access files in a directory #define HGFS_MODE_LIST_DIRECTORY (1 << 8) // Ability to list file names #define HGFS_MODE_ADD_SUBDIRECTORY (1 << 9) // Ability to create a new subdirectory #define HGFS_MODE_ADD_FILE (1 << 10) // Ability to create a new file #define HGFS_MODE_DELETE_CHILD (1 << 11) // Ability to delete file/subdirectory #define HGFS_MODE_READ_ATTRIBUTES (1 << 12) // Ability to read attributes #define HGFS_MODE_WRITE_ATTRIBUTES (1 << 13) // Ability to write attributes #define HGFS_MODE_READ_EXTATTRIBUTES (1 << 14) // Ability to read extended attributes #define HGFS_MODE_WRITE_EXTATTRIBUTES (1 << 15) // Ability to write extended attributes #define HGFS_MODE_READ_SECURITY (1 << 16) // Ability to read permissions/ACLs/owner #define HGFS_MODE_WRITE_SECURITY (1 << 17) // Ability to change permissions/ACLs #define HGFS_MODE_TAKE_OWNERSHIP (1 << 18) // Ability to change file owner/group /* * Server-side locking (oplocks and leases). * * The client can ask the server to acquire opportunistic locking/leasing * from the host FS on its behalf. This is communicated as part of an open request. * * HGFS_LOCK_OPPORTUNISTIC means that the client trusts the server * to decide what kind of locking to request from the host FS. * All other values tell the server explicitly the type of lock to * request. * * The server will attempt to acquire the desired lock and will notify the client * which type of lock was acquired as part of the reply to the open request. * Note that HGFS_LOCK_OPPORTUNISTIC should not be specified as the type of * lock acquired by the server, since HGFS_LOCK_OPPORTUNISTIC is not an * actual lock. */ typedef enum { HGFS_LOCK_NONE, HGFS_LOCK_OPPORTUNISTIC, HGFS_LOCK_EXCLUSIVE, HGFS_LOCK_SHARED, } HgfsServerLock; /* * Flags to indicate in a setattr request which fields should be * updated. Deprecated. */ typedef uint8 HgfsAttrChanges; #define HGFS_ATTR_SIZE (1 << 0) #define HGFS_ATTR_CREATE_TIME (1 << 1) #define HGFS_ATTR_ACCESS_TIME (1 << 2) #define HGFS_ATTR_WRITE_TIME (1 << 3) #define HGFS_ATTR_CHANGE_TIME (1 << 4) #define HGFS_ATTR_PERMISSIONS (1 << 5) #define HGFS_ATTR_ACCESS_TIME_SET (1 << 6) #define HGFS_ATTR_WRITE_TIME_SET (1 << 7) /* * Hints to indicate in a getattr or setattr which attributes * are valid for the request. * For setattr only, attributes should be set by host even if * no valid values are specified by the guest. */ typedef uint64 HgfsAttrHint; #define HGFS_ATTR_HINT_SET_ACCESS_TIME (1 << 0) #define HGFS_ATTR_HINT_SET_WRITE_TIME (1 << 1) #define HGFS_ATTR_HINT_USE_FILE_DESC (1 << 2) /* * Hint to determine using a name or a handle to determine * what to delete. */ typedef uint64 HgfsDeleteHint; #define HGFS_DELETE_HINT_USE_FILE_DESC (1 << 0) /* * Hint to determine using a name or a handle to determine * what to renames. */ typedef uint64 HgfsRenameHint; #define HGFS_RENAME_HINT_USE_SRCFILE_DESC (1 << 0) #define HGFS_RENAME_HINT_USE_TARGETFILE_DESC (1 << 1) #define HGFS_RENAME_HINT_NO_REPLACE_EXISTING (1 << 2) #define HGFS_RENAME_HINT_NO_COPY_ALLOWED (1 << 3) /* * File attributes. * * The four time fields below are in Windows NT format, which is in * units of 100ns since Jan 1, 1601, UTC. */ /* * Version 1 attributes. Deprecated. * Version 2 should be using HgfsAttrV2. */ typedef #include "vmware_pack_begin.h" struct HgfsAttr { HgfsFileType type; /* File type */ uint64 size; /* File size (in bytes) */ uint64 creationTime; /* Creation time. Ignored by POSIX */ uint64 accessTime; /* Time of last access */ uint64 writeTime; /* Time of last write */ uint64 attrChangeTime; /* Time file attributess were last * changed. Ignored by Windows */ HgfsPermissions permissions; /* Permissions bits */ } #include "vmware_pack_end.h" HgfsAttr; /* Various flags and Windows attributes. */ typedef uint64 HgfsAttrFlags; #define HGFS_ATTR_HIDDEN (1 << 0) #define HGFS_ATTR_SYSTEM (1 << 1) #define HGFS_ATTR_ARCHIVE (1 << 2) #define HGFS_ATTR_HIDDEN_FORCED (1 << 3) #define HGFS_ATTR_REPARSE_POINT (1 << 4) /* V4 additional definitions for hgfsAttrFlags. */ #define HGFS_ATTR_COMPRESSED (1 << 5) #define HGFS_ATTR_ENCRYPTED (1 << 6) #define HGFS_ATTR_OFFLINE (1 << 7) #define HGFS_ATTR_READONLY (1 << 8) #define HGFS_ATTR_SPARSE (1 << 9) #define HGFS_ATTR_TEMPORARY (1 << 10) #define HGFS_ATTR_SEQUENTIAL_ONLY (1 << 11) /* * Specifies which open request fields contain * valid values. */ typedef uint64 HgfsOpenValid; #define HGFS_OPEN_VALID_NONE 0 #define HGFS_OPEN_VALID_MODE (1 << 0) #define HGFS_OPEN_VALID_FLAGS (1 << 1) #define HGFS_OPEN_VALID_SPECIAL_PERMS (1 << 2) #define HGFS_OPEN_VALID_OWNER_PERMS (1 << 3) #define HGFS_OPEN_VALID_GROUP_PERMS (1 << 4) #define HGFS_OPEN_VALID_OTHER_PERMS (1 << 5) #define HGFS_OPEN_VALID_FILE_ATTR (1 << 6) #define HGFS_OPEN_VALID_ALLOCATION_SIZE (1 << 7) #define HGFS_OPEN_VALID_DESIRED_ACCESS (1 << 8) #define HGFS_OPEN_VALID_SHARE_ACCESS (1 << 9) #define HGFS_OPEN_VALID_SERVER_LOCK (1 << 10) #define HGFS_OPEN_VALID_FILE_NAME (1 << 11) /* V4 additional open mask flags. */ #define HGFS_OPEN_VALID_EA (1 << 12) #define HGFS_OPEN_VALID_ACL (1 << 13) #define HGFS_OPEN_VALID_STREAM_NAME (1 << 14) /* * Specifies which attribute fields contain * valid values. */ typedef uint64 HgfsAttrValid; #define HGFS_ATTR_VALID_NONE 0 #define HGFS_ATTR_VALID_TYPE (1 << 0) #define HGFS_ATTR_VALID_SIZE (1 << 1) #define HGFS_ATTR_VALID_CREATE_TIME (1 << 2) #define HGFS_ATTR_VALID_ACCESS_TIME (1 << 3) #define HGFS_ATTR_VALID_WRITE_TIME (1 << 4) #define HGFS_ATTR_VALID_CHANGE_TIME (1 << 5) #define HGFS_ATTR_VALID_SPECIAL_PERMS (1 << 6) #define HGFS_ATTR_VALID_OWNER_PERMS (1 << 7) #define HGFS_ATTR_VALID_GROUP_PERMS (1 << 8) #define HGFS_ATTR_VALID_OTHER_PERMS (1 << 9) #define HGFS_ATTR_VALID_FLAGS (1 << 10) #define HGFS_ATTR_VALID_ALLOCATION_SIZE (1 << 11) #define HGFS_ATTR_VALID_USERID (1 << 12) #define HGFS_ATTR_VALID_GROUPID (1 << 13) #define HGFS_ATTR_VALID_FILEID (1 << 14) #define HGFS_ATTR_VALID_VOLID (1 << 15) /* * Add our file and volume identifiers. * NOTE: On Windows hosts, the file identifier is not guaranteed to be valid * particularly with FAT. A defrag operation could cause it to change. * Therefore, to not confuse older clients, and non-Windows * clients we have added a separate flag. * The Windows client will check for both flags for the * file ID, and return the information to the guest application. * However, it will use the ID internally, when it has an open * handle on the server. * Non-Windows clients need the file ID to be always guaranteed, * which is to say, that the ID remains constant over the course of the * file's lifetime, and will use the HGFS_ATTR_VALID_FILEID flag * only to determine if the ID is valid. */ #define HGFS_ATTR_VALID_NON_STATIC_FILEID (1 << 16) /* * File permissions that are in effect for the user which runs HGFS server. * Client needs to know effective permissions in order to implement access(2). * Client can't derive it from group/owner/other permissions because of two resaons: * 1. It does not know user/group id of the user which runs HGFS server * 2. Effective permissions account for additional restrictions that may be imposed * by host file system, for example by ACL. */ #define HGFS_ATTR_VALID_EFFECTIVE_PERMS (1 << 17) #define HGFS_ATTR_VALID_EXTEND_ATTR_SIZE (1 << 18) #define HGFS_ATTR_VALID_REPARSE_POINT (1 << 19) #define HGFS_ATTR_VALID_SHORT_NAME (1 << 20) /* * Specifies which create dir request fields contain * valid values. */ typedef uint64 HgfsCreateDirValid; #define HGFS_CREATE_DIR_VALID_NONE 0 #define HGFS_CREATE_DIR_VALID_SPECIAL_PERMS (1 << 0) #define HGFS_CREATE_DIR_VALID_OWNER_PERMS (1 << 1) #define HGFS_CREATE_DIR_VALID_GROUP_PERMS (1 << 2) #define HGFS_CREATE_DIR_VALID_OTHER_PERMS (1 << 3) #define HGFS_CREATE_DIR_VALID_FILE_NAME (1 << 4) #define HGFS_CREATE_DIR_VALID_FILE_ATTR (1 << 5) /* * Version 2 of HgfsAttr */ typedef #include "vmware_pack_begin.h" struct HgfsAttrV2 { HgfsAttrValid mask; /* A bit mask to determine valid attribute fields */ HgfsFileType type; /* File type */ uint64 size; /* File size (in bytes) */ uint64 creationTime; /* Creation time. Ignored by POSIX */ uint64 accessTime; /* Time of last access */ uint64 writeTime; /* Time of last write */ uint64 attrChangeTime; /* Time file attributes were last * changed. Ignored by Windows */ HgfsPermissions specialPerms; /* Special permissions bits (suid, etc.). * Ignored by Windows */ HgfsPermissions ownerPerms; /* Owner permissions bits */ HgfsPermissions groupPerms; /* Group permissions bits. Ignored by * Windows */ HgfsPermissions otherPerms; /* Other permissions bits. Ignored by * Windows */ HgfsAttrFlags flags; /* Various flags and Windows 'attributes' */ uint64 allocationSize; /* Actual size of file on disk */ uint32 userId; /* User identifier, ignored by Windows */ uint32 groupId; /* group identifier, ignored by Windows */ uint64 hostFileId; /* File Id of the file on host: inode_t on Linux */ uint32 volumeId; /* volume identifier, non-zero is valid. */ uint32 effectivePerms; /* Permissions in effect for the user on the host. */ uint64 reserved2; /* Reserved for future use */ } #include "vmware_pack_end.h" HgfsAttrV2; /* * Cross-platform filename representation * * Cross-platform (CP) names are represented by a string with each * path component separated by NULs, and terminated with a final NUL, * but with no leading path separator. * * For example, the representations of a POSIX and Windows name * are as follows, with "0" meaning NUL. * * Original name Cross-platform name * ----------------------------------------------------- * "/home/bac/temp" -> "home0bac0temp0" * "C:\temp\file.txt" -> "C0temp0file.txt0" * * Note that as in the example above, Windows should strip the colon * off of drive letters as part of the conversion. Aside from that, * all characters in each path component should be left unescaped and * unmodified. Each OS is responsible for escaping any characters that * are not legal in its filenames when converting FROM the CP name * format, and unescaping them when converting TO the CP name format. * * In some requests (OPEN, GETATTR, SETATTR, DELETE, CREATE_DIR) the * CP name is used to represent a particular file, but it is also used * to represent a search pattern for looking up files using * SEARCH_OPEN. * * In the current HGFS server implementation, each request has a minimum packet * size that must be met for it to be considered valid. This minimum is simply * the sizeof the particular request, which includes the solitary byte from the * HgfsFileName struct. For these particular requests, clients add an extra * byte to their payload size, without that byte being present anywhere. * * It isn't clear that this behavior is correct, but the end result is that * neither end malfunctions, as an extra byte gets sent by the client and is * ignored by the server. Unfortunately, it cannot be easily fixed. The * server's minimum packet size can be changed, but the client should continue * to send an extra byte, otherwise older servers with a slightly longer * minimum packet size may consider the new client's packets to be too short. * * UTF-8 representation * -------------------- * XXX: It is expected that file names in the HGFS protocol will be a valid UTF-8 * encoding. * See RFC 3629 (http://tools.ietf.org/html/rfc3629) * * Unicode Format * -------------- * HGFS protocol requests that contain file names as in the structure below, * should contain unicode normal form C (precomposed see explanation below) * characters therefore hosts such as Mac OS which * use HFS+ and unicode form D should convert names before * processing or sending HGFS requests. * * Precomposed (normal form C) versus Decomposed (normal form D) * ------------------------------------------------------------- * Certain Unicode characters can be encoded in more than one way. * For example, an (A acute) can be encoded either precomposed, * as U+00C1 (LATIN CAPITAL LETTER A WITH ACUTE), or decomposed, * as U+0041 U+0301 (LATIN CAPITAL LETTER A followed by a COMBINING ACUTE ACCENT). * Precomposed characters are more common in the Windows world, * whereas decomposed characters are more common on the Mac. * * See UAX 15 (http://unicode.org/reports/tr15/) */ typedef #include "vmware_pack_begin.h" struct HgfsFileName { uint32 length; /* Does NOT include terminating NUL */ char name[1]; } #include "vmware_pack_end.h" HgfsFileName; /* * Windows hosts only: the server may return the DOS 8 dot 3 format * name as part of the directory entry. */ typedef #include "vmware_pack_begin.h" struct HgfsShortFileName { uint32 length; /* Does NOT include terminating NUL */ char name[12 * 4]; /* UTF8 max char size is 4 bytes. */ } #include "vmware_pack_end.h" HgfsShortFileName; /* * Case-sensitiviy flags are only used when any lookup is * involved on the server side. */ typedef enum { HGFS_FILE_NAME_DEFAULT_CASE, HGFS_FILE_NAME_CASE_SENSITIVE, HGFS_FILE_NAME_CASE_INSENSITIVE, } HgfsCaseType; /* * HgfsFileNameV3 - new header to incorporate case-sensitivity flags along with * Hgfs file handle. */ typedef #include "vmware_pack_begin.h" struct HgfsFileNameV3 { uint32 length; /* Does NOT include terminating NUL */ uint32 flags; /* Flags described below. */ HgfsCaseType caseType; /* Case-sensitivity type. */ HgfsHandle fid; char name[1]; } #include "vmware_pack_end.h" HgfsFileNameV3; /* * HgfsFileNameV3 flags. Case-sensitiviy flags are only used when any lookup is * involved on the server side. */ #define HGFS_FILE_NAME_USE_FILE_DESC (1 << 0) /* Case type ignored if set. */ /* * Request/reply structs. These are the first members of all * operation request and reply messages, respectively. */ typedef #include "vmware_pack_begin.h" struct HgfsRequest { HgfsHandle id; /* Opaque request ID used by the requestor */ HgfsOp op; } #include "vmware_pack_end.h" HgfsRequest; typedef #include "vmware_pack_begin.h" struct HgfsReply { HgfsHandle id; /* Opaque request ID used by the requestor */ HgfsStatus status; } #include "vmware_pack_end.h" HgfsReply; /* * Messages for our file operations. */ /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsRequestOpen { HgfsRequest header; HgfsOpenMode mode; /* Which type of access is requested */ HgfsOpenFlags flags; /* Which flags to open the file with */ HgfsPermissions permissions; /* Which permissions to *create* a new file with */ HgfsFileName fileName; } #include "vmware_pack_end.h" HgfsRequestOpen; /* Version 2 of HgfsRequestOpen */ typedef #include "vmware_pack_begin.h" struct HgfsRequestOpenV2 { HgfsRequest header; HgfsOpenValid mask; /* Bitmask that specified which fields are valid. */ HgfsOpenMode mode; /* Which type of access requested. See desiredAccess */ HgfsOpenFlags flags; /* Which flags to open the file with */ HgfsPermissions specialPerms; /* Desired 'special' permissions for file creation */ HgfsPermissions ownerPerms; /* Desired 'owner' permissions for file creation */ HgfsPermissions groupPerms; /* Desired 'group' permissions for file creation */ HgfsPermissions otherPerms; /* Desired 'other' permissions for file creation */ HgfsAttrFlags attr; /* Attributes, if any, for file creation */ uint64 allocationSize; /* How much space to pre-allocate during creation */ uint32 desiredAccess; /* Extended support for windows access modes */ uint32 shareAccess; /* Windows only, share access modes */ HgfsServerLock desiredLock; /* The type of lock desired by the client */ uint64 reserved1; /* Reserved for future use */ uint64 reserved2; /* Reserved for future use */ HgfsFileName fileName; } #include "vmware_pack_end.h" HgfsRequestOpenV2; /* Version 3 of HgfsRequestOpen */ typedef #include "vmware_pack_begin.h" struct HgfsRequestOpenV3 { HgfsOpenValid mask; /* Bitmask that specified which fields are valid. */ HgfsOpenMode mode; /* Which type of access requested. See desiredAccess */ HgfsOpenFlags flags; /* Which flags to open the file with */ HgfsPermissions specialPerms; /* Desired 'special' permissions for file creation */ HgfsPermissions ownerPerms; /* Desired 'owner' permissions for file creation */ HgfsPermissions groupPerms; /* Desired 'group' permissions for file creation */ HgfsPermissions otherPerms; /* Desired 'other' permissions for file creation */ HgfsAttrFlags attr; /* Attributes, if any, for file creation */ uint64 allocationSize; /* How much space to pre-allocate during creation */ uint32 desiredAccess; /* Extended support for windows access modes */ uint32 shareAccess; /* Windows only, share access modes */ HgfsServerLock desiredLock; /* The type of lock desired by the client */ uint64 reserved1; /* Reserved for future use */ uint64 reserved2; /* Reserved for future use */ HgfsFileNameV3 fileName; } #include "vmware_pack_end.h" HgfsRequestOpenV3; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsReplyOpen { HgfsReply header; HgfsHandle file; /* Opaque file ID used by the server */ } #include "vmware_pack_end.h" HgfsReplyOpen; /* Version 2 of HgfsReplyOpen */ typedef #include "vmware_pack_begin.h" struct HgfsReplyOpenV2 { HgfsReply header; HgfsHandle file; /* Opaque file ID used by the server */ HgfsServerLock acquiredLock; /* The type of lock acquired by the server */ } #include "vmware_pack_end.h" HgfsReplyOpenV2; /* Version 3 of HgfsReplyOpen */ typedef #include "vmware_pack_begin.h" struct HgfsReplyOpenV3 { HgfsHandle file; /* Opaque file ID used by the server */ HgfsServerLock acquiredLock; /* The type of lock acquired by the server */ uint64 reserved; /* Reserved for future use */ } #include "vmware_pack_end.h" HgfsReplyOpenV3; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsRequestRead { HgfsRequest header; HgfsHandle file; /* Opaque file ID used by the server */ uint64 offset; uint32 requiredSize; } #include "vmware_pack_end.h" HgfsRequestRead; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsReplyRead { HgfsReply header; uint32 actualSize; char payload[1]; } #include "vmware_pack_end.h" HgfsReplyRead; /* * Version 3 of HgfsRequestRead. * Server must support HGFS_LARGE_PACKET_MAX to implement this op. */ typedef #include "vmware_pack_begin.h" struct HgfsRequestReadV3 { HgfsHandle file; /* Opaque file ID used by the server */ uint64 offset; uint32 requiredSize; uint64 reserved; /* Reserved for future use */ } #include "vmware_pack_end.h" HgfsRequestReadV3; typedef #include "vmware_pack_begin.h" struct HgfsReplyReadV3 { uint32 actualSize; uint64 reserved; /* Reserved for future use */ char payload[1]; } #include "vmware_pack_end.h" HgfsReplyReadV3; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsRequestWrite { HgfsRequest header; HgfsHandle file; /* Opaque file ID used by the server */ HgfsWriteFlags flags; uint64 offset; uint32 requiredSize; char payload[1]; } #include "vmware_pack_end.h" HgfsRequestWrite; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsReplyWrite { HgfsReply header; uint32 actualSize; } #include "vmware_pack_end.h" HgfsReplyWrite; /* * Version 3 of HgfsRequestWrite. * Server must support HGFS_LARGE_PACKET_MAX to implement this op. */ typedef #include "vmware_pack_begin.h" struct HgfsRequestWriteV3 { HgfsHandle file; /* Opaque file ID used by the server */ HgfsWriteFlags flags; uint64 offset; uint32 requiredSize; uint64 reserved; /* Reserved for future use */ char payload[1]; } #include "vmware_pack_end.h" HgfsRequestWriteV3; typedef #include "vmware_pack_begin.h" struct HgfsReplyWriteV3 { uint32 actualSize; uint64 reserved; /* Reserved for future use */ } #include "vmware_pack_end.h" HgfsReplyWriteV3; /* Stream write flags */ typedef enum { HGFS_WIN32_STREAM_IGNORE_SECURITY = (1<<0), } HgfsWin32StreamFlags; /* * HgfsRequestWriteWin32Stream. * Server must support HGFS_LARGE_PACKET_MAX to implement this op. */ typedef #include "vmware_pack_begin.h" struct HgfsRequestWriteWin32StreamV3 { HgfsHandle file; /* Opaque file ID used by the server */ HgfsWin32StreamFlags flags; uint32 reserved1; uint32 requiredSize; uint64 reserved2; /* Reserved for future use */ char payload[1]; } #include "vmware_pack_end.h" HgfsRequestWriteWin32StreamV3; typedef #include "vmware_pack_begin.h" struct HgfsReplyWriteWin32StreamV3 { uint32 actualSize; uint64 reserved; /* Reserved for future use */ } #include "vmware_pack_end.h" HgfsReplyWriteWin32StreamV3; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsRequestClose { HgfsRequest header; HgfsHandle file; /* Opaque file ID used by the server */ } #include "vmware_pack_end.h" HgfsRequestClose; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsReplyClose { HgfsReply header; } #include "vmware_pack_end.h" HgfsReplyClose; typedef #include "vmware_pack_begin.h" struct HgfsRequestCloseV3 { HgfsHandle file; /* Opaque file ID used by the server */ uint64 reserved; /* Reserved for future use */ } #include "vmware_pack_end.h" HgfsRequestCloseV3; typedef #include "vmware_pack_begin.h" struct HgfsReplyCloseV3 { uint64 reserved; } #include "vmware_pack_end.h" HgfsReplyCloseV3; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsRequestSearchOpen { HgfsRequest header; HgfsFileName dirName; } #include "vmware_pack_end.h" HgfsRequestSearchOpen; typedef #include "vmware_pack_begin.h" struct HgfsRequestSearchOpenV3 { uint64 reserved; /* Reserved for future use */ HgfsFileNameV3 dirName; } #include "vmware_pack_end.h" HgfsRequestSearchOpenV3; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsReplySearchOpen { HgfsReply header; HgfsHandle search; /* Opaque search ID used by the server */ } #include "vmware_pack_end.h" HgfsReplySearchOpen; typedef #include "vmware_pack_begin.h" struct HgfsReplySearchOpenV3 { HgfsHandle search; /* Opaque search ID used by the server */ uint64 reserved; /* Reserved for future use */ } #include "vmware_pack_end.h" HgfsReplySearchOpenV3; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsRequestSearchRead { HgfsRequest header; HgfsHandle search; /* Opaque search ID used by the server */ uint32 offset; /* The first result is offset 0 */ } #include "vmware_pack_end.h" HgfsRequestSearchRead; /* Version 2 of HgfsRequestSearchRead */ typedef #include "vmware_pack_begin.h" struct HgfsRequestSearchReadV2 { HgfsRequest header; HgfsHandle search; /* Opaque search ID used by the server */ uint32 offset; /* The first result is offset 0 */ } #include "vmware_pack_end.h" HgfsRequestSearchReadV2; typedef #include "vmware_pack_begin.h" struct HgfsRequestSearchReadV3 { HgfsHandle search; /* Opaque search ID used by the server */ uint32 offset; /* The first result is offset 0 */ uint32 flags; /* Reserved for reading multiple directory entries. */ uint64 reserved; /* Reserved for future use */ } #include "vmware_pack_end.h" HgfsRequestSearchReadV3; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsReplySearchRead { HgfsReply header; HgfsAttr attr; HgfsFileName fileName; /* fileName.length = 0 means "no entry at this offset" */ } #include "vmware_pack_end.h" HgfsReplySearchRead; /* Version 2 of HgfsReplySearchRead */ typedef #include "vmware_pack_begin.h" struct HgfsReplySearchReadV2 { HgfsReply header; HgfsAttrV2 attr; /* * fileName.length = 0 means "no entry at this offset" * If the file is a symlink (as specified in attr) * this name is the name of the symlink, not the target. */ HgfsFileName fileName; } #include "vmware_pack_end.h" HgfsReplySearchReadV2; /* Directory entry structure. */ typedef struct HgfsDirEntry { uint32 nextEntry; HgfsAttrV2 attr; /* * fileName.length = 0 means "no entry at this offset" * If the file is a symlink (as specified in attr) * this name is the name of the symlink, not the target. */ HgfsFileNameV3 fileName; } HgfsDirEntry; typedef #include "vmware_pack_begin.h" struct HgfsReplySearchReadV3 { uint64 count; /* Number of directory entries. */ uint64 reserved; /* Reserved for future use. */ char payload[1]; /* Directory entries. */ } #include "vmware_pack_end.h" HgfsReplySearchReadV3; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsRequestSearchClose { HgfsRequest header; HgfsHandle search; /* Opaque search ID used by the server */ } #include "vmware_pack_end.h" HgfsRequestSearchClose; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsReplySearchClose { HgfsReply header; } #include "vmware_pack_end.h" HgfsReplySearchClose; typedef #include "vmware_pack_begin.h" struct HgfsRequestSearchCloseV3 { HgfsHandle search; /* Opaque search ID used by the server */ uint64 reserved; /* Reserved for future use */ } #include "vmware_pack_end.h" HgfsRequestSearchCloseV3; typedef #include "vmware_pack_begin.h" struct HgfsReplySearchCloseV3 { uint64 reserved; /* Reserved for future use */ } #include "vmware_pack_end.h" HgfsReplySearchCloseV3; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsRequestGetattr { HgfsRequest header; HgfsFileName fileName; } #include "vmware_pack_end.h" HgfsRequestGetattr; /* Version 2 of HgfsRequestGetattr */ typedef #include "vmware_pack_begin.h" struct HgfsRequestGetattrV2 { HgfsRequest header; HgfsAttrHint hints; /* Flags for file handle valid. */ HgfsHandle file; /* Opaque file ID used by the server. */ HgfsFileName fileName; /* Filename used when file handle invalid. */ } #include "vmware_pack_end.h" HgfsRequestGetattrV2; typedef #include "vmware_pack_begin.h" struct HgfsRequestGetattrV3 { HgfsAttrHint hints; /* Flags for file handle valid. */ uint64 reserved; /* Reserved for future use */ HgfsFileNameV3 fileName; /* Filename used when file handle invalid. */ } #include "vmware_pack_end.h" HgfsRequestGetattrV3; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsReplyGetattr { HgfsReply header; HgfsAttr attr; } #include "vmware_pack_end.h" HgfsReplyGetattr; /* Version 2 of HgfsReplyGetattr */ typedef #include "vmware_pack_begin.h" struct HgfsReplyGetattrV2 { HgfsReply header; HgfsAttrV2 attr; /* * If the file is a symlink, as specified in attr.type, then this is * the target for the symlink. If the file is not a symlink, this should * be ignored. * * This filename is in "CPNameLite" format. See CPNameLite.c for details. */ HgfsFileName symlinkTarget; } #include "vmware_pack_end.h" HgfsReplyGetattrV2; typedef #include "vmware_pack_begin.h" struct HgfsReplyGetattrV3 { HgfsAttrV2 attr; /* * If the file is a symlink, as specified in attr.type, then this is * the target for the symlink. If the file is not a symlink, this should * be ignored. * * This filename is in "CPNameLite" format. See CPNameLite.c for details. */ uint64 reserved; /* Reserved for future use */ HgfsFileNameV3 symlinkTarget; } #include "vmware_pack_end.h" HgfsReplyGetattrV3; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsRequestSetattr { HgfsRequest header; HgfsAttrChanges update; /* Which fields need to be updated */ HgfsAttr attr; HgfsFileName fileName; } #include "vmware_pack_end.h" HgfsRequestSetattr; /* Version 2 of HgfsRequestSetattr */ typedef #include "vmware_pack_begin.h" struct HgfsRequestSetattrV2 { HgfsRequest header; HgfsAttrHint hints; HgfsAttrV2 attr; HgfsHandle file; /* Opaque file ID used by the server. */ HgfsFileName fileName; /* Filename used when file handle invalid. */ } #include "vmware_pack_end.h" HgfsRequestSetattrV2; typedef #include "vmware_pack_begin.h" struct HgfsRequestSetattrV3 { HgfsAttrHint hints; HgfsAttrV2 attr; uint64 reserved; /* Reserved for future use */ HgfsFileNameV3 fileName; /* Filename used when file handle invalid. */ } #include "vmware_pack_end.h" HgfsRequestSetattrV3; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsReplySetattr { HgfsReply header; } #include "vmware_pack_end.h" HgfsReplySetattr; /* Version 2 of HgfsReplySetattr */ typedef #include "vmware_pack_begin.h" struct HgfsReplySetattrV2 { HgfsReply header; } #include "vmware_pack_end.h" HgfsReplySetattrV2; typedef #include "vmware_pack_begin.h" struct HgfsReplySetattrV3 { uint64 reserved; /* Reserved for future use */ } #include "vmware_pack_end.h" HgfsReplySetattrV3; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsRequestCreateDir { HgfsRequest header; HgfsPermissions permissions; HgfsFileName fileName; } #include "vmware_pack_end.h" HgfsRequestCreateDir; /* Version 2 of HgfsRequestCreateDir */ typedef #include "vmware_pack_begin.h" struct HgfsRequestCreateDirV2 { HgfsRequest header; HgfsCreateDirValid mask; HgfsPermissions specialPerms; HgfsPermissions ownerPerms; HgfsPermissions groupPerms; HgfsPermissions otherPerms; HgfsFileName fileName; } #include "vmware_pack_end.h" HgfsRequestCreateDirV2; /* Version 3 of HgfsRequestCreateDir */ typedef #include "vmware_pack_begin.h" struct HgfsRequestCreateDirV3 { HgfsCreateDirValid mask; HgfsPermissions specialPerms; HgfsPermissions ownerPerms; HgfsPermissions groupPerms; HgfsPermissions otherPerms; HgfsAttrFlags fileAttr; HgfsFileNameV3 fileName; } #include "vmware_pack_end.h" HgfsRequestCreateDirV3; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsReplyCreateDir { HgfsReply header; } #include "vmware_pack_end.h" HgfsReplyCreateDir; /* Version 2 of HgfsReplyCreateDir */ typedef #include "vmware_pack_begin.h" struct HgfsReplyCreateDirV2 { HgfsReply header; } #include "vmware_pack_end.h" HgfsReplyCreateDirV2; /* Version 3 of HgfsReplyCreateDir */ typedef #include "vmware_pack_begin.h" struct HgfsReplyCreateDirV3 { uint64 reserved; /* Reserved for future use */ } #include "vmware_pack_end.h" HgfsReplyCreateDirV3; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsRequestDelete { HgfsRequest header; HgfsFileName fileName; } #include "vmware_pack_end.h" HgfsRequestDelete; /* Version 2 of HgfsRequestDelete */ typedef #include "vmware_pack_begin.h" struct HgfsRequestDeleteV2 { HgfsRequest header; HgfsDeleteHint hints; HgfsHandle file; /* Opaque file ID used by the server. */ HgfsFileName fileName; /* Name used if the file is HGFS_HANDLE_INVALID */ } #include "vmware_pack_end.h" HgfsRequestDeleteV2; /* Version 3 of HgfsRequestDelete */ typedef #include "vmware_pack_begin.h" struct HgfsRequestDeleteV3 { HgfsDeleteHint hints; uint64 reserved; /* Reserved for future use */ HgfsFileNameV3 fileName; /* Name used if the file is HGFS_HANDLE_INVALID */ } #include "vmware_pack_end.h" HgfsRequestDeleteV3; /* Deprecated */ typedef #include "vmware_pack_begin.h" struct HgfsReplyDelete { HgfsReply header; } #include "vmware_pack_end.h" HgfsReplyDelete; /* Version 2 of HgfsReplyDelete */ typedef #include "vmware_pack_begin.h" struct HgfsReplyDeleteV2 { HgfsReply header; } #include "vmware_pack_end.h" HgfsReplyDeleteV2; /* Version 2 of HgfsReplyDelete */ typedef #include "vmware_pack_begin.h" struct HgfsReplyDeleteV3 { uint64 reserved; /* Reserved for future use */ } #include "vmware_pack_end.h" HgfsReplyDeleteV3; /* * The size of the HgfsFileName struct is variable depending on the * length of the name, so you can't use request->newName to get the * actual address of the new name, because where it starts is * dependant on how long the oldName is. To get the address of * newName, use this: * * &oldName + sizeof(HgfsFileName) + oldName.length */ typedef #include "vmware_pack_begin.h" struct HgfsRequestRename { HgfsRequest header; HgfsFileName oldName; HgfsFileName newName; } #include "vmware_pack_end.h" HgfsRequestRename; typedef #include "vmware_pack_begin.h" struct HgfsReplyRename { HgfsReply header; } #include "vmware_pack_end.h" HgfsReplyRename; typedef #include "vmware_pack_begin.h" struct HgfsRequestRenameV2 { HgfsRequest header; HgfsRenameHint hints; HgfsHandle srcFile; /* Opaque file ID to "old name" used by the server. */ HgfsHandle targetFile; /* Opaque file ID to "old name" used by the server. */ HgfsFileName oldName; HgfsFileName newName; } #include "vmware_pack_end.h" HgfsRequestRenameV2; typedef #include "vmware_pack_begin.h" struct HgfsReplyRenameV2 { HgfsReply header; } #include "vmware_pack_end.h" HgfsReplyRenameV2; /* HgfsRequestRename and HgfsReplyRename for v3. */ typedef #include "vmware_pack_begin.h" struct HgfsRequestRenameV3 { HgfsRenameHint hints; uint64 reserved; /* Reserved for future use */ HgfsFileNameV3 oldName; HgfsFileNameV3 newName; } #include "vmware_pack_end.h" HgfsRequestRenameV3; typedef #include "vmware_pack_begin.h" struct HgfsReplyRenameV3 { uint64 reserved; /* Reserved for future use */ } #include "vmware_pack_end.h" HgfsReplyRenameV3; typedef #include "vmware_pack_begin.h" struct HgfsRequestQueryVolume { HgfsRequest header; HgfsFileName fileName; } #include "vmware_pack_end.h" HgfsRequestQueryVolume; typedef #include "vmware_pack_begin.h" struct HgfsReplyQueryVolume { HgfsReply header; uint64 freeBytes; uint64 totalBytes; } #include "vmware_pack_end.h" HgfsReplyQueryVolume; /* HgfsRequestQueryVolume and HgfsReplyQueryVolume for v3. */ typedef #include "vmware_pack_begin.h" struct HgfsRequestQueryVolumeV3 { uint64 reserved; /* Reserved for future use */ HgfsFileNameV3 fileName; } #include "vmware_pack_end.h" HgfsRequestQueryVolumeV3; typedef #include "vmware_pack_begin.h" struct HgfsReplyQueryVolumeV3 { uint64 freeBytes; uint64 totalBytes; uint64 reserved; /* Reserved for future use */ } #include "vmware_pack_end.h" HgfsReplyQueryVolumeV3; /* New operations for Version 2 */ typedef #include "vmware_pack_begin.h" struct HgfsRequestServerLockChange { HgfsRequest header; HgfsHandle file; HgfsServerLock newServerLock; } #include "vmware_pack_end.h" HgfsRequestServerLockChange; typedef #include "vmware_pack_begin.h" struct HgfsReplyServerLockChange { HgfsReply header; HgfsServerLock serverLock; } #include "vmware_pack_end.h" HgfsReplyServerLockChange; typedef #include "vmware_pack_begin.h" struct HgfsRequestSymlinkCreate { HgfsRequest header; HgfsFileName symlinkName; /* This filename is in "CPNameLite" format. See CPNameLite.c for details. */ HgfsFileName targetName; } #include "vmware_pack_end.h" HgfsRequestSymlinkCreate; typedef #include "vmware_pack_begin.h" struct HgfsReplySymlinkCreate { HgfsReply header; } #include "vmware_pack_end.h" HgfsReplySymlinkCreate; /* HgfsRequestSymlinkCreate and HgfsReplySymlinkCreate for v3. */ typedef #include "vmware_pack_begin.h" struct HgfsRequestSymlinkCreateV3 { uint64 reserved; /* Reserved for future use */ HgfsFileNameV3 symlinkName; /* This filename is in "CPNameLite" format. See CPNameLite.c for details. */ HgfsFileNameV3 targetName; } #include "vmware_pack_end.h" HgfsRequestSymlinkCreateV3; typedef #include "vmware_pack_begin.h" struct HgfsReplySymlinkCreateV3 { uint64 reserved; /* Reserved for future use */ } #include "vmware_pack_end.h" HgfsReplySymlinkCreateV3; /* HGFS protocol version 4 definitions. */ /* * HGFS_PACKET_FLAG_NOTIFICATION set in flags field means that * this is a notification or a callback request (not a reply to client request). */ #define HGFS_PACKET_FLAG_NOTIFICATION (1 << 0) typedef #include "vmware_pack_begin.h" struct HgfsHeader { uint8 version; /* Header version. */ uint8 reserved1[3]; /* Reserved for future use. */ uint8 dummy; /* Needed to distinguish between older and newer header. */ uint8 reserved2[3]; /* Reserved for future use. */ uint32 packetSize; /* Size of the packet, including the header size. */ uint32 headerSize; /* Size of the Hgfs header. */ uint32 requestId; /* Request ID. */ uint32 op; /* Operation. */ uint32 status; /* Return value. */ uint32 flags; /* Flags. */ uint32 information; /* Generic field, used e.g. for native error code. */ uint64 sessionId; /* Session ID. */ uint64 reserved; /* Reserved for future use. */ } #include "vmware_pack_end.h" HgfsHeader; /* * If no flags are set then the capability is not supported by the host. */ #define HGFS_REQUEST_NOT_SUPPORTED 0 /* * Flag HGFS_REQUEST_SUPPORTED is set for every requests that are supported by the host. */ #define HGFS_REQUEST_SUPPORTED (1 << 0) /* * Following flags define which optional parameters for file open * requests are supported by the host. * HGFS_OPENV4_SUPPORTS_EA - host is capable of setting EA when creating * a new file. * HGFS_OPENV4_SUPPORTS_ACL - host is capable of setting ACLs when creating * a new file. * HGFS_OPENV4_SUPPORTS_NAMED_STREAMS - opening/enumerating named streams * is supported. * HGFS_OPENV4_SUPPORTS_SHARED_ACCESS - host supports file sharing restrictions. * HGFS_OPENV4_SUPPORTS_UNIX_PERMISSIONS - host stores POSIX permissions with * file. * HGFS_OPENV4_POSIX_FILE_DELETION - host supports POSIX file deletion semantics. */ typedef uint32 HgfsOpenV4Capabilities; #define HGFS_OPENV4_SUPPORTS_EA (1 << 1) #define HGFS_OPENV4_SUPPORTS_ACL (1 << 2) #define HGFS_OPENV4_SUPPORTS_NAMED_STREAMS (1 << 3) #define HGFS_OPENV4_SUPPORTS_SHARED_ACCESS (1 << 4) #define HGFS_OPENV4_SUPPORTS_UNIX_PERMISSIONS (1 << 5) #define HGFS_OPENV4_POSIX_FILE_DELETION (1 << 6) /* * There is a significant difference in byte range locking semantics between Windows * and POSIX file systems. Windows implements mandatory locking which means that every * read or write request that conflicts with byte range locks is rejected. POSIX has * an advisory locking which means that locks are validated only when another lock is * requested and are not enforced for read/write operations. * Applications in guest OS may expect byte range locking semantics that matches guest * OS which may be different from semantics that is natively supported by host OS. In * this case either HGFS server or HGFS client should provide compensation for the host * OS semantics to maintain application compatibility. * Client must know if the server is capable to provide appropriate byte range locking * semantics to perform some compensation on behalf of server when necessary. * * Following flags define various capabilities of byte range lock implementation on * the host. * * HGFS_BYTE_RANGE_LOCKS_SUPPORTS_64 means that server is capable of locking 64 bit * length ranges. * HGFS_BYTE_RANGE_LOCKS_SUPPORTS_32 means that server is limited to 32-bit ranges. * HGFS_BYTE_RANGE_LOCKS_SUPPORTS_MANDATORY means that server is capable of enforcing * read/write restrictions for locked ranges. * HGFS_BYTE_RANGE_LOCKS_SUPPORTS_ADVISORY means that server supports advisory locking; * locks are validated only for other bytes * range locking and are not enforced * for read/write operations. */ typedef uint32 HgfsByteRangeLockingCapabilities; #define HGFS_BYTE_RANGE_LOCKS_SUPPORTS_64 (1 << 1) #define HGFS_BYTE_RANGE_LOCKS_SUPPORTS_32 (1 << 2) #define HGFS_BYTE_RANGE_LOCKS_SUPPORTS_MANDATORY (1 << 3) #define HGFS_BYTE_RANGE_LOCKS_SUPPORTS_ADVISORY (1 << 4) /* HGFS_SUPPORTS_HARD_LINKS is set when the host supports hard links. */ typedef uint32 HgfsLinkMoveCapabilities; #define HGFS_SUPPORTS_HARD_LINKS (1 << 1) /* * HGFS_SET_WATCH_SUPPORTS_FINE_GRAIN_EVENTS is set when host supports * fine grain event reporting for directory notification. */ typedef uint32 HgfsSetWatchCapabilities; #define HGFS_SET_WATCH_SUPPORTS_FINE_GRAIN_EVENTS (1 << 1) typedef #include "vmware_pack_begin.h" struct HgfsCapability { HgfsOp op; /* Op. */ uint32 flags; /* Flags. */ } #include "vmware_pack_end.h" HgfsCapability; typedef HgfsFileName HgfsUserName; typedef HgfsFileName HgfsGroupName; /* Following structures describe user identity on the host which runs HGFS service. */ typedef #include "vmware_pack_begin.h" struct HgfsIdentity { uint32 uid; /* user id. */ uint32 gid; /* Primary group id. */ HgfsUserName user; /* User name in form specified in RFC 3530. */ HgfsGroupName group; /* Group name in form specified in RFC 3530. */ } #include "vmware_pack_end.h" HgfsIdentity; typedef #include "vmware_pack_begin.h" struct HgfsRequestCreateSessionV4 { uint32 numCapabilities; /* Number of capabilities to follow. */ uint32 maxPacketSize; /* Maximum packet size supported. */ uint64 reserved; /* Reserved for future use. */ HgfsCapability capabilities[1]; /* Array of HgfsCapabilities. */ } #include "vmware_pack_end.h" HgfsRequestCreateSessionV4; #define HGFS_INVALID_SESSION_ID (~((uint64)0)) typedef #include "vmware_pack_begin.h" struct HgfsReplyCreateSessionV4 { uint64 sessionId; /* Session ID. */ uint32 numCapabilities; /* Number of capabilities to follow. */ uint32 maxPacketSize; /* Maximum packet size supported. */ uint32 identityOffset; /* Offset to HgfsIdentity or 0 if no identity. */ uint64 reserved; /* Reserved for future use. */ HgfsCapability capabilities[1]; /* Array of HgfsCapabilities. */ } #include "vmware_pack_end.h" HgfsReplyCreateSessionV4; typedef #include "vmware_pack_begin.h" struct HgfsRequestDestroySessionV4 { uint64 reserved; /* Reserved for future use. */ } #include "vmware_pack_end.h" HgfsRequestDestroySessionV4; typedef #include "vmware_pack_begin.h" struct HgfsReplyDestroySessionV4 { uint64 reserved; /* Reserved for future use. */ } #include "vmware_pack_end.h" HgfsReplyDestroySessionV4; /* Adds new error status: HGFS_STATUS_INVALID_SESSION. */ /* * If file handle is used to set watch (HGFS_FILE_NAME_USE_FILE_DESC * is set in the fileName), closing this handle implicitly removes the watch. */ typedef #include "vmware_pack_begin.h" struct HgfsRequestSetWatchV4 { uint64 events; /* What events to watch? */ uint32 flags; /* Flags. */ uint64 reserved; /* Reserved for future use. */ HgfsFileNameV3 fileName; /* Filename to watch. */ } #include "vmware_pack_end.h" HgfsRequestSetWatchV4; /* * Coarse grain notification event types. */ #define HGFS_ACTION_ADDED (1 << 0) /* File was added. */ #define HGFS_ACTION_REMOVED (1 << 1) /* File was removed. */ #define HGFS_ACTION_MODIFIED (1 << 2) /* File attributes were changed. */ #define HGFS_ACTION_RENAMED (1 << 3) /* File was renamed. */ /* * Fine grain notification event types. * HgfsRequestSetWatch events. */ #define HGFS_NOTIFY_ACCESS (1 << 0) /* File accessed (read) */ #define HGFS_NOTIFY_ATTRIB (1 << 1) /* File attributes changed. */ #define HGFS_NOTIFY_SIZE (1 << 2) /* File size changed. */ #define HGFS_NOTIFY_ATIME (1 << 3) /* Access time changed. */ #define HGFS_NOTIFY_MTIME (1 << 4) /* Modification time changed. */ #define HGFS_NOTIFY_CTIME (1 << 5) /* Attribute time changed. */ #define HGFS_NOTIFY_CRTIME (1 << 6) /* Creation time changed. */ #define HGFS_NOTIFY_NAME (1 << 7) /* File / Directory name. */ #define HGFS_NOTIFY_OPEN (1 << 8) /* File opened */ #define HGFS_NOTIFY_CLOSE_WRITE (1 << 9) /* Modified file closed. */ #define HGFS_NOTIFY_CLOSE_NOWRITE (1 << 10) /* Non-modified file closed. */ #define HGFS_NOTIFY_CREATE_FILE (1 << 11) /* File created */ #define HGFS_NOTIFY_CREATE_DIR (1 << 12) /* Directory created */ #define HGFS_NOTIFY_DELETE_FILE (1 << 13) /* File deleted */ #define HGFS_NOTIFY_DELETE_DIR (1 << 14) /* Directory deleted */ #define HGFS_NOTIFY_DELETE_SELF (1 << 15) /* Watched directory deleted */ #define HGFS_NOTIFY_MODIFY (1 << 16) /* File modified. */ #define HGFS_NOTIFY_MOVE_SELF (1 << 17) /* Watched directory moved. */ #define HGFS_NOTIFY_OLD_FILE_NAME (1 << 18) /* Rename: old file name. */ #define HGFS_NOTIFY_NEW_FILE_NAME (1 << 19) /* Rename: new file name. */ #define HGFS_NOTIFY_OLD_DIR_NAME (1 << 20) /* Rename: old dir name. */ #define HGFS_NOTIFY_NEW_DIR_NAME (1 << 21) /* Rename: new dir name. */ #define HGFS_NOTIFY_CHANGE_EA (1 << 22) /* Extended attributes. */ #define HGFS_NOTIFY_CHANGE_SECURITY (1 << 23) /* Security/permissions. */ #define HGFS_NOTIFY_ADD_STREAM (1 << 24) /* Named stream created. */ #define HGFS_NOTIFY_DELETE_STREAM (1 << 25) /* Named stream deleted. */ #define HGFS_NOTIFY_CHANGE_STREAM_SIZE (1 << 26) /* Named stream size changed. */ #define HGFS_NOTIFY_CHANGE_STREAM_LAST_WRITE (1 << 27) /* Stream timestamp changed. */ #define HGFS_NOTIFY_WATCH_DELETED (1 << 28) /* Dir with watch deleted. */ #define HGFS_NOTIFY_EVENTS_DROPPED (1 << 29) /* Notifications dropped. */ /* HgfsRequestSetWatch flags. */ #define HGFS_NOTIFY_FLAG_WATCH_TREE (1 << 0) /* Watch the entire directory tree. */ #define HGFS_NOTIFY_FLAG_DONT_FOLLOW (1 << 1) /* Don't follow symlinks. */ #define HGFS_NOTIFY_FLAG_ONE_SHOT (1 << 2) /* Generate only one notification. */ #define HGFS_NOTIFY_FLAG_POSIX_HINT (1 << 3) /* Client is POSIX and thus expects * fine grain notification. Server * may provide coarse grain * notification even if this flag is * set. */ typedef uint64 HgfsSubscriberHandle; #define HGFS_INVALID_SUBSCRIBER_HANDLE ((HgfsSubscriberHandle)~((HgfsSubscriberHandle)0)) typedef #include "vmware_pack_begin.h" struct HgfsReplySetWatchV4 { HgfsSubscriberHandle watchId; /* Watch identifier for subsequent references. */ uint64 reserved; /* Reserved for future use. */ } #include "vmware_pack_end.h" HgfsReplySetWatchV4; typedef #include "vmware_pack_begin.h" struct HgfsRequestRemoveWatchV4 { HgfsSubscriberHandle watchId; /* Watch identifier to remove. */ } #include "vmware_pack_end.h" HgfsRequestRemoveWatchV4; typedef #include "vmware_pack_begin.h" struct HgfsReplyRemoveWatchV4 { uint64 reserved; /* Reserved for future use. */ } #include "vmware_pack_end.h" HgfsReplyRemoveWatchV4; typedef #include "vmware_pack_begin.h" struct HgfsNotifyEventV4 { uint32 nextOffset; /* Offset of next event; 0 if it i sthe last one. */ uint64 mask; /* Event occurred. */ uint64 reserved; /* Reserved for future use. */ HgfsFileName fileName; /* Filename. */ } #include "vmware_pack_end.h" HgfsNotifyEventV4; /* Too many events, some or all event were dropped by the server. */ #define HGFS_NOTIFY_FLAG_OVERFLOW (1 << 0) /* Watch had been removed either explicitly or implicitly. */ #define HGFS_NOTIFY_FLAG_REMOVED (1 << 1) /* Server generated coasrse grain events. */ #define HGFS_NOTIFY_FLAG_COARSE_GRAIN (1 << 2) typedef #include "vmware_pack_begin.h" struct HgfsRequestNotifyV4 { HgfsSubscriberHandle watchId; /* Watch identifier. */ uint32 flags; /* Various flags. */ uint32 count; /* Number of events occured. */ uint64 reserved; /* Reserved for future use. */ HgfsNotifyEventV4 events[1]; /* Events. HgfsNotifyEvent(s). */ } #include "vmware_pack_end.h" HgfsRequestNotifyV4; // Query EA flags values. #define HGFS_QUERY_EA_INDEX_SPECIFIED (1 << 0) #define HGFS_QUERY_EA_SINGLE_ENTRY (1 << 1) #define HGFS_QUERY_EA_RESTART_SCAN (1 << 2) typedef #include "vmware_pack_begin.h" struct HgfsRequestQueryEAV4 { uint32 flags; /* EA flags. */ uint32 index; uint64 reserved; /* Reserved for future use. */ uint32 eaNameLength; /* EA name length. */ uint32 eaNameOffset; /* Offset of the eaName field. */ HgfsFileNameV3 fileName; /* File to watch. */ char eaNames[1]; /* List of NULL terminated EA names. * Actual location of the data depends on * fileName length and defined by eaNameOffset. */ } #include "vmware_pack_end.h" HgfsRequestQueryEAV4; typedef #include "vmware_pack_begin.h" struct HgfsReplyQueryEAV4 { uint32 nextOffset; /* Offset of the next structure when more then * one record is returned. */ uint32 flags; /* EA flags. */ uint32 index; /* Index needed to resume scan. */ uint64 reserved; /* Reserved for future use. */ uint32 eaDataLength; /* EA value length. */ char eaData[1]; /* NULL termianed EA name followed by EA value. */ } #include "vmware_pack_end.h" HgfsReplyQueryEAV4; typedef #include "vmware_pack_begin.h" struct HgfsEAV4 { uint32 nextOffset; /* Offset of the next structure in the chain. */ uint32 valueLength; /* EA value length. */ char data[1]; /* NULL terminated EA name followed by EA value. */ } #include "vmware_pack_end.h" HgfsEAV4; typedef #include "vmware_pack_begin.h" struct HgfsRequestSetEAV4 { uint32 flags; /* Flags, see below. */ uint64 reserved; /* Reserved for future use. */ uint32 numEAs; /* Number of EAs in this request. */ HgfsEAV4 attributes[1]; /* Array of attributes. */ } #include "vmware_pack_end.h" HgfsRequestSetEAV4; typedef #include "vmware_pack_begin.h" struct HgfsReplySetEAV4 { uint64 reserved; /* Reserved for future use. */ } #include "vmware_pack_end.h" HgfsReplySetEAV4; /* * EA Flags. When both flags are set EA is either created or replaced if it exists. * HGFS_EA_FLAG_CREATE - create if EA is not present, error otherwise. * HGFS_EA_FLAG_REPLACE - Replace exisitng EA. Error if EA not already present. */ #define HGFS_EA_FLAG_CREATE (1 << 0) #define HGFS_EA_FLAG_REPLACE (1 << 1) /* * Byte range lock flag values: * HGFS_RANGE_LOCK_EXCLUSIVE - Requested lock is exclusive when this flag is set, * otherwise it is a shared lock. * HGFS_RANGE_LOCK_FAIL_IMMEDIATLY - If the flag is not set server waits until the * lock becomes available. */ #define HGFS_RANGE_LOCK_EXCLUSIVE (1 << 0) #define HGFS_RANGE_LOCK_FAIL_IMMEDIATLY (1 << 1) typedef #include "vmware_pack_begin.h" struct HgfsRequestLockRangeV4 { HgfsHandle fid; /* File to take lock on. */ uint32 flags; /* Various flags. */ uint64 start; /* Starting offset in the file. */ uint64 length; /* Number of bytes to lock. */ uint64 reserved; /* Reserved for future use. */ } #include "vmware_pack_end.h" HgfsRequestLockRangeV4; typedef #include "vmware_pack_begin.h" struct HgfsReplyLockRangeV4 { uint64 reserved; /* Reserved for future use. */ } #include "vmware_pack_end.h" HgfsReplyLockRangeV4; #define HGFS_RANGE_LOCK_UNLOCK_ALL (1 << 0) typedef #include "vmware_pack_begin.h" struct HgfsRequestUnlockRangeV4 { HgfsHandle fid; /* File to take lock on. */ uint32 flags; /* Various flags. */ uint64 start; /* Starting offset in the file. */ uint64 length; /* Number of bytes to lock. */ uint64 reserved; /* Reserved for future use. */ } #include "vmware_pack_end.h" HgfsRequestUnlockRangeV4; typedef #include "vmware_pack_begin.h" struct HgfsReplyUnlockRangeV4 { uint64 reserved; /* Reserved for future use. */ } #include "vmware_pack_end.h" HgfsReplyUnlockRangeV4; /* * There are three types of oplocks: level 1, batch, and level 2. Both the level 1 and * batch oplocks are "exclusive access" opens. They are used slightly differently, * however, and hence have somewhat different semantics. A level 2 oplock is a "shared * access" grant on the file. * Level 1 is used by a remote client that wishes to modify the data. Once granted a * Level 1 oplock, the remote client may cache the data, modify the data in its cache * and need not write it back to the server immediately. * Batch oplocks are used by remote clients for accessing script files where the file is * opened, read or written, and then closed repeatedly. Thus, a batch oplock * corresponds not to a particular application opening the file, but rather to a remote * clients network file system caching the file because it knows something about the * semantics of the given file access. The name "batch" comes from the fact that this * behavior was observed by Microsoft with "batch files" being processed by command line * utilities. Log files especially exhibit this behavior when a script it being * processed each command is executed in turn. If the output of the script is redirected * to a log file the file fits the pattern described earlier, namely open/write/close. * With many lines in a file this pattern can be repeated hundreds of times. * Level 2 is used by a remote client that merely wishes to read the data. Once granted * a Level 2 oplock, the remote client may cache the data and need not worry that the * data on the remote file server will change without it being advised of that change. * An oplock must be broken whenever the cache consistency guarantee provided by the * oplock can no longer be provided. Thus, whenever a second network client attempts to * access data in the same file across the network, the file server is responsible for * "breaking" the oplocks and only then allowing the remote client to access the file. * This ensures that the data is guaranteed to be consistent and hence we have preserved * the consistency guarantees essential to proper operation. * * HGFS_OPLOCK_NONE: no oplock. No caching on client side. * HGFS_OPLOCK_SHARED: shared (or LEVEL II) oplock. Read caching is allowed. * HGFS_OPLOCK_EXCLUSIVE: exclusive (or LEVEL I) oplock. Read/write caching is allowed. * HGFS_OPLOCK_BATCH: batch oplock. Read/Write and Open caching is allowed. */ typedef enum { HGFS_OPLOCK_NONE, HGFS_OPLOCK_SHARED, HGFS_OPLOCK_EXCLUSIVE, HGFS_OPLOCK_BATCH, } HgfsOpportunisticLock; typedef #include "vmware_pack_begin.h" struct HgfsRequestServerLockChangeV2 { HgfsHandle fid; /* File to take lock on. */ HgfsOpportunisticLock serverLock; /* Lock type. */ uint64 reserved; } #include "vmware_pack_end.h" HgfsRequestServerLockChangeV2; typedef #include "vmware_pack_begin.h" struct HgfsReplyServerLockChangeV2 { HgfsOpportunisticLock serverLock; /* Lock granted. */ uint64 reserved; } #include "vmware_pack_end.h" HgfsReplyServerLockChangeV2; /* * This request is sent from server to the client to notify that oplock * is revoked or downgraded. */ typedef #include "vmware_pack_begin.h" struct HgfsRequestOplockBreakV4 { HgfsHandle fid; /* File handle. */ HgfsOpportunisticLock serverLock; /* Lock downgraded to this type. */ uint64 reserved; /* Reserved for future use. */ } #include "vmware_pack_end.h" HgfsRequestOplockBreakV4; typedef #include "vmware_pack_begin.h" struct HgfsReplyOplockBreakV4 { uint64 reserved; /* Reserved for future use. */ } #include "vmware_pack_end.h" HgfsReplyOplockBreakV4; /* * Flusing of a whole volume is not supported. * Flusing of reqular files is supported on all hosts. * Flusing of directories is supproted on POSIX hosts and is * NOOP on Windows hosts. */ typedef #include "vmware_pack_begin.h" struct HgfsRequestFsyncV4 { HgfsHandle fid; /* File to sync. */ uint64 reserved; } #include "vmware_pack_end.h" HgfsRequestFsyncV4; typedef #include "vmware_pack_begin.h" struct HgfsReplyFsyncV4 { uint64 reserved; } #include "vmware_pack_end.h" HgfsReplyFsyncV4; /* * This request is name based only. * Server fails this request if HGFS_FILE_E_USE_FILE_DESC is set in the fileName. */ typedef #include "vmware_pack_begin.h" struct HgfsRequestAccessCheckV4 { HgfsFileNameV3 fileName; /* File concerned. */ HgfsPermissions perms; /* Permissions to check for. */ uint64 reserved; /* Reserved for future use. */ } #include "vmware_pack_end.h" HgfsRequestAccessCheckV4; typedef #include "vmware_pack_begin.h" struct HgfsReplyAccessCheckV4 { uint64 reserved; /* Reserved for future use. */ } #include "vmware_pack_end.h" HgfsReplyAccessCheckV4; /* * Additional HgfsPersmissions type: checks file existense without * requesting any particular access. * Matches F_OK mode parameter for POSIX access (2) API. */ #define HGFS_PERM_EXISTS 8 /* * HGFS_PLATFORM_ALL is a HGFS specific platform independent FSCTL * that correspond to different OS specific codes. * Other types of FSCTL are platform specific to allow better user * experience when guest and host OS are the same. HGFS does not interpret * platform specific FSCTL in any way, it just passes it through to the * host. If the host run appropriate OS it executes FSCTL on user's behalf, * otherwise it fails the request. */ typedef enum HgfsPlatformType { HGFS_PLATFORM_ALL, HGFS_PLATFORM_WINDOWS, HGFS_PLATFORM_LINUX, HGFS_PLATFORM_MAC }HgfsPlatformType; #define HGFS_FSCTL_SET_SPARSE 1 /* Platform independent FSCTL to make file sparse. */ /* Platform together with the code define exact meaning of the operation. */ typedef #include "vmware_pack_begin.h" struct HgfsRequestFsctlV4 { HgfsHandle fid; uint32 code; HgfsPlatformType platform; uint32 dataLength; char data[1]; } #include "vmware_pack_end.h" HgfsRequestFsctlV4; typedef #include "vmware_pack_begin.h" struct HgfsReplyFsctlV4 { uint32 dataLength; char data[1]; } #include "vmware_pack_end.h" HgfsReplyFsctlV4; /* * Creating a new file or reading file attributes involves ACL. There is a good * definition of multi-platform ACLs in RFC 3530, section 5.11. HGFS should use * ACLs defined in this document (http://tools.ietf.org/html/rfc3530#section-5.11). * ACL support is not mandatory. If a request to create file with ACL comes to a host * that does not support ACL, the request should succeed and setting ACL is ignored. * Such behavior is consistent with other file systems. */ typedef uint64 HgfsOpenCreateOptions; /* O_SYMLINK in Mac OS or FILE_FLAG_OPEN_REPARSE_POINT in Windows. */ #define HGFS_OPENCREATE_OPTION_SYMLINK (1 << 0) /* O_SHLOCK in Mac OS or obtain shared range lock for the whole file. */ #define HGFS_OPENCREATE_OPTION_SHLOCK (1 << 1) /* O_EXLOCK in Mac OS or obtain exclusive range lock for the whole file. */ #define HGFS_OPENCREATE_OPTION_EXLOCK (1 << 2) /* O_SYNC in Linux, ignored in Mac, FILE_FLAG_WRITE_THROUGH in Windows. */ #define HGFS_OPENCREATE_OPTION_WRITETHROUGH (1 << 3) /* FILE_FLAG_NO_BUFFERING in Windows, O_SYNC in Linux, ignored on Mac OS. */ #define HGFS_OPENCREATE_OPTION_NO_BUFERING (1 << 4) /* * O_NOFOLLOW in POSIX. Windows server checks for reparse point * and fails the request if file has one. */ #define HGFS_OPENCREATE_OPTION_NO_FOLLOW (1 << 5) /* FILE_FLAG_NO_RECALL in Windows. Ignored by POSIX host. */ #define HGFS_OPENCREATE_OPTION_NO_RECALL (1 << 6) /* FILE_FLAG_RANDOM_ACCESS in Windows. Ignored by POSIX host. */ #define HGFS_OPENCREATE_OPTION_RANDOM (1 << 7) /* FILE_FLAG_SEQUENTIAL_SCAN in Windows. Ignored by POSIX host. */ #define HGFS_OPENCREATE_OPTION_SEQUENTIAL (1 << 8) /* FILE_FLAG_BACKUP_SEMANTICS in Windows. Ignored by POSIX host. */ #define HGFS_OPENCREATE_OPTION_BACKUP_SEMANTICS (1 << 9) /* Fail opening if the file already exists and it is not a directory. */ #define HGFS_OPENCREATE_OPTION_DIRECTORY (1 << 10) /* Fail opening if the file already exists and it is a directory. */ #define HGFS_OPENCREATE_OPTION_NON_DIRECTORY (1 << 11) typedef #include "vmware_pack_begin.h" struct HgfsRequestOpenV4 { HgfsOpenValid mask; /* Bitmask that specified which fields are valid. */ HgfsOpenMode mode; /* Which type of access requested. See desiredAccess */ HgfsOpenFlags flags; /* Which flags to open the file with */ HgfsPermissions specialPerms; /* Desired 'special' permissions for file creation */ HgfsPermissions ownerPerms; /* Desired 'owner' permissions for file creation */ HgfsPermissions groupPerms; /* Desired 'group' permissions for file creation */ HgfsPermissions otherPerms; /* Desired 'other' permissions for file creation */ HgfsAttrFlags attr; /* Attributes, if any, for file creation */ uint64 allocationSize; /* How much space to pre-allocate during creation */ uint32 desiredAccess; /* Extended support for windows access modes */ uint32 shareAccess; /* Windows only, share access modes */ HgfsOpenCreateOptions createOptions; /* Various options. */ HgfsOpportunisticLock requestedLock; /* The type of lock desired by the client */ HgfsFileNameV3 fileName; /* fid can be used only for relative open, * i.e. to open named stream. */ HgfsFileName streamName; /* Name of the alternative named stream. * All flags are the same as defined in fileName. * The name is used in conjuction with fileName * field, for example if Windows opens file * "abc.txt:stream" then fileName contains * "abc.txt" and streamName contains "stream" */ /* * EA to set if the file is created or overwritten. The parameter should be ignored * if the file already exists. * It is needed to correctly implement Windows semantics for opening files. * It should work atomically - failure to add EA should result in failure to create * the new file. * If the host file system does not support EA server should fail the request rather * then succeeding and silently dropping EA. */ HgfsRequestSetEAV4 extendedAttributes; uint32 aclLength; /* Length of the acl field. */ char acl[1]; /* Multi-platform ACL as defined in RFC 3530. */ } #include "vmware_pack_end.h" HgfsRequestOpenV4; typedef enum HgfsOpenResult { HGFS_FILE_OPENED, HGFS_FILE_CREATED, HGFS_FILE_OVERWRITTEN, HGFS_FILE_SUPERSIDED, } HgfsOpenResult; /* * Win32 API has a special value for the desired access - MAXIMUM_ALLOWED. * Such desired access means that file system must grant as much rights for the file * as it is allowed for the current user. * HGFS client must know what access rights were granted to properly communicate this * information to the IoManager; grantedAccess field is used for this purpose. */ typedef #include "vmware_pack_begin.h" struct HgfsReplyOpenV4 { HgfsHandle file; /* Opaque file ID used by the server */ HgfsOpportunisticLock grantedLock; /* The type of lock acquired by the server */ HgfsOpenResult openResult; /* Opened/overwritten or a new file created? */ uint32 grantedAccess; /* Granted access rights. */ uint64 fileId; /* Persistent volume-wide unique file id. */ uint64 volumeId; /* Persistent unique volume id. */ } #include "vmware_pack_end.h" HgfsReplyOpenV4; /* * Flags that define behaviour of the move/creating hard link operation. */ typedef uint64 HgfsMoveLinkFlags; #define HGFS_LINKMOVE_FLAG_REPLACE_EXISTING (1 << 0) /* Delete existing target. */ #define HGFS_LINKMOVE_FLAG_HARD_LINK (1 << 1) /* Create hard link. */ typedef #include "vmware_pack_begin.h" struct HgfsRequestLinkMoveV4 { HgfsFileNameV3 oldFileName; /* Path to the exisitng source file.*/ HgfsFileNameV3 newFileName; /* Path to the destinatio name.*/ HgfsMoveLinkFlags flags; /* Flags that define behaviour of the operation.*/ } #include "vmware_pack_end.h" HgfsRequestLinkMoveV4; typedef #include "vmware_pack_begin.h" struct HgfsReplyLinkMove4 { uint64 reserved; /* Reserved for future use. */ } #include "vmware_pack_end.h" HgfsReplyLinkMove4; /* * HgfsQueryVolumeMaskV4 mask in a request defines which volume properties client needs; * mask in a reply defines which properties were actually returned by the host. * * HGFS_QUERY_VOLUME_MASK_SIZE controls totalBytes, freeBytes and availableBytes. * HGFS_QUERY_VOLUME_MASK_FS_CAPABILITIES controls capabilities. * HGFS_QUERY_VOLUME_MASK_ATTRIBUTES controls creationTime. * HGFS_QUERY_VOLUME_MASK_VOLUME_GEOMETRY controls bytesPerSector and sectorPerCluster. * HGFS_QUERY_VOLUME_MASK_VOLUME_LABEL controls volume label. * HGFS_QUERY_VOLUME_MASK_FS_NAME controls fileSystemName. */ typedef uint64 HgfsQueryVolumeMaskV4; #define HGFS_QUERY_VOLUME_MASK_SIZE (1 << 0) #define HGFS_QUERY_VOLUME_MASK_ATTRIBUTES (1 << 1) #define HGFS_QUERY_VOLUME_MASK_FS_CAPABILITIES (1 << 2) #define HGFS_QUERY_VOLUME_MASK_VOLUME_LABEL (1 << 3) #define HGFS_QUERY_VOLUME_MASK_VOLUME_GEOMETRY (1 << 4) #define HGFS_QUERY_VOLUME_MASK_FS_NAME (1 << 5) typedef uint64 HgfsFileSystemCapabilities; #define HGFS_VOLUME_CASE_SENSITIVE (1 << 0) #define HGFS_VOLUME_SUPPORTS_EA (1 << 1) #define HGFS_VOLUME_SUPPORTS_COMPRESSION (1 << 2) #define HGFS_VOLUME_SUPPORTS_SHORT_NAMES (1 << 3) #define HGFS_VOLUME_SUPPORTS_ACL (1 << 4) #define HGFS_VOLUME_READ_ONLY (1 << 5) #define HGFS_VOLUME_SUPPORTS_ENCRYPTION (1 << 6) #define HGFS_VOLUME_SUPPORTS_OBJECT_ID (1 << 7) #define HGFS_VOLUME_SUPPORTS_REMOTE_STORAGE (1 << 8) #define HGFS_VOLUME_SUPPORTS_SYMLINKS (1 << 9) #define HGFS_VOLUME_SUPPORTS_SPARSE_FILES (1 << 10) #define HGFS_VOLUME_SUPPORTS_UNICODE (1 << 11) #define HGFS_VOLUME_SUPPORTS_QUOTA (1 << 12) #define HGFS_VOLUME_SUPPORTS_NAMED_STREAMS (1 << 13) typedef #include "vmware_pack_begin.h" struct HgfsRequestQueryVolumeV4 { HgfsQueryVolumeMaskV4 mask; HgfsFileNameV3 name; } #include "vmware_pack_end.h" HgfsRequestQueryVolumeV4; typedef #include "vmware_pack_begin.h" struct HgfsReplyQueryVolumeV4 { HgfsQueryVolumeMaskV4 mask; /* Identifies which values were set by the host. */ uint64 totalBytes; /* Total volume capacity. */ uint64 freeBytes; /* Free space on the volume. */ uint64 availableBytes; /* Free space available for the user. */ HgfsFileSystemCapabilities capabilities; /* File system capabilities. */ uint64 creationTime; /* Volume creation time. */ uint32 bytesPerSector; /* Sector size for the volume. */ uint32 sectorsPerCluster; /* Cluster size for the volume. */ HgfsFileName volumeLabel; /* Volume name or label. */ HgfsFileName fileSystemName;/* File system name. */ } #include "vmware_pack_end.h" HgfsReplyQueryVolumeV4; typedef uint32 HgfsSearchReadMask; #define HGFS_SEARCH_READ_NAME (1 << 0) #define HGFS_SEARCH_READ_SHORT_NAME (1 << 1) #define HGFS_SEARCH_READ_FILE_SIZE (1 << 2) #define HGFS_SEARCH_READ_ALLOCATION_SIZE (1 << 3) #define HGFS_SEARCH_READ_EA_SIZE (1 << 4) #define HGFS_SEARCH_READ_TIME_STAMP (1 << 5) #define HGFS_SEARCH_READ_FILE_ATTRIBUTES (1 << 6) #define HGFS_SEARCH_READ_FILE_NODE_TYPE (1 << 7) #define HGFS_SEARCH_READ_REPARSE_TAG (1 << 8) #define HGFS_SEARCH_READ_FILE_ID (1 << 9) typedef uint32 HgfsSearchReadFlags; #define HGFS_SEARCH_READ_INITIAL_QUERY (1 << 1) #define HGFS_SEARCH_READ_SINGLE_ENTRY (1 << 2) #define HGFS_SEARCH_READ_FID_OPEN_V4 (1 << 3) #define HGFS_SEARCH_READ_REPLY_FINAL_ENTRY (1 << 4) /* * Read directory request can be used to enumerate files in a directory. * File handle used in the request can be either from HgfsRequestOpenV4 or * HgfsRequestSearchOpenV3. * searchPattern parameter allows filter out file names in the server for optimization. * It is optional - host may ignore patterns and return entries that do not match * the pattern. It is client responsibility to filter out names that do not match * the pattern. * * The mask field in request allows client to specify which properties it is * interested in. It allows to implement optimization in the server by skipping * parameters which client does not need. * * The HGFS Server fills mask field in the reply buffer to specify which * of the requested properties it supports, which may be a subset of the * requested properties. */ typedef #include "vmware_pack_begin.h" struct HgfsRequestSearchReadV4 { HgfsSearchReadMask mask; HgfsSearchReadFlags flags; HgfsHandle fid; uint32 replyDirEntryMaxSize; uint32 restartIndex; uint64 reserved; HgfsFileName searchPattern; } #include "vmware_pack_end.h" HgfsRequestSearchReadV4; typedef #include "vmware_pack_begin.h" struct HgfsDirEntryV4 { uint32 nextEntryOffset; uint32 fileIndex; HgfsSearchReadMask mask; /* Returned mask: may be a subset of requested mask. */ HgfsAttrFlags attrFlags; /* File system attributes of the entry */ HgfsFileType fileType; uint64 fileSize; uint64 allocationSize; uint64 creationTime; uint64 accessTime; uint64 writeTime; uint64 attrChangeTime; uint64 hostFileId; /* File Id of the file on host: inode_t on Linux */ uint32 eaSize; /* Byte size of any extended attributes. */ uint32 reparseTag; /* Windows only: reparse point tag. */ uint64 reserved; /* Reserved for future use. */ HgfsShortFileName shortName; /* Windows only: 8 dot 3 format name. */ HgfsFileName fileName; /* Entry file name. */ } #include "vmware_pack_end.h" HgfsDirEntryV4; typedef #include "vmware_pack_begin.h" struct HgfsReplySearchReadV4 { uint32 numberEntriesReturned; /* number of directory entries in this reply. */ uint32 offsetToContinue; /* Entry index of the directory entry. */ HgfsSearchReadFlags flags; /* Flags to indicate reply specifics */ uint64 reserved; /* Reserved for future use. */ HgfsDirEntryV4 entries[1]; /* Unused as entries transfered using shared memory. */ } #include "vmware_pack_end.h" HgfsReplySearchReadV4; /* * File handle returned by HgfsRequestOpenV4 or later. Descriptors returned by * HgfsHandle fid; earlier versions of HgfsRequestOpen are not supported. */ typedef #include "vmware_pack_begin.h" struct HgfsRequestEnumerateStreamsV4 { uint32 restartIndex; } #include "vmware_pack_end.h" HgfsRequestEnumerateStreamsV4; typedef #include "vmware_pack_begin.h" struct HgfsRequestStreamEntryV4 { uint32 nextEntryOffset; uint32 fileIndex; HgfsFileName fileName; } #include "vmware_pack_end.h" HgfsRequestStreamEntryV4; typedef #include "vmware_pack_begin.h" struct HgfsReplyEnumerateStreamsV4 { uint32 numberEntriesReturned; uint32 offsetToContinue; uint64 reserved; HgfsRequestStreamEntryV4 entries[1]; } #include "vmware_pack_end.h" HgfsReplyEnumerateStreamsV4; typedef #include "vmware_pack_begin.h" struct HgfsRequestGetattrV4 { uint32 mask; uint32 flags; uint64 reserved; HgfsFileNameV3 name; } #include "vmware_pack_end.h" HgfsRequestGetattrV4; /* * V4 reports different file size for symlinks then V3 or V2. * It does not return file name length as EOF - it reports actual EOF. * On POSIX the value is always 0 and on Windows it is an actual EOF of * a file with a reparse point. * Each client must adjust the value for file size according to guest OS rules. * * Mask in HgfsAttr2V2 should be extended to include short name, symlink target and ACL. * If the host does not support a requested feature it is free to clear the * correspondent bit in the mask and ignore the feature. * * Multi-platform notice: symbolic link is represented by a file with REPARSE_POINT * on Windows. Thus Windows supports swtiching a file type between * regular or directory => symlink and back. * Setting symlinkTarget attribute on Windows host results in assigning * reparse point to the host file. */ typedef #include "vmware_pack_begin.h" struct HgfsAttrV4 { HgfsAttrV2 attr; uint32 numberOfLinks; HgfsFileName shortName; HgfsFileName symlinkTarget; uint32 aclLength; uint64 reserved; char acl[1]; } #include "vmware_pack_end.h" HgfsAttrV4; typedef #include "vmware_pack_begin.h" struct HgfsReplyGetattrV4 { HgfsAttrV4 attr; } #include "vmware_pack_end.h" HgfsReplyGetattrV4; typedef #include "vmware_pack_begin.h" struct HgfsRequestSetattrV4 { HgfsAttrHint hints; HgfsAttrV2 attr; uint64 reserved; /* Reserved for future use */ HgfsFileNameV3 fileName; /* Filename used when file handle invalid. */ } #include "vmware_pack_end.h" HgfsRequestSetattrV4; typedef #include "vmware_pack_begin.h" struct HgfsReplySetattrV4 { uint32 mask; /* Defines which attributes were set. */ } #include "vmware_pack_end.h" HgfsReplySetattrV4; /* * Unlike V3 deletion this command can be used to delete both files and directories. * Its semantics depends on whether fid or file path is specified in the fileName. * When path is used it implements/emulates POSIX semantics - name is deleted from * the directory however if the file is opened it is still accessible. When fid is used * the file name disappears from the folder only when the last handle for the file is * closed - Windows style deletion. */ typedef #include "vmware_pack_begin.h" struct HgfsRequestDeleteFileV4 { HgfsFileNameV3 fileName; } #include "vmware_pack_end.h" HgfsRequestDeleteFileV4; typedef #include "vmware_pack_begin.h" struct HgfsReplyDeleteFileV4 { uint64 reserved; } #include "vmware_pack_end.h" HgfsReplyDeleteFileV4; #endif /* _HGFS_PROTO_H_ */ open-vm-tools-9.4.0-1280544/lib/include/err.h0000644765153500003110000000553612220061556016602 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * err.h -- * * General error handling library */ #ifndef _ERR_H_ #define _ERR_H_ #if !defined(_WIN32) #include #endif #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #if defined(__cplusplus) extern "C" { #endif #if defined(_WIN32) typedef DWORD Err_Number; #else typedef int Err_Number; #endif #define ERR_INVALID ((Err_Number) -1) const char *Err_ErrString(void); const char *Err_Errno2String(Err_Number errorNumber); Err_Number Err_String2Errno(const char *string); #ifdef VMX86_DEBUG Err_Number Err_String2ErrnoDebug(const char *string); #endif #if defined(_WIN32) char *Err_SanitizeMessage(const char *msg); #endif /* *---------------------------------------------------------------------- * * Err_Errno -- * * Gets last error in a platform independent way. * * Results: * Last error. * * Side effects: * None. * *---------------------------------------------------------------------- */ #if defined(_WIN32) #define Err_Errno() GetLastError() #else #define Err_Errno() errno #endif /* *---------------------------------------------------------------------- * * Err_SetErrno -- * * Set the last error in a platform independent way. * * Results: * None. * * Side effects: * Yes. * *---------------------------------------------------------------------- */ #if defined(_WIN32) #define Err_SetErrno(e) SetLastError(e) #else #define Err_SetErrno(e) (errno = (e)) #endif /* *---------------------------------------------------------------------- * * WITH_ERRNO -- * * Execute "body" with "e" bound to the last error number * and preserving the last error in surrounding code. * * Results: * None. * * Side effects: * Yes. * *---------------------------------------------------------------------- */ #define WITH_ERRNO(e, body) do { \ Err_Number e = Err_Errno(); \ body; \ Err_SetErrno(e); \ } while (FALSE) #ifdef __cplusplus } #endif #endif open-vm-tools-9.4.0-1280544/lib/include/vmsupport.h0000644765153500003110000000372512220061556020067 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vmsupport.h -- * * Defines constants related to VM support data collection. * */ #ifndef _VMSUPPORT_H_ #define _VMSUPPORT_H_ /* * The status of vm-support tool running in the guest, exported in VMDB at: * vm/#/vmx/guestTools/vmsupport/gStatus * This enum must be kept in sync with vm-support script implementation. * The ordering in enum is important. */ typedef enum { /* vm-support script is not running */ VMSUPPORT_NOT_RUNNING = 0, /* vm-support script is beginning */ VMSUPPORT_BEGINNING = 1, /* vm-support script running in progress */ VMSUPPORT_RUNNING = 2, /* vm-support script is ending */ VMSUPPORT_ENDING = 3, /* vm-support script failed */ VMSUPPORT_ERROR = 10, /* vm-support collection not supported */ VMSUPPORT_UNKNOWN = 100 } VMSupportStatus; /* * The command for vm-support tool launched in the guest, set in VMDB at: * vm/#/vmx/guestTools/vmsupport/hgCmd */ typedef enum { VMSUPPORT_CMD_RESET = 0, VMSUPPORT_CMD_SET = 1 } VMSupportCmd; #define RPC_VMSUPPORT_START "vmsupport.start" #define RPC_VMSUPPORT_STATUS "tools.vmsupport.status" #endif // _VMSUPPORT_H_ open-vm-tools-9.4.0-1280544/lib/include/conf.h0000644765153500003110000001050612220061556016730 0ustar dtormts/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * conf.h -- * * Manage the tools configuration file. * */ #ifndef __CONF_H__ #define __CONF_H__ #include "guestApp.h" #define CONF_FILE "tools.conf" #if ! defined(_WIN32) # define CONFVAL_POWERONSCRIPT_DEFAULT "poweron-vm-default" # define CONFVAL_POWEROFFSCRIPT_DEFAULT "poweroff-vm-default" # define CONFVAL_RESUMESCRIPT_DEFAULT "resume-vm-default" # define CONFVAL_SUSPENDSCRIPT_DEFAULT "suspend-vm-default" #else # define CONFVAL_POWERONSCRIPT_DEFAULT "poweron-vm-default.bat" # define CONFVAL_POWEROFFSCRIPT_DEFAULT "poweroff-vm-default.bat" # define CONFVAL_RESUMESCRIPT_DEFAULT "resume-vm-default.bat" # define CONFVAL_SUSPENDSCRIPT_DEFAULT "suspend-vm-default.bat" #endif #define CONFNAME_POWERONSCRIPT "poweron-script" #define CONFNAME_POWEROFFSCRIPT "poweroff-script" #define CONFNAME_RESUMESCRIPT "resume-script" #define CONFNAME_SUSPENDSCRIPT "suspend-script" #define CONFNAME_LOG "log" #define CONFNAME_LOGFILE "log.file" #define CONFNAME_LOGLEVEL "log.level" #define CONFNAME_DISABLETOOLSVERSION "disable-tools-version" #define CONFNAME_DISABLEPMTIMERWARNING "disable-pmtimerwarning" /* ****************************************************************************** * BEGIN GuestInfo goodies. */ /** * Defines the string used for the GuestInfo config file group. */ #define CONFGROUPNAME_GUESTINFO "guestinfo" /** * Lets users disable just the perf monitor. */ #define CONFNAME_GUESTINFO_DISABLEPERFMON "disable-perf-mon" /** * Lets users disable just DiskInfo. * * If thinking of deprecating this, please read bug 535343 first. */ #define CONFNAME_GUESTINFO_DISABLEQUERYDISKINFO "disable-query-diskinfo" /** * Define a custom GuestInfo poll interval (in seconds). * * @note Illegal values result in a @c g_warning and fallback to the default * poll interval. * * @param int User-defined poll interval. Set to 0 to disable polling. */ #define CONFNAME_GUESTINFO_POLLINTERVAL "poll-interval" /* * END GuestInfo goodies. ****************************************************************************** */ /* ****************************************************************************** * BEGIN Unity goodies. */ /** * Defines the string used for the Unity config file group. */ #define CONFGROUPNAME_UNITY "unity" /** * Lets users enable debug info from Unity. */ #define CONFNAME_UNITY_ENABLEDEBUG "debug" /** * Lets users override system decisions about whether unity should be available. */ #define CONFNAME_UNITY_FORCEENABLE "forceEnable" /** * Lets users override the desktop background color when in Unity mode. */ #define CONFNAME_UNITY_BACKGROUNDCOLOR "desktop.backgroundColor" /** * Lets users enable (or disable) the Protocol Buffer enabled service */ #define CONFNAME_UNITY_ENABLEPBRPC "pbrpc.enable" /** * Lets users configure the socket type for the PBRPC Services */ #define CONFNAME_UNITY_PBRPCSOCKETTYPE "pbrpc.socketType" #define CONFNAME_UNITY_PBRPCSOCKETTYPE_IPSOCKET "ipsocket" #define CONFNAME_UNITY_PBRPCSOCKETTYPE_VSOCKET "vsocket" /* * END Unity goodies. ****************************************************************************** */ /** Where to find Tools data in the Win32 registry. */ #define CONF_VMWARE_TOOLS_REGKEY "Software\\VMware, Inc.\\VMware Tools" /* Wait 5 seconds between polls to see if the conf file has changed */ #define CONF_POLL_TIME 500 #endif /* __CONF_H__ */ open-vm-tools-9.4.0-1280544/lib/include/message.h0000644765153500003110000000421412220061556017426 0ustar dtormts/********************************************************* * Copyright (C) 1999 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * message.h -- * * Second layer of the internal communication channel between guest * applications and vmware */ #ifndef __MESSAGE_H__ # define __MESSAGE_H__ #ifdef __cplusplus extern "C" { #endif #include "vm_basic_types.h" typedef struct Message_Channel Message_Channel; Message_Channel * Message_Open(uint32 proto); // IN Bool Message_Send(Message_Channel *chan, // IN/OUT const unsigned char *buf, // IN size_t bufSize); // IN Bool Message_Receive(Message_Channel *chan, // IN/OUT unsigned char **buf, // OUT size_t *bufSize); // OUT Bool Message_Close(Message_Channel *chan); // IN/OUT #ifdef __cplusplus } #endif #endif /* __MESSAGE_H__ */ open-vm-tools-9.4.0-1280544/lib/include/vmsignal.h0000644765153500003110000000236612220061556017630 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * vmsignal.h -- * * Posix signal handling utility functions * */ #ifndef __VMSIGNAL_H__ # define __VMSIGNAL_H__ #include int Signal_SetGroupHandler(int const *signals, struct sigaction *olds, unsigned int nr, void (*handler)(int signal)); int Signal_ResetGroupHandler(int const *signals, struct sigaction const *olds, unsigned int nr); #endif /* __VMSIGNAL_H__ */ open-vm-tools-9.4.0-1280544/lib/include/unicodeTransforms.h0000644765153500003110000000343612220061556021514 0ustar dtormts/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * unicodeTransforms.h -- * * Operations that transform all the characters in a string. * * Transform operations like uppercase and lowercase are * locale-sensitive (depending on the user's country and language * preferences). */ #ifndef _UNICODE_TRANSFORMS_H_ #define _UNICODE_TRANSFORMS_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "unicodeTypes.h" #ifdef __cplusplus extern "C" { #endif /* * Standardizes the case of the string by doing a locale-agnostic * uppercase operation, then a locale-agnostic lowercase operation. */ Unicode Unicode_FoldCase(ConstUnicode str); /* * Trims whitespace from either side of the string. */ Unicode Unicode_Trim(ConstUnicode str); Unicode Unicode_TrimLeft(ConstUnicode str); Unicode Unicode_TrimRight(ConstUnicode str); #ifdef __cplusplus } #endif #endif // _UNICODE_TRANSFORMS_H_ open-vm-tools-9.4.0-1280544/lib/include/bsd_output.h0000644765153500003110000000375712220061556020205 0ustar dtormts/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * bsd_output.h -- * * Declaration of BSD-borrowed formatted string output functions. */ #ifndef _BSD_OUTPUT_H_ #define _BSD_OUTPUT_H_ #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #include "compat/compat_stdarg.h" /* * Equivalents to the Windows vs*printf functions, except backed by code * borrowed from FreeBSD. This is necessary to provide certain * functionality missing from Windows formatted output APIs - namely * support for both positional arguments and 64-bit integers on all * platforms. * * Where feasible the BSD code has been altered to match what the * VisualC libc versions of vs*printf expect and do, as opposed to what * the GNU libc or FreeBSD versions do. Regarding 64-bit arguments, this * code supports all four of these prefixes: 'L', 'll', 'q', or 'I64'. */ int bsd_vsnprintf(char **outbuf, size_t bufSize, const char *fmt0, va_list ap); int bsd_vsnprintf_c_locale(char **outbuf, size_t bufSize, const char *fmt0, va_list ap); int bsd_vsnwprintf(wchar_t **outbuf, size_t bufSize, const wchar_t *fmt0, va_list ap); #endif // _BSD_OUTPUT_H_ open-vm-tools-9.4.0-1280544/lib/include/timeutil.h0000644765153500003110000000754412220061556017647 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * timeutil.h -- * * Miscellaneous time related utility functions. * */ #ifndef _TIMEUTIL_H_ #define _TIMEUTIL_H_ #include #define INCLUDE_ALLOW_USERLEVEL #include "includeCheck.h" #include "vm_basic_types.h" #include "vm_assert.h" #define MAX_DAYSLEFT 4096 struct timeval; #ifdef _WIN32 struct timespec { time_t tv_sec; long tv_nsec; }; #endif /* Similar to a struct tm but with slightly less weird semantics. */ typedef struct TimeUtil_Date { unsigned int year; /* e.g. 1970 */ unsigned int month; /* [1, 12] */ unsigned int day; /* [1, 31] */ unsigned int hour; /* [0, 23] */ unsigned int minute; /* [0, 59] */ unsigned int second; /* [0, 61] (for leap seconds) */ } TimeUtil_Date; typedef struct TimeUtil_TimeOfDay { unsigned long seconds; unsigned long useconds; } TimeUtil_TimeOfDay; typedef struct TimeUtil_Expiration { /* * Does it expire? */ Bool expires; /* * When does it expire? (valid only if 'expires' == TRUE) * * Note: TimeUtil_Expiration only uses the 'year', 'month' * and 'day' fields of 'when'. */ TimeUtil_Date when; /* * Compute this once for all, to avoid problems when the current day changes * (valid only if 'expires' == TRUE). */ unsigned int daysLeft; } TimeUtil_Expiration; time_t TimeUtil_MakeTime(const TimeUtil_Date *d); Bool TimeUtil_StringToDate(TimeUtil_Date *d, // IN/OUT char const *date); // IN: 'YYYYMMDD' or 'YYYY/MM/DD' or 'YYYY-MM-DD' Bool TimeUtil_DaysSubtract(TimeUtil_Date *d, // IN/OUT unsigned int nr); // IN int TimeUtil_DeltaDays(TimeUtil_Date const *left, // IN TimeUtil_Date const *right); // IN void TimeUtil_DaysAdd(TimeUtil_Date *d, // IN/OUT unsigned int nr); // IN void TimeUtil_PopulateWithCurrent(Bool local, // IN TimeUtil_Date *d); // OUT void TimeUtil_GetTimeOfDay(TimeUtil_TimeOfDay *d); // OUT unsigned int TimeUtil_DaysLeft(TimeUtil_Date const *d); // IN Bool TimeUtil_ExpirationLowerThan(TimeUtil_Expiration const *left, // IN TimeUtil_Expiration const *right); // IN Bool TimeUtil_DateLowerThan(TimeUtil_Date const *left, // IN TimeUtil_Date const *right); // IN void TimeUtil_ProductExpiration(TimeUtil_Expiration *e); // OUT char * TimeUtil_GetTimeFormat(int64 utcTime, // IN Bool showDate, // IN Bool showTime); // IN int TimeUtil_NtTimeToUnixTime(struct timespec *unixTime, // OUT VmTimeType ntTime); // IN VmTimeType TimeUtil_UnixTimeToNtTime(struct timespec unixTime); // IN #ifdef _WIN32 Bool TimeUtil_UTCTimeToSystemTime(const __time64_t utcTime, // IN SYSTEMTIME *systemTime); // OUT #endif int TimeUtil_GetLocalWindowsTimeZoneIndexAndName(char **ptzName); #endif // _TIMEUTIL_H_ open-vm-tools-9.4.0-1280544/lib/include/guestApp.h0000644765153500003110000000256312220061556017577 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * guestApp.h -- * * Utility functions common to all guest applications */ #ifndef __GUESTAPP_H__ # define __GUESTAPP_H__ #if defined(_WIN32) #include #endif #ifdef __cplusplus extern "C" { #endif # include "vm_basic_types.h" const char * GuestApp_GetDefaultScript(const char *confName); // IN #ifdef _WIN32 LPWSTR GuestApp_GetInstallPathW(void); #endif char * GuestApp_GetInstallPath(void); char * GuestApp_GetConfPath(void); #ifdef __cplusplus } #endif #endif /* __GUESTAPP_H__ */ open-vm-tools-9.4.0-1280544/lib/include/hgfsUtil.h0000644765153500003110000001450712220061556017575 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * hgfsUtil.h -- * * Utility functions and macros used by hgfs. */ #ifndef _HGFSUTIL_H_ # define _HGFSUTIL_H_ # if defined __linux__ && defined __KERNEL__ # include "driver-config.h" # include // for time_t and timespec /* Include time.h in userspace code, but not in Solaris kernel code. */ # elif defined __FreeBSD__ && defined _KERNEL /* Do nothing. */ # elif defined __APPLE__ && defined KERNEL # include # else # include # endif # include "vm_basic_types.h" # if !defined _STRUCT_TIMESPEC && \ !defined _TIMESPEC_DECLARED && \ !defined __timespec_defined && \ !defined sun && \ !defined __FreeBSD__ && \ !__APPLE__ && \ !defined _WIN32 struct timespec { time_t tv_sec; long tv_nsec; }; # endif # include "hgfs.h" /* Cross-platform representation of a platform-specific error code. */ #ifndef _WIN32 # if defined __KERNEL__ || defined _KERNEL || defined KERNEL # if defined __linux__ # include # elif defined sun || defined __FreeBSD__ || defined __APPLE__ # include # endif # else # include # endif typedef int HgfsInternalStatus; /* * There is no internal error in Linux. * Define a const that is converted to HGFS_INTERNAL_STATUS_ERROR. */ # define EINTERNAL 1001 #else # include typedef DWORD HgfsInternalStatus; #endif #if defined _WIN32 #define HGFS_ERROR_SUCCESS ERROR_SUCCESS #define HGFS_ERROR_IO ERROR_IO_DEVICE #define HGFS_ERROR_ACCESS_DENIED ERROR_ACCESS_DENIED #define HGFS_ERROR_INVALID_PARAMETER ERROR_INVALID_PARAMETER #define HGFS_ERROR_INVALID_HANDLE ERROR_INVALID_HANDLE #define HGFS_ERROR_PROTOCOL RPC_S_PROTOCOL_ERROR #define HGFS_ERROR_STALE_SESSION ERROR_CONNECTION_INVALID #define HGFS_ERROR_BUSY ERROR_RETRY #define HGFS_ERROR_PATH_BUSY ERROR_RETRY #define HGFS_ERROR_FILE_NOT_FOUND ERROR_FILE_NOT_FOUND #define HGFS_ERROR_FILE_EXIST ERROR_ALREADY_EXISTS #define HGFS_ERROR_NOT_SUPPORTED ERROR_NOT_SUPPORTED #define HGFS_ERROR_NOT_ENOUGH_MEMORY ERROR_NOT_ENOUGH_MEMORY #define HGFS_ERROR_TOO_MANY_SESSIONS ERROR_MAX_SESSIONS_REACHED #define HGFS_ERROR_INTERNAL ERROR_INTERNAL_ERROR #else #define HGFS_ERROR_SUCCESS 0 #define HGFS_ERROR_IO EIO #define HGFS_ERROR_ACCESS_DENIED EACCES #define HGFS_ERROR_INVALID_PARAMETER EINVAL #define HGFS_ERROR_INVALID_HANDLE EBADF #define HGFS_ERROR_PROTOCOL EPROTO #define HGFS_ERROR_STALE_SESSION ENETRESET #define HGFS_ERROR_BUSY EBUSY #define HGFS_ERROR_PATH_BUSY EBUSY #define HGFS_ERROR_FILE_NOT_FOUND ENOENT #define HGFS_ERROR_FILE_EXIST EEXIST #define HGFS_ERROR_NOT_SUPPORTED EOPNOTSUPP #define HGFS_ERROR_NOT_ENOUGH_MEMORY ENOMEM #define HGFS_ERROR_TOO_MANY_SESSIONS ECONNREFUSED #define HGFS_ERROR_INTERNAL EINTERNAL #endif // _WIN32 /* * Unfortunately, we need a catch-all "generic error" to use with * HgfsInternalStatus, because there are times when cross-platform code needs * to return its own errors along with errors from platform specific code. * * Using -1 should be safe because we expect our platforms to use zero as * success and a positive range of numbers as error values. */ #define HGFS_INTERNAL_STATUS_ERROR (-1) #ifndef _WIN32 /* * This error code is used to notify the client that some of the parameters passed * (e.g. file handles) are not supported. Clients are expected to correct * the parameter (e.g. pass file name instead) and retry. * * Note that this error code is artificially made up and in future may conflict * with an "official" error code when added. */ #define EPARAMETERNOTSUPPORTED (MAX_INT32 - 1) #endif /* * FreeBSD (pre-6.0) does not define EPROTO, so we'll define our own error code. */ #if defined __FreeBSD__ && !defined EPROTO #define EPROTO (ELAST + 1) #endif #define HGFS_NAME_BUFFER_SIZE(packetSize, request) (packetSize - (sizeof *request - 1)) #define HGFS_NAME_BUFFER_SIZET(packetSize, sizet) (packetSize - ((sizet) - 1)) #ifndef _WIN32 /* * Routines for converting between Win NT and unix time formats. The * hgfs attributes use the NT time formats, so the linux driver and * server have to convert back and forth. [bac] */ uint64 HgfsConvertToNtTime(time_t unixTime, // IN long nsec); // IN static INLINE uint64 HgfsConvertTimeSpecToNtTime(const struct timespec *unixTime) // IN { return HgfsConvertToNtTime(unixTime->tv_sec, unixTime->tv_nsec); } int HgfsConvertFromNtTime(time_t * unixTime, // OUT uint64 ntTime); // IN int HgfsConvertFromNtTimeNsec(struct timespec *unixTime, // OUT uint64 ntTime); // IN #endif /* !def(_WIN32) */ HgfsStatus HgfsConvertFromInternalStatus(HgfsInternalStatus status); // IN #endif /* _HGFSUTIL_H_ */ open-vm-tools-9.4.0-1280544/lib/include/slashProc.h0000644765153500003110000000252112220061556017737 0ustar dtormts/********************************************************* * Copyright (C) 2009 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /** * @file slashProc.h */ #ifndef _SLASHPROC_H_ #define _SLASHPROC_H_ #include #include /* * Global functions */ EXTERN GHashTable *SlashProcNet_GetSnmp(void); EXTERN GHashTable *SlashProcNet_GetSnmp6(void); EXTERN GPtrArray *SlashProcNet_GetRoute(void); EXTERN void SlashProcNet_FreeRoute(GPtrArray *); EXTERN GPtrArray *SlashProcNet_GetRoute6(void); EXTERN void SlashProcNet_FreeRoute6(GPtrArray *); #endif // ifndef _SLASHPROC_H_ open-vm-tools-9.4.0-1280544/lib/include/syncEvent.h0000644765153500003110000000431212220061556017757 0ustar dtormts/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * syncEvent.h -- * * Implements a platform independent condition event that * you can either wait on or pass to Poll() or your event loop. * * WARNING! * This is an auto-reset event. So, you cannot use it for devices * in Poll that may be holding a device lock. It works fine for Poll if * you don't specify a lock when you register the handle with Poll(). */ #ifndef _SYNC_EVENT_H_ #define _SYNC_EVENT_H_ //#include "syncWaitQ.h" #include "vm_atomic.h" #ifndef _WIN32 typedef enum { READ_FD_INDEX = 0, WRITE_FD_INDEX = 1, NUM_SYNC_EVENT_FDS = 2 } SyncEventFDTypes; #endif // _WIN32 /* * SyncEvent -- */ typedef struct SyncEvent { /* * Whether the waitqueue has been initialized; */ Bool initialized; #ifdef _WIN32 HANDLE event; #else Atomic_uint32 signalled; int fdList[NUM_SYNC_EVENT_FDS]; #endif // #ifdef _WIN32 } SyncEvent; /* * Be careful, on win64, handles are 64 bits, but Poll takes an int32. */ typedef int32 SyncEventSelectableHandle; Bool SyncEvent_Init(SyncEvent *that); void SyncEvent_Destroy(SyncEvent *that); void SyncEvent_Signal(SyncEvent *that); Bool SyncEvent_TryWait(SyncEvent *that); void SyncEvent_Wait(SyncEvent *that); SyncEventSelectableHandle SyncEvent_GetHandle(SyncEvent *that); #endif // #ifndef _SYNC_EVENT_H_ open-vm-tools-9.4.0-1280544/lib/include/vmware_pack_init.h0000644765153500003110000000475712220061556021340 0ustar dtormts/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ #ifndef __VMWARE_PACK_INIT_H__ # define __VMWARE_PACK_INIT_H__ /* * vmware_pack_init.h -- * * Platform-independent code to make the compiler pack (i.e. have them * occupy the smallest possible space) structure definitions. The following * constructs are known to work --hpreg * * #include "vmware_pack_begin.h" * struct foo { * ... * } * #include "vmware_pack_end.h" * ; * * typedef * #include "vmware_pack_begin.h" * struct foo { * ... * } * #include "vmware_pack_end.h" * foo; */ #ifdef _MSC_VER /* * MSVC 6.0 emits warning 4103 when the pack push and pop pragma pairing is * not balanced within 1 included file. That is annoying because our scheme * is based on the pairing being balanced between 2 included files. * * So we disable this warning, but this is safe because the compiler will also * emit warning 4161 when there is more pops than pushes within 1 main * file --hpreg */ # pragma warning(disable:4103) #elif __GNUC__ #else # error Compiler packing... #endif #endif /* __VMWARE_PACK_INIT_H__ */ open-vm-tools-9.4.0-1280544/lib/include/debug.h0000644765153500003110000000211112220061556017062 0ustar dtormts/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * debug.h -- * * Platform specific debug routines * */ #ifndef __DEBUG_H__ # define __DEBUG_H__ # include "vm_basic_types.h" void Debug(char const *fmt, ...) PRINTF_DECL(1, 2); #endif /* __DEBUG_H__ */ open-vm-tools-9.4.0-1280544/lib/include/hostType.h0000644765153500003110000000245412220061556017625 0ustar dtormts/********************************************************* * Copyright (C) 1998-2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /* * hostType.h -- * * Interface to host-specific information functions * */ #ifndef _HOSTTYPE_H_ #define _HOSTTYPE_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMKERNEL #include "includeCheck.h" #include "vm_basic_types.h" Bool HostType_OSIsVMK(void); Bool HostType_OSIsPureVMK(void); Bool HostType_OSIsVMK64(void); Bool HostType_OSIsSimulator(void); #endif /* ifndef _HOSTTYPE_H_ */ open-vm-tools-9.4.0-1280544/lib/include/vm_basic_asm.h0000644765153500003110000010332712220061556020432 0ustar dtormts/********************************************************* * Copyright (C) 2003-2011 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * *********************************************************/ /********************************************************* * The contents of this file are subject to the terms of the Common * Development and Distribution License (the "License") version 1.0 * and no later version. You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://www.opensource.org/licenses/cddl1.php * * See the License for the specific language governing permissions * and limitations under the License. * *********************************************************/ /* * vm_basic_asm.h * * Basic asm macros * * ARM not implemented. */ #ifndef _VM_BASIC_ASM_H_ #define _VM_BASIC_ASM_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_DISTRIBUTE #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMIROM #include "includeCheck.h" #include "vm_basic_types.h" #if defined VM_X86_64 #include "vm_basic_asm_x86_64.h" #elif defined __i386__ #include "vm_basic_asm_x86.h" #endif /* * x86-64 windows doesn't support inline asm so we have to use these * intrinsic functions defined in the compiler. Not all of these are well * documented. There is an array in the compiler dll (c1.dll) which has * an array of the names of all the intrinsics minus the leading * underscore. Searching around in the ntddk.h file can also be helpful. * * The declarations for the intrinsic functions were taken from the DDK. * Our declarations must match the ddk's otherwise the 64-bit c++ compiler * will complain about second linkage of the intrinsic functions. * We define the intrinsic using the basic types corresponding to the * Windows typedefs. This avoids having to include windows header files * to get to the windows types. */ #ifdef _MSC_VER #ifdef __cplusplus extern "C" { #endif /* * It seems x86 & x86-64 windows still implements these intrinsic * functions. The documentation for the x86-64 suggest the * __inbyte/__outbyte intrinsics even though the _in/_out work fine and * __inbyte/__outbyte aren't supported on x86. */ int _inp(unsigned short); unsigned short _inpw(unsigned short); unsigned long _inpd(unsigned short); int _outp(unsigned short, int); unsigned short _outpw(unsigned short, unsigned short); unsigned long _outpd(uint16, unsigned long); #pragma intrinsic(_inp, _inpw, _inpd, _outp, _outpw, _outpw, _outpd) /* * Prevents compiler from re-ordering reads, writes and reads&writes. * These functions do not add any instructions thus only affect * the compiler ordering. * * See: * `Lockless Programming Considerations for Xbox 360 and Microsoft Windows' * http://msdn.microsoft.com/en-us/library/bb310595(VS.85).aspx */ void _ReadBarrier(void); void _WriteBarrier(void); void _ReadWriteBarrier(void); #pragma intrinsic(_ReadBarrier, _WriteBarrier, _ReadWriteBarrier) void _mm_mfence(void); void _mm_lfence(void); #pragma intrinsic(_mm_mfence, _mm_lfence) unsigned int __getcallerseflags(void); #pragma intrinsic(__getcallerseflags) #ifdef VM_X86_64 /* * intrinsic functions only supported by x86-64 windows as of 2k3sp1 */ unsigned __int64 __rdtsc(void); void __stosw(unsigned short *, unsigned short, size_t); void __stosd(unsigned long *, unsigned long, size_t); void _mm_pause(void); #pragma intrinsic(__rdtsc, __stosw, __stosd, _mm_pause) unsigned char _BitScanForward64(unsigned long *, unsigned __int64); unsigned char _BitScanReverse64(unsigned long *, unsigned __int64); #pragma intrinsic(_BitScanForward64, _BitScanReverse64) #endif /* VM_X86_64 */ unsigned char _BitScanForward(unsigned long *, unsigned long); unsigned char _BitScanReverse(unsigned long *, unsigned long); #pragma intrinsic(_BitScanForward, _BitScanReverse) unsigned char _bittest(const long *, long); unsigned char _bittestandset(long *, long); unsigned char _bittestandreset(long *, long); unsigned char _bittestandcomplement(long *, long); #pragma intrinsic(_bittest, _bittestandset, _bittestandreset, _bittestandcomplement) #ifdef VM_X86_64 unsigned char _bittestandset64(__int64 *, __int64); unsigned char _bittestandreset64(__int64 *, __int64); #pragma intrinsic(_bittestandset64, _bittestandreset64) #endif /* VM_X86_64 */ #ifdef __cplusplus } #endif #endif /* _MSC_VER */ #ifdef __GNUC__ // { #if defined(__i386__) || defined(__x86_64__) // Only on x86* /* * Checked against the Intel manual and GCC --hpreg * * volatile because reading from port can modify the state of the underlying * hardware. * * Note: The undocumented %z construct doesn't work (internal compiler error) * with gcc-2.95.1 */ #define __GCC_IN(s, type, name) \ static INLINE type \ name(uint16 port) \ { \ type val; \ \ __asm__ __volatile__( \ "in" #s " %w1, %0" \ : "=a" (val) \ : "Nd" (port) \ ); \ \ return val; \ } __GCC_IN(b, uint8, INB) __GCC_IN(w, uint16, INW) __GCC_IN(l, uint32, IN32) /* * Checked against the Intel manual and GCC --hpreg * * Note: The undocumented %z construct doesn't work (internal compiler error) * with gcc-2.95.1 */ #define __GCC_OUT(s, s2, port, val) do { \ __asm__( \ "out" #s " %" #s2 "1, %w0" \ : \ : "Nd" (port), "a" (val) \ ); \ } while (0) #define OUTB(port, val) __GCC_OUT(b, b, port, val) #define OUTW(port, val) __GCC_OUT(w, w, port, val) #define OUT32(port, val) __GCC_OUT(l, , port, val) #define GET_CURRENT_EIP(_eip) \ __asm__ __volatile("call 0\n\tpopl %0" : "=r" (_eip): ); static INLINE unsigned int GetCallerEFlags(void) { unsigned long flags; asm volatile("pushf; pop %0" : "=r"(flags)); return flags; } #endif // x86* #elif defined(_MSC_VER) // } { static INLINE uint8 INB(uint16 port) { return (uint8)_inp(port); } static INLINE void OUTB(uint16 port, uint8 value) { _outp(port, value); } static INLINE uint16 INW(uint16 port) { return _inpw(port); } static INLINE void OUTW(uint16 port, uint16 value) { _outpw(port, value); } static INLINE uint32 IN32(uint16 port) { return _inpd(port); } static INLINE void OUT32(uint16 port, uint32 value) { _outpd(port, value); } #ifndef VM_X86_64 #ifdef NEAR #undef NEAR #endif #define GET_CURRENT_EIP(_eip) do { \ __asm call NEAR PTR $+5 \ __asm pop eax \ __asm mov _eip, eax \ } while (0) #endif // VM_X86_64 static INLINE unsigned int GetCallerEFlags(void) { return __getcallerseflags(); } #else // } { #error #endif // } /* Sequence recommended by Intel for the Pentium 4. */ #define INTEL_MICROCODE_VERSION() ( \ __SET_MSR(MSR_BIOS_SIGN_ID, 0), \ __GET_EAX_FROM_CPUID(1), \ __GET_MSR(MSR_BIOS_SIGN_ID)) /* * Locate most and least significant bit set functions. Use our own name * space to avoid namespace collisions. The new names follow a pattern, *